diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h index f535ca1728991..5b24441295f3d 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h @@ -118,6 +118,7 @@ namespace l1tp2 { // Other getters float ptLSB() const { return LSB_PT; } ap_uint<12> pt() const { return (clusterData & 0xFFF); } + float ptFloat() const { return (pt() * ptLSB()); } // crystal eta in the correlator region (LSB: 2.8/170) ap_uint<8> eta() const { return ((clusterData >> 12) & 0xFF); } // (eight 1's) 0b11111111 = 0xFF @@ -161,7 +162,8 @@ namespace l1tp2 { bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0x0); } // Get real eta (does not depend on card number). crystal iEta = 0 starts at real eta -1.4841. - float realEta() const { return (float)((-1 * ETA_RANGE_ONE_SIDE) + (eta() * LSB_ETA)); } + // LSB_ETA/2 is to add half a crystal width to get the center of the crystal in eta + float realEta() const { return (float)((-1 * ETA_RANGE_ONE_SIDE) + (eta() * LSB_ETA) + (LSB_ETA / 2)); } // Get real phi (uses card number). float realPhi() const { @@ -176,7 +178,8 @@ namespace l1tp2 { } int thisPhi = (phi() + (offset_tower * n_crystals_in_tower)); // crystal iPhi = 0 starts at real phi = -180 degrees - return (float)((-1 * M_PI) + (thisPhi * LSB_PHI)); + // LSB_PHI/2 is to add half a crystal width to get the center of the crystal in phi + return (float)((-1 * M_PI) + (thisPhi * LSB_PHI) + (LSB_PHI / 2)); } }; diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h new file mode 100644 index 0000000000000..a3d20221432df --- /dev/null +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h @@ -0,0 +1,137 @@ +#ifndef DataFormats_L1TCalorimeterPhase2_GCTEmDigiCluster_h +#define DataFormats_L1TCalorimeterPhase2_GCTEmDigiCluster_h + +#include +#include + +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" + +namespace l1tp2 { + + class GCTEmDigiCluster { + private: + // Data + unsigned long long int clusterData; + + // Constants + static constexpr float LSB_PT = 0.5; // 0.5 GeV + + // start of the unused bits + static constexpr int n_bits_unused_start = 52; + + // Reference to the original float cluster + edm::Ref clusterRef_; + + // reference to the original digitized cluster (before duplication in the output links) + edm::Ref digiClusterRef_; + + public: + GCTEmDigiCluster() { clusterData = 0; } + + GCTEmDigiCluster(ap_uint<64> data) { clusterData = data; } + + GCTEmDigiCluster(ap_uint<12> pt, + int etaCr, + int phiCr, + ap_uint<4> hoe, + ap_uint<2> hoeFlag, + ap_uint<3> iso, + ap_uint<2> isoFlag, + ap_uint<6> fb, + ap_uint<5> timing, + ap_uint<2> shapeFlag, + ap_uint<2> brems) { + // To use .range() we need an ap class member + ap_uint<64> temp_data; + ap_uint<7> etaCrDigitized = abs(etaCr); + ap_int<7> phiCrDigitized = phiCr; + + temp_data.range(11, 0) = pt.range(); + temp_data.range(18, 12) = etaCrDigitized.range(); + temp_data.range(25, 19) = phiCrDigitized.range(); + temp_data.range(29, 26) = hoe.range(); + temp_data.range(31, 30) = hoeFlag.range(); + temp_data.range(34, 32) = iso.range(); + temp_data.range(36, 35) = isoFlag.range(); + temp_data.range(42, 37) = fb.range(); + temp_data.range(47, 43) = timing.range(); + temp_data.range(49, 48) = shapeFlag.range(); + temp_data.range(51, 50) = brems.range(); + + clusterData = temp_data; + } + + // Setters + void setRef(const edm::Ref& clusterRef) { clusterRef_ = clusterRef; } + + void setDigiRef(const edm::Ref& digiClusterRef) { + digiClusterRef_ = digiClusterRef; + } + + // Getters + ap_uint<64> data() const { return clusterData; } + + // Other getters + float ptLSB() const { return LSB_PT; } + ap_uint<12> pt() const { return data().range(11, 0); } + float ptFloat() const { return pt() * ptLSB(); } + + // crystal eta (unsigned, 7 bits), starting at 0 at real eta = 0, and increasing in the direction of larger abs(real eta) + // to convert to real eta, need to know which link this cluster is in + int eta() const { return (ap_uint<7>)data().range(18, 12); } + + // crystal phi (signed, 7 bits), relative to center of the SLR + // to convert to real phi, need to know which SLR this cluster is in + int phi() const { return (ap_int<7>)data().range(25, 19); } + + // HoE value and flag: not defined yet in the emulator + ap_uint<4> hoe() const { return data().range(29, 26); } + ap_uint<2> hoeFlag() const { return data().range(31, 30); } + + // Raw isolation sum: not saved in the emulator + ap_uint<3> iso() const { return data().range(34, 32); } + + // iso flag: two bits, least significant bit is the standalone WP (true or false), second bit is the looseTk WP (true or false) + // e.g. 0b01 : standalone iso flag passed, loose Tk iso flag did not pass + ap_uint<2> isoFlags() const { return data().range(36, 35); } + bool passes_iso() const { return (isoFlags() & 0x1); } // standalone iso WP + bool passes_looseTkiso() const { return (isoFlags() & 0x2); } // loose Tk iso WP + + // fb and timing: not saved in the current emulator + ap_uint<6> fb() const { return data().range(42, 37); } + ap_uint<5> timing() const { return data().range(47, 43); } + + // shower shape shape flag: two bits, least significant bit is the standalone WP, second bit is the looseTk WP + // e.g. 0b01 : standalone shower shape flag passed, loose Tk shower shape flag did not pass + ap_uint<2> shapeFlags() const { return data().range(49, 48); } + + bool passes_ss() const { return (shapeFlags() & 0x1); } // standalone shower shape WP + bool passes_looseTkss() const { return (shapeFlags() & 0x2); } // loose Tk shower shape WP + + // brems: not saved in the current emulator + ap_uint<2> brems() const { return data().range(51, 50); } + + // Check that unused bits are zero + const int unusedBitsStart() const { return n_bits_unused_start; } + bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0); } + + // Get the underlying float cluster + const edm::Ref& clusterRef() const { return clusterRef_; } + // Get the underlying digitized cluster (before duplication and zero-padding) + const edm::Ref& digiClusterRef() const { return digiClusterRef_; } + }; + + // Collection typedefs + + // This represents the 36 GCTEmDigiClusters in one link (one link spans 4 RCT cards, each RCT card sends 9 clusters (zero-padded and sorted by decreasing pT)) + // The ordering of the 4 RCT cards in the link is, e.g. for GCT1.SLR3, real phi -50 to -20 degrees, then real phi -20 to 10 degrees, then real phi 10 to 40 degrees, and lastly real phi 40 to 70 degrees + typedef std::vector GCTEmDigiClusterLink; + + // This represents the 12 links sending GCTEmDigiClusters in the full barrel: there are 12 links = (3 GCT cards) * (two SLRs per GCT) * (one positive eta link and one negative eta link) + // The ordering of the links in this std::vector is (GCT1.SLR1 negEta, GCT.SLR1 posEta, GCT1.SLR3 negEta, GCT1.SLR3 posEta, then analogously for GCT2 and GCT3) + typedef std::vector GCTEmDigiClusterCollection; + +} // namespace l1tp2 + +#endif \ No newline at end of file diff --git a/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h new file mode 100644 index 0000000000000..771ef23647412 --- /dev/null +++ b/DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h @@ -0,0 +1,84 @@ +#ifndef DataFormats_L1TCalorimeterPhase2_GCTHadDigiCluster_h +#define DataFormats_L1TCalorimeterPhase2_GCTHadDigiCluster_h + +#include +#include + +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h" + +namespace l1tp2 { + + class GCTHadDigiCluster { + private: + // Data + unsigned long long int clusterData; + + // Constants + static constexpr float LSB_PT = 0.5; // 0.5 GeV + + // start of the unused bits + static constexpr int n_bits_unused_start = 31; + + // reference to corresponding float cluster + edm::Ref clusterRef_; + + public: + GCTHadDigiCluster() { clusterData = 0; } + + GCTHadDigiCluster(ap_uint<64> data) { clusterData = data; } + + // Note types of the constructor + GCTHadDigiCluster(ap_uint<12> pt, int etaCr, int phiCr, ap_uint<4> hoe) { + // To use .range() we need an ap class member + ap_uint<64> temp_data; + + ap_uint<7> etaCrDigitized = abs(etaCr); + ap_int<7> phiCrDigitized = phiCr; + + temp_data.range(11, 0) = pt.range(); + temp_data.range(18, 12) = etaCrDigitized.range(); + temp_data.range(25, 19) = phiCrDigitized.range(); + + clusterData = temp_data; + } + + // Setters + void setRef(const edm::Ref &clusterRef) { clusterRef_ = clusterRef; } + // Getters + ap_uint<64> data() const { return clusterData; } + + // Other getters + float ptLSB() const { return LSB_PT; } + ap_uint<12> pt() const { return data().range(11, 0); } + float ptFloat() const { return pt() * ptLSB(); } + + // crystal eta (unsigned 7 bits) + int eta() const { return (ap_uint<7>)data().range(18, 12); } + + // crystal phi (signed 7 bits) + int phi() const { return (ap_int<7>)data().range(25, 19); } + + // HoE value + ap_uint<4> hoe() const { return data().range(30, 26); } + + // Check that unused bits are zero + const int unusedBitsStart() const { return n_bits_unused_start; } + bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0); } + + // Get the underlying ref + edm::Ref clusterRef() const { return clusterRef_; } + }; + + // Collection typedefs + + // This represents the 36 GCTHadDigiClusters in one link (one link spans 4 RCT cards, each RCT card sends 9 clusters (zero-padded and sorted by decreasing pT) + // The ordering of the 4 RCT cards in this std::vector is, e.g. for GCT1.SLR3, real phi -50 to -20 degrees, then real phi -20 to 10 degrees, then real phi 10 to 40 degrees, and lastly real phi 40 to 70 degrees + typedef std::vector GCTHadDigiClusterLink; + + // This represents the 12 links sending GCTHadDigiClusters in the full barrel: there are 12 links = (3 GCT cards) * (two SLRs per GCT) * (one positive eta link and one negative eta link) + // The ordering of the links in this std::vector is (GCT1.SLR1 negEta, GCT.SLR1 posEta, GCT1.SLR3 negEta, GCT1.SLR3 posEta, then analogously for GCT2 and GCT3) + typedef std::vector GCTHadDigiClusterCollection; + +} // namespace l1tp2 + +#endif \ No newline at end of file diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes.h b/DataFormats/L1TCalorimeterPhase2/src/classes.h index 864965f0305f2..e979982097f68 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes.h +++ b/DataFormats/L1TCalorimeterPhase2/src/classes.h @@ -9,10 +9,12 @@ /*********************/ #include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/CaloJet.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h" #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h" #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterGT.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/Phase2L1CaloJet.h" diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml index 41fcdc88121ae..d812650d64efd 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml +++ b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml @@ -10,13 +10,7 @@ - - - - - - - + @@ -25,19 +19,35 @@ + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + @@ -46,12 +56,19 @@ - - + + + + - - - + + + + + + + + @@ -60,5 +77,6 @@ + diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h new file mode 100644 index 0000000000000..07bd4218df300 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h @@ -0,0 +1,86 @@ +#ifndef PHASE_2_L1_CALO_BARREL_TO_CORRELATOR +#define PHASE_2_L1_CALO_BARREL_TO_CORRELATOR + +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" + +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h" + +/* + * Comparators for sorting EG clusters + */ +inline bool p2eg::compareGCTEmDigiClusterET(const l1tp2::GCTEmDigiCluster& lhs, const l1tp2::GCTEmDigiCluster& rhs) { + return (lhs.ptFloat() > rhs.ptFloat()); +} + +/* + * Returns the difference in the azimuth coordinates of phi1 and phi2 (all in degrees not radians), taking the wrap-around at 180 degrees into account + */ +inline float p2eg::deltaPhiInDegrees(float phi1, float phi2, const float c = 180) { + float r = std::fmod(phi1 - phi2, 2.0 * c); + if (r < -c) { + r += 2.0 * c; + } else if (r > c) { + r -= 2.0 * c; + } + return r; +} + +/* + * For a given phi in degrees (e.g. computed from some difference), return the phi (in degrees) which takes the wrap-around at 180 degrees into account + */ +inline float p2eg::wrappedPhiInDegrees(float phi) { return p2eg::deltaPhiInDegrees(phi, 0); } + +/* + * Sort the clusters in each egamma SLR in descending pT, then pad any zero clusters so that the total number of clusters in the SLR is six + */ +inline void p2eg::sortAndPad_eg_SLR(l1tp2::GCTEmDigiClusterLink& thisSLR) { + // input is a vector and can be sorted + std::sort(thisSLR.begin(), thisSLR.end(), p2eg::compareGCTEmDigiClusterET); + int nClusters = thisSLR.size(); + + // If there are fewer than the designated number of clusters, pad with zeros + if (nClusters < p2eg::N_EG_CLUSTERS_PER_RCT_CARD) { + // do padding. if size == 2, push back four clusters + for (int i = 0; i < (p2eg::N_EG_CLUSTERS_PER_RCT_CARD - nClusters); i++) { + l1tp2::GCTEmDigiCluster zeroCluster; + thisSLR.push_back(zeroCluster); + } + } + // If there are more than the designated number of clusters, truncate the vector + else if (nClusters > p2eg::N_EG_CLUSTERS_PER_RCT_CARD) { + // Get the iterator to the sixth element and delete til the end of the vector + thisSLR.erase(thisSLR.begin() + p2eg::N_EG_CLUSTERS_PER_RCT_CARD, thisSLR.end()); + } +} + +/* + * Comparators for sorting PF clusters + */ +inline bool p2eg::compareGCTHadDigiClusterET(const l1tp2::GCTHadDigiCluster& lhs, const l1tp2::GCTHadDigiCluster& rhs) { + return (lhs.ptFloat() > rhs.ptFloat()); +} + +/* + * Sort the clusters in each PF SLR in descending pT, then pad any zero clusters so that the total number of clusters in the SLR is six + */ +inline void p2eg::sortAndPad_had_SLR(l1tp2::GCTHadDigiClusterLink& thisSLR) { + // input is a vector and can be sorted + std::sort(thisSLR.begin(), thisSLR.end(), p2eg::compareGCTHadDigiClusterET); + int nClusters = thisSLR.size(); + + // If there are fewer than the designated number of clusters, pad with zeros + if (nClusters < p2eg::N_PF_CLUSTERS_PER_RCT_CARD) { + for (int i = 0; i < (p2eg::N_PF_CLUSTERS_PER_RCT_CARD - nClusters); i++) { + l1tp2::GCTHadDigiCluster zeroCluster; + thisSLR.push_back(zeroCluster); + } + } + // If there are more than the designated number of clusters, truncate the vector + else if (nClusters > p2eg::N_EG_CLUSTERS_PER_RCT_CARD) { + // Get the iterator to the sixth element and delete til the end of the vector + thisSLR.erase(thisSLR.begin() + p2eg::N_EG_CLUSTERS_PER_RCT_CARD, thisSLR.end()); + } +} + +#endif \ No newline at end of file diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h index 2a81058517dc2..8186e4fddecdb 100644 --- a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -21,6 +21,8 @@ #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h" #include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterGT.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" #include "DataFormats/L1Trigger/interface/BXVector.h" #include "DataFormats/L1Trigger/interface/EGamma.h" @@ -94,6 +96,13 @@ namespace p2eg { static constexpr int N_GCTTOWERS_CLUSTER_ISO_ONESIDE = 5; // window size of isolation sum (5x5 in towers) + // Outputs to correlator + // Fixed number of EG and PF clusters per RCT card in each output SLR + static constexpr int N_EG_CLUSTERS_PER_RCT_CARD = 9; + static constexpr int N_PF_CLUSTERS_PER_RCT_CARD = 12; + // Height of one SLR region in phi in degrees + static constexpr float PHI_RANGE_PER_SLR_DEGREES = 120; + ////////////////////////////////////////////////////////////////////////// // RCT: indexing helper functions ////////////////////////////////////////////////////////////////////////// @@ -1661,6 +1670,16 @@ namespace p2eg { int corrFiberIndexOffset, int corrTowPhiOffset); + /*******************************************************************************************/ + /* Interface to correlator helper functions (defined in Phase2L1CaloBarrelToCorrelator.h) */ + /*******************************************************************************************/ + bool compareGCTEmDigiClusterET(const l1tp2::GCTEmDigiCluster& lhs, const l1tp2::GCTEmDigiCluster& rhs); + void sortAndPad_eg_SLR(l1tp2::GCTEmDigiClusterLink& thisSLR); + bool compareGCTHadDigiClusterET(const l1tp2::GCTHadDigiCluster& lhs, const l1tp2::GCTHadDigiCluster& rhs); + void sortAndPad_had_SLR(l1tp2::GCTHadDigiClusterLink& thisSLR); + float deltaPhiInDegrees(float phi1, float phi2, const float c); + float wrappedPhiInDegrees(float phi); + } // namespace p2eg #endif diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc new file mode 100644 index 0000000000000..dc3dcac10821c --- /dev/null +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1TCaloBarrelToCorrelator.cc @@ -0,0 +1,446 @@ +// -*- C++ -*- +// +// Package: L1Trigger/L1CaloTrigger +// Class: L1TCaloBarrelToCorrelator +// +/* + Description: Creates digitized EGamma and ParticleFlow clusters to be sent to correlator. + + Implementation: To be run together with Phase2L1CaloEGammaEmulator. +*/ + +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloPFCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" + +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTEmDigiCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/GCTHadDigiCluster.h" + +#include +#include +#include +#include +#include +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloBarrelToCorrelator.h" +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h" + +// +// class declaration +// + +class Phase2GCTBarrelToCorrelatorLayer1 : public edm::stream::EDProducer<> { +public: + explicit Phase2GCTBarrelToCorrelatorLayer1(const edm::ParameterSet&); + ~Phase2GCTBarrelToCorrelatorLayer1() override = default; + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + + // ----------member data --------------------------- + const edm::EDGetTokenT gctClusterSrc_; + const edm::EDGetTokenT digiInputClusterSrc_; + const edm::EDGetTokenT caloPFClustersSrc_; +}; + +// +// constructors and destructor +// +Phase2GCTBarrelToCorrelatorLayer1::Phase2GCTBarrelToCorrelatorLayer1(const edm::ParameterSet& iConfig) + : gctClusterSrc_( + consumes(iConfig.getParameter("gctClustersInput"))), + digiInputClusterSrc_(consumes( + iConfig.getParameter("gctDigiClustersInput"))), + caloPFClustersSrc_( + consumes(iConfig.getParameter("gctPFclusters"))) { + produces("GCTEmDigiClusters"); + produces("GCTHadDigiClusters"); +} + +void Phase2GCTBarrelToCorrelatorLayer1::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + + //***************************************************// + // Get the GCT digitized clusters and PF clusters + //***************************************************// + edm::Handle inputGCTClusters; + iEvent.getByToken(gctClusterSrc_, inputGCTClusters); + + edm::Handle inputGCTDigiClusters; + iEvent.getByToken(digiInputClusterSrc_, inputGCTDigiClusters); + + edm::Handle inputPFClusters; + iEvent.getByToken(caloPFClustersSrc_, inputPFClusters); + + //***************************************************// + // Initialize outputs + //***************************************************// + + // Em digi cluster output + auto outputEmClusters = std::make_unique(); + // Had digi cluster output + auto outputHadClusters = std::make_unique(); + + // EG Clusters output by GCT SLR (duplicates included) + l1tp2::GCTEmDigiClusterLink out_eg_GCT1_SLR1_posEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT1_SLR1_negEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT1_SLR3_posEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT1_SLR3_negEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT2_SLR1_posEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT2_SLR1_negEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT2_SLR3_posEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT2_SLR3_negEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT3_SLR1_posEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT3_SLR1_negEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT3_SLR3_posEta; + l1tp2::GCTEmDigiClusterLink out_eg_GCT3_SLR3_negEta; + + // Temporary arrays used to represent the four RCT cards in one SLR one side of eta (positive or eta) + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT1_SLR1_posEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT1_SLR1_negEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT1_SLR3_posEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT1_SLR3_negEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT2_SLR1_posEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT2_SLR1_negEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT2_SLR3_posEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT2_SLR3_negEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT3_SLR1_posEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT3_SLR1_negEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT3_SLR3_posEta[4]; + l1tp2::GCTEmDigiClusterLink buffer_eg_GCT3_SLR3_negEta[4]; + + // PF Clusters output by GCT SLR (duplicates included) + l1tp2::GCTHadDigiClusterLink out_had_GCT1_SLR1_posEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT1_SLR1_negEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT1_SLR3_posEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT1_SLR3_negEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT2_SLR1_posEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT2_SLR1_negEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT2_SLR3_posEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT2_SLR3_negEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT3_SLR1_posEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT3_SLR1_negEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT3_SLR3_posEta; + l1tp2::GCTHadDigiClusterLink out_had_GCT3_SLR3_negEta; + + // Temporary arrays used to represent the four RCT cards in one SLR one side of eta (positive or eta) + l1tp2::GCTHadDigiClusterLink buffer_had_GCT1_SLR1_posEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT1_SLR1_negEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT1_SLR3_posEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT1_SLR3_negEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT2_SLR1_posEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT2_SLR1_negEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT2_SLR3_posEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT2_SLR3_negEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT3_SLR1_posEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT3_SLR1_negEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT3_SLR3_posEta[4]; + l1tp2::GCTHadDigiClusterLink buffer_had_GCT3_SLR3_negEta[4]; + + //***************************************************// + // Loop over the regions: in order: GCT1 SLR1, GCT1 SLR3, GCT2 SLR1, GCT2 SLR3, GCT3 SLR1, GCT3SLR3 + //***************************************************// + + const int nRegions = 6; + float regionCentersInDegrees[nRegions] = {10.0, 70.0, 130.0, -170.0, -110.0, -50.0}; + + for (int iRegion = 0; iRegion < nRegions; iRegion++) { + // EM digi clusters + for (size_t iCluster = 0; iCluster < inputGCTDigiClusters->size(); ++iCluster) { + l1tp2::DigitizedClusterCorrelator clusterIn = inputGCTDigiClusters->at(iCluster); + + // Check if this cluster falls into each SLR region, i.e. if the cluster is within 120/2 = 60 degrees of the center of the SLR in phi + float clusterRealPhiAsDegree = clusterIn.realPhi() * 180 / M_PI; + float phiDifference = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[iRegion]); + if (std::abs(phiDifference) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 2)) { + // Go from real phi to an index in the SLR + // The crystal directly above the region center in phi, is iPhi 0. The crystal directly below the region center in phi, is iPhi -1. + int iPhiCrystalDifference = std::floor(phiDifference); + + // For eta, the eta is already digitized, just needs to be converted from [0, +2*17*5) to [-17*5, +17*5) + int temp_iEta_signed = clusterIn.eta() - (p2eg::CRYSTALS_IN_TOWER_ETA * p2eg::n_towers_per_link); + + // Default value: for clusters in positive eta, values go from 0, 1, 2, 3, 4 + int iEta = temp_iEta_signed; + // If cluster is in negative eta, instead of from -5, -4, -3, -2, -1, we want 4, 3, 2, 1, 0 + if (temp_iEta_signed < 0) { + // If in negative eta, convert to an absolute value, with 0 being the crystal nearest real eta = 0 + iEta = std::abs(temp_iEta_signed + 1); + } + + // Initialize the new cluster and set the edm::Ref pointing to the underlying float + l1tp2::GCTEmDigiCluster clusterOut = l1tp2::GCTEmDigiCluster(clusterIn.pt(), + iEta, + iPhiCrystalDifference, + clusterIn.hoe(), + clusterIn.hoeFlag(), + clusterIn.iso(), + clusterIn.isoFlags(), + clusterIn.fb(), + clusterIn.timing(), + clusterIn.shapeFlags(), + clusterIn.brems()); + // there is a 1-to-1 mapping between the original float clusters and the first step of digitization, so we can build a ref to the same cluster + edm::Ref thisRef(inputGCTClusters, iCluster); + clusterOut.setRef(thisRef); + edm::Ref thisDigiRef(inputGCTDigiClusters, iCluster); + clusterOut.setDigiRef(thisDigiRef); + + // Check which RCT card this falls into, ordered 0, 1, 2, 3 counting from the most negative phi (real phi or iPhi) to the most positive + // so RCT card 0 is -60 to -30 degrees in phi from the center, RCT card 1 is -30 to 0 degrees in phi from the center, RCT card 2 is 0 to +30 degrees in phi from the center, RCT card 3 is +30 to +60 degrees in phi from the center + int whichRCTcard = 0; + if (phiDifference < -30) { + whichRCTcard = 0; + } else if (phiDifference < 0) { + whichRCTcard = 1; + } else if (phiDifference < 30) { + whichRCTcard = 2; + } else { + whichRCTcard = 3; + } + + if (iRegion == 0) { + if (temp_iEta_signed < 0) { + buffer_eg_GCT1_SLR1_negEta[whichRCTcard].push_back(clusterOut); + } else { + buffer_eg_GCT1_SLR1_posEta[whichRCTcard].push_back(clusterOut); + } + } else if (iRegion == 1) { + if (temp_iEta_signed < 0) { + buffer_eg_GCT1_SLR3_negEta[whichRCTcard].push_back(clusterOut); + } else { + buffer_eg_GCT1_SLR3_posEta[whichRCTcard].push_back(clusterOut); + } + } else if (iRegion == 2) { + if (temp_iEta_signed < 0) { + buffer_eg_GCT2_SLR1_negEta[whichRCTcard].push_back(clusterOut); + } else { + buffer_eg_GCT2_SLR1_posEta[whichRCTcard].push_back(clusterOut); + } + } else if (iRegion == 3) { + if (temp_iEta_signed < 0) { + buffer_eg_GCT2_SLR3_negEta[whichRCTcard].push_back(clusterOut); + } else { + buffer_eg_GCT2_SLR3_posEta[whichRCTcard].push_back(clusterOut); + } + } else if (iRegion == 4) { + if (temp_iEta_signed < 0) { + buffer_eg_GCT3_SLR1_negEta[whichRCTcard].push_back(clusterOut); + } else { + buffer_eg_GCT3_SLR1_posEta[whichRCTcard].push_back(clusterOut); + } + } else if (iRegion == 5) { + if (temp_iEta_signed < 0) { + buffer_eg_GCT3_SLR3_negEta[whichRCTcard].push_back(clusterOut); + } else { + buffer_eg_GCT3_SLR3_posEta[whichRCTcard].push_back(clusterOut); + } + } + } + } + + // Repeat for PF Clusters + for (size_t iCluster = 0; iCluster < inputPFClusters->size(); ++iCluster) { + l1tp2::CaloPFCluster pfIn = inputPFClusters->at(iCluster); + + // Skip zero-energy clusters + if (pfIn.clusterEt() == 0) + continue; + + // Check if this cluster falls into each GCT card + float clusterRealPhiAsDegree = pfIn.clusterPhi() * 180 / M_PI; + float differenceInPhi = p2eg::deltaPhiInDegrees(clusterRealPhiAsDegree, regionCentersInDegrees[iRegion]); + if (std::abs(differenceInPhi) < (p2eg::PHI_RANGE_PER_SLR_DEGREES / 2)) { + // Go from real phi to an index in the SLR + // Calculate the distance in phi from the center of the region + float phiDifference = clusterRealPhiAsDegree - regionCentersInDegrees[iRegion]; + int iPhiCrystalDifference = std::floor(phiDifference); + + // For PFClusters, the method clusterEta returns a float, so we need to digitize this + float eta_LSB = p2eg::ECAL_eta_range / (p2eg::N_GCTTOWERS_FIBER * p2eg::CRYSTALS_IN_TOWER_ETA); + int temp_iEta_signed = std::floor(pfIn.clusterEta() / eta_LSB); + // Default value (for positive eta) + int iEta = temp_iEta_signed; + // If cluster is in negative eta, instead of from -5, -4, -3, -2, -1 we want 4, 3, 2, 1, 0 + if (temp_iEta_signed < 0) { + // If in negative eta, convert to an absolute value, with 0 being the crystal nearest real eta = 0 + iEta = std::abs(temp_iEta_signed + 1); + } + + // Initialize the new cluster + l1tp2::GCTHadDigiCluster pfOut = + l1tp2::GCTHadDigiCluster(pfIn.clusterEt() / p2eg::ECAL_LSB, // convert to integer + iEta, + iPhiCrystalDifference, + 0 // no HoE value in PF Cluster + ); + pfOut.setRef(edm::Ref(inputPFClusters, iCluster)); + + // Check which RCT card this falls into, ordered 0, 1, 2, 3 counting from the most negative phi (real phi or iPhi) to the most positive + // so RCT card 0 is -60 to -30 degrees in phi from the center, RCT card 1 is -30 to 0 degrees in phi from the center, RCT card 2 is 0 to +30 degrees in phi from the center, RCT card 3 is +30 to +60 degrees in phi from the center + int whichRCTcard = 0; + if (phiDifference < -30) { + whichRCTcard = 0; + } else if (phiDifference < 0) { + whichRCTcard = 1; + } else if (phiDifference < 30) { + whichRCTcard = 2; + } else { + whichRCTcard = 3; + } + + if (iRegion == 0) { + if (temp_iEta_signed < 0) { + buffer_had_GCT1_SLR1_negEta[whichRCTcard].push_back(pfOut); + } else { + buffer_had_GCT1_SLR1_posEta[whichRCTcard].push_back(pfOut); + } + } else if (iRegion == 1) { + if (temp_iEta_signed < 0) { + buffer_had_GCT1_SLR3_negEta[whichRCTcard].push_back(pfOut); + } else { + buffer_had_GCT1_SLR3_posEta[whichRCTcard].push_back(pfOut); + } + } else if (iRegion == 2) { + if (temp_iEta_signed < 0) { + buffer_had_GCT2_SLR1_negEta[whichRCTcard].push_back(pfOut); + } else { + buffer_had_GCT2_SLR1_posEta[whichRCTcard].push_back(pfOut); + } + } else if (iRegion == 3) { + if (temp_iEta_signed < 0) { + buffer_had_GCT2_SLR3_negEta[whichRCTcard].push_back(pfOut); + } else { + buffer_had_GCT2_SLR3_posEta[whichRCTcard].push_back(pfOut); + } + } else if (iRegion == 4) { + if (temp_iEta_signed < 0) { + buffer_had_GCT3_SLR1_negEta[whichRCTcard].push_back(pfOut); + } else { + buffer_had_GCT3_SLR1_posEta[whichRCTcard].push_back(pfOut); + } + } else if (iRegion == 5) { + if (temp_iEta_signed < 0) { + buffer_had_GCT3_SLR3_negEta[whichRCTcard].push_back(pfOut); + } else { + buffer_had_GCT3_SLR3_posEta[whichRCTcard].push_back(pfOut); + } + } + } + } + } + + // Within each RCT card, sort the egamma clusters in descending pT order and add zero-padding + for (int iRCT = 0; iRCT < 4; iRCT++) { + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT1_SLR1_negEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT1_SLR3_negEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT2_SLR1_negEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT2_SLR3_negEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT3_SLR1_negEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT3_SLR3_negEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT1_SLR1_posEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT1_SLR3_posEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT2_SLR1_posEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT2_SLR3_posEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT3_SLR1_posEta[iRCT]); + p2eg::sortAndPad_eg_SLR(buffer_eg_GCT3_SLR3_posEta[iRCT]); + } + + // Then build the container for each egamma SLR, by pushing back, in order, the four RCT cards (starting from most negative phi to most positive phi) + for (int iRCT = 0; iRCT < 4; iRCT++) { + for (int iCluster = 0; iCluster < p2eg::N_EG_CLUSTERS_PER_RCT_CARD; iCluster++) { + // outer loop is over RCT cards, inner loop is over the clusters in each RCT card + out_eg_GCT1_SLR1_posEta.push_back(buffer_eg_GCT1_SLR1_posEta[iRCT][iCluster]); + out_eg_GCT1_SLR1_negEta.push_back(buffer_eg_GCT1_SLR1_negEta[iRCT][iCluster]); + out_eg_GCT1_SLR3_posEta.push_back(buffer_eg_GCT1_SLR3_posEta[iRCT][iCluster]); + out_eg_GCT1_SLR3_negEta.push_back(buffer_eg_GCT1_SLR3_negEta[iRCT][iCluster]); + out_eg_GCT2_SLR1_posEta.push_back(buffer_eg_GCT2_SLR1_posEta[iRCT][iCluster]); + out_eg_GCT2_SLR1_negEta.push_back(buffer_eg_GCT2_SLR1_negEta[iRCT][iCluster]); + out_eg_GCT2_SLR3_posEta.push_back(buffer_eg_GCT2_SLR3_posEta[iRCT][iCluster]); + out_eg_GCT2_SLR3_negEta.push_back(buffer_eg_GCT2_SLR3_negEta[iRCT][iCluster]); + out_eg_GCT3_SLR1_posEta.push_back(buffer_eg_GCT3_SLR1_posEta[iRCT][iCluster]); + out_eg_GCT3_SLR1_negEta.push_back(buffer_eg_GCT3_SLR1_negEta[iRCT][iCluster]); + out_eg_GCT3_SLR3_posEta.push_back(buffer_eg_GCT3_SLR3_posEta[iRCT][iCluster]); + out_eg_GCT3_SLR3_negEta.push_back(buffer_eg_GCT3_SLR3_negEta[iRCT][iCluster]); + } + } + + // Repeat for PF: Within each RCT card, sort the PF clusters in descending pT order and add zero-padding + for (int iRCT = 0; iRCT < 4; iRCT++) { + p2eg::sortAndPad_had_SLR(buffer_had_GCT1_SLR1_negEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT1_SLR3_negEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT2_SLR1_negEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT2_SLR3_negEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT3_SLR1_negEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT3_SLR3_negEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT1_SLR1_posEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT1_SLR3_posEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT2_SLR1_posEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT2_SLR3_posEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT3_SLR1_posEta[iRCT]); + p2eg::sortAndPad_had_SLR(buffer_had_GCT3_SLR3_posEta[iRCT]); + } + + // Then build the container for each PF SLR, by pushing back, in order, the four RCT cards (starting from most negative phi to most positive phi) + for (int iRCT = 0; iRCT < 4; iRCT++) { + for (int iCluster = 0; iCluster < p2eg::N_PF_CLUSTERS_PER_RCT_CARD; iCluster++) { + // outer loop is over RCT cards, inner loop is over clusters + out_had_GCT1_SLR1_posEta.push_back(buffer_had_GCT1_SLR1_posEta[iRCT][iCluster]); + out_had_GCT1_SLR1_negEta.push_back(buffer_had_GCT1_SLR1_negEta[iRCT][iCluster]); + out_had_GCT1_SLR3_posEta.push_back(buffer_had_GCT1_SLR3_posEta[iRCT][iCluster]); + out_had_GCT1_SLR3_negEta.push_back(buffer_had_GCT1_SLR3_negEta[iRCT][iCluster]); + out_had_GCT2_SLR1_posEta.push_back(buffer_had_GCT2_SLR1_posEta[iRCT][iCluster]); + out_had_GCT2_SLR1_negEta.push_back(buffer_had_GCT2_SLR1_negEta[iRCT][iCluster]); + out_had_GCT2_SLR3_posEta.push_back(buffer_had_GCT2_SLR3_posEta[iRCT][iCluster]); + out_had_GCT2_SLR3_negEta.push_back(buffer_had_GCT2_SLR3_negEta[iRCT][iCluster]); + out_had_GCT3_SLR1_posEta.push_back(buffer_had_GCT3_SLR1_posEta[iRCT][iCluster]); + out_had_GCT3_SLR1_negEta.push_back(buffer_had_GCT3_SLR1_negEta[iRCT][iCluster]); + out_had_GCT3_SLR3_posEta.push_back(buffer_had_GCT3_SLR3_posEta[iRCT][iCluster]); + out_had_GCT3_SLR3_negEta.push_back(buffer_had_GCT3_SLR3_negEta[iRCT][iCluster]); + } + } + + // Finally, push back the SLR containers + outputEmClusters->push_back(out_eg_GCT1_SLR1_posEta); + outputEmClusters->push_back(out_eg_GCT1_SLR1_negEta); + outputEmClusters->push_back(out_eg_GCT1_SLR3_posEta); + outputEmClusters->push_back(out_eg_GCT1_SLR3_negEta); + outputEmClusters->push_back(out_eg_GCT2_SLR1_posEta); + outputEmClusters->push_back(out_eg_GCT2_SLR1_negEta); + outputEmClusters->push_back(out_eg_GCT2_SLR3_posEta); + outputEmClusters->push_back(out_eg_GCT2_SLR3_negEta); + outputEmClusters->push_back(out_eg_GCT3_SLR1_posEta); + outputEmClusters->push_back(out_eg_GCT3_SLR1_negEta); + outputEmClusters->push_back(out_eg_GCT3_SLR3_posEta); + outputEmClusters->push_back(out_eg_GCT3_SLR3_negEta); + + outputHadClusters->push_back(out_had_GCT1_SLR1_posEta); + outputHadClusters->push_back(out_had_GCT1_SLR1_negEta); + outputHadClusters->push_back(out_had_GCT1_SLR3_posEta); + outputHadClusters->push_back(out_had_GCT1_SLR3_negEta); + outputHadClusters->push_back(out_had_GCT2_SLR1_posEta); + outputHadClusters->push_back(out_had_GCT2_SLR1_negEta); + outputHadClusters->push_back(out_had_GCT2_SLR3_posEta); + outputHadClusters->push_back(out_had_GCT2_SLR3_negEta); + outputHadClusters->push_back(out_had_GCT3_SLR1_posEta); + outputHadClusters->push_back(out_had_GCT3_SLR1_negEta); + outputHadClusters->push_back(out_had_GCT3_SLR3_posEta); + outputHadClusters->push_back(out_had_GCT3_SLR3_negEta); + + iEvent.put(std::move(outputEmClusters), "GCTEmDigiClusters"); + iEvent.put(std::move(outputHadClusters), "GCTHadDigiClusters"); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(Phase2GCTBarrelToCorrelatorLayer1); diff --git a/L1Trigger/L1CaloTrigger/python/l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi.py b/L1Trigger/L1CaloTrigger/python/l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi.py new file mode 100644 index 0000000000000..54493b6a486a5 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/l1tPhase2GCTBarrelToCorrelatorLayer1Emulator_cfi.py @@ -0,0 +1,7 @@ +import FWCore.ParameterSet.Config as cms + +l1tPhase2GCTBarrelToCorrelatorLayer1Emulator = cms.EDProducer("Phase2GCTBarrelToCorrelatorLayer1", + gctClustersInput = cms.InputTag("l1tPhase2L1CaloEGammaEmulator", "GCTClusters", "REPR"), + gctDigiClustersInput = cms.InputTag("l1tPhase2L1CaloEGammaEmulator", "GCTDigitizedClusterToCorrelator"), + gctPFclusters = cms.InputTag("l1tPhase2CaloPFClusterEmulator", "GCTPFCluster") +)