Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:58:32

0001 /****************************************************************************

0002 * Authors: 

0003 *  Jan Kašpar (jan.kaspar@gmail.com) 

0004 *  Mateusz Kocot (mateuszkocot99@gmail.com)

0005 ****************************************************************************/
0006 
0007 #include "DQMServices/Core/interface/DQMEDAnalyzer.h"
0008 #include "DQMServices/Core/interface/DQMStore.h"
0009 #include "DQMServices/Core/interface/MonitorElement.h"
0010 
0011 #include "FWCore/Framework/interface/ESHandle.h"
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013 #include "FWCore/Framework/interface/Event.h"
0014 #include "FWCore/Framework/interface/EventSetup.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016 #include "FWCore/Utilities/interface/InputTag.h"
0017 
0018 #include "DataFormats/CTPPSDetId/interface/CTPPSDetId.h"
0019 #include "DataFormats/CTPPSReco/interface/CTPPSLocalTrackLite.h"
0020 #include "DataFormats/CTPPSReco/interface/CTPPSLocalTrackLiteFwd.h"
0021 
0022 #include "CondFormats/PPSObjects/interface/PPSAlignmentConfiguration.h"
0023 #include "CondFormats/DataRecord/interface/PPSAlignmentConfigurationRcd.h"
0024 
0025 #include <map>
0026 #include <string>
0027 #include <cmath>
0028 #include <memory>
0029 
0030 #include "TH2D.h"
0031 #include "TGraph.h"
0032 
0033 //----------------------------------------------------------------------------------------------------

0034 
0035 class PPSAlignmentWorker : public DQMEDAnalyzer {
0036 public:
0037   PPSAlignmentWorker(const edm::ParameterSet& iConfig);
0038 
0039   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0040 
0041 private:
0042   void bookHistograms(DQMStore::IBooker& iBooker, edm::Run const&, edm::EventSetup const& iSetup) override;
0043   void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0044 
0045   // ------------ structures ------------

0046   struct SectorData {
0047     PPSAlignmentConfiguration::SectorConfig scfg_;
0048 
0049     // hit distributions

0050     std::map<unsigned int, MonitorElement*> m_h2_y_vs_x_bef_sel;
0051     std::map<unsigned int, MonitorElement*> m_h2_y_vs_x_mlt_sel;
0052     std::map<unsigned int, MonitorElement*> m_h2_y_vs_x_aft_sel;
0053 
0054     // cut plots

0055     MonitorElement* h_q_cut_h_bef;
0056     MonitorElement* h_q_cut_h_aft;
0057     MonitorElement* h2_cut_h_bef;
0058     MonitorElement* h2_cut_h_aft;
0059 
0060     MonitorElement* h_q_cut_v_bef;
0061     MonitorElement* h_q_cut_v_aft;
0062     MonitorElement* h2_cut_v_bef;
0063     MonitorElement* h2_cut_v_aft;
0064 
0065     // near-far plots

0066     MonitorElement* p_x_diffFN_vs_x_N;
0067     MonitorElement* p_y_diffFN_vs_y_F;
0068 
0069     struct SlicePlots {
0070       MonitorElement* h_y;
0071       MonitorElement* h2_y_diffFN_vs_y;
0072       MonitorElement* p_y_diffFN_vs_y;
0073 
0074       SlicePlots();
0075       SlicePlots(DQMStore::IBooker& iBooker, const PPSAlignmentConfiguration& cfg, bool debug);
0076       void fill(const double y, const double yDiff, const bool debug);
0077     };
0078 
0079     std::map<unsigned int, SlicePlots> x_slice_plots_N, x_slice_plots_F;
0080 
0081     void init(DQMStore::IBooker& iBooker,
0082               const PPSAlignmentConfiguration& cfg,
0083               const PPSAlignmentConfiguration::SectorConfig& scfg,
0084               const std::string& rootDir,
0085               bool debug);
0086 
0087     unsigned int process(const CTPPSLocalTrackLiteCollection& tracks, const PPSAlignmentConfiguration& cfg, bool debug);
0088   };
0089 
0090   // ------------ member data ------------

0091   const edm::ESGetToken<PPSAlignmentConfiguration, PPSAlignmentConfigurationRcd> esTokenBookHistograms_;
0092   const edm::ESGetToken<PPSAlignmentConfiguration, PPSAlignmentConfigurationRcd> esTokenAnalyze_;
0093 
0094   const std::vector<edm::InputTag> tracksTags_;
0095   std::vector<edm::EDGetTokenT<CTPPSLocalTrackLiteCollection>> tracksTokens_;
0096 
0097   SectorData sectorData45_;
0098   SectorData sectorData56_;
0099 
0100   const std::string dqmDir_;
0101   const bool debug_;
0102 };
0103 
0104 // -------------------------------- DQMEDAnalyzer methods --------------------------------

