Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:07:08

0001 /*
0002  * \file DTDataIntegrityROSOffline.cc
0003  *
0004  * \author M. Zanetti (INFN Padova), S. Bolognesi (INFN Torino), G. Cerminara (INFN Torino)
0005  *
0006  */
0007 
0008 #include "DQM/DTMonitorModule/interface/DTDataIntegrityROSOffline.h"
0009 #include "FWCore/Framework/interface/Frameworkfwd.h"
0010 #include "FWCore/Framework/interface/Event.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "DataFormats/DTDigi/interface/DTControlData.h"
0013 #include "DataFormats/DTDigi/interface/DTDDUWords.h"
0014 #include "DQMServices/Core/interface/DQMStore.h"
0015 #include "FWCore/ServiceRegistry/interface/Service.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0018 #include "FWCore/Utilities/interface/Exception.h"
0019 
0020 #include <cmath>
0021 #include <fstream>
0022 #include <map>
0023 #include <string>
0024 #include <vector>
0025 
0026 using namespace std;
0027 using namespace edm;
0028 
0029 DTDataIntegrityROSOffline::DTDataIntegrityROSOffline(const edm::ParameterSet& ps) : nevents(0) {
0030   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0031       << "[DTDataIntegrityROSOffline]: Constructor" << endl;
0032 
0033   dduToken = consumes<DTDDUCollection>(ps.getUntrackedParameter<InputTag>("dtDDULabel"));
0034   ros25Token = consumes<DTROS25Collection>(ps.getUntrackedParameter<InputTag>("dtROS25Label"));
0035   FEDIDmin = FEDNumbering::MINDTFEDID;
0036   FEDIDmax = FEDNumbering::MAXDTFEDID;
0037 
0038   neventsFED = 0;
0039 
0040   //   Plot quantities about SC
0041   getSCInfo = ps.getUntrackedParameter<bool>("getSCInfo", false);
0042 
0043   fedIntegrityFolder = ps.getUntrackedParameter<string>("fedIntegrityFolder", "DT/FEDIntegrity");
0044 }
0045 
0046 DTDataIntegrityROSOffline::~DTDataIntegrityROSOffline() {
0047   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0048       << "[DTDataIntegrityROSOffline]: Destructor. Analyzed " << neventsFED << " events" << endl;
0049   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0050       << "[DTDataIntegrityROSOffline]: postEndJob called!" << endl;
0051 }
0052 
0053 /*
0054   Folder Structure (ROS Legacy):
0055   - One folder for each DDU, named FEDn
0056   - Inside each DDU folder the DDU histos and the ROSn folder
0057   - Inside each ROS folder the ROS histos and the ROBn folder
0058   - Inside each ROB folder one occupancy plot and the TimeBoxes
0059   with the chosen granularity (simply change the histo name)
0060 */
0061 
0062 void DTDataIntegrityROSOffline::bookHistograms(DQMStore::IBooker& ibooker,
0063                                                edm::Run const& iRun,
0064                                                edm::EventSetup const& iSetup) {
0065   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0066       << "[DTDataIntegrityROSOffline]: postBeginJob" << endl;
0067 
0068   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0069       << "[DTDataIntegrityROSOffline] Get DQMStore service" << endl;
0070 
0071   // Loop over the DT FEDs
0072 
0073   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0074       << " FEDS: " << FEDIDmin << " to " << FEDIDmax << " in the RO" << endl;
0075 
0076   // book FED integrity histos
0077   bookHistos(ibooker, FEDIDmin, FEDIDmax);
0078 
0079   //Legacy ROS
0080 
0081   // static booking of the histograms
0082 
0083   for (int fed = FEDIDmin; fed <= FEDIDmax; ++fed) {  // loop over the FEDs in the readout
0084     DTROChainCoding code;
0085     code.setDDU(fed);
0086     bookHistos(ibooker, string("ROS_S"), code);
0087 
0088     bookHistos(ibooker, string("DDU"), code);
0089 
0090     for (int ros = 1; ros <= nROS; ++ros) {  // loop over all ROS
0091       code.setROS(ros);
0092       bookHistosROS25(ibooker, code);
0093     }
0094   }
0095 }
0096 
0097 void DTDataIntegrityROSOffline::bookHistos(DQMStore::IBooker& ibooker, const int fedMin, const int fedMax) {
0098   ibooker.setCurrentFolder("DT/EventInfo/Counters");
0099   nEventMonitor = ibooker.bookFloat("nProcessedEventsDataIntegrity");
0100 
0101   // Standard FED integrity histos
0102   ibooker.setCurrentFolder(topFolder(true));
0103 
0104   int nFED = (fedMax - fedMin) + 1;
0105 
0106   hFEDEntry = ibooker.book1D("FEDEntries", "# entries per DT FED", nFED, fedMin, fedMax + 1);
0107 
0108   hFEDFatal = ibooker.book1D("FEDFatal", "# fatal errors DT FED", nFED, fedMin, fedMax + 1);
0109   hFEDNonFatal = ibooker.book1D("FEDNonFatal", "# NON fatal errors DT FED", nFED, fedMin, fedMax + 1);
0110 
0111   ibooker.setCurrentFolder(topFolder(false));
0112   hTTSSummary = ibooker.book2D("TTSSummary", "Summary Status TTS", nFED, fedMin, fedMax + 1, 9, 1, 10);
0113   hTTSSummary->setAxisTitle("FED", 1);
0114   hTTSSummary->setBinLabel(1, "ROS PAF", 2);
0115   hTTSSummary->setBinLabel(2, "DDU PAF", 2);
0116   hTTSSummary->setBinLabel(3, "ROS PAF", 2);
0117   hTTSSummary->setBinLabel(4, "DDU PAF", 2);
0118   hTTSSummary->setBinLabel(5, "DDU Full", 2);
0119   hTTSSummary->setBinLabel(6, "L1A Mism.", 2);
0120   hTTSSummary->setBinLabel(7, "ROS Error", 2);
0121   hTTSSummary->setBinLabel(8, "BX Mism.", 2);
0122   hTTSSummary->setBinLabel(9, "DDU Logic Err.", 2);
0123 
0124   // bookkeeping of the histos
0125   hCorruptionSummary =
0126       ibooker.book2D("DataCorruptionSummary", "Data Corruption Sources", nFED, fedMin, fedMax + 1, 8, 1, 9);
0127   hCorruptionSummary->setAxisTitle("FED", 1);
0128   hCorruptionSummary->setBinLabel(1, "Miss Ch.", 2);
0129   hCorruptionSummary->setBinLabel(2, "ROS BX mism", 2);
0130   hCorruptionSummary->setBinLabel(3, "DDU BX mism", 2);
0131   hCorruptionSummary->setBinLabel(4, "ROS L1A mism", 2);
0132   hCorruptionSummary->setBinLabel(5, "Miss Payload", 2);
0133   hCorruptionSummary->setBinLabel(6, "FCRC bit", 2);
0134   hCorruptionSummary->setBinLabel(7, "Header check", 2);
0135   hCorruptionSummary->setBinLabel(8, "Trailer Check", 2);
0136 }
0137 
0138 void DTDataIntegrityROSOffline::bookHistos(DQMStore::IBooker& ibooker, string folder, DTROChainCoding code) {
0139   string dduID_s = to_string(code.getDDU());
0140   string rosID_s = to_string(code.getROS());
0141   string robID_s = to_string(code.getROB());
0142   int wheel = (code.getDDUID() - 770) % 5 - 2;
0143   string wheel_s = to_string(wheel);
0144 
0145   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0146       << " Booking histos for FED: " << code.getDDU() << " ROS: " << code.getROS() << " ROB: " << code.getROB()
0147       << " folder: " << folder << endl;
0148 
0149   string histoType;
0150   string histoName;
0151   string histoTitle;
0152   MonitorElement* histo = nullptr;
0153 
0154   // DDU Histograms
0155   if (folder == "DDU") {
0156     ibooker.setCurrentFolder(topFolder(false) + "FED" + dduID_s);
0157 
0158     histoType = "EventLength";
0159     histoName = "FED" + dduID_s + "_" + histoType;
0160     histoTitle = "Event Length (Bytes) FED " + dduID_s;
0161     (fedHistos[histoType])[code.getDDUID()] = ibooker.book1D(histoName, histoTitle, 501, 0, 16032);
0162 
0163     histoType = "ROSStatus";
0164     histoName = "FED" + dduID_s + "_" + histoType;
0165     (fedHistos[histoType])[code.getDDUID()] = ibooker.book2D(histoName, histoName, 12, 0, 12, 12, 0, 12);
0166     histo = (fedHistos[histoType])[code.getDDUID()];
0167     histo->setBinLabel(1, "ch.enabled", 1);
0168     histo->setBinLabel(2, "timeout", 1);
0169     histo->setBinLabel(3, "ev.trailer lost", 1);
0170     histo->setBinLabel(4, "opt.fiber lost", 1);
0171     histo->setBinLabel(5, "tlk.prop.error", 1);
0172     histo->setBinLabel(6, "tlk.pattern error", 1);
0173     histo->setBinLabel(7, "tlk.sign.lost", 1);
0174     histo->setBinLabel(8, "error from ROS", 1);
0175     histo->setBinLabel(9, "if ROS in events", 1);
0176     histo->setBinLabel(10, "Miss. Evt.", 1);
0177     histo->setBinLabel(11, "Evt. ID Mismatch", 1);
0178     histo->setBinLabel(12, "BX Mismatch", 1);
0179 
0180     histo->setBinLabel(1, "ROS 1", 2);
0181     histo->setBinLabel(2, "ROS 2", 2);
0182     histo->setBinLabel(3, "ROS 3", 2);
0183     histo->setBinLabel(4, "ROS 4", 2);
0184     histo->setBinLabel(5, "ROS 5", 2);
0185     histo->setBinLabel(6, "ROS 6", 2);
0186     histo->setBinLabel(7, "ROS 7", 2);
0187     histo->setBinLabel(8, "ROS 8", 2);
0188     histo->setBinLabel(9, "ROS 9", 2);
0189     histo->setBinLabel(10, "ROS 10", 2);
0190     histo->setBinLabel(11, "ROS 11", 2);
0191     histo->setBinLabel(12, "ROS 12", 2);
0192   }
0193 
0194   // ROS Histograms
0195   if (folder == "ROS_S") {  // The summary of the error of the ROS on the same FED
0196     ibooker.setCurrentFolder(topFolder(false));
0197 
0198     histoType = "ROSSummary";
0199     histoName = "FED" + dduID_s + "_ROSSummary";
0200     string histoTitle = "Summary Wheel" + wheel_s + " (FED " + dduID_s + ")";
0201 
0202     ((summaryHistos[histoType])[code.getDDUID()]) = ibooker.book2D(histoName, histoTitle, 20, 0, 20, 12, 1, 13);
0203     MonitorElement* histo = ((summaryHistos[histoType])[code.getDDUID()]);
0204     // ROS error bins
0205     histo->setBinLabel(1, "Link TimeOut", 1);
0206     histo->setBinLabel(2, "Ev.Id.Mis.", 1);
0207     histo->setBinLabel(3, "FIFO almost full", 1);
0208     histo->setBinLabel(4, "FIFO full", 1);
0209     histo->setBinLabel(5, "CEROS timeout", 1);
0210     histo->setBinLabel(6, "Max. wds", 1);
0211     histo->setBinLabel(7, "WO L1A FIFO", 1);
0212     histo->setBinLabel(8, "TDC parity err.", 1);
0213     histo->setBinLabel(9, "BX ID Mis.", 1);
0214     histo->setBinLabel(10, "TXP", 1);
0215     histo->setBinLabel(11, "L1A almost full", 1);
0216     histo->setBinLabel(12, "Ch. blocked", 1);
0217     histo->setBinLabel(13, "Ev. Id. Mis.", 1);
0218     histo->setBinLabel(14, "CEROS blocked", 1);
0219     // TDC error bins
0220     histo->setBinLabel(15, "TDC Fatal", 1);
0221     histo->setBinLabel(16, "TDC RO FIFO ov.", 1);
0222     histo->setBinLabel(17, "TDC L1 buf. ov.", 1);
0223     histo->setBinLabel(18, "TDC L1A FIFO ov.", 1);
0224     histo->setBinLabel(19, "TDC hit err.", 1);
0225     histo->setBinLabel(20, "TDC hit rej.", 1);
0226 
0227     histo->setBinLabel(1, "ROS1", 2);
0228     histo->setBinLabel(2, "ROS2", 2);
0229     histo->setBinLabel(3, "ROS3", 2);
0230     histo->setBinLabel(4, "ROS4", 2);
0231     histo->setBinLabel(5, "ROS5", 2);
0232     histo->setBinLabel(6, "ROS6", 2);
0233     histo->setBinLabel(7, "ROS7", 2);
0234     histo->setBinLabel(8, "ROS8", 2);
0235     histo->setBinLabel(9, "ROS9", 2);
0236     histo->setBinLabel(10, "ROS10", 2);
0237     histo->setBinLabel(11, "ROS11", 2);
0238     histo->setBinLabel(12, "ROS12", 2);
0239   }
0240 
0241   if (folder == "ROS") {
0242     ibooker.setCurrentFolder(topFolder(false) + "FED" + dduID_s + "/" + folder + rosID_s);
0243 
0244     histoType = "ROSError";
0245     histoName = "FED" + dduID_s + "_" + folder + rosID_s + "_ROSError";
0246     histoTitle = histoName + " (ROBID error summary)";
0247     (rosHistos[histoType])[code.getROSID()] = ibooker.book2D(histoName, histoTitle, 11, 0, 11, 26, 0, 26);
0248 
0249     MonitorElement* histo = (rosHistos[histoType])[code.getROSID()];
0250     // ROS error bins
0251     histo->setBinLabel(1, "Link TimeOut", 1);
0252     histo->setBinLabel(2, "Ev.Id.Mis.", 1);
0253     histo->setBinLabel(3, "FIFO almost full", 1);
0254     histo->setBinLabel(4, "FIFO full", 1);
0255     histo->setBinLabel(5, "CEROS timeout", 1);
0256     histo->setBinLabel(6, "Max. wds", 1);
0257     histo->setBinLabel(7, "TDC parity err.", 1);
0258     histo->setBinLabel(8, "BX ID Mis.", 1);
0259     histo->setBinLabel(9, "Ch. blocked", 1);
0260     histo->setBinLabel(10, "Ev. Id. Mis.", 1);
0261     histo->setBinLabel(11, "CEROS blocked", 1);
0262 
0263     histo->setBinLabel(1, "ROB0", 2);
0264     histo->setBinLabel(2, "ROB1", 2);
0265     histo->setBinLabel(3, "ROB2", 2);
0266     histo->setBinLabel(4, "ROB3", 2);
0267     histo->setBinLabel(5, "ROB4", 2);
0268     histo->setBinLabel(6, "ROB5", 2);
0269     histo->setBinLabel(7, "ROB6", 2);
0270     histo->setBinLabel(8, "ROB7", 2);
0271     histo->setBinLabel(9, "ROB8", 2);
0272     histo->setBinLabel(10, "ROB9", 2);
0273     histo->setBinLabel(11, "ROB10", 2);
0274     histo->setBinLabel(12, "ROB11", 2);
0275     histo->setBinLabel(13, "ROB12", 2);
0276     histo->setBinLabel(14, "ROB13", 2);
0277     histo->setBinLabel(15, "ROB14", 2);
0278     histo->setBinLabel(16, "ROB15", 2);
0279     histo->setBinLabel(17, "ROB16", 2);
0280     histo->setBinLabel(18, "ROB17", 2);
0281     histo->setBinLabel(19, "ROB18", 2);
0282     histo->setBinLabel(20, "ROB19", 2);
0283     histo->setBinLabel(21, "ROB20", 2);
0284     histo->setBinLabel(22, "ROB21", 2);
0285     histo->setBinLabel(23, "ROB22", 2);
0286     histo->setBinLabel(24, "ROB23", 2);
0287     histo->setBinLabel(25, "ROB24", 2);
0288     histo->setBinLabel(26, "SC", 2);
0289   }
0290 
0291   // SC Histograms
0292   if (folder == "SC") {
0293     // The plots are per wheel
0294     ibooker.setCurrentFolder(topFolder(false) + "FED" + dduID_s);
0295 
0296     // SC data Size
0297     histoType = "SCSizeVsROSSize";
0298     histoName = "FED" + dduID_s + "_SCSizeVsROSSize";
0299     histoTitle = "SC size vs SC (FED " + dduID_s + ")";
0300     rosHistos[histoType][code.getSCID()] = ibooker.book2D(histoName, histoTitle, 12, 1, 13, 51, -1, 50);
0301     rosHistos[histoType][code.getSCID()]->setAxisTitle("SC", 1);
0302   }
0303 }
0304 
0305 void DTDataIntegrityROSOffline::bookHistosROS25(DQMStore::IBooker& ibooker, DTROChainCoding code) {
0306   bookHistos(ibooker, string("ROS"), code);
0307 }
0308 
0309 void DTDataIntegrityROSOffline::processROS25(DTROS25Data& data, int ddu, int ros) {
0310   neventsROS++;
0311 
0312   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0313       << "[DTDataIntegrityROSOffline]: " << neventsROS << " events analyzed by processROS25" << endl;
0314 
0315   // The ID of the RO board (used to map the histos)
0316   DTROChainCoding code;
0317   code.setDDU(ddu);
0318   code.setROS(ros);
0319 
0320   MonitorElement* ROSSummary = summaryHistos["ROSSummary"][code.getDDUID()];
0321 
0322   // Summary of all ROB errors
0323   MonitorElement* ROSError = nullptr;
0324   ROSError = rosHistos["ROSError"][code.getROSID()];
0325 
0326   if ((!ROSError)) {
0327     LogError("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0328         << "Trying to access non existing ME at ROSID " << code.getROSID() << std::endl;
0329     return;
0330   }
0331 
0332   // L1A ids to be checked against FED one
0333   rosL1AIdsPerFED[ddu].insert(data.getROSHeader().TTCEventCounter());
0334 
0335   // ROS errors
0336 
0337   // check for TPX errors
0338   if (data.getROSTrailer().TPX() != 0) {
0339     LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0340         << " TXP error en ROS " << code.getROS() << endl;
0341     ROSSummary->Fill(9, code.getROS());
0342   }
0343 
0344   // L1 Buffer almost full (non-critical error!)
0345   if (data.getROSTrailer().l1AFifoOccupancy() > 31) {
0346     ROSSummary->Fill(10, code.getROS());
0347   }
0348 
0349   for (vector<DTROSErrorWord>::const_iterator error_it = data.getROSErrors().begin();
0350        error_it != data.getROSErrors().end();
0351        error_it++) {  // Loop over ROS error words
0352 
0353     LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0354         << " Error in ROS " << code.getROS() << " ROB Id " << (*error_it).robID() << " Error type "
0355         << (*error_it).errorType() << endl;
0356 
0357     // Fill the ROSSummary (1 per FED) histo
0358     ROSSummary->Fill((*error_it).errorType(), code.getROS());
0359     if ((*error_it).errorType() <= 11) {  // set error flag
0360       eventErrorFlag = true;
0361     }
0362 
0363     // Fill the ROB Summary (1 per ROS) histo
0364     if ((*error_it).robID() != 31) {
0365       ROSError->Fill((*error_it).errorType(), (*error_it).robID());
0366     } else if ((*error_it).errorType() == 4) {
0367       vector<int> channelBins;
0368       channelsInROS((*error_it).cerosID(), channelBins);
0369       vector<int>::const_iterator channelIt = channelBins.begin();
0370       vector<int>::const_iterator channelEnd = channelBins.end();
0371       for (; channelIt != channelEnd; ++channelIt) {
0372         ROSError->Fill(4, (*channelIt));
0373       }
0374     }
0375   }
0376 
0377   int ROSDebug_BunchNumber = -1;
0378 
0379   for (vector<DTROSDebugWord>::const_iterator debug_it = data.getROSDebugs().begin();
0380        debug_it != data.getROSDebugs().end();
0381        debug_it++) {  // Loop over ROS debug words
0382 
0383     int debugROSSummary = 0;
0384     int debugROSError = 0;
0385     vector<int> debugBins;
0386     bool hasEvIdMis = false;
0387     vector<int> evIdMisBins;
0388 
0389     if ((*debug_it).debugType() == 0) {
0390       ROSDebug_BunchNumber = (*debug_it).debugMessage();
0391     } else if ((*debug_it).debugType() == 1) {
0392       // not used
0393       // ROSDebug_BcntResCntLow = (*debug_it).debugMessage();
0394     } else if ((*debug_it).debugType() == 2) {
0395       // not used
0396       // ROSDebug_BcntResCntHigh = (*debug_it).debugMessage();
0397     } else if ((*debug_it).debugType() == 3) {
0398       if ((*debug_it).dontRead()) {
0399         debugROSSummary = 11;
0400         debugROSError = 8;
0401         channelsInCEROS((*debug_it).cerosIdCerosStatus(), (*debug_it).dontRead(), debugBins);
0402       }
0403       if ((*debug_it).evIdMis()) {
0404         hasEvIdMis = true;
0405         channelsInCEROS((*debug_it).cerosIdCerosStatus(), (*debug_it).evIdMis(), evIdMisBins);
0406       }
0407     } else if ((*debug_it).debugType() == 4 && (*debug_it).cerosIdRosStatus()) {
0408       debugROSSummary = 13;
0409       debugROSError = 10;
0410       channelsInROS((*debug_it).cerosIdRosStatus(), debugBins);
0411     }
0412 
0413     if (debugROSSummary) {
0414       ROSSummary->Fill(debugROSSummary, code.getROS());
0415       vector<int>::const_iterator channelIt = debugBins.begin();
0416       vector<int>::const_iterator channelEnd = debugBins.end();
0417       for (; channelIt != channelEnd; ++channelIt) {
0418         ROSError->Fill(debugROSError, (*channelIt));
0419       }
0420     }
0421 
0422     if (hasEvIdMis) {
0423       ROSSummary->Fill(12, code.getROS());
0424       vector<int>::const_iterator channelIt = evIdMisBins.begin();
0425       vector<int>::const_iterator channelEnd = evIdMisBins.end();
0426       for (; channelIt != channelEnd; ++channelIt) {
0427         ROSError->Fill(9, (*channelIt));
0428       }
0429     }
0430   }
0431 
0432   // ROB Group Header
0433   // Check the BX of the ROB headers against the BX of the ROS
0434   for (vector<DTROBHeader>::const_iterator rob_it = data.getROBHeaders().begin(); rob_it != data.getROBHeaders().end();
0435        rob_it++) {  // loop over ROB headers
0436 
0437     code.setROB((*rob_it).first);
0438     DTROBHeaderWord robheader = (*rob_it).second;
0439 
0440     rosBxIdsPerFED[ddu].insert(ROSDebug_BunchNumber);
0441 
0442     if (robheader.bunchID() != ROSDebug_BunchNumber) {
0443       // fill ROS Summary plot
0444       ROSSummary->Fill(8, code.getROS());
0445       eventErrorFlag = true;
0446 
0447       // fill ROB Summary plot for that particular ROS
0448       ROSError->Fill(7, robheader.robID());
0449     }
0450   }
0451 
0452   // TDC Data
0453   for (vector<DTTDCData>::const_iterator tdc_it = data.getTDCData().begin(); tdc_it != data.getTDCData().end();
0454        tdc_it++) {  // loop over TDC data
0455 
0456     DTTDCMeasurementWord tdcDatum = (*tdc_it).second;
0457 
0458     if (tdcDatum.PC() != 0) {
0459       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0460           << " PC error in ROS " << code.getROS() << " TDC " << (*tdc_it).first << endl;
0461       //     fill ROS Summary plot
0462       ROSSummary->Fill(7, code.getROS());
0463 
0464       eventErrorFlag = true;
0465 
0466       // fill ROB Summary plot for that particular ROS
0467       ROSError->Fill(6, (*tdc_it).first);
0468     }
0469   }
0470 
0471   // TDC Error
0472   for (vector<DTTDCError>::const_iterator tdc_it = data.getTDCError().begin(); tdc_it != data.getTDCError().end();
0473        tdc_it++) {  // loop over TDC errors
0474 
0475     code.setROB((*tdc_it).first);
0476 
0477     int tdcError_ROSSummary = 0;
0478     int tdcError_ROSError = 0;
0479 
0480     if (((*tdc_it).second).tdcError() & 0x4000) {
0481       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0482           << " ROS " << code.getROS() << " ROB " << code.getROB() << " Internal fatal Error 4000 in TDC "
0483           << (*tdc_it).first << endl;
0484 
0485       tdcError_ROSSummary = 14;
0486       tdcError_ROSError = 11;
0487 
0488     } else if (((*tdc_it).second).tdcError() & 0x0249) {
0489       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0490           << " ROS " << code.getROS() << " ROB " << code.getROB() << " TDC FIFO overflow in TDC " << (*tdc_it).first
0491           << endl;
0492 
0493       tdcError_ROSSummary = 15;
0494       tdcError_ROSError = 12;
0495 
0496     } else if (((*tdc_it).second).tdcError() & 0x0492) {
0497       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0498           << " ROS " << code.getROS() << " ROB " << code.getROB() << " TDC L1 buffer overflow in TDC "
0499           << (*tdc_it).first << endl;
0500 
0501       tdcError_ROSSummary = 16;
0502       tdcError_ROSError = 13;
0503 
0504     } else if (((*tdc_it).second).tdcError() & 0x2000) {
0505       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0506           << " ROS " << code.getROS() << " ROB " << code.getROB() << " TDC L1A FIFO overflow in TDC " << (*tdc_it).first
0507           << endl;
0508 
0509       tdcError_ROSSummary = 17;
0510       tdcError_ROSError = 14;
0511 
0512     } else if (((*tdc_it).second).tdcError() & 0x0924) {
0513       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0514           << " ROS " << code.getROS() << " ROB " << code.getROB() << " TDC hit error in TDC " << (*tdc_it).first
0515           << endl;
0516 
0517       tdcError_ROSSummary = 18;
0518       tdcError_ROSError = 15;
0519 
0520     } else if (((*tdc_it).second).tdcError() & 0x1000) {
0521       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0522           << " ROS " << code.getROS() << " ROB " << code.getROB() << " TDC hit rejected in TDC " << (*tdc_it).first
0523           << endl;
0524 
0525       tdcError_ROSSummary = 19;
0526       tdcError_ROSError = 16;
0527 
0528     } else {
0529       LogWarning("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0530           << " TDC error code not known " << ((*tdc_it).second).tdcError() << endl;
0531     }
0532 
0533     ROSSummary->Fill(tdcError_ROSSummary, code.getROS());
0534 
0535     if (tdcError_ROSSummary <= 15) {
0536       eventErrorFlag = true;
0537     }
0538 
0539     ROSError->Fill(tdcError_ROSError, (*tdc_it).first);
0540   }
0541 }
0542 
0543 void DTDataIntegrityROSOffline::processFED(DTDDUData& data, const std::vector<DTROS25Data>& rosData, int ddu) {
0544   neventsFED++;
0545   if (neventsFED % 1000 == 0)
0546     LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0547         << "[DTDataIntegrityROSOffline]: " << neventsFED << " events analyzed by processFED" << endl;
0548 
0549   DTROChainCoding code;
0550   code.setDDU(ddu);
0551   if (code.getDDUID() < FEDIDmin || code.getDDUID() > FEDIDmax)
0552     return;
0553 
0554   hFEDEntry->Fill(code.getDDUID());
0555 
0556   const FEDTrailer& trailer = data.getDDUTrailer();
0557   const FEDHeader& header = data.getDDUHeader();
0558 
0559   // check consistency of header and trailer
0560   if (!header.check()) {
0561     // error code 7
0562     hFEDFatal->Fill(code.getDDUID());
0563     hCorruptionSummary->Fill(code.getDDUID(), 7);
0564   }
0565 
0566   if (!trailer.check()) {
0567     // error code 8
0568     hFEDFatal->Fill(code.getDDUID());
0569     hCorruptionSummary->Fill(code.getDDUID(), 8);
0570   }
0571 
0572   // check CRC error bit set by DAQ before sending data on SLink
0573   if (data.crcErrorBit()) {
0574     // error code 6
0575     hFEDFatal->Fill(code.getDDUID());
0576     hCorruptionSummary->Fill(code.getDDUID(), 6);
0577   }
0578 
0579   const DTDDUSecondStatusWord& secondWord = data.getSecondStatusWord();
0580 
0581   //2D HISTO: ROS VS STATUS (8 BIT = 8 BIN) from 1st-2nd status words (9th BIN FROM LIST OF ROS in 2nd status word)
0582   MonitorElement* hROSStatus = fedHistos["ROSStatus"][code.getDDUID()];
0583   //1D HISTO: NUMBER OF ROS IN THE EVENTS from 2nd status word
0584 
0585   int rosList = secondWord.rosList();
0586   set<int> rosPositions;
0587   for (int i = 0; i < 12; i++) {
0588     if (rosList & 0x1) {
0589       rosPositions.insert(i);
0590       //9th BIN FROM LIST OF ROS in 2nd status word
0591       hROSStatus->Fill(8, i, 1);
0592     }
0593     rosList >>= 1;
0594   }
0595 
0596   int channel = 0;
0597   for (vector<DTDDUFirstStatusWord>::const_iterator fsw_it = data.getFirstStatusWord().begin();
0598        fsw_it != data.getFirstStatusWord().end();
0599        fsw_it++) {
0600     // assuming association one-to-one between DDU channel and ROS
0601     hROSStatus->Fill(0, channel, (*fsw_it).channelEnabled());
0602     hROSStatus->Fill(1, channel, (*fsw_it).timeout());
0603     hROSStatus->Fill(2, channel, (*fsw_it).eventTrailerLost());
0604     hROSStatus->Fill(3, channel, (*fsw_it).opticalFiberSignalLost());
0605     hROSStatus->Fill(4, channel, (*fsw_it).tlkPropagationError());
0606     hROSStatus->Fill(5, channel, (*fsw_it).tlkPatternError());
0607     hROSStatus->Fill(6, channel, (*fsw_it).tlkSignalLost());
0608     hROSStatus->Fill(7, channel, (*fsw_it).errorFromROS());
0609     // check that the enabled channel was also in the read-out
0610     if ((*fsw_it).channelEnabled() == 1 && rosPositions.find(channel) == rosPositions.end()) {
0611       hROSStatus->Fill(9, channel, 1);
0612       // error code 1
0613       hFEDFatal->Fill(code.getDDUID());
0614       hCorruptionSummary->Fill(code.getDDUID(), 1);
0615     }
0616     channel++;
0617   }
0618 
0619   // ---------------------------------------------------------------------
0620   // cross checks between FED and ROS data
0621   // check the BX ID against the ROSs
0622   set<int> rosBXIds = rosBxIdsPerFED[ddu];
0623   if ((rosBXIds.size() > 1 || rosBXIds.find(header.bxID()) == rosBXIds.end()) &&
0624       !rosBXIds.empty()) {  // in this case look for faulty ROSs
0625     for (vector<DTROS25Data>::const_iterator rosControlData = rosData.begin(); rosControlData != rosData.end();
0626          ++rosControlData) {  // loop over the ROS data
0627       for (vector<DTROSDebugWord>::const_iterator debug_it = (*rosControlData).getROSDebugs().begin();
0628            debug_it != (*rosControlData).getROSDebugs().end();
0629            debug_it++) {                                                                    // Loop over ROS debug words
0630         if ((*debug_it).debugType() == 0 && (*debug_it).debugMessage() != header.bxID()) {  // check the BX
0631           int ros = (*rosControlData).getROSID();
0632           // fill the error bin
0633           hROSStatus->Fill(11, ros - 1);
0634           // error code 2
0635           hFEDFatal->Fill(code.getDDUID());
0636           hCorruptionSummary->Fill(code.getDDUID(), 2);
0637         }
0638       }
0639     }
0640   }
0641 
0642   // check the BX ID against other FEDs
0643   fedBXIds.insert(header.bxID());
0644   if (fedBXIds.size() != 1) {
0645     LogWarning("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0646         << "ERROR: FED " << ddu << " BX ID different from other feds: " << header.bxID() << endl;
0647     // error code 3
0648     hFEDFatal->Fill(code.getDDUID());
0649     hCorruptionSummary->Fill(code.getDDUID(), 3);
0650   }
0651 
0652   // check the L1A ID against the ROSs
0653   set<int> rosL1AIds = rosL1AIdsPerFED[ddu];
0654   if ((rosL1AIds.size() > 1 || rosL1AIds.find(header.lvl1ID() - 1) == rosL1AIds.end()) &&
0655       !rosL1AIds.empty()) {  // in this case look for faulty ROSs
0656     //If L1A_ID error identify which ROS has wrong L1A
0657     for (vector<DTROS25Data>::const_iterator rosControlData = rosData.begin(); rosControlData != rosData.end();
0658          rosControlData++) {  // loop over the ROS data
0659       unsigned int ROSHeader_TTCCount =
0660           ((*rosControlData).getROSHeader().TTCEventCounter() + 1) %
0661           0x1000000;  // fix comparison in case of last counting bin in ROS /first one in DDU
0662       if (ROSHeader_TTCCount != header.lvl1ID()) {
0663         int ros = (*rosControlData).getROSID();
0664         hROSStatus->Fill(10, ros - 1);
0665         // error code 4
0666         hFEDFatal->Fill(code.getDDUID());
0667         hCorruptionSummary->Fill(code.getDDUID(), 4);
0668       }
0669     }
0670   }
0671 
0672   //1D HISTOS: EVENT LENGHT from trailer
0673   int fedEvtLength = trailer.fragmentLength() * 8;
0674   //   if(fedEvtLength > 16000) fedEvtLength = 16000; // overflow bin
0675   fedHistos["EventLength"][code.getDDUID()]->Fill(fedEvtLength);
0676 }
0677 
0678 // log number of times the payload of each fed is unpacked
0679 void DTDataIntegrityROSOffline::fedEntry(int dduID) { hFEDEntry->Fill(dduID); }
0680 
0681 // log number of times the payload of each fed is skipped (no ROS inside)
0682 void DTDataIntegrityROSOffline::fedFatal(int dduID) { hFEDFatal->Fill(dduID); }
0683 
0684 // log number of times the payload of each fed is partially skipped (some ROS skipped)
0685 void DTDataIntegrityROSOffline::fedNonFatal(int dduID) { hFEDNonFatal->Fill(dduID); }
0686 
0687 std::string DTDataIntegrityROSOffline::topFolder(bool isFEDIntegrity) const {
0688   string folder = "DT/00-DataIntegrity/";
0689 
0690   return folder;
0691 }
0692 
0693 void DTDataIntegrityROSOffline::channelsInCEROS(int cerosId, int chMask, vector<int>& channels) {
0694   for (int iCh = 0; iCh < 6; ++iCh) {
0695     if ((chMask >> iCh) & 0x1) {
0696       channels.push_back(cerosId * 6 + iCh);
0697     }
0698   }
0699   return;
0700 }
0701 
0702 void DTDataIntegrityROSOffline::channelsInROS(int cerosMask, vector<int>& channels) {
0703   for (int iCeros = 0; iCeros < 5; ++iCeros) {
0704     if ((cerosMask >> iCeros) & 0x1) {
0705       for (int iCh = 0; iCh < 6; ++iCh) {
0706         channels.push_back(iCeros * 6 + iCh);
0707       }
0708     }
0709   }
0710   return;
0711 }
0712 
0713 void DTDataIntegrityROSOffline::analyze(const edm::Event& e, const edm::EventSetup& c) {
0714   nevents++;
0715   nEventMonitor->Fill(nevents);
0716 
0717   LogTrace("DTRawToDigi|TDQM|DTMonitorModule|DTDataIntegrityROSOffline")
0718       << "[DTDataIntegrityROSOffline]: preProcessEvent" << endl;
0719 
0720   //Legacy ROS
0721   // clear the set of BXids from the ROSs
0722   for (map<int, set<int> >::iterator rosBxIds = rosBxIdsPerFED.begin(); rosBxIds != rosBxIdsPerFED.end(); ++rosBxIds) {
0723     (*rosBxIds).second.clear();
0724   }
0725 
0726   fedBXIds.clear();
0727 
0728   for (map<int, set<int> >::iterator rosL1AIds = rosL1AIdsPerFED.begin(); rosL1AIds != rosL1AIdsPerFED.end();
0729        ++rosL1AIds) {
0730     (*rosL1AIds).second.clear();
0731   }
0732 
0733   // reset the error flag
0734   eventErrorFlag = false;
0735 
0736   // Digi collection
0737   edm::Handle<DTDDUCollection> dduProduct;
0738   e.getByToken(dduToken, dduProduct);
0739   edm::Handle<DTROS25Collection> ros25Product;
0740   e.getByToken(ros25Token, ros25Product);
0741 
0742   DTDDUData dduData;
0743   std::vector<DTROS25Data> ros25Data;
0744   if (dduProduct.isValid() && ros25Product.isValid()) {
0745     for (unsigned int i = 0; i < dduProduct->size(); ++i) {
0746       dduData = dduProduct->at(i);
0747       ros25Data = ros25Product->at(i);
0748       FEDHeader header = dduData.getDDUHeader();
0749       int id = header.sourceID();
0750       if (id > FEDIDmax || id < FEDIDmin)
0751         continue;  //SIM uses extra FEDs not monitored
0752 
0753       processFED(dduData, ros25Data, id);
0754       for (unsigned int j = 0; j < ros25Data.size(); ++j) {
0755         int rosid = j + 1;
0756         processROS25(ros25Data[j], id, rosid);
0757       }
0758     }
0759   }
0760 }
0761 
0762 // Local Variables:
0763 // show-trailing-whitespace: t
0764 // truncate-lines: t
0765 // End: