Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:35

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