Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /******************************************
0002  *
0003  * This is a part of CTPPSDQM software.
0004  * Authors:
0005  *   F.Ferro INFN Genova
0006  *   Vladimir Popov (vladimir.popov@cern.ch)
0007  *
0008  *******************************************/
0009 
0010 #include "FWCore/Framework/interface/Event.h"
0011 #include "FWCore/Framework/interface/EventSetup.h"
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "FWCore/Utilities/interface/InputTag.h"
0015 #include "FWCore/Common/interface/TriggerNames.h"
0016 
0017 #include "DQMServices/Core/interface/DQMEDAnalyzer.h"
0018 #include "DQMServices/Core/interface/DQMStore.h"
0019 
0020 #include "DataFormats/Common/interface/DetSetVector.h"
0021 
0022 #include "CondFormats/PPSObjects/interface/CTPPSPixelIndices.h"
0023 #include "DataFormats/CTPPSDetId/interface/CTPPSDetId.h"
0024 #include "DataFormats/CTPPSDigi/interface/CTPPSPixelDigi.h"
0025 #include "DataFormats/CTPPSDigi/interface/CTPPSPixelDataError.h"
0026 #include "DataFormats/CTPPSReco/interface/CTPPSPixelCluster.h"
0027 #include "DataFormats/CTPPSReco/interface/CTPPSPixelLocalTrack.h"
0028 #include "DataFormats/Common/interface/TriggerResults.h"
0029 
0030 #include "CondFormats/DataRecord/interface/CTPPSPixelDAQMappingRcd.h"
0031 #include "CondFormats/PPSObjects/interface/CTPPSPixelDAQMapping.h"
0032 
0033 #include <string>
0034 
0035 //-----------------------------------------------------------------------------
0036 
0037 class CTPPSPixelDQMSource : public DQMEDAnalyzer {
0038 public:
0039   CTPPSPixelDQMSource(const edm::ParameterSet &ps);
0040   ~CTPPSPixelDQMSource() override;
0041 
0042 protected:
0043   void dqmBeginRun(edm::Run const &, edm::EventSetup const &) override;
0044   void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
0045   void analyze(edm::Event const &e, edm::EventSetup const &eSetup) override;
0046 
0047 private:
0048   unsigned int verbosity;
0049   long int nEvents = 0;
0050   edm::EDGetTokenT<edm::DetSetVector<CTPPSPixelDigi>> tokenDigi;
0051   edm::EDGetTokenT<edm::DetSetVector<CTPPSPixelDataError>> tokenError;
0052   edm::EDGetTokenT<edm::DetSetVector<CTPPSPixelCluster>> tokenCluster;
0053   edm::EDGetTokenT<edm::DetSetVector<CTPPSPixelLocalTrack>> tokenTrack;
0054   edm::EDGetTokenT<edm::TriggerResults> tokenTrigResults;
0055   edm::ESGetToken<CTPPSPixelDAQMapping, CTPPSPixelDAQMappingRcd> tokenPixelDAQMapping;
0056   std::string randomHLTPath;
0057   std::string mappingLabel;
0058 
0059   static constexpr int NArms = 2;
0060   static constexpr int NStationMAX = 3;  // in an arm
0061   static constexpr int NRPotsMAX = 6;    // per station
0062   static constexpr int NplaneMAX = 6;    // per RPot
0063   static constexpr int NROCsMAX = 6;     // per plane
0064   static constexpr int RPn_first = 3, RPn_last = 4;
0065   static constexpr int ADCMax = 256;
0066   static constexpr int StationIDMAX = 4;  // possible range of ID
0067   static constexpr int RPotsIDMAX = 8;    // possible range of ID
0068   static constexpr int NLocalTracksMAX = 20;
0069   static constexpr int hitMultMAX = 50;   // tuned
0070   static constexpr int ClusMultMAX = 10;  // tuned
0071   static constexpr int ClusterSizeMax = 9;
0072   static constexpr int errCodeSize = 15;
0073   static constexpr int minFedNumber = 1462;
0074   static constexpr int numberOfFeds = 2;
0075   static constexpr int mapXbins = 200;
0076   static constexpr int mapYbins = 240;
0077   static constexpr float mapYmin = -16.;
0078   static constexpr float mapYmax = 8.;
0079   const float mapXmin = 0. * TMath::Cos(18.4 / 180. * TMath::Pi());
0080   const float mapXmax = 30. * TMath::Cos(18.4 / 180. * TMath::Pi());
0081 
0082   CTPPSPixelIndices thePixIndices;
0083 
0084   int TrackFitDimension = 4;
0085 
0086   static constexpr int NRPotBinsInStation = RPn_last - RPn_first;
0087   static constexpr int NPlaneBins = NplaneMAX * NRPotBinsInStation;
0088 
0089   MonitorElement *hBX, *hBXshort, *h2AllPlanesActive, *hpixLTrack;
0090   MonitorElement *hpRPactive;
0091 
0092   MonitorElement *h2HitsMultipl[NArms][NStationMAX];
0093   MonitorElement *h2CluSize[NArms][NStationMAX];
0094 
0095   static constexpr int RPotsTotalNumber = NArms * NStationMAX * NRPotsMAX;
0096 
0097   int RPindexValid[RPotsTotalNumber];
0098   MonitorElement *h2trackXY0[RPotsTotalNumber];
0099   MonitorElement *h2ErrorCodeRP[RPotsTotalNumber];
0100   MonitorElement *h2ErrorCodeFED[2];
0101   MonitorElement *h2TBMMessageFED[2];
0102   MonitorElement *h2TBMTypeFED[2];
0103   MonitorElement *h2ErrorCodeUnidDet;
0104   MonitorElement *h2TBMMessageUnidDet;
0105   MonitorElement *h2TBMTypeUnidDet;
0106 
0107   MonitorElement *h2FullType;
0108   MonitorElement *h2TBMMessageRP[RPotsTotalNumber];
0109   MonitorElement *h2TBMTypeRP[RPotsTotalNumber];
0110 
0111   MonitorElement *htrackMult[RPotsTotalNumber];
0112   MonitorElement *htrackHits[RPotsTotalNumber];
0113   MonitorElement *hRPotActivPlanes[RPotsTotalNumber];
0114   MonitorElement *hRPotActivBX[RPotsTotalNumber];
0115   MonitorElement *hRPotActivBXroc[RPotsTotalNumber];
0116   MonitorElement *hRPotActivBXroc_3[RPotsTotalNumber];
0117   MonitorElement *hRPotActivBXroc_2[RPotsTotalNumber];
0118   MonitorElement *h2HitsMultROC[RPotsTotalNumber];
0119   MonitorElement *hp2HitsMultROC_LS[RPotsTotalNumber];
0120   MonitorElement *hHitsMult[RPotsTotalNumber][NplaneMAX];
0121   MonitorElement *h2xyHits[RPotsTotalNumber][NplaneMAX];
0122   MonitorElement *hp2xyADC[RPotsTotalNumber][NplaneMAX];
0123   MonitorElement *h2Efficiency[RPotsTotalNumber][NplaneMAX];
0124   MonitorElement *h2xyROCHits[RPotsTotalNumber * NplaneMAX][NROCsMAX];
0125   MonitorElement *hROCadc[RPotsTotalNumber * NplaneMAX][NROCsMAX];
0126   MonitorElement *hRPotActivBXall[RPotsTotalNumber];
0127   MonitorElement *h2HitsVsBXRandoms[RPotsTotalNumber];
0128   int HitsMultROC[RPotsTotalNumber * NplaneMAX][NROCsMAX];
0129   int HitsMultPlane[RPotsTotalNumber][NplaneMAX];
0130 
0131   //--------------------------------------------------------
0132   static constexpr int LINK_bits = 6;
0133   static constexpr int ROC_bits = 5;
0134   static constexpr int DCOL_bits = 5;
0135   static constexpr int PXID_bits = 8;
0136   static constexpr int ADC_bits = 8;
0137   static constexpr int DataBit_bits = 1;
0138 
0139   static constexpr int ADC_shift = 0;
0140   static constexpr int PXID_shift = ADC_shift + ADC_bits;
0141   static constexpr int DCOL_shift = PXID_shift + PXID_bits;
0142   static constexpr int ROC_shift = DCOL_shift + DCOL_bits;
0143   static constexpr int LINK_shift = ROC_shift + ROC_bits;
0144   static constexpr int DB0_shift = 0;
0145   static constexpr int DB1_shift = DB0_shift + DataBit_bits;
0146   static constexpr int DB2_shift = DB1_shift + DataBit_bits;
0147   static constexpr int DB3_shift = DB2_shift + DataBit_bits;
0148   static constexpr int DB4_shift = DB3_shift + DataBit_bits;
0149   static constexpr int DB5_shift = DB4_shift + DataBit_bits;
0150   static constexpr int DB6_shift = DB5_shift + DataBit_bits;
0151   static constexpr int DB7_shift = DB6_shift + DataBit_bits;
0152 
0153   static constexpr uint32_t LINK_mask = ~(~uint32_t(0) << LINK_bits);
0154   static constexpr uint32_t ROC_mask = ~(~uint32_t(0) << ROC_bits);
0155   static constexpr uint32_t DCOL_mask = ~(~uint32_t(0) << DCOL_bits);
0156   static constexpr uint32_t PXID_mask = ~(~uint32_t(0) << PXID_bits);
0157   static constexpr uint32_t ADC_mask = ~(~uint32_t(0) << ADC_bits);
0158   static constexpr uint32_t DataBit_mask = ~(~uint32_t(0) << DataBit_bits);
0159   // Flags for disabling set of plots
0160   bool offlinePlots = true;
0161   bool onlinePlots = true;
0162 
0163   // Flags for disabling plots of a plane
0164   bool isPlanePlotsTurnedOff[NArms][NStationMAX][NRPotsMAX][NplaneMAX] = {};
0165 
0166   unsigned int rpStatusWord = 0x8008;      // 220_fr_hr(stn2rp3)+ 210_fr_hr
0167   int RPstatus[StationIDMAX][RPotsIDMAX];  // symmetric in both arms
0168   int StationStatus[StationIDMAX];         // symmetric in both arms
0169   const int IndexNotValid = 0;
0170 
0171   int getRPindex(int arm, int station, int rp) {
0172     if (arm < 0 || station < 0 || rp < 0)
0173       return (IndexNotValid);
0174     if (arm > 1 || station >= NStationMAX || rp >= NRPotsMAX)
0175       return (IndexNotValid);
0176     int rc = (arm * NStationMAX + station) * NRPotsMAX + rp;
0177     return (rc);
0178   }
0179 
0180   int getPlaneIndex(int arm, int station, int rp, int plane) {
0181     if (plane < 0 || plane >= NplaneMAX)
0182       return (IndexNotValid);
0183     int rc = getRPindex(arm, station, rp);
0184     if (rc == IndexNotValid)
0185       return (IndexNotValid);
0186     return (rc * NplaneMAX + plane);
0187   }
0188 
0189   int getRPInStationBin(int rp) { return (rp - RPn_first + 1); }
0190 
0191   static constexpr int NRPglobalBins = 4;  // 2 arms w. 2 stations w. 1 RP
0192 
0193   int getRPglobalBin(int arm, int stn) {
0194     static constexpr int stationBinOrder[NStationMAX] = {0, 4, 1};
0195     return (arm * 2 + stationBinOrder[stn] + 1);
0196   }
0197 
0198   int prIndex(int rp, int plane)  // plane index in station
0199 
0200   {
0201     return ((rp - RPn_first) * NplaneMAX + plane);
0202   }
0203   int getDet(int id) { return (id >> DetId::kDetOffset) & 0xF; }
0204   int getPixPlane(int id) { return ((id >> 16) & 0x7); }
0205   //  int getSubdet(int id) { return ((id>>kSubdetOffset)&0x7); }
0206 
0207   float x0_MIN, x0_MAX, y0_MIN, y0_MAX;
0208 };
0209 
0210 //----------------------------------------------------------------------------------
0211 
0212 using namespace std;
0213 using namespace edm;
0214 
0215 //-------------------------------------------------------------------------------
0216 
0217 CTPPSPixelDQMSource::CTPPSPixelDQMSource(const edm::ParameterSet &ps)
0218     : verbosity(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
0219       randomHLTPath(ps.getUntrackedParameter<std::string>("randomHLTPath", "")),
0220       rpStatusWord(ps.getUntrackedParameter<unsigned int>("RPStatusWord", 0x8008)) {
0221   tokenDigi = consumes<DetSetVector<CTPPSPixelDigi>>(ps.getUntrackedParameter<edm::InputTag>("tagRPixDigi"));
0222   tokenError = consumes<DetSetVector<CTPPSPixelDataError>>(ps.getUntrackedParameter<edm::InputTag>("tagRPixError"));
0223   tokenCluster = consumes<DetSetVector<CTPPSPixelCluster>>(ps.getUntrackedParameter<edm::InputTag>("tagRPixCluster"));
0224   tokenTrack = consumes<DetSetVector<CTPPSPixelLocalTrack>>(ps.getUntrackedParameter<edm::InputTag>("tagRPixLTrack"));
0225   tokenTrigResults = consumes<edm::TriggerResults>(ps.getUntrackedParameter<edm::InputTag>("tagTrigResults"));
0226   tokenPixelDAQMapping = esConsumes<CTPPSPixelDAQMapping, CTPPSPixelDAQMappingRcd>();
0227   mappingLabel = ps.getUntrackedParameter<std::string>("mappingLabel");
0228   offlinePlots = ps.getUntrackedParameter<bool>("offlinePlots", true);
0229   onlinePlots = ps.getUntrackedParameter<bool>("onlinePlots", true);
0230 
0231   vector<string> disabledPlanePlotsVec =
0232       ps.getUntrackedParameter<vector<string>>("turnOffPlanePlots", vector<string>());
0233   // Parse the strings in disabledPlanePlotsVec and set the flags in
0234   // isPlanePlotsTurnedOff
0235   for (auto s : disabledPlanePlotsVec) {
0236     // Check that the format is <arm>_<station>_<RP>_<Plane>
0237     if (count(s.begin(), s.end(), '_') != 3)
0238       throw cms::Exception("RPixPlaneCombinatoryTracking") << "Invalid string in turnOffPlanePlots: " << s;
0239     else {
0240       vector<string> armStationRpPlane;
0241       size_t pos = 0;
0242       while ((pos = s.find('_')) != string::npos) {
0243         armStationRpPlane.push_back(s.substr(0, pos));
0244         s.erase(0, pos + 1);
0245       }
0246       armStationRpPlane.push_back(s);
0247 
0248       int arm = stoi(armStationRpPlane.at(0));
0249       int station = stoi(armStationRpPlane.at(1));
0250       int rp = stoi(armStationRpPlane.at(2));
0251       int plane = stoi(armStationRpPlane.at(3));
0252 
0253       if (arm < NArms && station < NStationMAX && rp < NRPotsMAX && plane < NplaneMAX) {
0254         if (verbosity)
0255           LogPrint("CTPPSPixelDQMSource")
0256               << "Shutting off plots for: Arm " << arm << " Station " << station << " Rp " << rp << " Plane " << plane;
0257         isPlanePlotsTurnedOff[arm][station][rp][plane] = true;
0258       } else {
0259         throw cms::Exception("RPixPlaneCombinatoryTracking") << "Invalid string in turnOffPlanePlots: " << s;
0260       }
0261     }
0262   }
0263 }
0264 
0265 //----------------------------------------------------------------------------------
0266 
0267 CTPPSPixelDQMSource::~CTPPSPixelDQMSource() {}
0268 
0269 //--------------------------------------------------------------------------
0270 
0271 void CTPPSPixelDQMSource::dqmBeginRun(edm::Run const &run, edm::EventSetup const &) {
0272   if (verbosity)
0273     LogPrint("CTPPSPixelDQMSource") << "RPstatusWord= " << rpStatusWord;
0274   nEvents = 0;
0275 
0276   CTPPSPixelLocalTrack thePixelLocalTrack;
0277   TrackFitDimension = thePixelLocalTrack.dimension;
0278 
0279   for (int stn = 0; stn < StationIDMAX; stn++) {
0280     StationStatus[stn] = 0;
0281     for (int rp = 0; rp < RPotsIDMAX; rp++)
0282       RPstatus[stn][rp] = 0;
0283   }
0284 
0285   unsigned int rpSts = rpStatusWord << 1;
0286   for (int stn = 0; stn < NStationMAX; stn++) {
0287     int stns = 0;
0288     for (int rp = 0; rp < NRPotsMAX; rp++) {
0289       rpSts = (rpSts >> 1);
0290       RPstatus[stn][rp] = rpSts & 1;
0291       if (RPstatus[stn][rp] > 0)
0292         stns = 1;
0293     }
0294     StationStatus[stn] = stns;
0295   }
0296 
0297   for (int ind = 0; ind < 2 * 3 * NRPotsMAX; ind++)
0298     RPindexValid[ind] = 0;
0299 
0300   x0_MIN = y0_MIN = 1.0e06;
0301   x0_MAX = y0_MAX = -1.0e06;
0302 }
0303 
0304 //-------------------------------------------------------------------------------------
0305 
0306 void CTPPSPixelDQMSource::bookHistograms(DQMStore::IBooker &ibooker, edm::Run const &, edm::EventSetup const &) {
0307   ibooker.cd();
0308   ibooker.setCurrentFolder("CTPPS/TrackingPixel");
0309   char s[50];
0310   string armTitleShort, stnTitleShort;
0311 
0312   TAxis *yah1st = nullptr;
0313   TAxis *xaRPact = nullptr;
0314   TAxis *xah1trk = nullptr;
0315   if (onlinePlots) {
0316     hBX = ibooker.book1D("events per BX", "ctpps_pixel;Event.BX", 4002, -1.5, 4000. + 0.5);
0317     hBXshort = ibooker.book1D("events per BX(short)", "ctpps_pixel;Event.BX", 102, -1.5, 100. + 0.5);
0318 
0319     string str1st = "Pixel planes activity";
0320     h2AllPlanesActive = ibooker.book2DD(
0321         str1st, str1st + "(digi task);Plane #", NplaneMAX, 0, NplaneMAX, NRPglobalBins, 0.5, NRPglobalBins + 0.5);
0322     TH2D *h1st = h2AllPlanesActive->getTH2D();
0323     h1st->SetOption("colz");
0324     yah1st = h1st->GetYaxis();
0325 
0326     string str2 = "Pixel RP active";
0327     hpRPactive = ibooker.bookProfile(
0328         str2, str2 + " per event(digi task)", NRPglobalBins, 0.5, NRPglobalBins + 0.5, -0.1, 1.1, "");
0329     xaRPact = hpRPactive->getTProfile()->GetXaxis();
0330     hpRPactive->getTProfile()->SetOption("hist");
0331     hpRPactive->getTProfile()->SetMinimum(0.);
0332     hpRPactive->getTProfile()->SetMaximum(1.1);
0333 
0334     str2 = "Pixel Local Tracks";
0335     hpixLTrack = ibooker.bookProfile(
0336         str2, str2 + " per event", NRPglobalBins, 0.5, NRPglobalBins + 0.5, -0.1, NLocalTracksMAX, "");
0337 
0338     xah1trk = hpixLTrack->getTProfile()->GetXaxis();
0339     hpixLTrack->getTProfile()->GetYaxis()->SetTitle("average number of tracks per event");
0340     hpixLTrack->getTProfile()->SetOption("hist");
0341   }
0342   const float minErrCode = 25.;
0343   const string errCode[errCodeSize] = {
0344       "Masked channel                     ",  // error 25
0345       "Gap word",                             // error 26
0346       "Dummy word",                           // error 27
0347       "FIFO nearly full",                     // error 28
0348       "Channel Timeout",                      // error 29
0349       "TBM Trailer",                          // error 30
0350       "Event number mismatch",                // error 31
0351       "Invalid/no FED header",                // error 32
0352       "Invalid/no FED trailer",               // error 33
0353       "Size mismatch",                        // error 34
0354       "Conversion: inv. channel",             // error 35
0355       "Conversion: inv. ROC number",          // error 36
0356       "Conversion: inv. pixel address",       // error 37
0357       "-",
0358       "CRC"  //error 39
0359   };
0360 
0361   const string tbmMessage[8] = {"Stack full ",
0362                                 "Pre-cal issued ",
0363                                 "Clear trigger counter",
0364                                 "Synch trigger",
0365                                 "Synch trigger error",
0366                                 "Reset ROC",
0367                                 "Reset TBM",
0368                                 "No token pass"};
0369 
0370   const string tbmType[5] = {
0371       "All bits 0", "bit 8 : Overflow", "bit 9 : PKAM", "bit 10 : Auto Reset", "bit 11 : Number of ROC Error"};
0372 
0373   h2ErrorCodeUnidDet = ibooker.book2D("Errors in Unidentified Det",
0374                                       "Errors in Unidentified Det;;fed",
0375                                       errCodeSize,
0376                                       minErrCode - 0.5,
0377                                       minErrCode + float(errCodeSize) - 0.5,
0378                                       2,
0379                                       1461.5,
0380                                       1463.5);
0381   for (unsigned int iBin = 1; iBin <= errCodeSize; iBin++)
0382     h2ErrorCodeUnidDet->setBinLabel(iBin, errCode[iBin - 1]);
0383   h2ErrorCodeUnidDet->setBinLabel(1, "1462", 2);
0384   h2ErrorCodeUnidDet->setBinLabel(2, "1463", 2);
0385   h2ErrorCodeUnidDet->getTH2F()->SetOption("colz");
0386   h2TBMMessageUnidDet =
0387       ibooker.book2D("TBM Message Unid Det", "TBM Message Unid Det;;fed", 8, -0.5, 7.5, 2, 1461.5, 1463.5);
0388   for (unsigned int iBin = 1; iBin <= 8; iBin++)
0389     h2TBMMessageUnidDet->setBinLabel(iBin, tbmMessage[iBin - 1]);
0390   h2TBMMessageUnidDet->getTH2F()->SetOption("colz");
0391 
0392   h2TBMTypeUnidDet =
0393       ibooker.book2D("TBM Type in Unid Det", "TBM Type in Unid Det;;fed", 5, -0.5, 4.5, 2, 1461.5, 1463.5);
0394   for (unsigned int iBin = 1; iBin <= 5; iBin++)
0395     h2TBMTypeUnidDet->setBinLabel(iBin, tbmType[iBin - 1]);
0396   h2TBMTypeUnidDet->getTH2F()->SetOption("colz");
0397 
0398   h2FullType = ibooker.book2D("Full FIFO", "Full FIFO;;fed", 7, 0.5, 7.5, 2, 1461.5, 1463.5);
0399   h2FullType->setBinLabel(1, "1462", 2);
0400   h2FullType->setBinLabel(2, "1463", 2);
0401   h2FullType->getTH2F()->SetOption("colz");
0402 
0403   for (int iFed = 0; iFed < numberOfFeds; iFed++) {
0404     int fedId = minFedNumber + iFed;
0405     auto s_fed = std::to_string(fedId);
0406 
0407     h2ErrorCodeFED[iFed] = ibooker.book2D("Errors in FED" + s_fed,
0408                                           "Errors in FED" + s_fed + ";;channel",
0409                                           errCodeSize,
0410                                           minErrCode - 0.5,
0411                                           minErrCode + float(errCodeSize) - 0.5,
0412                                           37,
0413                                           -0.5,
0414                                           36.5);
0415     for (unsigned int iBin = 1; iBin <= errCodeSize; iBin++)
0416       h2ErrorCodeFED[iFed]->setBinLabel(iBin, errCode[iBin - 1]);
0417     h2ErrorCodeFED[iFed]->getTH2F()->SetOption("colz");
0418 
0419     h2TBMMessageFED[iFed] = ibooker.book2D(
0420         "TBM Message in FED" + s_fed, "TBM Message in FED" + s_fed + ";;channel", 8, -0.5, 7.5, 37, -0.5, 36.5);
0421     for (unsigned int iBin = 1; iBin <= 8; iBin++)
0422       h2TBMMessageFED[iFed]->setBinLabel(iBin, tbmMessage[iBin - 1]);
0423     h2TBMMessageFED[iFed]->getTH2F()->SetOption("colz");
0424 
0425     h2TBMTypeFED[iFed] = ibooker.book2D(
0426         "TBM Type in FED" + s_fed, "TBM Type in FED" + s_fed + ";;channel", 5, -0.5, 4.5, 37, -0.5, 36.5);
0427     for (unsigned int iBin = 1; iBin <= 5; iBin++)
0428       h2TBMTypeFED[iFed]->setBinLabel(iBin, tbmType[iBin - 1]);
0429     h2TBMTypeFED[iFed]->getTH2F()->SetOption("colz");
0430   }
0431 
0432   for (int arm = 0; arm < 2; arm++) {
0433     CTPPSDetId ID(CTPPSDetId::sdTrackingPixel, arm, 0);
0434     string sd, armTitle;
0435     ID.armName(sd, CTPPSDetId::nPath);
0436     ID.armName(armTitle, CTPPSDetId::nFull);
0437     ID.armName(armTitleShort, CTPPSDetId::nShort);
0438 
0439     ibooker.setCurrentFolder(sd);
0440 
0441     for (int stn = 0; stn < NStationMAX; stn++) {
0442       if (StationStatus[stn] == 0)
0443         continue;
0444       ID.setStation(stn);
0445       string stnd, stnTitle;
0446 
0447       CTPPSDetId(ID.stationId()).stationName(stnd, CTPPSDetId::nPath);
0448       CTPPSDetId(ID.stationId()).stationName(stnTitle, CTPPSDetId::nFull);
0449       CTPPSDetId(ID.stationId()).stationName(stnTitleShort, CTPPSDetId::nShort);
0450 
0451       ibooker.setCurrentFolder(stnd);
0452       //--------- RPots ---
0453       int pixBinW = 4;
0454       for (int rp = RPn_first; rp < RPn_last; rp++) {  // only installed pixel pots
0455         ID.setRP(rp);
0456         string rpd, rpTitle;
0457         CTPPSDetId(ID.rpId()).rpName(rpTitle, CTPPSDetId::nShort);
0458         string rpBinName = armTitleShort + "_" + stnTitleShort + "_" + rpTitle;
0459         if (onlinePlots) {
0460           yah1st->SetBinLabel(getRPglobalBin(arm, stn), rpBinName.c_str());
0461           xah1trk->SetBinLabel(getRPglobalBin(arm, stn), rpBinName.c_str());
0462           xaRPact->SetBinLabel(getRPglobalBin(arm, stn), rpBinName.c_str());
0463         }
0464         if (RPstatus[stn][rp] == 0)
0465           continue;
0466         int indexP = getRPindex(arm, stn, rp);
0467         RPindexValid[indexP] = 1;
0468 
0469         CTPPSDetId(ID.rpId()).rpName(rpTitle, CTPPSDetId::nFull);
0470         CTPPSDetId(ID.rpId()).rpName(rpd, CTPPSDetId::nPath);
0471 
0472         ibooker.setCurrentFolder(rpd);
0473 
0474         const float x0Maximum = 70.;
0475         const float y0Maximum = 15.;
0476         string st = "track intercept point";
0477         string st2 = ": " + stnTitle;
0478         h2trackXY0[indexP] = ibooker.book2D(
0479             st, st + st2 + ";x0;y0", int(x0Maximum) * 2, 0., x0Maximum, int(y0Maximum) * 4, -y0Maximum, y0Maximum);
0480         h2trackXY0[indexP]->getTH2F()->SetOption("colz");
0481         st = "Error Code";
0482         h2ErrorCodeRP[indexP] = ibooker.book2D(st,
0483                                                st + st2 + ";;plane",
0484                                                errCodeSize,
0485                                                minErrCode - 0.5,
0486                                                minErrCode + float(errCodeSize) - 0.5,
0487                                                6,
0488                                                -0.5,
0489                                                5.5);
0490         for (unsigned int iBin = 1; iBin <= errCodeSize; iBin++)
0491           h2ErrorCodeRP[indexP]->setBinLabel(iBin, errCode[iBin - 1]);
0492         h2ErrorCodeRP[indexP]->getTH2F()->SetOption("colz");
0493 
0494         h2TBMMessageRP[indexP] = ibooker.book2D("TBM Message", "TBM Message;;plane", 8, -0.5, 7.5, 6, -0.5, 5.5);
0495         for (unsigned int iBin = 1; iBin <= 8; iBin++)
0496           h2TBMMessageRP[indexP]->setBinLabel(iBin, tbmMessage[iBin - 1]);
0497         h2TBMMessageRP[indexP]->getTH2F()->SetOption("colz");
0498 
0499         h2TBMTypeRP[indexP] = ibooker.book2D("TBM Type", "TBM Type;;plane", 5, -0.5, 4.5, 6, -0.5, 5.5);
0500         for (unsigned int iBin = 1; iBin <= 5; iBin++)
0501           h2TBMTypeRP[indexP]->setBinLabel(iBin, tbmType[iBin - 1]);
0502         h2TBMTypeRP[indexP]->getTH2F()->SetOption("colz");
0503 
0504         st = "number of tracks per event";
0505         htrackMult[indexP] = ibooker.bookProfile(st,
0506                                                  rpTitle + ";number of tracks",
0507                                                  NLocalTracksMAX + 1,
0508                                                  -0.5,
0509                                                  NLocalTracksMAX + 0.5,
0510                                                  -0.5,
0511                                                  NLocalTracksMAX + 0.5,
0512                                                  "");
0513         htrackMult[indexP]->getTProfile()->SetOption("hist");
0514 
0515         hRPotActivPlanes[indexP] = ibooker.bookProfile("number of fired planes per event",
0516                                                        rpTitle + ";nPlanes;Probability",
0517                                                        NplaneMAX + 1,
0518                                                        -0.5,
0519                                                        NplaneMAX + 0.5,
0520                                                        -0.5,
0521                                                        NplaneMAX + 0.5,
0522                                                        "");
0523         hRPotActivPlanes[indexP]->getTProfile()->SetOption("hist");
0524 
0525         hp2HitsMultROC_LS[indexP] = ibooker.bookProfile2D("ROCs hits multiplicity per event vs LS",
0526                                                           rpTitle + ";LumiSection;Plane#___ROC#",
0527                                                           1000,
0528                                                           0.,
0529                                                           1000.,
0530                                                           NplaneMAX * NROCsMAX,
0531                                                           0.,
0532                                                           double(NplaneMAX * NROCsMAX),
0533                                                           0.,
0534                                                           rpixValues::ROCSizeInX * rpixValues::ROCSizeInY,
0535                                                           "");
0536         hp2HitsMultROC_LS[indexP]->getTProfile2D()->SetOption("colz");
0537         hp2HitsMultROC_LS[indexP]->getTProfile2D()->SetMinimum(1.0e-10);
0538         hp2HitsMultROC_LS[indexP]->getTProfile2D()->SetCanExtend(TProfile2D::kXaxis);
0539         TAxis *yahp2 = hp2HitsMultROC_LS[indexP]->getTProfile2D()->GetYaxis();
0540         for (int p = 0; p < NplaneMAX; p++) {
0541           sprintf(s, "plane%d_0", p);
0542           yahp2->SetBinLabel(p * NplaneMAX + 1, s);
0543           for (int r = 1; r < NROCsMAX; r++) {
0544             sprintf(s, "   %d_%d", p, r);
0545             yahp2->SetBinLabel(p * NplaneMAX + r + 1, s);
0546           }
0547         }
0548 
0549         // Hits per plane per bx
0550         h2HitsVsBXRandoms[indexP] = ibooker.book2D(
0551             "Hits per plane per BX - random triggers", rpTitle + ";Event.BX;Plane", 4002, -1.5, 4000. + 0.5, 6, 0, 6);
0552 
0553         if (onlinePlots) {
0554           string st3 = ";PlaneIndex(=pixelPot*PlaneMAX + plane)";
0555 
0556           st = "hit multiplicity in planes";
0557           h2HitsMultipl[arm][stn] = ibooker.book2DD(
0558               st, st + st2 + st3 + ";multiplicity", NPlaneBins, 0, NPlaneBins, hitMultMAX, 0, hitMultMAX);
0559           h2HitsMultipl[arm][stn]->getTH2D()->SetOption("colz");
0560 
0561           st = "cluster size in planes";
0562           h2CluSize[arm][stn] = ibooker.book2D(st,
0563                                                st + st2 + st3 + ";Cluster size",
0564                                                NPlaneBins,
0565                                                0,
0566                                                NPlaneBins,
0567                                                ClusterSizeMax + 1,
0568                                                0,
0569                                                ClusterSizeMax + 1);
0570           h2CluSize[arm][stn]->getTH2F()->SetOption("colz");
0571 
0572           st = "number of hits per track";
0573           htrackHits[indexP] = ibooker.bookProfile(st, rpTitle + ";number of hits", 5, 1.5, 6.5, -0.1, 1.1, "");
0574           htrackHits[indexP]->getTProfile()->SetOption("hist");
0575 
0576           h2HitsMultROC[indexP] = ibooker.bookProfile2D("ROCs hits multiplicity per event",
0577                                                         rpTitle + ";plane # ;ROC #",
0578                                                         NplaneMAX,
0579                                                         -0.5,
0580                                                         NplaneMAX - 0.5,
0581                                                         NROCsMAX,
0582                                                         -0.5,
0583                                                         NROCsMAX - 0.5,
0584                                                         0.,
0585                                                         rpixValues::ROCSizeInX * rpixValues::ROCSizeInY,
0586                                                         "");
0587           h2HitsMultROC[indexP]->getTProfile2D()->SetOption("colztext");
0588           h2HitsMultROC[indexP]->getTProfile2D()->SetMinimum(1.e-10);
0589 
0590           ibooker.setCurrentFolder(rpd + "/latency");
0591           hRPotActivBX[indexP] =
0592               ibooker.book1D("5 fired planes per BX", rpTitle + ";Event.BX", 4002, -1.5, 4000. + 0.5);
0593 
0594           hRPotActivBXroc[indexP] =
0595               ibooker.book1D("4 fired ROCs per BX", rpTitle + ";Event.BX", 4002, -1.5, 4000. + 0.5);
0596           hRPotActivBXroc_3[indexP] =
0597               ibooker.book1D("3 fired ROCs per BX", rpTitle + ";Event.BX", 4002, -1.5, 4000. + 0.5);
0598           hRPotActivBXroc_2[indexP] =
0599               ibooker.book1D("2 fired ROCs per BX", rpTitle + ";Event.BX", 4002, -1.5, 4000. + 0.5);
0600 
0601           hRPotActivBXall[indexP] = ibooker.book1D("hits per BX", rpTitle + ";Event.BX", 4002, -1.5, 4000. + 0.5);
0602         }
0603         int nbins = rpixValues::defaultDetSizeInX / pixBinW;
0604 
0605         for (int p = 0; p < NplaneMAX; p++) {
0606           if (isPlanePlotsTurnedOff[arm][stn][rp][p])
0607             continue;
0608           sprintf(s, "plane_%d", p);
0609           string pd = rpd + "/" + string(s);
0610           ibooker.setCurrentFolder(pd);
0611           string st1 = ": " + rpTitle + "_" + string(s);
0612 
0613           st = "adc average value";
0614           hp2xyADC[indexP][p] = ibooker.bookProfile2D(st,
0615                                                       st1 + ";pix col;pix row",
0616                                                       nbins,
0617                                                       0,
0618                                                       rpixValues::defaultDetSizeInX,
0619                                                       nbins,
0620                                                       0,
0621                                                       rpixValues::defaultDetSizeInX,
0622                                                       0.,
0623                                                       512.,
0624                                                       "");
0625           hp2xyADC[indexP][p]->getTProfile2D()->SetOption("colz");
0626 
0627           if (onlinePlots) {
0628             st = "hits position";
0629             h2xyHits[indexP][p] = ibooker.book2DD(st,
0630                                                   st1 + ";pix col;pix row",
0631                                                   rpixValues::defaultDetSizeInX,
0632                                                   0,
0633                                                   rpixValues::defaultDetSizeInX,
0634                                                   rpixValues::defaultDetSizeInX,
0635                                                   0,
0636                                                   rpixValues::defaultDetSizeInX);
0637             h2xyHits[indexP][p]->getTH2D()->SetOption("colz");
0638 
0639             st = "hits multiplicity";
0640             hHitsMult[indexP][p] =
0641                 ibooker.book1DD(st, st1 + ";number of hits;N / 1 hit", hitMultMAX + 1, -0.5, hitMultMAX + 0.5);
0642           }
0643 
0644           if (offlinePlots) {
0645             st = "plane efficiency";
0646             h2Efficiency[indexP][p] = ibooker.bookProfile2D(
0647                 st, st1 + ";x0;y0", mapXbins, mapXmin, mapXmax, mapYbins, mapYmin, mapYmax, 0, 1, "");
0648             h2Efficiency[indexP][p]->getTProfile2D()->SetOption("colz");
0649           }
0650         }  // end of for(int p=0; p<NplaneMAX;..
0651 
0652       }  // end for(int rp=0; rp<NRPotsMAX;...
0653     }    // end of for(int stn=0; stn<
0654   }      // end of for(int arm=0; arm<2;...
0655 
0656   return;
0657 }
0658 
0659 //-------------------------------------------------------------------------------
0660 
0661 void CTPPSPixelDQMSource::analyze(edm::Event const &event, edm::EventSetup const &eventSetup) {
0662   ++nEvents;
0663   int lumiId = event.getLuminosityBlock().id().luminosityBlock();
0664   if (lumiId < 0)
0665     lumiId = 0;
0666 
0667   int RPactivity[RPotsTotalNumber], RPdigiSize[RPotsTotalNumber];
0668   int pixRPTracks[RPotsTotalNumber];
0669 
0670   for (int rp = 0; rp < RPotsTotalNumber; rp++) {
0671     RPactivity[rp] = RPdigiSize[rp] = pixRPTracks[rp] = 0;
0672   }
0673 
0674   for (int ind = 0; ind < RPotsTotalNumber; ind++) {
0675     for (int p = 0; p < NplaneMAX; p++) {
0676       HitsMultPlane[ind][p] = 0;
0677     }
0678   }
0679   for (int ind = 0; ind < RPotsTotalNumber * NplaneMAX; ind++) {
0680     for (int roc = 0; roc < NROCsMAX; roc++) {
0681       HitsMultROC[ind][roc] = 0;
0682     }
0683   }
0684   Handle<DetSetVector<CTPPSPixelDigi>> pixDigi;
0685   event.getByToken(tokenDigi, pixDigi);
0686 
0687   Handle<DetSetVector<CTPPSPixelDataError>> pixError;
0688   event.getByToken(tokenError, pixError);
0689 
0690   Handle<DetSetVector<CTPPSPixelCluster>> pixClus;
0691   event.getByToken(tokenCluster, pixClus);
0692 
0693   Handle<DetSetVector<CTPPSPixelLocalTrack>> pixTrack;
0694   event.getByToken(tokenTrack, pixTrack);
0695 
0696   Handle<edm::TriggerResults> hltResults;
0697   event.getByToken(tokenTrigResults, hltResults);
0698 
0699   const CTPPSPixelDAQMapping *mapping = &eventSetup.getData(tokenPixelDAQMapping);
0700 
0701   if (onlinePlots) {
0702     hBX->Fill(event.bunchCrossing());
0703     hBXshort->Fill(event.bunchCrossing());
0704   }
0705 
0706   if (pixTrack.isValid()) {
0707     for (const auto &ds_tr : *pixTrack) {
0708       int idet = getDet(ds_tr.id);
0709       if (idet != DetId::VeryForward) {
0710         if (verbosity > 1)
0711           LogPrint("CTPPSPixelDQMSource") << "not CTPPS: ds_tr.id" << ds_tr.id;
0712         continue;
0713       }
0714       CTPPSDetId theId(ds_tr.id);
0715       int arm = theId.arm() & 0x1;
0716       int station = theId.station() & 0x3;
0717       int rpot = theId.rp() & 0x7;
0718       int rpInd = getRPindex(arm, station, rpot);
0719 
0720       for (DetSet<CTPPSPixelLocalTrack>::const_iterator dit = ds_tr.begin(); dit != ds_tr.end(); ++dit) {
0721         ++pixRPTracks[rpInd];
0722         int nh_tr = (dit->ndf() + TrackFitDimension) / 2;
0723         if (onlinePlots) {
0724           for (int i = 0; i <= NplaneMAX; i++) {
0725             if (i == nh_tr)
0726               htrackHits[rpInd]->Fill(nh_tr, 1.);
0727             else
0728               htrackHits[rpInd]->Fill(i, 0.);
0729           }
0730         }
0731         float x0 = dit->x0();
0732         float y0 = dit->y0();
0733         h2trackXY0[rpInd]->Fill(x0, y0);
0734 
0735         if (x0_MAX < x0)
0736           x0_MAX = x0;
0737         if (y0_MAX < y0)
0738           y0_MAX = y0;
0739         if (x0_MIN > x0)
0740           x0_MIN = x0;
0741         if (y0_MIN > y0)
0742           y0_MIN = y0;
0743 
0744         if (offlinePlots) {
0745           edm::DetSetVector<CTPPSPixelFittedRecHit> fittedHits = dit->hits();
0746 
0747           std::map<int, int> numberOfPointPerPlaneEff;
0748           for (const auto &ds_frh : fittedHits) {
0749             int plane = getPixPlane(ds_frh.id);
0750             for (DetSet<CTPPSPixelFittedRecHit>::const_iterator frh_it = ds_frh.begin(); frh_it != ds_frh.end();
0751                  ++frh_it) {  // there should always be only one hit in each
0752                               // vector
0753               if (frh_it != ds_frh.begin())
0754                 if (verbosity > 1)
0755                   LogPrint("CTPPSPixelDQMSource") << "More than one FittedRecHit found in plane " << plane;
0756               if (frh_it->isRealHit())
0757                 for (int p = 0; p < NplaneMAX; p++) {
0758                   if (p != plane)
0759                     numberOfPointPerPlaneEff[p]++;
0760                 }
0761             }
0762           }
0763 
0764           if (verbosity > 1)
0765             for (auto planeAndHitsOnOthers : numberOfPointPerPlaneEff) {
0766               LogPrint("CTPPSPixelDQMSource")
0767                   << "For plane " << planeAndHitsOnOthers.first << ", " << planeAndHitsOnOthers.second
0768                   << " hits on other planes were found" << endl;
0769             }
0770 
0771           for (const auto &ds_frh : fittedHits) {
0772             int plane = getPixPlane(ds_frh.id);
0773             if (isPlanePlotsTurnedOff[arm][station][rpot][plane])
0774               continue;
0775             for (DetSet<CTPPSPixelFittedRecHit>::const_iterator frh_it = ds_frh.begin(); frh_it != ds_frh.end();
0776                  ++frh_it) {
0777               float frhX0 = frh_it->globalCoordinates().x() + frh_it->xResidual();
0778               float frhY0 = frh_it->globalCoordinates().y() + frh_it->yResidual();
0779               if (numberOfPointPerPlaneEff[plane] >= 3) {
0780                 if (frh_it->isRealHit())
0781                   h2Efficiency[rpInd][plane]->Fill(frhX0, frhY0, 1);
0782                 else
0783                   h2Efficiency[rpInd][plane]->Fill(frhX0, frhY0, 0);
0784               }
0785             }
0786           }
0787         }
0788       }
0789     }
0790   }  // end  if(pixTrack.isValid())
0791 
0792   bool valid = false;
0793   valid |= pixDigi.isValid();
0794   //  valid |= Clus.isValid();
0795 
0796   if (!valid && verbosity)
0797     LogPrint("CTPPSPixelDQMSource") << "No valid data in Event " << nEvents;
0798 
0799   if (pixDigi.isValid()) {
0800     for (const auto &ds_digi : *pixDigi) {
0801       int idet = getDet(ds_digi.id);
0802       if (idet != DetId::VeryForward) {
0803         if (verbosity > 1)
0804           LogPrint("CTPPSPixelDQMSource") << "not CTPPS: ds_digi.id" << ds_digi.id;
0805         continue;
0806       }
0807       //   int subdet = getSubdet(ds_digi.id);
0808 
0809       int plane = getPixPlane(ds_digi.id);
0810 
0811       CTPPSDetId theId(ds_digi.id);
0812       int arm = theId.arm() & 0x1;
0813       int station = theId.station() & 0x3;
0814       int rpot = theId.rp() & 0x7;
0815       int rpInd = getRPindex(arm, station, rpot);
0816       RPactivity[rpInd] = 1;
0817       ++RPdigiSize[rpInd];
0818 
0819       if (StationStatus[station] && RPstatus[station][rpot]) {
0820         if (onlinePlots) {
0821           h2HitsMultipl[arm][station]->Fill(prIndex(rpot, plane), ds_digi.data.size());
0822           h2AllPlanesActive->Fill(plane, getRPglobalBin(arm, station));
0823         }
0824         int index = getRPindex(arm, station, rpot);
0825         HitsMultPlane[index][plane] += ds_digi.data.size();
0826         if (RPindexValid[index]) {
0827           int nh = ds_digi.data.size();
0828           if (nh > hitMultMAX)
0829             nh = hitMultMAX;
0830           if (!isPlanePlotsTurnedOff[arm][station][rpot][plane])
0831             if (onlinePlots)
0832               hHitsMult[index][plane]->Fill(nh);
0833         }
0834         int rocHistIndex = getPlaneIndex(arm, station, rpot, plane);
0835 
0836         for (DetSet<CTPPSPixelDigi>::const_iterator dit = ds_digi.begin(); dit != ds_digi.end(); ++dit) {
0837           int row = dit->row();
0838           int col = dit->column();
0839           int adc = dit->adc();
0840 
0841           if (RPindexValid[index]) {
0842             if (!isPlanePlotsTurnedOff[arm][station][rpot][plane]) {
0843               if (onlinePlots)
0844                 h2xyHits[index][plane]->Fill(col, row);
0845               hp2xyADC[index][plane]->Fill(col, row, adc);
0846             }
0847             int colROC, rowROC;
0848             int trocId;
0849             if (!thePixIndices.transformToROC(col, row, trocId, colROC, rowROC)) {
0850               if (trocId >= 0 && trocId < NROCsMAX) {
0851                 ++HitsMultROC[rocHistIndex][trocId];
0852               }
0853             }
0854           }  // end if(RPindexValid[index]) {
0855         }
0856       }  // end  if(StationStatus[station]) {
0857     }    // end for(const auto &ds_digi : *pixDigi)
0858   }      // if(pixDigi.isValid()) {
0859 
0860   if (pixError.isValid()) {
0861     std::map<CTPPSPixelFramePosition, CTPPSPixelROCInfo> rocMapping = mapping->ROCMapping;
0862     for (const auto &ds_error : *pixError) {
0863       int idet = getDet(ds_error.id);
0864       if (idet != DetId::VeryForward) {
0865         if (idet == 15) {  //dummy det id: store in a plot with fed info
0866 
0867           for (DetSet<CTPPSPixelDataError>::const_iterator dit = ds_error.begin(); dit != ds_error.end(); ++dit) {
0868             // recover fed channel number
0869             int chanNmbr = -1;
0870             if (dit->errorType() == 32 || dit->errorType() == 33 || dit->errorType() == 34) {
0871               long long errorWord = dit->errorWord64();  // for 64-bit error words
0872               chanNmbr = (errorWord >> LINK_shift) & LINK_mask;
0873             } else {
0874               uint32_t errorWord = dit->errorWord32();
0875               chanNmbr = (errorWord >> LINK_shift) & LINK_mask;
0876             }
0877 
0878             // recover detector Id from chanNmbr and fedId
0879             CTPPSPixelFramePosition fPos(dit->fedId(), 0, chanNmbr, 0);  // frame position for ROC 0
0880             std::map<CTPPSPixelFramePosition, CTPPSPixelROCInfo>::const_iterator mit;
0881             int index = -1;
0882             int plane = -1;
0883             bool goodRecovery = false;
0884             mit = rocMapping.find(fPos);
0885             if (mit != rocMapping.end()) {
0886               CTPPSPixelROCInfo rocInfo = (*mit).second;
0887               CTPPSPixelDetId recoveredDetId(rocInfo.iD);
0888               plane = recoveredDetId.plane();
0889               index = getRPindex(recoveredDetId.arm(), recoveredDetId.station(), recoveredDetId.rp());
0890               if (RPindexValid[index] && !isPlanePlotsTurnedOff[recoveredDetId.arm()][recoveredDetId.station()]
0891                                                                [recoveredDetId.rp()][recoveredDetId.plane()])
0892                 goodRecovery = true;
0893             }  // if (mit != rocMapping.end())
0894 
0895             if (goodRecovery) {
0896               h2ErrorCodeRP[index]->Fill(dit->errorType(), plane);
0897             } else {
0898               h2ErrorCodeUnidDet->Fill(dit->errorType(), dit->fedId());
0899             }
0900 
0901             bool fillFED = false;
0902             int iFed = dit->fedId() - minFedNumber;
0903             if (iFed >= 0 && iFed < numberOfFeds)
0904               fillFED = true;
0905 
0906             if (dit->errorType() == 28) {  //error 28 = FIFO nearly full: identify FIFO and fill histogram
0907               int fullType = -1;
0908               uint32_t errorWord = dit->errorWord32();
0909               int NFa = (errorWord >> DB0_shift) & DataBit_mask;
0910               int NFb = (errorWord >> DB1_shift) & DataBit_mask;
0911               int NFc = (errorWord >> DB2_shift) & DataBit_mask;
0912               int NFd = (errorWord >> DB3_shift) & DataBit_mask;
0913               int NFe = (errorWord >> DB4_shift) & DataBit_mask;
0914               int NF2 = (errorWord >> DB6_shift) & DataBit_mask;
0915               int L1A = (errorWord >> DB7_shift) & DataBit_mask;
0916               if (NFa == 1) {
0917                 fullType = 1;
0918                 h2FullType->Fill((int)fullType, dit->fedId());
0919               }
0920               if (NFb == 1) {
0921                 fullType = 2;
0922                 h2FullType->Fill((int)fullType, dit->fedId());
0923               }
0924               if (NFc == 1) {
0925                 fullType = 3;
0926                 h2FullType->Fill((int)fullType, dit->fedId());
0927               }
0928               if (NFd == 1) {
0929                 fullType = 4;
0930                 h2FullType->Fill((int)fullType, dit->fedId());
0931               }
0932               if (NFe == 1) {
0933                 fullType = 5;
0934                 h2FullType->Fill((int)fullType, dit->fedId());
0935               }
0936               if (NF2 == 1) {
0937                 fullType = 6;
0938                 h2FullType->Fill((int)fullType, dit->fedId());
0939               }
0940               if (L1A == 1) {
0941                 fullType = 7;
0942                 h2FullType->Fill((int)fullType, dit->fedId());
0943               }
0944             }
0945             if (dit->errorType() == 30) {  //error 30 = TBM error trailer
0946               uint32_t errorWord = dit->errorWord32();
0947               int t0 = (errorWord >> DB0_shift) & DataBit_mask;
0948               int t1 = (errorWord >> DB1_shift) & DataBit_mask;
0949               int t2 = (errorWord >> DB2_shift) & DataBit_mask;
0950               int t3 = (errorWord >> DB3_shift) & DataBit_mask;
0951               int t4 = (errorWord >> DB4_shift) & DataBit_mask;
0952               int t5 = (errorWord >> DB5_shift) & DataBit_mask;
0953               int t6 = (errorWord >> DB6_shift) & DataBit_mask;
0954               int t7 = (errorWord >> DB7_shift) & DataBit_mask;
0955               if (t0 == 1) {
0956                 if (goodRecovery) {
0957                   h2TBMMessageRP[index]->Fill(0, plane);
0958                 } else {
0959                   h2TBMMessageUnidDet->Fill(0, dit->fedId());
0960                 }
0961                 if (fillFED)
0962                   h2TBMMessageFED[iFed]->Fill(0, chanNmbr);
0963               }
0964               if (t1 == 1) {
0965                 if (goodRecovery) {
0966                   h2TBMMessageRP[index]->Fill(1, plane);
0967                 } else {
0968                   h2TBMMessageUnidDet->Fill(1, dit->fedId());
0969                 }
0970                 if (fillFED)
0971                   h2TBMMessageFED[iFed]->Fill(1, chanNmbr);
0972               }
0973               if (t2 == 1) {
0974                 if (goodRecovery) {
0975                   h2TBMMessageRP[index]->Fill(2, plane);
0976                 } else {
0977                   h2TBMMessageUnidDet->Fill(2, dit->fedId());
0978                 }
0979                 if (fillFED)
0980                   h2TBMMessageFED[iFed]->Fill(2, chanNmbr);
0981               }
0982               if (t3 == 1) {
0983                 if (goodRecovery) {
0984                   h2TBMMessageRP[index]->Fill(3, plane);
0985                 } else {
0986                   h2TBMMessageUnidDet->Fill(3, dit->fedId());
0987                 }
0988                 if (fillFED)
0989                   h2TBMMessageFED[iFed]->Fill(3, chanNmbr);
0990               }
0991               if (t4 == 1) {
0992                 if (goodRecovery) {
0993                   h2TBMMessageRP[index]->Fill(4, plane);
0994                 } else {
0995                   h2TBMMessageUnidDet->Fill(4, dit->fedId());
0996                 }
0997                 if (fillFED)
0998                   h2TBMMessageFED[iFed]->Fill(4, chanNmbr);
0999               }
1000               if (t5 == 1) {
1001                 if (goodRecovery) {
1002                   h2TBMMessageRP[index]->Fill(5, plane);
1003                 } else {
1004                   h2TBMMessageUnidDet->Fill(5, dit->fedId());
1005                 }
1006                 if (fillFED)
1007                   h2TBMMessageFED[iFed]->Fill(5, chanNmbr);
1008               }
1009               if (t6 == 1) {
1010                 if (goodRecovery) {
1011                   h2TBMMessageRP[index]->Fill(6, plane);
1012                 } else {
1013                   h2TBMMessageUnidDet->Fill(6, dit->fedId());
1014                 }
1015                 if (fillFED)
1016                   h2TBMMessageFED[iFed]->Fill(6, chanNmbr);
1017               }
1018               if (t7 == 1) {
1019                 if (goodRecovery) {
1020                   h2TBMMessageRP[index]->Fill(7, plane);
1021                 } else {
1022                   h2TBMMessageUnidDet->Fill(7, dit->fedId());
1023                 }
1024                 if (fillFED)
1025                   h2TBMMessageFED[iFed]->Fill(7, chanNmbr);
1026               }
1027               int stateMach_bits = 4;
1028               int stateMach_shift = 8;
1029               uint32_t stateMach_mask = ~(~uint32_t(0) << stateMach_bits);
1030               uint32_t stateMach = (errorWord >> stateMach_shift) & stateMach_mask;
1031               if (stateMach == 0) {
1032                 if (goodRecovery) {
1033                   h2TBMTypeRP[index]->Fill(0, plane);
1034                 } else {
1035                   h2TBMTypeUnidDet->Fill(0, dit->fedId());
1036                 }
1037                 if (fillFED)
1038                   h2TBMTypeFED[iFed]->Fill(0, chanNmbr);
1039               } else {
1040                 if (((stateMach >> DB0_shift) & DataBit_mask) == 1) {
1041                   if (goodRecovery) {
1042                     h2TBMTypeRP[index]->Fill(1, plane);
1043                   } else {
1044                     h2TBMTypeUnidDet->Fill(1, dit->fedId());
1045                   }
1046                   if (fillFED)
1047                     h2TBMTypeFED[iFed]->Fill(1, chanNmbr);
1048                 }
1049                 if (((stateMach >> DB1_shift) & DataBit_mask) == 1) {
1050                   if (goodRecovery) {
1051                     h2TBMTypeRP[index]->Fill(2, plane);
1052                   } else {
1053                     h2TBMTypeUnidDet->Fill(2, dit->fedId());
1054                   }
1055                   if (fillFED)
1056                     h2TBMTypeFED[iFed]->Fill(2, chanNmbr);
1057                 }
1058                 if (((stateMach >> DB2_shift) & DataBit_mask) == 1) {
1059                   if (goodRecovery) {
1060                     h2TBMTypeRP[index]->Fill(3, plane);
1061                   } else {
1062                     h2TBMTypeUnidDet->Fill(3, dit->fedId());
1063                   }
1064                   if (fillFED)
1065                     h2TBMTypeFED[iFed]->Fill(3, chanNmbr);
1066                 }
1067                 if (((stateMach >> DB3_shift) & DataBit_mask) == 1) {
1068                   if (goodRecovery) {
1069                     h2TBMTypeRP[index]->Fill(4, plane);
1070                   } else {
1071                     h2TBMTypeUnidDet->Fill(4, dit->fedId());
1072                   }
1073                   if (fillFED)
1074                     h2TBMTypeFED[iFed]->Fill(4, chanNmbr);
1075                 }
1076               }
1077             }
1078             if (fillFED)
1079               h2ErrorCodeFED[iFed]->Fill(dit->errorType(), chanNmbr);
1080           }
1081           continue;
1082         }  // if idet == 15
1083         if (verbosity > 1)
1084           LogPrint("CTPPSPixelDQMSource") << "not CTPPS: ds_error.id" << ds_error.id;
1085         continue;
1086       }  // end of dummy detId block
1087 
1088       int plane = getPixPlane(ds_error.id);
1089       CTPPSDetId theId(ds_error.id);
1090       int arm = theId.arm() & 0x1;
1091       int station = theId.station() & 0x3;
1092       int rpot = theId.rp() & 0x7;
1093       int rpInd = getRPindex(arm, station, rpot);
1094       RPactivity[rpInd] = 1;
1095       CTPPSPixelDetId IDD(ds_error.id);
1096 
1097       if (StationStatus[station] && RPstatus[station][rpot]) {
1098         int index = getRPindex(arm, station, rpot);
1099         for (DetSet<CTPPSPixelDataError>::const_iterator dit = ds_error.begin(); dit != ds_error.end(); ++dit) {
1100           if (RPindexValid[index]) {
1101             if (!isPlanePlotsTurnedOff[arm][station][rpot][plane]) {
1102               h2ErrorCodeRP[index]->Fill(dit->errorType(), plane);
1103               // recover fed channel number
1104               int chanNmbr = -1;
1105               if (dit->errorType() == 32 || dit->errorType() == 33 || dit->errorType() == 34) {
1106                 long long errorWord = dit->errorWord64();  // for 64-bit error words
1107                 chanNmbr = (errorWord >> LINK_shift) & LINK_mask;
1108               } else {
1109                 uint32_t errorWord = dit->errorWord32();
1110                 chanNmbr = (errorWord >> LINK_shift) & LINK_mask;
1111               }
1112               bool fillFED = false;
1113               int iFed = dit->fedId() - minFedNumber;
1114               if (iFed >= 0 && iFed < numberOfFeds)
1115                 fillFED = true;
1116               if (dit->errorType() == 28) {  //error 28 = FIFO nearly full: identify FIFO and fill histogram
1117                 int fullType = -1;
1118                 uint32_t errorWord = dit->errorWord32();
1119                 int NFa = (errorWord >> DB0_shift) & DataBit_mask;
1120                 int NFb = (errorWord >> DB1_shift) & DataBit_mask;
1121                 int NFc = (errorWord >> DB2_shift) & DataBit_mask;
1122                 int NFd = (errorWord >> DB3_shift) & DataBit_mask;
1123                 int NFe = (errorWord >> DB4_shift) & DataBit_mask;
1124                 int NF2 = (errorWord >> DB6_shift) & DataBit_mask;
1125                 int L1A = (errorWord >> DB7_shift) & DataBit_mask;
1126                 if (NFa == 1) {
1127                   fullType = 1;
1128                   h2FullType->Fill((int)fullType, dit->fedId());
1129                 }
1130                 if (NFb == 1) {
1131                   fullType = 2;
1132                   h2FullType->Fill((int)fullType, dit->fedId());
1133                 }
1134                 if (NFc == 1) {
1135                   fullType = 3;
1136                   h2FullType->Fill((int)fullType, dit->fedId());
1137                 }
1138                 if (NFd == 1) {
1139                   fullType = 4;
1140                   h2FullType->Fill((int)fullType, dit->fedId());
1141                 }
1142                 if (NFe == 1) {
1143                   fullType = 5;
1144                   h2FullType->Fill((int)fullType, dit->fedId());
1145                 }
1146                 if (NF2 == 1) {
1147                   fullType = 6;
1148                   h2FullType->Fill((int)fullType, dit->fedId());
1149                 }
1150                 if (L1A == 1) {
1151                   fullType = 7;
1152                   h2FullType->Fill((int)fullType, dit->fedId());
1153                 }
1154               }
1155 
1156               if (dit->errorType() == 30) {  //error 30 = TBM error trailer
1157                 uint32_t errorWord = dit->errorWord32();
1158                 int t0 = (errorWord >> DB0_shift) & DataBit_mask;
1159                 int t1 = (errorWord >> DB1_shift) & DataBit_mask;
1160                 int t2 = (errorWord >> DB2_shift) & DataBit_mask;
1161                 int t3 = (errorWord >> DB3_shift) & DataBit_mask;
1162                 int t4 = (errorWord >> DB4_shift) & DataBit_mask;
1163                 int t5 = (errorWord >> DB5_shift) & DataBit_mask;
1164                 int t6 = (errorWord >> DB6_shift) & DataBit_mask;
1165                 int t7 = (errorWord >> DB7_shift) & DataBit_mask;
1166                 if (t0 == 1) {
1167                   h2TBMMessageRP[index]->Fill(0, plane);
1168                   if (fillFED)
1169                     h2TBMMessageFED[iFed]->Fill(0, chanNmbr);
1170                 }
1171                 if (t1 == 1) {
1172                   h2TBMMessageRP[index]->Fill(1, plane);
1173                   if (fillFED)
1174                     h2TBMMessageFED[iFed]->Fill(1, chanNmbr);
1175                 }
1176                 if (t2 == 1) {
1177                   h2TBMMessageRP[index]->Fill(2, plane);
1178                   if (fillFED)
1179                     h2TBMMessageFED[iFed]->Fill(2, chanNmbr);
1180                 }
1181                 if (t3 == 1) {
1182                   h2TBMMessageRP[index]->Fill(3, plane);
1183                   if (fillFED)
1184                     h2TBMMessageFED[iFed]->Fill(3, chanNmbr);
1185                 }
1186                 if (t4 == 1) {
1187                   h2TBMMessageRP[index]->Fill(4, plane);
1188                   if (fillFED)
1189                     h2TBMMessageFED[iFed]->Fill(4, chanNmbr);
1190                 }
1191                 if (t5 == 1) {
1192                   h2TBMMessageRP[index]->Fill(5, plane);
1193                   if (fillFED)
1194                     h2TBMMessageFED[iFed]->Fill(5, chanNmbr);
1195                 }
1196                 if (t6 == 1) {
1197                   h2TBMMessageRP[index]->Fill(6, plane);
1198                   if (fillFED)
1199                     h2TBMMessageFED[iFed]->Fill(6, chanNmbr);
1200                 }
1201                 if (t7 == 1) {
1202                   h2TBMMessageRP[index]->Fill(7, plane);
1203                   if (fillFED)
1204                     h2TBMMessageFED[iFed]->Fill(7, chanNmbr);
1205                 }
1206                 int stateMach_bits = 4;
1207                 int stateMach_shift = 8;
1208                 uint32_t stateMach_mask = ~(~uint32_t(0) << stateMach_bits);
1209                 uint32_t stateMach = (errorWord >> stateMach_shift) & stateMach_mask;
1210                 if (stateMach == 0) {
1211                   h2TBMTypeRP[index]->Fill(0, plane);
1212                   if (fillFED)
1213                     h2TBMTypeFED[iFed]->Fill(0, chanNmbr);
1214                 } else {
1215                   if (((stateMach >> DB0_shift) & DataBit_mask) == 1) {
1216                     h2TBMTypeRP[index]->Fill(1, plane);
1217                     if (fillFED)
1218                       h2TBMTypeFED[iFed]->Fill(1, chanNmbr);
1219                   }
1220                   if (((stateMach >> DB1_shift) & DataBit_mask) == 1) {
1221                     h2TBMTypeRP[index]->Fill(2, plane);
1222                     if (fillFED)
1223                       h2TBMTypeFED[iFed]->Fill(2, chanNmbr);
1224                   }
1225                   if (((stateMach >> DB2_shift) & DataBit_mask) == 1) {
1226                     h2TBMTypeRP[index]->Fill(3, plane);
1227                     if (fillFED)
1228                       h2TBMTypeFED[iFed]->Fill(3, chanNmbr);
1229                   }
1230                   if (((stateMach >> DB3_shift) & DataBit_mask) == 1) {
1231                     h2TBMTypeRP[index]->Fill(4, plane);
1232                     if (fillFED)
1233                       h2TBMTypeFED[iFed]->Fill(4, chanNmbr);
1234                   }
1235                 }
1236               }
1237               if (fillFED)
1238                 h2ErrorCodeFED[iFed]->Fill(dit->errorType(), chanNmbr);
1239             }
1240           }  // end if(RPindexValid[index]) {
1241         }
1242       }  // end  if(StationStatus[station]) {
1243     }    // end for(const auto &ds_error : *pixDigi)
1244   }      // if(pixError.isValid())
1245 
1246   if (pixClus.isValid() && onlinePlots)
1247     for (const auto &ds : *pixClus) {
1248       int idet = getDet(ds.id);
1249       if (idet != DetId::VeryForward && verbosity > 1) {
1250         LogPrint("CTPPSPixelDQMSource") << "not CTPPS: cluster.id" << ds.id;
1251         continue;
1252       }
1253 
1254       CTPPSDetId theId(ds.id);
1255       int plane = getPixPlane(ds.id);
1256       int arm = theId.arm() & 0x1;
1257       int station = theId.station() & 0x3;
1258       int rpot = theId.rp() & 0x7;
1259 
1260       if ((StationStatus[station] == 0) || (RPstatus[station][rpot] == 0))
1261         continue;
1262 
1263       for (const auto &p : ds) {
1264         int clusize = p.size();
1265 
1266         if (clusize > ClusterSizeMax)
1267           clusize = ClusterSizeMax;
1268 
1269         h2CluSize[arm][station]->Fill(prIndex(rpot, plane), clusize);
1270       }
1271     }  // end if(pixClus.isValid()) for(const auto &ds : *pixClus)
1272 
1273   bool allRPactivity = false;
1274   for (int rp = 0; rp < RPotsTotalNumber; rp++)
1275     if (RPactivity[rp] > 0)
1276       allRPactivity = true;
1277   for (int arm = 0; arm < 2; arm++) {
1278     for (int stn = 0; stn < NStationMAX; stn++) {
1279       for (int rp = 0; rp < NRPotsMAX; rp++) {
1280         int index = getRPindex(arm, stn, rp);
1281         if (RPindexValid[index] == 0)
1282           continue;
1283 
1284         if (onlinePlots)
1285           hpRPactive->Fill(getRPglobalBin(arm, stn), RPactivity[index]);
1286         //        if(RPactivity[index]==0) continue;
1287         if (!allRPactivity)
1288           continue;
1289         if (onlinePlots)
1290           hpixLTrack->Fill(getRPglobalBin(arm, stn), pixRPTracks[index]);
1291         int ntr = pixRPTracks[index];
1292         if (ntr > NLocalTracksMAX)
1293           ntr = NLocalTracksMAX;
1294         for (int i = 0; i <= NLocalTracksMAX; i++) {
1295           if (i == ntr)
1296             htrackMult[index]->Fill(ntr, 1.);
1297           else
1298             htrackMult[index]->Fill(i, 0.);
1299         }
1300 
1301         int np = 0;
1302         for (int p = 0; p < NplaneMAX; p++)
1303           if (HitsMultPlane[index][p] > 0)
1304             np++;
1305         for (int p = 0; p <= NplaneMAX; p++) {
1306           if (p == np)
1307             hRPotActivPlanes[index]->Fill(p, 1.);
1308           else
1309             hRPotActivPlanes[index]->Fill(p, 0.);
1310         }
1311         if (onlinePlots) {
1312           if (np >= 5)
1313             hRPotActivBX[index]->Fill(event.bunchCrossing());
1314           hRPotActivBXall[index]->Fill(event.bunchCrossing(), float(RPdigiSize[index]));
1315         }
1316 
1317         // Select only events from the desired random trigger and fill the histogram
1318         const edm::TriggerNames &trigNames = event.triggerNames(*hltResults);
1319         for (int p = 0; p < NplaneMAX; p++) {
1320           for (unsigned int i = 0; i < trigNames.size(); i++) {
1321             const std::string &triggerName = trigNames.triggerName(i);
1322             if ((hltResults->accept(i) > 0) && (triggerName == randomHLTPath))
1323               h2HitsVsBXRandoms[index]->Fill(event.bunchCrossing(), p, HitsMultPlane[index][p]);
1324           }
1325         }
1326 
1327         int planesFiredAtROC[NROCsMAX];  // how many planes registered hits on ROC r
1328         for (int r = 0; r < NROCsMAX; r++)
1329           planesFiredAtROC[r] = 0;
1330         for (int p = 0; p < NplaneMAX; p++) {
1331           int indp = getPlaneIndex(arm, stn, rp, p);
1332           for (int r = 0; r < NROCsMAX; r++)
1333             if (HitsMultROC[indp][r] > 0)
1334               ++planesFiredAtROC[r];
1335           for (int r = 0; r < NROCsMAX; r++) {
1336             if (onlinePlots)
1337               h2HitsMultROC[index]->Fill(p, r, HitsMultROC[indp][r]);
1338             hp2HitsMultROC_LS[index]->Fill(lumiId, p * NROCsMAX + r, HitsMultROC[indp][r]);
1339           }
1340         }
1341         int max = 0;
1342         for (int r = 0; r < NROCsMAX; r++)
1343           if (max < planesFiredAtROC[r])
1344             max = planesFiredAtROC[r];
1345         if (max >= 4 && onlinePlots)  // fill only if there are at least 4 aligned ROCs firing
1346           hRPotActivBXroc[index]->Fill(event.bunchCrossing());
1347         if (max >= 3 && onlinePlots)  // fill only if there are at least 3 aligned ROCs firing
1348           hRPotActivBXroc_3[index]->Fill(event.bunchCrossing());
1349         if (max >= 2 && onlinePlots)  // fill only if there are at least 2 aligned ROCs firing
1350           hRPotActivBXroc_2[index]->Fill(event.bunchCrossing());
1351       }  // end for(int rp=0; rp<NRPotsMAX; rp++) {
1352     }
1353   }  // end for(int arm=0; arm<2; arm++) {
1354 
1355   if ((nEvents % 100))
1356     return;
1357   if (verbosity)
1358     LogPrint("CTPPSPixelDQMSource") << "analyze event " << nEvents;
1359 }
1360 
1361 //---------------------------------------------------------------------------
1362 DEFINE_FWK_MODULE(CTPPSPixelDQMSource);