0105 
0106 PPSAlignmentWorker::PPSAlignmentWorker(const edm::ParameterSet& iConfig)
0107     : esTokenBookHistograms_(
0108           esConsumes<PPSAlignmentConfiguration, PPSAlignmentConfigurationRcd, edm::Transition::BeginRun>(
0109               edm::ESInputTag("", iConfig.getParameter<std::string>("label")))),
0110       esTokenAnalyze_(esConsumes<PPSAlignmentConfiguration, PPSAlignmentConfigurationRcd>(
0111           edm::ESInputTag("", iConfig.getParameter<std::string>("label")))),
0112       tracksTags_(iConfig.getParameter<std::vector<edm::InputTag>>("tracksTags")),
0113       dqmDir_(iConfig.getParameter<std::string>("dqm_dir")),
0114       debug_(iConfig.getParameter<bool>("debug")) {
0115   edm::LogInfo("PPSAlignmentWorker").log([&](auto& li) {
0116     li << "parameters:\n";
0117     li << "* label: " << iConfig.getParameter<std::string>("label") << "\n";
0118     li << "* tracksTags:\n";
0119     for (auto& tag : tracksTags_) {
0120       li << "    " << tag << ",\n";
0121     }
0122     li << "* dqm_dir: " << dqmDir_ << "\n";
0123     li << "* debug: " << std::boolalpha << debug_;
0124   });
0125 
0126   for (auto& tag : tracksTags_) {
0127     tracksTokens_.emplace_back(consumes<CTPPSLocalTrackLiteCollection>(tag));
0128   }
0129 }
0130 
0131 void PPSAlignmentWorker::bookHistograms(DQMStore::IBooker& iBooker, edm::Run const&, edm::EventSetup const& iSetup) {
0132   const auto& cfg = iSetup.getData(esTokenBookHistograms_);
0133 
0134   sectorData45_.init(iBooker, cfg, cfg.sectorConfig45(), dqmDir_ + "/worker", debug_);
0135   sectorData56_.init(iBooker, cfg, cfg.sectorConfig56(), dqmDir_ + "/worker", debug_);
0136 }
0137 
0138 void PPSAlignmentWorker::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0139   CTPPSLocalTrackLiteCollection tracks;
0140   bool foundProduct = false;
0141 
0142   for (unsigned int i = 0; i < tracksTokens_.size(); i++) {
0143     if (auto handle = iEvent.getHandle(tracksTokens_[i])) {
0144       tracks = *handle;
0145       foundProduct = true;
0146       edm::LogInfo("PPSAlignmentWorker") << "Found a product with " << tracksTags_[i];
0147       break;
0148     }
0149   }
0150   if (!foundProduct) {
0151     throw edm::Exception(edm::errors::ProductNotFound) << "Could not find a product with any of the selected labels.";
0152   }
0153 
0154   const auto& cfg = iSetup.getData(esTokenAnalyze_);
0155 
0156   sectorData45_.process(tracks, cfg, debug_);
0157   sectorData56_.process(tracks, cfg, debug_);
0158 }
0159 
0160 void PPSAlignmentWorker::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0161   edm::ParameterSetDescription desc;
0162 
0163   desc.add<std::string>("label", "");
0164   desc.add<std::vector<edm::InputTag>>("tracksTags", {edm::InputTag("ctppsLocalTrackLiteProducer")});
0165   desc.add<std::string>("dqm_dir", "AlCaReco/PPSAlignment");
0166   desc.add<bool>("debug", false);
0167 
0168   descriptions.addWithDefaultLabel(desc);
0169 }
0170 
0171 // -------------------------------- SectorData and SlicePlots methods --------------------------------

