Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:54:16

0001 /*
0002  * \file DTDataIntegrityTask.cc
0003  *
0004  * Class for DT Data Integrity
0005  * at Online DQM (Single Thread)
0006  * expected to monitor uROS
0007  * Class with MEs vs Time/LS
0008  *
0009  * \author Javier Fernandez (Uni. Oviedo) 
0010  *
0011  */
0012 
0013 #include "DQM/DTMonitorModule/interface/DTDataIntegrityTask.h"
0014 #include "FWCore/Framework/interface/Frameworkfwd.h"
0015 #include "FWCore/Framework/interface/Event.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0017 #include "DQMServices/Core/interface/DQMStore.h"
0018 #include "DQM/DTMonitorModule/interface/DTTimeEvolutionHisto.h"
0019 #include "FWCore/ServiceRegistry/interface/Service.h"
0020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0021 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0022 #include "FWCore/Utilities/interface/Exception.h"
0023 
0024 #include <cmath>
0025 #include <fstream>
0026 #include <map>
0027 #include <string>
0028 #include <vector>
0029 
0030 using namespace std;
0031 using namespace edm;
0032 
0033 DTDataIntegrityTask::DTDataIntegrityTask(const edm::ParameterSet& ps) : nevents(0) {
0034   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask") << "[DTDataIntegrityTask]: Constructor" << endl;
0035 
0036   fedToken = consumes<DTuROSFEDDataCollection>(ps.getUntrackedParameter<InputTag>("dtFEDlabel"));
0037   FEDIDmin = FEDNumbering::MINDTUROSFEDID;
0038   FEDIDmax = FEDNumbering::MAXDTUROSFEDID;
0039 
0040   neventsFED = 0;
0041   neventsuROS = 0;
0042 
0043   fedIntegrityFolder = ps.getUntrackedParameter<string>("fedIntegrityFolder", "DT/FEDIntegrity");
0044   nLinksForFatal = ps.getUntrackedParameter<int>("nLinksForFatal", 15);  //per wheel
0045 
0046   string processingMode = ps.getUntrackedParameter<string>("processingMode", "Online");
0047 
0048   // processing mode flag to select plots to be produced and basedirs CB vedi se farlo meglio...
0049   if (processingMode == "Online") {
0050     mode = 0;
0051   } else if (processingMode == "SM") {
0052     mode = 1;
0053   } else if (processingMode == "Offline") {
0054     mode = 2;
0055   } else if (processingMode == "HLT") {
0056     mode = 3;
0057   } else {
0058     throw cms::Exception("MissingParameter") << "[DTDataIntegrityTask]: processingMode :" << processingMode
0059                                              << " invalid! Must be Online, SM, Offline or HLT !" << endl;
0060   }
0061 }
0062 
0063 DTDataIntegrityTask::~DTDataIntegrityTask() {
0064   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0065       << "[DTDataIntegrityTask]: Destructor. Analyzed " << neventsFED << " events" << endl;
0066   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0067       << "[DTDataIntegrityTask]: postEndJob called!" << endl;
0068 }
0069 
0070 /*
0071   Folder Structure uROS:
0072   - 3 uROS Summary plots: Wheel-1/-2 (FED1369), Wheel0 (FED1370), Wheel+1/+2 (FED1371)
0073   - One folder for each FED
0074   - Inside each FED folder the uROSStatus histos, FED histos
0075   - One folder for each wheel and the corresponding ROSn folders
0076   - Inside each ROS folder the TDC and ROS errors histos, 24 Links/plot
0077 */
0078 
0079 void DTDataIntegrityTask::bookHistograms(DQMStore::IBooker& ibooker,
0080                                          edm::Run const& iRun,
0081                                          edm::EventSetup const& iSetup) {
0082   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask") << "[DTDataIntegrityTask]: postBeginJob" << endl;
0083 
0084   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0085       << "[DTDataIntegrityTask] Get DQMStore service" << endl;
0086 
0087   // Loop over the DT FEDs
0088 
0089   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0090       << " FEDS: " << FEDIDmin << " to " << FEDIDmax << " in the RO" << endl;
0091 
0092   // book FED integrity histos
0093   bookHistos(ibooker, FEDIDmin, FEDIDmax);
0094 
0095   // static booking of the histograms
0096 
0097   if (mode == 0 || mode == 2) {
0098     for (int fed = FEDIDmin; fed <= FEDIDmax; ++fed) {  // loop over the FEDs in the readout
0099 
0100       bookHistos(ibooker, string("FED"), fed);
0101 
0102       bookHistos(ibooker, string("CRATE"), fed);
0103 
0104       for (int uRos = 1; uRos <= NuROS; ++uRos) {  // loop over all ROS
0105         bookHistosuROS(ibooker, fed, uRos);
0106       }
0107     }
0108 
0109     for (int wheel = -2; wheel < 3; ++wheel) {
0110       for (int ros = 1; ros <= NuROS; ++ros) {  // loop over all ROS
0111         bookHistosROS(ibooker, wheel, ros);
0112       }
0113     }
0114 
0115   }  //Not in HLT or SM mode
0116 }
0117 
0118 void DTDataIntegrityTask::bookHistos(DQMStore::IBooker& ibooker, const int fedMin, const int fedMax) {
0119   ibooker.setCurrentFolder("DT/EventInfo/Counters");
0120   nEventMonitor = ibooker.bookFloat("nProcessedEventsDataIntegrity");
0121 
0122   // Standard FED integrity histos
0123   ibooker.setCurrentFolder(topFolder(true));
0124 
0125   int nFED = (fedMax - fedMin) + 1;
0126 
0127   hFEDEntry = ibooker.book1D("FEDEntries", "# entries per DT FED", nFED, fedMin, fedMax + 1);
0128   hFEDFatal = ibooker.book1D("FEDFatal", "# fatal errors DT FED", nFED, fedMin, fedMax + 1);
0129 
0130   if (mode == 1)
0131     return;  // to avoid duplication in FEDIntegrity_EvF folder
0132 
0133   string histoType = "ROSSummary";
0134   for (int wheel = -2; wheel < 3; ++wheel) {
0135     string wheel_s = to_string(wheel);
0136     string histoName = "ROSSummary_W" + wheel_s;
0137     string fed_s = to_string(FEDIDmin + 1);  //3 FEDs from 2018 onwards
0138     if (wheel < 0)
0139       fed_s = to_string(FEDIDmin);
0140     else if (wheel > 0)
0141       fed_s = to_string(FEDIDmax);
0142     string histoTitle = "Summary Wheel" + wheel_s + " (FED " + fed_s + ")";
0143 
0144     ((summaryHistos[histoType])[wheel]) = ibooker.book2D(histoName, histoTitle, 11, 0, 11, 12, 1, 13);
0145     MonitorElement* histo = ((summaryHistos[histoType])[wheel]);
0146     histo->setBinLabel(1, "Error 1", 1);
0147     histo->setBinLabel(2, "Error 2", 1);
0148     histo->setBinLabel(3, "Error 3", 1);
0149     histo->setBinLabel(4, "Error 4", 1);
0150     histo->setBinLabel(5, "Not OKflag", 1);
0151     // TDC error bins
0152     histo->setBinLabel(6, "TDC Fatal", 1);
0153     histo->setBinLabel(7, "TDC RO FIFO ov.", 1);
0154     histo->setBinLabel(8, "TDC L1 buf. ov.", 1);
0155     histo->setBinLabel(9, "TDC L1A FIFO ov.", 1);
0156     histo->setBinLabel(10, "TDC hit err.", 1);
0157     histo->setBinLabel(11, "TDC hit rej.", 1);
0158 
0159     histo->setBinLabel(1, "Sector1", 2);
0160     histo->setBinLabel(2, "Sector2", 2);
0161     histo->setBinLabel(3, "Sector3", 2);
0162     histo->setBinLabel(4, "Sector4", 2);
0163     histo->setBinLabel(5, "Sector5", 2);
0164     histo->setBinLabel(6, "Sector6", 2);
0165     histo->setBinLabel(7, "Sector7", 2);
0166     histo->setBinLabel(8, "Sector8", 2);
0167     histo->setBinLabel(9, "Sector9", 2);
0168     histo->setBinLabel(10, "Sector10", 2);
0169     histo->setBinLabel(11, "Sector11", 2);
0170     histo->setBinLabel(12, "Sector12", 2);
0171   }
0172 }
0173 
0174 void DTDataIntegrityTask::bookHistos(DQMStore::IBooker& ibooker, string folder, const int fed) {
0175   string wheel = "ZERO";
0176   if (fed == FEDIDmin)
0177     wheel = "NEG";
0178   else if (fed == FEDIDmax)
0179     wheel = "POS";
0180   string fed_s = to_string(fed);
0181   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0182       << " Booking histos for FED: " << fed_s << " folder: " << folder << endl;
0183 
0184   string histoType;
0185   string histoName;
0186   string histoTitle;
0187   MonitorElement* histo = nullptr;
0188 
0189   // Crate (old DDU) Histograms
0190   if (folder == "CRATE") {
0191     ibooker.setCurrentFolder(topFolder(false) + "FED" + fed_s);
0192 
0193     histoType = "EventLength";
0194     histoName = "FED" + fed_s + "_" + histoType;
0195     histoTitle = "Event Length (Bytes) FED " + fed_s;
0196     (fedHistos[histoType])[fed] = ibooker.book1D(histoName, histoTitle, 501, 0, 30000);
0197 
0198     if (mode == 3 || mode == 1)
0199       return;  //Avoid duplication of Info in FEDIntegrity_EvF
0200 
0201     histoType = "uROSStatus";
0202     histoName = "FED" + fed_s + "_" + histoType;
0203     (fedHistos[histoType])[fed] = ibooker.book2D(histoName, histoName, 12, 0, 12, 12, 1, 13);
0204     histo = (fedHistos[histoType])[fed];
0205     // only placeholders for the moment
0206     histo->setBinLabel(1, "Error G 1", 1);
0207     histo->setBinLabel(2, "Error G 2", 1);
0208     histo->setBinLabel(3, "Error G 3", 1);
0209     histo->setBinLabel(4, "Error G 4", 1);
0210     histo->setBinLabel(5, "Error G 5", 1);
0211     histo->setBinLabel(6, "Error G 6", 1);
0212     histo->setBinLabel(7, "Error G 7", 1);
0213     histo->setBinLabel(8, "Error G 8", 1);
0214     histo->setBinLabel(9, "Error G 9", 1);
0215     histo->setBinLabel(10, "Error G 10", 1);
0216     histo->setBinLabel(11, "Error G 11", 1);
0217     histo->setBinLabel(12, "Error G 12", 1);
0218 
0219     histo->setBinLabel(1, "uROS 1", 2);
0220     histo->setBinLabel(2, "uROS 2", 2);
0221     histo->setBinLabel(3, "uROS 3", 2);
0222     histo->setBinLabel(4, "uROS 4", 2);
0223     histo->setBinLabel(5, "uROS 5", 2);
0224     histo->setBinLabel(6, "uROS 6", 2);
0225     histo->setBinLabel(7, "uROS 7", 2);
0226     histo->setBinLabel(8, "uROS 8", 2);
0227     histo->setBinLabel(9, "uROS 9", 2);
0228     histo->setBinLabel(10, "uROS 10", 2);
0229     histo->setBinLabel(11, "uROS 11", 2);
0230     histo->setBinLabel(12, "uROS 12", 2);
0231 
0232     if (mode == 0) {  //Info for Online only
0233 
0234       histoType = "FEDAvgEvLengthvsLumi";
0235       histoName = "FED" + fed_s + "_" + histoType;
0236       histoTitle = "Avg Event Length (Bytes) vs LumiSec FED " + fed_s;
0237       (fedTimeHistos[histoType])[fed] = new DTTimeEvolutionHisto(ibooker, histoName, histoTitle, 200, 10, true, 0);
0238 
0239       //Not used for the moment due to wrong coding from AMC13
0240       /*
0241     histoType = "TTSValues";
0242     histoName = "FED" + fed_s + "_" + histoType;
0243     (fedHistos[histoType])[fed] = ibooker.book1D(histoName, histoName, 6, 0, 6);
0244     histo = (fedHistos[histoType])[fed];
0245     histo->setBinLabel(1, "Ready", 1);
0246     histo->setBinLabel(2, "Overflow Warning ", 1);
0247     histo->setBinLabel(3, "Busy", 1);
0248     histo->setBinLabel(4, "Sync lost", 1);
0249     histo->setBinLabel(5, "Error", 1);
0250     histo->setBinLabel(6, "Unknown", 1);
0251     */
0252       histoType = "uROSList";
0253       histoName = "FED" + fed_s + "_" + histoType;
0254       histoTitle = "# of uROS in the FED payload (FED" + fed_s + ")";
0255       (fedHistos[histoType])[fed] = ibooker.book1D(histoName, histoTitle, 13, 0, 13);
0256 
0257       histoType = "BXID";
0258       histoName = "FED" + fed_s + "_BXID";
0259       histoTitle = "Distrib. BX ID (FED" + fed_s + ")";
0260       (fedHistos[histoType])[fed] = ibooker.book1D(histoName, histoTitle, 3600, 0, 3600);
0261     }  // mode == 0 for Online only
0262   }
0263 
0264   // uROS Histograms
0265   if (folder == "FED") {  // The summary of the error of the ROS on the same FED
0266     ibooker.setCurrentFolder(topFolder(false));
0267 
0268     if (mode == 3 || mode == 1)
0269       return;  //Avoid duplication of Info in FEDIntegrity_EvF
0270 
0271     histoType = "uROSSummary";
0272     histoName = "FED" + fed_s + "_uROSSummary";
0273     string histoTitle = "Summary Wheel" + wheel + " (FED " + fed_s + ")";
0274 
0275     ((summaryHistos[histoType])[fed]) = ibooker.book2D(histoName, histoTitle, 12, 0, 12, 12, 1, 13);
0276     MonitorElement* histo = ((summaryHistos[histoType])[fed]);
0277     // ROS error bins
0278     // Placeholders for Global Errors for the moment
0279     histo->setBinLabel(1, "Error G 1", 1);
0280     histo->setBinLabel(2, "Error G 2", 1);
0281     histo->setBinLabel(3, "Error G 3", 1);
0282     histo->setBinLabel(4, "Error G 4", 1);
0283     histo->setBinLabel(5, "Error G 5", 1);
0284     histo->setBinLabel(6, "Error G 6", 1);
0285     histo->setBinLabel(7, "Error G 7", 1);
0286     histo->setBinLabel(8, "Error G 8", 1);
0287     histo->setBinLabel(9, "Error G 9", 1);
0288     histo->setBinLabel(10, "Error G 10", 1);
0289     histo->setBinLabel(11, "Error G 11", 1);
0290     histo->setBinLabel(12, "Error G 12", 1);
0291 
0292     histo->setBinLabel(1, "uROS1", 2);
0293     histo->setBinLabel(2, "uROS2", 2);
0294     histo->setBinLabel(3, "uROS3", 2);
0295     histo->setBinLabel(4, "uROS4", 2);
0296     histo->setBinLabel(5, "uROS5", 2);
0297     histo->setBinLabel(6, "uROS6", 2);
0298     histo->setBinLabel(7, "uROS7", 2);
0299     histo->setBinLabel(8, "uROS8", 2);
0300     histo->setBinLabel(9, "uROS9", 2);
0301     histo->setBinLabel(10, "uROS10", 2);
0302     histo->setBinLabel(11, "uROS11", 2);
0303     histo->setBinLabel(12, "uROS12", 2);
0304   }
0305 }
0306 
0307 void DTDataIntegrityTask::bookHistosROS(DQMStore::IBooker& ibooker, const int wheel, const int ros) {
0308   string wheel_s = to_string(wheel);
0309   string ros_s = to_string(ros);
0310   ibooker.setCurrentFolder(topFolder(false) + "Wheel" + wheel_s + "/Sector" + ros_s);
0311 
0312   string histoType = "ROSError";
0313   int linkDown = 0;
0314   string linkDown_s = to_string(linkDown);
0315   int linkUp = linkDown + 24;
0316   string linkUp_s = to_string(linkUp);
0317   string histoName = "W" + wheel_s + "_" + "Sector" + ros_s + "_" + histoType;
0318   string histoTitle = histoName + " (Channel " + linkDown_s + "-" + linkUp_s + " error summary)";
0319   unsigned int keyHisto = (uROSError)*1000 + (wheel + 2) * 100 + (ros - 1);
0320   if (mode < 1)  // Online only
0321     urosHistos[keyHisto] = ibooker.book2D(histoName, histoTitle, 11, 0, 11, 25, 0, 25);
0322   else if (mode > 1)
0323     urosHistos[keyHisto] = ibooker.book2D(histoName, histoTitle, 5, 0, 5, 25, 0, 25);
0324 
0325   MonitorElement* histo = urosHistos[keyHisto];
0326   // uROS error bins
0327   // Placeholders for the moment
0328   histo->setBinLabel(1, "Error 1", 1);
0329   histo->setBinLabel(2, "Error 2", 1);
0330   histo->setBinLabel(3, "Error 3", 1);
0331   histo->setBinLabel(4, "Error 4", 1);
0332   histo->setBinLabel(5, "Not OKFlag", 1);
0333   if (mode < 1) {  //Online only
0334                    // TDC error bins
0335     histo->setBinLabel(6, "TDC Fatal", 1);
0336     histo->setBinLabel(7, "TDC RO FIFO ov.", 1);
0337     histo->setBinLabel(8, "TDC L1 buf. ov.", 1);
0338     histo->setBinLabel(9, "TDC L1A FIFO ov.", 1);
0339     histo->setBinLabel(10, "TDC hit err.", 1);
0340     histo->setBinLabel(11, "TDC hit rej.", 1);
0341   }
0342   for (int link = linkDown; link < linkUp; ++link) {
0343     int sector = ros;
0344 
0345     int station = int(link / 6) + 1;
0346     if (link == 18)
0347       station = 3;
0348 
0349     int rob = link % 6;
0350     if (link == 18)
0351       rob = 6;
0352     else if (link > 18)
0353       rob = rob - 1;
0354 
0355     //Sector 4 exceptions
0356     if (ros == 4) {
0357       if (link > 18 && link < 22)
0358         rob = rob + 2;
0359       else if (link == 22 || link == 23) {
0360         sector = 13;
0361         rob = rob - 1;
0362       }
0363     }
0364 
0365     //Sector 9 exceptions
0366     if (ros == 9 && (link == 22 || link == 23)) {
0367       sector = 13;
0368       rob = rob - 3;
0369     }
0370 
0371     //Sector 10 exceptions
0372     if (ros == 10) {
0373       if (link > 18 && link < 22)
0374         sector = 14;
0375       else if (link == 22 || link == 23)
0376         rob = rob - 3;
0377     }
0378 
0379     //Sector 11 exceptions
0380     if (ros == 11 && (link == 22 || link == 23)) {
0381       sector = 4;
0382       rob = rob - 3;
0383     }
0384 
0385     string sector_s = to_string(sector);
0386     string st_s = to_string(station);
0387     string rob_s = to_string(rob);
0388     histo->setBinLabel(link + 1, "S" + sector_s + " MB" + st_s + " ROB" + rob_s, 2);
0389   }
0390 
0391   int link25 = linkUp;
0392   string label25[12] = {"S1 MB4 ROB5",
0393                         "S2 MB4 ROB5",
0394                         "S3 MB4 ROB5",
0395                         "S13 MB4 ROB4",
0396                         "S5 MB4 ROB5",
0397                         "S6 MB4 ROB5",
0398                         "S7 MB4 ROB5",
0399                         "S8 MB4 ROB5",
0400                         "S10 MB4 ROB3",
0401                         "S10 MB4 ROB2",
0402                         "S14 MB4 ROB3",
0403                         "S12 MB4 ROB5"};
0404   histo->setBinLabel(link25 + 1, label25[ros - 1], 2);
0405 
0406   if (mode > 1)
0407     return;
0408 
0409   histoType = "TDCError";
0410   linkDown = 0;
0411   linkDown_s = to_string(linkDown);
0412   linkUp = linkDown + 24;
0413   linkUp_s = to_string(linkUp);
0414   histoName = "W" + wheel_s + "_" + "Sector" + ros_s + "_" + histoType;
0415   histoTitle = histoName + " (Channel " + linkDown_s + "-" + linkUp_s + " error summary)";
0416   keyHisto = (TDCError)*1000 + (wheel + 2) * 100 + (ros - 1);
0417   urosHistos[keyHisto] = ibooker.book2D(histoName, histoTitle, 24, 0, 24, 25, 0, 25);
0418   histo = urosHistos[keyHisto];
0419   // TDC error bins
0420   histo->setBinLabel(1, "Fatal", 1);
0421   histo->setBinLabel(2, "RO FIFO ov.", 1);
0422   histo->setBinLabel(3, "L1 buf. ov.", 1);
0423   histo->setBinLabel(4, "L1A FIFO ov.", 1);
0424   histo->setBinLabel(5, "hit err.", 1);
0425   histo->setBinLabel(6, "hit rej.", 1);
0426   histo->setBinLabel(7, "Fatal", 1);
0427   histo->setBinLabel(8, "RO FIFO ov.", 1);
0428   histo->setBinLabel(9, "L1 buf. ov.", 1);
0429   histo->setBinLabel(10, "L1A FIFO ov.", 1);
0430   histo->setBinLabel(11, "hit err.", 1);
0431   histo->setBinLabel(12, "hit rej.", 1);
0432   histo->setBinLabel(13, "Fatal", 1);
0433   histo->setBinLabel(14, "RO FIFO ov.", 1);
0434   histo->setBinLabel(15, "L1 buf. ov.", 1);
0435   histo->setBinLabel(16, "L1A FIFO ov.", 1);
0436   histo->setBinLabel(17, "hit err.", 1);
0437   histo->setBinLabel(18, "hit rej.", 1);
0438   histo->setBinLabel(19, "Fatal", 1);
0439   histo->setBinLabel(20, "RO FIFO ov.", 1);
0440   histo->setBinLabel(21, "L1 buf. ov.", 1);
0441   histo->setBinLabel(22, "L1A FIFO ov.", 1);
0442   histo->setBinLabel(23, "hit err.", 1);
0443   histo->setBinLabel(24, "hit rej.", 1);
0444 
0445   for (int link = linkDown; link < linkUp; ++link) {
0446     int sector = ros;
0447 
0448     int station = int(link / 6) + 1;
0449     if (link == 18)
0450       station = 3;
0451 
0452     int rob = link % 6;
0453     if (link == 18)
0454       rob = 6;
0455     else if (link > 18)
0456       rob = rob - 1;
0457 
0458     //Sector 4 exceptions
0459     if (ros == 4) {
0460       if (link > 18 && link < 22)
0461         rob = rob + 2;
0462       else if (link == 22 || link == 23) {
0463         sector = 13;
0464         rob = rob - 1;
0465       }
0466     }
0467 
0468     //Sector 9 exceptions
0469     if (ros == 9 && (link == 22 || link == 23))
0470       rob = rob - 3;
0471 
0472     //Sector 10 exceptions
0473     if (ros == 10) {
0474       if (link > 18 && link < 22)
0475         sector = 14;
0476       else if (link == 22 || link == 23)
0477         rob = rob - 3;
0478     }
0479 
0480     //Sector 11 exceptions
0481     if (ros == 11 && (link == 22 || link == 23)) {
0482       sector = 4;
0483       rob = rob - 3;
0484     }
0485 
0486     string sector_s = to_string(sector);
0487     string st_s = to_string(station);
0488     string rob_s = to_string(rob);
0489     histo->setBinLabel(link + 1, "S" + sector_s + " MB" + st_s + " ROB" + rob_s, 2);
0490   }
0491 
0492   link25 = linkUp;
0493   histo->setBinLabel(link25 + 1, label25[ros - 1], 2);
0494 
0495 }  //bookHistosROS
0496 
0497 void DTDataIntegrityTask::bookHistosuROS(DQMStore::IBooker& ibooker, const int fed, const int uRos) {
0498   string fed_s = to_string(fed);
0499   string uRos_s = to_string(uRos);
0500   ibooker.setCurrentFolder(topFolder(false) + "FED" + fed_s + "/uROS" + uRos_s);
0501 
0502   if (mode >= 1)
0503     return;
0504 
0505   string histoType = "uROSEventLength";
0506   string histoName = "FED" + fed_s + "_uROS" + uRos_s + "_" + "EventLength";
0507   string histoTitle = "Event Length (Bytes) FED " + fed_s + " uROS" + uRos_s;
0508   unsigned int keyHisto = (uROSEventLength)*1000 + (fed - FEDIDmin) * 100 + (uRos - 1);
0509   urosHistos[keyHisto] = ibooker.book1D(histoName, histoTitle, 101, 0, 5000);
0510 
0511   histoType = "uROSAvgEventLengthvsLumi";
0512   histoName = "FED" + fed_s + "_ROS" + uRos_s + "AvgEventLengthvsLumi";
0513   histoTitle = "Event Length (Bytes) FED " + fed_s + " ROS" + uRos_s;
0514   keyHisto = (fed - FEDIDmin) * 100 + (uRos - 1);
0515   urosTimeHistos[keyHisto] = new DTTimeEvolutionHisto(ibooker, histoName, histoTitle, 200, 10, true, 0);
0516 
0517   histoType = "TTSValues";
0518   histoName = "FED" + fed_s + "_" + "uROS" + uRos_s + "_" + histoType;
0519   keyHisto = TTSValues * 1000 + (fed - FEDIDmin) * 100 + (uRos - 1);
0520   urosHistos[keyHisto] = ibooker.book1D(histoName, histoName, 4, 1, 5);
0521   MonitorElement* histo = urosHistos[keyHisto];
0522   histo->setBinLabel(1, "Overflow Warning ", 1);
0523   histo->setBinLabel(2, "Busy", 1);
0524   histo->setBinLabel(3, "Ready", 1);
0525   histo->setBinLabel(4, "Unknown", 1);
0526 }
0527 
0528 void DTDataIntegrityTask::processuROS(DTuROSROSData& data, int fed, int uRos) {
0529   neventsuROS++;
0530 
0531   LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0532       << "[DTDataIntegrityTask]: " << neventsuROS << " events analyzed by processuROS" << endl;
0533 
0534   if (mode == 3)  // || mode == 1)
0535     return;       //Avoid duplication of Info in FEDIntegrity_EvF
0536 
0537   MonitorElement* uROSSummary = nullptr;
0538   MonitorElement* uROSStatus = nullptr;
0539 
0540   unsigned int slotMap = (data.getboardId()) & 0xF;
0541   if (slotMap == 0)
0542     return;                               //prevention for Simulation empty uROS data
0543   unsigned int ros = theROS(slotMap, 0);  //first sector correspondign to link 0
0544   int ddu = theDDU(fed, slotMap, 0, false);
0545   int wheel = (ddu - 770) % 5 - 2;
0546   int sector4 = 3;  //Asymmetry  in mapping
0547 
0548   MonitorElement* ROSSummary = nullptr;
0549   ROSSummary = summaryHistos["ROSSummary"][wheel];
0550 
0551   // Summary of all Link errors
0552   MonitorElement* uROSError0 = nullptr;
0553   MonitorElement* uROSError1 = nullptr;
0554   MonitorElement* uROSError2 = nullptr;
0555   MonitorElement* uROSErrorS4 = nullptr;
0556 
0557   if (mode <= 2) {
0558     if (uRos > 2) {  //sectors 1-12
0559       if (mode != 1) {
0560         uROSSummary = summaryHistos["uROSSummary"][fed];
0561         uROSStatus = fedHistos["uROSStatus"][fed];
0562         if (!uROSSummary) {
0563           LogError("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0564               << "Trying to access non existing ME at FED " << fed << std::endl;
0565           return;
0566         }
0567 
0568         uROSError0 = urosHistos[(uROSError)*1000 + (wheel + 2) * 100 + (ros - 1)];  //links 0-23
0569         uROSError1 = urosHistos[(uROSError)*1000 + (wheel + 2) * 100 + (ros)];      //links 24-47
0570         uROSError2 = urosHistos[(uROSError)*1000 + (wheel + 2) * 100 + (ros + 1)];  //links 48-71
0571         uROSErrorS4 = urosHistos[(uROSError)*1000 + (wheel + 2) * 100 + 3];
0572 
0573         if ((!uROSError2) || (!uROSError1) || (!uROSError0)) {
0574           LogError("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0575               << "Trying to access non existing ME at uROS " << uRos << std::endl;
0576           return;
0577         }
0578       }
0579 
0580       // uROS errors
0581       for (unsigned int link = 0; link < 72; ++link) {
0582         for (unsigned int flag = 0; flag < 5; ++flag) {
0583           if ((data.getokxflag(link) >> flag) & 0x1) {  // Undefined Flag 1-4 64bits word for each MTP (12 channels)
0584             int value = flag;
0585 
0586             if (flag == 0)
0587               value = 5;  //move it to the 5th bin
0588 
0589             if (value > 0) {
0590               if (link < 24) {
0591                 errorX[value - 1][ros - 1][wheel + 2] += 1;
0592                 if (mode != 1)
0593                   uROSError0->Fill(value - 1, link);  //bins start at 0 despite labeling
0594               } else if (link < 48) {
0595                 if ((link == 46 || link == 57) && ros == 10)
0596                   errorX[value - 1][sector4][wheel + 2] += 1;
0597                 else
0598                   errorX[value - 1][ros][wheel + 2] += 1;
0599                 if (mode != 1) {
0600                   if ((link == 46 || link == 57) && ros == 10)
0601                     uROSErrorS4->Fill(value - 1, link - 24);
0602                   else
0603                     uROSError1->Fill(value - 1, link - 24);
0604                 }
0605               } else if (link < 72) {
0606                 errorX[value - 1][ros + 1][wheel + 2] += 1;
0607                 if (mode != 1)
0608                   uROSError2->Fill(value - 1, link - 48);
0609               }
0610             }  //value>0
0611           }    //flag value
0612         }      //loop on flags
0613       }        //loop on links
0614     }          //uROS>2
0615 
0616     else {  //uRos<3  25th Channel slot
0617 
0618       for (unsigned int link = 0; link < 12; ++link) {
0619         for (unsigned int flag = 0; flag < 5; ++flag) {
0620           if ((data.getokxflag(link) >> flag) & 0x1) {  // Undefined Flag 1-4 64bits word for each MTP (12 channels)
0621             int value = flag;
0622             int ch25 = 24;
0623             int sector = link + 1;
0624             if (flag == 0)
0625               value = 5;  //move it to the 5th bin
0626 
0627             if (value > 0) {
0628               if (mode != 1) {
0629                 if (sector == 9)
0630                   sector = 10;
0631                 unsigned int keyHisto =
0632                     (uROSError)*1000 + (wheel + 2) * 100 + abs(sector - 1);  //ros -1 = link in this case
0633                 uROSError0 = urosHistos[keyHisto];
0634                 if (!uROSError0) {
0635                   LogError("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0636                       << "Trying to access non existing ME at uROS " << uRos << std::endl;
0637                   return;
0638                 }
0639               }
0640               errorX[value - 1][sector - 1][wheel + 2] += 1;  // ros-1=link in this case
0641               if (mode != 1)
0642                 uROSError0->Fill(value - 1, ch25);  //bins start at 0 despite labeling, this is the old SC
0643             }
0644           }  //flag values
0645         }    //loop on flags
0646       }      //loop on links
0647     }        //else uRos<3
0648 
0649   }  //mode<=2
0650 
0651   if (mode != 1) {
0652     // Fill the ROSSummary (1 per wheel) histo
0653     for (unsigned int iros = ros - 1; iros < (ros + 2); ++iros) {
0654       for (unsigned int bin = 0; bin < 5; ++bin) {
0655         if (errorX[bin][iros][wheel + 2] != 0) {
0656           ROSSummary->Fill(bin, iros + 1, errorX[bin][iros][wheel + 2]);  //bins start at 1
0657         }
0658       }
0659     }
0660 
0661     // Global Errors for uROS
0662     for (unsigned int flag = 4; flag < 16; ++flag) {
0663       if ((data.getuserWord() >> flag) & 0x1) {
0664         uROSSummary->Fill(flag - 4, uRos);
0665         uROSStatus->Fill(flag - 4, uRos);  //duplicated info?
0666       }
0667     }
0668   }
0669 
0670   // ROS error
0671   for (unsigned int icounter = 0; icounter < data.geterrors().size(); ++icounter) {
0672     int link = data.geterrorROBID(icounter);
0673     int tdc = data.geterrorTDCID(icounter);
0674     int error = data.geterror(icounter);
0675     int tdcError_ROSSummary = 0;
0676     int tdcError_ROSError = 0;
0677     int tdcError_TDCHisto = 0;
0678 
0679     if (error & 0x4000) {
0680       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0681           << " ROS " << uRos << " ROB " << link << " Internal fatal Error 4000 in TDC " << error << endl;
0682 
0683       tdcError_ROSSummary = 5;
0684       tdcError_ROSError = 5;
0685       tdcError_TDCHisto = 0;
0686 
0687     } else if (error & 0x0249) {
0688       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0689           << " ROS " << uRos << " ROB " << link << " TDC FIFO overflow in TDC " << error << endl;
0690 
0691       tdcError_ROSSummary = 6;
0692       tdcError_ROSError = 6;
0693       tdcError_TDCHisto = 1;
0694 
0695     } else if (error & 0x0492) {
0696       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0697           << " ROS " << uRos << " ROB " << link << " TDC L1 buffer overflow in TDC " << error << endl;
0698 
0699       tdcError_ROSSummary = 7;
0700       tdcError_ROSError = 7;
0701       tdcError_TDCHisto = 2;
0702 
0703     } else if (error & 0x2000) {
0704       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0705           << " ROS " << uRos << " ROB " << link << " TDC L1A FIFO overflow in TDC " << error << endl;
0706 
0707       tdcError_ROSSummary = 8;
0708       tdcError_ROSError = 8;
0709       tdcError_TDCHisto = 3;
0710 
0711     } else if (error & 0x0924) {
0712       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0713           << " uROS " << uRos << " ROB " << link << " TDC hit error in TDC " << error << endl;
0714 
0715       tdcError_ROSSummary = 9;
0716       tdcError_ROSError = 9;
0717       tdcError_TDCHisto = 4;
0718 
0719     } else if (error & 0x1000) {
0720       LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0721           << " uROS " << uRos << " ROB " << link << " TDC hit rejected in TDC " << error << endl;
0722 
0723       tdcError_ROSSummary = 10;
0724       tdcError_ROSError = 10;
0725       tdcError_TDCHisto = 5;
0726 
0727     } else {
0728       LogWarning("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0729           << " TDC error code not known " << error << endl;
0730     }
0731 
0732     if (uRos < 3) {
0733       int sector = link + 1;
0734       if (tdcError_ROSSummary == 5)
0735         errorX[5][link][wheel + 2] += 1;
0736       if (mode != 1) {
0737         if (sector == 9)
0738           sector = 10;
0739         ROSSummary->Fill(tdcError_ROSSummary, sector - 1);  //link 0 = ROS 1
0740         int ch25 = 24;
0741         if (mode <= 2) {
0742           urosHistos[(uROSError)*1000 + (wheel + 2) * 100 + (sector - 1)]->Fill(tdcError_ROSError, ch25);
0743           if (mode < 1)
0744             urosHistos[(TDCError)*1000 + (wheel + 2) * 100 + (sector - 1)]->Fill(tdcError_TDCHisto + 6 * tdc,
0745                                                                                  ch25);  // ros-1=link in this case
0746         }                                                                                //mode <= 2
0747       }                                                                                  //mode!=1
0748     }                                                                                    //uRos<3
0749     else {                                                                               //uRos>2
0750       if (link < 24) {
0751         if (tdcError_ROSSummary == 5)
0752           errorX[5][ros - 1][wheel + 2] += 1;
0753         if (mode != 1)
0754           ROSSummary->Fill(tdcError_ROSSummary, ros);
0755       } else if (link < 48) {
0756         if (tdcError_ROSSummary == 5) {
0757           if ((link == 46 || link == 57) && ros == 10)
0758             errorX[5][sector4][wheel + 2] += 1;
0759           else
0760             errorX[5][ros][wheel + 2] += 1;
0761         }
0762         if (mode != 1) {
0763           if ((link == 46 || link == 57) && ros == 10)
0764             ROSSummary->Fill(tdcError_ROSSummary, sector4);
0765           else
0766             ROSSummary->Fill(tdcError_ROSSummary, ros + 1);
0767         }
0768       } else if (link < 72) {
0769         if (tdcError_ROSSummary == 5)
0770           errorX[5][ros + 1][wheel + 2] += 1;
0771         if (mode != 1)
0772           ROSSummary->Fill(tdcError_ROSSummary, ros + 2);
0773       }
0774 
0775       if (mode <= 2 && mode != 1) {
0776         if (link < 24)
0777           uROSError0->Fill(tdcError_ROSError, link);
0778         else if (link < 48)
0779           if ((link == 46 || link == 57) && ros == 10)
0780             uROSError1->Fill(tdcError_ROSError, sector4);
0781           else
0782             uROSError1->Fill(tdcError_ROSError, link - 24);
0783         else if (link < 72)
0784           uROSError2->Fill(tdcError_ROSError, link - 48);
0785 
0786         if (mode < 1) {
0787           if (link < 24)
0788             urosHistos[(TDCError)*1000 + (wheel + 2) * 100 + (ros - 1)]->Fill(tdcError_TDCHisto + 6 * tdc, link);
0789           else if (link < 48)
0790             urosHistos[(TDCError)*1000 + (wheel + 2) * 100 + (ros)]->Fill(tdcError_TDCHisto + 6 * tdc, link - 24);
0791           else if (link < 72)
0792             urosHistos[(TDCError)*1000 + (wheel + 2) * 100 + (ros + 1)]->Fill(tdcError_TDCHisto + 6 * tdc, link - 48);
0793 
0794         }  //mode<1
0795       }    //mode<=2 && mode != 1
0796     }      //uROS>2
0797   }        //loop on errors
0798 
0799   // 1D histograms for TTS values per uROS
0800   if (mode < 1) {
0801     int ttsCodeValue = -1;
0802     int value = (data.getuserWord() & 0xF);
0803     switch (value) {
0804       case 1: {  //warning overflow
0805         ttsCodeValue = 1;
0806         break;
0807       }
0808       case 4: {  //busy
0809         ttsCodeValue = 2;
0810         break;
0811       }
0812       case 8: {  //ready
0813         ttsCodeValue = 3;
0814         break;
0815       }
0816       default: {
0817         LogError("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0818             << "[DTDataIntegrityTask] FED User control: wrong TTS value " << value << " in FED " << fed << " uROS "
0819             << uRos << endl;
0820         ttsCodeValue = 4;
0821       }
0822     }
0823 
0824     urosHistos[TTSValues * 1000 + (fed - FEDIDmin) * 100 + (uRos - 1)]->Fill(ttsCodeValue);
0825 
0826     // Plot the event length //NOHLT
0827     int uRosEventLength = (data.gettrailer() & 0xFFFFF) * 8;
0828     urosTimeHistos[(fed - FEDIDmin) * 100 + (uRos - 1)]->accumulateValueTimeSlot(uRosEventLength);
0829 
0830     if (uRosEventLength > 5000)
0831       uRosEventLength = 5000;
0832     urosHistos[uROSEventLength * 1000 + (fed - FEDIDmin) * 100 + (uRos - 1)]->Fill(uRosEventLength);
0833   }
0834 }
0835 
0836 void DTDataIntegrityTask::processFED(DTuROSFEDData& data, int fed) {
0837   neventsFED++;
0838   if (neventsFED % 1000 == 0)
0839     LogTrace("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0840         << "[DTDataIntegrityTask]: " << neventsFED << " events analyzed by processFED" << endl;
0841 
0842   if (fed < FEDIDmin || fed > FEDIDmax)
0843     return;
0844 
0845   hFEDEntry->Fill(fed);
0846 
0847   if (mode == 3)
0848     return;  //Avoid duplication of Info in FEDIntegrity_EvF
0849 
0850   if (mode != 1) {
0851     //1D HISTOS: EVENT LENGHT from trailer
0852     int fedEvtLength = data.getevtlgth() * 8;  //1 word = 8 bytes
0853     //   if(fedEvtLength > 16000) fedEvtLength = 16000; // overflow bin
0854     fedHistos["EventLength"][fed]->Fill(fedEvtLength);
0855 
0856     if (mode == 0) {
0857       fedTimeHistos["FEDAvgEvLengthvsLumi"][fed]->accumulateValueTimeSlot(fedEvtLength);
0858 
0859       // fill the distribution of the BX ids
0860       fedHistos["BXID"][fed]->Fill(data.getBXId());
0861 
0862       // size of the list of ROS in the Read-Out
0863       fedHistos["uROSList"][fed]->Fill(data.getnslots());
0864     }
0865 
0866   }  //mode != 1
0867 
0868   // Fill the status summary of the TTS
0869 
0870   //1D HISTO WITH TTS VALUES form trailer
0871   //Not used for the moment due to wrong coding from AMC13
0872   /*
0873   int ttsCodeValue = -1;
0874   int value = data.getTTS();
0875   switch (value) {
0876     case 0: {  //ready
0877       ttsCodeValue = 0;
0878       break;
0879     }
0880     case 1: {  //warning overflow
0881       ttsCodeValue = 1;
0882       break;
0883     }
0884     case 2: {  //busy
0885       ttsCodeValue = 2;
0886       break;
0887     }
0888     case 4: {  //synch lost
0889       ttsCodeValue = 3;
0890       break;
0891     }
0892     case 8: {  //error
0893       ttsCodeValue = 4;
0894       break;
0895     }
0896     default: {
0897       LogError("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0898           << "[DTDataIntegrityTask] FED TTS control: wrong TTS value " << value << " in FED " << fed << endl;
0899       ttsCodeValue = 5;
0900     }
0901   }
0902   if (mode < 1)
0903     fedHistos["TTSValues"][fed]->Fill(ttsCodeValue);
0904   */
0905 
0906   //FEDFatal definition per wheel: 5*TDCFatal/6000 + 5*NotOKFlag/1500
0907   int wheel = 0;
0908   if (fed == FEDIDmin)
0909     wheel = -2;
0910   else if (fed == FEDIDmax)
0911     wheel = 1;
0912 
0913   float sumTDC = 0., sumNotOKFlag = 0.;
0914   for (int ros = 0; ros < 12; ros++) {
0915     sumNotOKFlag += errorX[4][ros][wheel + 2];
0916     sumTDC += errorX[5][ros][wheel + 2];
0917   }
0918 
0919   if (wheel != 0) {  // consider both wheels for FEDs 1369 & 1371
0920     wheel += 1;
0921     for (int ros = 0; ros < 12; ros++) {
0922       sumNotOKFlag += errorX[4][ros][wheel + 2];
0923       sumTDC += errorX[5][ros][wheel + 2];
0924     }
0925   }
0926 
0927   //Divide by 2 for egde FEDs to normalize per wheel
0928   sumNotOKFlag = sumNotOKFlag / ((wheel != 0) ? 2. : 1.);
0929   sumTDC = sumTDC / ((wheel != 0) ? 2. : 1.);
0930 
0931   if (sumNotOKFlag > nLinksForFatal || sumTDC > nLinksForFatal)
0932     hFEDFatal->Fill(fed);
0933 }
0934 
0935 std::string DTDataIntegrityTask::topFolder(bool isFEDIntegrity) const {
0936   string folder = isFEDIntegrity ? fedIntegrityFolder : "DT/00-DataIntegrity/";
0937 
0938   if (mode == 0)
0939     folder = "DT/00-DataIntegrity/";  //Move everything from FEDIntegrity except for SM and HLT modes
0940 
0941   return folder;
0942 }
0943 
0944 std::shared_ptr<dtdi::Void> DTDataIntegrityTask::globalBeginLuminosityBlock(const edm::LuminosityBlock& ls,
0945                                                                             const edm::EventSetup& es) const {
0946   nEventsLS = 0;
0947   return std::shared_ptr<dtdi::Void>();
0948 }
0949 
0950 void DTDataIntegrityTask::globalEndLuminosityBlock(const edm::LuminosityBlock& ls, const edm::EventSetup& es) {
0951   int lumiBlock = ls.id().luminosityBlock();
0952 
0953   map<string, map<int, DTTimeEvolutionHisto*> >::iterator fedIt = fedTimeHistos.begin();
0954   map<string, map<int, DTTimeEvolutionHisto*> >::iterator fedEnd = fedTimeHistos.end();
0955   for (; fedIt != fedEnd; ++fedIt) {
0956     map<int, DTTimeEvolutionHisto*>::iterator histoIt = fedIt->second.begin();
0957     map<int, DTTimeEvolutionHisto*>::iterator histoEnd = fedIt->second.end();
0958     for (; histoIt != histoEnd; ++histoIt) {
0959       histoIt->second->updateTimeSlot(lumiBlock, nEventsLS);
0960     }
0961   }
0962 
0963   map<unsigned int, DTTimeEvolutionHisto*>::iterator urosIt = urosTimeHistos.begin();
0964   map<unsigned int, DTTimeEvolutionHisto*>::iterator urosEnd = urosTimeHistos.end();
0965   for (; urosIt != urosEnd; ++urosIt) {
0966     urosIt->second->updateTimeSlot(lumiBlock, nEventsLS);
0967   }
0968 }
0969 
0970 void DTDataIntegrityTask::analyze(const edm::Event& e, const edm::EventSetup& c) {
0971   nevents++;
0972   nEventMonitor->Fill(nevents);
0973   nEventsLS++;
0974 
0975   //errorX[6][12][5] = {0};  //5th is notOK flag and 6th is TDC Fatal; ros; wheel
0976   fill(&errorX[0][0][0], &errorX[0][0][0] + 360, 0);
0977 
0978   LogTrace("DTRawToDigi|TDQM|DTMonitorModule|DTDataIntegrityTask") << "[DTDataIntegrityTask]: preProcessEvent" << endl;
0979 
0980   // Digi collection
0981   edm::Handle<DTuROSFEDDataCollection> fedCol;
0982   e.getByToken(fedToken, fedCol);
0983   DTuROSFEDData fedData;
0984   DTuROSROSData urosData;
0985 
0986   if (fedCol.isValid()) {
0987     for (unsigned int j = 0; j < fedCol->size(); ++j) {
0988       fedData = fedCol->at(j);
0989       int fed = fedData.getfed();  //argument should be void
0990       if (fed > FEDIDmax || fed < FEDIDmin) {
0991         LogError("DTRawToDigi|DTDQM|DTMonitorModule|DTDataIntegrityTask")
0992             << "[DTDataIntegrityTask]: analyze, FED ID " << fed << " not expected." << endl;
0993         continue;
0994       }
0995 
0996       if (mode == 3)
0997         continue;  //Not needed for FEDIntegrity_EvF
0998 
0999       for (int slot = 1; slot <= DOCESLOTS; ++slot) {
1000         urosData = fedData.getuROS(slot);
1001         if (fedData.getslotsize(slot) == 0 || urosData.getslot() == -1)
1002           continue;
1003         processuROS(urosData, fed, slot);
1004       }
1005       processFED(fedData, fed);
1006     }
1007   }
1008 }
1009 
1010 // Conversions
1011 int DTDataIntegrityTask::theDDU(int crate, int slot, int link, bool tenDDU) {
1012   int ros = theROS(slot, link);
1013 
1014   int ddu = 772;
1015   //if (crate == 1368) { ddu = 775; }
1016   //Needed just in case this FED should be used due to fibers length
1017 
1018   if (crate == FEDNumbering::MINDTUROSFEDID) {
1019     if (slot < 7)
1020       ddu = 770;
1021     else
1022       ddu = 771;
1023   }
1024 
1025   if (crate == (FEDNumbering::MINDTUROSFEDID + 1)) {
1026     ddu = 772;
1027   }
1028 
1029   if (crate == FEDNumbering::MAXDTUROSFEDID) {
1030     if (slot < 7)
1031       ddu = 773;
1032     else
1033       ddu = 774;
1034   }
1035 
1036   if (ros > 6 && tenDDU && ddu < 775)
1037     ddu += 5;
1038 
1039   return ddu;
1040 }
1041 
1042 int DTDataIntegrityTask::theROS(int slot, int link) {
1043   if (slot % 6 == 5)
1044     return link + 1;
1045 
1046   int ros = (link / 24) + 3 * (slot % 6) - 2;
1047   return ros;
1048 }
1049 
1050 // Local Variables:
1051 // show-trailing-whitespace: t
1052 // truncate-lines: t
1053 // End: