Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-10-01 22:40:29

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