0172 
0173 PPSAlignmentWorker::SectorData::SlicePlots::SlicePlots() {}
0174 
0175 PPSAlignmentWorker::SectorData::SlicePlots::SlicePlots(DQMStore::IBooker& iBooker,
0176                                                        const PPSAlignmentConfiguration& cfg,
0177                                                        bool debug) {
0178   h_y = iBooker.book1DD(
0179       "h_y", ";y", cfg.binning().slice_n_bins_x_, cfg.binning().slice_x_min_, cfg.binning().slice_x_max_);
0180 
0181   auto profilePtr = std::make_unique<TProfile>(
0182       "", ";y;y_{F} - y_{N}", cfg.binning().slice_n_bins_x_, cfg.binning().slice_x_min_, cfg.binning().slice_x_max_);
0183   p_y_diffFN_vs_y = iBooker.bookProfile("p_y_diffFN_vs_y", profilePtr.get());
0184 
0185   if (debug)
0186     h2_y_diffFN_vs_y = iBooker.book2DD("h2_y_diffFN_vs_y",
0187                                        ";y;y_{F} - y_{N}",
0188                                        cfg.binning().slice_n_bins_x_,
0189                                        cfg.binning().slice_x_min_,
0190                                        cfg.binning().slice_x_max_,
0191                                        cfg.binning().slice_n_bins_y_,
0192                                        cfg.binning().slice_y_min_,
0193                                        cfg.binning().slice_y_max_);
0194 }
0195 
0196 void PPSAlignmentWorker::SectorData::SlicePlots::fill(const double y, const double yDiff, const bool debug) {
0197   h_y->Fill(y);
0198   p_y_diffFN_vs_y->Fill(y, yDiff);
0199   if (debug)
0200     h2_y_diffFN_vs_y->Fill(y, yDiff);
0201 }
0202 
0203 void PPSAlignmentWorker::SectorData::init(DQMStore::IBooker& iBooker,
0204                                           const PPSAlignmentConfiguration& cfg,
0205                                           const PPSAlignmentConfiguration::SectorConfig& scfg,
0206                                           const std::string& rootDir,
0207                                           bool debug) {
0208   scfg_ = scfg;
0209 
0210   // binning

0211   const double bin_size_x = cfg.binning().bin_size_x_;
0212   const unsigned int n_bins_x = cfg.binning().n_bins_x_;
0213 
0214   const double pixel_x_offset = cfg.binning().pixel_x_offset_;
0215 
0216   const double x_min_pix = pixel_x_offset, x_max_pix = pixel_x_offset + n_bins_x * bin_size_x;
0217   const double x_min_str = 0., x_max_str = n_bins_x * bin_size_x;
0218 
0219   const unsigned int n_bins_y = cfg.binning().n_bins_y_;
0220   const double y_min = cfg.binning().y_min_, y_max = cfg.binning().y_max_;
0221 
0222   // hit distributions

0223   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/before selection/" + scfg_.rp_N_.name_);
0224   m_h2_y_vs_x_bef_sel[scfg_.rp_N_.id_] =
0225       iBooker.book2DD("h2_y_vs_x", ";x;y", n_bins_x, x_min_str, x_max_str, n_bins_y, y_min, y_max);
0226   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/before selection/" + scfg_.rp_F_.name_);
0227   m_h2_y_vs_x_bef_sel[scfg_.rp_F_.id_] =
0228       iBooker.book2DD("h2_y_vs_x", ";x;y", n_bins_x, x_min_pix, x_max_pix, n_bins_y, y_min, y_max);
0229 
0230   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/multiplicity selection/" + scfg_.rp_N_.name_);
0231   m_h2_y_vs_x_mlt_sel[scfg_.rp_N_.id_] =
0232       iBooker.book2DD("h2_y_vs_x", ";x;y", n_bins_x, x_min_str, x_max_str, n_bins_y, y_min, y_max);
0233   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/multiplicity selection/" + scfg_.rp_F_.name_);
0234   m_h2_y_vs_x_mlt_sel[scfg_.rp_F_.id_] =
0235       iBooker.book2DD("h2_y_vs_x", ";x;y", n_bins_x, x_min_pix, x_max_pix, n_bins_y, y_min, y_max);
0236 
0237   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/after selection/" + scfg_.rp_N_.name_);
0238   m_h2_y_vs_x_aft_sel[scfg_.rp_N_.id_] =
0239       iBooker.book2DD("h2_y_vs_x", ";x;y", n_bins_x, x_min_str, x_max_str, n_bins_y, y_min, y_max);
0240   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/after selection/" + scfg_.rp_F_.name_);
0241   m_h2_y_vs_x_aft_sel[scfg_.rp_F_.id_] =
0242       iBooker.book2DD("h2_y_vs_x", ";x;y", n_bins_x, x_min_pix, x_max_pix, n_bins_y, y_min, y_max);
0243 
0244   // cut plots

0245   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/cuts/cut_h");
0246   h_q_cut_h_bef = iBooker.book1DD("h_q_cut_h_bef", ";cq_h", 400, -2., 2.);
0247   h_q_cut_h_aft = iBooker.book1DD("h_q_cut_h_aft", ";cq_h", 400, -2., 2.);
0248   h2_cut_h_bef =
0249       iBooker.book2DD("h2_cut_h_bef", ";x_up;x_dw", n_bins_x, x_min_str, x_max_str, n_bins_x, x_min_pix, x_max_pix);
0250   h2_cut_h_aft =
0251       iBooker.book2DD("h2_cut_h_aft", ";x_up;x_dw", n_bins_x, x_min_str, x_max_str, n_bins_x, x_min_pix, x_max_pix);
0252 
0253   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/cuts/cut_v");
0254   h_q_cut_v_bef = iBooker.book1DD("h_q_cut_v_bef", ";cq_v", 400, -2., 2.);
0255   h_q_cut_v_aft = iBooker.book1DD("h_q_cut_v_aft", ";cq_v", 400, -2., 2.);
0256   h2_cut_v_bef = iBooker.book2DD("h2_cut_v_bef", ";y_up;y_dw", n_bins_y, y_min, y_max, n_bins_y, y_min, y_max);
0257   h2_cut_v_aft = iBooker.book2DD("h2_cut_v_aft", ";y_up;y_dw", n_bins_y, y_min, y_max, n_bins_y, y_min, y_max);
0258 
0259   // near-far plots

0260   iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/near_far");
0261 
0262   auto profilePtr = std::make_unique<TProfile>("",
0263                                                ";x_{N};x_{F} - x_{N}",
0264                                                cfg.binning().diffFN_n_bins_x_,
0265                                                cfg.binning().diffFN_x_min_,
0266                                                cfg.binning().diffFN_x_max_);
0267   p_x_diffFN_vs_x_N = iBooker.bookProfile("p_x_diffFN_vs_x_N", profilePtr.get());
0268 
0269   // slice plots

0270   for (int i = 0; i < scfg_.rp_N_.x_slice_n_; i++) {
0271     const double x_min = scfg_.rp_N_.x_slice_min_ + i * scfg_.rp_N_.x_slice_w_;
0272     const double x_max = scfg_.rp_N_.x_slice_min_ + (i + 1) * scfg_.rp_N_.x_slice_w_;
0273 
0274     char buf[100];
0275     sprintf(buf, "%.1f-%.1f", x_min, x_max);
0276     std::replace(buf, buf + strlen(buf), '.', '_');  // replace . with _

0277     iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/near_far/x slices N/" + buf);
0278     x_slice_plots_N.insert({i, SlicePlots(iBooker, cfg, debug)});
0279   }
0280 
0281   for (int i = 0; i < scfg_.rp_F_.x_slice_n_; i++) {
0282     const double x_min = scfg_.rp_F_.x_slice_min_ + i * scfg_.rp_F_.x_slice_w_;
0283     const double x_max = scfg_.rp_F_.x_slice_min_ + (i + 1) * scfg_.rp_F_.x_slice_w_;
0284 
0285     char buf[100];
0286     sprintf(buf, "%.1f-%.1f", x_min, x_max);
0287     std::replace(buf, buf + strlen(buf), '.', '_');  // replace . with _

0288     iBooker.setCurrentFolder(rootDir + "/" + scfg_.name_ + "/near_far/x slices F/" + buf);
0289     x_slice_plots_F.insert({i, SlicePlots(iBooker, cfg, debug)});
0290   }
0291 }
0292 
0293 unsigned int PPSAlignmentWorker::SectorData::process(const CTPPSLocalTrackLiteCollection& tracks,
0294                                                      const PPSAlignmentConfiguration& cfg,
0295                                                      bool debug) {
0296   CTPPSLocalTrackLiteCollection tracksUp, tracksDw;
0297 
0298   for (const auto& tr : tracks) {
0299     CTPPSDetId rpId(tr.rpId());
0300     unsigned int rpDecId = rpId.arm() * 100 + rpId.station() * 10 + rpId.rp();
0301 
0302     if (rpDecId != scfg_.rp_N_.id_ && rpDecId != scfg_.rp_F_.id_)
0303       continue;
0304 
0305     // store the track in the right collection

0306     if (rpDecId == scfg_.rp_N_.id_)
0307       tracksUp.push_back(tr);
0308     if (rpDecId == scfg_.rp_F_.id_)
0309       tracksDw.push_back(tr);
0310   }
0311 
0312   // update plots before selection

0313   for (const auto& tr : tracksUp)
0314     m_h2_y_vs_x_bef_sel[scfg_.rp_N_.id_]->Fill(tr.x(), tr.y());
0315 
0316   for (const auto& tr : tracksDw)
0317     m_h2_y_vs_x_bef_sel[scfg_.rp_F_.id_]->Fill(tr.x(), tr.y());
0318 
0319   // skip crowded events (multiplicity selection)

0320   if (tracksUp.size() < cfg.minRPTracksSize() || tracksUp.size() > cfg.maxRPTracksSize())
0321     return 0;
0322 
0323   if (tracksDw.size() < cfg.minRPTracksSize() || tracksDw.size() > cfg.maxRPTracksSize())
0324     return 0;
0325 
0326   // update plots with multiplicity selection

0327   for (const auto& tr : tracksUp)
0328     m_h2_y_vs_x_mlt_sel[scfg_.rp_N_.id_]->Fill(tr.x(), tr.y());
0329 
0330   for (const auto& tr : tracksDw)
0331     m_h2_y_vs_x_mlt_sel[scfg_.rp_F_.id_]->Fill(tr.x(), tr.y());
0332 
0333   // do the selection

0334   unsigned int pairsSelected = 0;
0335   for (const auto& trUp : tracksUp) {
0336     for (const auto& trDw : tracksDw) {
0337       h2_cut_h_bef->Fill(trUp.x(), trDw.x());
0338       h2_cut_v_bef->Fill(trUp.y(), trDw.y());
0339 
0340       // horizontal cut

0341       const double cq_h = trDw.x() + scfg_.cut_h_a_ * trUp.x() + scfg_.cut_h_c_;
0342       h_q_cut_h_bef->Fill(cq_h);
0343       const bool cv_h = (std::fabs(cq_h) < cfg.n_si() * scfg_.cut_h_si_);
0344 
0345       // vertical cut

0346       const double cq_v = trDw.y() + scfg_.cut_v_a_ * trUp.y() + scfg_.cut_v_c_;
0347       h_q_cut_v_bef->Fill(cq_v);
0348       const bool cv_v = (std::fabs(cq_v) < cfg.n_si() * scfg_.cut_v_si_);
0349 
0350       bool cutsPassed = true;
0351       if (scfg_.cut_h_apply_)
0352         cutsPassed &= cv_h;
0353       if (scfg_.cut_v_apply_)
0354         cutsPassed &= cv_v;
0355 
0356       if (cutsPassed) {
0357         pairsSelected++;
0358 
0359         h_q_cut_h_aft->Fill(cq_h);
0360         h_q_cut_v_aft->Fill(cq_v);
0361 
0362         h2_cut_h_aft->Fill(trUp.x(), trDw.x());
0363         h2_cut_v_aft->Fill(trUp.y(), trDw.y());
0364 
0365         m_h2_y_vs_x_aft_sel[scfg_.rp_N_.id_]->Fill(trUp.x(), trUp.y());
0366         m_h2_y_vs_x_aft_sel[scfg_.rp_F_.id_]->Fill(trDw.x(), trDw.y());
0367 
0368         p_x_diffFN_vs_x_N->Fill(trUp.x(), trDw.x() - trUp.x());
0369 
0370         int idx = (trUp.x() - scfg_.rp_N_.x_slice_min_) / scfg_.rp_N_.x_slice_w_;
0371         if (idx >= 0 && idx < scfg_.rp_N_.x_slice_n_) {
0372           x_slice_plots_N[idx].fill(trUp.y(), trDw.y() - trUp.y(), debug);
0373         }
0374 
0375         idx = (trDw.x() - scfg_.rp_F_.x_slice_min_) / scfg_.rp_F_.x_slice_w_;
0376         if (idx >= 0 && idx < scfg_.rp_F_.x_slice_n_) {
0377           x_slice_plots_F[idx].fill(trDw.y(), trDw.y() - trUp.y(), debug);
0378         }
0379       }
0380     }
0381   }
0382 
0383   return pairsSelected;
0384 }
0385 
0386 DEFINE_FWK_MODULE(PPSAlignmentWorker);