Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /****************************************************************************
0002 *
0003 * Authors:
0004 *   Jan Kašpar (jan.kaspar@gmail.com)
0005 *
0006 ****************************************************************************/
0007 
0008 #include "FWCore/Framework/interface/MakerMacros.h"
0009 #include "FWCore/Framework/interface/Event.h"
0010 #include "FWCore/Framework/interface/EventSetup.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/Utilities/interface/InputTag.h"
0013 
0014 #include "DQMServices/Core/interface/DQMEDAnalyzer.h"
0015 #include "DQMServices/Core/interface/DQMStore.h"
0016 
0017 #include "DataFormats/Common/interface/DetSetVector.h"
0018 #include "DataFormats/CTPPSDetId/interface/TotemRPDetId.h"
0019 #include "DataFormats/CTPPSReco/interface/TotemRPRecHit.h"
0020 #include "DataFormats/CTPPSReco/interface/TotemRPUVPattern.h"
0021 #include "DataFormats/CTPPSReco/interface/TotemRPLocalTrack.h"
0022 
0023 #include <string>
0024 #include <array>
0025 #include <map>
0026 
0027 //----------------------------------------------------------------------------------------------------
0028 
0029 class ElasticPlotDQMSource : public DQMEDAnalyzer {
0030 public:
0031   ElasticPlotDQMSource(const edm::ParameterSet &ps);
0032   ~ElasticPlotDQMSource() override;
0033 
0034 protected:
0035   void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
0036 
0037   void analyze(edm::Event const &e, edm::EventSetup const &eSetup) override;
0038 
0039 private:
0040   static constexpr double ls_duration_inverse = 1. / 23.357;  // s^-1
0041   static constexpr unsigned int ls_min = 0;
0042   static constexpr unsigned int ls_max = 2000;  // little more than 12h
0043 
0044   unsigned int verbosity;
0045 
0046   edm::EDGetTokenT<edm::DetSetVector<TotemRPRecHit>> tokenRecHit;
0047   edm::EDGetTokenT<edm::DetSetVector<TotemRPUVPattern>> tokenUVPattern;
0048   edm::EDGetTokenT<edm::DetSetVector<TotemRPLocalTrack>> tokenLocalTrack;
0049 
0050   /// plots related to one (anti)diagonal
0051   struct DiagonalPlots {
0052     // in the order 45-220-fr, 45-210-fr, 56-210-fr, 56-220-fr
0053     std::array<unsigned int, 4> rpIds;
0054 
0055     // track correlation in vertical RPs
0056     MonitorElement *h2_track_corr_vert = nullptr;
0057 
0058     // y distributions in a RP (1st index) with another RP (2nd index) in coincidence
0059     std::array<std::array<MonitorElement *, 4>, 4> v_h_y;
0060 
0061     // XY hit maps in a give RP (array index) under these conditions
0062     //   4rp: all 4 diagonal RPs have a track
0063     //   2rp: diagonal RPs in 220-fr have a track
0064     std::array<MonitorElement *, 4> v_h2_y_vs_x_dgn_4rp;
0065     std::array<MonitorElement *, 4> v_h2_y_vs_x_dgn_2rp;
0066 
0067     // event rates vs. time
0068     MonitorElement *h_rate_vs_time_dgn_4rp = nullptr;
0069     MonitorElement *h_rate_vs_time_dgn_2rp = nullptr;
0070 
0071     DiagonalPlots() {}
0072 
0073     DiagonalPlots(DQMStore::IBooker &ibooker, int _id);
0074   };
0075 
0076   std::map<unsigned int, DiagonalPlots> diagonalPlots;
0077 
0078   /// plots related to one RP
0079   struct PotPlots {
0080     // event rates vs. time
0081     //  suff = singal sufficient to reconstruct track
0082     //  track = track is reconstructed
0083     //  unresolved = suff && !track
0084     MonitorElement *h_rate_vs_time_suff = nullptr;
0085     MonitorElement *h_rate_vs_time_track = nullptr;
0086     MonitorElement *h_rate_vs_time_unresolved = nullptr;
0087 
0088     PotPlots() {}
0089     PotPlots(DQMStore::IBooker &ibooker, unsigned int id);
0090   };
0091 
0092   std::map<unsigned int, PotPlots> potPlots;
0093 };
0094 
0095 //----------------------------------------------------------------------------------------------------
0096 //----------------------------------------------------------------------------------------------------
0097 
0098 using namespace std;
0099 using namespace edm;
0100 
0101 //----------------------------------------------------------------------------------------------------
0102 
0103 ElasticPlotDQMSource::DiagonalPlots::DiagonalPlots(DQMStore::IBooker &ibooker, int id) {
0104   // determine captions
0105   bool top45 = id & 2;
0106   bool top56 = id & 1;
0107   bool diag = (top45 != top56);
0108 
0109   string name = string((diag) ? "diagonal" : "antidiagonal") + " 45" + ((top45) ? "top" : "bot") + " - 56" +
0110                 ((top56) ? "top" : "bot");
0111 
0112   const string &title = name;
0113 
0114   // dermine RP ids of this diagonal
0115   rpIds[0] = TotemRPDetId(0, 2, (top45) ? 4 : 5);
0116   rpIds[1] = TotemRPDetId(0, 0, (top45) ? 4 : 5);
0117   rpIds[2] = TotemRPDetId(1, 0, (top56) ? 4 : 5);
0118   rpIds[3] = TotemRPDetId(1, 2, (top56) ? 4 : 5);
0119 
0120   // book histograms
0121   ibooker.setCurrentFolder("CTPPS/TrackingStrip/" + name);
0122 
0123   h2_track_corr_vert = ibooker.book2D("track correlation in verticals", title + ";;", 4, -0.5, 3.5, 4, -0.5, 3.5);
0124   TH2F *h2 = h2_track_corr_vert->getTH2F();
0125   TAxis *xa = h2->GetXaxis(), *ya = h2->GetYaxis();
0126   for (unsigned int i = 0; i < 4; i++) {
0127     string rpName;
0128     TotemRPDetId(rpIds[i]).rpName(rpName, TotemRPDetId::nFull);
0129     rpName = rpName.substr(15);  // removes obvious prefix for better readability
0130 
0131     xa->SetBinLabel(i + 1, rpName.c_str());
0132     ya->SetBinLabel(i + 1, rpName.c_str());
0133   }
0134 
0135   h_rate_vs_time_dgn_4rp =
0136       ibooker.book1D("rate - 4 RPs", title + ";lumi section", ls_max - ls_min + 1, -0.5 + ls_min, +0.5 + ls_max);
0137   h_rate_vs_time_dgn_2rp = ibooker.book1D(
0138       "rate - 2 RPs (220-fr)", title + ";lumi section", ls_max - ls_min + 1, -0.5 + ls_min, +0.5 + ls_max);
0139 
0140   for (unsigned int i = 0; i < 4; i++) {
0141     string rpName;
0142     TotemRPDetId(rpIds[i]).rpName(rpName, TotemRPDetId::nFull);
0143     rpName = rpName.substr(15);
0144 
0145     ibooker.setCurrentFolder("CTPPS/TrackingStrip/" + name + "/xy hists");
0146 
0147     v_h2_y_vs_x_dgn_4rp[i] = ibooker.book2D(
0148         "xy hist - " + rpName + " - 4 RPs cond", title + ";x   (mm);y   (mm)", 100, -18., +18., 100, -18., +18.);
0149     v_h2_y_vs_x_dgn_2rp[i] = ibooker.book2D(
0150         "xy hist - " + rpName + " - 2 RPs cond", title + ";x   (mm);y   (mm)", 100, -18., +18., 100, -18., +18.);
0151 
0152     ibooker.setCurrentFolder("CTPPS/TrackingStrip/" + name + "/y hists");
0153 
0154     for (unsigned int j = 0; j < 4; j++) {
0155       string rpCoincName;
0156       TotemRPDetId(rpIds[j]).rpName(rpCoincName, TotemRPDetId::nFull);
0157       rpCoincName = rpCoincName.substr(15);
0158 
0159       v_h_y[i][j] =
0160           ibooker.book1D("y hist - " + rpName + " - coinc " + rpCoincName, title + ";y   (mm)", 180, -18., +18.);
0161     }
0162   }
0163 }
0164 
0165 //----------------------------------------------------------------------------------------------------
0166 
0167 ElasticPlotDQMSource::PotPlots::PotPlots(DQMStore::IBooker &ibooker, unsigned int id) {
0168   string path;
0169   TotemRPDetId(id).rpName(path, TotemRPDetId::nPath);
0170   ibooker.setCurrentFolder(path);
0171 
0172   string title;
0173   TotemRPDetId(id).rpName(title, TotemRPDetId::nFull);
0174 
0175   h_rate_vs_time_suff =
0176       ibooker.book1D("rate - suff", title + ";lumi section", ls_max - ls_min + 1, -0.5 + ls_min, +0.5 + ls_max);
0177   h_rate_vs_time_track =
0178       ibooker.book1D("rate - track", title + ";lumi section", ls_max - ls_min + 1, -0.5 + ls_min, +0.5 + ls_max);
0179   h_rate_vs_time_unresolved =
0180       ibooker.book1D("rate - unresolved", title + ";lumi section", ls_max - ls_min + 1, -0.5 + ls_min, +0.5 + ls_max);
0181 }
0182 
0183 //----------------------------------------------------------------------------------------------------
0184 //----------------------------------------------------------------------------------------------------
0185 
0186 ElasticPlotDQMSource::ElasticPlotDQMSource(const edm::ParameterSet &ps)
0187     : verbosity(ps.getUntrackedParameter<unsigned int>("verbosity", 0)) {
0188   tokenRecHit = consumes<edm::DetSetVector<TotemRPRecHit>>(ps.getUntrackedParameter<edm::InputTag>("tagRecHit"));
0189   tokenUVPattern = consumes<DetSetVector<TotemRPUVPattern>>(ps.getUntrackedParameter<edm::InputTag>("tagUVPattern"));
0190   tokenLocalTrack = consumes<DetSetVector<TotemRPLocalTrack>>(ps.getUntrackedParameter<edm::InputTag>("tagLocalTrack"));
0191 }
0192 
0193 //----------------------------------------------------------------------------------------------------
0194 
0195 ElasticPlotDQMSource::~ElasticPlotDQMSource() {}
0196 
0197 //----------------------------------------------------------------------------------------------------
0198 
0199 void ElasticPlotDQMSource::bookHistograms(DQMStore::IBooker &ibooker, edm::Run const &, edm::EventSetup const &) {
0200   ibooker.cd();
0201   ibooker.setCurrentFolder("CTPPS");
0202 
0203   // initialize (anti-)diagonal plots
0204   diagonalPlots[0] = DiagonalPlots(ibooker, 0);  // 45 bot - 56 bot
0205   diagonalPlots[1] = DiagonalPlots(ibooker, 1);  // 45 bot - 56 top
0206   diagonalPlots[2] = DiagonalPlots(ibooker, 2);  // 45 top - 56 bot
0207   diagonalPlots[3] = DiagonalPlots(ibooker, 3);  // 45 top - 56 top
0208 
0209   // loop over arms
0210   for (unsigned int arm = 0; arm < 2; arm++) {
0211     // loop over stations
0212     for (unsigned int st : {0, 2}) {
0213       // loop over RPs
0214       for (unsigned int rp : {4, 5}) {
0215         TotemRPDetId rpId(arm, st, rp);
0216         potPlots[rpId] = PotPlots(ibooker, rpId);
0217       }
0218     }
0219   }
0220 }
0221 
0222 //----------------------------------------------------------------------------------------------------
0223 
0224 void ElasticPlotDQMSource::analyze(edm::Event const &event, edm::EventSetup const &eventSetup) {
0225   // get event data
0226   Handle<DetSetVector<TotemRPRecHit>> hits;
0227   event.getByToken(tokenRecHit, hits);
0228 
0229   Handle<DetSetVector<TotemRPUVPattern>> patterns;
0230   event.getByToken(tokenUVPattern, patterns);
0231 
0232   Handle<DetSetVector<TotemRPLocalTrack>> tracks;
0233   event.getByToken(tokenLocalTrack, tracks);
0234 
0235   // check validity
0236   bool valid = true;
0237   valid &= hits.isValid();
0238   valid &= patterns.isValid();
0239   valid &= tracks.isValid();
0240 
0241   if (!valid) {
0242     if (verbosity) {
0243       LogProblem("ElasticPlotDQMSource") << "ERROR in ElasticPlotDQMSource::analyze > some of the required inputs are "
0244                                             "not valid. Skipping this event.\n"
0245                                          << "    hits.isValid = " << hits.isValid() << "\n"
0246                                          << "    patterns.isValid = " << patterns.isValid() << "\n"
0247                                          << "    tracks.isValid = " << tracks.isValid();
0248     }
0249 
0250     return;
0251   }
0252 
0253   //------------------------------
0254   // categorise RP data
0255   map<unsigned int, unsigned int> rp_planes_u_too_full, rp_planes_v_too_full;
0256   map<unsigned int, bool> rp_pat_suff;
0257   map<unsigned int, const TotemRPLocalTrack *> rp_track;
0258 
0259   for (const auto &ds : *hits) {
0260     TotemRPDetId detId(ds.detId());
0261     CTPPSDetId rpId = detId.rpId();
0262 
0263     if (ds.size() > 5) {
0264       if (detId.isStripsCoordinateUDirection())
0265         rp_planes_u_too_full[rpId]++;
0266       else
0267         rp_planes_v_too_full[rpId]++;
0268     }
0269   }
0270 
0271   for (auto &ds : *patterns) {
0272     CTPPSDetId rpId(ds.detId());
0273 
0274     // count U and V patterns
0275     unsigned int n_pat_u = 0, n_pat_v = 0;
0276     for (auto &p : ds) {
0277       if (!p.fittable())
0278         continue;
0279 
0280       if (p.projection() == TotemRPUVPattern::projU)
0281         n_pat_u++;
0282       else if (p.projection() == TotemRPUVPattern::projV)
0283         n_pat_v++;
0284     }
0285 
0286     rp_pat_suff[rpId] =
0287         (n_pat_u > 0 || rp_planes_u_too_full[rpId] >= 3) && (n_pat_v > 0 || rp_planes_v_too_full[rpId] >= 3);
0288   }
0289 
0290   for (auto &ds : *tracks) {
0291     CTPPSDetId rpId(ds.detId());
0292 
0293     const TotemRPLocalTrack *track = nullptr;
0294     for (auto &ft : ds) {
0295       if (ft.isValid()) {
0296         track = &ft;
0297         break;
0298       }
0299     }
0300 
0301     rp_track[rpId] = track;
0302   }
0303 
0304   //------------------------------
0305   // diagonal plots
0306 
0307   for (auto &dpp : diagonalPlots) {
0308     auto &dp = dpp.second;
0309 
0310     // determine diagonal conditions
0311     bool cond_4rp = true, cond_2rp = true;
0312     for (unsigned int i = 0; i < 4; i++) {
0313       if (rp_track[dp.rpIds[i]] == nullptr)
0314         cond_4rp = false;
0315 
0316       if ((i == 0 || i == 3) && rp_track[dp.rpIds[i]] == nullptr)
0317         cond_2rp = false;
0318     }
0319 
0320     if (cond_4rp)
0321       dp.h_rate_vs_time_dgn_4rp->Fill(event.luminosityBlock(), ls_duration_inverse);
0322 
0323     if (cond_2rp)
0324       dp.h_rate_vs_time_dgn_2rp->Fill(event.luminosityBlock(), ls_duration_inverse);
0325 
0326     for (unsigned int i = 0; i < 4; i++) {
0327       const TotemRPLocalTrack *tr_i = rp_track[dp.rpIds[i]];
0328 
0329       if (tr_i == nullptr)
0330         continue;
0331 
0332       if (cond_4rp)
0333         dp.v_h2_y_vs_x_dgn_4rp[i]->Fill(tr_i->x0(), tr_i->y0());
0334 
0335       if (cond_2rp)
0336         dp.v_h2_y_vs_x_dgn_2rp[i]->Fill(tr_i->x0(), tr_i->y0());
0337 
0338       for (unsigned int j = 0; j < 4; j++) {
0339         if (rp_track[dp.rpIds[j]] == nullptr)
0340           continue;
0341 
0342         dp.h2_track_corr_vert->Fill(i, j);
0343 
0344         dp.v_h_y[i][j]->Fill(tr_i->y0());
0345       }
0346     }
0347   }
0348 
0349   //------------------------------
0350   // pot plots
0351 
0352   for (const auto &p : rp_pat_suff) {
0353     const auto &rpId = p.first;
0354     auto pp_it = potPlots.find(rpId);
0355     if (pp_it == potPlots.end())
0356       continue;
0357     auto &pp = pp_it->second;
0358 
0359     const auto &pat_suff = rp_pat_suff[rpId];
0360     const auto &has_track = (rp_track[rpId] != nullptr);
0361 
0362     if (pat_suff)
0363       pp.h_rate_vs_time_suff->Fill(event.luminosityBlock(), ls_duration_inverse);
0364     if (has_track)
0365       pp.h_rate_vs_time_track->Fill(event.luminosityBlock(), ls_duration_inverse);
0366     if (pat_suff && !has_track)
0367       pp.h_rate_vs_time_unresolved->Fill(event.luminosityBlock(), ls_duration_inverse);
0368   }
0369 }
0370 
0371 //----------------------------------------------------------------------------------------------------
0372 
0373 DEFINE_FWK_MODULE(ElasticPlotDQMSource);