Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-04 22:36:03

0001 /****************************************************************************
0002  *
0003  * This is a part of TotemDQM and TOTEM offline software.
0004  * Authors:
0005  *   Jan Kašpar (jan.kaspar@gmail.com)
0006  *
0007  ****************************************************************************/
0008 
0009 #include "FWCore/Framework/interface/MakerMacros.h"
0010 #include "FWCore/Framework/interface/Event.h"
0011 #include "FWCore/Framework/interface/EventSetup.h"
0012 #include "FWCore/Framework/interface/LuminosityBlock.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "FWCore/Utilities/interface/InputTag.h"
0015 
0016 #include "DQMServices/Core/interface/DQMOneEDAnalyzer.h"
0017 #include "DQMServices/Core/interface/DQMStore.h"
0018 
0019 #include "DataFormats/CTPPSDetId/interface/CTPPSDetId.h"
0020 #include "DataFormats/CTPPSReco/interface/CTPPSLocalTrackLite.h"
0021 #include "DataFormats/ProtonReco/interface/ForwardProton.h"
0022 #include "DataFormats/OnlineMetaData/interface/CTPPSRecord.h"
0023 
0024 #include <string>
0025 
0026 //----------------------------------------------------------------------------------------------------
0027 
0028 class CTPPSCommonDQMSource : public DQMOneEDAnalyzer<edm::LuminosityBlockCache<std::vector<int>>> {
0029 public:
0030   CTPPSCommonDQMSource(const edm::ParameterSet &ps);
0031   ~CTPPSCommonDQMSource() override;
0032 
0033 protected:
0034   void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
0035   void analyze(edm::Event const &e, edm::EventSetup const &eSetup) override;
0036   std::shared_ptr<std::vector<int>> globalBeginLuminosityBlock(const edm::LuminosityBlock &iLumi,
0037                                                                const edm::EventSetup &c) const override;
0038   void globalEndLuminosityBlock(const edm::LuminosityBlock &iLumi, const edm::EventSetup &c) override;
0039 
0040   void analyzeCTPPSRecord(edm::Event const &event, edm::EventSetup const &eventSetup);
0041   void analyzeTracks(edm::Event const &event, edm::EventSetup const &eventSetup);
0042   void analyzeProtons(edm::Event const &event, edm::EventSetup const &eventSetup);
0043 
0044 private:
0045   const unsigned int verbosity;
0046   constexpr static int MAX_VBINS = 20;
0047 
0048   const edm::EDGetTokenT<CTPPSRecord> ctppsRecordToken;
0049   const edm::EDGetTokenT<std::vector<CTPPSLocalTrackLite>> tokenLocalTrackLite;
0050   const edm::EDGetTokenT<std::vector<reco::ForwardProton>> tokenRecoProtons;
0051 
0052   bool makeProtonRecoPlots_;
0053   bool perLSsaving_;  //to avoid nanoDQMIO crashing, driven by  DQMServices/Core/python/DQMStore_cfi.py
0054 
0055   int currentLS;
0056   int endLS;
0057 
0058   std::vector<int> rpstate;
0059 
0060   /// plots related to the whole system
0061   struct GlobalPlots {
0062     MonitorElement *RPState = nullptr;
0063     MonitorElement *events_per_bx = nullptr, *events_per_bx_short = nullptr;
0064     MonitorElement *h_trackCorr_hor = nullptr, *h_trackCorr_vert = nullptr;
0065 
0066     void Init(DQMStore::IBooker &ibooker);
0067   };
0068 
0069   GlobalPlots globalPlots;
0070 
0071   /// plots related to one arm
0072   struct ArmPlots {
0073     int id;
0074 
0075     MonitorElement *h_numRPWithTrack_top = nullptr, *h_numRPWithTrack_hor = nullptr, *h_numRPWithTrack_bot = nullptr;
0076     MonitorElement *h_trackCorr = nullptr, *h_trackCorr_overlap = nullptr;
0077 
0078     MonitorElement *h_proton_xi = nullptr, *h_proton_th_x = nullptr, *h_proton_th_y = nullptr, *h_proton_t = nullptr,
0079                    *h_proton_time = nullptr;
0080 
0081     struct TrackingRPPlots {
0082       MonitorElement *h_x, *h_y;
0083     };
0084 
0085     std::map<unsigned int, TrackingRPPlots> trackingRPPlots;
0086 
0087     struct TimingRPPlots {
0088       MonitorElement *h_x, *h_time;
0089     };
0090 
0091     std::map<unsigned int, TimingRPPlots> timingRPPlots;
0092 
0093     ArmPlots() {}
0094 
0095     ArmPlots(DQMStore::IBooker &ibooker, int _id, bool makeProtonRecoPlots);
0096   };
0097 
0098   std::map<unsigned int, ArmPlots> armPlots;
0099 };
0100 
0101 //----------------------------------------------------------------------------------------------------
0102 //----------------------------------------------------------------------------------------------------
0103 
0104 using namespace std;
0105 using namespace edm;
0106 
0107 const int CTPPSCommonDQMSource::MAX_VBINS;
0108 
0109 //----------------------------------------------------------------------------------------------------
0110 
0111 void CTPPSCommonDQMSource::GlobalPlots::Init(DQMStore::IBooker &ibooker) {
0112   ibooker.setCurrentFolder("CTPPS/common");
0113 
0114   events_per_bx = ibooker.book1D("events per BX", "rp;Event.BX", 4002, -1.5, 4000. + 0.5);
0115   events_per_bx_short = ibooker.book1D("events per BX (short)", "rp;Event.BX", 102, -1.5, 100. + 0.5);
0116 
0117   /*
0118      RP State (HV & LV & Insertion):
0119      0 -> not used
0120      1 -> bad
0121      2 -> warning
0122      3 -> ok
0123   */
0124   RPState = ibooker.book2D(
0125       "rpstate per LS", "RP State per Lumisection;Luminosity Section;", 1000, 0, 1000, MAX_VBINS, 0., MAX_VBINS);
0126   {
0127     TH2F *hist = RPState->getTH2F();
0128     hist->SetCanExtend(TH2F::kXaxis);
0129     TAxis *ya = hist->GetYaxis();
0130     ya->SetBinLabel(1, "45, 210, FR-BT");
0131     ya->SetBinLabel(2, "45, 210, FR-HR");
0132     ya->SetBinLabel(3, "45, 210, FR-TP");
0133     ya->SetBinLabel(4, "45, 220, C1");
0134     ya->SetBinLabel(5, "45, 220, FR-BT");
0135     ya->SetBinLabel(6, "45, 220, FR-HR");
0136     ya->SetBinLabel(7, "45, 220, FR-TP");
0137     ya->SetBinLabel(8, "45, 220, NR-BT");
0138     ya->SetBinLabel(9, "45, 220, NR-HR");
0139     ya->SetBinLabel(10, "45, 220, NR-TP");
0140     ya->SetBinLabel(11, "56, 210, FR-BT");
0141     ya->SetBinLabel(12, "56, 210, FR-HR");
0142     ya->SetBinLabel(13, "56, 210, FR-TP");
0143     ya->SetBinLabel(14, "56, 220, C1");
0144     ya->SetBinLabel(15, "56, 220, FR-BT");
0145     ya->SetBinLabel(16, "56, 220, FR-HR");
0146     ya->SetBinLabel(17, "56, 220, FR-TP");
0147     ya->SetBinLabel(18, "56, 220, NR-BT");
0148     ya->SetBinLabel(19, "56, 220, NR-HR");
0149     ya->SetBinLabel(20, "56, 220, NR-TP");
0150   }
0151 
0152   h_trackCorr_hor = ibooker.book2D("track correlation hor", "ctpps_common_rp_hor", 8, -0.5, 7.5, 8, -0.5, 7.5);
0153   {
0154     TH2F *hist = h_trackCorr_hor->getTH2F();
0155     TAxis *xa = hist->GetXaxis(), *ya = hist->GetYaxis();
0156     xa->SetBinLabel(1, "45, 210, FR");
0157     ya->SetBinLabel(1, "45, 210, FR");
0158     xa->SetBinLabel(2, "45, 220, NR");
0159     ya->SetBinLabel(2, "45, 220, NR");
0160     xa->SetBinLabel(3, "45, 220, C1");
0161     ya->SetBinLabel(3, "45, 220, C1");
0162     xa->SetBinLabel(4, "45, 220, FR");
0163     ya->SetBinLabel(4, "45, 220, FR");
0164 
0165     xa->SetBinLabel(5, "56, 210, FR");
0166     ya->SetBinLabel(5, "56, 210, FR");
0167     xa->SetBinLabel(6, "56, 220, NR");
0168     ya->SetBinLabel(6, "56, 220, NR");
0169     xa->SetBinLabel(7, "56, 220, C1");
0170     ya->SetBinLabel(7, "56, 220, C1");
0171     xa->SetBinLabel(8, "56, 220, FR");
0172     ya->SetBinLabel(8, "56, 220, FR");
0173   }
0174 
0175   h_trackCorr_vert = ibooker.book2D("track correlation vert", "ctpps_common_rp_vert", 8, -0.5, 7.5, 8, -0.5, 7.5);
0176   {
0177     TH2F *hist = h_trackCorr_vert->getTH2F();
0178     TAxis *xa = hist->GetXaxis(), *ya = hist->GetYaxis();
0179     xa->SetBinLabel(1, "45, 210, FR-TP");
0180     ya->SetBinLabel(1, "45, 210, FR-TP");
0181     xa->SetBinLabel(2, "45, 210, FR-BT");
0182     ya->SetBinLabel(2, "45, 210, FR-BT");
0183     xa->SetBinLabel(3, "45, 220, FR-TP");
0184     ya->SetBinLabel(3, "45, 220, FR-TP");
0185     xa->SetBinLabel(4, "45, 220, FR-BT");
0186     ya->SetBinLabel(4, "45, 220, FR-BT");
0187     xa->SetBinLabel(5, "56, 210, FR-TP");
0188     ya->SetBinLabel(5, "56, 210, FR-TP");
0189     xa->SetBinLabel(6, "56, 210, FR-BT");
0190     ya->SetBinLabel(6, "56, 210, FR-BT");
0191     xa->SetBinLabel(7, "56, 220, FR-TP");
0192     ya->SetBinLabel(7, "56, 220, FR-TP");
0193     xa->SetBinLabel(8, "56, 220, FR-BT");
0194     ya->SetBinLabel(8, "56, 220, FR-BT");
0195   }
0196 }
0197 
0198 //----------------------------------------------------------------------------------------------------
0199 
0200 CTPPSCommonDQMSource::ArmPlots::ArmPlots(DQMStore::IBooker &ibooker, int _id, bool makeProtonRecoPlots) : id(_id) {
0201   string name;
0202   CTPPSDetId(CTPPSDetId::sdTrackingStrip, id, 0).armName(name, CTPPSDetId::nShort);
0203 
0204   ibooker.setCurrentFolder("CTPPS/common/sector " + name);
0205 
0206   string title = "ctpps_common_sector_" + name;
0207 
0208   h_numRPWithTrack_top =
0209       ibooker.book1D("number of top RPs with tracks", title + ";number of top RPs with tracks", 5, -0.5, 4.5);
0210   h_numRPWithTrack_hor =
0211       ibooker.book1D("number of hor RPs with tracks", title + ";number of hor RPs with tracks", 5, -0.5, 4.5);
0212   h_numRPWithTrack_bot =
0213       ibooker.book1D("number of bot RPs with tracks", title + ";number of bot RPs with tracks", 5, -0.5, 4.5);
0214 
0215   h_trackCorr = ibooker.book2D("track correlation", title, 8, -0.5, 7.5, 8, -0.5, 7.5);
0216   TH2F *h_trackCorr_h = h_trackCorr->getTH2F();
0217   TAxis *xa = h_trackCorr_h->GetXaxis(), *ya = h_trackCorr_h->GetYaxis();
0218   xa->SetBinLabel(1, "210, FR-HR");
0219   ya->SetBinLabel(1, "210, FR-HR");
0220   xa->SetBinLabel(2, "210, FR-TP");
0221   ya->SetBinLabel(2, "210, FR-TP");
0222   xa->SetBinLabel(3, "210, FR-BT");
0223   ya->SetBinLabel(3, "210, FR-BT");
0224   xa->SetBinLabel(4, "220, NR-HR");
0225   ya->SetBinLabel(4, "220, NR-HR");
0226   xa->SetBinLabel(5, "220, C1");
0227   ya->SetBinLabel(5, "220, C1");
0228   xa->SetBinLabel(6, "220, FR-HR");
0229   ya->SetBinLabel(6, "220, FR-HR");
0230   xa->SetBinLabel(7, "220, FR-TP");
0231   ya->SetBinLabel(7, "220, FR-TP");
0232   xa->SetBinLabel(8, "220, FR-BT");
0233   ya->SetBinLabel(8, "220, FR-BT");
0234 
0235   h_trackCorr_overlap = ibooker.book2D("track correlation hor-vert overlaps", title, 8, -0.5, 7.5, 8, -0.5, 7.5);
0236   h_trackCorr_h = h_trackCorr_overlap->getTH2F();
0237   xa = h_trackCorr_h->GetXaxis();
0238   ya = h_trackCorr_h->GetYaxis();
0239   xa->SetBinLabel(1, "210, FR-HR");
0240   ya->SetBinLabel(1, "210, FR-HR");
0241   xa->SetBinLabel(2, "210, FR-TP");
0242   ya->SetBinLabel(2, "210, FR-TP");
0243   xa->SetBinLabel(3, "210, FR-BT");
0244   ya->SetBinLabel(3, "210, FR-BT");
0245   xa->SetBinLabel(4, "220, NR-HR");
0246   ya->SetBinLabel(4, "220, NR-HR");
0247   xa->SetBinLabel(5, "220, C1");
0248   ya->SetBinLabel(5, "220, C1");
0249   xa->SetBinLabel(6, "220, FR-HR");
0250   ya->SetBinLabel(6, "220, FR-HR");
0251   xa->SetBinLabel(7, "220, FR-TP");
0252   ya->SetBinLabel(7, "220, FR-TP");
0253   xa->SetBinLabel(8, "220, FR-BT");
0254   ya->SetBinLabel(8, "220, FR-BT");
0255 
0256   if (makeProtonRecoPlots) {
0257     h_proton_xi = ibooker.book1D("proton xi", title + ";xi", 100, 0., 0.3);
0258     h_proton_th_x = ibooker.book1D("proton theta st x", ";#theta^{*}_{x}   (rad)", 250, -500E-6, +500E-6);
0259     h_proton_th_y = ibooker.book1D("proton theta st y", ";#theta^{*}_{y}   (rad)", 250, -500E-6, +500E-6);
0260     h_proton_t = ibooker.book1D("proton t", title + ";|t|   GeV^{2}", 100, 0., 5.);
0261     h_proton_time = ibooker.book1D("proton time", title + ";time   (ns)", 100, -1., 1.);
0262   }
0263 
0264   for (const unsigned int rpDecId : {3, 22, 16, 23}) {
0265     unsigned int st = rpDecId / 10, rp = rpDecId % 10, rpFullDecId = id * 100 + rpDecId;
0266     CTPPSDetId rpId(CTPPSDetId::sdTrackingStrip, id, st, rp);
0267     string stName, rpName;
0268     rpId.stationName(stName, CTPPSDetId::nShort);
0269     rpId.rpName(rpName, CTPPSDetId::nShort);
0270     rpName = stName + "_" + rpName;
0271 
0272     const bool timingRP = (rpDecId == 22 || rpDecId == 16);
0273 
0274     if (timingRP) {
0275       timingRPPlots[rpFullDecId] = {
0276           ibooker.book1D(rpName + " - track x histogram", title + "/" + rpName + ";track x   (mm)", 200, 0., 40.),
0277           ibooker.book1D(
0278               rpName + " - track time histogram", title + "/" + rpName + ";track time   (ns)", 100, -25., +50.)};
0279     } else {
0280       trackingRPPlots[rpFullDecId] = {
0281           ibooker.book1D(rpName + " - track x histogram", title + "/" + rpName + ";track x   (mm)", 200, 0., 40.),
0282           ibooker.book1D(rpName + " - track y histogram", title + "/" + rpName + ";track y   (mm)", 200, -20., +20.)};
0283     }
0284   }
0285 }
0286 
0287 //----------------------------------------------------------------------------------------------------
0288 //----------------------------------------------------------------------------------------------------
0289 
0290 CTPPSCommonDQMSource::CTPPSCommonDQMSource(const edm::ParameterSet &ps)
0291     : verbosity(ps.getUntrackedParameter<unsigned int>("verbosity", 0)),
0292       ctppsRecordToken(consumes<CTPPSRecord>(ps.getUntrackedParameter<edm::InputTag>("ctppsmetadata"))),
0293       tokenLocalTrackLite(
0294           consumes<vector<CTPPSLocalTrackLite>>(ps.getUntrackedParameter<edm::InputTag>("tagLocalTrackLite"))),
0295       tokenRecoProtons(
0296           consumes<std::vector<reco::ForwardProton>>(ps.getUntrackedParameter<InputTag>("tagRecoProtons"))),
0297       makeProtonRecoPlots_(ps.getParameter<bool>("makeProtonRecoPlots")),
0298       perLSsaving_(ps.getUntrackedParameter<bool>("perLSsaving", false)) {
0299   currentLS = 0;
0300   endLS = 0;
0301   rpstate.clear();
0302 }
0303 
0304 //----------------------------------------------------------------------------------------------------
0305 
0306 CTPPSCommonDQMSource::~CTPPSCommonDQMSource() {}
0307 
0308 //----------------------------------------------------------------------------------------------------
0309 
0310 void CTPPSCommonDQMSource::bookHistograms(DQMStore::IBooker &ibooker, edm::Run const &, edm::EventSetup const &) {
0311   // global plots
0312   globalPlots.Init(ibooker);
0313 
0314   // loop over arms
0315   for (unsigned int arm = 0; arm < 2; arm++) {
0316     armPlots[arm] = ArmPlots(ibooker, arm, makeProtonRecoPlots_);
0317   }
0318 }
0319 
0320 //----------------------------------------------------------------------------------------------------
0321 
0322 void CTPPSCommonDQMSource::analyze(edm::Event const &event, edm::EventSetup const &eventSetup) {
0323   analyzeCTPPSRecord(event, eventSetup);
0324   analyzeTracks(event, eventSetup);
0325 
0326   if (makeProtonRecoPlots_)
0327     analyzeProtons(event, eventSetup);
0328 }
0329 
0330 //----------------------------------------------------------------------------------------------------
0331 
0332 void CTPPSCommonDQMSource::analyzeCTPPSRecord(edm::Event const &event, edm::EventSetup const &eventSetup) {
0333   Handle<CTPPSRecord> hCTPPSRecord;
0334   event.getByToken(ctppsRecordToken, hCTPPSRecord);
0335 
0336   if (!hCTPPSRecord.isValid()) {
0337     if (verbosity)
0338       LogProblem("CTPPSCommonDQMSource") << "ERROR in CTPPSCommonDQMSource::analyzeCTPPSRecord > input not available.";
0339 
0340     return;
0341   }
0342 
0343   auto &rpstate = *luminosityBlockCache(event.getLuminosityBlock().index());
0344   if (rpstate.empty()) {
0345     rpstate.reserve(CTPPSRecord::RomanPot::Last);
0346     for (uint8_t i = 0; i < CTPPSRecord::RomanPot::Last; ++i)
0347       rpstate.push_back(hCTPPSRecord->status(i));
0348   }
0349 }
0350 
0351 //----------------------------------------------------------------------------------------------------
0352 
0353 void CTPPSCommonDQMSource::analyzeTracks(edm::Event const &event, edm::EventSetup const &eventSetup) {
0354   // get event data
0355   Handle<vector<CTPPSLocalTrackLite>> hTracks;
0356   event.getByToken(tokenLocalTrackLite, hTracks);
0357 
0358   // check validity
0359   if (!hTracks.isValid()) {
0360     if (verbosity)
0361       LogProblem("CTPPSCommonDQMSource") << "ERROR in CTPPSCommonDQMSource::analyzeTracks > input not available.";
0362 
0363     return;
0364   }
0365 
0366   //------------------------------
0367   // collect indeces of RP with tracks, for each correlation plot
0368   set<signed int> s_rp_idx_global_hor, s_rp_idx_global_vert;
0369   map<unsigned int, set<signed int>> ms_rp_idx_arm;
0370 
0371   for (auto &tr : *hTracks) {
0372     const CTPPSDetId rpId(tr.rpId());
0373     const unsigned int arm = rpId.arm();
0374     const unsigned int stNum = rpId.station();
0375     const unsigned int rpNum = rpId.rp();
0376     const unsigned int stRPNum = stNum * 10 + rpNum;
0377 
0378     {
0379       signed int idx = -1;
0380       if (stRPNum == 3)
0381         idx = 0;
0382       if (stRPNum == 22)
0383         idx = 1;
0384       if (stRPNum == 16)
0385         idx = 2;
0386       if (stRPNum == 23)
0387         idx = 3;
0388 
0389       if (idx >= 0)
0390         s_rp_idx_global_hor.insert(4 * arm + idx);
0391     }
0392 
0393     {
0394       signed int idx = -1;
0395       if (stRPNum == 4)
0396         idx = 0;
0397       if (stRPNum == 5)
0398         idx = 1;
0399       if (stRPNum == 24)
0400         idx = 2;
0401       if (stRPNum == 25)
0402         idx = 3;
0403 
0404       if (idx >= 0)
0405         s_rp_idx_global_vert.insert(4 * arm + idx);
0406     }
0407 
0408     {
0409       signed int idx = -1;
0410       if (stRPNum == 3)
0411         idx = 0;
0412       if (stRPNum == 4)
0413         idx = 1;
0414       if (stRPNum == 5)
0415         idx = 2;
0416       if (stRPNum == 22)
0417         idx = 3;
0418       if (stRPNum == 16)
0419         idx = 4;
0420       if (stRPNum == 23)
0421         idx = 5;
0422       if (stRPNum == 24)
0423         idx = 6;
0424       if (stRPNum == 25)
0425         idx = 7;
0426 
0427       const signed int hor = ((rpNum == 2) || (rpNum == 3) || (rpNum == 6)) ? 1 : 0;
0428 
0429       if (idx >= 0)
0430         ms_rp_idx_arm[arm].insert(idx * 10 + hor);
0431     }
0432   }
0433 
0434   //------------------------------
0435   // Global Plots
0436 
0437   globalPlots.events_per_bx->Fill(event.bunchCrossing());
0438   globalPlots.events_per_bx_short->Fill(event.bunchCrossing());
0439 
0440   for (const auto &idx1 : s_rp_idx_global_hor)
0441     for (const auto &idx2 : s_rp_idx_global_hor)
0442       globalPlots.h_trackCorr_hor->Fill(idx1, idx2);
0443 
0444   for (const auto &idx1 : s_rp_idx_global_vert)
0445     for (const auto &idx2 : s_rp_idx_global_vert)
0446       globalPlots.h_trackCorr_vert->Fill(idx1, idx2);
0447 
0448   //------------------------------
0449   // Arm Plots
0450 
0451   map<unsigned int, set<unsigned int>> mTop, mHor, mBot;
0452 
0453   for (auto &tr : *hTracks) {
0454     CTPPSDetId rpId(tr.rpId());
0455     const unsigned int rpNum = rpId.rp();
0456     const unsigned int armIdx = rpId.arm();
0457 
0458     if (rpNum == 0 || rpNum == 4)
0459       mTop[armIdx].insert(rpId);
0460     if (rpNum == 2 || rpNum == 3 || rpNum == 6)
0461       mHor[armIdx].insert(rpId);
0462     if (rpNum == 1 || rpNum == 5)
0463       mBot[armIdx].insert(rpId);
0464 
0465     auto &ap = armPlots[rpId.arm()];
0466     unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
0467 
0468     // fill in reference tracking-RP plots
0469     {
0470       auto it = ap.trackingRPPlots.find(rpDecId);
0471       if (it != ap.trackingRPPlots.end()) {
0472         it->second.h_x->Fill(tr.x());
0473         it->second.h_y->Fill(tr.y());
0474       }
0475     }
0476 
0477     // fill in reference timing-RP plots
0478     {
0479       auto it = ap.timingRPPlots.find(rpDecId);
0480       if (it != ap.timingRPPlots.end()) {
0481         it->second.h_x->Fill(tr.x());
0482         it->second.h_time->Fill(tr.time());
0483       }
0484     }
0485   }
0486 
0487   for (auto &p : armPlots) {
0488     p.second.h_numRPWithTrack_top->Fill(mTop[p.first].size());
0489     p.second.h_numRPWithTrack_hor->Fill(mHor[p.first].size());
0490     p.second.h_numRPWithTrack_bot->Fill(mBot[p.first].size());
0491   }
0492 
0493   //------------------------------
0494   // Correlation plots
0495 
0496   for (const auto &ap : ms_rp_idx_arm) {
0497     auto &plots = armPlots[ap.first];
0498 
0499     for (const auto &idx1 : ap.second) {
0500       for (const auto &idx2 : ap.second) {
0501         plots.h_trackCorr->Fill(idx1 / 10, idx2 / 10);
0502 
0503         if ((idx1 % 10) != (idx2 % 10))
0504           plots.h_trackCorr_overlap->Fill(idx1 / 10, idx2 / 10);
0505       }
0506     }
0507   }
0508 }
0509 
0510 //----------------------------------------------------------------------------------------------------
0511 
0512 void CTPPSCommonDQMSource::analyzeProtons(edm::Event const &event, edm::EventSetup const &eventSetup) {
0513   // get event data
0514   Handle<vector<reco::ForwardProton>> hRecoProtons;
0515   event.getByToken(tokenRecoProtons, hRecoProtons);
0516 
0517   // check validity
0518   if (!hRecoProtons.isValid()) {
0519     if (verbosity)
0520       LogProblem("CTPPSCommonDQMSource") << "ERROR in CTPPSCommonDQMSource::analyzeProtons > input not available.";
0521 
0522     return;
0523   }
0524 
0525   // loop over protons
0526   for (auto &p : *hRecoProtons) {
0527     if (!p.validFit())
0528       continue;
0529 
0530     signed int armIndex = -1;
0531     if (p.lhcSector() == reco::ForwardProton::LHCSector::sector45)
0532       armIndex = 0;
0533     if (p.lhcSector() == reco::ForwardProton::LHCSector::sector56)
0534       armIndex = 1;
0535     if (armIndex < 0)
0536       continue;
0537 
0538     auto &plots = armPlots[armIndex];
0539 
0540     plots.h_proton_xi->Fill(p.xi());
0541     plots.h_proton_th_x->Fill(p.thetaX());
0542     plots.h_proton_th_y->Fill(p.thetaY());
0543     plots.h_proton_t->Fill(fabs(p.t()));
0544     plots.h_proton_time->Fill(p.time());
0545   }
0546 }
0547 
0548 //----------------------------------------------------------------------------------------------------
0549 
0550 std::shared_ptr<std::vector<int>> CTPPSCommonDQMSource::globalBeginLuminosityBlock(const edm::LuminosityBlock &,
0551                                                                                    const edm::EventSetup &) const {
0552   return std::make_shared<std::vector<int>>();
0553 }
0554 
0555 //----------------------------------------------------------------------------------------------------
0556 
0557 void CTPPSCommonDQMSource::globalEndLuminosityBlock(const edm::LuminosityBlock &iLumi, const edm::EventSetup &c) {
0558   auto const &rpstate = *luminosityBlockCache(iLumi.index());
0559   auto currentLS = iLumi.id().luminosityBlock();
0560   if (!perLSsaving_) {
0561     for (std::vector<int>::size_type i = 0; i < rpstate.size(); i++)
0562       globalPlots.RPState->setBinContent(currentLS, i + 1, rpstate[i]);
0563   }
0564 }
0565 
0566 //----------------------------------------------------------------------------------------------------
0567 
0568 DEFINE_FWK_MODULE(CTPPSCommonDQMSource);