Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:06:59

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