Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-09 00:01:04

0001 #ifndef L1Trigger_CSCTriggerPrimitives_CSCTriggerPrimitivesProducer_h
0002 #define L1Trigger_CSCTriggerPrimitives_CSCTriggerPrimitivesProducer_h
0003 
0004 /** \class CSCTriggerPrimitivesProducer
0005  *
0006  * Implementation of the local Level-1 Cathode Strip Chamber trigger.
0007  * Simulates functionalities of the anode and cathode Local Charged Tracks
0008  * (LCT) processors, of the Trigger Mother Board (TMB), and of the Muon Port
0009  * Card (MPC).
0010  *
0011  * Input to the simulation are collections of the CSC wire and comparator
0012  * digis.
0013  *
0014  * Produces four collections of the Level-1 CSC Trigger Primitives (track
0015  * stubs, or LCTs): anode LCTs (ALCTs), cathode LCTs (CLCTs), correlated
0016  * LCTs at TMB, and correlated LCTs at MPC.
0017  *
0018  * \author Slava Valuev, UCLA.
0019  *
0020  * The trigger primitive emulator has been expanded with options to
0021  * use both ALCTs, CLCTs and GEM clusters. The GEM-CSC integrated
0022  * local trigger combines ALCT, CLCT and GEM information to produce integrated
0023  * stubs. The available stub types can be found in the class definition of
0024  * CSCCorrelatedLCTDigi (DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigi.h)
0025  *
0026  * authors: Sven Dildick (TAMU), Tao Huang (TAMU)
0027  */
0028 
0029 #include "FWCore/Framework/interface/ConsumesCollector.h"
0030 #include "FWCore/Framework/interface/one/EDProducer.h"
0031 #include "FWCore/Framework/interface/Event.h"
0032 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0034 
0035 #include "DataFormats/Common/interface/Handle.h"
0036 #include "DataFormats/CSCDigi/interface/CSCALCTDigiCollection.h"
0037 #include "DataFormats/CSCDigi/interface/CSCCLCTDigiCollection.h"
0038 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiCollection.h"
0039 #include "DataFormats/CSCDigi/interface/CSCALCTPreTriggerDigiCollection.h"
0040 #include "DataFormats/CSCDigi/interface/CSCCLCTPreTriggerDigiCollection.h"
0041 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigiCollection.h"
0042 #include "DataFormats/CSCDigi/interface/CSCShowerDigiCollection.h"
0043 #include "DataFormats/CSCDigi/interface/CSCComparatorDigiCollection.h"
0044 #include "DataFormats/CSCDigi/interface/CSCWireDigiCollection.h"
0045 #include "DataFormats/GEMDigi/interface/GEMPadDigiClusterCollection.h"
0046 #include "DataFormats/GEMDigi/interface/GEMCoPadDigiCollection.h"
0047 #include "L1Trigger/CSCTriggerPrimitives/interface/CSCTriggerPrimitivesBuilder.h"
0048 #include "CondFormats/CSCObjects/interface/CSCDBL1TPParameters.h"
0049 #include "CondFormats/DataRecord/interface/CSCBadChambersRcd.h"
0050 #include "CondFormats/DataRecord/interface/CSCL1TPLookupTableCCLUTRcd.h"
0051 #include "CondFormats/DataRecord/interface/CSCL1TPLookupTableME11ILTRcd.h"
0052 #include "CondFormats/DataRecord/interface/CSCL1TPLookupTableME21ILTRcd.h"
0053 #include "CondFormats/DataRecord/interface/CSCDBL1TPParametersRcd.h"
0054 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0055 #include "Geometry/GEMGeometry/interface/GEMGeometry.h"
0056 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
0057 
0058 // temporarily switch to a "one" module with a CSCTriggerPrimitivesBuilder data member
0059 class CSCTriggerPrimitivesProducer : public edm::one::EDProducer<> {
0060 public:
0061   explicit CSCTriggerPrimitivesProducer(const edm::ParameterSet&);
0062   ~CSCTriggerPrimitivesProducer() override;
0063 
0064   void produce(edm::Event&, const edm::EventSetup&) override;
0065 
0066 private:
0067   // master configuration
0068   edm::ParameterSet config_;
0069 
0070   // temporarily switch to a "one" module with a CSCTriggerPrimitivesBuilder data member
0071   std::unique_ptr<CSCTriggerPrimitivesBuilder> builder_;
0072 
0073   // input tags for input collections
0074   edm::InputTag compDigiProducer_;
0075   edm::InputTag wireDigiProducer_;
0076   edm::InputTag gemPadDigiClusterProducer_;
0077 
0078   // tokens
0079   edm::EDGetTokenT<CSCComparatorDigiCollection> comp_token_;
0080   edm::EDGetTokenT<CSCWireDigiCollection> wire_token_;
0081   edm::EDGetTokenT<GEMPadDigiClusterCollection> gem_pad_cluster_token_;
0082   edm::ESGetToken<CSCGeometry, MuonGeometryRecord> cscToken_;
0083   edm::ESGetToken<GEMGeometry, MuonGeometryRecord> gemToken_;
0084   edm::ESGetToken<CSCBadChambers, CSCBadChambersRcd> pBadChambersToken_;
0085   edm::ESGetToken<CSCL1TPLookupTableCCLUT, CSCL1TPLookupTableCCLUTRcd> pLookupTableCCLUTToken_;
0086   edm::ESGetToken<CSCL1TPLookupTableME11ILT, CSCL1TPLookupTableME11ILTRcd> pLookupTableME11ILTToken_;
0087   edm::ESGetToken<CSCL1TPLookupTableME21ILT, CSCL1TPLookupTableME21ILTRcd> pLookupTableME21ILTToken_;
0088   edm::ESGetToken<CSCDBL1TPParameters, CSCDBL1TPParametersRcd> confToken_;
0089   // switch to force the use of parameters from config file rather then from DB
0090   bool debugParameters_;
0091 
0092   // switch to for enabling checking against the list of bad chambers
0093   bool checkBadChambers_;
0094 
0095   // Write out pre-triggers
0096   bool keepCLCTPreTriggers_;
0097   bool keepALCTPreTriggers_;
0098 
0099   // write out showrs
0100   bool keepShowers_;
0101 
0102   // switches to enable the Run-3 pattern finding
0103   bool runCCLUT_;       // 'OR' of the two options below
0104   bool runCCLUT_TMB_;   // ME1/2, ME1/3, ME2/2, ME3/2, ME4/2
0105   bool runCCLUT_OTMB_;  // ME1/1, ME2/1, ME3/1, ME4/1
0106 
0107   bool runILT_;  // // 'OR' of the two options below
0108   bool runME11ILT_;
0109   bool runME21ILT_;
0110 };
0111 
0112 #endif
0113 
0114 CSCTriggerPrimitivesProducer::CSCTriggerPrimitivesProducer(const edm::ParameterSet& conf) {
0115   config_ = conf;
0116 
0117   // if false, parameters will be read in from DB using EventSetup mechanism
0118   // else will use all parameters from the config file
0119   debugParameters_ = conf.getParameter<bool>("debugParameters");
0120 
0121   wireDigiProducer_ = conf.getParameter<edm::InputTag>("CSCWireDigiProducer");
0122   compDigiProducer_ = conf.getParameter<edm::InputTag>("CSCComparatorDigiProducer");
0123   gemPadDigiClusterProducer_ = conf.getParameter<edm::InputTag>("GEMPadDigiClusterProducer");
0124 
0125   checkBadChambers_ = conf.getParameter<bool>("checkBadChambers");
0126 
0127   keepCLCTPreTriggers_ = conf.getParameter<bool>("keepCLCTPreTriggers");
0128   keepALCTPreTriggers_ = conf.getParameter<bool>("keepALCTPreTriggers");
0129   keepShowers_ = conf.getParameter<bool>("keepShowers");
0130 
0131   // check whether you need to run the integrated local triggers
0132   const edm::ParameterSet commonParam(conf.getParameter<edm::ParameterSet>("commonParam"));
0133   runCCLUT_TMB_ = commonParam.getParameter<bool>("runCCLUT_TMB");
0134   runCCLUT_OTMB_ = commonParam.getParameter<bool>("runCCLUT_OTMB");
0135   runCCLUT_ = runCCLUT_TMB_ or runCCLUT_OTMB_;
0136 
0137   runME11ILT_ = commonParam.getParameter<bool>("runME11ILT");
0138   runME21ILT_ = commonParam.getParameter<bool>("runME21ILT");
0139   runILT_ = runME11ILT_ or runME21ILT_;
0140 
0141   wire_token_ = consumes<CSCWireDigiCollection>(wireDigiProducer_);
0142   comp_token_ = consumes<CSCComparatorDigiCollection>(compDigiProducer_);
0143   if (runILT_)
0144     gem_pad_cluster_token_ = consumes<GEMPadDigiClusterCollection>(gemPadDigiClusterProducer_);
0145 
0146   cscToken_ = esConsumes<CSCGeometry, MuonGeometryRecord>();
0147   gemToken_ = esConsumes<GEMGeometry, MuonGeometryRecord>();
0148   pBadChambersToken_ = esConsumes<CSCBadChambers, CSCBadChambersRcd>();
0149   // consume lookup tables only when flags are set
0150   if (runCCLUT_)
0151     pLookupTableCCLUTToken_ = esConsumes<CSCL1TPLookupTableCCLUT, CSCL1TPLookupTableCCLUTRcd>();
0152   if (runME11ILT_)
0153     pLookupTableME11ILTToken_ = esConsumes<CSCL1TPLookupTableME11ILT, CSCL1TPLookupTableME11ILTRcd>();
0154   if (runME21ILT_)
0155     pLookupTableME21ILTToken_ = esConsumes<CSCL1TPLookupTableME21ILT, CSCL1TPLookupTableME21ILTRcd>();
0156   confToken_ = esConsumes<CSCDBL1TPParameters, CSCDBL1TPParametersRcd>();
0157 
0158   // register what this produces
0159   produces<CSCALCTDigiCollection>();
0160   produces<CSCCLCTDigiCollection>();
0161   produces<CSCCLCTPreTriggerCollection>();
0162   if (keepCLCTPreTriggers_) {
0163     produces<CSCCLCTPreTriggerDigiCollection>();
0164   }
0165   if (keepALCTPreTriggers_) {
0166     produces<CSCALCTPreTriggerDigiCollection>();
0167   }
0168   produces<CSCCorrelatedLCTDigiCollection>();
0169   produces<CSCCorrelatedLCTDigiCollection>("MPCSORTED");
0170   if (keepShowers_) {
0171     produces<CSCShowerDigiCollection>();
0172     produces<CSCShowerDigiCollection>("Anode");
0173     produces<CSCShowerDigiCollection>("Cathode");
0174   }
0175   if (runILT_) {
0176     produces<GEMCoPadDigiCollection>();
0177   }
0178   // temporarily switch to a "one" module with a CSCTriggerPrimitivesBuilder data member
0179   builder_ = std::make_unique<CSCTriggerPrimitivesBuilder>(config_);
0180 }
0181 
0182 CSCTriggerPrimitivesProducer::~CSCTriggerPrimitivesProducer() {}
0183 
0184 void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup& setup) {
0185   // get the csc geometry
0186   builder_->setCSCGeometry(&setup.getData(cscToken_));
0187 
0188   // get the gem geometry if it's there
0189   edm::ESHandle<GEMGeometry> h_gem = setup.getHandle(gemToken_);
0190   if (runILT_) {
0191     if (h_gem.isValid()) {
0192       builder_->setGEMGeometry(&*h_gem);
0193     } else {
0194       edm::LogWarning("CSCTriggerPrimitivesProducer|NoGEMGeometry")
0195           << "GEM geometry is unavailable. Running CSC-only trigger algorithm. +++\n";
0196     }
0197   }
0198 
0199   // Find conditions data for bad chambers.
0200   edm::ESHandle<CSCBadChambers> pBadChambers = setup.getHandle(pBadChambersToken_);
0201 
0202   if (runCCLUT_) {
0203     edm::ESHandle<CSCL1TPLookupTableCCLUT> conf = setup.getHandle(pLookupTableCCLUTToken_);
0204     if (conf.product() == nullptr) {
0205       edm::LogError("CSCTriggerPrimitivesProducer")
0206           << "Failed to find a CSCL1TPLookupTableCCLUTRcd in EventSetup with runCCLUT_ on";
0207       return;
0208     }
0209     builder_->setESLookupTables(conf.product());
0210   }
0211 
0212   if (runME11ILT_) {
0213     edm::ESHandle<CSCL1TPLookupTableME11ILT> conf = setup.getHandle(pLookupTableME11ILTToken_);
0214     if (conf.product() == nullptr) {
0215       edm::LogError("CSCTriggerPrimitivesProducer")
0216           << "Failed to find a CSCL1TPLookupTableME11ILTRcd in EventSetup with runME11ILT_ on";
0217       return;
0218     }
0219     builder_->setESLookupTables(conf.product());
0220   }
0221 
0222   if (runME21ILT_) {
0223     edm::ESHandle<CSCL1TPLookupTableME21ILT> conf = setup.getHandle(pLookupTableME21ILTToken_);
0224     if (conf.product() == nullptr) {
0225       edm::LogError("CSCTriggerPrimitivesProducer")
0226           << "Failed to find a CSCL1TPLookupTableME21ILTRcd in EventSetup with runME21ILT_ on";
0227       return;
0228     }
0229     builder_->setESLookupTables(conf.product());
0230   }
0231 
0232   // If !debugParameters then get config parameters using EventSetup mechanism.
0233   // This must be done in produce() for every event and not in beginJob()
0234   // (see mail from Jim Brooke sent to hn-cms-L1TrigEmulator on July 30, 2007).
0235   if (!debugParameters_) {
0236     edm::ESHandle<CSCDBL1TPParameters> conf = setup.getHandle(confToken_);
0237     if (conf.product() == nullptr) {
0238       edm::LogError("CSCTriggerPrimitivesProducer|ConfigError")
0239           << "+++ Failed to find a CSCDBL1TPParametersRcd in EventSetup! +++\n"
0240           << "+++ Cannot continue emulation without these parameters +++\n";
0241       return;
0242     }
0243     builder_->setConfigParameters(conf.product());
0244   }
0245 
0246   // Get the collections of comparator & wire digis from event.
0247   edm::Handle<CSCComparatorDigiCollection> compDigis;
0248   edm::Handle<CSCWireDigiCollection> wireDigis;
0249   ev.getByToken(comp_token_, compDigis);
0250   ev.getByToken(wire_token_, wireDigis);
0251 
0252   // input GEM pad cluster collection for upgrade scenarios
0253   edm::Handle<GEMPadDigiClusterCollection> gemPadDigiClusters;
0254   const GEMPadDigiClusterCollection* gemPadClusters = nullptr;
0255 
0256   // Create empty collections of ALCTs, CLCTs, and correlated LCTs upstream
0257   // and downstream of MPC.
0258   std::unique_ptr<CSCALCTDigiCollection> oc_alct(new CSCALCTDigiCollection);
0259   std::unique_ptr<CSCCLCTDigiCollection> oc_clct(new CSCCLCTDigiCollection);
0260   std::unique_ptr<CSCCLCTPreTriggerDigiCollection> oc_clctpretrigger(new CSCCLCTPreTriggerDigiCollection);
0261   std::unique_ptr<CSCALCTPreTriggerDigiCollection> oc_alctpretrigger(new CSCALCTPreTriggerDigiCollection);
0262   std::unique_ptr<CSCCLCTPreTriggerCollection> oc_pretrig(new CSCCLCTPreTriggerCollection);
0263   std::unique_ptr<CSCCorrelatedLCTDigiCollection> oc_lct(new CSCCorrelatedLCTDigiCollection);
0264   std::unique_ptr<CSCCorrelatedLCTDigiCollection> oc_sorted_lct(new CSCCorrelatedLCTDigiCollection);
0265   std::unique_ptr<CSCShowerDigiCollection> oc_shower(new CSCShowerDigiCollection);
0266   std::unique_ptr<CSCShowerDigiCollection> oc_shower_anode(new CSCShowerDigiCollection);
0267   std::unique_ptr<CSCShowerDigiCollection> oc_shower_cathode(new CSCShowerDigiCollection);
0268   std::unique_ptr<GEMCoPadDigiCollection> oc_gemcopad(new GEMCoPadDigiCollection);
0269 
0270   if (!wireDigis.isValid()) {
0271     edm::LogWarning("CSCTriggerPrimitivesProducer|NoInputCollection")
0272         << "+++ Warning: Collection of wire digis with label " << wireDigiProducer_.label()
0273         << " requested in configuration, but not found in the event..."
0274         << " Skipping production of CSC TP digis +++\n";
0275   }
0276   if (!compDigis.isValid()) {
0277     edm::LogWarning("CSCTriggerPrimitivesProducer|NoInputCollection")
0278         << "+++ Warning: Collection of comparator digis with label " << compDigiProducer_.label()
0279         << " requested in configuration, but not found in the event..."
0280         << " Skipping production of CSC TP digis +++\n";
0281   }
0282   // the GEM-CSC trigger flag is set, so GEM clusters are expected in the event data
0283   if (runILT_) {
0284     // no valid label, let the user know that GEM clusters are missing
0285     // the algorithm should not crash. instead it should just produce the regular CSC LCTs
0286     // in ME1/1 and/or ME2/1
0287     ev.getByToken(gem_pad_cluster_token_, gemPadDigiClusters);
0288     if (!gemPadDigiClusters.isValid()) {
0289       edm::LogWarning("CSCTriggerPrimitivesProducer|NoInputCollection")
0290           << "+++ Warning: Collection of GEM clusters with label " << gemPadDigiClusterProducer_.label()
0291           << " requested in configuration, but not found in the event..."
0292           << " Running CSC-only trigger algorithm +++\n";
0293     } else {
0294       // when the GEM-CSC trigger should be run and the label is not empty, set a valid pointer
0295       gemPadClusters = gemPadDigiClusters.product();
0296     }
0297   }
0298 
0299   // Fill output collections if valid input collections are available.
0300   if (wireDigis.isValid() && compDigis.isValid()) {
0301     const CSCBadChambers* temp = checkBadChambers_ ? pBadChambers.product() : new CSCBadChambers;
0302     builder_->build(temp,
0303                     wireDigis.product(),
0304                     compDigis.product(),
0305                     gemPadClusters,
0306                     *oc_alct,
0307                     *oc_clct,
0308                     *oc_alctpretrigger,
0309                     *oc_clctpretrigger,
0310                     *oc_pretrig,
0311                     *oc_lct,
0312                     *oc_sorted_lct,
0313                     *oc_shower_anode,
0314                     *oc_shower_cathode,
0315                     *oc_shower,
0316                     *oc_gemcopad);
0317     if (!checkBadChambers_)
0318       delete temp;
0319   }
0320 
0321   // Put collections in event.
0322   ev.put(std::move(oc_alct));
0323   ev.put(std::move(oc_clct));
0324   if (keepALCTPreTriggers_) {
0325     ev.put(std::move(oc_alctpretrigger));
0326   }
0327   if (keepCLCTPreTriggers_) {
0328     ev.put(std::move(oc_clctpretrigger));
0329   }
0330   ev.put(std::move(oc_pretrig));
0331   ev.put(std::move(oc_lct));
0332   ev.put(std::move(oc_sorted_lct), "MPCSORTED");
0333   if (keepShowers_) {
0334     ev.put(std::move(oc_shower));
0335     ev.put(std::move(oc_shower_anode), "Anode");
0336     ev.put(std::move(oc_shower_cathode), "Cathode");
0337   }
0338   // only put GEM copad collections in the event when the
0339   // integrated local triggers are running
0340   if (runILT_)
0341     ev.put(std::move(oc_gemcopad));
0342 }
0343 
0344 #include "FWCore/Framework/interface/MakerMacros.h"
0345 DEFINE_FWK_MODULE(CSCTriggerPrimitivesProducer);