diff --git a/DataFormats/L1TGlobal/interface/GlobalObject.h b/DataFormats/L1TGlobal/interface/GlobalObject.h index 8156c367ffbbd..7a930329ad066 100644 --- a/DataFormats/L1TGlobal/interface/GlobalObject.h +++ b/DataFormats/L1TGlobal/interface/GlobalObject.h @@ -15,6 +15,7 @@ namespace l1t { /// ObjNull catch all errors enum GlobalObject { gtMu, + gtMuShower, gtEG, gtJet, gtTau, diff --git a/DataFormats/L1TGlobal/src/GlobalObject.cc b/DataFormats/L1TGlobal/src/GlobalObject.cc index 0d1803c353b60..00341eaf49746 100644 --- a/DataFormats/L1TGlobal/src/GlobalObject.cc +++ b/DataFormats/L1TGlobal/src/GlobalObject.cc @@ -25,6 +25,7 @@ using namespace l1t; l1t::GlobalObject l1TGtObjectStringToEnum(const std::string& label) { static const l1t::L1TGtObjectStringToEnum l1TGtObjectStringToEnumMap[] = {{"Mu", gtMu}, + {"MuShower", gtMuShower}, {"EG", gtEG}, {"Tau", gtTau}, {"Jet", gtJet}, @@ -87,6 +88,10 @@ std::string l1t::l1TGtObjectEnumToString(const GlobalObject& gtObject) { gtObjectString = "Mu"; } break; + case gtMuShower: { + gtObjectString = "MuShower"; + } break; + case gtEG: { gtObjectString = "EG"; } break; diff --git a/L1Trigger/CSCTriggerPrimitives/README.md b/L1Trigger/CSCTriggerPrimitives/README.md index b10d4023df033..e5884d66d9f94 100644 --- a/L1Trigger/CSCTriggerPrimitives/README.md +++ b/L1Trigger/CSCTriggerPrimitives/README.md @@ -5,4 +5,5 @@ Please refer to this important documentation: * GEM, CSC, GEM-CSC, and HMT trigger algorithm https://gitlab.cern.ch/tdr/notes/DN-21-019/blob/master/temp/DN-21-019_temp.pdf * CCLUT algorithm https://gitlab.cern.ch/tdr/notes/DN-19-059/blob/master/temp/DN-19-059_temp.pdf * Hadronic shower trigger algorithm: https://gitlab.cern.ch/tdr/notes/DN-20-033/blob/master/temp/DN-20-033_temp.pdf -* Note describing the CSC firmware and CSC DAQ format https://github.com/csc-fw/otmb_fw_docs \ No newline at end of file +* Note describing the TMB/OTMB firmware and CSC DAQ format https://github.com/csc-fw/otmb_fw_docs +* Note describing the ALCT Virtex-E and Spartan-6 firmware and DAQ format: http://www.phys.ufl.edu/~madorsky/alctv/firmware/2021-11-19/alct_firmware.pdf \ No newline at end of file diff --git a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc index 0048ff8262a6e..327fc46513653 100644 --- a/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc +++ b/L1Trigger/CSCTriggerPrimitives/plugins/CSCTriggerPrimitivesProducer.cc @@ -142,6 +142,7 @@ CSCTriggerPrimitivesProducer::CSCTriggerPrimitivesProducer(const edm::ParameterS comp_token_ = consumes(compDigiProducer_); if (runILT_) gem_pad_cluster_token_ = consumes(gemPadDigiClusterProducer_); + cscToken_ = esConsumes(); gemToken_ = esConsumes(); pBadChambersToken_ = esConsumes(); @@ -249,14 +250,8 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup ev.getByToken(wire_token_, wireDigis); // input GEM pad cluster collection for upgrade scenarios + edm::Handle gemPadDigiClusters; const GEMPadDigiClusterCollection* gemPadClusters = nullptr; - if (runILT_) { - if (!gemPadDigiClusterProducer_.label().empty()) { - edm::Handle gemPadDigiClusters; - ev.getByToken(gem_pad_cluster_token_, gemPadDigiClusters); - gemPadClusters = gemPadDigiClusters.product(); - } - } // Create empty collections of ALCTs, CLCTs, and correlated LCTs upstream // and downstream of MPC. @@ -284,6 +279,23 @@ void CSCTriggerPrimitivesProducer::produce(edm::Event& ev, const edm::EventSetup << " requested in configuration, but not found in the event..." << " Skipping production of CSC TP digis +++\n"; } + // the GEM-CSC trigger flag is set, so GEM clusters are expected in the event data + if (runILT_) { + // no valid label, let the user know that GEM clusters are missing + // the algorithm should not crash. instead it should just produce the regular CSC LCTs + // in ME1/1 and/or ME2/1 + ev.getByToken(gem_pad_cluster_token_, gemPadDigiClusters); + if (!gemPadDigiClusters.isValid()) { + edm::LogWarning("CSCTriggerPrimitivesProducer|NoInputCollection") + << "+++ Warning: Collection of GEM clusters with label " << gemPadDigiClusterProducer_.label() + << " requested in configuration, but not found in the event..." + << " Running CSC-only trigger algorithm +++\n"; + } else { + // when the GEM-CSC trigger should be run and the label is not empty, set a valid pointer + gemPadClusters = gemPadDigiClusters.product(); + } + } + // Fill output collections if valid input collections are available. if (wireDigis.isValid() && compDigis.isValid()) { const CSCBadChambers* temp = checkBadChambers_ ? pBadChambers.product() : new CSCBadChambers; diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMatcher.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMatcher.cc index 1d57e5171d504..5861e46d02807 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMatcher.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMatcher.cc @@ -13,6 +13,11 @@ CSCGEMMatcher::CSCGEMMatcher( : endcap_(endcap), station_(station), chamber_(chamber) { isEven_ = (chamber_ % 2 == 0); + // These LogErrors are sanity checks and should not be printed + if (station_ == 3 or station_ == 4) { + edm::LogError("CSCGEMMatcher") << "Class constructed for a chamber in ME3 or ME4!"; + }; + maxDeltaBXALCTGEM_ = tmbParams.getParameter("maxDeltaBXALCTGEM"); maxDeltaBXCLCTGEM_ = tmbParams.getParameter("maxDeltaBXCLCTGEM"); diff --git a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc index 813034549af82..50d3b2894f5c5 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/CSCGEMMotherboard.cc @@ -38,6 +38,11 @@ CSCGEMMotherboard::CSCGEMMotherboard(unsigned endcap, edm::LogError("CSCGEMMotherboard") << "TMB constructed while runME21ILT_ is not set!"; }; + // These LogErrors are sanity checks and should not be printed + if (!isME11_ and !isME21_) { + edm::LogError("CSCGEMMotherboard") << "GEM-CSC OTMB constructed for a non-ME1/1 or a non-ME2/1 chamber!"; + }; + // super chamber has layer=0! gemId = GEMDetId(theRegion, 1, theStation, 0, theChamber, 0).rawId(); @@ -59,18 +64,13 @@ void CSCGEMMotherboard::run(const CSCWireDigiCollection* wiredc, // Step 1: Setup clear(); - // check for GEM geometry - if (gem_g == nullptr) { - edm::LogError("CSCGEMMotherboard") << "run() called for GEM-CSC integrated trigger without valid GEM geometry! \n"; - return; - } - // Check that the processors can deliver data if (!(alctProc and clctProc)) { - edm::LogError("CSCGEMMotherboard") << "run() called for non-existing ALCT/CLCT processor! \n"; + edm::LogError("CSCGEMMotherboard") << "run() called for non-existing ALCT/CLCT processor in " << theCSCName_; return; } + // set geometry alctProc->setCSCGeometry(cscGeometry_); clctProc->setCSCGeometry(cscGeometry_); @@ -90,19 +90,39 @@ void CSCGEMMotherboard::run(const CSCWireDigiCollection* wiredc, if (alctV.empty() and clctV.empty()) return; - // set the lookup tables for coordinate conversion and matching - if (isME11_) { - clusterProc_->setESLookupTables(lookupTableME11ILT_); - cscGEMMatcher_->setESLookupTables(lookupTableME11ILT_); + bool validClustersAndGeometry = true; + + // Step 3a: check for GEM geometry + if (gem_g == nullptr) { + edm::LogWarning("CSCGEMMotherboard") << "run() called for GEM-CSC integrated trigger" + << " without valid GEM geometry! Running CSC-only" + << " trigger algorithm in " << theCSCName_; + validClustersAndGeometry = false; } - if (isME21_) { - clusterProc_->setESLookupTables(lookupTableME21ILT_); - cscGEMMatcher_->setESLookupTables(lookupTableME21ILT_); + + // Step 3b: check that the GEM cluster collection is a valid pointer + if (gemClusters == nullptr) { + edm::LogWarning("CSCGEMMotherboard") << "run() called for GEM-CSC integrated trigger" + << " without valid GEM clusters! Running CSC-only" + << " trigger algorithm in " << theCSCName_; + validClustersAndGeometry = false; } - // Step 3: run the GEM cluster processor to get the internal clusters - clusterProc_->run(gemClusters); - hasGE21Geometry16Partitions_ = clusterProc_->hasGE21Geometry16Partitions(); + if (validClustersAndGeometry) { + // Step 3c: set the lookup tables for coordinate conversion and matching + if (isME11_) { + clusterProc_->setESLookupTables(lookupTableME11ILT_); + cscGEMMatcher_->setESLookupTables(lookupTableME11ILT_); + } + if (isME21_) { + clusterProc_->setESLookupTables(lookupTableME21ILT_); + cscGEMMatcher_->setESLookupTables(lookupTableME21ILT_); + } + + // Step 3d: run the GEM cluster processor to get the internal clusters + clusterProc_->run(gemClusters); + hasGE21Geometry16Partitions_ = clusterProc_->hasGE21Geometry16Partitions(); + } /* Mask for bunch crossings were LCTs were previously found @@ -122,12 +142,12 @@ void CSCGEMMotherboard::run(const CSCWireDigiCollection* wiredc, CSCMotherboard::matchALCTCLCT(bunch_crossing_mask); // Step 6: CLCT-2GEM matching for BX's that were not previously masked - if (build_lct_from_clct_gem_) { + if (build_lct_from_clct_gem_ and validClustersAndGeometry) { matchCLCT2GEM(bunch_crossing_mask); } // Step 7: ALCT-2GEM matching for BX's that were not previously masked - if (build_lct_from_alct_gem_) { + if (build_lct_from_alct_gem_ and validClustersAndGeometry) { matchALCT2GEM(bunch_crossing_mask); } diff --git a/L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc b/L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc index 18cb610258e76..1dd3efe89b65e 100644 --- a/L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc +++ b/L1Trigger/CSCTriggerPrimitives/src/GEMClusterProcessor.cc @@ -8,6 +8,11 @@ GEMClusterProcessor::GEMClusterProcessor(int region, unsigned station, unsigned : region_(region), station_(station), chamber_(chamber) { isEven_ = chamber_ % 2 == 0; + // These LogErrors are sanity checks and should not be printed + if (station_ == 3 or station_ == 4) { + edm::LogError("GEMClusterProcessor") << "Class constructed for a chamber in ME3 or ME4!"; + }; + if (station_ == 1) { const edm::ParameterSet copad(conf.getParameter("copadParamGE11")); maxDeltaPad_ = copad.getParameter("maxDeltaPad"); @@ -36,6 +41,7 @@ void GEMClusterProcessor::run(const GEMPadDigiClusterCollection* in_clusters) { // Step 1: clear the GEMInternalCluster vector clear(); + // check that the GEM cluster collection is a valid pointer if (in_clusters == nullptr) { edm::LogWarning("GEMClusterProcessor") << "Attempt to run without valid in_clusters pointer."; return; diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index 90d2089ee5774..cd49c041f3f59 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -25,6 +25,7 @@ // Trigger Objects #include "DataFormats/L1Trigger/interface/EGamma.h" #include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" #include "DataFormats/L1Trigger/interface/Tau.h" #include "DataFormats/L1Trigger/interface/Jet.h" #include "DataFormats/L1Trigger/interface/EtSum.h" @@ -77,11 +78,17 @@ namespace l1t { const bool receiveMu, const int nrL1Mu); + void receiveMuonShowerObjectData(edm::Event&, + const edm::EDGetTokenT>&, + const bool receiveMuShower, + const int nrL1MuShower); + void receiveExternalData(edm::Event&, const edm::EDGetTokenT>&, const bool receiveExt); /// initialize the class (mainly reserve) void init(const int numberPhysTriggers, const int nrL1Mu, + const int nrL1MuShower, const int nrL1EG, const int nrL1Tau, const int nrL1Jet, @@ -97,6 +104,7 @@ namespace l1t { std::unique_ptr& gtObjectMapRecord, //GTO const unsigned int numberPhysTriggers, const int nrL1Mu, + const int nrL1MuShower, const int nrL1EG, const int nrL1Tau, const int nrL1Jet); @@ -122,6 +130,7 @@ namespace l1t { /// clear uGT void reset(); void resetMu(); + void resetMuonShower(); void resetCalo(); void resetExternal(); @@ -137,6 +146,9 @@ namespace l1t { /// return global muon trigger candidate inline const BXVector* getCandL1Mu() const { return m_candL1Mu; } + /// return global muon trigger candidate + inline const BXVector* getCandL1MuShower() const { return m_candL1MuShower; } + /// pointer to EG data list inline const BXVector* getCandL1EG() const { return m_candL1EG; } @@ -203,6 +215,7 @@ namespace l1t { private: BXVector* m_candL1Mu; + BXVector* m_candL1MuShower; BXVector* m_candL1EG; BXVector* m_candL1Tau; BXVector* m_candL1Jet; diff --git a/L1Trigger/L1TGlobal/interface/GlobalDefinitions.h b/L1Trigger/L1TGlobal/interface/GlobalDefinitions.h index 16b13af902d7b..fd6323da6408f 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalDefinitions.h +++ b/L1Trigger/L1TGlobal/interface/GlobalDefinitions.h @@ -98,7 +98,8 @@ namespace l1t { CondCorrelation, CondExternal, CondCorrelationWithOverlapRemoval, - CondCorrelationThreeBody + CondCorrelationThreeBody, + CondMuonShower, }; struct GtConditionCategoryStringToEnum { diff --git a/L1Trigger/L1TGlobal/interface/MuonShowerCondition.h b/L1Trigger/L1TGlobal/interface/MuonShowerCondition.h new file mode 100644 index 0000000000000..03a2f232de338 --- /dev/null +++ b/L1Trigger/L1TGlobal/interface/MuonShowerCondition.h @@ -0,0 +1,81 @@ +#ifndef L1Trigger_L1TGlobal_MuonShowerCondition_h +#define L1Trigger_L1TGlobal_MuonShowerCondition_h + +/** + * \class MuonShowerCondition + * + * Description: evaluation of a CondMuonShower condition. + */ + +// system include files +#include +#include + +// user include files +// base classes +#include "L1Trigger/L1TGlobal/interface/ConditionEvaluation.h" + +#include "DataFormats/L1Trigger/interface/MuonShower.h" + +// forward declarations +class GlobalCondition; +class MuonShowerTemplate; + +namespace l1t { + + class GlobalBoard; + + // class declaration + class MuonShowerCondition : public ConditionEvaluation { + public: + /// constructors + /// default + MuonShowerCondition(); + + /// from base template condition (from event setup usually) + MuonShowerCondition(const GlobalCondition*, const GlobalBoard*, const int nrL1MuShower); + + // copy constructor + MuonShowerCondition(const MuonShowerCondition&); + + // destructor + ~MuonShowerCondition() override; + + // assign operator + MuonShowerCondition& operator=(const MuonShowerCondition&); + + /// the core function to check if the condition matches + const bool evaluateCondition(const int bxEval) const override; + + /// print condition + void print(std::ostream& myCout) const override; + + /// get / set the pointer to a Condition + inline const MuonShowerTemplate* gtMuonShowerTemplate() const { return m_gtMuonShowerTemplate; } + + void setGtMuonShowerTemplate(const MuonShowerTemplate*); + + /// get / set the pointer to GTL + inline const GlobalBoard* gtGTL() const { return m_gtGTL; } + + void setGtGTL(const GlobalBoard*); + + private: + /// copy function for copy constructor and operator= + void copy(const MuonShowerCondition& cp); + + /// load muon candidates + const l1t::MuonShower* getCandidate(const int bx, const int indexCand) const; + + /// function to check a single object if it matches a condition + const bool checkObjectParameter(const int iCondition, const l1t::MuonShower& cand, const unsigned int index) const; + + /// pointer to a MuonShowerTemplate + const MuonShowerTemplate* m_gtMuonShowerTemplate; + + /// pointer to GTL, to be able to get the trigger objects + const GlobalBoard* m_gtGTL; + }; + +} // namespace l1t +#endif diff --git a/L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h b/L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h new file mode 100644 index 0000000000000..fbaacc6ffa2c7 --- /dev/null +++ b/L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h @@ -0,0 +1,74 @@ +#ifndef L1Trigger_L1TGlobal_MuonShowerTemplate_h +#define L1Trigger_L1TGlobal_MuonShowerTemplate_h + +/** + * \class MuonShowerTemplate + * + * + * Description: L1 Global Trigger muon shower template. + * + * \author: Sven Dildick (Rice University) + * + */ + +// system include files +#include +#include + +// user include files + +// base class +#include "L1Trigger/L1TGlobal/interface/GlobalCondition.h" + +// forward declarations + +// class declaration +class MuonShowerTemplate : public GlobalCondition { +public: + // constructor + MuonShowerTemplate(); + + // constructor + MuonShowerTemplate(const std::string&); + + // constructor + MuonShowerTemplate(const std::string&, const l1t::GtConditionType&); + + // copy constructor + MuonShowerTemplate(const MuonShowerTemplate&); + + // destructor + ~MuonShowerTemplate() override; + + // assign operator + MuonShowerTemplate& operator=(const MuonShowerTemplate&); + + // typedef for a single object template + struct ObjectParameter { + bool MuonShower0; + bool MuonShower1; + bool MuonShowerOutOfTime0; + bool MuonShowerOutOfTime1; + }; + +public: + inline const std::vector* objectParameter() const { return &m_objectParameter; } + + /// set functions + void setConditionParameter(const std::vector& objParameter); + + /// print the condition + void print(std::ostream& myCout) const override; + + /// output stream operator + friend std::ostream& operator<<(std::ostream&, const MuonShowerTemplate&); + +private: + /// copy function for copy constructor and operator= + void copy(const MuonShowerTemplate& cp); + + /// variables containing the parameters + std::vector m_objectParameter; +}; + +#endif diff --git a/L1Trigger/L1TGlobal/interface/TriggerMenu.h b/L1Trigger/L1TGlobal/interface/TriggerMenu.h index 6ab26ec8d79b4..2a02bb0220c6f 100644 --- a/L1Trigger/L1TGlobal/interface/TriggerMenu.h +++ b/L1Trigger/L1TGlobal/interface/TriggerMenu.h @@ -32,6 +32,7 @@ #include "L1Trigger/L1TGlobal/interface/GlobalScales.h" #include "L1Trigger/L1TGlobal/interface/MuonTemplate.h" +#include "L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h" #include "L1Trigger/L1TGlobal/interface/CaloTemplate.h" #include "L1Trigger/L1TGlobal/interface/EnergySumTemplate.h" #include "L1Trigger/L1TGlobal/interface/ExternalTemplate.h" @@ -53,6 +54,7 @@ class TriggerMenu { TriggerMenu(const std::string&, const unsigned int numberConditionChips, const std::vector >&, + const std::vector >&, const std::vector >&, const std::vector >&, const std::vector >&, @@ -109,6 +111,13 @@ class TriggerMenu { void setVecMuonTemplate(const std::vector >&); + // + inline const std::vector >& vecMuonShowerTemplate() const { + return m_vecMuonShowerTemplate; + } + + void setVecMuonShowerTemplate(const std::vector >&); + // inline const std::vector >& vecCaloTemplate() const { return m_vecCaloTemplate; } @@ -218,6 +227,7 @@ class TriggerMenu { /// vectors containing the conditions /// explicit, due to persistency... std::vector > m_vecMuonTemplate; + std::vector > m_vecMuonShowerTemplate; std::vector > m_vecCaloTemplate; std::vector > m_vecEnergySumTemplate; diff --git a/L1Trigger/L1TGlobal/plugins/BXVectorInputProducer.cc b/L1Trigger/L1TGlobal/plugins/BXVectorInputProducer.cc index 231be47fd5c19..b3ae33d16c0ea 100644 --- a/L1Trigger/L1TGlobal/plugins/BXVectorInputProducer.cc +++ b/L1Trigger/L1TGlobal/plugins/BXVectorInputProducer.cc @@ -31,6 +31,7 @@ #include "DataFormats/L1Trigger/interface/EGamma.h" #include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" #include "DataFormats/L1Trigger/interface/Tau.h" #include "DataFormats/L1Trigger/interface/Jet.h" #include "DataFormats/L1Trigger/interface/EtSum.h" @@ -84,6 +85,7 @@ namespace l1t { int bxLast_; unsigned int maxNumMuCands_; + unsigned int maxNumMuShowerCands_; unsigned int maxNumJetCands_; unsigned int maxNumEGCands_; unsigned int maxNumTauCands_; @@ -101,6 +103,7 @@ namespace l1t { // Tokens for inputs from other parts of the L1 system edm::EDGetToken egToken; edm::EDGetToken muToken; + edm::EDGetToken muShowerToken; edm::EDGetToken tauToken; edm::EDGetToken jetToken; edm::EDGetToken etsumToken; @@ -112,6 +115,11 @@ namespace l1t { std::vector muonVec_bx0; std::vector muonVec_bxp1; + std::vector muonShowerVec_bxm2; + std::vector muonShowerVec_bxm1; + std::vector muonShowerVec_bx0; + std::vector muonShowerVec_bxp1; + std::vector egammaVec_bxm2; std::vector egammaVec_bxm1; std::vector egammaVec_bx0; @@ -139,6 +147,7 @@ namespace l1t { BXVectorInputProducer::BXVectorInputProducer(const ParameterSet& iConfig) { egToken = consumes>(iConfig.getParameter("egInputTag")); muToken = consumes>(iConfig.getParameter("muInputTag")); + muShowerToken = consumes>(iConfig.getParameter("muShowerInputTag")); tauToken = consumes>(iConfig.getParameter("tauInputTag")); jetToken = consumes>(iConfig.getParameter("jetInputTag")); etsumToken = consumes>(iConfig.getParameter("etsumInputTag")); @@ -146,6 +155,7 @@ namespace l1t { // register what you produce produces>(); produces>(); + produces>(); produces>(); produces>(); produces>(); @@ -155,6 +165,7 @@ namespace l1t { bxLast_ = iConfig.getParameter("bxLast"); maxNumMuCands_ = iConfig.getParameter("maxMuCand"); + maxNumMuShowerCands_ = iConfig.getParameter("maxMuShowerCand"); maxNumJetCands_ = iConfig.getParameter("maxJetCand"); maxNumEGCands_ = iConfig.getParameter("maxEGCand"); maxNumTauCands_ = iConfig.getParameter("maxTauCand"); @@ -186,6 +197,7 @@ namespace l1t { // Setup vectors std::vector muonVec; + std::vector muonShowerVec; std::vector egammaVec; std::vector tauVec; std::vector jetVec; @@ -198,6 +210,7 @@ namespace l1t { //outputs std::unique_ptr egammas(new l1t::EGammaBxCollection(0, bxFirst, bxLast)); std::unique_ptr muons(new l1t::MuonBxCollection(0, bxFirst, bxLast)); + std::unique_ptr muonShowers(new l1t::MuonShowerBxCollection(0, bxFirst, bxLast)); std::unique_ptr taus(new l1t::TauBxCollection(0, bxFirst, bxLast)); std::unique_ptr jets(new l1t::JetBxCollection(0, bxFirst, bxLast)); std::unique_ptr etsums(new l1t::EtSumBxCollection(0, bxFirst, bxLast)); @@ -233,6 +246,20 @@ namespace l1t { LogTrace("l1t|Global") << ">>> input Mu collection not found!" << std::endl; } + // Make sure that you can get input Muon Showers + Handle> inputMuonShowers; + if (iEvent.getByToken(muToken, inputMuonShowers)) { + for (std::vector::const_iterator mu = inputMuonShowers->begin(bx); + mu != inputMuonShowers->end(bx); + ++mu) { + if (mu->isValid() && muonShowerVec.size() < maxNumMuCands_) { + muonShowerVec.push_back((*mu)); + } + } + } else { + LogTrace("l1t|Global") << ">>> input Mu collection not found!" << std::endl; + } + // Make sure that you can get input Tau Handle> inputTaus; if (iEvent.getByToken(tauToken, inputTaus)) { @@ -294,6 +321,28 @@ namespace l1t { muonVec.clear(); } + // Fill MuonShowers + for (int iMuShower = 0; iMuShower < int(muonShowerVec_bxm2.size()); iMuShower++) { + muonShowers->push_back(-2, muonShowerVec_bxm2[iMuShower]); + } + for (int iMuShower = 0; iMuShower < int(muonShowerVec_bxm1.size()); iMuShower++) { + muonShowers->push_back(-1, muonShowerVec_bxm1[iMuShower]); + } + for (int iMuShower = 0; iMuShower < int(muonShowerVec_bx0.size()); iMuShower++) { + muonShowers->push_back(0, muonShowerVec_bx0[iMuShower]); + } + for (int iMuShower = 0; iMuShower < int(muonShowerVec_bxp1.size()); iMuShower++) { + muonShowers->push_back(1, muonShowerVec_bxp1[iMuShower]); + } + if (emptyBxTrailer_ <= (emptyBxEvt_ - eventCnt_)) { + for (int iMuShower = 0; iMuShower < int(muonShowerVec.size()); iMuShower++) { + muonShowers->push_back(2, muonShowerVec[iMuShower]); + } + } else { + // this event is part of empty trailer...clear out data + muonShowerVec.clear(); + } + // Fill Egammas for (int iEG = 0; iEG < int(egammaVec_bxm2.size()); iEG++) { egammas->push_back(-2, egammaVec_bxm2[iEG]); @@ -384,30 +433,35 @@ namespace l1t { iEvent.put(std::move(egammas)); iEvent.put(std::move(muons)); + iEvent.put(std::move(muonShowers)); iEvent.put(std::move(taus)); iEvent.put(std::move(jets)); iEvent.put(std::move(etsums)); // Now shift the bx data by one to prepare for next event. muonVec_bxm2 = muonVec_bxm1; + muonShowerVec_bxm2 = muonShowerVec_bxm1; egammaVec_bxm2 = egammaVec_bxm1; tauVec_bxm2 = tauVec_bxm1; jetVec_bxm2 = jetVec_bxm1; etsumVec_bxm2 = etsumVec_bxm1; muonVec_bxm1 = muonVec_bx0; + muonShowerVec_bxm1 = muonShowerVec_bx0; egammaVec_bxm1 = egammaVec_bx0; tauVec_bxm1 = tauVec_bx0; jetVec_bxm1 = jetVec_bx0; etsumVec_bxm1 = etsumVec_bx0; muonVec_bx0 = muonVec_bxp1; + muonShowerVec_bx0 = muonShowerVec_bxp1; egammaVec_bx0 = egammaVec_bxp1; tauVec_bx0 = tauVec_bxp1; jetVec_bx0 = jetVec_bxp1; etsumVec_bx0 = etsumVec_bxp1; muonVec_bxp1 = muonVec; + muonShowerVec_bxp1 = muonShowerVec; egammaVec_bxp1 = egammaVec; tauVec_bxp1 = tauVec; jetVec_bxp1 = jetVec; diff --git a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc index 34e6a526ea58d..05680e759f1a1 100644 --- a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc +++ b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc @@ -39,6 +39,8 @@ void L1TGlobalProducer::fillDescriptions(edm::ConfigurationDescriptions& descrip // These parameters are part of the L1T/HLT interface, avoid changing if possible:: desc.add("MuonInputTag", edm::InputTag("")) ->setComment("InputTag for Global Muon Trigger (required parameter: default value is invalid)"); + desc.add("MuonShowerInputTag", edm::InputTag("")) + ->setComment("InputTag for Global Muon Shower Trigger (required parameter: default value is invalid)"); desc.add("EGammaInputTag", edm::InputTag("")) ->setComment("InputTag for Calo Trigger EGamma (required parameter: default value is invalid)"); desc.add("TauInputTag", edm::InputTag("")) @@ -63,6 +65,10 @@ void L1TGlobalProducer::fillDescriptions(edm::ConfigurationDescriptions& descrip "true when used by the HLT to produce the object map"); desc.add("AlgorithmTriggersUnmasked", false) ->setComment("not required, but recommend to specify explicitly in config"); + + // switch for muon showers in Run-3 + desc.add("useMuonShowers", false); + // These parameters have well defined default values and are not currently // part of the L1T/HLT interface. They can be cleaned up or updated at will: desc.add("ProduceL1GtDaqRecord", true); @@ -83,6 +89,7 @@ void L1TGlobalProducer::fillDescriptions(edm::ConfigurationDescriptions& descrip L1TGlobalProducer::L1TGlobalProducer(const edm::ParameterSet& parSet) : m_muInputTag(parSet.getParameter("MuonInputTag")), + m_muShowerInputTag(parSet.getParameter("MuonShowerInputTag")), m_egInputTag(parSet.getParameter("EGammaInputTag")), m_tauInputTag(parSet.getParameter("TauInputTag")), m_jetInputTag(parSet.getParameter("JetInputTag")), @@ -108,12 +115,15 @@ L1TGlobalProducer::L1TGlobalProducer(const edm::ParameterSet& parSet) m_isDebugEnabled(edm::isDebugEnabled()), m_getPrescaleColumnFromData(parSet.getParameter("GetPrescaleColumnFromData")), m_requireMenuToMatchAlgoBlkInput(parSet.getParameter("RequireMenuToMatchAlgoBlkInput")), - m_algoblkInputTag(parSet.getParameter("AlgoBlkInputTag")) { + m_algoblkInputTag(parSet.getParameter("AlgoBlkInputTag")), + m_useMuonShowers(parSet.getParameter("useMuonShowers")) { m_egInputToken = consumes>(m_egInputTag); m_tauInputToken = consumes>(m_tauInputTag); m_jetInputToken = consumes>(m_jetInputTag); m_sumInputToken = consumes>(m_sumInputTag); m_muInputToken = consumes>(m_muInputTag); + if (m_useMuonShowers) + m_muShowerInputToken = consumes>(m_muShowerInputTag); m_extInputToken = consumes>(m_extInputTag); m_l1GtStableParToken = esConsumes(); m_l1GtMenuToken = esConsumes(); @@ -197,6 +207,7 @@ L1TGlobalProducer::L1TGlobalProducer(const edm::ParameterSet& parSet) m_numberDaqPartitions = 0; m_nrL1Mu = 0; + m_nrL1MuShower = 0; m_nrL1EG = 0; m_nrL1Tau = 0; @@ -259,6 +270,12 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet // number of objects of each type m_nrL1Mu = data->numberL1Mu(); + // There should be at most 1 muon shower object per BX + // This object contains information for the in-time + // showers and out-of-time showers + if (m_useMuonShowers) + m_nrL1MuShower = 1; + // EG m_nrL1EG = data->numberL1EG(); @@ -274,8 +291,14 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet int maxL1DataBxInEvent = (m_L1DataBxInEvent + 1) / 2 - 1; // Initialize Board - m_uGtBrd->init( - m_numberPhysTriggers, m_nrL1Mu, m_nrL1EG, m_nrL1Tau, m_nrL1Jet, minL1DataBxInEvent, maxL1DataBxInEvent); + m_uGtBrd->init(m_numberPhysTriggers, + m_nrL1Mu, + m_nrL1MuShower, + m_nrL1EG, + m_nrL1Tau, + m_nrL1Jet, + minL1DataBxInEvent, + maxL1DataBxInEvent); // m_l1GtParCacheID = l1GtParCacheID; @@ -330,6 +353,7 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet m_l1GtMenu = std::make_unique(gtParser.gtTriggerMenuName(), data->numberChips(), gtParser.vecMuonTemplate(), + gtParser.vecMuonShowerTemplate(), gtParser.vecCaloTemplate(), gtParser.vecEnergySumTemplate(), gtParser.vecExternalTemplate(), @@ -471,6 +495,7 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet // bool receiveMu = true; + bool receiveMuShower = false; bool receiveEG = true; bool receiveTau = true; bool receiveJet = true; @@ -574,6 +599,9 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet m_uGtBrd->receiveMuonObjectData(iEvent, m_muInputToken, receiveMu, m_nrL1Mu); + if (m_useMuonShowers) + m_uGtBrd->receiveMuonShowerObjectData(iEvent, m_muShowerInputToken, receiveMuShower, m_nrL1MuShower); + m_uGtBrd->receiveExternalData(iEvent, m_extInputToken, receiveExt); // loop over BxInEvent @@ -590,6 +618,7 @@ void L1TGlobalProducer::produce(edm::Event& iEvent, const edm::EventSetup& evSet gtObjectMapRecord, m_numberPhysTriggers, m_nrL1Mu, + m_nrL1MuShower, m_nrL1EG, m_nrL1Tau, m_nrL1Jet); diff --git a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h index b8e58777dba81..c8127a1f6b7fd 100644 --- a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h +++ b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h @@ -68,6 +68,7 @@ class L1TGlobalProducer : public edm::stream::EDProducer<> { // number of objects of each type int m_nrL1Mu; + int m_nrL1MuShower; int m_nrL1EG; int m_nrL1Tau; @@ -119,7 +120,9 @@ class L1TGlobalProducer : public edm::stream::EDProducer<> { /// input tag for muon collection from GMT edm::InputTag m_muInputTag; + edm::InputTag m_muShowerInputTag; edm::EDGetTokenT> m_muInputToken; + edm::EDGetTokenT> m_muShowerInputToken; /// input tag for calorimeter collections from GCT edm::InputTag m_egInputTag; @@ -185,6 +188,9 @@ class L1TGlobalProducer : public edm::stream::EDProducer<> { edm::ESGetToken m_l1GtStableParToken; edm::ESGetToken m_l1GtMenuToken; edm::ESGetToken m_l1GtPrescaleVetosToken; + + // switch to load muon showers in the global board + bool m_useMuonShowers; }; #endif /*L1TGlobalProducer_h*/ diff --git a/L1Trigger/L1TGlobal/plugins/TriggerMenuParser.cc b/L1Trigger/L1TGlobal/plugins/TriggerMenuParser.cc index d7a33924800e4..5aef86f75b9d3 100644 --- a/L1Trigger/L1TGlobal/plugins/TriggerMenuParser.cc +++ b/L1Trigger/L1TGlobal/plugins/TriggerMenuParser.cc @@ -14,9 +14,9 @@ * - correlations with overlap object removal * - displaced muons by R.Cavanaugh * - * \new features: Elisa Fontanesi - * - extended for three-body correlation conditions - * + * \new features: Elisa Fontanesi + * - extended for three-body correlation conditions + * * $Date$ * $Revision$ * @@ -111,6 +111,11 @@ void l1t::TriggerMenuParser::setVecMuonTemplate(const std::vector >& vecMuonShowerTempl) { + m_vecMuonShowerTemplate = vecMuonShowerTempl; +} + void l1t::TriggerMenuParser::setVecCaloTemplate(const std::vector >& vecCaloTempl) { m_vecCaloTemplate = vecCaloTempl; } @@ -202,6 +207,7 @@ void l1t::TriggerMenuParser::parseCondFormats(const L1TUtmTriggerMenu* utmMenu) m_conditionMap.resize(m_numberConditionChips); m_vecMuonTemplate.resize(m_numberConditionChips); + m_vecMuonShowerTemplate.resize(m_numberConditionChips); m_vecCaloTemplate.resize(m_numberConditionChips); m_vecEnergySumTemplate.resize(m_numberConditionChips); m_vecExternalTemplate.resize(m_numberConditionChips); @@ -300,6 +306,12 @@ void l1t::TriggerMenuParser::parseCondFormats(const L1TUtmTriggerMenu* utmMenu) condition.getType() == esConditionType::QuadMuon) { parseMuon(condition, chipNr, false); + } else if (condition.getType() == esConditionType::MuonShower0 || + condition.getType() == esConditionType::MuonShower1 || + condition.getType() == esConditionType::MuonShowerOutOfTime0 || + condition.getType() == esConditionType::MuonShowerOutOfTime1) { + parseMuonShower(condition, chipNr, false); + //parse Correlation Conditions } else if (condition.getType() == esConditionType::MuonMuonCorrelation || condition.getType() == esConditionType::MuonEsumCorrelation || @@ -1519,6 +1531,84 @@ bool l1t::TriggerMenuParser::parseMuonCorr(const tmeventsetup::esObject* corrMu, return true; } +/** + * parseMuonShower Parse a muonShower condition and insert an entry to the conditions map + * + * @param node The corresponding node. + * @param name The name of the condition. + * @param chipNr The number of the chip this condition is located. + * + * @return "true" if succeeded, "false" if an error occurred. + * + */ + +bool l1t::TriggerMenuParser::parseMuonShower(tmeventsetup::esCondition condMu, + unsigned int chipNr, + const bool corrFlag) { + using namespace tmeventsetup; + + // get condition, particle name (must be muon) and type name + std::string condition = "muonShower"; + std::string particle = "muonShower"; //l1t2string( condMu.objectType() ); + std::string type = l1t2string(condMu.getType()); + std::string name = l1t2string(condMu.getName()); + // the number of muon shower objects is always 1 + int nrObj = 1; + + // condition type is always 1 particle, thus Type1s + GtConditionType cType = l1t::Type1s; + + // temporary storage of the parameters + std::vector objParameter(nrObj); + + if (int(condMu.getObjects().size()) != nrObj) { + edm::LogError("TriggerMenuParser") << " condMu objects: nrObj = " << nrObj + << "condMu.getObjects().size() = " << condMu.getObjects().size() << std::endl; + return false; + } + + // Get the muon shower object + esObject object = condMu.getObjects().at(0); + int relativeBx = object.getBxOffset(); + + if (condMu.getType() == esConditionType::MuonShower0) { + objParameter[0].MuonShower0 = true; + } else if (condMu.getType() == esConditionType::MuonShower1) { + objParameter[0].MuonShower1 = true; + } else if (condMu.getType() == esConditionType::MuonShowerOutOfTime0) { + objParameter[0].MuonShowerOutOfTime0 = true; + } else if (condMu.getType() == esConditionType::MuonShowerOutOfTime1) { + objParameter[0].MuonShowerOutOfTime1 = true; + } + + // object types - all muons + std::vector objType(nrObj, gtMuShower); + + // now create a new CondMuonition + MuonShowerTemplate muonShowerCond(name); + muonShowerCond.setCondType(cType); + muonShowerCond.setObjectType(objType); + muonShowerCond.setCondChipNr(chipNr); + muonShowerCond.setCondRelativeBx(relativeBx); + + muonShowerCond.setConditionParameter(objParameter); + + if (edm::isDebugEnabled()) { + std::ostringstream myCoutStream; + muonShowerCond.print(myCoutStream); + } + + // insert condition into the map and into muon template vector + if (!insertConditionIntoMap(muonShowerCond, chipNr)) { + edm::LogError("TriggerMenuParser") << " Error: duplicate condition (" << name << ")" << std::endl; + return false; + } else { + (m_vecMuonShowerTemplate[chipNr]).push_back(muonShowerCond); + } + + return true; +} + /** * parseCalo Parse a calo condition and insert an entry to the conditions map * diff --git a/L1Trigger/L1TGlobal/plugins/TriggerMenuParser.h b/L1Trigger/L1TGlobal/plugins/TriggerMenuParser.h index 85111e1a0f4bd..89921f675aabd 100644 --- a/L1Trigger/L1TGlobal/plugins/TriggerMenuParser.h +++ b/L1Trigger/L1TGlobal/plugins/TriggerMenuParser.h @@ -33,6 +33,7 @@ #include "L1Trigger/L1TGlobal/interface/TriggerMenuFwd.h" #include "L1Trigger/L1TGlobal/interface/MuonTemplate.h" +#include "L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h" #include "L1Trigger/L1TGlobal/interface/CaloTemplate.h" #include "L1Trigger/L1TGlobal/interface/EnergySumTemplate.h" #include "L1Trigger/L1TGlobal/interface/CorrelationTemplate.h" @@ -124,6 +125,12 @@ namespace l1t { inline const std::vector >& vecMuonTemplate() const { return m_vecMuonTemplate; } void setVecMuonTemplate(const std::vector >&); + // + inline const std::vector >& vecMuonShowerTemplate() const { + return m_vecMuonShowerTemplate; + } + void setVecMuonShowerTemplate(const std::vector >&); + // inline const std::vector >& vecCaloTemplate() const { return m_vecCaloTemplate; } @@ -266,6 +273,9 @@ namespace l1t { bool parseMuonCorr(const tmeventsetup::esObject* condMu, unsigned int chipNr = 0); + /// parse a muon shower condition + bool parseMuonShower(tmeventsetup::esCondition condMu, unsigned int chipNr = 0, const bool corrFlag = false); + /// parse a calorimeter condition /* bool parseCalo(XERCES_CPP_NAMESPACE::DOMNode* node, */ /* const std::string& name, unsigned int chipNr = 0, */ @@ -383,6 +393,7 @@ namespace l1t { /// vectors containing the conditions /// explicit, due to persistency... std::vector > m_vecMuonTemplate; + std::vector > m_vecMuonShowerTemplate; std::vector > m_vecCaloTemplate; std::vector > m_vecEnergySumTemplate; std::vector > m_vecExternalTemplate; diff --git a/L1Trigger/L1TGlobal/python/simGtStage2Digis_cfi.py b/L1Trigger/L1TGlobal/python/simGtStage2Digis_cfi.py index 19e7f2b8998bd..7b7ff376db73d 100644 --- a/L1Trigger/L1TGlobal/python/simGtStage2Digis_cfi.py +++ b/L1Trigger/L1TGlobal/python/simGtStage2Digis_cfi.py @@ -9,6 +9,7 @@ simGtStage2Digis = cms.EDProducer("L1TGlobalProducer", MuonInputTag = cms.InputTag("simGmtStage2Digis"), + MuonShowerInputTag = cms.InputTag("simGmtShowerDigis"), ExtInputTag = cms.InputTag("simGtExtFakeStage2Digis"), EGammaInputTag = cms.InputTag("simCaloStage2Digis"), TauInputTag = cms.InputTag("simCaloStage2Digis"), @@ -33,3 +34,6 @@ #Verbosity = cms.untracked.int32(0) ) +from Configuration.Eras.Modifier_run3_common_cff import run3_common +run3_common.toModify(simGtStage2Digis, + useMuonShowers = cms.bool(True)) diff --git a/L1Trigger/L1TGlobal/src/GlobalBoard.cc b/L1Trigger/L1TGlobal/src/GlobalBoard.cc index eff9a910d533e..980f61685146b 100644 --- a/L1Trigger/L1TGlobal/src/GlobalBoard.cc +++ b/L1Trigger/L1TGlobal/src/GlobalBoard.cc @@ -27,6 +27,7 @@ #include "L1Trigger/L1TGlobal/interface/GlobalAlgorithm.h" #include "L1Trigger/L1TGlobal/interface/MuonTemplate.h" +#include "L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h" #include "L1Trigger/L1TGlobal/interface/CaloTemplate.h" #include "L1Trigger/L1TGlobal/interface/EnergySumTemplate.h" #include "L1Trigger/L1TGlobal/interface/ExternalTemplate.h" @@ -42,6 +43,7 @@ // Conditions for uGt #include "L1Trigger/L1TGlobal/interface/MuCondition.h" +#include "L1Trigger/L1TGlobal/interface/MuonShowerCondition.h" #include "L1Trigger/L1TGlobal/interface/CaloCondition.h" #include "L1Trigger/L1TGlobal/interface/EnergySumCondition.h" #include "L1Trigger/L1TGlobal/interface/ExternalCondition.h" @@ -60,6 +62,7 @@ // constructor l1t::GlobalBoard::GlobalBoard() : m_candL1Mu(new BXVector), + m_candL1MuShower(new BXVector), m_candL1EG(new BXVector), m_candL1Tau(new BXVector), m_candL1Jet(new BXVector), @@ -91,6 +94,7 @@ l1t::GlobalBoard::GlobalBoard() l1t::GlobalBoard::~GlobalBoard() { //reset(); //why would we need a reset? delete m_candL1Mu; + delete m_candL1MuShower; delete m_candL1EG; delete m_candL1Tau; delete m_candL1Jet; @@ -107,6 +111,7 @@ void l1t::GlobalBoard::setBxLast(int bx) { m_bxLast_ = bx; } void l1t::GlobalBoard::init(const int numberPhysTriggers, const int nrL1Mu, + const int nrL1MuShower, const int nrL1EG, const int nrL1Tau, const int nrL1Jet, @@ -116,6 +121,7 @@ void l1t::GlobalBoard::init(const int numberPhysTriggers, setBxLast(bxLast); m_candL1Mu->setBXRange(m_bxFirst_, m_bxLast_); + m_candL1MuShower->setBXRange(m_bxFirst_, m_bxLast_); m_candL1EG->setBXRange(m_bxFirst_, m_bxLast_); m_candL1Tau->setBXRange(m_bxFirst_, m_bxLast_); m_candL1Jet->setBXRange(m_bxFirst_, m_bxLast_); @@ -384,6 +390,54 @@ void l1t::GlobalBoard::receiveMuonObjectData(edm::Event& iEvent, } //end if ReveiveMuon data } +// receive muon shower data from Global Muon Trigger +void l1t::GlobalBoard::receiveMuonShowerObjectData(edm::Event& iEvent, + const edm::EDGetTokenT>& muShowerInputToken, + const bool receiveMuShower, + const int nrL1MuShower) { + // get data from Global Muon Trigger + if (receiveMuShower) { + edm::Handle> muonData; + iEvent.getByToken(muShowerInputToken, muonData); + + if (!muonData.isValid()) { + if (m_verbosity) { + edm::LogWarning("L1TGlobal") << "\nWarning: BXVector with input tag " + << "\nrequested in configuration, but not found in the event.\n" + << std::endl; + } + } else { + //Loop over Muon Showers in this bx + int nObj = 0; + for (auto mu = muonData->begin(0); mu != muonData->end(0); ++mu) { + if (nObj < nrL1MuShower) { + /* Important here to split up the single object into 4 separate MuonShower + bits for the global board. This is because the UTM library considers those bits separate as well + */ + l1t::MuonShower mus0; + l1t::MuonShower mus1; + l1t::MuonShower musOutOfTime0; + l1t::MuonShower musOutOfTime1; + + mus0.setMus0(mu->mus0()); + mus1.setMus1(mu->mus1()); + musOutOfTime0.setMusOutOfTime0(mu->musOutOfTime0()); + musOutOfTime1.setMusOutOfTime1(mu->musOutOfTime1()); + + (*m_candL1MuShower).push_back(0, &mus0); + (*m_candL1MuShower).push_back(0, &mus1); + (*m_candL1MuShower).push_back(0, &musOutOfTime0); + (*m_candL1MuShower).push_back(0, &musOutOfTime1); + } else { + edm::LogWarning("L1TGlobal") << " Too many Muon Showers (" << nObj + << ") for uGT Configuration maxMuShower =" << nrL1MuShower << std::endl; + } + nObj++; + } //end loop over muon showers in bx + } //end if over valid muon shower data + } //end if ReveiveMuonShower data +} + // receive data from Global External Conditions void l1t::GlobalBoard::receiveExternalData(edm::Event& iEvent, const edm::EDGetTokenT>& extInputToken, @@ -435,6 +489,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::unique_ptr& gtObjectMapRecord, const unsigned int numberPhysTriggers, const int nrL1Mu, + const int nrL1MuShower, const int nrL1EG, const int nrL1Tau, const int nrL1Jet) { @@ -505,6 +560,24 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, } //delete muCondition; + } break; + case CondMuonShower: { + MuonShowerCondition* muShowerCondition = new MuonShowerCondition(itCond->second, this, nrL1MuShower); + + muShowerCondition->setVerbosity(m_verbosity); + + muShowerCondition->evaluateConditionStoreResult(iBxInEvent); + + cMapResults[itCond->first] = muShowerCondition; + + if (m_verbosity && m_isDebugEnabled) { + std::ostringstream myCout; + muShowerCondition->print(myCout); + + edm::LogWarning("L1TGlobal") << "MuonShowerCondition " << myCout.str() << std::endl; + } + //delete muShowerCondition; + } break; case CondCalo: { // BLW Not sure w hat to do with this for now @@ -1039,6 +1112,7 @@ void l1t::GlobalBoard::fillAlgRecord(int iBxInEvent, // clear GTL void l1t::GlobalBoard::reset() { resetMu(); + resetMuonShower(); resetCalo(); resetExternal(); @@ -1054,6 +1128,12 @@ void l1t::GlobalBoard::resetMu() { m_candL1Mu->setBXRange(m_bxFirst_, m_bxLast_); } +// clear muon shower +void l1t::GlobalBoard::resetMuonShower() { + m_candL1MuShower->clear(); + m_candL1MuShower->setBXRange(m_bxFirst_, m_bxLast_); +} + // clear calo void l1t::GlobalBoard::resetCalo() { m_candL1EG->clear(); diff --git a/L1Trigger/L1TGlobal/src/GlobalCondition.cc b/L1Trigger/L1TGlobal/src/GlobalCondition.cc index 05b28bdde1549..3bb8aa22c58aa 100644 --- a/L1Trigger/L1TGlobal/src/GlobalCondition.cc +++ b/L1Trigger/L1TGlobal/src/GlobalCondition.cc @@ -179,6 +179,12 @@ void GlobalCondition::print(std::ostream& myCout) const { << "l1t::CondMuon" << std::endl; } + break; + case l1t::CondMuonShower: { + myCout << " Condition category: " + << "l1t::CondMuonShower" << std::endl; + } + break; case l1t::CondCalo: { myCout << " Condition category: " @@ -431,6 +437,11 @@ void GlobalCondition::print(std::ostream& myCout) const { myCout << " Mu "; } + break; + case l1t::gtMuShower: { + myCout << " MuShower "; + } + break; case l1t::gtEG: { myCout << " EG "; diff --git a/L1Trigger/L1TGlobal/src/MuonShowerCondition.cc b/L1Trigger/L1TGlobal/src/MuonShowerCondition.cc new file mode 100644 index 0000000000000..a3bf27dc82ad2 --- /dev/null +++ b/L1Trigger/L1TGlobal/src/MuonShowerCondition.cc @@ -0,0 +1,188 @@ +// this class header +#include "L1Trigger/L1TGlobal/interface/MuonShowerCondition.h" + +// system include files +#include +#include + +#include +#include +#include + +// user include files +// base classes +#include "L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h" +#include "L1Trigger/L1TGlobal/interface/ConditionEvaluation.h" + +#include "DataFormats/L1Trigger/interface/MuonShower.h" + +#include "L1Trigger/L1TGlobal/interface/GlobalBoard.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/MessageLogger/interface/MessageDrop.h" + +// constructors +// default +l1t::MuonShowerCondition::MuonShowerCondition() : ConditionEvaluation() { + // empty +} + +// from base template condition (from event setup usually) +l1t::MuonShowerCondition::MuonShowerCondition(const GlobalCondition* muonShowerTemplate, + const GlobalBoard* ptrGTL, + const int nrL1MuShower) + : ConditionEvaluation(), + m_gtMuonShowerTemplate(static_cast(muonShowerTemplate)), + m_gtGTL(ptrGTL) { + m_condMaxNumberObjects = nrL1MuShower; +} + +// copy constructor +void l1t::MuonShowerCondition::copy(const l1t::MuonShowerCondition& cp) { + m_gtMuonShowerTemplate = cp.gtMuonShowerTemplate(); + m_gtGTL = cp.gtGTL(); + + m_condMaxNumberObjects = cp.condMaxNumberObjects(); + m_condLastResult = cp.condLastResult(); + m_combinationsInCond = cp.getCombinationsInCond(); + + m_verbosity = cp.m_verbosity; +} + +l1t::MuonShowerCondition::MuonShowerCondition(const l1t::MuonShowerCondition& cp) : ConditionEvaluation() { copy(cp); } + +// destructor +l1t::MuonShowerCondition::~MuonShowerCondition() { + // empty +} + +// equal operator +l1t::MuonShowerCondition& l1t::MuonShowerCondition::operator=(const l1t::MuonShowerCondition& cp) { + copy(cp); + return *this; +} + +// methods +void l1t::MuonShowerCondition::setGtMuonShowerTemplate(const MuonShowerTemplate* muonTempl) { + m_gtMuonShowerTemplate = muonTempl; +} + +/// set the pointer to GTL +void l1t::MuonShowerCondition::setGtGTL(const GlobalBoard* ptrGTL) { m_gtGTL = ptrGTL; } + +// try all object permutations and check spatial correlations, if required +const bool l1t::MuonShowerCondition::evaluateCondition(const int bxEval) const { + // number of trigger objects in the condition + int nObjInCond = m_gtMuonShowerTemplate->nrObjects(); + + // the candidates + const BXVector* candVec = m_gtGTL->getCandL1MuShower(); + + // Look at objects in bx = bx + relativeBx + int useBx = bxEval + m_gtMuonShowerTemplate->condRelativeBx(); + + // Fail condition if attempting to get Bx outside of range + if ((useBx < candVec->getFirstBX()) || (useBx > candVec->getLastBX())) { + return false; + } + + // store the indices of the shower objects + // from the combination evaluated in the condition + SingleCombInCond objectsInComb; + objectsInComb.reserve(nObjInCond); + + // clear the m_combinationsInCond vector + (combinationsInCond()).clear(); + + // clear the indices in the combination + objectsInComb.clear(); + + // If no candidates, no use looking any further. + int numberObjects = candVec->size(useBx); + if (numberObjects < 1) { + return false; + } + + std::vector index(numberObjects); + + for (int i = 0; i < numberObjects; ++i) { + index[i] = i; + } + + bool condResult = false; + + // index is always zero, as they are global quantities (there is only one object) + int indexObj = 0; + + objectsInComb.push_back(indexObj); + (combinationsInCond()).push_back(objectsInComb); + + // if we get here all checks were successfull for this combination + // set the general result for evaluateCondition to "true" + + condResult = true; + return condResult; +} + +// load muon candidates +const l1t::MuonShower* l1t::MuonShowerCondition::getCandidate(const int bx, const int indexCand) const { + return (m_gtGTL->getCandL1MuShower())->at(bx, indexCand); //BLW Change for BXVector +} + +/** + * checkObjectParameter - Compare a single particle with a numbered condition. + * + * @param iCondition The number of the condition. + * @param cand The candidate to compare. + * + * @return The result of the comparison (false if a condition does not exist). + */ + +const bool l1t::MuonShowerCondition::checkObjectParameter(const int iCondition, + const l1t::MuonShower& cand, + const unsigned int index) const { + // number of objects in condition + int nObjInCond = m_gtMuonShowerTemplate->nrObjects(); + + if (iCondition >= nObjInCond || iCondition < 0) { + return false; + } + + const MuonShowerTemplate::ObjectParameter objPar = (*(m_gtMuonShowerTemplate->objectParameter()))[iCondition]; + + LogDebug("L1TGlobal") << "\n MuonShowerTemplate::ObjectParameter : " << std::hex << "\n\t MuonShower0 = 0x " + << objPar.MuonShower0 << "\n\t MuonShower1 = 0x " << objPar.MuonShower1 + << "\n\t MuonShowerOutOfTime0 = 0x " << objPar.MuonShowerOutOfTime0 + << "\n\t MuonShowerOutOfTime1 = 0x " << objPar.MuonShowerOutOfTime1 << std::endl; + + LogDebug("L1TGlobal") << "\n l1t::MuonShower : " + << "\n\t MuonShower0 = 0x " << cand.mus0() << "\n\t MuonShower1 = 0x " << cand.mus1() + << "\n\t MuonShowerOutOfTime0 = 0x " << cand.musOutOfTime0() + << "\n\t MuonShowerOutOfTime1 = 0x " << cand.musOutOfTime1() << std::dec << std::endl; + + // check oneNominalInTime + if (cand.mus0() != objPar.MuonShower0) { + LogDebug("L1TGlobal") << "\t\t MuonShower failed MuonShower0 requirement" << std::endl; + return false; + } + if (cand.mus1() != objPar.MuonShower1) { + LogDebug("L1TGlobal") << "\t\t MuonShower failed MuonShower1 requirement" << std::endl; + return false; + } + if (cand.musOutOfTime0() != objPar.MuonShowerOutOfTime0) { + LogDebug("L1TGlobal") << "\t\t MuonShower failed MuonShowerOutOfTime0 requirement" << std::endl; + return false; + } + if (cand.musOutOfTime1() != objPar.MuonShowerOutOfTime1) { + LogDebug("L1TGlobal") << "\t\t MuonShower failed MuonShowerOutOfTime1 requirement" << std::endl; + return false; + } + + return true; +} + +void l1t::MuonShowerCondition::print(std::ostream& myCout) const { + m_gtMuonShowerTemplate->print(myCout); + + ConditionEvaluation::print(myCout); +} diff --git a/L1Trigger/L1TGlobal/src/MuonShowerTemplate.cc b/L1Trigger/L1TGlobal/src/MuonShowerTemplate.cc new file mode 100644 index 0000000000000..11c323d81e0ee --- /dev/null +++ b/L1Trigger/L1TGlobal/src/MuonShowerTemplate.cc @@ -0,0 +1,81 @@ +// this class header +#include "L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h" + +// system include files +#include +#include + +MuonShowerTemplate::MuonShowerTemplate() : GlobalCondition() { m_condCategory = l1t::CondMuonShower; } + +MuonShowerTemplate::MuonShowerTemplate(const std::string& cName) : GlobalCondition(cName) { + m_condCategory = l1t::CondMuonShower; +} + +MuonShowerTemplate::MuonShowerTemplate(const std::string& cName, const l1t::GtConditionType& cType) + : GlobalCondition(cName, l1t::CondMuonShower, cType) { + int nObjects = nrObjects(); + + if (nObjects > 0) { + m_objectParameter.reserve(nObjects); + + m_objectType.reserve(nObjects); + m_objectType.assign(nObjects, l1t::gtMuShower); + } +} + +// copy constructor +MuonShowerTemplate::MuonShowerTemplate(const MuonShowerTemplate& cp) : GlobalCondition(cp.m_condName) { copy(cp); } + +// destructor +MuonShowerTemplate::~MuonShowerTemplate() { + // empty now +} + +// assign operator +MuonShowerTemplate& MuonShowerTemplate::operator=(const MuonShowerTemplate& cp) { + copy(cp); + return *this; +} + +// setConditionParameter - set the parameters of the condition +void MuonShowerTemplate::setConditionParameter(const std::vector& objParameter) { + m_objectParameter = objParameter; +} + +void MuonShowerTemplate::print(std::ostream& myCout) const { + myCout << "\n MuonShowerTemplate print..." << std::endl; + + GlobalCondition::print(myCout); + + int nObjects = nrObjects(); + + for (int i = 0; i < nObjects; i++) { + myCout << std::endl; + myCout << " Template for object " << i << " [ hex ]" << std::endl; + myCout << " MuonShower0 = " << std::hex << m_objectParameter[i].MuonShower0 << std::endl; + myCout << " MuonShower1 = " << std::hex << m_objectParameter[i].MuonShower1 << std::endl; + myCout << " MuonShowerOutOfTime0 = " << std::hex << m_objectParameter[i].MuonShowerOutOfTime0 << std::endl; + myCout << " MuonShowerOutOfTime1 = " << std::hex << m_objectParameter[i].MuonShowerOutOfTime1 << std::endl; + } + + // reset to decimal output + myCout << std::dec << std::endl; +} + +void MuonShowerTemplate::copy(const MuonShowerTemplate& cp) { + m_condName = cp.condName(); + m_condCategory = cp.condCategory(); + m_condType = cp.condType(); + m_objectType = cp.objectType(); + m_condGEq = cp.condGEq(); + m_condChipNr = cp.condChipNr(); + m_condRelativeBx = cp.condRelativeBx(); + + m_objectParameter = *(cp.objectParameter()); +} + +// output stream operator +std::ostream& operator<<(std::ostream& os, const MuonShowerTemplate& result) { + result.print(os); + return os; +} diff --git a/L1Trigger/L1TGlobal/src/TriggerMenu.cc b/L1Trigger/L1TGlobal/src/TriggerMenu.cc index 74e6d5ff7eff2..bb2cac90174a6 100644 --- a/L1Trigger/L1TGlobal/src/TriggerMenu.cc +++ b/L1Trigger/L1TGlobal/src/TriggerMenu.cc @@ -41,6 +41,7 @@ TriggerMenu::TriggerMenu( const std::string& triggerMenuNameVal, const unsigned int numberConditionChips, const std::vector >& vecMuonTemplateVal, + const std::vector >& vecMuonShowerTemplateVal, const std::vector >& vecCaloTemplateVal, const std::vector >& vecEnergySumTemplateVal, const std::vector >& vecExternalTemplateVal, @@ -57,6 +58,7 @@ TriggerMenu::TriggerMenu( m_triggerMenuImplementation(0x0), m_scaleDbKey("NULL"), m_vecMuonTemplate(vecMuonTemplateVal), + m_vecMuonShowerTemplate(vecMuonShowerTemplateVal), m_vecCaloTemplate(vecCaloTemplateVal), m_vecEnergySumTemplate(vecEnergySumTemplateVal), m_vecExternalTemplate(vecExternalTemplateVal), @@ -81,6 +83,7 @@ TriggerMenu::TriggerMenu(const TriggerMenu& rhs) { // copy physics conditions m_vecMuonTemplate = rhs.m_vecMuonTemplate; + m_vecMuonShowerTemplate = rhs.m_vecMuonShowerTemplate; m_vecCaloTemplate = rhs.m_vecCaloTemplate; m_vecEnergySumTemplate = rhs.m_vecEnergySumTemplate; m_vecExternalTemplate = rhs.m_vecExternalTemplate; @@ -128,6 +131,7 @@ TriggerMenu& TriggerMenu::operator=(const TriggerMenu& rhs) { m_triggerMenuUUID = rhs.m_triggerMenuUUID; m_vecMuonTemplate = rhs.m_vecMuonTemplate; + m_vecMuonShowerTemplate = rhs.m_vecMuonShowerTemplate; m_vecCaloTemplate = rhs.m_vecCaloTemplate; m_vecEnergySumTemplate = rhs.m_vecEnergySumTemplate; m_vecExternalTemplate = rhs.m_vecExternalTemplate; @@ -189,6 +193,26 @@ void TriggerMenu::buildGtConditionMap() { } } + // + size_t vecMuonShowerSize = m_vecMuonShowerTemplate.size(); + if (condMapSize < vecMuonShowerSize) { + m_conditionMap.resize(vecMuonShowerSize); + condMapSize = m_conditionMap.size(); + } + + chipNr = -1; + + for (std::vector >::iterator itCondOnChip = m_vecMuonShowerTemplate.begin(); + itCondOnChip != m_vecMuonShowerTemplate.end(); + itCondOnChip++) { + chipNr++; + + for (std::vector::iterator itCond = itCondOnChip->begin(); itCond != itCondOnChip->end(); + itCond++) { + (m_conditionMap.at(chipNr))[itCond->condName()] = &(*itCond); + } + } + // size_t vecCaloSize = m_vecCaloTemplate.size(); if (condMapSize < vecCaloSize) { diff --git a/L1Trigger/L1TGlobal/src/classes.h b/L1Trigger/L1TGlobal/src/classes.h index 6a935d541760f..b8e6e6237c40a 100644 --- a/L1Trigger/L1TGlobal/src/classes.h +++ b/L1Trigger/L1TGlobal/src/classes.h @@ -8,5 +8,6 @@ namespace L1Trigger_L1TGlobal { std::vector dummy3; std::vector dummy4; std::vector dummy5; + std::vector dummy6; }; } // namespace L1Trigger_L1TGlobal diff --git a/L1Trigger/L1TGlobal/src/classes_def.xml b/L1Trigger/L1TGlobal/src/classes_def.xml index 39b771b22d5ae..1ea80d258347e 100644 --- a/L1Trigger/L1TGlobal/src/classes_def.xml +++ b/L1Trigger/L1TGlobal/src/classes_def.xml @@ -31,6 +31,7 @@ + @@ -44,4 +45,10 @@ + + + + + + diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisL1Upgrade.h b/L1Trigger/L1TNtuples/interface/L1AnalysisL1Upgrade.h index 21fdfba49510c..1ea121808581b 100644 --- a/L1Trigger/L1TNtuples/interface/L1AnalysisL1Upgrade.h +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisL1Upgrade.h @@ -13,6 +13,7 @@ #include "DataFormats/L1Trigger/interface/Jet.h" #include "DataFormats/L1Trigger/interface/Muon.h" #include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" #include "L1AnalysisL1UpgradeDataFormat.h" @@ -30,6 +31,7 @@ namespace L1Analysis { void SetJet(const edm::Handle jet, unsigned maxL1Upgrade); void SetSum(const edm::Handle sums, unsigned maxL1Upgrade); void SetMuon(const edm::Handle muon, unsigned maxL1Upgrade); + void SetMuonShower(const edm::Handle muonShower, unsigned maxL1Upgrade); L1AnalysisL1UpgradeDataFormat* getData() { return &l1upgrade_; } private: diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h index 82168330c0e31..7f01488b42283 100644 --- a/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h @@ -125,6 +125,12 @@ namespace L1Analysis { muonTfMuonIdx.clear(); muonBx.clear(); + nMuonShowers = 0; + muonShowerBx.clear(); + muonShowerOneNominal.clear(); + muonShowerOneTight.clear(); + muonShowerTwoLoose.clear(); + nSums = 0; sumType.clear(); sumEt.clear(); @@ -211,6 +217,12 @@ namespace L1Analysis { std::vector muonTfMuonIdx; std::vector muonBx; + unsigned short int nMuonShowers; + std::vector muonShowerBx; + std::vector muonShowerOneNominal; + std::vector muonShowerOneTight; + std::vector muonShowerTwoLoose; + unsigned short int nSums; std::vector sumType; std::vector sumEt; diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShower.h b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShower.h new file mode 100644 index 0000000000000..2d9363ebe28a6 --- /dev/null +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShower.h @@ -0,0 +1,21 @@ +#ifndef __L1Analysis_L1AnalysisL1UpgradeTfMuonShower_H__ +#define __L1Analysis_L1AnalysisL1UpgradeTfMuonShower_H__ + +#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h" + +#include "L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShowerDataFormat.h" +namespace L1Analysis { + class L1AnalysisL1UpgradeTfMuonShower { + public: + enum { TEST = 0 }; + L1AnalysisL1UpgradeTfMuonShower(); + ~L1AnalysisL1UpgradeTfMuonShower(); + void Reset() { l1upgradetfmuonshower_.Reset(); } + void SetTfMuonShower(const l1t::RegionalMuonShowerBxCollection& muon, unsigned maxL1UpgradeTfMuonShower); + L1AnalysisL1UpgradeTfMuonShowerDataFormat* getData() { return &l1upgradetfmuonshower_; } + + private: + L1AnalysisL1UpgradeTfMuonShowerDataFormat l1upgradetfmuonshower_; + }; +} // namespace L1Analysis +#endif diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShowerDataFormat.h b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShowerDataFormat.h new file mode 100644 index 0000000000000..6424f59a4b44c --- /dev/null +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShowerDataFormat.h @@ -0,0 +1,32 @@ +#ifndef __L1Analysis_L1AnalysisL1UpgradeTfMuonShowerDataFormat_H__ +#define __L1Analysis_L1AnalysisL1UpgradeTfMuonShowerDataFormat_H__ + +#include +#include + +namespace L1Analysis { + + struct L1AnalysisL1UpgradeTfMuonShowerDataFormat { + L1AnalysisL1UpgradeTfMuonShowerDataFormat() { Reset(); }; + ~L1AnalysisL1UpgradeTfMuonShowerDataFormat(){}; + + void Reset() { + nTfMuonShowers = 0; + tfMuonShowerBx.clear(); + tfMuonShowerOneNominal.clear(); + tfMuonShowerOneTight.clear(); + tfMuonShowerTwoLoose.clear(); + tfMuonShowerEndcap.clear(); + tfMuonShowerSector.clear(); + } + + unsigned short int nTfMuonShowers; + std::vector tfMuonShowerBx; + std::vector tfMuonShowerOneNominal; + std::vector tfMuonShowerOneTight; + std::vector tfMuonShowerTwoLoose; + std::vector tfMuonShowerEndcap; + std::vector tfMuonShowerSector; + }; +} // namespace L1Analysis +#endif diff --git a/L1Trigger/L1TNtuples/plugins/L1UpgradeTfMuonShowerTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1UpgradeTfMuonShowerTreeProducer.cc new file mode 100644 index 0000000000000..33dd61f2ce89d --- /dev/null +++ b/L1Trigger/L1TNtuples/plugins/L1UpgradeTfMuonShowerTreeProducer.cc @@ -0,0 +1,97 @@ +// system include files +#include + +// framework +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +// data formats +#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h" + +// ROOT output stuff +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "TTree.h" + +#include "L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShower.h" + +// +// class declaration +// + +class L1UpgradeTfMuonShowerTreeProducer : public edm::one::EDAnalyzer<> { +public: + explicit L1UpgradeTfMuonShowerTreeProducer(const edm::ParameterSet&); + ~L1UpgradeTfMuonShowerTreeProducer() override; + +private: + void beginJob(void) override; + void analyze(const edm::Event&, const edm::EventSetup&) override; + void endJob() override; + +public: + L1Analysis::L1AnalysisL1UpgradeTfMuonShower l1UpgradeEmtf; + L1Analysis::L1AnalysisL1UpgradeTfMuonShowerDataFormat* l1UpgradeEmtfData; + +private: + unsigned maxL1UpgradeTfMuonShower_; + + // output file + edm::Service fs_; + + // tree + TTree* tree_; + + // EDM input tags + edm::EDGetTokenT emtfMuonShowerToken_; +}; + +L1UpgradeTfMuonShowerTreeProducer::L1UpgradeTfMuonShowerTreeProducer(const edm::ParameterSet& iConfig) { + emtfMuonShowerToken_ = consumes( + iConfig.getUntrackedParameter("emtfMuonShowerToken")); + + maxL1UpgradeTfMuonShower_ = iConfig.getParameter("maxL1UpgradeTfMuonShower"); + + l1UpgradeEmtfData = l1UpgradeEmtf.getData(); + + // set up output + tree_ = fs_->make("L1UpgradeTfMuonShowerTree", "L1UpgradeTfMuonShowerTree"); + tree_->Branch( + "L1UpgradeEmtfMuonShower", "L1Analysis::L1AnalysisL1UpgradeTfMuonShowerDataFormat", &l1UpgradeEmtfData, 32000, 3); +} + +L1UpgradeTfMuonShowerTreeProducer::~L1UpgradeTfMuonShowerTreeProducer() {} + +// +// member functions +// + +// ------------ method called to for each event ------------ +void L1UpgradeTfMuonShowerTreeProducer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + l1UpgradeEmtf.Reset(); + + edm::Handle emtfMuonShower; + + iEvent.getByToken(emtfMuonShowerToken_, emtfMuonShower); + + if (emtfMuonShower.isValid()) { + l1UpgradeEmtf.SetTfMuonShower(*emtfMuonShower, maxL1UpgradeTfMuonShower_); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade EMTF muons not found. Branch will not be filled" << std::endl; + } + + tree_->Fill(); +} + +// ------------ method called once each job just before starting event loop ------------ +void L1UpgradeTfMuonShowerTreeProducer::beginJob(void) {} + +// ------------ method called once each job just after ending the event loop ------------ +void L1UpgradeTfMuonShowerTreeProducer::endJob() {} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1UpgradeTfMuonShowerTreeProducer); diff --git a/L1Trigger/L1TNtuples/plugins/L1UpgradeTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1UpgradeTreeProducer.cc index 32add86552bc7..596a7c7103bcb 100644 --- a/L1Trigger/L1TNtuples/plugins/L1UpgradeTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1UpgradeTreeProducer.cc @@ -8,7 +8,7 @@ Description: Produce L1 Extra tree Implementation: - + */ // // Original Author: @@ -33,6 +33,7 @@ Description: Produce L1 Extra tree #include "DataFormats/L1Trigger/interface/Tau.h" #include "DataFormats/L1Trigger/interface/Jet.h" #include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" #include "DataFormats/L1Trigger/interface/EtSum.h" // ROOT output stuff @@ -75,6 +76,7 @@ class L1UpgradeTreeProducer : public edm::EDAnalyzer { edm::EDGetTokenT jetToken_; edm::EDGetTokenT sumToken_; edm::EDGetTokenT muonToken_; + edm::EDGetTokenT muonShowerToken_; }; L1UpgradeTreeProducer::L1UpgradeTreeProducer(const edm::ParameterSet& iConfig) { @@ -83,6 +85,8 @@ L1UpgradeTreeProducer::L1UpgradeTreeProducer(const edm::ParameterSet& iConfig) { jetToken_ = consumes(iConfig.getUntrackedParameter("jetToken")); sumToken_ = consumes(iConfig.getUntrackedParameter("sumToken")); muonToken_ = consumes(iConfig.getUntrackedParameter("muonToken")); + muonShowerToken_ = + consumes(iConfig.getUntrackedParameter("muonShowerToken")); const auto& taus = iConfig.getUntrackedParameter>("tauTokens"); for (const auto& tau : taus) { @@ -116,11 +120,13 @@ void L1UpgradeTreeProducer::analyze(const edm::Event& iEvent, const edm::EventSe edm::Handle jet; edm::Handle sums; edm::Handle muon; + edm::Handle muonShower; iEvent.getByToken(egToken_, eg); iEvent.getByToken(jetToken_, jet); iEvent.getByToken(sumToken_, sums); iEvent.getByToken(muonToken_, muon); + iEvent.getByToken(muonShowerToken_, muonShower); if (eg.isValid()) { l1Upgrade->SetEm(eg, maxL1Upgrade_); @@ -145,6 +151,12 @@ void L1UpgradeTreeProducer::analyze(const edm::Event& iEvent, const edm::EventSe edm::LogWarning("MissingProduct") << "L1Upgrade Muons not found. Branch will not be filled" << std::endl; } + if (muonShower.isValid()) { + l1Upgrade->SetMuonShower(muonShower, maxL1Upgrade_); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade Muon Showers not found. Branch will not be filled" << std::endl; + } + for (auto& tautoken : tauTokens_) { edm::Handle tau; iEvent.getByToken(tautoken, tau); diff --git a/L1Trigger/L1TNtuples/python/L1NtupleRAW_cff.py b/L1Trigger/L1TNtuples/python/L1NtupleRAW_cff.py index a9767de62b269..0645ef37fcd36 100644 --- a/L1Trigger/L1TNtuples/python/L1NtupleRAW_cff.py +++ b/L1Trigger/L1TNtuples/python/L1NtupleRAW_cff.py @@ -4,26 +4,28 @@ from L1Trigger.L1TNtuples.l1ExtraTree_cfi import * from L1Trigger.L1TNtuples.l1CaloTowerTree_cfi import * from L1Trigger.L1TNtuples.l1UpgradeTfMuonTree_cfi import * +from L1Trigger.L1TNtuples.l1UpgradeTfMuonShowerTree_cfi import * from L1Trigger.L1TNtuples.l1UpgradeTree_cfi import * from L1Trigger.L1TNtuples.l1uGTTree_cfi import * from L1Trigger.L1TNtuples.l1HOTree_cfi import * # we don't have omtfDigis yet, use unpacked input payloads of GMT -l1UpgradeTfMuonTree.omtfMuonToken = cms.untracked.InputTag("gmtStage2Digis","OMTF") +l1UpgradeTfMuonTree.omtfMuonToken = cms.untracked.InputTag("gmtStage2Digis","OMTF") # we don't have emtfDigis yet, use unpacked input payloads of GMT -l1UpgradeTfMuonTree.emtfMuonToken = cms.untracked.InputTag("gmtStage2Digis","EMTF") +l1UpgradeTfMuonTree.emtfMuonToken = cms.untracked.InputTag("gmtStage2Digis","EMTF") L1NtupleRAW = cms.Sequence( l1EventTree #+l1ExtraTree +l1CaloTowerTree +l1UpgradeTfMuonTree + +l1UpgradeTfMuonShowerTree +l1UpgradeTree +l1uGTTree +l1HOTree ) -# do not have l1t::CaloTowerBxCollection in Stage1 +# do not have l1t::CaloTowerBxCollection in Stage1 from Configuration.Eras.Modifier_stage1L1Trigger_cff import stage1L1Trigger _stage1_L1NTupleRAW = L1NtupleRAW.copyAndExclude([l1CaloTowerTree,l1UpgradeTfMuonTree]) stage1L1Trigger.toReplaceWith(L1NtupleRAW,_stage1_L1NTupleRAW) diff --git a/L1Trigger/L1TNtuples/python/l1UpgradeTfMuonShowerTree_cfi.py b/L1Trigger/L1TNtuples/python/l1UpgradeTfMuonShowerTree_cfi.py new file mode 100644 index 0000000000000..f6abfc9ef3142 --- /dev/null +++ b/L1Trigger/L1TNtuples/python/l1UpgradeTfMuonShowerTree_cfi.py @@ -0,0 +1,12 @@ +import FWCore.ParameterSet.Config as cms + +l1UpgradeTfMuonShowerTree = cms.EDAnalyzer( + "L1UpgradeTfMuonShowerTreeProducer", + emtfMuonShowerToken = cms.untracked.InputTag("simEmtfShowers","EMTF"), + maxL1UpgradeTfMuonShower = cms.uint32(12), +) + +from Configuration.Eras.Modifier_stage1L1Trigger_cff import stage1L1Trigger +stage1L1Trigger.toModify( l1UpgradeTfMuonShowerTree, + emtfMuonShowerToken = "none", +) diff --git a/L1Trigger/L1TNtuples/python/l1UpgradeTree_cfi.py b/L1Trigger/L1TNtuples/python/l1UpgradeTree_cfi.py index fe27c58e77711..c0be4e75a1947 100644 --- a/L1Trigger/L1TNtuples/python/l1UpgradeTree_cfi.py +++ b/L1Trigger/L1TNtuples/python/l1UpgradeTree_cfi.py @@ -6,6 +6,7 @@ tauTokens = cms.untracked.VInputTag(cms.InputTag("caloStage2Digis","Tau")), jetToken = cms.untracked.InputTag("caloStage2Digis","Jet"), muonToken = cms.untracked.InputTag("gmtStage2Digis","Muon"), + muonShowerToken = cms.untracked.InputTag("simGmtShowerDigis"), muonLegacyToken = cms.untracked.InputTag("muonLegacyInStage2FormatDigis","legacyMuon"), sumToken = cms.untracked.InputTag("caloStage2Digis","EtSum"), maxL1Upgrade = cms.uint32(60) @@ -17,6 +18,6 @@ tauTokens = cms.untracked.VInputTag("caloStage1FinalDigis:rlxTaus"), jetToken = "caloStage1FinalDigis", muonToken = "muonLegacyInStage2FormatDigis", + muonShowerToken = "", sumToken = "caloStage1FinalDigis", ) - diff --git a/L1Trigger/L1TNtuples/src/L1AnalysisL1Upgrade.cc b/L1Trigger/L1TNtuples/src/L1AnalysisL1Upgrade.cc index e037ce0e76339..0472960563a7e 100644 --- a/L1Trigger/L1TNtuples/src/L1AnalysisL1Upgrade.cc +++ b/L1Trigger/L1TNtuples/src/L1AnalysisL1Upgrade.cc @@ -121,6 +121,23 @@ void L1Analysis::L1AnalysisL1Upgrade::SetMuon(const edm::Handle muonShower, + unsigned maxL1Upgrade) { + for (int ibx = muonShower->getFirstBX(); ibx <= muonShower->getLastBX(); ++ibx) { + for (l1t::MuonShowerBxCollection::const_iterator it = muonShower->begin(ibx); + it != muonShower->end(ibx) && l1upgrade_.nMuonShowers < maxL1Upgrade; + it++) { + if (it->isValid()) { + l1upgrade_.muonShowerBx.push_back(ibx); + l1upgrade_.muonShowerOneNominal.push_back(it->isOneNominalInTime()); + l1upgrade_.muonShowerOneTight.push_back(it->isOneTightInTime()); + l1upgrade_.muonShowerTwoLoose.push_back(it->isTwoLooseInTime()); + l1upgrade_.nMuonShowers++; + } + } + } +} + void L1Analysis::L1AnalysisL1Upgrade::SetSum(const edm::Handle sums, unsigned maxL1Upgrade) { for (int ibx = sums->getFirstBX(); ibx <= sums->getLastBX(); ++ibx) { for (l1t::EtSumBxCollection::const_iterator it = sums->begin(ibx); diff --git a/L1Trigger/L1TNtuples/src/L1AnalysisL1UpgradeTfMuonShower.cc b/L1Trigger/L1TNtuples/src/L1AnalysisL1UpgradeTfMuonShower.cc new file mode 100644 index 0000000000000..65677c599fad6 --- /dev/null +++ b/L1Trigger/L1TNtuples/src/L1AnalysisL1UpgradeTfMuonShower.cc @@ -0,0 +1,24 @@ +#include "L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShower.h" +#include +L1Analysis::L1AnalysisL1UpgradeTfMuonShower::L1AnalysisL1UpgradeTfMuonShower() {} + +L1Analysis::L1AnalysisL1UpgradeTfMuonShower::~L1AnalysisL1UpgradeTfMuonShower() {} + +void L1Analysis::L1AnalysisL1UpgradeTfMuonShower::SetTfMuonShower(const l1t::RegionalMuonShowerBxCollection& muonShower, + unsigned maxL1UpgradeTfMuonShower) { + for (int ibx = muonShower.getFirstBX(); ibx <= muonShower.getLastBX(); ++ibx) { + for (auto it = muonShower.begin(ibx); + it != muonShower.end(ibx) && l1upgradetfmuonshower_.nTfMuonShowers < maxL1UpgradeTfMuonShower; + ++it) { + if (it->isValid()) { + l1upgradetfmuonshower_.tfMuonShowerBx.push_back(ibx); + l1upgradetfmuonshower_.tfMuonShowerEndcap.push_back(it->endcap()); + l1upgradetfmuonshower_.tfMuonShowerSector.push_back(it->sector()); + l1upgradetfmuonshower_.tfMuonShowerOneNominal.push_back(it->isOneNominalInTime()); + l1upgradetfmuonshower_.tfMuonShowerOneTight.push_back(it->isOneTightInTime()); + l1upgradetfmuonshower_.tfMuonShowerTwoLoose.push_back(it->isTwoLooseInTime()); + l1upgradetfmuonshower_.nTfMuonShowers++; + } + } + } +} diff --git a/L1Trigger/L1TNtuples/src/classes.h b/L1Trigger/L1TNtuples/src/classes.h index b1c776e5472b3..220da7a47b3f9 100644 --- a/L1Trigger/L1TNtuples/src/classes.h +++ b/L1Trigger/L1TNtuples/src/classes.h @@ -20,6 +20,7 @@ #include "L1Trigger/L1TNtuples/interface/L1AnalysisL1MenuDataFormat.h" #include "L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeDataFormat.h" #include "L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonDataFormat.h" +#include "L1Trigger/L1TNtuples/interface/L1AnalysisL1UpgradeTfMuonShowerDataFormat.h" #include "L1Trigger/L1TNtuples/interface/L1AnalysisL1CaloTowerDataFormat.h" #include "L1Trigger/L1TNtuples/interface/L1AnalysisL1CaloClusterDataFormat.h" #include "L1Trigger/L1TNtuples/interface/L1AnalysisBMTFInputsDataFormat.h" diff --git a/L1Trigger/L1TNtuples/src/classes_def.xml b/L1Trigger/L1TNtuples/src/classes_def.xml index 14cc04a2f5c59..2fd7d7bafa97f 100644 --- a/L1Trigger/L1TNtuples/src/classes_def.xml +++ b/L1Trigger/L1TNtuples/src/classes_def.xml @@ -21,6 +21,7 @@ +