diff --git a/DQMOffline/L1Trigger/python/L1TPhase2Offline_cfi.py b/DQMOffline/L1Trigger/python/L1TPhase2Offline_cfi.py index 01ede6aaa5785..f5adb89fb4bcf 100644 --- a/DQMOffline/L1Trigger/python/L1TPhase2Offline_cfi.py +++ b/DQMOffline/L1Trigger/python/L1TPhase2Offline_cfi.py @@ -6,7 +6,7 @@ OuterTrackerTkMET = DQMEDAnalyzer('L1TPhase2OuterTrackerTkMET', TopFolderName = cms.string('L1T/L1TPhase2/'), TTTracksTag = cms.InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks"), - L1VertexInputTag = cms.InputTag("l1tVertexFinderEmulator", "l1verticesEmulation"), + L1VertexInputTag = cms.InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation"), maxZ0 = cms.double ( 15. ) , # in cm maxEta = cms.double ( 2.4 ) , chi2dofMax = cms.double( 10. ), diff --git a/DataFormats/L1TCalorimeterPhase2/BuildFile.xml b/DataFormats/L1TCalorimeterPhase2/BuildFile.xml index 732b899908e54..3bbe2c4a51ebb 100644 --- a/DataFormats/L1TCalorimeterPhase2/BuildFile.xml +++ b/DataFormats/L1TCalorimeterPhase2/BuildFile.xml @@ -3,6 +3,7 @@ + diff --git a/DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h b/DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h index 4326f2b686327..de9d7996ffd51 100644 --- a/DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h +++ b/DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h @@ -1,6 +1,7 @@ #ifndef DataFormats_L1TCalorimeterPhase2_CaloCrystalsCluster_h #define DataFormats_L1TCalorimeterPhase2_CaloCrystalsCluster_h +#include #include #include #include diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h new file mode 100644 index 0000000000000..2be7d1eaf7cb6 --- /dev/null +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h @@ -0,0 +1,152 @@ +#ifndef DataFormats_L1TCalorimeterPhase2_DigitizedClusterCorrelator_h +#define DataFormats_L1TCalorimeterPhase2_DigitizedClusterCorrelator_h + +#include +#include + +namespace l1tp2 { + + class DigitizedClusterCorrelator { + private: + // Data + ap_uint<64> clusterData; + unsigned int idxGCTCard; // 0, 1, or 2 + + // Constants + static constexpr unsigned int n_towers_eta = 34; // in GCT card unique region + static constexpr unsigned int n_towers_phi = 24; // in GCT card unique region + static constexpr unsigned int n_crystals_in_tower = 5; + static constexpr float LSB_PT = 0.5; // 0.5 GeV + static constexpr unsigned int n_bits_pt = 12; // 12 bits allocated for pt + static constexpr unsigned int n_bits_unused_start = 49; // unused bits start at bit 49 + + // Private member functions to perform digitization + ap_uint<12> digitizePt(float pt_f) { + float maxPt_f = (std::pow(2, n_bits_pt) - 1) * LSB_PT; + // If pT exceeds the maximum (extremely unlikely), saturate the value + if (pt_f >= maxPt_f) { + return (ap_uint<12>)0xFFF; + } + + return (ap_uint<12>)(pt_f / LSB_PT); + } + + // + ap_uint<6> digitizeIEta(unsigned int iEta) { + assert(iEta < n_towers_eta); + return (ap_uint<6>)iEta; + } + + // This is tower iPhi in the unique region of the GCT card, so this only goes from 0-23 + ap_uint<5> digitizeIPhi(unsigned int iPhi) { + assert(iPhi < n_towers_phi); + return (ap_uint<5>)iPhi; + } + + ap_uint<3> digitizeIEtaCr(unsigned int iEtaCr) { + assert(iEtaCr < n_crystals_in_tower); + return (ap_uint<3>)iEtaCr; + } + + ap_uint<3> digitizeIPhiCr(unsigned int iPhiCr) { + assert(iPhiCr < n_crystals_in_tower); + return (ap_uint<3>)iPhiCr; + } + + // To-do: HoE is not defined for clusters + ap_uint<4> digitizeHoE(unsigned int hoe) { return (ap_uint<4>)hoe; } + + // + ap_uint<3> digitizeIso(bool iso) { return (ap_uint<3>)iso; } + + // To-do: fb: no information yet + ap_uint<6> digitizeFb(unsigned int fb) { return (ap_uint<6>)fb; } + + // To-do: timing: no information yet + ap_uint<5> digitizeTiming(unsigned int timing) { return (ap_uint<5>)timing; } + + // Shape: shower shape working point + ap_uint<1> digitizeShape(bool is_ss) { return (ap_uint<1>)is_ss; } + + // TO-DO: Brems: was brems applied (NOT STORED YET IN GCT) + ap_uint<1> digitizeBrems(bool brems_applied) { return (ap_uint<1>)brems_applied; } + + public: + DigitizedClusterCorrelator() { clusterData = 0x0; } + + DigitizedClusterCorrelator(ap_uint<64> data) { clusterData = data; } + + // Constructor from digitized inputs + DigitizedClusterCorrelator(ap_uint<12> pt, + ap_uint<6> eta, + ap_uint<5> phi, + ap_uint<3> etaCr, + ap_uint<3> phiCr, + ap_uint<4> hoe, + ap_uint<3> iso, + ap_uint<6> fb, + ap_uint<5> timing, + ap_uint<1> shape, + ap_uint<1> brems, + int iGCTCard, + bool fullydigitizedInputs) { + (void)fullydigitizedInputs; + + clusterData = ((ap_uint<64>)pt) | (((ap_uint<64>)eta) << 12) | (((ap_uint<64>)phi) << 18) | + (((ap_uint<64>)etaCr) << 23) | (((ap_uint<64>)phiCr) << 26) | (((ap_uint<64>)hoe) << 29) | + (((ap_uint<64>)iso << 33)) | (((ap_uint<64>)fb << 36)) | (((ap_uint<64>)timing << 42)) | + (((ap_uint<64>)shape << 47)) | (((ap_uint<64>)brems << 48)); + idxGCTCard = iGCTCard; + } + + // Constructor from float inputs + DigitizedClusterCorrelator(float pt_f, + unsigned int iEta, + unsigned int iPhi, + unsigned int iEtaCr, + unsigned int iPhiCr, + unsigned int hoe, + bool iso, + unsigned int fb, + unsigned int timing, + bool shape, + unsigned int brems, + int iGCTCard) { + clusterData = (((ap_uint<64>)digitizePt(pt_f)) | ((ap_uint<64>)digitizeIEta(iEta) << 12) | + ((ap_uint<64>)digitizeIPhi(iPhi) << 18) | ((ap_uint<64>)digitizeIEtaCr(iEtaCr) << 23) | + ((ap_uint<64>)digitizeIPhiCr(iPhiCr) << 26) | ((ap_uint<64>)digitizeHoE(hoe) << 29) | + ((ap_uint<64>)digitizeIso(iso) << 33) | ((ap_uint<64>)digitizeFb(fb) << 36) | + ((ap_uint<64>)digitizeTiming(timing) << 42) | ((ap_uint<64>)digitizeShape(shape) << 47) | + ((ap_uint<64>)digitizeBrems(brems) << 48)); + idxGCTCard = iGCTCard; + } + + ap_uint<64> data() const { return clusterData; } + + // Other getters + float ptLSB() const { return LSB_PT; } + ap_uint<12> pt() const { return (clusterData & 0xFFF); } + ap_uint<6> eta() const { return ((clusterData >> 12) & 0x3F); } // (six 1's) 0b111111 = 0x3F + ap_uint<5> phi() const { return ((clusterData >> 18) & 0x1F); } // (five 1's) 0b11111 = 0x1F + ap_uint<3> etaCr() const { return ((clusterData >> 23) & 0x7); } // (three 1's) 0b111 = 0x7 + ap_uint<3> phiCr() const { return ((clusterData >> 26) & 0x7); } + ap_uint<4> hoe() const { return ((clusterData >> 29) & 0xF); } // (four 1's) 0b1111 = 0xF + ap_uint<3> iso() const { return ((clusterData >> 33) & 0x7); } + ap_uint<6> fb() const { return ((clusterData >> 36) & 0x3F); } + ap_uint<5> timing() const { return ((clusterData >> 42) & 0x1F); } + ap_uint<1> shape() const { return ((clusterData >> 47) & 0x1); } + ap_uint<1> brems() const { return ((clusterData >> 48) & 0x1); } + unsigned int cardNumber() const { return idxGCTCard; } // which GCT card (0, 1, or 2) + + const int unusedBitsStart() const { return 49; } // unused bits start at bit 49 + + // Other checks + bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0x0); } + }; + + // Collection typedef + typedef std::vector DigitizedClusterCorrelatorCollection; + +} // namespace l1tp2 + +#endif \ No newline at end of file diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterGT.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterGT.h new file mode 100644 index 0000000000000..d44537819915f --- /dev/null +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterGT.h @@ -0,0 +1,104 @@ +#ifndef DataFormats_L1TCalorimeterPhase2_DigitizedClusterGT_h +#define DataFormats_L1TCalorimeterPhase2_DigitizedClusterGT_h + +#include +#include + +namespace l1tp2 { + + class DigitizedClusterGT { + private: + // Data + ap_uint<64> clusterData; + + // Constants + static constexpr float LSB_PT = 0.03125; // 0.03125 GeV + static constexpr unsigned int n_bits_eta_pi = 12; // 12 bits corresponds to pi in eta + static constexpr unsigned int n_bits_phi_pi = 12; // 12 bits corresponds to pi in phi + static constexpr unsigned int n_bits_pt = 16; // 12 bits allocated for pt + static constexpr unsigned int n_bits_unused_start = 44; // unused bits start at bit number 44 + + float LSB_ETA = (M_PI / std::pow(2, n_bits_eta_pi)); + float LSB_PHI = (M_PI / std::pow(2, n_bits_phi_pi)); + + // Private member functions to perform digitization + ap_uint<1> digitizeIsValid(bool isValid) { return (ap_uint<1>)isValid; } + + ap_uint<16> digitizePt(float pt_f) { + float maxPt_f = (std::pow(2, n_bits_pt) - 1) * LSB_PT; + // If pT exceeds the maximum, saturate the value + if (pt_f >= maxPt_f) { + return (ap_uint<16>)0xFFFF; + } + return (ap_uint<16>)(pt_f / LSB_PT); + } + + // Use two's complements representation + ap_int<13> digitizePhi(float phi_f) { + ap_int<13> phi_digitized = (phi_f / LSB_PHI); + return phi_digitized; + } + + // Use two's complements representation + ap_int<14> digitizeEta(float eta_f) { + ap_int<14> eta_digitized = (eta_f / LSB_ETA); + return eta_digitized; + } + + public: + DigitizedClusterGT() { clusterData = 0x0; } + + DigitizedClusterGT(ap_uint<64> data) { clusterData = data; } + + // Constructor from digitized inputs + DigitizedClusterGT(ap_uint<1> isValid, ap_uint<16> pt, ap_int<13> phi, ap_int<14> eta, bool fullyDigitizedInputs) { + (void)fullyDigitizedInputs; + clusterData = + ((ap_uint<64>)isValid) | (((ap_uint<64>)pt) << 1) | (((ap_uint<64>)phi) << 17) | (((ap_uint<64>)eta) << 30); + } + + // Constructor from float inputs that will perform digitization + DigitizedClusterGT(bool isValid, float pt_f, float phi_f, float eta_f) { + // N.b.: For eta/phi, after shifting the bits to the correct place and casting to ap_uint<64>, + // we have an additional bit mask + // e.g. 0x3FFE0000 for phi. This mask is all zero's except for 1 in the phi bits (bits 17 through 29): + // bit mask = 0x3FFE0000 = 0b111111111111100000000000000000 + // Applying the "and" of this bitmask, avoids bogus 1's in the case where phi is negative + + clusterData = ((ap_uint<64>)digitizeIsValid(isValid)) | ((ap_uint<64>)digitizePt(pt_f) << 1) | + (((ap_uint<64>)digitizePhi(phi_f) << 17) & + 0x3FFE0000) | // 0x3FFE0000 is all zero's except the phi bits (bits 17 through 29) + (((ap_uint<64>)digitizeEta(eta_f) << 30) & + 0xFFFC0000000); // 0xFFFC0000000 is all zero's except the eta bits (bits 30 through 32) + } + + ap_uint<64> data() const { return clusterData; } + + // Other getters + float ptLSB() const { return LSB_PT; } + float phiLSB() const { return LSB_PHI; } + float etaLSB() const { return LSB_ETA; } + ap_uint<1> isValid() const { return (clusterData & 0x1); } + ap_uint<16> pt() const { return ((clusterData >> 1) & 0xFFFF); } // 16 1's = 0xFFFF + ap_int<13> phi() const { return ((clusterData >> 17) & 0x1FFF); } // (thirteen 1's)= 0x1FFF + ap_int<14> eta() const { return ((clusterData >> 30) & 0x3FFF); } // (fourteen 1's) = 0x3FFF + + float ptFloat() const { return (pt() * ptLSB()); } + float realPhi() const { // convert from signed int to float + return (phi() * phiLSB()); + } + float realEta() const { // convert from signed int to float + return (eta() * etaLSB()); + } + const int unusedBitsStart() const { return n_bits_unused_start; } // unused bits start at bit 44 + + // Other checks + bool passNullBitsCheck(void) const { return ((data() >> unusedBitsStart()) == 0x0); } + }; + + // Collection typedef + typedef std::vector DigitizedClusterGTCollection; + +} // namespace l1tp2 + +#endif \ No newline at end of file diff --git a/DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h new file mode 100644 index 0000000000000..cd7e0f6676233 --- /dev/null +++ b/DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h @@ -0,0 +1,97 @@ +#ifndef DataFormats_L1TCalorimeterPhase2_DigitizedTowerCorrelator_h +#define DataFormats_L1TCalorimeterPhase2_DigitizedTowerCorrelator_h + +#include +#include + +namespace l1tp2 { + + class DigitizedTowerCorrelator { + private: + // Data + ap_uint<16> towerData; + unsigned int idxCard; // 0, 1, or 2 (there are three GCT cards) + unsigned int idxFiber; // 0 to 47 (there are 48 fibers in one GCT card) + unsigned int idxTower; // 0 to 16 (there are 17 towers in one fiber) + + // Constants + static constexpr float LSB_ET = 0.5; // 0.5 GeV, so max value is (2^10 - 1) * 0.5 = 511.5 GeV + static constexpr unsigned int n_bits_pt = 10; + static constexpr unsigned int n_towers_in_fiber = 17; + static constexpr unsigned int n_fibers_in_card = 48; + static constexpr unsigned int n_cards = 3; + + // Private member functions to perform digitization + ap_uint<10> digitizeEt(float et_f) { + float maxEt_f = (std::pow(2, n_bits_pt) - 1) * LSB_ET; + // If pT exceeds the maximum, saturate the value + if (et_f >= maxEt_f) { + return (ap_uint<10>)0x3FF; + } + return (ap_uint<10>)(et_f / LSB_ET); + } + + ap_uint<4> digitizeHoE(ap_uint<4> hoe) { return (ap_uint<4>)hoe; } + + // To-do: FB not implemented yet + ap_uint<2> digitizeFB(ap_uint<2> fb) { return (ap_uint<2>)fb; } + + public: + DigitizedTowerCorrelator() { towerData = 0x0; } + + DigitizedTowerCorrelator(ap_uint<16> data) { towerData = data; } + + // Constructor from digitized inputs + DigitizedTowerCorrelator(ap_uint<10> et, + ap_uint<4> hoe, + ap_uint<2> fb, + unsigned int indexCard, + unsigned int indexFiber, + unsigned int indexTower, + bool fullyDigitizedInputs) { + (void)fullyDigitizedInputs; + towerData = ((ap_uint<16>)et) | (((ap_uint<16>)hoe) << 10) | (((ap_uint<16>)fb) << 14); + idxCard = indexCard; + idxFiber = indexFiber; + idxTower = indexTower; + assert(hasValidIndices()); + } + + // Constructor from float inputs + DigitizedTowerCorrelator(float et_f, + ap_uint<4> hoe, + ap_uint<2> fb, + unsigned int indexCard, + unsigned int indexFiber, + unsigned int indexTower) { + towerData = ((ap_uint<16>)digitizeEt(et_f)) | (((ap_uint<16>)hoe) << 10) | (((ap_uint<16>)fb) << 14); + idxCard = indexCard; + idxFiber = indexFiber; + idxTower = indexTower; + assert(hasValidIndices()); + } + + ap_uint<16> data() const { return towerData; } + + // Other getters + float etLSB() const { return LSB_ET; } + ap_uint<10> et() const { return (towerData & 0x3FF); } // ten 1's = 0x3FF + ap_uint<4> hoe() const { return ((towerData >> 10) & 0xF); } // four 1's= 0xF + ap_uint<2> fb() const { return ((towerData >> 14) & 0x3); } // two 1's = 0x3 + float etFloat() const { return et() * etLSB(); } + unsigned int cardNumber() const { return idxCard; } // GCT card number + unsigned int fiberNumber() const { return idxFiber; } // fiber number in card (hardware convention) + unsigned int towerNumber() const { return idxTower; } // tower number in fiber (hardware convention) + + // Other checks + bool hasValidIndices(void) const { + return (idxTower < n_towers_in_fiber) && (idxFiber < n_fibers_in_card) && (idxCard < n_cards); + } + }; + + // Collection typedef + typedef std::vector DigitizedTowerCorrelatorCollection; + +} // namespace l1tp2 + +#endif \ No newline at end of file diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes.h b/DataFormats/L1TCalorimeterPhase2/src/classes.h index 3c0d9bb3cb3c5..afe0cd9d264f3 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes.h +++ b/DataFormats/L1TCalorimeterPhase2/src/classes.h @@ -11,3 +11,6 @@ #include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" #include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h" #include "DataFormats/L1TCalorimeterPhase2/interface/CaloJet.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterCorrelator.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedTowerCorrelator.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/DigitizedClusterGT.h" diff --git a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml index 0c81ef7cc560d..8b3c871176a9e 100644 --- a/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml +++ b/DataFormats/L1TCalorimeterPhase2/src/classes_def.xml @@ -25,5 +25,22 @@ + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/Configuration/python/SimL1Emulator_cff.py b/L1Trigger/Configuration/python/SimL1Emulator_cff.py index 5dc7ba09569f6..3658d54d3fee9 100644 --- a/L1Trigger/Configuration/python/SimL1Emulator_cff.py +++ b/L1Trigger/Configuration/python/SimL1Emulator_cff.py @@ -88,10 +88,12 @@ # Barrel and EndCap EGamma # ######################################################################## - from L1Trigger.L1CaloTrigger.l1tEGammaCrystalsEmulatorProducer_cfi import * _phase2_siml1emulator.add(l1tEGammaClusterEmuProducer) +from L1Trigger.L1CaloTrigger.l1tPhase2L1CaloEGammaEmulator_cfi import * +_phase2_siml1emulator.add(l1tPhase2L1CaloEGammaEmulator) + # Barrel and EndCap CaloJet/HT # ######################################################################## # ---- Produce the calibrated tower collection combining Barrel, HGCal, HF @@ -120,16 +122,19 @@ # ######################################################################## # Phase-2 L1T - TrackTrigger dependent modules # ######################################################################## + from L1Trigger.L1TTrackMatch.l1tGTTInputProducer_cfi import * +from L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi import * +from L1Trigger.L1TTrackMatch.l1tTrackVertexAssociationProducer_cfi import * from L1Trigger.VertexFinder.l1tVertexProducer_cfi import * -l1tVertexFinder = l1tVertexProducer.clone() -l1tVertexFinderEmulator = l1tVertexProducer.clone() -l1tVertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" -l1tVertexFinderEmulator.l1TracksInputTag = ("l1tGTTInputProducer","Level1TTTracksConverted") -_phase2_siml1emulator.add(l1tVertexFinder) -_phase2_siml1emulator.add(l1tVertexProducer) + +# Track Conversion, Track Selection, Vertex Finding _phase2_siml1emulator.add(l1tGTTInputProducer) _phase2_siml1emulator.add(l1tGTTInputProducerExtended) +_phase2_siml1emulator.add(l1tTrackSelectionProducer) +_phase2_siml1emulator.add(l1tTrackSelectionProducerExtended) +_phase2_siml1emulator.add(l1tVertexFinder) +_phase2_siml1emulator.add(l1tVertexProducer) _phase2_siml1emulator.add(l1tVertexFinderEmulator) # Emulated GMT Muons (Tk + Stub, Tk + MuonTFT, StandaloneMuon) @@ -144,36 +149,44 @@ _phase2_siml1emulator.add( l1tTkMuonsGmt ) _phase2_siml1emulator.add( l1tSAMuonsGmt ) +## fix for low-pt muons, this collection is a copy of the l1tTkMuonsGmt collection +## in which we only keep those low pt muons with an SA muon associated to it. Threshold +## for this cutoff is configurable. +l1tTkMuonsGmtLowPtFix = l1tGMTFilteredMuons.clone() +_phase2_siml1emulator.add( l1tTkMuonsGmtLowPtFix ) + # Tracker Objects # ######################################################################## from L1Trigger.L1TTrackMatch.l1tTrackJets_cfi import * from L1Trigger.L1TTrackMatch.l1tTrackFastJets_cfi import * from L1Trigger.L1TTrackMatch.l1tTrackerEtMiss_cfi import * from L1Trigger.L1TTrackMatch.l1tTrackerHTMiss_cfi import * -# make the input tags consistent with the choice L1VertexFinder above -l1tTrackJets.L1PVertexInputTag = ("l1tVertexFinderEmulator","l1verticesEmulation") -l1tTrackFastJets.L1PrimaryVertexTag = ("l1tVertexFinder", "l1vertices") -l1tTrackJetsExtended.L1PVertexInputTag = ("l1tVertexFinderEmulator","l1verticesEmulation") -#l1tTrackerEtMiss.L1VertexInputTag = ("l1tVertexFinder", "l1vertices") -#l1tTrackerEtMissExtended.L1VertexInputTag = ("l1tVertexFinder", "l1vertices") -from L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi import * -_phase2_siml1emulator.add(l1tTrackSelectionProducer) -_phase2_siml1emulator.add(l1tTrackSelectionProducerExtended) +#Selected and Associated tracks for Jets and Emulated Jets +_phase2_siml1emulator.add(l1tTrackSelectionProducerForJets) +_phase2_siml1emulator.add(l1tTrackSelectionProducerExtendedForJets) +_phase2_siml1emulator.add(l1tTrackVertexAssociationProducerForJets) +_phase2_siml1emulator.add(l1tTrackVertexAssociationProducerExtendedForJets) + +#Selected and Associated tracks for EtMiss and Emulated EtMiss +_phase2_siml1emulator.add(l1tTrackSelectionProducerForEtMiss) +_phase2_siml1emulator.add(l1tTrackSelectionProducerExtendedForEtMiss) +_phase2_siml1emulator.add(l1tTrackVertexAssociationProducerForEtMiss) +_phase2_siml1emulator.add(l1tTrackVertexAssociationProducerExtendedForEtMiss) +#Track Jets, Track Only Et Miss, Track Only HT Miss _phase2_siml1emulator.add(l1tTrackJets) _phase2_siml1emulator.add(l1tTrackJetsExtended) _phase2_siml1emulator.add(l1tTrackFastJets) _phase2_siml1emulator.add(l1tTrackerEtMiss) _phase2_siml1emulator.add(l1tTrackerHTMiss) -#Emulated tracker objects +#Emulated Track Jets, Track Only Et Miss, Track Only HT Miss from L1Trigger.L1TTrackMatch.l1tTrackJetsEmulation_cfi import * _phase2_siml1emulator.add(l1tTrackJetsEmulation) _phase2_siml1emulator.add(l1tTrackJetsExtendedEmulation) from L1Trigger.L1TTrackMatch.l1tTrackerEmuEtMiss_cfi import * -l1tTrackerEmuEtMiss.L1VertexInputTag = ("l1tVertexFinderEmulator","l1verticesEmulation") _phase2_siml1emulator.add(l1tTrackerEmuEtMiss) from L1Trigger.L1TTrackMatch.l1tTrackerEmuHTMiss_cfi import * diff --git a/L1Trigger/DemonstratorTools/BuildFile.xml b/L1Trigger/DemonstratorTools/BuildFile.xml index 692d3965bb994..a0e9d37b75993 100644 --- a/L1Trigger/DemonstratorTools/BuildFile.xml +++ b/L1Trigger/DemonstratorTools/BuildFile.xml @@ -5,6 +5,7 @@ + diff --git a/L1Trigger/DemonstratorTools/interface/BoardData.h b/L1Trigger/DemonstratorTools/interface/BoardData.h index f68c8c3d83ddb..9c25462e5191e 100644 --- a/L1Trigger/DemonstratorTools/interface/BoardData.h +++ b/L1Trigger/DemonstratorTools/interface/BoardData.h @@ -22,6 +22,8 @@ namespace l1t::demo { const std::string& name() const; + void name(const std::string& aName); + std::map::const_iterator begin() const; std::map::iterator begin(); diff --git a/L1Trigger/DemonstratorTools/interface/BoardDataWriter.h b/L1Trigger/DemonstratorTools/interface/BoardDataWriter.h index 30e7cd3369df7..a3d54b0562065 100644 --- a/L1Trigger/DemonstratorTools/interface/BoardDataWriter.h +++ b/L1Trigger/DemonstratorTools/interface/BoardDataWriter.h @@ -24,6 +24,7 @@ namespace l1t::demo { BoardDataWriter(FileFormat, const std::string& filePath, + const std::string& fileExt, const size_t framesPerBX, const size_t tmux, const size_t maxFramesPerFile, @@ -31,12 +32,16 @@ namespace l1t::demo { BoardDataWriter(FileFormat, const std::string& filePath, + const std::string& fileExt, const size_t framesPerBX, const size_t tmux, const size_t maxFramesPerFile, const std::map>&, const std::map&); + // Set ID string that's written at start of board data files + void setBoardDataFileID(const std::string&); + void addEvent(const EventData& data); // If there are events that have not been written to file, forces creation of a board data file containing them @@ -50,6 +55,9 @@ namespace l1t::demo { FileFormat fileFormat_; + // ID string that's written at start of board data files + std::string boardDataFileID_; + std::function filePathGen_; std::vector fileNames_; diff --git a/L1Trigger/DemonstratorTools/interface/FileFormat.h b/L1Trigger/DemonstratorTools/interface/FileFormat.h index 06d5bc15b7bcb..b17b12044530a 100644 --- a/L1Trigger/DemonstratorTools/interface/FileFormat.h +++ b/L1Trigger/DemonstratorTools/interface/FileFormat.h @@ -6,7 +6,12 @@ namespace l1t::demo { - enum class FileFormat { APx, EMP, X20 }; + enum class FileFormat { + APx, + EMPv1, //< Format used in EMP until version 0.6.x + EMPv2, //< Format used in EMP from verison 0.7.0 + X2O + }; std::ostream& operator<<(std::ostream&, FileFormat); diff --git a/L1Trigger/DemonstratorTools/interface/Frame.h b/L1Trigger/DemonstratorTools/interface/Frame.h index 00534443bb57d..8abd16a061f6d 100644 --- a/L1Trigger/DemonstratorTools/interface/Frame.h +++ b/L1Trigger/DemonstratorTools/interface/Frame.h @@ -18,8 +18,9 @@ namespace l1t::demo { ap_uint<64> data{0}; bool valid{false}; bool strobe{true}; - bool start{false}; - bool end{false}; + bool startOfOrbit{false}; + bool startOfPacket{false}; + bool endOfPacket{false}; }; } // namespace l1t::demo diff --git a/L1Trigger/DemonstratorTools/plugins/GTTFileWriter.cc b/L1Trigger/DemonstratorTools/plugins/GTTFileWriter.cc index b28157833db59..c79de7f8ee836 100644 --- a/L1Trigger/DemonstratorTools/plugins/GTTFileWriter.cc +++ b/L1Trigger/DemonstratorTools/plugins/GTTFileWriter.cc @@ -164,6 +164,7 @@ GTTFileWriter::GTTFileWriter(const edm::ParameterSet& iConfig) etMissToken_(consumes>(iConfig.getUntrackedParameter("etmiss"))), fileWriterInputTracks_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), iConfig.getUntrackedParameter("inputFilename"), + iConfig.getUntrackedParameter("fileExtension"), kFramesPerTMUXPeriod, kGTTBoardTMUX, kMaxLinesPerFile, @@ -171,6 +172,7 @@ GTTFileWriter::GTTFileWriter(const edm::ParameterSet& iConfig) kChannelSpecsInput), fileWriterConvertedTracks_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), iConfig.getUntrackedParameter("inputConvertedFilename"), + iConfig.getUntrackedParameter("fileExtension"), kFramesPerTMUXPeriod, kGTTBoardTMUX, kMaxLinesPerFile, @@ -178,6 +180,7 @@ GTTFileWriter::GTTFileWriter(const edm::ParameterSet& iConfig) kChannelSpecsInput), fileWriterSelectedTracks_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), iConfig.getUntrackedParameter("selectedTracksFilename"), + iConfig.getUntrackedParameter("fileExtension"), kFramesPerTMUXPeriod, kGTTBoardTMUX, kMaxLinesPerFile, @@ -186,6 +189,7 @@ GTTFileWriter::GTTFileWriter(const edm::ParameterSet& iConfig) fileWriterVertexAssociatedTracks_( l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), iConfig.getUntrackedParameter("vertexAssociatedTracksFilename"), + iConfig.getUntrackedParameter("fileExtension"), kFramesPerTMUXPeriod, kGTTBoardTMUX, kMaxLinesPerFile, @@ -193,12 +197,14 @@ GTTFileWriter::GTTFileWriter(const edm::ParameterSet& iConfig) kChannelSpecsInput), fileWriterOutputToCorrelator_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), iConfig.getUntrackedParameter("outputCorrelatorFilename"), + iConfig.getUntrackedParameter("fileExtension"), kFramesPerTMUXPeriod, kGTTBoardTMUX, kMaxLinesPerFile, kChannelSpecsOutputToCorrelator), fileWriterOutputToGlobalTrigger_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), iConfig.getUntrackedParameter("outputGlobalTriggerFilename"), + iConfig.getUntrackedParameter("fileExtension"), kFramesPerTMUXPeriod, kGTTBoardTMUX, kMaxLinesPerFile, @@ -299,7 +305,7 @@ void GTTFileWriter::fillDescriptions(edm::ConfigurationDescriptions& description desc.addUntracked( "vertexAssociatedTracks", edm::InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelectedAssociatedEmulation")); - desc.addUntracked("vertices", edm::InputTag("l1tVertexProducer", "l1verticesEmulation")); + desc.addUntracked("vertices", edm::InputTag("l1tVertexProducer", "L1VerticesEmulation")); desc.addUntracked("jets", edm::InputTag("l1tTrackJetsEmulation", "L1TrackJets")); desc.addUntracked("htmiss", edm::InputTag("l1tTrackerEmuHTMiss", "L1TrackerEmuHTMiss")); desc.addUntracked("etmiss", edm::InputTag("l1tTrackerEmuEtMiss", "L1TrackerEmuEtMiss")); @@ -310,6 +316,7 @@ void GTTFileWriter::fillDescriptions(edm::ConfigurationDescriptions& description desc.addUntracked("outputCorrelatorFilename", "L1GTTOutputToCorrelatorFile"); desc.addUntracked("outputGlobalTriggerFilename", "L1GTTOutputToGlobalTriggerFile"); desc.addUntracked("format", "APx"); + desc.addUntracked("fileExtension", "txt"); descriptions.add("GTTFileWriter", desc); } diff --git a/L1Trigger/DemonstratorTools/python/GTTFileReader_cff.py b/L1Trigger/DemonstratorTools/python/l1tGTTFileReader_cfi.py similarity index 73% rename from L1Trigger/DemonstratorTools/python/GTTFileReader_cff.py rename to L1Trigger/DemonstratorTools/python/l1tGTTFileReader_cfi.py index 0a5c25c0f714f..10033c8fb738b 100644 --- a/L1Trigger/DemonstratorTools/python/GTTFileReader_cff.py +++ b/L1Trigger/DemonstratorTools/python/l1tGTTFileReader_cfi.py @@ -1,6 +1,6 @@ import FWCore.ParameterSet.Config as cms -GTTFileReader = cms.EDProducer('GTTFileReader', +l1tGTTFileReader = cms.EDProducer('GTTFileReader', files = cms.vstring("gttOutput_0.txt"), #, "gttOutput_1.txt"), format = cms.untracked.string("APx") -) \ No newline at end of file +) diff --git a/L1Trigger/DemonstratorTools/python/GTTFileWriter_cff.py b/L1Trigger/DemonstratorTools/python/l1tGTTFileWriter_cfi.py similarity index 88% rename from L1Trigger/DemonstratorTools/python/GTTFileWriter_cff.py rename to L1Trigger/DemonstratorTools/python/l1tGTTFileWriter_cfi.py index 61c4c46929041..b5e575ceafcd7 100644 --- a/L1Trigger/DemonstratorTools/python/GTTFileWriter_cff.py +++ b/L1Trigger/DemonstratorTools/python/l1tGTTFileWriter_cfi.py @@ -1,9 +1,9 @@ import FWCore.ParameterSet.Config as cms -GTTFileWriter = cms.EDAnalyzer('GTTFileWriter', +l1tGTTFileWriter = cms.EDAnalyzer('GTTFileWriter', tracks = cms.untracked.InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks"), convertedTracks = cms.untracked.InputTag("l1tGTTInputProducer", "Level1TTTracksConverted"), - vertices = cms.untracked.InputTag("l1tVertexProducer", "l1verticesEmulation"), + vertices = cms.untracked.InputTag("l1tVertexProducer", "L1VerticesEmulation"), selectedTracks = cms.untracked.InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelectedEmulation"), vertexAssociatedTracks = cms.untracked.InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelectedAssociatedEmulation"), jets = cms.untracked.InputTag("l1tTrackJetsEmulation","L1TrackJets"), @@ -15,5 +15,6 @@ vertexAssociatedTracksFilename = cms.untracked.string("L1GTTVertexAssociatedTracksFile"), outputCorrelatorFilename = cms.untracked.string("L1GTTOutputToCorrelatorFile"), outputGlobalTriggerFilename = cms.untracked.string("L1GTTOutputToGlobalTriggerFile"), + fileExtension = cms.untracked.string("txt"), format = cms.untracked.string("APx") ) diff --git a/L1Trigger/DemonstratorTools/src/BoardData.cc b/L1Trigger/DemonstratorTools/src/BoardData.cc index 2a40b5c3d6fec..f6d4992bfb40d 100644 --- a/L1Trigger/DemonstratorTools/src/BoardData.cc +++ b/L1Trigger/DemonstratorTools/src/BoardData.cc @@ -14,6 +14,8 @@ namespace l1t::demo { const std::string& BoardData::name() const { return name_; } + void BoardData::name(const std::string& aName) { name_ = aName; } + std::map::const_iterator BoardData::begin() const { return data_.begin(); } std::map::iterator BoardData::begin() { return data_.begin(); } diff --git a/L1Trigger/DemonstratorTools/src/BoardDataWriter.cc b/L1Trigger/DemonstratorTools/src/BoardDataWriter.cc index c98a3cb5b9918..7dcd95af15696 100644 --- a/L1Trigger/DemonstratorTools/src/BoardDataWriter.cc +++ b/L1Trigger/DemonstratorTools/src/BoardDataWriter.cc @@ -9,12 +9,14 @@ namespace l1t::demo { BoardDataWriter::BoardDataWriter(FileFormat format, const std::string& path, + const std::string& fileExt, const size_t framesPerBX, const size_t tmux, const size_t maxFramesPerFile, const ChannelMap_t& channelSpecs) : fileFormat_(format), - filePathGen_([=](const size_t i) { return path + "_" + std::to_string(i) + ".txt"; }), + boardDataFileID_("CMSSW"), + filePathGen_([=](const size_t i) { return path + "_" + std::to_string(i) + "." + fileExt; }), framesPerBX_(framesPerBX), boardTMUX_(tmux), maxFramesPerFile_(maxFramesPerFile), @@ -24,6 +26,8 @@ namespace l1t::demo { channelMap_(channelSpecs) { if (channelMap_.empty()) throw std::runtime_error("BoardDataWriter channel map cannnot be empty"); + if (fileExt != "txt" && fileExt != "txt.gz" && fileExt != "txt.xz") + throw std::runtime_error("BoardDataWriter fileExt must be one of txt, txt.gz, txt.xz"); for (const auto& [id, value] : channelMap_) { const auto& [spec, indices] = value; @@ -50,12 +54,16 @@ namespace l1t::demo { BoardDataWriter::BoardDataWriter(FileFormat format, const std::string& path, + const std::string& fileExt, const size_t framesPerBX, const size_t tmux, const size_t maxFramesPerFile, const std::map>& channelMap, const std::map& channelSpecs) - : BoardDataWriter(format, path, framesPerBX, tmux, maxFramesPerFile, mergeMaps(channelMap, channelSpecs)) {} + : BoardDataWriter( + format, path, fileExt, framesPerBX, tmux, maxFramesPerFile, mergeMaps(channelMap, channelSpecs)) {} + + void BoardDataWriter::setBoardDataFileID(const std::string& aId) { boardDataFileID_ = aId; } void BoardDataWriter::addEvent(const EventData& eventData) { // Check that data is supplied for each channel @@ -90,9 +98,9 @@ namespace l1t::demo { // Override flags for start & end of event BoardData::Channel::iterator it(boardData_.at(chanIndex).end() - 1); - it->end = true; + it->endOfPacket = true; it -= (channelData.size() - 1); - it->start = true; + it->startOfPacket = true; // Pad link with non-valid frames boardData_.at(chanIndex).insert( @@ -114,6 +122,19 @@ namespace l1t::demo { for (auto& x : boardData_) x.second.resize(maxFramesPerFile_); + // For each channel: Assert start_of_orbit for first clock cycle that start is asserted + for (auto& x : boardData_) { + for (auto& frame : x.second) { + if (frame.startOfPacket) { + frame.startOfOrbit = true; + break; + } + } + } + + // Set ID field for board data files + boardData_.name(boardDataFileID_); + // Write board data object to file const std::string filePath = filePathGen_(fileNames_.size()); write(boardData_, filePath, fileFormat_); @@ -144,4 +165,4 @@ namespace l1t::demo { pendingEvents_ = 0; } -} // namespace l1t::demo \ No newline at end of file +} // namespace l1t::demo diff --git a/L1Trigger/DemonstratorTools/src/FileFormat.cc b/L1Trigger/DemonstratorTools/src/FileFormat.cc index d51110af1308d..741b26c595bdb 100644 --- a/L1Trigger/DemonstratorTools/src/FileFormat.cc +++ b/L1Trigger/DemonstratorTools/src/FileFormat.cc @@ -10,11 +10,14 @@ namespace l1t::demo { case FileFormat::APx: os << "APx"; break; - case FileFormat::EMP: - os << "EMP"; + case FileFormat::EMPv1: + os << "EMPv1"; break; - case FileFormat::X20: - os << "X20"; + case FileFormat::EMPv2: + os << "EMPv2"; + break; + case FileFormat::X2O: + os << "X2O"; } return os; } diff --git a/L1Trigger/DemonstratorTools/src/utilities.cc b/L1Trigger/DemonstratorTools/src/utilities.cc index b35ba60c138d6..f9c13a3dcce54 100644 --- a/L1Trigger/DemonstratorTools/src/utilities.cc +++ b/L1Trigger/DemonstratorTools/src/utilities.cc @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include #ifdef CMSSW_GIT_HASH #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -68,12 +71,14 @@ namespace { namespace l1t::demo { FileFormat parseFileFormat(const std::string& s) { - static const std::unordered_map kFormatStringMap({{"EMP", FileFormat::EMP}, - {"emp", FileFormat::EMP}, + static const std::unordered_map kFormatStringMap({{"EMP", FileFormat::EMPv1}, + {"emp", FileFormat::EMPv1}, + {"EMPv1", FileFormat::EMPv1}, + {"EMPv2", FileFormat::EMPv2}, {"APx", FileFormat::APx}, {"apx", FileFormat::APx}, - {"X20", FileFormat::X20}, - {"x20", FileFormat::X20}}); + {"X2O", FileFormat::X2O}, + {"x2O", FileFormat::X2O}}); const auto it = kFormatStringMap.find(s); if (it == kFormatStringMap.end()) @@ -82,31 +87,49 @@ namespace l1t::demo { return it->second; } - BoardData readAPxFile(std::istream&, const FileFormat); + BoardData readAPxFile(std::istream&); - BoardData readEMPFile(std::istream&, const FileFormat); + BoardData readEMPFileV1(std::istream&); - BoardData readX20File(std::istream&, const FileFormat); + BoardData readEMPFileV2(std::istream&); + + BoardData readX2OFile(std::istream&); BoardData read(const std::string& filePath, const FileFormat format) { - std::ifstream file(filePath); + std::ifstream file(filePath, std::ios_base::in | std::ios_base::binary); if (not file.is_open()) throw std::runtime_error("Could not open file '" + filePath + "'"); - return read(file, format); + boost::iostreams::filtering_istream stream; + if (filePath.rfind(".gz") == filePath.length() - 3) + stream.push(boost::iostreams::gzip_decompressor()); + else if (filePath.rfind(".xz") == filePath.length() - 3) + stream.push(boost::iostreams::lzma_decompressor()); + + stream.push(file); + + return read(stream, format); } BoardData read(std::istream& file, const FileFormat format) { - if (format == FileFormat::APx) - return readAPxFile(file, format); - else if (format == FileFormat::EMP) - return readEMPFile(file, format); - else - return readX20File(file, format); + switch (format) { + case FileFormat::APx: + return readAPxFile(file); + case FileFormat::EMPv1: + return readEMPFileV1(file); + case FileFormat::EMPv2: + return readEMPFileV2(file); + case FileFormat::X2O: + return readX2OFile(file); + } + + std::ostringstream messageStream; + messageStream << "No read function registered for format " << format; + throw std::runtime_error(messageStream.str()); } - BoardData readAPxFile(std::istream& file, const FileFormat format) { + BoardData readAPxFile(std::istream& file) { std::string line; // Complain if file is empty @@ -171,8 +194,8 @@ namespace l1t::demo { else if ((count % 2) == 1) { uint16_t sbValue = std::stoul(token, nullptr, 16); dataRows.back().at((count - 1) / 2).valid = (sbValue & 0x1); - dataRows.back().at((count - 1) / 2).start = ((sbValue >> 1) & 0x1); - dataRows.back().at((count - 1) / 2).end = ((sbValue >> 3) & 0x1); + dataRows.back().at((count - 1) / 2).startOfPacket = ((sbValue >> 1) & 0x1); + dataRows.back().at((count - 1) / 2).endOfPacket = ((sbValue >> 3) & 0x1); } // Data word else @@ -187,7 +210,7 @@ namespace l1t::demo { return createBoardDataFromRows("", indices, dataRows); } - BoardData readEMPFile(std::istream& file, const FileFormat format) { + BoardData readEMPFileV1(std::istream& file) { // 1) Search for ID string std::string id, line; while (getline(file, line)) { @@ -257,15 +280,94 @@ namespace l1t::demo { return createBoardDataFromRows(id, channels, dataRows); } - BoardData readX20File(std::istream& file, const FileFormat format) { - throw std::runtime_error("Reading X20 file format not yet implemented. Will be done ASAP."); + BoardData readEMPFileV2(std::istream& file) { + // 1) Search for ID string + std::string id, line; + while (getline(file, line)) { + if (line.empty()) + continue; + if (line[0] == '#') + continue; + + if (line.rfind("ID: ", 0) != std::string::npos) { + id = line.substr(4); + break; + } else + throw std::logic_error("Found unexpected line found when searching for board ID: \"" + line + "\""); + } + + // 2) Check that next line states metadata formatting + getline(file, line); + if (line.find("Metadata: (strobe,) start of orbit, start of packet, end of packet, valid") != 0) + throw std::logic_error("Expected metadata line following 'ID' line. Instead found:" + line); + + // 3) Search for column labels (i.e. list of channels/links) + const auto tokens = searchAndTokenize(file, "Link "); + std::vector channels; + std::transform(tokens.begin(), tokens.end(), std::back_inserter(channels), [](const std::string& s) { + return std::stoull(s); + }); + + // 4) Read the main data rows + const std::regex delimiterRegex("\\s\\s+"); + static const std::regex frameRegex("([01])?([01])([01])([01])([01]) ([0-9a-fA-F]{16})"); + std::vector> dataRows; + while (file.good() and getline(file, line)) { + if (line.empty() or line[0] == '#') + continue; + + std::ostringstream prefixStream; + prefixStream << "Frame "; + prefixStream << std::setw(4) << std::setfill('0') << dataRows.size(); + prefixStream << " "; + + const std::string prefix(prefixStream.str()); + if (line.rfind(prefix, 0) == std::string::npos) + throw std::logic_error("Found unexpected line found when searching for \"" + prefix + "\": \"" + line + "\""); + + std::vector row; + std::sregex_token_iterator it(line.begin() + prefix.size(), line.end(), delimiterRegex, -1); + for (; it != std::sregex_token_iterator(); it++) { + const std::string token(it->str()); + if (token.empty()) + continue; + + std::smatch what; + if (not std::regex_match(token, what, frameRegex)) + throw std::logic_error("Token '" + token + "' doesn't match the valid format"); + + l1t::demo::Frame value; + // Import strobe if the strobe group is matched + if (what[1].matched) { + value.strobe = (what[1] == "1"); + } + + value.startOfOrbit = (what[2] == "1"); + value.startOfPacket = (what[3] == "1"); + value.endOfPacket = (what[4] == "1"); + value.valid = (what[5] == "1"); + value.data = ap_uint<64>(std::stoull(what[6].str(), nullptr, 16)); + + row.push_back(value); + } + + dataRows.push_back(row); + } + + return createBoardDataFromRows(id, channels, dataRows); + } + + BoardData readX2OFile(std::istream& file) { + throw std::runtime_error("Reading X2O file format not yet implemented. Will be done ASAP."); } - void writeAPxFile(const BoardData&, std::ostream&, const FileFormat); + void writeAPxFile(const BoardData&, std::ostream&); + + void writeEMPFileV1(const BoardData&, std::ostream&); - void writeEMPFile(const BoardData&, std::ostream&, const FileFormat); + void writeEMPFileV2(const BoardData&, std::ostream&); - void writeX20File(const BoardData&, std::ostream&, const FileFormat); + void writeX2OFile(const BoardData&, std::ostream&); void write(const BoardData& data, const std::string& filePath, const FileFormat format) { // Open file @@ -277,12 +379,19 @@ namespace l1t::demo { << "Writing board data (" << std::distance(data.begin(), data.end()) << " channels, " << data.begin()->second.size() << " frames) to file '" << filePath << "' (format: " << format << ")" << std::endl; - std::ofstream file(filePath); + + std::ofstream file(filePath, std::ios_base::out | std::ios_base::binary); if (not file.is_open()) throw std::runtime_error("Could not open file '" + filePath + "'"); - write(data, file, format); + boost::iostreams::filtering_ostream stream; + if (filePath.rfind(".gz") == filePath.length() - 3) + stream.push(boost::iostreams::gzip_compressor()); + else if (filePath.rfind(".xz") == filePath.length() - 3) + stream.push(boost::iostreams::lzma_compressor()); + stream.push(file); + write(data, stream, format); } void write(const BoardData& data, std::ostream& file, const FileFormat format) { @@ -302,18 +411,21 @@ namespace l1t::demo { // Call relevant write function switch (format) { case FileFormat::APx: - writeAPxFile(data, file, format); + writeAPxFile(data, file); return; - case FileFormat::EMP: - writeEMPFile(data, file, format); + case FileFormat::EMPv1: + writeEMPFileV1(data, file); return; - case FileFormat::X20: - writeX20File(data, file, format); + case FileFormat::EMPv2: + writeEMPFileV2(data, file); + return; + case FileFormat::X2O: + writeX2OFile(data, file); return; } } - void writeAPxFile(const BoardData& data, std::ostream& file, const FileFormat format) { + void writeAPxFile(const BoardData& data, std::ostream& file) { // Note: APx sideband encoding // Short-term, simulation only: // 0 -> Valid @@ -350,8 +462,8 @@ namespace l1t::demo { //const auto j = channel.first; const auto channelData = channel.second; uint16_t sideband = channelData.at(i).valid; - sideband |= channelData.at(i).start << 1; - sideband |= channelData.at(i).end << 3; + sideband |= channelData.at(i).startOfPacket << 1; + sideband |= channelData.at(i).endOfPacket << 3; file << " 0x" << std::setw(2) << sideband; file << " 0x" << std::setw(16) << uint64_t(channelData.at(i).data); } @@ -359,7 +471,7 @@ namespace l1t::demo { } } - void writeEMPFile(const BoardData& data, std::ostream& file, const FileFormat format) { + void writeEMPFileV1(const BoardData& data, std::ostream& file) { file << std::setfill('0'); // Board name/id @@ -398,8 +510,47 @@ namespace l1t::demo { } } - void writeX20File(const BoardData& data, std::ostream& file, const FileFormat format) { - throw std::runtime_error("Writing X20 file format not yet implemented. Will be done ASAP."); + void writeEMPFileV2(const BoardData& data, std::ostream& file) { + file << std::setfill('0'); + + // Board name/id + file << "ID: " << data.name() << std::endl; + file << "Metadata: (strobe,) start of orbit, start of packet, end of packet, valid" << std::endl; + file << std::endl; + + // Link header + file << " Link "; + std::map strobedLinkMap; + for (const auto& channel : data) { + const auto i = channel.first; + strobedLinkMap[i] = + std::any_of(channel.second.begin(), channel.second.end(), [](const Frame& x) { return not x.strobe; }); + if (strobedLinkMap.at(i)) + file << " "; + file << " " << std::setw(3) << i << " "; + } + file << std::endl; + + // Frames + const auto firstChannel = data.begin(); + for (size_t i = 0; i < firstChannel->second.size(); i++) { + file << "Frame " << std::setw(4) << i << " "; + for (const auto& channel : data) { + //const auto j = channel.first; + const auto channelData = channel.second; + file << " "; + if (strobedLinkMap.at(channel.first)) + file << std::setw(1) << channelData.at(i).strobe; + file << std::setw(1) << channelData.at(i).startOfOrbit << channelData.at(i).startOfPacket + << channelData.at(i).endOfPacket << channelData.at(i).valid; + file << " " << std::setw(16) << std::hex << uint64_t(channelData.at(i).data); + } + file << std::endl << std::dec; + } + } + + void writeX2OFile(const BoardData& data, std::ostream& file) { + throw std::runtime_error("Writing X2O file format not yet implemented. Will be done ASAP."); } } // namespace l1t::demo diff --git a/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py b/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py index 6f720104d9db5..a973588daf9b2 100644 --- a/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py +++ b/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py @@ -2,7 +2,6 @@ import FWCore.Utilities.FileUtils as FileUtils import FWCore.ParameterSet.VarParsing as VarParsing - # PART 1 : PARSE ARGUMENTS options = VarParsing.VarParsing ('analysis') @@ -15,7 +14,7 @@ 'EMP', # default value VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, - "File format (APx, EMP or X20)") + "File format (APx, EMP or X2O)") options.register('threads', 1, # default value VarParsing.VarParsing.multiplicity.singleton, @@ -44,8 +43,8 @@ process = cms.Process("GTTFileWriter") -process.load('Configuration.Geometry.GeometryExtended2026D77Reco_cff') -process.load('Configuration.Geometry.GeometryExtended2026D77_cff') +process.load('Configuration.Geometry.GeometryExtended2026D88Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D88_cff') process.load('Configuration.StandardSequences.MagneticField_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag @@ -64,25 +63,57 @@ process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") process.load('L1Trigger.L1TTrackMatch.l1tGTTInputProducer_cfi') +process.load('L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi') process.load('L1Trigger.VertexFinder.l1tVertexProducer_cfi') -process.load("L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi") -process.load("L1Trigger.L1TTrackMatch.l1tTrackJetsEmulation_cfi") -process.load("L1Trigger.L1TTrackMatch.l1tTrackerEmuHTMiss_cfi") -process.load("L1Trigger.L1TTrackMatch.l1tTrackerEmuEtMiss_cfi") -process.load('L1Trigger.DemonstratorTools.GTTFileWriter_cff') - +process.load('L1Trigger.L1TTrackMatch.l1tTrackVertexAssociationProducer_cfi') +process.load('L1Trigger.L1TTrackMatch.l1tTrackJetsEmulation_cfi') +process.load('L1Trigger.L1TTrackMatch.l1tTrackerEmuHTMiss_cfi') +process.load('L1Trigger.L1TTrackMatch.l1tTrackerEmuEtMiss_cfi') +process.load('L1Trigger.DemonstratorTools.l1tGTTFileWriter_cfi') + process.l1tGTTInputProducer.debug = cms.int32(options.debug) -process.l1tVertexProducer.l1TracksInputTag = cms.InputTag("l1tGTTInputProducer","Level1TTTracksConverted") -process.l1tVertexProducer.VertexReconstruction.Algorithm = cms.string("fastHistoEmulation") -process.l1tVertexProducer.VertexReconstruction.VxMinTrackPt = cms.double(0.0) -process.l1tVertexProducer.debug = options.debug + process.l1tTrackSelectionProducer.processSimulatedTracks = cms.bool(False) -process.l1tTrackSelectionProducer.l1VerticesEmulationInputTag = cms.InputTag("l1tVertexProducer", "l1verticesEmulation") -process.l1tTrackSelectionProducer.debug = options.debug -process.l1tTrackJetsEmulation.VertexInputTag = cms.InputTag("l1tVertexProducer", "l1verticesEmulation") -process.l1tTrackerEmuEtMiss.L1VertexInputTag = cms.InputTag("l1tVertexProducer", "l1verticesEmulation") +process.l1tVertexFinderEmulator.VertexReconstruction.VxMinTrackPt = cms.double(0.0) +process.l1tVertexFinderEmulator.debug = options.debug +process.l1tTrackVertexAssociationProducer.processSimulatedTracks = cms.bool(False) + +process.l1tTrackSelectionProducerForEtMiss.processSimulatedTracks = cms.bool(False) +process.l1tTrackVertexAssociationProducerForEtMiss.processSimulatedTracks = cms.bool(False) process.l1tTrackerEmuEtMiss.debug = options.debug +process.l1tTrackSelectionProducerForJets.processSimulatedTracks = cms.bool(False) +process.l1tTrackSelectionProducerForJets.cutSet = cms.PSet( + ptMin = cms.double(2.0), # pt must be greater than this value, [GeV] + absEtaMax = cms.double(2.4), # absolute value of eta must be less than this value + absZ0Max = cms.double(15.0), # z0 must be less than this value, [cm] + nStubsMin = cms.int32(4), # number of stubs must be greater than or equal to this value + nPSStubsMin = cms.int32(0), # the number of stubs in the PS Modules must be greater than or equal to this value + + reducedBendChi2Max = cms.double(2.25), # bend chi2 must be less than this value + reducedChi2RZMax = cms.double(5.0), # chi2rz/dof must be less than this value + reducedChi2RPhiMax = cms.double(20.0), # chi2rphi/dof must be less than this value +) +process.l1tTrackVertexAssociationProducerForJets.processSimulatedTracks = cms.bool(False) +process.l1tTrackVertexAssociationProducerForJets.cutSet = cms.PSet( + #deltaZMaxEtaBounds = cms.vdouble(0.0, absEtaMax.value), # these values define the bin boundaries in |eta| + #deltaZMax = cms.vdouble(0.5), # delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, [cm] + deltaZMaxEtaBounds = cms.vdouble(0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4), # these values define the bin boundaries in |eta| + deltaZMax = cms.vdouble(0.37, 0.50, 0.60, 0.75, 1.00, 1.60), # delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, [cm] +) +process.l1tTrackerEmuHTMiss.debug = (options.debug > 0) + +#Disable internal track selection +process.l1tTrackJetsEmulation.MaxDzTrackPV = cms.double(10000.0) +process.l1tTrackJetsEmulation.trk_zMax = cms.double(10000.0) # maximum track z +process.l1tTrackJetsEmulation.trk_ptMax = cms.double(10000.0) # maximumum track pT before saturation [GeV] +process.l1tTrackJetsEmulation.trk_ptMin = cms.double(0.0) # minimum track pt [GeV] +process.l1tTrackJetsEmulation.trk_etaMax = cms.double(10000.0) # maximum track eta +process.l1tTrackJetsEmulation.nStubs4PromptChi2=cms.double(10000.0) #Prompt track quality flags for loose/tight +process.l1tTrackJetsEmulation.nStubs4PromptBend=cms.double(10000.0) +process.l1tTrackJetsEmulation.nStubs5PromptChi2=cms.double(10000.0) +process.l1tTrackJetsEmulation.nStubs5PromptBend=cms.double(10000.0) + if options.debug: process.MessageLogger.cerr.INFO.limit = cms.untracked.int32(1000000000) process.MessageLogger.suppressInfo = cms.untracked.vstring('CondDBESSource', 'PoolDBESSource') @@ -90,10 +121,35 @@ limit = cms.untracked.int32(0) ) -process.GTTFileWriter.format = cms.untracked.string(options.format) -# process.GTTFileWriter.outputFilename = cms.untracked.string("myOutputFile.txt") +process.l1tGTTFileWriter.format = cms.untracked.string(options.format) #FIXME Put all this into the default GTTFileWriter +process.l1tGTTFileWriter.tracks = cms.untracked.InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks") +process.l1tGTTFileWriter.convertedTracks = cms.untracked.InputTag("l1tGTTInputProducer", "Level1TTTracksConverted") +process.l1tGTTFileWriter.selectedTracks = cms.untracked.InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelectedEmulation") +process.l1tGTTFileWriter.vertices = cms.untracked.InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation") +process.l1tGTTFileWriter.vertexAssociatedTracks = cms.untracked.InputTag("l1tTrackVertexAssociationProducer", "Level1TTTracksSelectedAssociatedEmulation") +process.l1tGTTFileWriter.jets = cms.untracked.InputTag("l1tTrackJetsEmulation","L1TrackJets") +process.l1tGTTFileWriter.htmiss = cms.untracked.InputTag("l1tTrackerEmuHTMiss", "L1TrackerEmuHTMiss") +process.l1tGTTFileWriter.etmiss = cms.untracked.InputTag("l1tTrackerEmuEtMiss", "L1TrackerEmuEtMiss") +process.l1tGTTFileWriter.outputCorrelatorFilename = cms.untracked.string("L1GTTOutputToCorrelatorFile") +process.l1tGTTFileWriter.outputGlobalTriggerFilename = cms.untracked.string("L1GTTOutputToGlobalTriggerFile") +process.l1tGTTFileWriter.selectedTracksFilename = cms.untracked.string("L1GTTSelectedTracksFile") +process.l1tGTTFileWriter.vertexAssociatedTracksFilename = cms.untracked.string("L1GTTVertexAssociatedTracksFile") process.MessageLogger.cerr.FwkReport.reportEvery = 1 process.Timing = cms.Service("Timing", summaryOnly = cms.untracked.bool(True)) -process.p = cms.Path(process.l1tGTTInputProducer * process.l1tVertexProducer * process.l1tTrackSelectionProducer * process.l1tTrackJetsEmulation * process.l1tTrackerEmuHTMiss * process.l1tTrackerEmuEtMiss * process.GTTFileWriter) + +process.p = cms.Path(process.l1tGTTFileWriter) +process.p.associate(cms.Task(process.l1tGTTInputProducer, + process.l1tTrackSelectionProducer, + process.l1tVertexFinderEmulator, + process.l1tTrackVertexAssociationProducer, + process.l1tTrackSelectionProducerForJets, + process.l1tTrackVertexAssociationProducerForJets, + process.l1tTrackJetsEmulation, + process.l1tTrackerEmuHTMiss, + process.l1tTrackSelectionProducerForEtMiss, + process.l1tTrackVertexAssociationProducerForEtMiss, + process.l1tTrackerEmuEtMiss, + ) + ) diff --git a/L1Trigger/DemonstratorTools/test/gtt/example_vertex_emp.txt b/L1Trigger/DemonstratorTools/test/gtt/example_vertex_empV1.txt similarity index 100% rename from L1Trigger/DemonstratorTools/test/gtt/example_vertex_emp.txt rename to L1Trigger/DemonstratorTools/test/gtt/example_vertex_empV1.txt diff --git a/L1Trigger/DemonstratorTools/test/gtt/example_vertex_empV2.txt b/L1Trigger/DemonstratorTools/test/gtt/example_vertex_empV2.txt new file mode 100644 index 0000000000000..a415a333a4cc4 --- /dev/null +++ b/L1Trigger/DemonstratorTools/test/gtt/example_vertex_empV2.txt @@ -0,0 +1,176 @@ +ID: CMSSW +Metadata: (strobe,) start of orbit, start of packet, end of packet, valid + + Link 000 +Frame 0000 0000 0000000000000000 +Frame 0001 0000 0000000000000000 +Frame 0002 0000 0000000000000000 +Frame 0003 0000 0000000000000000 +Frame 0004 0000 0000000000000000 +Frame 0005 0000 0000000000000000 +Frame 0006 0000 0000000000000000 +Frame 0007 0000 0000000000000000 +Frame 0008 0000 0000000000000000 +Frame 0009 0000 0000000000000000 +Frame 0010 1101 0000000000000001 +Frame 0011 0001 0000000000000001 +Frame 0012 0001 0000000000000001 +Frame 0013 0001 0000000000000001 +Frame 0014 0001 0000000000000000 +Frame 0015 0001 0000000000000000 +Frame 0016 0001 0000000000000000 +Frame 0017 0001 0000000000000000 +Frame 0018 0001 0000000000000000 +Frame 0019 0011 0000000000000000 +Frame 0020 0000 0000000000000000 +Frame 0021 0000 0000000000000000 +Frame 0022 0000 0000000000000000 +Frame 0023 0000 0000000000000000 +Frame 0024 0000 0000000000000000 +Frame 0025 0000 0000000000000000 +Frame 0026 0000 0000000000000000 +Frame 0027 0000 0000000000000000 +Frame 0028 0000 0000000000000000 +Frame 0029 0000 0000000000000000 +Frame 0030 0000 0000000000000000 +Frame 0031 0000 0000000000000000 +Frame 0032 0000 0000000000000000 +Frame 0033 0000 0000000000000000 +Frame 0034 0000 0000000000000000 +Frame 0035 0000 0000000000000000 +Frame 0036 0000 0000000000000000 +Frame 0037 0000 0000000000000000 +Frame 0038 0000 0000000000000000 +Frame 0039 0000 0000000000000000 +Frame 0040 0000 0000000000000000 +Frame 0041 0000 0000000000000000 +Frame 0042 0000 0000000000000000 +Frame 0043 0000 0000000000000000 +Frame 0044 0000 0000000000000000 +Frame 0045 0000 0000000000000000 +Frame 0046 0000 0000000000000000 +Frame 0047 0000 0000000000000000 +Frame 0048 0000 0000000000000000 +Frame 0049 0000 0000000000000000 +Frame 0050 0000 0000000000000000 +Frame 0051 0000 0000000000000000 +Frame 0052 0000 0000000000000000 +Frame 0053 0000 0000000000000000 +Frame 0054 0000 0000000000000000 +Frame 0055 0000 0000000000000000 +Frame 0056 0000 0000000000000000 +Frame 0057 0000 0000000000000000 +Frame 0058 0000 0000000000000000 +Frame 0059 0000 0000000000000000 +Frame 0060 0000 0000000000000000 +Frame 0061 0000 0000000000000000 +Frame 0062 0000 0000000000000000 +Frame 0063 0000 0000000000000000 +Frame 0064 0101 0000000000000001 +Frame 0065 0001 0000000000000001 +Frame 0066 0001 0000000000000000 +Frame 0067 0001 0000000000000000 +Frame 0068 0001 0000000000000000 +Frame 0069 0001 0000000000000000 +Frame 0070 0001 0000000000000000 +Frame 0071 0001 0000000000000000 +Frame 0072 0001 0000000000000000 +Frame 0073 0011 0000000000000000 +Frame 0074 0000 0000000000000000 +Frame 0075 0000 0000000000000000 +Frame 0076 0000 0000000000000000 +Frame 0077 0000 0000000000000000 +Frame 0078 0000 0000000000000000 +Frame 0079 0000 0000000000000000 +Frame 0080 0000 0000000000000000 +Frame 0081 0000 0000000000000000 +Frame 0082 0000 0000000000000000 +Frame 0083 0000 0000000000000000 +Frame 0084 0000 0000000000000000 +Frame 0085 0000 0000000000000000 +Frame 0086 0000 0000000000000000 +Frame 0087 0000 0000000000000000 +Frame 0088 0000 0000000000000000 +Frame 0089 0000 0000000000000000 +Frame 0090 0000 0000000000000000 +Frame 0091 0000 0000000000000000 +Frame 0092 0000 0000000000000000 +Frame 0093 0000 0000000000000000 +Frame 0094 0000 0000000000000000 +Frame 0095 0000 0000000000000000 +Frame 0096 0000 0000000000000000 +Frame 0097 0000 0000000000000000 +Frame 0098 0000 0000000000000000 +Frame 0099 0000 0000000000000000 +Frame 0100 0000 0000000000000000 +Frame 0101 0000 0000000000000000 +Frame 0102 0000 0000000000000000 +Frame 0103 0000 0000000000000000 +Frame 0104 0000 0000000000000000 +Frame 0105 0000 0000000000000000 +Frame 0106 0000 0000000000000000 +Frame 0107 0000 0000000000000000 +Frame 0108 0000 0000000000000000 +Frame 0109 0000 0000000000000000 +Frame 0110 0000 0000000000000000 +Frame 0111 0000 0000000000000000 +Frame 0112 0000 0000000000000000 +Frame 0113 0000 0000000000000000 +Frame 0114 0000 0000000000000000 +Frame 0115 0000 0000000000000000 +Frame 0116 0000 0000000000000000 +Frame 0117 0000 0000000000000000 +Frame 0118 0101 0000000000000001 +Frame 0119 0001 0000000000000001 +Frame 0120 0001 0000000000000001 +Frame 0121 0001 0000000000000001 +Frame 0122 0001 0000000000000001 +Frame 0123 0001 0000000000000001 +Frame 0124 0001 0000000000000001 +Frame 0125 0001 0000000000000001 +Frame 0126 0001 0000000000000000 +Frame 0127 0011 0000000000000000 +Frame 0128 0000 0000000000000000 +Frame 0129 0000 0000000000000000 +Frame 0130 0000 0000000000000000 +Frame 0131 0000 0000000000000000 +Frame 0132 0000 0000000000000000 +Frame 0133 0000 0000000000000000 +Frame 0134 0000 0000000000000000 +Frame 0135 0000 0000000000000000 +Frame 0136 0000 0000000000000000 +Frame 0137 0000 0000000000000000 +Frame 0138 0000 0000000000000000 +Frame 0139 0000 0000000000000000 +Frame 0140 0000 0000000000000000 +Frame 0141 0000 0000000000000000 +Frame 0142 0000 0000000000000000 +Frame 0143 0000 0000000000000000 +Frame 0144 0000 0000000000000000 +Frame 0145 0000 0000000000000000 +Frame 0146 0000 0000000000000000 +Frame 0147 0000 0000000000000000 +Frame 0148 0000 0000000000000000 +Frame 0149 0000 0000000000000000 +Frame 0150 0000 0000000000000000 +Frame 0151 0000 0000000000000000 +Frame 0152 0000 0000000000000000 +Frame 0153 0000 0000000000000000 +Frame 0154 0000 0000000000000000 +Frame 0155 0000 0000000000000000 +Frame 0156 0000 0000000000000000 +Frame 0157 0000 0000000000000000 +Frame 0158 0000 0000000000000000 +Frame 0159 0000 0000000000000000 +Frame 0160 0000 0000000000000000 +Frame 0161 0000 0000000000000000 +Frame 0162 0000 0000000000000000 +Frame 0163 0000 0000000000000000 +Frame 0164 0000 0000000000000000 +Frame 0165 0000 0000000000000000 +Frame 0166 0000 0000000000000000 +Frame 0167 0000 0000000000000000 +Frame 0168 0000 0000000000000000 +Frame 0169 0000 0000000000000000 +Frame 0170 0000 0000000000000000 +Frame 0171 0000 0000000000000000 diff --git a/L1Trigger/DemonstratorTools/test/gtt/verifyFirmwareOutput_cfg.py b/L1Trigger/DemonstratorTools/test/gtt/verifyFirmwareOutput_cfg.py index ae64cf0329e65..f393086e4477f 100644 --- a/L1Trigger/DemonstratorTools/test/gtt/verifyFirmwareOutput_cfg.py +++ b/L1Trigger/DemonstratorTools/test/gtt/verifyFirmwareOutput_cfg.py @@ -11,7 +11,7 @@ 'EMP', # default value VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, - "File format (APx, EMP or X20)") + "File format (APx, EMP or X2O)") options.parseArguments() inputFiles = [] @@ -38,11 +38,11 @@ process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.maxEvents) ) process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") -process.load('L1Trigger.DemonstratorTools.GTTFileReader_cff') -process.GTTFileReader.files = cms.vstring("test/gtt/example_vertex_apx.txt") -process.GTTFileReader.format = cms.untracked.string(options.format) +process.load('L1Trigger.DemonstratorTools.l1tGTTFileReader_cfi') +process.l1tGTTFileReader.files = cms.vstring("test/gtt/example_vertex_apx.txt") +process.l1tGTTFileReader.format = cms.untracked.string(options.format) process.MessageLogger.cerr.FwkReport.reportEvery = 1 process.Timing = cms.Service("Timing", summaryOnly = cms.untracked.bool(True)) -process.p = cms.Path(process.L1HybridTracks * process.GTTFileReader) # vertex emulator & FW-emulator comparsion module need to be added here +process.p = cms.Path(process.L1HybridTracks * process.l1tGTTFileReader) # vertex emulator & FW-emulator comparsion module need to be added here diff --git a/L1Trigger/L1CaloTrigger/BuildFile.xml b/L1Trigger/L1CaloTrigger/BuildFile.xml index b95505a2ac92a..5345c8faa4379 100644 --- a/L1Trigger/L1CaloTrigger/BuildFile.xml +++ b/L1Trigger/L1CaloTrigger/BuildFile.xml @@ -1,5 +1,10 @@ + + + - + + + diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h new file mode 100644 index 0000000000000..448b0118d1c49 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h @@ -0,0 +1,1742 @@ +//------------------------------------ +// Helper functions for Phase2L1CaloEGammaEmulator.cc +//------------------------------------ +#ifndef L1Trigger_L1CaloTrigger_Phase2L1CaloEGammaUtils +#define L1Trigger_L1CaloTrigger_Phase2L1CaloEGammaUtils + +#include +#include +#include +#include +#include + +#include "DataFormats/EcalDetId/interface/EBDetId.h" +#include "DataFormats/HcalDetId/interface/HcalDetId.h" +#include "L1Trigger/L1CaloTrigger/interface/ParametricCalibration.h" + +// Output collections +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.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/L1Trigger/interface/BXVector.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" + +namespace p2eg { + + static constexpr int n_towers_Eta = 34; + static constexpr int n_towers_Phi = 72; + static constexpr int n_towers_halfPhi = 36; + static constexpr int n_towers_cardEta = 17; // new: equivalent to n_towers_per_link + static constexpr int n_towers_cardPhi = 4; + static constexpr int n_crystals_cardEta = (n_towers_Eta * n_towers_cardEta); + static constexpr int n_crystals_cardPhi = (n_towers_Phi * n_towers_cardPhi); + + // outputs + static constexpr int n_links_card = 4; // 4 links per card + static constexpr int n_clusters_link = 2; // 2 clusters sent out in each link + static constexpr int n_clusters_4link = 8; // 8 clusters sent out in 4 links + static constexpr int n_towers_per_link = 17; + + static constexpr int CRYSTALS_IN_TOWER_ETA = 5; + static constexpr int CRYSTALS_IN_TOWER_PHI = 5; + + static constexpr int TOWER_IN_ETA = 3; // number of towers in eta, in one 3x4 region (barrel) + static constexpr int TOWER_IN_PHI = 4; // number of towers in phi, in one 3x4 region (barrel) + + static constexpr int CRYSTAL_IN_ETA = 15; // number of crystals in eta, in one 3x4 region (barrel) + static constexpr int CRYSTAL_IN_PHI = 20; // number of crystals in phi, in one 3x4 region (barrel) + + static constexpr float ECAL_eta_range = 1.4841; + static constexpr float half_crystal_size = 0.00873; + + static constexpr float slideIsoPtThreshold = 80; + static constexpr float a0_80 = 0.85, a1_80 = 0.0080, a0 = 0.21; // passes_iso + static constexpr float b0 = 0.38, b1 = 1.9, b2 = 0.05; // passes_looseTkiso + static constexpr float c0_ss = 0.94, c1_ss = 0.052, c2_ss = 0.044; // passes_ss + static constexpr float d0 = 0.96, d1 = 0.0003; // passes_photon + static constexpr float e0_looseTkss = 0.944, e1_looseTkss = 0.65, e2_looseTkss = 0.4; // passes_looseTkss + static constexpr float cut_500_MeV = 0.5; + + static constexpr float ECAL_LSB = 0.125; // to convert from int to float (GeV) multiply by LSB + static constexpr float HCAL_LSB = 0.5; + + static constexpr int N_CLUSTERS_PER_REGION = 4; // number of clusters per ECAL region + static constexpr int N_REGIONS_PER_CARD = 6; // number of ECAL regions per card + + // GCT constants + static constexpr int N_RCTCARDS_PHI = 8; + static constexpr int N_RCTGCT_FIBERS = 4; + static constexpr int N_RCTTOWERS_FIBER = 17; + static constexpr int N_RCTCLUSTERS_FIBER = 2; + + static constexpr int N_GCTCARDS = 3; + static constexpr int N_GCTCORR_FIBERS = 48; + static constexpr int N_GCTTOWERS_FIBER = 17; + static constexpr int N_GCTCLUSTERS_FIBER = 2; + + static constexpr int N_GCTINTERNAL_FIBERS = 64; + static constexpr int N_GCTPOSITIVE_FIBERS = 32; + static constexpr int N_GCTETA = 34; + static constexpr int N_GCTPHI = 32; + + // for emulator: "top" of the GCT card in phi is tower idx 20, for GCT card #0: + static constexpr int GCTCARD_0_TOWER_IPHI_OFFSET = 20; + // same but for GCT cards #1 and 2 (cards wrap around phi = 180 degrees): + static constexpr int GCTCARD_1_TOWER_IPHI_OFFSET = 44; + static constexpr int GCTCARD_2_TOWER_IPHI_OFFSET = 68; + + static constexpr int N_GCTTOWERS_CLUSTER_ISO_ONESIDE = 5; // window size of isolation sum (5x5 in towers) + + /* + * Convert HCAL ET to ECAL ET convention + */ + inline ap_uint<12> convertHcalETtoEcalET(ap_uint<12> HCAL) { + float hcalEtAsFloat = HCAL * HCAL_LSB; + return (ap_uint<12>(hcalEtAsFloat / ECAL_LSB)); + } + + ////////////////////////////////////////////////////////////////////////// + // RCT: indexing helper functions + ////////////////////////////////////////////////////////////////////////// + + // Assert that the card index is within bounds. (Valid cc: 0 to 35, since there are 36 RCT cards) + inline bool isValidCard(int cc) { return ((cc > -1) && (cc < 36)); } + + // RCT Cards: need to know their min/max crystal boundaries. + + // For a card (ranging from 0 to 35, since there are 36 cards), return the iEta of the crystal with max iEta. + // This represents the card boundaries in eta (identical to getEtaMax_card in the original emulator) + inline int getCard_iEtaMax(int cc) { + assert(isValidCard(cc)); + + int etamax = 0; + if (cc % 2 == 0) // Even card: negative eta + etamax = (n_towers_cardEta * CRYSTALS_IN_TOWER_ETA - 1); // First eta half. 5 crystals in eta in 1 tower. + else // Odd card: positive eta + etamax = (n_towers_Eta * CRYSTALS_IN_TOWER_ETA - 1); + return etamax; + } + + // Same as above but for minimum iEta. + inline int getCard_iEtaMin(int cc) { + int etamin = 0; + if (cc % 2 == 0) // Even card: negative eta + etamin = (0); + else // Odd card: positive eta + etamin = (n_towers_cardEta * CRYSTALS_IN_TOWER_ETA); + return etamin; + } + + // Same as above but for maximum iPhi. + inline int getCard_iPhiMax(int cc) { + int phimax = ((cc / 2) + 1) * 4 * CRYSTALS_IN_TOWER_PHI - 1; + return phimax; + } + + // Same as above but for minimum iPhi. + inline int getCard_iPhiMin(int cc) { + int phimin = (cc / 2) * 4 * CRYSTALS_IN_TOWER_PHI; + return phimin; + } + + // Given the RCT card number (0-35), get the crystal iEta of the "bottom left" corner + inline int getCard_refCrystal_iEta(int cc) { + if ((cc % 2) == 1) { // if cc is odd (positive eta) + return (17 * CRYSTALS_IN_TOWER_ETA); + } else { // if cc is even (negative eta) the bottom left corner is further in eta, hence +4 + return ((16 * CRYSTALS_IN_TOWER_ETA) + 4); + } + } + + // Given the RCT card number (0-35), get the global crystal iPhi of the "bottom left" corner (0- 71*5) + inline int getCard_refCrystal_iPhi(int cc) { + if ((cc % 2) == 1) { + // if cc is odd: positive eta + return int(cc / 2) * TOWER_IN_PHI * CRYSTALS_IN_TOWER_PHI; + } else { + // if cc is even, the bottom left corner is further in phi, hence the +4 and -1 + return (((int(cc / 2) * TOWER_IN_PHI) + 4) * CRYSTALS_IN_TOWER_PHI) - 1; + } + } + + // Towers: Go from real (eta, phi) to tower absolute ID + + /* + * For a real eta, get the tower absolute Eta index (possible values are 0-33, since there + * are 34 towers in eta. (Adapted from getTower_absoluteEtaID) + */ + inline int getTower_absEtaID(float eta) { + float size_cell = 2 * ECAL_eta_range / n_towers_Eta; + int etaID = int((eta + ECAL_eta_range) / size_cell); + return etaID; + } + + /* + * Same as above, but for phi. + * Possible values range from 0-71 (Adapted from getTower_absolutePhiID) + */ + inline int getTower_absPhiID(float phi) { + float size_cell = 2 * M_PI / n_towers_Phi; + int phiID = int((phi + M_PI) / size_cell); + return phiID; + } + + // Towers: Go from firmware specifics (RCT card, tower number in link, and link number (all firmware convention)) + // to tower absolute ID. + + /* + * Get the global tower iEta (0-31) from the firmware card, tower number (0-16), and link (0-3). Respects the fact that + * in the firmware, negative eta cards are "rotated" (link 0, tower 0) starts in the "top right" corner if we + * look at a diagram of the barrel region. + */ + inline int getAbsID_iEta_fromFirmwareCardTowerLink(int nCard, int nTower, int nLink) { + // iEta only depends on the tower position in the link + (void)nCard; + (void)nLink; + if ((nCard % 2) == 1) { // if cc is odd (positive eta), e.g. nTower = 0 will correspond to absolute iEta ID 17. + return n_towers_per_link + nTower; + } else { // if cc is even (negative eta): e.g. nTower = 0 will correspond to absolute iEta ID 16. + return (16 - nTower); + } + } + + /* + * Get the global tower iPhi (0-71) from the firmware card, tower number (0-16), and link (0-3). + */ + inline int getAbsID_iPhi_fromFirmwareCardTowerLink(int nCard, int nTower, int nLink) { + // iPhi only depends on the card and link number + (void)nTower; + if ((nCard % 2) == 1) { // if cc is odd (positive eta), + // e.g. cc=3, link #2, global iPhi = int(3/2) * 4 + 2 = 6 + return (int(nCard / 2) * TOWER_IN_PHI) + nLink; + } else { // if cc is even (negative eta) + // e.g. cc=4, link #2, global iPhi = int(4/2) * 4 + (4 - 2 - 1) + // = 2*4 + 1 + // = 9 + // minus one is because TOWER_IN_PHI is 4 + return (int(nCard / 2) * TOWER_IN_PHI) + (TOWER_IN_PHI - nLink - 1); + } + } + + // Towers: Go from absolute ID, back to real eta and phi. + + /* + * From the tower absolute ID in eta (0-33), get the real eta of the tower center + * Same as getTowerEta_fromAbsoluteID in previous CMSSW emulator + */ + inline float getTowerEta_fromAbsID(int id) { + float size_cell = 2 * ECAL_eta_range / n_towers_Eta; + float eta = (id * size_cell) - ECAL_eta_range + 0.5 * size_cell; + return eta; + } + + /* + * From the tower absolute ID in phi (0-71), get the real phi of the tower center + * Same as getTowerPhi_fromAbsoluteID in previous CMSSW emulator + */ + inline float getTowerPhi_fromAbsID(int id) { + float size_cell = 2 * M_PI / n_towers_Phi; + float phi = (id * size_cell) - M_PI + 0.5 * size_cell; + return phi; + } + + /* + * Get the RCT card region that a crystal is in, given the "local" iEta of the crystal + * 0 is region closest to eta = 0. Regions 0, 1, 2, 3, 4 are in the barrel, Region 5 is in overlap + */ + inline int getRegionNumber(const int local_iEta) { + int no = int(local_iEta / (TOWER_IN_ETA * CRYSTALS_IN_TOWER_ETA)); + assert(no < 6); + return no; + } + + /*******************************************************************/ + /* RCT classes and structs */ + /*******************************************************************/ + + /* + * Represents one input HCAL or ECAL hit. + */ + class SimpleCaloHit { + private: + float pt_ = 0; + float energy_ = 0.; + ap_uint<10> et_uint_; + GlobalVector position_; // As opposed to GlobalPoint, so we can add them (for weighted average) + HcalDetId id_hcal_; + EBDetId id_; + + public: + // tool functions + inline void setPt() { pt_ = (position_.mag2() > 0) ? energy_ * sin(position_.theta()) : 0; }; + inline void setEnergy(float et) { energy_ = et / sin(position_.theta()); }; + inline void setEt_uint(ap_uint<10> et_uint) { et_uint_ = et_uint; } + inline void setPosition(const GlobalVector& pos) { position_ = pos; }; + inline void setIdHcal(const HcalDetId& idhcal) { id_hcal_ = idhcal; }; + inline void setId(const EBDetId& id) { id_ = id; }; + + inline float pt() const { return pt_; }; + inline float energy() const { return energy_; }; + inline ap_uint<10> et_uint() const { return et_uint_; }; + inline const GlobalVector& position() const { return position_; }; + inline const EBDetId& id() const { return id_; }; + + /* + * Get crystal's iEta from real eta. (identical to getCrystal_etaID in L1EGammaCrystalsEmulatorProducer.cc) + * This "global" iEta ranges from 0 to (33*5) since there are 34 towers in eta in the full detector, + * each with five crystals in eta. + */ + int crystaliEta(void) const { + float size_cell = 2 * ECAL_eta_range / (CRYSTALS_IN_TOWER_ETA * n_towers_Eta); + int iEta = int((position().eta() + ECAL_eta_range) / size_cell); + return iEta; + } + + /* + * Get crystal's iPhi from real phi. (identical to getCrystal_phiID in L1EGammaCrystalsEmulatorProducer.cc) + * This "global" iPhi ranges from 0 to (71*5) since there are 72 towers in phi in the full detector, each with five crystals in eta. + */ + int crystaliPhi(void) const { + float phi = position().phi(); + float size_cell = 2 * M_PI / (CRYSTALS_IN_TOWER_PHI * n_towers_Phi); + int iPhi = int((phi + M_PI) / size_cell); + return iPhi; + } + + /* + * Check if it falls within the boundary of a card. + */ + bool isInCard(int cc) const { + return (crystaliPhi() <= getCard_iPhiMax(cc) && crystaliPhi() >= getCard_iPhiMin(cc) && + crystaliEta() <= getCard_iEtaMax(cc) && crystaliEta() >= getCard_iEtaMin(cc)); + }; + + /* + * For a crystal with real eta, and falling in card cc, get its local iEta + * relative to the bottom left corner of the card (possible local iEta ranges from 0 to 17 * 5, + * since in one card, there are 17 towers in eta, each with 5 crystals in eta. + */ + int crystalLocaliEta(int cc) const { return abs(getCard_refCrystal_iEta(cc) - crystaliEta()); } + + /* + * Same as above, but for iPhi (possible local iPhi ranges from 0 to (3*5), since in one card, + * there are 4 towers in phi, each with 5 crystals in phi. + */ + int crystalLocaliPhi(int cc) const { return abs(getCard_refCrystal_iPhi(cc) - crystaliPhi()); } + + /* + * Print hit info + */ + void printHitInfo(std::string description = "") const { + std::cout << "[printHitInfo]: [" << description << "]" + << " hit with energy " << pt() << " at eta " << position().eta() << ", phi " << position().phi() + << std::endl; + } + }; + + /*******************************************************************/ + + /* + * linkECAL class: represents one ECAL link (one tower: 5x5 crystals) + */ + + class linkECAL { + private: + ap_uint<10> crystalE[CRYSTALS_IN_TOWER_ETA][CRYSTALS_IN_TOWER_PHI]; + + public: + // constructor + linkECAL() {} + + // Set members + inline void zeroOut() { // zero out the crystalE array + for (int i = 0; i < CRYSTALS_IN_TOWER_ETA; i++) { + for (int j = 0; j < CRYSTALS_IN_TOWER_PHI; j++) { + crystalE[i][j] = 0; + } + } + }; + inline void setCrystalE(int iEta, int iPhi, ap_uint<10> energy) { + assert(iEta < CRYSTALS_IN_TOWER_ETA); + assert(iPhi < CRYSTALS_IN_TOWER_PHI); + crystalE[iEta][iPhi] = energy; + }; + inline void addCrystalE(int iEta, int iPhi, ap_uint<10> energy) { + assert(iEta < CRYSTALS_IN_TOWER_ETA); + assert(iPhi < CRYSTALS_IN_TOWER_PHI); + crystalE[iEta][iPhi] += energy; + }; + + // Access members + inline ap_uint<10> getCrystalE(int iEta, int iPhi) { + assert(iEta < 5); + assert(iPhi < 5); + return crystalE[iEta][iPhi]; + }; + }; + + /*******************************************************************/ + + /* + * region3x4 class: represents one 3x4 ECAL region. The region stores no + * information about which card it is located in. + * idx: 0-4. Region 0 is the one closest to eta = 0, counting outwards in eta + */ + + class region3x4 { + private: + int idx_ = -1; + linkECAL linksECAL[TOWER_IN_ETA][TOWER_IN_PHI]; // 3x4 in towers + + public: + // constructor + region3x4() { idx_ = -1; } + + // copy constructor + region3x4(const region3x4& other) { + idx_ = other.idx_; + for (int i = 0; i < TOWER_IN_ETA; i++) { + for (int j = 0; j < TOWER_IN_PHI; j++) { + linksECAL[i][j] = other.linksECAL[i][j]; + } + } + } + + // overload operator= to use copy constructor + region3x4 operator=(const region3x4& other) { + const region3x4& newRegion(other); + return newRegion; + }; + + // set members + inline void zeroOut() { + for (int i = 0; i < TOWER_IN_ETA; i++) { + for (int j = 0; j < TOWER_IN_PHI; j++) { + linksECAL[i][j].zeroOut(); + } + } + }; + inline void setIdx(int idx) { idx_ = idx; }; + + // get members + inline float getIdx() const { return idx_; }; + inline linkECAL& getLinkECAL(int iEta, int iPhi) { return linksECAL[iEta][iPhi]; }; + }; + + /*******************************************************************/ + + /* + * towerHCAL class: represents one HCAL tower + */ + + class towerHCAL { + private: + ap_uint<10> et; + ap_uint<6> fb; + + public: + // constructor + towerHCAL() { + et = 0; + fb = 0; + }; + + // copy constructor + towerHCAL(const towerHCAL& other) { + et = other.et; + fb = other.fb; + }; + + // set members + inline void zeroOut() { + et = 0; + fb = 0; + }; + inline void addEt(ap_uint<10> newEt) { et += newEt; }; + + // get members + inline ap_uint<10> getEt() { return et; }; + }; + + /*******************************************************************/ + + /* + * towers3x4 class: represents 3x4 array of HCAL towers. idx = 0, 1, ... 4 are the barrel gion + */ + + class towers3x4 { + private: + int idx_ = -1; + towerHCAL towersHCAL[TOWER_IN_ETA][TOWER_IN_PHI]; // 3x4 in towers + + public: + // constructor + towers3x4() { idx_ = -1; }; + + // copy constructor + towers3x4(const towers3x4& other) { + idx_ = other.idx_; + for (int i = 0; i < TOWER_IN_ETA; i++) { + for (int j = 0; j < TOWER_IN_PHI; j++) { + towersHCAL[i][j] = other.towersHCAL[i][j]; + } + }; + }; + + // set members + inline void zeroOut() { + for (int i = 0; i < TOWER_IN_ETA; i++) { + for (int j = 0; j < TOWER_IN_PHI; j++) { + towersHCAL[i][j].zeroOut(); + } + } + }; + inline void setIdx(int idx) { idx_ = idx; }; + + // get members + inline float getIdx() const { return idx_; }; + inline towerHCAL& getTowerHCAL(int iEta, int iPhi) { return towersHCAL[iEta][iPhi]; }; + }; + + /*******************************************************************/ + + /* + * card class: represents one RCT card. Each card has five 3x4 regions and one 2x4 region, + * which is represented by a 3x4 region with its third row zero'd out. + * idx 0-35: odd values of cardIdx span eta = 0 to eta = 1.41 + * even values of cardIdx span eta = -1.41 to eta = 0 + * The realEta and realPhi arrays store the (eta, phi) of the center of the towers. + */ + + class card { + private: + int idx_ = -1; + region3x4 card3x4Regions[N_REGIONS_PER_CARD]; + towers3x4 card3x4Towers[N_REGIONS_PER_CARD]; + + public: + // constructor + card() { + idx_ = -1; + for (int i = 0; i < N_REGIONS_PER_CARD; i++) { + card3x4Regions[i].setIdx(i); + card3x4Regions[i].zeroOut(); + card3x4Towers[i].setIdx(i); + card3x4Towers[i].zeroOut(); + } + }; + + // copy constructor + card(const card& other) { + idx_ = other.idx_; + for (int i = 0; i < N_REGIONS_PER_CARD; i++) { + card3x4Regions[i] = other.card3x4Regions[i]; + card3x4Towers[i] = other.card3x4Towers[i]; + } + }; + + // overload operator= to use copy constructor + card operator=(const card& other) { + const card& newCard(other); + return newCard; + }; + + // set members + inline void setIdx(int idx) { idx_ = idx; }; + inline void zeroOut() { + for (int i = 0; i < N_REGIONS_PER_CARD; i++) { + card3x4Regions[i].zeroOut(); + card3x4Towers[i].zeroOut(); + }; + }; + + // get members + inline float getIdx() const { return idx_; }; + inline region3x4& getRegion3x4(int idx) { + assert(idx < N_REGIONS_PER_CARD); + return card3x4Regions[idx]; + } + inline towers3x4& getTowers3x4(int idx) { + assert(idx < N_REGIONS_PER_CARD); + return card3x4Towers[idx]; + } + }; + + /*******************************************************************/ + + /* + * Crystal class for RCT + */ + + class crystal { + public: + ap_uint<10> energy; + + crystal() { + energy = 0; + // timing = 0; + } + + crystal(ap_uint<10> energy) { // To-do: add timing information + this->energy = energy; + // this->timing = 0; + } + + crystal& operator=(const crystal& rhs) { + energy = rhs.energy; + // timing = rhs.timing; + return *this; + } + }; + + /* + * crystalMax class for RCT + */ + class crystalMax { + public: + ap_uint<10> energy; + uint8_t phiMax; + uint8_t etaMax; + + crystalMax() { + energy = 0; + phiMax = 0; + etaMax = 0; + } + + crystalMax& operator=(const crystalMax& rhs) { + energy = rhs.energy; + phiMax = rhs.phiMax; + etaMax = rhs.etaMax; + return *this; + } + }; + + class ecaltp_t { + public: + ap_uint<10> energy; + ap_uint<5> phi; + ap_uint<5> eta; + }; + + class etaStrip_t { + public: + ecaltp_t cr0; + ecaltp_t cr1; + ecaltp_t cr2; + ecaltp_t cr3; + ecaltp_t cr4; + ecaltp_t cr5; + ecaltp_t cr6; + ecaltp_t cr7; + ecaltp_t cr8; + ecaltp_t cr9; + ecaltp_t cr10; + ecaltp_t cr11; + ecaltp_t cr12; + ecaltp_t cr13; + ecaltp_t cr14; + ecaltp_t cr15; + ecaltp_t cr16; + ecaltp_t cr17; + ecaltp_t cr18; + ecaltp_t cr19; + }; + + class ecalRegion_t { + public: + etaStrip_t etaStrip0; + etaStrip_t etaStrip1; + etaStrip_t etaStrip2; + etaStrip_t etaStrip3; + etaStrip_t etaStrip4; + etaStrip_t etaStrip5; + etaStrip_t etaStrip6; + etaStrip_t etaStrip7; + etaStrip_t etaStrip8; + etaStrip_t etaStrip9; + etaStrip_t etaStrip10; + etaStrip_t etaStrip11; + etaStrip_t etaStrip12; + etaStrip_t etaStrip13; + etaStrip_t etaStrip14; + }; + + class etaStripPeak_t { + public: + ecaltp_t pk0; + ecaltp_t pk1; + ecaltp_t pk2; + ecaltp_t pk3; + ecaltp_t pk4; + ecaltp_t pk5; + ecaltp_t pk6; + ecaltp_t pk7; + ecaltp_t pk8; + ecaltp_t pk9; + ecaltp_t pk10; + ecaltp_t pk11; + ecaltp_t pk12; + ecaltp_t pk13; + ecaltp_t pk14; + }; + + class tower_t { + public: + ap_uint<16> data; + + tower_t() { data = 0; } + tower_t& operator=(const tower_t& rhs) { + data = rhs.data; + return *this; + } + + tower_t(ap_uint<12> et, ap_uint<4> hoe) { data = (et) | (((ap_uint<16>)hoe) << 12); } + + ap_uint<12> et() { return (data & 0xFFF); } + ap_uint<4> hoe() { return ((data >> 12) & 0xF); } + + float getEt() { return (float)et() * ECAL_LSB; } + + operator uint16_t() { return (uint16_t)data; } + + // Only for ECAL towers! Apply calibration and modify the et() value. + void applyCalibration(float factor) { + // Get the new pT as a float + float newEt = getEt() * factor; + + // Convert the new pT to an unsigned int (16 bits so we can take the logical OR with the bit mask later) + ap_uint<16> newEt_uint = (ap_uint<16>)(int)(newEt * 8.0); + // Make sure the first four bits are zero + newEt_uint = (newEt_uint & 0x0FFF); + + // Modify 'data' + ap_uint<16> bitMask = 0xF000; // last twelve digits are zero + data = (data & bitMask); // zero out the last twelve digits + data = (data | newEt_uint); // write in the new ET + } + /* + * For towers: Calculate H/E ratio given the ECAL and HCAL energies and modify the hoe() value. + */ + void getHoverE(ap_uint<12> ECAL, ap_uint<12> HCAL_inHcalConvention) { + // Convert HCAL ET to ECAL ET convention + ap_uint<12> HCAL = convertHcalETtoEcalET(HCAL_inHcalConvention); + ap_uint<4> hoeOut; + ap_uint<1> hoeLSB = 0; + ap_uint<4> hoe = 0; + ap_uint<12> A; + ap_uint<12> B; + + A = (ECAL > HCAL) ? ECAL : HCAL; + B = (ECAL > HCAL) ? HCAL : ECAL; + + if (ECAL == 0 || HCAL == 0 || HCAL >= ECAL) + hoeLSB = 0; + else + hoeLSB = 1; + if (A > B) { + if (A > 2 * B) + hoe = 0x1; + if (A > 4 * B) + hoe = 0x2; + if (A > 8 * B) + hoe = 0x3; + if (A > 16 * B) + hoe = 0x4; + if (A > 32 * B) + hoe = 0x5; + if (A > 64 * B) + hoe = 0x6; + if (A > 128 * B) + hoe = 0x7; + } + hoeOut = hoeLSB | (hoe << 1); + ap_uint<16> hoeOutLong = + ((((ap_uint<16>)hoeOut) << 12) | 0x0000); // e.g. 0b ____ 0000 0000 0000 where ___ are the hoe digits + // Take the logical OR to preserve the saturation and tower ET bits + ap_uint<16> bitMask = 0x0FFF; // 0000 1111 1111 1111 : zero-out the HoE bits + data = (data & bitMask); // zero-out the HoE bits + data = (data | hoeOutLong); // write in the new HoE bits + } + }; + + class clusterInfo { + public: + ap_uint<10> seedEnergy; + ap_uint<15> energy; + ap_uint<15> et5x5; + ap_uint<15> et2x5; + ap_uint<5> phiMax; + ap_uint<5> etaMax; + ap_uint<2> brems; + + clusterInfo() { + seedEnergy = 0; + energy = 0; + et5x5 = 0; + et2x5 = 0; + phiMax = 0; + etaMax = 0; + brems = 0; + } + + clusterInfo& operator=(const clusterInfo& rhs) { + seedEnergy = rhs.seedEnergy; + energy = rhs.energy; + et5x5 = rhs.et5x5; + et2x5 = rhs.et2x5; + phiMax = rhs.phiMax; + etaMax = rhs.etaMax; + brems = rhs.brems; + return *this; + } + }; + + //--------------------------------------------------------// + + /* + * Cluster class for RCT. + */ + class Cluster { + public: + ap_uint<28> data; + int regionIdx; // region is 0 through 4 in barrel, 5 for overlap in barrel+endcap + float calib; // ECAL energy calibration factor + ap_uint<2> brems; // brems flag + ap_uint<15> et5x5; // et5x5 sum in towers around cluster + ap_uint<15> et2x5; // et2x5 sum in towers around cluster + bool is_ss; // shower shape flag + bool is_looseTkss; // loose Tk shower shape flag + bool is_iso; // isolation flag (not computed until GCT) + bool is_looseTkiso; // isolation flag (not computed until GCT) + + Cluster() { + data = 0; + regionIdx = -1; + calib = 1.0; + brems = 0; + et5x5 = 0; + et2x5 = 0; + is_ss = false; + is_looseTkss = false; + is_iso = false; + is_looseTkiso = false; + } + + Cluster(ap_uint<12> clusterEnergy, + ap_uint<5> towerEta, + ap_uint<2> towerPhi, + ap_uint<3> clusterEta, + ap_uint<3> clusterPhi, + ap_uint<3> satur, + ap_uint<15> clusterEt5x5 = 0, + ap_uint<15> clusterEt2x5 = 0, + ap_uint<2> clusterBrems = 0, + bool cluster_is_ss = false, + bool cluster_is_looseTkss = false, + bool cluster_is_iso = false, + bool cluster_is_looseTkiso = false, + int clusterRegionIdx = 0) { + data = (clusterEnergy) | (((ap_uint<32>)towerEta) << 12) | (((ap_uint<32>)towerPhi) << 17) | + (((ap_uint<32>)clusterEta) << 19) | (((ap_uint<32>)clusterPhi) << 22) | (((ap_uint<32>)satur) << 25); + regionIdx = clusterRegionIdx, et5x5 = clusterEt5x5; + et2x5 = clusterEt2x5; + brems = clusterBrems; + is_ss = cluster_is_ss; + is_looseTkss = cluster_is_looseTkss; + is_iso = cluster_is_iso; + is_looseTkiso = cluster_is_looseTkiso; + } + + Cluster& operator=(const Cluster& rhs) { + data = rhs.data; + regionIdx = rhs.regionIdx; + calib = rhs.calib; + brems = rhs.brems; + et5x5 = rhs.et5x5; + et2x5 = rhs.et2x5; + is_ss = rhs.is_ss; + is_looseTkss = rhs.is_looseTkss; + is_iso = rhs.is_iso; + is_looseTkiso = rhs.is_looseTkiso; + return *this; + } + + void setRegionIdx(int regIdx) { regionIdx = regIdx; } // Newly added + + ap_uint<12> clusterEnergy() const { return (data & 0xFFF); } + ap_uint<5> towerEta() const { return ((data >> 12) & 0x1F); } // goes from 0 to 3 (need region for full info) + ap_uint<2> towerPhi() const { return ((data >> 17) & 0x3); } + ap_uint<3> clusterEta() const { return ((data >> 19) & 0x7); } + ap_uint<3> clusterPhi() const { return ((data >> 22) & 0x7); } + ap_uint<3> satur() const { return ((data >> 25) & 0x7); } + ap_uint<15> uint_et2x5() const { return et2x5; } + ap_uint<15> uint_et5x5() const { return et5x5; } + + operator uint32_t() const { return (ap_uint<28>)data; } + int region() const { return regionIdx; } // Newly added + int getBrems() const { return (int)brems; } + float getCalib() const { return (float)calib; } + float getPt() const { return ((float)clusterEnergy() * ECAL_LSB); } // Return pT as a float + float getEt5x5() const { return ((float)et5x5 * ECAL_LSB); } // Return ET5x5 as a float + float getEt2x5() const { return ((float)et2x5 * ECAL_LSB); } // Return ET2x5 as a float + + int towerEtaInCard() { return ((int)(region() * TOWER_IN_ETA) + towerEta()); } + + bool getIsSS() { return is_ss; } + bool getIsLooseTkss() { return is_looseTkss; } + bool getIsIso() { return is_iso; } + bool getIsLooseTkIso() { return is_looseTkiso; } + + /* + * Apply calibration (float) to the pT in-place. + */ + void applyCalibration(float factor) { + float newPt = getPt() * factor; + // Convert the new pT to an unsigned int, 28 bits to take the logical OR with the mask + ap_uint<28> newPt_uint = (ap_uint<28>)(int)(newPt / ECAL_LSB); + // Make sure that the new pT only takes up the last twelve bits + newPt_uint = (newPt_uint & 0x0000FFF); + + // Modify 'data' + ap_uint<28> bitMask = 0xFFFF000; // last twelve digits are zero + data = (data & bitMask); // zero out the last twelve digits + data = (data | newPt_uint); // write in the new ET + } + + // Get Cluster crystal iEta from card number, region, tower eta, and cluster eta indices + const int crystaliEtaFromCardRegionInfo(int cc) { + int crystalEta_in_card = + ((region() * TOWER_IN_ETA * CRYSTALS_IN_TOWER_ETA) + (towerEta() * CRYSTALS_IN_TOWER_ETA) + clusterEta()); + if ((cc % 2) == 1) { + return (getCard_refCrystal_iEta(cc) + crystalEta_in_card); + } else { + // if card is even (negative eta) + return (getCard_refCrystal_iEta(cc) - crystalEta_in_card); + } + } + + // Get Cluster crystal iPhi from card number, region, tower eta, and cluster phi indices + const int crystaliPhiFromCardRegionInfo(int cc) { + int crystalPhi_in_card = (towerPhi() * CRYSTALS_IN_TOWER_PHI) + clusterPhi(); + if ((cc % 2) == 1) { + // if card is odd (positive eta) + return (getCard_refCrystal_iPhi(cc) + crystalPhi_in_card); + } else { + // if card is even (negative eta) + return (getCard_refCrystal_iPhi(cc) - crystalPhi_in_card); + } + } + + // Get real eta + const float realEta(int cc) { + float size_cell = 2 * ECAL_eta_range / (CRYSTALS_IN_TOWER_ETA * n_towers_Eta); + return crystaliEtaFromCardRegionInfo(cc) * size_cell - ECAL_eta_range + half_crystal_size; + } + + // Get real phi + const float realPhi(int cc) { + float size_cell = 2 * M_PI / (CRYSTALS_IN_TOWER_PHI * n_towers_Phi); + return crystaliPhiFromCardRegionInfo(cc) * size_cell - M_PI + half_crystal_size; + } + + // Print info + void printClusterInfo(int cc, std::string description = "") { + std::cout << "[Print Cluster class info:] [" << description << "]: " + << "card " << cc << ", " + << "et (float): " << getPt() << ", " + << "eta: " << realEta(cc) << ", " + << "phi: " << realPhi(cc) << std::endl; + } + }; + + /* + * Compare the ET of two clusters (pass this to std::sort to get clusters sorted in decreasing ET). + */ + inline bool compareClusterET(const Cluster& lhs, const Cluster& rhs) { + return (lhs.clusterEnergy() > rhs.clusterEnergy()); + } + + /*******************************************************************/ + /* RCT helper functions */ + /*******************************************************************/ + ecalRegion_t initStructure(crystal temporary[CRYSTAL_IN_ETA][CRYSTAL_IN_PHI]); + ecaltp_t bestOf2(const ecaltp_t ecaltp0, const ecaltp_t ecaltp1); + ecaltp_t getPeakBin20N(const etaStrip_t etaStrip); + crystalMax getPeakBin15N(const etaStripPeak_t etaStrip); + void getECALTowersEt(crystal tempX[CRYSTAL_IN_ETA][CRYSTAL_IN_PHI], ap_uint<12> towerEt[12]); + clusterInfo getClusterPosition(const ecalRegion_t ecalRegion); + Cluster packCluster(ap_uint<15>& clusterEt, ap_uint<5>& etaMax_t, ap_uint<5>& phiMax_t); + void removeClusterFromCrystal(crystal temp[CRYSTAL_IN_ETA][CRYSTAL_IN_PHI], + ap_uint<5> seed_eta, + ap_uint<5> seed_phi, + ap_uint<2> brems); + clusterInfo getBremsValuesPos(crystal tempX[CRYSTAL_IN_ETA][CRYSTAL_IN_PHI], + ap_uint<5> seed_eta, + ap_uint<5> seed_phi); + clusterInfo getBremsValuesNeg(crystal tempX[CRYSTAL_IN_ETA][CRYSTAL_IN_PHI], + ap_uint<5> seed_eta, + ap_uint<5> seed_phi); + clusterInfo getClusterValues(crystal tempX[CRYSTAL_IN_ETA][CRYSTAL_IN_PHI], ap_uint<5> seed_eta, ap_uint<5> seed_phi); + Cluster getClusterFromRegion3x4(crystal temp[CRYSTAL_IN_ETA][CRYSTAL_IN_PHI]); + void stitchClusterOverRegionBoundary(std::vector& cluster_list, int towerEtaUpper, int towerEtaLower, int cc); + + /*******************************************************************/ + /* Cluster flags */ + /*******************************************************************/ + inline bool passes_iso(float pt, float iso) { + bool is_iso = true; + if (pt > 130) + is_iso = true; + else if (pt < slideIsoPtThreshold) { + if (!((a0_80 - a1_80 * pt) > iso)) + is_iso = false; + } else { + if (iso > a0) + is_iso = false; + } + return is_iso; + } + + inline bool passes_looseTkiso(float pt, float iso) { + bool is_iso; + if (pt > 130) + is_iso = true; + else + is_iso = (b0 + b1 * std::exp(-b2 * pt) > iso); + return is_iso; + } + + inline bool passes_ss(float pt, float ss) { + bool is_ss; + if (pt > 130) + is_ss = true; + else + is_ss = ((c0_ss + c1_ss * std::exp(-c2_ss * pt)) <= ss); + return is_ss; + } + + inline bool passes_looseTkss(float pt, float ss) { + bool is_ss; + if (pt > 130) + is_ss = true; + else + is_ss = ((e0_looseTkss - e1_looseTkss * std::exp(-e2_looseTkss * pt)) <= ss); + return is_ss; + } + + /*******************************************************************/ + /* GCT classes. */ + /*******************************************************************/ + + class RCTcluster_t { + public: + ap_uint<12> et; + ap_uint<5> towEta; // goes from 0 to 17 (vs. class Cluster in the RCT emulator) + ap_uint<2> towPhi; + ap_uint<3> crEta; + ap_uint<3> crPhi; + + ap_uint<12> iso; + ap_uint<15> et2x5; + ap_uint<15> et5x5; + bool is_ss; + bool is_looseTkss; + bool is_iso; + bool is_looseTkiso; + ap_uint<2> brems; + + int nGCTCard; + }; + + class RCTtower_t { + public: + ap_uint<12> et; + ap_uint<4> hoe; + // For CMSSW outputs, not firmware + ap_uint<12> ecalEt; + ap_uint<12> hcalEt; + }; + + class RCTtoGCTfiber_t { + public: + RCTtower_t RCTtowers[N_RCTTOWERS_FIBER]; + RCTcluster_t RCTclusters[N_RCTCLUSTERS_FIBER]; + }; + + class RCTcard_t { + public: + RCTtoGCTfiber_t RCTtoGCTfiber[N_RCTGCT_FIBERS]; + }; + + class GCTcard_t { + public: + RCTcard_t RCTcardEtaPos[N_RCTCARDS_PHI]; + RCTcard_t RCTcardEtaNeg[N_RCTCARDS_PHI]; + }; + + class GCTcluster_t { + public: + bool isPositiveEta; // is cluster in positive eta side or not + ap_uint<12> et; + ap_uint<6> towEta; + ap_uint<7> towPhi; + ap_uint<3> crEta; + ap_uint<3> crPhi; + ap_uint<12> iso; + + ap_uint<15> et2x5; + ap_uint<15> et5x5; + bool is_ss; + bool is_looseTkss; + bool is_iso; + bool is_looseTkiso; + + unsigned int hoe; // not defined + unsigned int fb; // not defined + unsigned int timing; // not defined + ap_uint<2> + brems; // 0 if no brems applied, 1 or 2 if brems applied (one for + direction, one for - direction: check firmware) + + float relIso; // for analyzer only, not firmware + int nGCTCard; // for analyzer only, not firmware + + inline float etFloat() const { return ((float)et * ECAL_LSB); } // Return energy as a float + inline float isoFloat() const { return ((float)iso * ECAL_LSB); } // Return energy as a float + inline float et2x5Float() const { return ((float)et2x5 * ECAL_LSB); } // Return energy as a float + inline float et5x5Float() const { return ((float)et5x5 * ECAL_LSB); } // Return energy as a float + inline float relIsoFloat() const { return relIso; } // relIso is a float already + + inline int etInt() const { return et; } + inline int isoInt() const { return iso; } + + inline int standaloneWP() const { return (is_iso && is_ss); } + inline int looseL1TkMatchWP() const { return (is_looseTkiso && is_looseTkss); } + inline int photonWP() const { return 1; } // NOTE: NO PHOTON WP + + inline int passesShowerShape() const { return is_ss; } + + /* + * Initialize from RCTcluster_t. + */ + void initFromRCTCluster(int iRCTcardIndex, bool isPosEta, const RCTcluster_t& rctCluster) { + isPositiveEta = isPosEta; + + et = rctCluster.et; + towEta = rctCluster.towEta; + if (isPositiveEta) { + towPhi = rctCluster.towPhi + (iRCTcardIndex * 4); + } else { + towPhi = (3 - rctCluster.towPhi) + (iRCTcardIndex * 4); + } + crEta = rctCluster.crEta; + if (isPositiveEta) { + crPhi = rctCluster.crPhi; + } else { + crPhi = (4 - rctCluster.crPhi); + } + et2x5 = rctCluster.et2x5; + et5x5 = rctCluster.et5x5; + is_ss = rctCluster.is_ss; + is_looseTkss = rctCluster.is_looseTkss; + iso = 0; // initialize: no info from RCT, so set it to null + relIso = 0; // initialize: no info from RCT, so set it to null + is_iso = false; // initialize: no info from RCT, so set it to false + is_looseTkiso = false; // initialize: no info from RCT, so set it to false + hoe = 0; // initialize: no info from RCT, so set it to null + fb = 0; // initialize: no info from RCT, so set it to null + timing = 0; // initialize: no info from RCT, so set it to null + brems = rctCluster.brems; + nGCTCard = rctCluster.nGCTCard; + } + + /* + * Get GCT cluster c's iEta (global iEta convention), (0-33*5). Called in realEta(). + */ + int globalClusteriEta(void) const { + // First get the "iEta/iPhi" in the GCT card. i.e. in the diagram where the barrel is split up into three GCT cards, + // (iEta, iPhi) = (0, 0) is the top left corner of the GCT card. + int iEta_in_gctCard; + if (!isPositiveEta) { + // Negative eta: c.towEta and c.crEta count outwards from the real eta = 0 center line, so to convert to the barrel diagram global iEta + // (global iEta = 0 from LHS of page), do (17*5 - 1) minus the GCT value. + // e.g. If in GCT, a negative card's cluster had iEta = 84, this would be global iEta = 0. + iEta_in_gctCard = + ((N_GCTTOWERS_FIBER * CRYSTALS_IN_TOWER_ETA - 1) - ((towEta * CRYSTALS_IN_TOWER_ETA) + crEta)); + } else { + // c.towEta and c.crEta count outwards from the real eta = 0 center line, so for positive + // eta we need to add the 17*5 offset so that positive eta 0+epsilon starts at 17*5. + // e.g. If in GCT, a positive card's cluster had iEta = 0, this would be global iEta = 85. + // e.g. If in GCT, a positive card's cluster had iEta = 84, this would be global iEta = 169. + iEta_in_gctCard = ((N_GCTTOWERS_FIBER * CRYSTALS_IN_TOWER_ETA) + ((towEta * CRYSTALS_IN_TOWER_ETA) + crEta)); + } + // Last, convert to the global iEta/iPhi in the barrel region. For eta these two indices are the same (but this is not true for phi). + int iEta_in_barrel = iEta_in_gctCard; + return iEta_in_barrel; + } + + /* + * Get GCT cluster iPhi (global convention, (0-71*5)). Called in realPhi(). + * Use with getPhi_fromCrystaliPhi from Phase2L1RCT.h to convert from GCT cluster to real phi. + * If returnGlobalGCTiPhi is true (Default value) then return the iPhi in the entire GCT barrel. Otherwise + * just return the iPhi in the current GCT card. + */ + int globalClusteriPhi(bool returnGlobalGCTiPhi = true) const { + int iPhi_in_gctCard = ((towPhi * CRYSTALS_IN_TOWER_PHI) + crPhi); + // If we should return the global GCT iPhi, get the iPhi offset due to the number of the GCT card + int iPhi_card_offset = 0; + if (returnGlobalGCTiPhi) { + if (nGCTCard == 0) + iPhi_card_offset = GCTCARD_0_TOWER_IPHI_OFFSET * CRYSTALS_IN_TOWER_PHI; + else if (nGCTCard == 1) + iPhi_card_offset = GCTCARD_1_TOWER_IPHI_OFFSET * CRYSTALS_IN_TOWER_PHI; + else if (nGCTCard == 2) + iPhi_card_offset = GCTCARD_2_TOWER_IPHI_OFFSET * CRYSTALS_IN_TOWER_PHI; + } + // Detector wraps around in phi: modulo number of crystals in phi (n_towers_Phi = 72) + int iPhi_in_barrel = (iPhi_card_offset + iPhi_in_gctCard) % (n_towers_Phi * CRYSTALS_IN_TOWER_PHI); + return iPhi_in_barrel; + } + + /* + * Each cluster falls in a tower: get this tower iEta in the GCT card (same as global) given the cluster's info. + */ + int globalToweriEta(void) const { return (int)(globalClusteriEta() / 5); } + + /* + * Each cluster falls in a tower: get this tower iPhi in global given the cluster's info. + */ + int globalToweriPhi(void) const { + bool getGlobalIndex = true; + return (int)(globalClusteriPhi(getGlobalIndex) / 5); + } + + /* + * Get tower iPhi IN GCT CARD + */ + int inCardToweriPhi(void) const { + bool getGlobalIndex = false; + return (int)(globalClusteriPhi(getGlobalIndex) / 5); + } + + /* + * Get tower iEta IN GCT CARD (conveniently the same as global eta) + */ + int inCardToweriEta(void) const { return (int)(globalClusteriEta() / 5); } + + /* + * Get GCT cluster's real eta from global iEta (0-33*5). + */ + float realEta(void) const { + float size_cell = 2 * ECAL_eta_range / (CRYSTALS_IN_TOWER_ETA * n_towers_Eta); + return globalClusteriEta() * size_cell - ECAL_eta_range + half_crystal_size; + } + + /* + * Get GCT cluster's real eta from global iPhi (0-71*5). + */ + float realPhi(void) const { + float size_cell = 2 * M_PI / (CRYSTALS_IN_TOWER_PHI * n_towers_Phi); + return globalClusteriPhi() * size_cell - M_PI + half_crystal_size; + } + + /* + * Return the 4-vector. + */ + reco::Candidate::PolarLorentzVector p4(void) const { + return reco::Candidate::PolarLorentzVector(etFloat(), realEta(), realPhi(), 0.); + } + + /* + * Compute relative isolation and set its flags in-place, assuming that the isolation is already computed. + */ + void setRelIsoAndFlags(void) { + float relativeIsolationAsFloat = 0; + if (et > 0) { + relativeIsolationAsFloat = (isoFloat() / etFloat()); + } else { + relativeIsolationAsFloat = 0; + } + relIso = relativeIsolationAsFloat; + is_iso = passes_iso(etFloat(), relIso); + is_looseTkiso = passes_looseTkiso(isoFloat(), relIso); + } + + /* + * Create a l1tp2::CaloCrystalCluster object. + */ + l1tp2::CaloCrystalCluster createCaloCrystalCluster(void) const { + l1tp2::CaloCrystalCluster caloCrystalCluster( + p4(), + etFloat(), // convert to float + 0, // supposed to be H over E in the constructor but we do not store/use this information + relIsoFloat(), // for consistency with the old emulator, in this field save (iso energy sum)/(cluster energy) + 0, // DetId seedCrystal + 0, // puCorrPt + 0, // brems: not propagated to output (0, 1, or 2 as computed in firmware) + 0, // et2x2 (not calculated) + et2x5Float(), // et2x5 (save float) + 0, // et3x5 (not calculated) + et5x5Float(), // et5x5 (save float) + standaloneWP(), // standalone WP + false, // electronWP98: not computed + false, // photonWP80: not computed + false, // electronWP90: not computed + false, // looseL1TkMatchWP: not computed + false // stage2effMatch: not computed + ); + + // Flags + std::map params; + params["standaloneWP_showerShape"] = is_ss; + params["standaloneWP_isolation"] = is_iso; + params["trkMatchWP_showerShape"] = is_looseTkss; + params["trkMatchWP_isolation"] = is_looseTkiso; + caloCrystalCluster.setExperimentalParams(params); + + return caloCrystalCluster; + } + + /* + * Create a l1t::EGamma object. + */ + l1t::EGamma createL1TEGamma(void) const { + // n.b. No photon WP, photonWP() always returns true + int quality = + (standaloneWP() * std::pow(2, 0)) + (looseL1TkMatchWP() * std::pow(2, 1)) + (photonWP() * std::pow(2, 2)); + + // The constructor zeros out everyhing except the p4() + l1t::EGamma eg = l1t::EGamma(p4(), etInt(), globalClusteriEta(), globalClusteriPhi(), quality, isoInt()); + + // Write in fields that were zerod out + eg.setRawEt(etInt()); // et as int + eg.setTowerIEta(globalToweriEta()); // 0-33 in barrel + eg.setTowerIPhi(globalToweriPhi()); // 0-71 in barrel + eg.setIsoEt(isoInt()); // raw isolation sum as int + eg.setShape(passesShowerShape()); // write shower shape flag to this field + return eg; + } + + /* + * Create a l1tp2::DigitizedClusterCorrelator object, with corrTowPhiOffset specifying the offset necessary to correct the tower phi to the region + * unique to each GCT card. + */ + l1tp2::DigitizedClusterCorrelator createDigitizedClusterCorrelator(const int corrTowPhiOffset) const { + return l1tp2::DigitizedClusterCorrelator( + etFloat(), // technically we are just multiplying and then dividing again by the LSB + towEta, + towPhi - corrTowPhiOffset, + crEta, + crPhi, + hoe, + is_iso, + fb, + timing, + is_ss, + brems, + nGCTCard); + } + + /* + * Create a l1tp2::DigitizedClusterGT object + */ + l1tp2::DigitizedClusterGT createDigitizedClusterGT(bool isValid) const { + // Constructor arguments take phi, then eta + return l1tp2::DigitizedClusterGT(isValid, etFloat(), realPhi(), realEta()); + } + + /* + * Print GCT cluster information. + */ + void printGCTClusterInfo(std::string description = "") { + std::cout << "[PrintGCTClusterInfo:] [" << description << "]: " + << "et (float): " << etFloat() << ", " + << "eta: " << realEta() << ", " + << "phi: " << realPhi() << ", " + << "isPositiveEta " << isPositiveEta << ", " + << "towEta: " << towEta << ", " + << "towPhi: " << towPhi << ", " + << "crEta: " << crEta << ", " + << "crPhi: " << crPhi << ", " + << "iso (GeV): " << isoFloat() << ", " + << "rel iso (unitless float): " << relIsoFloat() << ", " + << "et2x5 (GeV): " << et2x5Float() << ", " + << "et5x5 (GeV): " << et5x5Float() << ", " + << "is_ss: " << is_ss << ", " + << "is_looseTkss" << is_looseTkss << ", " + << "is_iso: " << is_iso << ", " + << "is_looseTkiso: " << is_looseTkiso << ", " + << "brems: " << brems << std::endl; + } + }; + + class GCTtower_t { + public: + ap_uint<12> et; + ap_uint<4> hoe; + ap_uint<2> fb; // not defined yet in emulator + // For CMSSW outputs, not firmware + ap_uint<12> ecalEt; + ap_uint<12> hcalEt; + + inline float totalEtFloat() const { + return ((float)et * ECAL_LSB); + } // Return total energy as a float (assuming the energy uses the ECAL LSB convention) + inline float ecalEtFloat() const { return ((float)ecalEt * ECAL_LSB); } // Return ECAL energy as a float + inline float hcalEtFloat() const { + return ((float)hcalEt * HCAL_LSB); + } // Return HCAL energy as a float, use HCAL LSB + + /* + * Initialize from RCTtower_t. + */ + void initFromRCTTower(const RCTtower_t& rctTower) { + et = rctTower.et; + hoe = rctTower.hoe; + ecalEt = rctTower.ecalEt; + hcalEt = rctTower.hcalEt; + } + + /* + * Correlator fiber convention -> Global GCT convention + * Get tower's global (iEta) from the GCTCorrFiber index [0, 64) and the tower's postion in the fiber [0, 17). + * Recall that GCTCorrFiber is [0, 32) for negative eta and [32, 64) for positive eta. The tower's position in the fiber [0, 17) + * always counts outwards from real eta = 0. + * Use in conjunction with (float) getTowerEta_fromAbsID(int id) from Phase2L1RCT.h to get a tower's real eta. + */ + int globalToweriEta(unsigned int nGCTCard, unsigned int gctCorrFiberIdx, unsigned int posInFiber) { + (void)nGCTCard; // not needed + bool isTowerInPositiveEta = (gctCorrFiberIdx < N_GCTPOSITIVE_FIBERS); // N_GCTPOSITIVE_FIBERS = 32 + int global_toweriEta; + if (isTowerInPositiveEta) { + global_toweriEta = (N_GCTTOWERS_FIBER + posInFiber); // N_GCTTOWERS_FIBER = 17 + } else { + // e.g. For negative eta, posInFiber = 0 is at real eta = 0, and global tower iEta is 17 - 1 - 0 = 16 + // posInFiber = 16 is at real eta = -1.4841, and global tower iEta is 17 - 1 - 16 = 0. + global_toweriEta = (N_GCTTOWERS_FIBER - 1 - posInFiber); + } + return global_toweriEta; + } + + /* + * Correlator fiber convention -> Global GCT convention + * Get tower's global (iPhi) from the GCT card number (0, 1, 2), and the GCTCorrFiber index [0, 64). + * GCTCorrFiber is [0, 32) for negative eta and [32, 64) for positive eta. In the phi direction, fiber index #0 has the same phi + * as fiber index #32, so only the (fiber index modulo 32) matters for the phi direction. + * The tower's position in the fiber doesn't matter; in each fiber the phi is the same. + * Use in conjunction with (float) getTowerPhi_fromAbsID(int id) from Phase2L1RCT.h to get a tower's real phi. + */ + int globalToweriPhi(unsigned int nGCTCard, unsigned int gctCorrFiberIdx, unsigned int posInFiber) { + (void)posInFiber; // not needed + unsigned int effectiveFiberIdx = (gctCorrFiberIdx % N_GCTPOSITIVE_FIBERS); // N_GCTPOSITIVE_FIBERS = 32 + int toweriPhi_card_offset = 0; + if (nGCTCard == 0) + toweriPhi_card_offset = GCTCARD_0_TOWER_IPHI_OFFSET; + else if (nGCTCard == 1) + toweriPhi_card_offset = GCTCARD_1_TOWER_IPHI_OFFSET; + else if (nGCTCard == 2) + toweriPhi_card_offset = GCTCARD_2_TOWER_IPHI_OFFSET; + + // as explained above, effectiveFiberIdx is [0, 32). n_towers_Phi = 72: + int global_tower_iPhi = (toweriPhi_card_offset + effectiveFiberIdx) % (n_towers_Phi); + return global_tower_iPhi; + } + + /* + * For fulltowers that are indexed by GCT local index: eta + */ + int globalToweriEtaFromGCTcardiEta(int gctCard_tower_iEta) { + int global_iEta = gctCard_tower_iEta; + return global_iEta; + } + + /* + * For fulltowers that are indexed by GCT local index: phi. Very similar to globalToweriPhi function but keep them separate for clarity. + */ + int globalToweriPhiFromGCTcardiPhi(unsigned int nGCTCard, int gctCard_tower_iPhi) { + assert(nGCTCard <= 2); // Make sure the card number is valid + int toweriPhi_card_offset = 0; + if (nGCTCard == 0) + toweriPhi_card_offset = GCTCARD_0_TOWER_IPHI_OFFSET; + else if (nGCTCard == 1) + toweriPhi_card_offset = GCTCARD_1_TOWER_IPHI_OFFSET; + else if (nGCTCard == 2) + toweriPhi_card_offset = GCTCARD_2_TOWER_IPHI_OFFSET; + + int global_iPhi = (toweriPhi_card_offset + gctCard_tower_iPhi) % (n_towers_Phi); // n_towers_Phi = 72 + return global_iPhi; + } + + /* + * Method to create a l1tp2::CaloTower object from the fiber and tower-in-fiber indices. + * nGCTCard (0, 1, 2) is needed to determine the absolute eta/phi. + * iFiber and iTowerInFiber are the indices of the tower in the card, e.g. GCTinternal.GCTCorrFiber[iFiber].GCTtowers[iTowerInFiber] + */ + l1tp2::CaloTower createCaloTowerFromFiberIdx(int nGCTCard, int iFiber, int iTowerInFiber) { + l1tp2::CaloTower l1CaloTower; + l1CaloTower.setEcalTowerEt(ecalEtFloat()); // float: ECAL divide by 8.0 + l1CaloTower.setHcalTowerEt(hcalEtFloat()); // float: HCAL multiply by LSB + int global_tower_iEta = globalToweriEta(nGCTCard, iFiber, iTowerInFiber); + int global_tower_iPhi = globalToweriPhi(nGCTCard, iFiber, iTowerInFiber); + l1CaloTower.setTowerIEta(global_tower_iEta); + l1CaloTower.setTowerIPhi(global_tower_iPhi); + l1CaloTower.setTowerEta(getTowerEta_fromAbsID(global_tower_iEta)); + l1CaloTower.setTowerPhi(getTowerPhi_fromAbsID(global_tower_iPhi)); + return l1CaloTower; + } + + /* + * Method to create a l1tp2::CaloTower object from the global tower ieta and iphi. + */ + l1tp2::CaloTower createFullTowerFromCardIdx(int nGCTCard, int gctCard_tower_iEta, int gctCard_tower_iPhi) { + l1tp2::CaloTower l1CaloTower; + // Store total Et (HCAL+ECAL) in the ECAL Et member + l1CaloTower.setEcalTowerEt(totalEtFloat()); + int global_tower_iEta = globalToweriEtaFromGCTcardiEta(gctCard_tower_iEta); + int global_tower_iPhi = globalToweriPhiFromGCTcardiPhi(nGCTCard, gctCard_tower_iPhi); + l1CaloTower.setTowerIEta(global_tower_iEta); + l1CaloTower.setTowerIPhi(global_tower_iPhi); + l1CaloTower.setTowerEta(getTowerEta_fromAbsID(global_tower_iEta)); + l1CaloTower.setTowerPhi(getTowerPhi_fromAbsID(global_tower_iPhi)); + return l1CaloTower; + } + + /* + * Method to create a l1tp2::DigitizedTowerCorrelator, from the GCT card number, the fiber index *inside the GCT card* (excluding overlap region), + * and the index of the tower inside the fiber. + */ + l1tp2::DigitizedTowerCorrelator createDigitizedTowerCorrelator(unsigned int indexCard, + unsigned int indexFiber, + unsigned int indexTower) { + return l1tp2::DigitizedTowerCorrelator(totalEtFloat(), hoe, fb, indexCard, indexFiber, indexTower); + } + + /* + * Print GCTtower_t tower information. + */ + void printGCTTowerInfoFromGlobalIdx(int global_tower_iEta, int global_tower_iPhi, std::string description = "") { + std::cout << "[Print GCTtower_t class info from global idx:] [" << description << "]: " + << "total et (float): " << totalEtFloat() << ", " + << "ecal et (float): " << ecalEtFloat() << ", " + << "hcal et (float): " << hcalEtFloat() << ", " + << "fb: " << fb << ", " + << "global tower ieta: " << global_tower_iEta << ", " + << "global tower iphi: " << global_tower_iPhi << ", " + << "eta: " << getTowerEta_fromAbsID(global_tower_iEta) << ", " + << "phi: " << getTowerPhi_fromAbsID(global_tower_iPhi) << std::endl; + } + }; + + class GCTCorrfiber_t { + public: + GCTtower_t GCTtowers[N_GCTTOWERS_FIBER]; + GCTcluster_t GCTclusters[N_GCTCLUSTERS_FIBER]; + }; + + class GCTtoCorr_t { + public: + GCTCorrfiber_t GCTCorrfiber[N_GCTCORR_FIBERS]; + }; + + class GCTinternal_t { + public: + GCTCorrfiber_t GCTCorrfiber[N_GCTINTERNAL_FIBERS]; + + void computeClusterIsolationInPlace(int nGCTCard) { + for (unsigned int iFiber = 0; iFiber < N_GCTINTERNAL_FIBERS; iFiber++) { + for (unsigned int iCluster = 0; iCluster < N_GCTCLUSTERS_FIBER; iCluster++) { + // We will only save clusters with > 0 GeV, so only need to do this for clusters with >0 energy + if (GCTCorrfiber[iFiber].GCTclusters[iCluster].et == 0) { + GCTCorrfiber[iFiber].GCTclusters[iCluster].iso = 0; + continue; + } + + ap_uint<12> uint_isolation = 0; + + // do not add the GCT card off-set, so we remain in the gct local card iEta/iPhi + int toweriEta_in_GCT_card = GCTCorrfiber[iFiber].GCTclusters[iCluster].inCardToweriEta(); + int toweriPhi_in_GCT_card = GCTCorrfiber[iFiber].GCTclusters[iCluster].inCardToweriPhi(); + + // If cluster is in the overlap region, do not compute isolation + bool inOverlapWithAnotherGCTCard = (((toweriPhi_in_GCT_card >= 0) && (toweriPhi_in_GCT_card < 4)) || + ((toweriPhi_in_GCT_card >= 28) && (toweriPhi_in_GCT_card < 32))); + if (inOverlapWithAnotherGCTCard) { + GCTCorrfiber[iFiber].GCTclusters[iCluster].iso = 0; + continue; + } + + // Size 5x5 in towers: include the overlap-region-between-GCT-cards-if-applicable. In eta direction, the min and max towers (inclusive!) are: + int isoWindow_toweriEta_in_GCT_card_min = std::max(0, toweriEta_in_GCT_card - 2); + int isoWindow_toweriEta_in_GCT_card_max = std::min(toweriEta_in_GCT_card + 2, N_GCTETA - 1); // N_GCTETA = 34 + // e.g. if our window is centered at tower_iEta = 5, we want to sum towers_iEta 3, 4, (5), 6, 7, inclusive + // e.g. if our window is near the boundary, tower_iEta = 32, we want to sum towers_iEta 30, 31, (32), 33 + // inclusive (but there are only N_GCTETA = 34 towers, so we stop at tower_iEta = 33) + + // in phi direction, the min and max towers (inclusive!) are: + int isoWindow_toweriPhi_in_GCT_card_min = std::max(0, toweriPhi_in_GCT_card - 2); + int isoWindow_toweriPhi_in_GCT_card_max = std::min(toweriPhi_in_GCT_card + 2, N_GCTPHI - 1); + + // Keep track of the number of towers we summed over + int nTowersSummed = 0; + + // First add any nearby clusters to the isolation + for (unsigned int candFiber = 0; candFiber < N_GCTINTERNAL_FIBERS; candFiber++) { + for (unsigned int candCluster = 0; candCluster < N_GCTCLUSTERS_FIBER; candCluster++) { + // Do not double-count the cluster we are calculating the isolation for + if (!((candFiber == iFiber) && (candCluster == iCluster))) { + // Only consider clusters with et > 0 for isolation sum + if (GCTCorrfiber[candFiber].GCTclusters[candCluster].et > 0) { + // Get the candidate cluster's tower iEta and iPhi in GCT card + int candidate_toweriEta = GCTCorrfiber[candFiber].GCTclusters[candCluster].inCardToweriEta(); + int candidate_toweriPhi = GCTCorrfiber[candFiber].GCTclusters[candCluster].inCardToweriPhi(); + + // If the tower that the candidate cluster is in, is within a 5x5 window, add the candidate cluster energy's to the isolation as a proxy for the ECAL energy + if (((candidate_toweriEta >= isoWindow_toweriEta_in_GCT_card_min) && + (candidate_toweriEta <= isoWindow_toweriEta_in_GCT_card_max)) && + ((candidate_toweriPhi >= isoWindow_toweriPhi_in_GCT_card_min) && + (candidate_toweriPhi <= isoWindow_toweriPhi_in_GCT_card_max))) { + uint_isolation += GCTCorrfiber[candFiber].GCTclusters[candCluster].et; + } + } + } + } + } + + // From "tower index in GCT card", get which fiber it is in (out of 64 fibers), and which tower it is inside the fiber (out of 17 towers) + for (int iEta = isoWindow_toweriEta_in_GCT_card_min; iEta <= isoWindow_toweriEta_in_GCT_card_max; iEta++) { + for (int iPhi = isoWindow_toweriPhi_in_GCT_card_min; iPhi <= isoWindow_toweriPhi_in_GCT_card_max; iPhi++) { + nTowersSummed += 1; + + int indexInto64Fibers; + int indexInto17TowersInFiber; + + bool isTowerInPositiveEta = (iEta >= N_GCTTOWERS_FIBER); + if (isTowerInPositiveEta) { + // phi index is simple (e.g. if real phi = +80 degrees, iPhi in GCT = 31) + indexInto64Fibers = iPhi; + // if real eta = 1.47, iEta in GCT card = 33. If real eta = 0.0, iEta in GCT = 17, so iEta in fiber = 17%17 = 0. + indexInto17TowersInFiber = (iEta % 17); + } else { + // add offset (e.g. if real phi = +80 degrees, iPhi in GCT = 31, and my index into GCT fibers 31 + 32 = 63) + indexInto64Fibers = (iPhi + N_GCTPOSITIVE_FIBERS); + // e.g. if real eta = 0, iEta innew GCT card = 16, i.e. our index into the GCT fiber is 16-16 = 0 + indexInto17TowersInFiber = (16 - iEta); + } + + ap_uint<12> ecalEt = GCTCorrfiber[indexInto64Fibers].GCTtowers[indexInto17TowersInFiber].ecalEt; + uint_isolation += ecalEt; + } + } + + // Scale the isolation sum up if we summed over fewer than (5x5) = 25 towers + float scaleFactor = + ((float)(N_GCTTOWERS_CLUSTER_ISO_ONESIDE * N_GCTTOWERS_CLUSTER_ISO_ONESIDE) / (float)nTowersSummed); + + uint_isolation = (ap_uint<12>)(((float)uint_isolation) * scaleFactor); + + // Set the iso in the cluster + GCTCorrfiber[iFiber].GCTclusters[iCluster].iso = uint_isolation; + } + } + } + + void setIsolationInfo(void) { + for (unsigned int iFiber = 0; iFiber < N_GCTINTERNAL_FIBERS; iFiber++) { + for (unsigned int iCluster = 0; iCluster < N_GCTCLUSTERS_FIBER; iCluster++) { + // update the cluster's isolation information + GCTCorrfiber[iFiber].GCTclusters[iCluster].setRelIsoAndFlags(); + } + } + } + }; + + class GCTintTowers_t { + public: + GCTtower_t GCTtower[N_GCTETA][N_GCTPHI]; + + // Write contents to output CMSSW collection. Note the use of the GCTtower_t method that creates the + // l1tp2::CaloTower object from the global eta/phi. + void writeToPFOutput(int nGCTCard, std::unique_ptr const& gctFullTowers) { + for (unsigned int iEta = 0; iEta < N_GCTETA; iEta++) { + for (unsigned int iPhi = 0; iPhi < N_GCTPHI; iPhi++) { + GCTtower_t thisFullTower = GCTtower[iEta][iPhi]; + gctFullTowers->push_back(thisFullTower.createFullTowerFromCardIdx(nGCTCard, iEta, iPhi)); + } + } + } + }; + + /* For each GCT card (3 of them in total, for barrel + endcap), list the sixteen + * RCT cards that fall in them. The first eight are in positive eta, the next + * eight are in negative eta (see figure of one GCT card). The RCT cards themselves + * run from 0 to 35 (see RCT figure). + * Hard-coded because the GCT cards wrap around the barrel region. + * Used only to convert the RCT emulator outputs to the GCT emulator inputs. + */ + static const unsigned int GCTcardtoRCTcardnumber[N_GCTCARDS][N_RCTCARDS_PHI * 2] = { + // GCT Card 0 + {11, 13, 15, 17, 19, 21, 23, 25, 10, 12, 14, 16, 18, 20, 22, 24}, + + // GCT Card 1 + {23, 25, 27, 29, 31, 33, 35, 1, 22, 24, 26, 28, 30, 32, 34, 0}, + + // GCT Card 2 + {35, 1, 3, 5, 7, 9, 11, 13, 34, 0, 2, 4, 6, 8, 10, 12}}; + + /* + * Helper function to monitor l1tp2::CaloTower members. + */ + inline void printl1tp2TowerInfo(l1tp2::CaloTower thisTower, std::string description = "") { + std::cout << "[Print l1tp2::CaloTower info:] [" << description << "]: " + << ".ecalTowerEta() (float): " << thisTower.ecalTowerEt() << ", " + << ".hcalTowerEta() (float): " << thisTower.hcalTowerEt() << ", " + << ".towerIEta(): " << thisTower.towerIEta() << ", " + << ".towerIPhi(): " << thisTower.towerIPhi() << ", " + << ".towerEta() " << thisTower.towerEta() << ", " + << ".towerPhi() " << thisTower.towerPhi() << std::endl; + } + + void algo_top(const GCTcard_t& GCTcard, + GCTtoCorr_t& GCTtoCorr, + unsigned int nGCTCard, + std::unique_ptr const& gctClusters, + std::unique_ptr const& gctTowers, + std::unique_ptr const& gctFullTowers, + std::unique_ptr const& gctEGammas, + std::unique_ptr const& gctDigitizedClustersCorrelator, + std::unique_ptr const& gctDigitizedTowersCorrelator, + std::unique_ptr const& gctDigitizedClustersGT, + l1tp2::ParametricCalibration calib_); + + GCTinternal_t getClustersTowers(const GCTcard_t& GCTcard, unsigned int nGCTCard); + + void doProximityAndBremsStitching(const RCTcard_t (&inputCards)[N_RCTCARDS_PHI], + RCTcard_t (&outputCards)[N_RCTCARDS_PHI], + int iStartingCard, + bool isPositiveEta); + + GCTcard_t getClustersCombined(const GCTcard_t& GCTcard, unsigned int nGCTCard); + + GCTintTowers_t getFullTowers(const GCTinternal_t& GCTinternal); + + void writeToCorrelatorAndGTOutputs( + const GCTinternal_t& GCTinternal, + GCTtoCorr_t& GCTtoCorrOutput, + std::unique_ptr const& gctClustersOutput, + std::unique_ptr const& gctTowersOutput, + std::unique_ptr const& gctEGammas, + std::unique_ptr const& gctDigitizedClustersCorrelator, + std::unique_ptr const& gctDigitizedTowersCorrelator, + std::unique_ptr const& gctDigitizedClustersGT, + int nGCTCard, + int fiberStart, + int fiberEnd, + int corrFiberIndexOffset, + int corrTowPhiOffset); + +} // namespace p2eg + +#endif diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1GCT.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1GCT.h new file mode 100644 index 0000000000000..e0f117e580847 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1GCT.h @@ -0,0 +1,450 @@ +#ifndef L1Trigger_L1CaloTrigger_Phase2L1GCT_h +#define L1Trigger_L1CaloTrigger_Phase2L1RCT_h + +#include +#include + +// Output collections +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h" + +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h" + +/* + * Do proximity stitching and brems combination for POSITIVE eta, using GCTcard as input. Write to GCTcombinedClusters. + * iStartingCard is 0 for even phi boundaries, and 1 for odd phi boundaries. + * The first argument is for RCTcardEtaPos/Neg, which are arrays of RCTcard_t of size N_RCTCARDS_PHI. We pass by reference for the second argument to modify it. + */ +inline void p2eg::doProximityAndBremsStitching(const p2eg::RCTcard_t (&inputCards)[p2eg::N_RCTCARDS_PHI], + p2eg::RCTcard_t (&outputCards)[p2eg::N_RCTCARDS_PHI], + int iStartingCard, + bool isPositiveEta) { + for (int i = iStartingCard; i < p2eg::N_RCTCARDS_PHI - 1; i = i + 2) { + for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) { + for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) { + ap_uint<5> towerPhi1 = inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].towPhi; + + ap_uint<15> crystalEta1 = inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].towEta * 5 + + inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].crEta; + ap_uint<15> crystalPhi1 = inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].crPhi; + + for (int j1 = 0; j1 < p2eg::N_RCTGCT_FIBERS; j1++) { + for (int k1 = 0; k1 < p2eg::N_RCTCLUSTERS_FIBER; k1++) { + // For each pair, we check if cluster #1 is in the top card and if cluster #2 is in the bottom card. + ap_uint<5> towerPhi2 = inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].towPhi; + ap_uint<15> crystalEta2 = inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].towEta * 5 + + inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].crEta; + ap_uint<15> crystalPhi2 = inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].crPhi; + + // For positive eta, phi1 = 4, phi2 = 0 if cluster 1 is in the top card and cluster 2 is in the bottom card. For negative eta, the reverse is true. + ap_uint<15> dPhi; + dPhi = (isPositiveEta) ? ((5 - crystalPhi1) + crystalPhi2) : ((5 - crystalPhi2) + crystalPhi1); + ap_uint<15> dEta; + dEta = (crystalEta1 > crystalEta2) ? (crystalEta1 - crystalEta2) : (crystalEta2 - crystalEta1); + + ap_uint<12> one = inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et; + ap_uint<12> two = inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et; + + int topTowerPhi = (isPositiveEta) ? 3 : 0; + int botTowerPhi = (isPositiveEta) ? 0 : 3; + + int topCrystalPhi = (isPositiveEta) ? 4 : 0; + int botCrystalPhi = (isPositiveEta) ? 0 : 4; + + // First check for proximity stitching: clusters need to be exactly next to each other in crystals (across an RCT card boundary). + // No requirement on their relative energy. + if (towerPhi1 == topTowerPhi && crystalPhi1 == topCrystalPhi) { + if (towerPhi2 == botTowerPhi && crystalPhi2 == botCrystalPhi) { + if (dEta < 2) { + if (one > two) { + outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = one + two; + outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = 0; + } else { + outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = 0; + outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = one + two; + } + } + } + } + + // Next, check for brems correction: clusters need to be next to each other in TOWERS only (not crystals) across an RCT card boundary. + // And the sub-leading cluster must have a significant (>10%) energy of the larger cluster, in order for them to be combined. + if (towerPhi1 == topTowerPhi) { + if (towerPhi2 == botTowerPhi) { + if ((dPhi <= 5) && (dEta < 2)) { + if (one > two) { + if (two > + (0.10 * one)) { // Only stitch if the sub-leading cluster has a significant amount of energy + outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = one + two; + outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = 0; + } + } else { + if (one > + (0.10 * two)) { // Only stitch if the sub-leading cluster has a significant amount of energy + outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = 0; + outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = one + two; + } + } + } + } + } + } + } + } + } + } +} + +inline p2eg::GCTcard_t p2eg::getClustersCombined(const p2eg::GCTcard_t& GCTcard, unsigned int nGCTCard) { + p2eg::GCTcard_t GCTcombinedClusters; + + // Initialize the output + for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) { + for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) { + for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) { + GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k] = + GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k]; + GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k] = + GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k]; + } + } + } + bool isPositiveEta; + int iStartingCard; + + // we will store new et in the GCTcombinedClusters, 0'ing lower clusters after stitching, dont need to care about other variables they stay the + // same as input for now at least + // we combine even phi boundaries positive eta. Start at card 0 (third argument), and tell the function this is positive eta (fourth argument) + isPositiveEta = true; + iStartingCard = 0; + p2eg::doProximityAndBremsStitching( + GCTcard.RCTcardEtaPos, GCTcombinedClusters.RCTcardEtaPos, iStartingCard, isPositiveEta); + + // now we combine odd phi boundaries positive eta + isPositiveEta = true; + iStartingCard = 1; + p2eg::doProximityAndBremsStitching( + GCTcard.RCTcardEtaPos, GCTcombinedClusters.RCTcardEtaPos, iStartingCard, isPositiveEta); + + // repeat above steps for NEGATIVE eta, even phi boundaries + isPositiveEta = false; + iStartingCard = 0; + p2eg::doProximityAndBremsStitching( + GCTcard.RCTcardEtaNeg, GCTcombinedClusters.RCTcardEtaNeg, iStartingCard, isPositiveEta); + + // lastly, NEGATIVE eta, odd phi boundaries + isPositiveEta = false; + iStartingCard = 1; + p2eg::doProximityAndBremsStitching( + GCTcard.RCTcardEtaNeg, GCTcombinedClusters.RCTcardEtaNeg, iStartingCard, isPositiveEta); + + // we need to store what we did before we start phi stitching + p2eg::GCTcard_t GCTout; + for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) { + for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) { + for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) { + GCTout.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k] = + GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k]; + GCTout.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k] = + GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k]; + } + } + } + + // now we combine eta boundaries, just positive and negative eta + // Uses RCTcardEtaPos and RCTcardEtaNeg + for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) { + for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) { + for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) { + ap_uint<15> phi1 = (i * 4 + GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].towPhi) * 5 + + GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].crPhi; + ap_uint<15> eta1 = GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].crEta; + if (GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].towEta == 0 && eta1 == 0) { + for (int j1 = 0; j1 < p2eg::N_RCTGCT_FIBERS; j1++) { + for (int k1 = 0; k1 < p2eg::N_RCTCLUSTERS_FIBER; k1++) { + ap_uint<15> phi2 = (i * 4 + (3 - GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].towPhi)) * 5 + + (4 - GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].crPhi); + ap_uint<15> eta2 = GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].crEta; + if (GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].towEta == 0 && eta2 == 0) { + ap_uint<15> dPhi; + dPhi = (phi1 > phi2) ? (phi1 - phi2) : (phi2 - phi1); + if (dPhi < 2) { + ap_uint<12> one = GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].et; + ap_uint<12> two = GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et; + if (one > two) { + GCTout.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].et = one + two; + GCTout.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et = 0; + } else { + GCTout.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].et = 0; + GCTout.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et = one + two; + } + } + } + } + } + } + } + } + } + return GCTout; +} + +/* + * Populate a GCTinternal_t struct (consisting of 64 fibers, each fiber has clusters and towers) by converting RCT clusters and towers to GCT notation. + */ + +inline p2eg::GCTinternal_t p2eg::getClustersTowers(const p2eg::GCTcard_t& GCTcard, unsigned int nGCTCard) { + p2eg::GCTcard_t GCTcombinedClusters; + p2eg::GCTinternal_t GCTout; + + // here we will stitch the clusters in phi and eta + GCTcombinedClusters = p2eg::getClustersCombined(GCTcard, nGCTCard); + + // create internal structure of GCT card + // we start from RCT card 0 - it is overlap with other GCT card and fill structure that we will use to send data to Correlator + // we only need to care about clusters et in combinrdClusters, since the rest remains unchanged wrt input, the cluster that we set to 0 + // remain in the data at the same place , it will just get 0 et now + // we need to code Positive and Negative Eta differently ! For negative Eta link 0 for each RCT + // region becomes 3 in GCT output, the RCT card is rotated around 0:0 point of the card + // First 16 fibers - positive Eta , second 16 - negative. Eta coded 0...16 and towEtaNeg = 0 or 1 for clusters ; + // Phi is coded 0...15 , in case if whole card 0...33 and subdevision 1/5 in crPhi and crEta 0...4 for + // position in tower + // + // towers are put in link starting from eta=0, the link number defines Eta negative or positive and Phi position of tower. + for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) { + for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) { + for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) { + bool isPositiveEta; + // positive eta: initialize from RCT clusters in pos object + isPositiveEta = true; + GCTout.GCTCorrfiber[i * 4 + j].GCTclusters[k].initFromRCTCluster( + i, isPositiveEta, GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k]); + // negative eta: initialize from RCT clusters in neg object + isPositiveEta = false; + GCTout.GCTCorrfiber[i * 4 + (3 - j) + p2eg::N_GCTPOSITIVE_FIBERS].GCTclusters[k].initFromRCTCluster( + i, isPositiveEta, GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k]); + } + for (int k = 0; k < N_RCTTOWERS_FIBER; k++) { + GCTout.GCTCorrfiber[i * 4 + j].GCTtowers[k].initFromRCTTower( + GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTtowers[k]); // pos eta + GCTout.GCTCorrfiber[i * 4 + (3 - j) + p2eg::N_GCTPOSITIVE_FIBERS].GCTtowers[k].initFromRCTTower( + GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTtowers[k]); // neg eta + } + } + } + return GCTout; +} + +/* + * Return full towers with the tower energy (i.e. unclustered energy) and cluster energy added together. + */ +inline p2eg::GCTintTowers_t p2eg::getFullTowers(const p2eg::GCTinternal_t& GCTinternal) { + p2eg::GCTintTowers_t GCTintTowers; + + // Positive eta + for (int i = 0; i < p2eg::N_GCTPOSITIVE_FIBERS; i = i + 4) { + for (int i1 = 0; i1 < 4; i1++) { + for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) { + ap_uint<15> phi = i + i1; + ap_uint<15> eta = p2eg::N_GCTETA / 2 + k; + GCTintTowers.GCTtower[eta][phi].et = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].et; + GCTintTowers.GCTtower[eta][phi].hoe = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].hoe; + for (int ic1 = 0; ic1 < 4; ic1++) { + for (int jc = 0; jc < p2eg::N_GCTCLUSTERS_FIBER; jc++) { + ap_uint<15> eta1 = p2eg::N_GCTETA / 2 + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towEta; + ap_uint<15> phi1 = GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towPhi; + if (eta == eta1 && phi == phi1) { + GCTintTowers.GCTtower[eta][phi].et = + (GCTintTowers.GCTtower[eta][phi].et + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et); + } + } + } + } + } + } + + // Negative eta + for (int i = p2eg::N_GCTPOSITIVE_FIBERS; i < p2eg::N_GCTINTERNAL_FIBERS; i = i + 4) { + for (int i1 = 0; i1 < 4; i1++) { + for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) { + ap_uint<15> eta = p2eg::N_GCTETA / 2 - k - 1; + ap_uint<15> phi = i + i1 - p2eg::N_GCTPOSITIVE_FIBERS; + GCTintTowers.GCTtower[eta][phi].et = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].et; + GCTintTowers.GCTtower[eta][phi].hoe = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].hoe; + for (int ic1 = 0; ic1 < 4; ic1++) { + for (int jc = 0; jc < p2eg::N_GCTCLUSTERS_FIBER; jc++) { + ap_uint<15> eta1 = p2eg::N_GCTETA / 2 - 1 - GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towEta; + ap_uint<15> phi1 = GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towPhi; + if (eta == eta1 && phi == phi1) { + GCTintTowers.GCTtower[eta][phi].et = + (GCTintTowers.GCTtower[eta][phi].et + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et); + } + } + } + } + } + } + + return GCTintTowers; +} + +/* + * Fill CMSSW collections and correlator outputs, using GCTinternal. + */ +inline void p2eg::writeToCorrelatorAndGTOutputs( + const p2eg::GCTinternal_t& GCTinternal, + p2eg::GCTtoCorr_t& GCTtoCorrOutput, + std::unique_ptr const& gctClustersOutput, + std::unique_ptr const& gctTowersOutput, + std::unique_ptr const& gctEGammas, + std::unique_ptr const& gctDigitizedClustersCorrelator, + std::unique_ptr const& gctDigitizedTowersCorrelator, + std::unique_ptr const& gctDigitizedClustersGT, + int nGCTCard, + int fiberStart, + int fiberEnd, + int corrFiberIndexOffset, + int corrTowPhiOffset = 4) { + for (int i = fiberStart; i < fiberEnd; i++) { + // In each fiber, first do clusters + for (int k = 0; k < p2eg::N_GCTCLUSTERS_FIBER; k++) { + // First do CMSSW cluster outputs + p2eg::GCTcluster_t thisCluster = GCTinternal.GCTCorrfiber[i].GCTclusters[k]; + if (thisCluster.etFloat() > 0.0) { + // Make l1tp2::CaloCrystalCluster + gctClustersOutput->push_back(thisCluster.createCaloCrystalCluster()); + + // Make l1t::EGamma + int bx = 0; + l1t::EGamma thisEGamma = thisCluster.createL1TEGamma(); + gctEGammas->push_back(bx, thisEGamma); + } + + // Then the clusters to the correlator: all fields are the same with the exception of towPhi, which + // needs to be subtracted by 4 because the output to correlator does NOT include the overlap region. + GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTclusters[k] = thisCluster; + GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTclusters[k].towPhi = + (thisCluster.towPhi - corrTowPhiOffset); + + // Make l1tp2::DigitizedClusterCorrelator. The function needs corrTowPhiOffset to know the towPhi in the card excluding the overlap region. + // The correlator clusters don't need to know the fiber offset. + if (thisCluster.etFloat() > 0.0) { + gctDigitizedClustersCorrelator->push_back(thisCluster.createDigitizedClusterCorrelator(corrTowPhiOffset)); + } + + // Make l1tp2::DigitizedClusterGT. + if (thisCluster.etFloat() > 0.0) { + bool isValid = true; + gctDigitizedClustersGT->push_back(thisCluster.createDigitizedClusterGT(isValid)); + } + } + + // Next do tower outputs + for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) { + // First do CMSSW tower outputs + p2eg::GCTtower_t thisTower = GCTinternal.GCTCorrfiber[i].GCTtowers[k]; + l1tp2::CaloTower thisL1CaloTower = thisTower.createCaloTowerFromFiberIdx(nGCTCard, i, k); + gctTowersOutput->push_back(thisL1CaloTower); + + // Then the towers to the correlator. Note the same corrFiberIndexOffset as was done for the clusters + GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTtowers[k] = thisTower; + + // For the collection, the three arguments are (1) the GCT card, (2) the fiber index in the GCT card (excluding the overlap region), and (3) the tower index in the fiber + l1tp2::DigitizedTowerCorrelator thisDigitizedTowerCorrelator = + thisTower.createDigitizedTowerCorrelator(nGCTCard, i - corrFiberIndexOffset, k); + gctDigitizedTowersCorrelator->push_back(thisDigitizedTowerCorrelator); + } + } +} + +/* + * algo_top: First two arguments are the same as in the original firmware. + * nGCTCard is 0, 1, or 2 (needed for getting the cluster real eta/phis for CMSSW collections). + * gctClusters is the CMSSW-style output collection of clusters. + * gctTowers is the CMSSW-style output collection of towers. + */ + +inline void p2eg::algo_top( + const p2eg::GCTcard_t& GCTcard, + p2eg::GCTtoCorr_t& GCTtoCorr, + unsigned int nGCTCard, + std::unique_ptr const& gctClusters, + std::unique_ptr const& gctTowers, + std::unique_ptr const& gctFullTowers, + std::unique_ptr const& gctEGammas, + std::unique_ptr const& gctDigitizedClustersCorrelator, + std::unique_ptr const& gctDigitizedTowersCorrelator, + std::unique_ptr const& gctDigitizedClustersGT, + l1tp2::ParametricCalibration calib_) { + //-------------------------// + // Initialize the GCT area + //-------------------------// + p2eg::GCTinternal_t GCTinternal = p2eg::getClustersTowers(GCTcard, nGCTCard); + + //------------------------------------------------// + // Combine towers and clusters to get full towers + //------------------------------------------------// + p2eg::GCTintTowers_t GCTintTowers = p2eg::getFullTowers(GCTinternal); + + //---------------------------// + // Compute cluster isolation + //--------------------------// + GCTinternal.computeClusterIsolationInPlace(nGCTCard); + GCTinternal.setIsolationInfo(); + + //-----------------------------------------------------------------------------------------------------------------------// + // Output to correlator and CMSSW collections. + // For positive eta, skip overlap region, i.e. fibers i = 0, 1, 2, 3, and i = 28, 29, 30, 31. + // For negative eta, skip overlap region, i.e. fibers 32, 33, 34, 35, and 61, 62, 63, 64. + //-----------------------------------------------------------------------------------------------------------------------// + int posEtaFiberStart = p2eg::N_RCTGCT_FIBERS; // 4, since there are 4 fibers in one RCT card + int posEtaFiberEnd = (p2eg::N_GCTPOSITIVE_FIBERS - p2eg::N_RCTGCT_FIBERS); + int negEtaFiberStart = (p2eg::N_GCTPOSITIVE_FIBERS + p2eg::N_RCTGCT_FIBERS); + int negEtaFiberEnd = + (p2eg::N_GCTINTERNAL_FIBERS - p2eg::N_RCTGCT_FIBERS); // first term is number of gct internal fibers + + // When indexing into the correlator output, note that the output to correlator does NOT include the overlap region, + // so fiber number "i" in GCT is not fiber "i" in the correlator output, it's reduced by 4 in positive eta, and 12 in negative eta. + // (4 because we are skipping one RCT card in positive eta, and 12 because we are skipping three RCT cards in negative eta) + int posEtaCorrelatorFiberIndexOffset = 4; + int negEtaCorrelatorFiberIndexOffset = 12; + + // The offset in the actual towPhi value is going to be the same in pos/neg eta; shifted down by 4 due to no overlap region + int correlatorTowPhiOffset = 4; + + // Positive eta + p2eg::writeToCorrelatorAndGTOutputs(GCTinternal, + GCTtoCorr, + gctClusters, + gctTowers, + gctEGammas, + gctDigitizedClustersCorrelator, + gctDigitizedTowersCorrelator, + gctDigitizedClustersGT, + nGCTCard, + posEtaFiberStart, + posEtaFiberEnd, + posEtaCorrelatorFiberIndexOffset, + correlatorTowPhiOffset); + // Negative eta + p2eg::writeToCorrelatorAndGTOutputs(GCTinternal, + GCTtoCorr, + gctClusters, + gctTowers, + gctEGammas, + gctDigitizedClustersCorrelator, + gctDigitizedTowersCorrelator, + gctDigitizedClustersGT, + nGCTCard, + negEtaFiberStart, + negEtaFiberEnd, + negEtaCorrelatorFiberIndexOffset, + correlatorTowPhiOffset); + + //-----------------------------------------------------------------------------------------------------------------------// + // CMSSW outputs for GCT Full Towers (clusters + towers) output for PFClusters. + //-----------------------------------------------------------------------------------------------------------------------// + GCTintTowers.writeToPFOutput(nGCTCard, gctFullTowers); +} + +#endif diff --git a/L1Trigger/L1CaloTrigger/interface/Phase2L1RCT.h b/L1Trigger/L1CaloTrigger/interface/Phase2L1RCT.h new file mode 100644 index 0000000000000..43547af9d0bd8 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/interface/Phase2L1RCT.h @@ -0,0 +1,1590 @@ +#ifndef L1Trigger_L1CaloTrigger_Phase2L1RCT +#define L1Trigger_L1CaloTrigger_Phase2L1RCT + +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h" + +////////////////////////////////////////////////////////////////////////// +// Other emulator helper functions +////////////////////////////////////////////////////////////////////////// + +inline p2eg::ecalRegion_t p2eg::initStructure(p2eg::crystal temporary[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI]) { + ap_uint<5> Eta = 0x0; + ap_uint<5> Phi = 0x0; + + p2eg::ecalRegion_t out; + + out.etaStrip0.cr0.energy = temporary[Eta + 0][Phi + 0].energy; + out.etaStrip0.cr0.eta = 0; + out.etaStrip0.cr0.phi = 0; + out.etaStrip0.cr1.energy = temporary[Eta + 0][Phi + 1].energy; + out.etaStrip0.cr1.eta = 0; + out.etaStrip0.cr1.phi = 1; + out.etaStrip0.cr2.energy = temporary[Eta + 0][Phi + 2].energy; + out.etaStrip0.cr2.eta = 0; + out.etaStrip0.cr2.phi = 2; + out.etaStrip0.cr3.energy = temporary[Eta + 0][Phi + 3].energy; + out.etaStrip0.cr3.eta = 0; + out.etaStrip0.cr3.phi = 3; + out.etaStrip0.cr4.energy = temporary[Eta + 0][Phi + 4].energy; + out.etaStrip0.cr4.eta = 0; + out.etaStrip0.cr4.phi = 4; + out.etaStrip0.cr5.energy = temporary[Eta + 0][Phi + 5].energy; + out.etaStrip0.cr5.eta = 0; + out.etaStrip0.cr5.phi = 5; + out.etaStrip0.cr6.energy = temporary[Eta + 0][Phi + 6].energy; + out.etaStrip0.cr6.eta = 0; + out.etaStrip0.cr6.phi = 6; + out.etaStrip0.cr7.energy = temporary[Eta + 0][Phi + 7].energy; + out.etaStrip0.cr7.eta = 0; + out.etaStrip0.cr7.phi = 7; + out.etaStrip0.cr8.energy = temporary[Eta + 0][Phi + 8].energy; + out.etaStrip0.cr8.eta = 0; + out.etaStrip0.cr8.phi = 8; + out.etaStrip0.cr9.energy = temporary[Eta + 0][Phi + 9].energy; + out.etaStrip0.cr9.eta = 0; + out.etaStrip0.cr9.phi = 9; + out.etaStrip0.cr10.energy = temporary[Eta + 0][Phi + 10].energy; + out.etaStrip0.cr10.eta = 0; + out.etaStrip0.cr10.phi = 10; + out.etaStrip0.cr11.energy = temporary[Eta + 0][Phi + 11].energy; + out.etaStrip0.cr11.eta = 0; + out.etaStrip0.cr11.phi = 11; + out.etaStrip0.cr12.energy = temporary[Eta + 0][Phi + 12].energy; + out.etaStrip0.cr12.eta = 0; + out.etaStrip0.cr12.phi = 12; + out.etaStrip0.cr13.energy = temporary[Eta + 0][Phi + 13].energy; + out.etaStrip0.cr13.eta = 0; + out.etaStrip0.cr13.phi = 13; + out.etaStrip0.cr14.energy = temporary[Eta + 0][Phi + 14].energy; + out.etaStrip0.cr14.eta = 0; + out.etaStrip0.cr14.phi = 14; + out.etaStrip0.cr15.energy = temporary[Eta + 0][Phi + 15].energy; + out.etaStrip0.cr15.eta = 0; + out.etaStrip0.cr15.phi = 15; + out.etaStrip0.cr16.energy = temporary[Eta + 0][Phi + 16].energy; + out.etaStrip0.cr16.eta = 0; + out.etaStrip0.cr16.phi = 16; + out.etaStrip0.cr17.energy = temporary[Eta + 0][Phi + 17].energy; + out.etaStrip0.cr17.eta = 0; + out.etaStrip0.cr17.phi = 17; + out.etaStrip0.cr18.energy = temporary[Eta + 0][Phi + 18].energy; + out.etaStrip0.cr18.eta = 0; + out.etaStrip0.cr18.phi = 18; + out.etaStrip0.cr19.energy = temporary[Eta + 0][Phi + 19].energy; + out.etaStrip0.cr19.eta = 0; + out.etaStrip0.cr19.phi = 19; + + out.etaStrip1.cr0.energy = temporary[Eta + 1][Phi + 0].energy; + out.etaStrip1.cr0.eta = 1; + out.etaStrip1.cr0.phi = 0; + out.etaStrip1.cr1.energy = temporary[Eta + 1][Phi + 1].energy; + out.etaStrip1.cr1.eta = 1; + out.etaStrip1.cr1.phi = 1; + out.etaStrip1.cr2.energy = temporary[Eta + 1][Phi + 2].energy; + out.etaStrip1.cr2.eta = 1; + out.etaStrip1.cr2.phi = 2; + out.etaStrip1.cr3.energy = temporary[Eta + 1][Phi + 3].energy; + out.etaStrip1.cr3.eta = 1; + out.etaStrip1.cr3.phi = 3; + out.etaStrip1.cr4.energy = temporary[Eta + 1][Phi + 4].energy; + out.etaStrip1.cr4.eta = 1; + out.etaStrip1.cr4.phi = 4; + out.etaStrip1.cr5.energy = temporary[Eta + 1][Phi + 5].energy; + out.etaStrip1.cr5.eta = 1; + out.etaStrip1.cr5.phi = 5; + out.etaStrip1.cr6.energy = temporary[Eta + 1][Phi + 6].energy; + out.etaStrip1.cr6.eta = 1; + out.etaStrip1.cr6.phi = 6; + out.etaStrip1.cr7.energy = temporary[Eta + 1][Phi + 7].energy; + out.etaStrip1.cr7.eta = 1; + out.etaStrip1.cr7.phi = 7; + out.etaStrip1.cr8.energy = temporary[Eta + 1][Phi + 8].energy; + out.etaStrip1.cr8.eta = 1; + out.etaStrip1.cr8.phi = 8; + out.etaStrip1.cr9.energy = temporary[Eta + 1][Phi + 9].energy; + out.etaStrip1.cr9.eta = 1; + out.etaStrip1.cr9.phi = 9; + out.etaStrip1.cr10.energy = temporary[Eta + 1][Phi + 10].energy; + out.etaStrip1.cr10.eta = 1; + out.etaStrip1.cr10.phi = 10; + out.etaStrip1.cr11.energy = temporary[Eta + 1][Phi + 11].energy; + out.etaStrip1.cr11.eta = 1; + out.etaStrip1.cr11.phi = 11; + out.etaStrip1.cr12.energy = temporary[Eta + 1][Phi + 12].energy; + out.etaStrip1.cr12.eta = 1; + out.etaStrip1.cr12.phi = 12; + out.etaStrip1.cr13.energy = temporary[Eta + 1][Phi + 13].energy; + out.etaStrip1.cr13.eta = 1; + out.etaStrip1.cr13.phi = 13; + out.etaStrip1.cr14.energy = temporary[Eta + 1][Phi + 14].energy; + out.etaStrip1.cr14.eta = 1; + out.etaStrip1.cr14.phi = 14; + out.etaStrip1.cr15.energy = temporary[Eta + 1][Phi + 15].energy; + out.etaStrip1.cr15.eta = 1; + out.etaStrip1.cr15.phi = 15; + out.etaStrip1.cr16.energy = temporary[Eta + 1][Phi + 16].energy; + out.etaStrip1.cr16.eta = 1; + out.etaStrip1.cr16.phi = 16; + out.etaStrip1.cr17.energy = temporary[Eta + 1][Phi + 17].energy; + out.etaStrip1.cr17.eta = 1; + out.etaStrip1.cr17.phi = 17; + out.etaStrip1.cr18.energy = temporary[Eta + 1][Phi + 18].energy; + out.etaStrip1.cr18.eta = 1; + out.etaStrip1.cr18.phi = 18; + out.etaStrip1.cr19.energy = temporary[Eta + 1][Phi + 19].energy; + out.etaStrip1.cr19.eta = 1; + out.etaStrip1.cr19.phi = 19; + + out.etaStrip2.cr0.energy = temporary[Eta + 2][Phi + 0].energy; + out.etaStrip2.cr0.eta = 2; + out.etaStrip2.cr0.phi = 0; + out.etaStrip2.cr1.energy = temporary[Eta + 2][Phi + 1].energy; + out.etaStrip2.cr1.eta = 2; + out.etaStrip2.cr1.phi = 1; + out.etaStrip2.cr2.energy = temporary[Eta + 2][Phi + 2].energy; + out.etaStrip2.cr2.eta = 2; + out.etaStrip2.cr2.phi = 2; + out.etaStrip2.cr3.energy = temporary[Eta + 2][Phi + 3].energy; + out.etaStrip2.cr3.eta = 2; + out.etaStrip2.cr3.phi = 3; + out.etaStrip2.cr4.energy = temporary[Eta + 2][Phi + 4].energy; + out.etaStrip2.cr4.eta = 2; + out.etaStrip2.cr4.phi = 4; + out.etaStrip2.cr5.energy = temporary[Eta + 2][Phi + 5].energy; + out.etaStrip2.cr5.eta = 2; + out.etaStrip2.cr5.phi = 5; + out.etaStrip2.cr6.energy = temporary[Eta + 2][Phi + 6].energy; + out.etaStrip2.cr6.eta = 2; + out.etaStrip2.cr6.phi = 6; + out.etaStrip2.cr7.energy = temporary[Eta + 2][Phi + 7].energy; + out.etaStrip2.cr7.eta = 2; + out.etaStrip2.cr7.phi = 7; + out.etaStrip2.cr8.energy = temporary[Eta + 2][Phi + 8].energy; + out.etaStrip2.cr8.eta = 2; + out.etaStrip2.cr8.phi = 8; + out.etaStrip2.cr9.energy = temporary[Eta + 2][Phi + 9].energy; + out.etaStrip2.cr9.eta = 2; + out.etaStrip2.cr9.phi = 9; + out.etaStrip2.cr10.energy = temporary[Eta + 2][Phi + 10].energy; + out.etaStrip2.cr10.eta = 2; + out.etaStrip2.cr10.phi = 10; + out.etaStrip2.cr11.energy = temporary[Eta + 2][Phi + 11].energy; + out.etaStrip2.cr11.eta = 2; + out.etaStrip2.cr11.phi = 11; + out.etaStrip2.cr12.energy = temporary[Eta + 2][Phi + 12].energy; + out.etaStrip2.cr12.eta = 2; + out.etaStrip2.cr12.phi = 12; + out.etaStrip2.cr13.energy = temporary[Eta + 2][Phi + 13].energy; + out.etaStrip2.cr13.eta = 2; + out.etaStrip2.cr13.phi = 13; + out.etaStrip2.cr14.energy = temporary[Eta + 2][Phi + 14].energy; + out.etaStrip2.cr14.eta = 2; + out.etaStrip2.cr14.phi = 14; + out.etaStrip2.cr15.energy = temporary[Eta + 2][Phi + 15].energy; + out.etaStrip2.cr15.eta = 2; + out.etaStrip2.cr15.phi = 15; + out.etaStrip2.cr16.energy = temporary[Eta + 2][Phi + 16].energy; + out.etaStrip2.cr16.eta = 2; + out.etaStrip2.cr16.phi = 16; + out.etaStrip2.cr17.energy = temporary[Eta + 2][Phi + 17].energy; + out.etaStrip2.cr17.eta = 2; + out.etaStrip2.cr17.phi = 17; + out.etaStrip2.cr18.energy = temporary[Eta + 2][Phi + 18].energy; + out.etaStrip2.cr18.eta = 2; + out.etaStrip2.cr18.phi = 18; + out.etaStrip2.cr19.energy = temporary[Eta + 2][Phi + 19].energy; + out.etaStrip2.cr19.eta = 2; + out.etaStrip2.cr19.phi = 19; + + out.etaStrip3.cr0.energy = temporary[Eta + 3][Phi + 0].energy; + out.etaStrip3.cr0.eta = 3; + out.etaStrip3.cr0.phi = 0; + out.etaStrip3.cr1.energy = temporary[Eta + 3][Phi + 1].energy; + out.etaStrip3.cr1.eta = 3; + out.etaStrip3.cr1.phi = 1; + out.etaStrip3.cr2.energy = temporary[Eta + 3][Phi + 2].energy; + out.etaStrip3.cr2.eta = 3; + out.etaStrip3.cr2.phi = 2; + out.etaStrip3.cr3.energy = temporary[Eta + 3][Phi + 3].energy; + out.etaStrip3.cr3.eta = 3; + out.etaStrip3.cr3.phi = 3; + out.etaStrip3.cr4.energy = temporary[Eta + 3][Phi + 4].energy; + out.etaStrip3.cr4.eta = 3; + out.etaStrip3.cr4.phi = 4; + out.etaStrip3.cr5.energy = temporary[Eta + 3][Phi + 5].energy; + out.etaStrip3.cr5.eta = 3; + out.etaStrip3.cr5.phi = 5; + out.etaStrip3.cr6.energy = temporary[Eta + 3][Phi + 6].energy; + out.etaStrip3.cr6.eta = 3; + out.etaStrip3.cr6.phi = 6; + out.etaStrip3.cr7.energy = temporary[Eta + 3][Phi + 7].energy; + out.etaStrip3.cr7.eta = 3; + out.etaStrip3.cr7.phi = 7; + out.etaStrip3.cr8.energy = temporary[Eta + 3][Phi + 8].energy; + out.etaStrip3.cr8.eta = 3; + out.etaStrip3.cr8.phi = 8; + out.etaStrip3.cr9.energy = temporary[Eta + 3][Phi + 9].energy; + out.etaStrip3.cr9.eta = 3; + out.etaStrip3.cr9.phi = 9; + out.etaStrip3.cr10.energy = temporary[Eta + 3][Phi + 10].energy; + out.etaStrip3.cr10.eta = 3; + out.etaStrip3.cr10.phi = 10; + out.etaStrip3.cr11.energy = temporary[Eta + 3][Phi + 11].energy; + out.etaStrip3.cr11.eta = 3; + out.etaStrip3.cr11.phi = 11; + out.etaStrip3.cr12.energy = temporary[Eta + 3][Phi + 12].energy; + out.etaStrip3.cr12.eta = 3; + out.etaStrip3.cr12.phi = 12; + out.etaStrip3.cr13.energy = temporary[Eta + 3][Phi + 13].energy; + out.etaStrip3.cr13.eta = 3; + out.etaStrip3.cr13.phi = 13; + out.etaStrip3.cr14.energy = temporary[Eta + 3][Phi + 14].energy; + out.etaStrip3.cr14.eta = 3; + out.etaStrip3.cr14.phi = 14; + out.etaStrip3.cr15.energy = temporary[Eta + 3][Phi + 15].energy; + out.etaStrip3.cr15.eta = 3; + out.etaStrip3.cr15.phi = 15; + out.etaStrip3.cr16.energy = temporary[Eta + 3][Phi + 16].energy; + out.etaStrip3.cr16.eta = 3; + out.etaStrip3.cr16.phi = 16; + out.etaStrip3.cr17.energy = temporary[Eta + 3][Phi + 17].energy; + out.etaStrip3.cr17.eta = 3; + out.etaStrip3.cr17.phi = 17; + out.etaStrip3.cr18.energy = temporary[Eta + 3][Phi + 18].energy; + out.etaStrip3.cr18.eta = 3; + out.etaStrip3.cr18.phi = 18; + out.etaStrip3.cr19.energy = temporary[Eta + 3][Phi + 19].energy; + out.etaStrip3.cr19.eta = 3; + out.etaStrip3.cr19.phi = 19; + + out.etaStrip4.cr0.energy = temporary[Eta + 4][Phi + 0].energy; + out.etaStrip4.cr0.eta = 4; + out.etaStrip4.cr0.phi = 0; + out.etaStrip4.cr1.energy = temporary[Eta + 4][Phi + 1].energy; + out.etaStrip4.cr1.eta = 4; + out.etaStrip4.cr1.phi = 1; + out.etaStrip4.cr2.energy = temporary[Eta + 4][Phi + 2].energy; + out.etaStrip4.cr2.eta = 4; + out.etaStrip4.cr2.phi = 2; + out.etaStrip4.cr3.energy = temporary[Eta + 4][Phi + 3].energy; + out.etaStrip4.cr3.eta = 4; + out.etaStrip4.cr3.phi = 3; + out.etaStrip4.cr4.energy = temporary[Eta + 4][Phi + 4].energy; + out.etaStrip4.cr4.eta = 4; + out.etaStrip4.cr4.phi = 4; + out.etaStrip4.cr5.energy = temporary[Eta + 4][Phi + 5].energy; + out.etaStrip4.cr5.eta = 4; + out.etaStrip4.cr5.phi = 5; + out.etaStrip4.cr6.energy = temporary[Eta + 4][Phi + 6].energy; + out.etaStrip4.cr6.eta = 4; + out.etaStrip4.cr6.phi = 6; + out.etaStrip4.cr7.energy = temporary[Eta + 4][Phi + 7].energy; + out.etaStrip4.cr7.eta = 4; + out.etaStrip4.cr7.phi = 7; + out.etaStrip4.cr8.energy = temporary[Eta + 4][Phi + 8].energy; + out.etaStrip4.cr8.eta = 4; + out.etaStrip4.cr8.phi = 8; + out.etaStrip4.cr9.energy = temporary[Eta + 4][Phi + 9].energy; + out.etaStrip4.cr9.eta = 4; + out.etaStrip4.cr9.phi = 9; + out.etaStrip4.cr10.energy = temporary[Eta + 4][Phi + 10].energy; + out.etaStrip4.cr10.eta = 4; + out.etaStrip4.cr10.phi = 10; + out.etaStrip4.cr11.energy = temporary[Eta + 4][Phi + 11].energy; + out.etaStrip4.cr11.eta = 4; + out.etaStrip4.cr11.phi = 11; + out.etaStrip4.cr12.energy = temporary[Eta + 4][Phi + 12].energy; + out.etaStrip4.cr12.eta = 4; + out.etaStrip4.cr12.phi = 12; + out.etaStrip4.cr13.energy = temporary[Eta + 4][Phi + 13].energy; + out.etaStrip4.cr13.eta = 4; + out.etaStrip4.cr13.phi = 13; + out.etaStrip4.cr14.energy = temporary[Eta + 4][Phi + 14].energy; + out.etaStrip4.cr14.eta = 4; + out.etaStrip4.cr14.phi = 14; + out.etaStrip4.cr15.energy = temporary[Eta + 4][Phi + 15].energy; + out.etaStrip4.cr15.eta = 4; + out.etaStrip4.cr15.phi = 15; + out.etaStrip4.cr16.energy = temporary[Eta + 4][Phi + 16].energy; + out.etaStrip4.cr16.eta = 4; + out.etaStrip4.cr16.phi = 16; + out.etaStrip4.cr17.energy = temporary[Eta + 4][Phi + 17].energy; + out.etaStrip4.cr17.eta = 4; + out.etaStrip4.cr17.phi = 17; + out.etaStrip4.cr18.energy = temporary[Eta + 4][Phi + 18].energy; + out.etaStrip4.cr18.eta = 4; + out.etaStrip4.cr18.phi = 18; + out.etaStrip4.cr19.energy = temporary[Eta + 4][Phi + 19].energy; + out.etaStrip4.cr19.eta = 4; + out.etaStrip4.cr19.phi = 19; + + out.etaStrip5.cr0.energy = temporary[Eta + 5][Phi + 0].energy; + out.etaStrip5.cr0.eta = 5; + out.etaStrip5.cr0.phi = 0; + out.etaStrip5.cr1.energy = temporary[Eta + 5][Phi + 1].energy; + out.etaStrip5.cr1.eta = 5; + out.etaStrip5.cr1.phi = 1; + out.etaStrip5.cr2.energy = temporary[Eta + 5][Phi + 2].energy; + out.etaStrip5.cr2.eta = 5; + out.etaStrip5.cr2.phi = 2; + out.etaStrip5.cr3.energy = temporary[Eta + 5][Phi + 3].energy; + out.etaStrip5.cr3.eta = 5; + out.etaStrip5.cr3.phi = 3; + out.etaStrip5.cr4.energy = temporary[Eta + 5][Phi + 4].energy; + out.etaStrip5.cr4.eta = 5; + out.etaStrip5.cr4.phi = 4; + out.etaStrip5.cr5.energy = temporary[Eta + 5][Phi + 5].energy; + out.etaStrip5.cr5.eta = 5; + out.etaStrip5.cr5.phi = 5; + out.etaStrip5.cr6.energy = temporary[Eta + 5][Phi + 6].energy; + out.etaStrip5.cr6.eta = 5; + out.etaStrip5.cr6.phi = 6; + out.etaStrip5.cr7.energy = temporary[Eta + 5][Phi + 7].energy; + out.etaStrip5.cr7.eta = 5; + out.etaStrip5.cr7.phi = 7; + out.etaStrip5.cr8.energy = temporary[Eta + 5][Phi + 8].energy; + out.etaStrip5.cr8.eta = 5; + out.etaStrip5.cr8.phi = 8; + out.etaStrip5.cr9.energy = temporary[Eta + 5][Phi + 9].energy; + out.etaStrip5.cr9.eta = 5; + out.etaStrip5.cr9.phi = 9; + out.etaStrip5.cr10.energy = temporary[Eta + 5][Phi + 10].energy; + out.etaStrip5.cr10.eta = 5; + out.etaStrip5.cr10.phi = 10; + out.etaStrip5.cr11.energy = temporary[Eta + 5][Phi + 11].energy; + out.etaStrip5.cr11.eta = 5; + out.etaStrip5.cr11.phi = 11; + out.etaStrip5.cr12.energy = temporary[Eta + 5][Phi + 12].energy; + out.etaStrip5.cr12.eta = 5; + out.etaStrip5.cr12.phi = 12; + out.etaStrip5.cr13.energy = temporary[Eta + 5][Phi + 13].energy; + out.etaStrip5.cr13.eta = 5; + out.etaStrip5.cr13.phi = 13; + out.etaStrip5.cr14.energy = temporary[Eta + 5][Phi + 14].energy; + out.etaStrip5.cr14.eta = 5; + out.etaStrip5.cr14.phi = 14; + out.etaStrip5.cr15.energy = temporary[Eta + 5][Phi + 15].energy; + out.etaStrip5.cr15.eta = 5; + out.etaStrip5.cr15.phi = 15; + out.etaStrip5.cr16.energy = temporary[Eta + 5][Phi + 16].energy; + out.etaStrip5.cr16.eta = 5; + out.etaStrip5.cr16.phi = 16; + out.etaStrip5.cr17.energy = temporary[Eta + 5][Phi + 17].energy; + out.etaStrip5.cr17.eta = 5; + out.etaStrip5.cr17.phi = 17; + out.etaStrip5.cr18.energy = temporary[Eta + 5][Phi + 18].energy; + out.etaStrip5.cr18.eta = 5; + out.etaStrip5.cr18.phi = 18; + out.etaStrip5.cr19.energy = temporary[Eta + 5][Phi + 19].energy; + out.etaStrip5.cr19.eta = 5; + out.etaStrip5.cr19.phi = 19; + + out.etaStrip6.cr0.energy = temporary[Eta + 6][Phi + 0].energy; + out.etaStrip6.cr0.eta = 6; + out.etaStrip6.cr0.phi = 0; + out.etaStrip6.cr1.energy = temporary[Eta + 6][Phi + 1].energy; + out.etaStrip6.cr1.eta = 6; + out.etaStrip6.cr1.phi = 1; + out.etaStrip6.cr2.energy = temporary[Eta + 6][Phi + 2].energy; + out.etaStrip6.cr2.eta = 6; + out.etaStrip6.cr2.phi = 2; + out.etaStrip6.cr2.energy = temporary[Eta + 6][Phi + 2].energy; + out.etaStrip6.cr2.eta = 6; + out.etaStrip6.cr2.phi = 2; + out.etaStrip6.cr3.energy = temporary[Eta + 6][Phi + 3].energy; + out.etaStrip6.cr3.eta = 6; + out.etaStrip6.cr3.phi = 3; + out.etaStrip6.cr4.energy = temporary[Eta + 6][Phi + 4].energy; + out.etaStrip6.cr4.eta = 6; + out.etaStrip6.cr4.phi = 4; + out.etaStrip6.cr5.energy = temporary[Eta + 6][Phi + 5].energy; + out.etaStrip6.cr5.eta = 6; + out.etaStrip6.cr5.phi = 5; + out.etaStrip6.cr6.energy = temporary[Eta + 6][Phi + 6].energy; + out.etaStrip6.cr6.eta = 6; + out.etaStrip6.cr6.phi = 6; + out.etaStrip6.cr7.energy = temporary[Eta + 6][Phi + 7].energy; + out.etaStrip6.cr7.eta = 6; + out.etaStrip6.cr7.phi = 7; + out.etaStrip6.cr8.energy = temporary[Eta + 6][Phi + 8].energy; + out.etaStrip6.cr8.eta = 6; + out.etaStrip6.cr8.phi = 8; + out.etaStrip6.cr9.energy = temporary[Eta + 6][Phi + 9].energy; + out.etaStrip6.cr9.eta = 6; + out.etaStrip6.cr9.phi = 9; + out.etaStrip6.cr10.energy = temporary[Eta + 6][Phi + 10].energy; + out.etaStrip6.cr10.eta = 6; + out.etaStrip6.cr10.phi = 10; + out.etaStrip6.cr11.energy = temporary[Eta + 6][Phi + 11].energy; + out.etaStrip6.cr11.eta = 6; + out.etaStrip6.cr11.phi = 11; + out.etaStrip6.cr12.energy = temporary[Eta + 6][Phi + 12].energy; + out.etaStrip6.cr12.eta = 6; + out.etaStrip6.cr12.phi = 12; + out.etaStrip6.cr13.energy = temporary[Eta + 6][Phi + 13].energy; + out.etaStrip6.cr13.eta = 6; + out.etaStrip6.cr13.phi = 13; + out.etaStrip6.cr14.energy = temporary[Eta + 6][Phi + 14].energy; + out.etaStrip6.cr14.eta = 6; + out.etaStrip6.cr14.phi = 14; + out.etaStrip6.cr15.energy = temporary[Eta + 6][Phi + 15].energy; + out.etaStrip6.cr15.eta = 6; + out.etaStrip6.cr15.phi = 15; + out.etaStrip6.cr16.energy = temporary[Eta + 6][Phi + 16].energy; + out.etaStrip6.cr16.eta = 6; + out.etaStrip6.cr16.phi = 16; + out.etaStrip6.cr17.energy = temporary[Eta + 6][Phi + 17].energy; + out.etaStrip6.cr17.eta = 6; + out.etaStrip6.cr17.phi = 17; + out.etaStrip6.cr18.energy = temporary[Eta + 6][Phi + 18].energy; + out.etaStrip6.cr18.eta = 6; + out.etaStrip6.cr18.phi = 18; + out.etaStrip6.cr19.energy = temporary[Eta + 6][Phi + 19].energy; + out.etaStrip6.cr19.eta = 6; + out.etaStrip6.cr19.phi = 19; + + out.etaStrip7.cr0.energy = temporary[Eta + 7][Phi + 0].energy; + out.etaStrip7.cr0.eta = 7; + out.etaStrip7.cr0.phi = 0; + out.etaStrip7.cr1.energy = temporary[Eta + 7][Phi + 1].energy; + out.etaStrip7.cr1.eta = 7; + out.etaStrip7.cr1.phi = 1; + out.etaStrip7.cr2.energy = temporary[Eta + 7][Phi + 2].energy; + out.etaStrip7.cr2.eta = 7; + out.etaStrip7.cr2.phi = 2; + out.etaStrip7.cr3.energy = temporary[Eta + 7][Phi + 3].energy; + out.etaStrip7.cr3.eta = 7; + out.etaStrip7.cr3.phi = 3; + out.etaStrip7.cr4.energy = temporary[Eta + 7][Phi + 4].energy; + out.etaStrip7.cr4.eta = 7; + out.etaStrip7.cr4.phi = 4; + out.etaStrip7.cr5.energy = temporary[Eta + 7][Phi + 5].energy; + out.etaStrip7.cr5.eta = 7; + out.etaStrip7.cr5.phi = 5; + out.etaStrip7.cr6.energy = temporary[Eta + 7][Phi + 6].energy; + out.etaStrip7.cr6.eta = 7; + out.etaStrip7.cr6.phi = 6; + out.etaStrip7.cr7.energy = temporary[Eta + 7][Phi + 7].energy; + out.etaStrip7.cr7.eta = 7; + out.etaStrip7.cr7.phi = 7; + out.etaStrip7.cr8.energy = temporary[Eta + 7][Phi + 8].energy; + out.etaStrip7.cr8.eta = 7; + out.etaStrip7.cr8.phi = 8; + out.etaStrip7.cr9.energy = temporary[Eta + 7][Phi + 9].energy; + out.etaStrip7.cr9.eta = 7; + out.etaStrip7.cr9.phi = 9; + out.etaStrip7.cr10.energy = temporary[Eta + 7][Phi + 10].energy; + out.etaStrip7.cr10.eta = 7; + out.etaStrip7.cr10.phi = 10; + out.etaStrip7.cr11.energy = temporary[Eta + 7][Phi + 11].energy; + out.etaStrip7.cr11.eta = 7; + out.etaStrip7.cr11.phi = 11; + out.etaStrip7.cr12.energy = temporary[Eta + 7][Phi + 12].energy; + out.etaStrip7.cr12.eta = 7; + out.etaStrip7.cr12.phi = 12; + out.etaStrip7.cr13.energy = temporary[Eta + 7][Phi + 13].energy; + out.etaStrip7.cr13.eta = 7; + out.etaStrip7.cr13.phi = 13; + out.etaStrip7.cr14.energy = temporary[Eta + 7][Phi + 14].energy; + out.etaStrip7.cr14.eta = 7; + out.etaStrip7.cr14.phi = 14; + out.etaStrip7.cr15.energy = temporary[Eta + 7][Phi + 15].energy; + out.etaStrip7.cr15.eta = 7; + out.etaStrip7.cr15.phi = 15; + out.etaStrip7.cr16.energy = temporary[Eta + 7][Phi + 16].energy; + out.etaStrip7.cr16.eta = 7; + out.etaStrip7.cr16.phi = 16; + out.etaStrip7.cr17.energy = temporary[Eta + 7][Phi + 17].energy; + out.etaStrip7.cr17.eta = 7; + out.etaStrip7.cr17.phi = 17; + out.etaStrip7.cr18.energy = temporary[Eta + 7][Phi + 18].energy; + out.etaStrip7.cr18.eta = 7; + out.etaStrip7.cr18.phi = 18; + out.etaStrip7.cr19.energy = temporary[Eta + 7][Phi + 19].energy; + out.etaStrip7.cr19.eta = 7; + out.etaStrip7.cr19.phi = 19; + + out.etaStrip8.cr0.energy = temporary[Eta + 8][Phi + 0].energy; + out.etaStrip8.cr0.eta = 8; + out.etaStrip8.cr0.phi = 0; + out.etaStrip8.cr1.energy = temporary[Eta + 8][Phi + 1].energy; + out.etaStrip8.cr1.eta = 8; + out.etaStrip8.cr1.phi = 1; + out.etaStrip8.cr2.energy = temporary[Eta + 8][Phi + 2].energy; + out.etaStrip8.cr2.eta = 8; + out.etaStrip8.cr2.phi = 2; + out.etaStrip8.cr3.energy = temporary[Eta + 8][Phi + 3].energy; + out.etaStrip8.cr3.eta = 8; + out.etaStrip8.cr3.phi = 3; + out.etaStrip8.cr4.energy = temporary[Eta + 8][Phi + 4].energy; + out.etaStrip8.cr4.eta = 8; + out.etaStrip8.cr4.phi = 4; + out.etaStrip8.cr5.energy = temporary[Eta + 8][Phi + 5].energy; + out.etaStrip8.cr5.eta = 8; + out.etaStrip8.cr5.phi = 5; + out.etaStrip8.cr6.energy = temporary[Eta + 8][Phi + 6].energy; + out.etaStrip8.cr6.eta = 8; + out.etaStrip8.cr6.phi = 6; + out.etaStrip8.cr7.energy = temporary[Eta + 8][Phi + 7].energy; + out.etaStrip8.cr7.eta = 8; + out.etaStrip8.cr7.phi = 7; + out.etaStrip8.cr8.energy = temporary[Eta + 8][Phi + 8].energy; + out.etaStrip8.cr8.eta = 8; + out.etaStrip8.cr8.phi = 8; + out.etaStrip8.cr9.energy = temporary[Eta + 8][Phi + 9].energy; + out.etaStrip8.cr9.eta = 8; + out.etaStrip8.cr9.phi = 9; + out.etaStrip8.cr10.energy = temporary[Eta + 8][Phi + 10].energy; + out.etaStrip8.cr10.eta = 8; + out.etaStrip8.cr10.phi = 10; + out.etaStrip8.cr11.energy = temporary[Eta + 8][Phi + 11].energy; + out.etaStrip8.cr11.eta = 8; + out.etaStrip8.cr11.phi = 11; + out.etaStrip8.cr12.energy = temporary[Eta + 8][Phi + 12].energy; + out.etaStrip8.cr12.eta = 8; + out.etaStrip8.cr12.phi = 12; + out.etaStrip8.cr13.energy = temporary[Eta + 8][Phi + 13].energy; + out.etaStrip8.cr13.eta = 8; + out.etaStrip8.cr13.phi = 13; + out.etaStrip8.cr14.energy = temporary[Eta + 8][Phi + 14].energy; + out.etaStrip8.cr14.eta = 8; + out.etaStrip8.cr14.phi = 14; + out.etaStrip8.cr15.energy = temporary[Eta + 8][Phi + 15].energy; + out.etaStrip8.cr15.eta = 8; + out.etaStrip8.cr15.phi = 15; + out.etaStrip8.cr16.energy = temporary[Eta + 8][Phi + 16].energy; + out.etaStrip8.cr16.eta = 8; + out.etaStrip8.cr16.phi = 16; + out.etaStrip8.cr17.energy = temporary[Eta + 8][Phi + 17].energy; + out.etaStrip8.cr17.eta = 8; + out.etaStrip8.cr17.phi = 17; + out.etaStrip8.cr18.energy = temporary[Eta + 8][Phi + 18].energy; + out.etaStrip8.cr18.eta = 8; + out.etaStrip8.cr18.phi = 18; + out.etaStrip8.cr19.energy = temporary[Eta + 8][Phi + 19].energy; + out.etaStrip8.cr19.eta = 8; + out.etaStrip8.cr19.phi = 19; + + out.etaStrip9.cr0.energy = temporary[Eta + 9][Phi + 0].energy; + out.etaStrip9.cr0.eta = 9; + out.etaStrip9.cr0.phi = 0; + out.etaStrip9.cr1.energy = temporary[Eta + 9][Phi + 1].energy; + out.etaStrip9.cr1.eta = 9; + out.etaStrip9.cr1.phi = 1; + out.etaStrip9.cr2.energy = temporary[Eta + 9][Phi + 2].energy; + out.etaStrip9.cr2.eta = 9; + out.etaStrip9.cr2.phi = 2; + out.etaStrip9.cr3.energy = temporary[Eta + 9][Phi + 3].energy; + out.etaStrip9.cr3.eta = 9; + out.etaStrip9.cr3.phi = 3; + out.etaStrip9.cr4.energy = temporary[Eta + 9][Phi + 4].energy; + out.etaStrip9.cr4.eta = 9; + out.etaStrip9.cr4.phi = 4; + out.etaStrip9.cr5.energy = temporary[Eta + 9][Phi + 5].energy; + out.etaStrip9.cr5.eta = 9; + out.etaStrip9.cr5.phi = 5; + out.etaStrip9.cr6.energy = temporary[Eta + 9][Phi + 6].energy; + out.etaStrip9.cr6.eta = 9; + out.etaStrip9.cr6.phi = 6; + out.etaStrip9.cr7.energy = temporary[Eta + 9][Phi + 7].energy; + out.etaStrip9.cr7.eta = 9; + out.etaStrip9.cr7.phi = 7; + out.etaStrip9.cr8.energy = temporary[Eta + 9][Phi + 8].energy; + out.etaStrip9.cr8.eta = 9; + out.etaStrip9.cr8.phi = 8; + out.etaStrip9.cr9.energy = temporary[Eta + 9][Phi + 9].energy; + out.etaStrip9.cr9.eta = 9; + out.etaStrip9.cr9.phi = 9; + out.etaStrip9.cr10.energy = temporary[Eta + 9][Phi + 10].energy; + out.etaStrip9.cr10.eta = 9; + out.etaStrip9.cr10.phi = 10; + out.etaStrip9.cr11.energy = temporary[Eta + 9][Phi + 11].energy; + out.etaStrip9.cr11.eta = 9; + out.etaStrip9.cr11.phi = 11; + out.etaStrip9.cr12.energy = temporary[Eta + 9][Phi + 12].energy; + out.etaStrip9.cr12.eta = 9; + out.etaStrip9.cr12.phi = 12; + out.etaStrip9.cr13.energy = temporary[Eta + 9][Phi + 13].energy; + out.etaStrip9.cr13.eta = 9; + out.etaStrip9.cr13.phi = 13; + out.etaStrip9.cr14.energy = temporary[Eta + 9][Phi + 14].energy; + out.etaStrip9.cr14.eta = 9; + out.etaStrip9.cr14.phi = 14; + out.etaStrip9.cr15.energy = temporary[Eta + 9][Phi + 15].energy; + out.etaStrip9.cr15.eta = 9; + out.etaStrip9.cr15.phi = 15; + out.etaStrip9.cr16.energy = temporary[Eta + 9][Phi + 16].energy; + out.etaStrip9.cr16.eta = 9; + out.etaStrip9.cr16.phi = 16; + out.etaStrip9.cr17.energy = temporary[Eta + 9][Phi + 17].energy; + out.etaStrip9.cr17.eta = 9; + out.etaStrip9.cr17.phi = 17; + out.etaStrip9.cr18.energy = temporary[Eta + 9][Phi + 18].energy; + out.etaStrip9.cr18.eta = 9; + out.etaStrip9.cr18.phi = 18; + out.etaStrip9.cr19.energy = temporary[Eta + 9][Phi + 19].energy; + out.etaStrip9.cr19.eta = 9; + out.etaStrip9.cr19.phi = 19; + + out.etaStrip10.cr0.energy = temporary[Eta + 10][Phi + 0].energy; + out.etaStrip10.cr0.eta = 10; + out.etaStrip10.cr0.phi = 0; + out.etaStrip10.cr1.energy = temporary[Eta + 10][Phi + 1].energy; + out.etaStrip10.cr1.eta = 10; + out.etaStrip10.cr1.phi = 1; + out.etaStrip10.cr2.energy = temporary[Eta + 10][Phi + 2].energy; + out.etaStrip10.cr2.eta = 10; + out.etaStrip10.cr2.phi = 2; + out.etaStrip10.cr3.energy = temporary[Eta + 10][Phi + 3].energy; + out.etaStrip10.cr3.eta = 10; + out.etaStrip10.cr3.phi = 3; + out.etaStrip10.cr4.energy = temporary[Eta + 10][Phi + 4].energy; + out.etaStrip10.cr4.eta = 10; + out.etaStrip10.cr4.phi = 4; + out.etaStrip10.cr5.energy = temporary[Eta + 10][Phi + 5].energy; + out.etaStrip10.cr5.eta = 10; + out.etaStrip10.cr5.phi = 5; + out.etaStrip10.cr6.energy = temporary[Eta + 10][Phi + 6].energy; + out.etaStrip10.cr6.eta = 10; + out.etaStrip10.cr6.phi = 6; + out.etaStrip10.cr7.energy = temporary[Eta + 10][Phi + 7].energy; + out.etaStrip10.cr7.eta = 10; + out.etaStrip10.cr7.phi = 7; + out.etaStrip10.cr8.energy = temporary[Eta + 10][Phi + 8].energy; + out.etaStrip10.cr8.eta = 10; + out.etaStrip10.cr8.phi = 8; + out.etaStrip10.cr9.energy = temporary[Eta + 10][Phi + 9].energy; + out.etaStrip10.cr9.eta = 10; + out.etaStrip10.cr9.phi = 9; + out.etaStrip10.cr10.energy = temporary[Eta + 10][Phi + 10].energy; + out.etaStrip10.cr10.eta = 10; + out.etaStrip10.cr10.phi = 10; + out.etaStrip10.cr11.energy = temporary[Eta + 10][Phi + 11].energy; + out.etaStrip10.cr11.eta = 10; + out.etaStrip10.cr11.phi = 11; + out.etaStrip10.cr12.energy = temporary[Eta + 10][Phi + 12].energy; + out.etaStrip10.cr12.eta = 10; + out.etaStrip10.cr12.phi = 12; + out.etaStrip10.cr13.energy = temporary[Eta + 10][Phi + 13].energy; + out.etaStrip10.cr13.eta = 10; + out.etaStrip10.cr13.phi = 13; + out.etaStrip10.cr14.energy = temporary[Eta + 10][Phi + 14].energy; + out.etaStrip10.cr14.eta = 10; + out.etaStrip10.cr14.phi = 14; + out.etaStrip10.cr15.energy = temporary[Eta + 10][Phi + 15].energy; + out.etaStrip10.cr15.eta = 10; + out.etaStrip10.cr15.phi = 15; + out.etaStrip10.cr16.energy = temporary[Eta + 10][Phi + 16].energy; + out.etaStrip10.cr16.eta = 10; + out.etaStrip10.cr16.phi = 16; + out.etaStrip10.cr17.energy = temporary[Eta + 10][Phi + 17].energy; + out.etaStrip10.cr17.eta = 10; + out.etaStrip10.cr17.phi = 17; + out.etaStrip10.cr18.energy = temporary[Eta + 10][Phi + 18].energy; + out.etaStrip10.cr18.eta = 10; + out.etaStrip10.cr18.phi = 18; + out.etaStrip10.cr19.energy = temporary[Eta + 10][Phi + 19].energy; + out.etaStrip10.cr19.eta = 10; + out.etaStrip10.cr19.phi = 19; + + out.etaStrip11.cr0.energy = temporary[Eta + 11][Phi + 0].energy; + out.etaStrip11.cr0.eta = 11; + out.etaStrip11.cr0.phi = 0; + out.etaStrip11.cr1.energy = temporary[Eta + 11][Phi + 1].energy; + out.etaStrip11.cr1.eta = 11; + out.etaStrip11.cr1.phi = 1; + out.etaStrip11.cr2.energy = temporary[Eta + 11][Phi + 2].energy; + out.etaStrip11.cr2.eta = 11; + out.etaStrip11.cr2.phi = 2; + out.etaStrip11.cr3.energy = temporary[Eta + 11][Phi + 3].energy; + out.etaStrip11.cr3.eta = 11; + out.etaStrip11.cr3.phi = 3; + out.etaStrip11.cr4.energy = temporary[Eta + 11][Phi + 4].energy; + out.etaStrip11.cr4.eta = 11; + out.etaStrip11.cr4.phi = 4; + out.etaStrip11.cr5.energy = temporary[Eta + 11][Phi + 5].energy; + out.etaStrip11.cr5.eta = 11; + out.etaStrip11.cr5.phi = 5; + out.etaStrip11.cr6.energy = temporary[Eta + 11][Phi + 6].energy; + out.etaStrip11.cr6.eta = 11; + out.etaStrip11.cr6.phi = 6; + out.etaStrip11.cr7.energy = temporary[Eta + 11][Phi + 7].energy; + out.etaStrip11.cr7.eta = 11; + out.etaStrip11.cr7.phi = 7; + out.etaStrip11.cr8.energy = temporary[Eta + 11][Phi + 8].energy; + out.etaStrip11.cr8.eta = 11; + out.etaStrip11.cr8.phi = 8; + out.etaStrip11.cr9.energy = temporary[Eta + 11][Phi + 9].energy; + out.etaStrip11.cr9.eta = 11; + out.etaStrip11.cr9.phi = 9; + out.etaStrip11.cr10.energy = temporary[Eta + 11][Phi + 10].energy; + out.etaStrip11.cr10.eta = 11; + out.etaStrip11.cr10.phi = 10; + out.etaStrip11.cr11.energy = temporary[Eta + 11][Phi + 11].energy; + out.etaStrip11.cr11.eta = 11; + out.etaStrip11.cr11.phi = 11; + out.etaStrip11.cr12.energy = temporary[Eta + 11][Phi + 12].energy; + out.etaStrip11.cr12.eta = 11; + out.etaStrip11.cr12.phi = 12; + out.etaStrip11.cr13.energy = temporary[Eta + 11][Phi + 13].energy; + out.etaStrip11.cr13.eta = 11; + out.etaStrip11.cr13.phi = 13; + out.etaStrip11.cr14.energy = temporary[Eta + 11][Phi + 14].energy; + out.etaStrip11.cr14.eta = 11; + out.etaStrip11.cr14.phi = 14; + out.etaStrip11.cr15.energy = temporary[Eta + 11][Phi + 15].energy; + out.etaStrip11.cr15.eta = 11; + out.etaStrip11.cr15.phi = 15; + out.etaStrip11.cr16.energy = temporary[Eta + 11][Phi + 16].energy; + out.etaStrip11.cr16.eta = 11; + out.etaStrip11.cr16.phi = 16; + out.etaStrip11.cr17.energy = temporary[Eta + 11][Phi + 17].energy; + out.etaStrip11.cr17.eta = 11; + out.etaStrip11.cr17.phi = 17; + out.etaStrip11.cr18.energy = temporary[Eta + 11][Phi + 18].energy; + out.etaStrip11.cr18.eta = 11; + out.etaStrip11.cr18.phi = 18; + out.etaStrip11.cr19.energy = temporary[Eta + 11][Phi + 19].energy; + out.etaStrip11.cr19.eta = 11; + out.etaStrip11.cr19.phi = 19; + + out.etaStrip12.cr0.energy = temporary[Eta + 12][Phi + 0].energy; + out.etaStrip12.cr0.eta = 12; + out.etaStrip12.cr0.phi = 0; + out.etaStrip12.cr1.energy = temporary[Eta + 12][Phi + 1].energy; + out.etaStrip12.cr1.eta = 12; + out.etaStrip12.cr1.phi = 1; + out.etaStrip12.cr2.energy = temporary[Eta + 12][Phi + 2].energy; + out.etaStrip12.cr2.eta = 12; + out.etaStrip12.cr2.phi = 2; + out.etaStrip12.cr3.energy = temporary[Eta + 12][Phi + 3].energy; + out.etaStrip12.cr3.eta = 12; + out.etaStrip12.cr3.phi = 3; + out.etaStrip12.cr4.energy = temporary[Eta + 12][Phi + 4].energy; + out.etaStrip12.cr4.eta = 12; + out.etaStrip12.cr4.phi = 4; + out.etaStrip12.cr5.energy = temporary[Eta + 12][Phi + 5].energy; + out.etaStrip12.cr5.eta = 12; + out.etaStrip12.cr5.phi = 5; + out.etaStrip12.cr6.energy = temporary[Eta + 12][Phi + 6].energy; + out.etaStrip12.cr6.eta = 12; + out.etaStrip12.cr6.phi = 6; + out.etaStrip12.cr7.energy = temporary[Eta + 12][Phi + 7].energy; + out.etaStrip12.cr7.eta = 12; + out.etaStrip12.cr7.phi = 7; + out.etaStrip12.cr8.energy = temporary[Eta + 12][Phi + 8].energy; + out.etaStrip12.cr8.eta = 12; + out.etaStrip12.cr8.phi = 8; + out.etaStrip12.cr9.energy = temporary[Eta + 12][Phi + 9].energy; + out.etaStrip12.cr9.eta = 12; + out.etaStrip12.cr9.phi = 9; + out.etaStrip12.cr10.energy = temporary[Eta + 12][Phi + 10].energy; + out.etaStrip12.cr10.eta = 12; + out.etaStrip12.cr10.phi = 10; + out.etaStrip12.cr11.energy = temporary[Eta + 12][Phi + 11].energy; + out.etaStrip12.cr11.eta = 12; + out.etaStrip12.cr11.phi = 11; + out.etaStrip12.cr12.energy = temporary[Eta + 12][Phi + 12].energy; + out.etaStrip12.cr12.eta = 12; + out.etaStrip12.cr12.phi = 12; + out.etaStrip12.cr13.energy = temporary[Eta + 12][Phi + 13].energy; + out.etaStrip12.cr13.eta = 12; + out.etaStrip12.cr13.phi = 13; + out.etaStrip12.cr14.energy = temporary[Eta + 12][Phi + 14].energy; + out.etaStrip12.cr14.eta = 12; + out.etaStrip12.cr14.phi = 14; + out.etaStrip12.cr15.energy = temporary[Eta + 12][Phi + 15].energy; + out.etaStrip12.cr15.eta = 12; + out.etaStrip12.cr15.phi = 15; + out.etaStrip12.cr16.energy = temporary[Eta + 12][Phi + 16].energy; + out.etaStrip12.cr16.eta = 12; + out.etaStrip12.cr16.phi = 16; + out.etaStrip12.cr17.energy = temporary[Eta + 12][Phi + 17].energy; + out.etaStrip12.cr17.eta = 12; + out.etaStrip12.cr17.phi = 17; + out.etaStrip12.cr18.energy = temporary[Eta + 12][Phi + 18].energy; + out.etaStrip12.cr18.eta = 12; + out.etaStrip12.cr18.phi = 18; + out.etaStrip12.cr19.energy = temporary[Eta + 12][Phi + 19].energy; + out.etaStrip12.cr19.eta = 12; + out.etaStrip12.cr19.phi = 19; + + out.etaStrip13.cr0.energy = temporary[Eta + 13][Phi + 0].energy; + out.etaStrip13.cr0.eta = 13; + out.etaStrip13.cr0.phi = 0; + out.etaStrip13.cr1.energy = temporary[Eta + 13][Phi + 1].energy; + out.etaStrip13.cr1.eta = 13; + out.etaStrip13.cr1.phi = 1; + out.etaStrip13.cr2.energy = temporary[Eta + 13][Phi + 2].energy; + out.etaStrip13.cr2.eta = 13; + out.etaStrip13.cr2.phi = 2; + out.etaStrip13.cr3.energy = temporary[Eta + 13][Phi + 3].energy; + out.etaStrip13.cr3.eta = 13; + out.etaStrip13.cr3.phi = 3; + out.etaStrip13.cr4.energy = temporary[Eta + 13][Phi + 4].energy; + out.etaStrip13.cr4.eta = 13; + out.etaStrip13.cr4.phi = 4; + out.etaStrip13.cr5.energy = temporary[Eta + 13][Phi + 5].energy; + out.etaStrip13.cr5.eta = 13; + out.etaStrip13.cr5.phi = 5; + out.etaStrip13.cr6.energy = temporary[Eta + 13][Phi + 6].energy; + out.etaStrip13.cr6.eta = 13; + out.etaStrip13.cr6.phi = 6; + out.etaStrip13.cr7.energy = temporary[Eta + 13][Phi + 7].energy; + out.etaStrip13.cr7.eta = 13; + out.etaStrip13.cr7.phi = 7; + out.etaStrip13.cr8.energy = temporary[Eta + 13][Phi + 8].energy; + out.etaStrip13.cr8.eta = 13; + out.etaStrip13.cr8.phi = 8; + out.etaStrip13.cr9.energy = temporary[Eta + 13][Phi + 9].energy; + out.etaStrip13.cr9.eta = 13; + out.etaStrip13.cr9.phi = 9; + out.etaStrip13.cr10.energy = temporary[Eta + 13][Phi + 10].energy; + out.etaStrip13.cr10.eta = 13; + out.etaStrip13.cr10.phi = 10; + out.etaStrip13.cr11.energy = temporary[Eta + 13][Phi + 11].energy; + out.etaStrip13.cr11.eta = 13; + out.etaStrip13.cr11.phi = 11; + out.etaStrip13.cr12.energy = temporary[Eta + 13][Phi + 12].energy; + out.etaStrip13.cr12.eta = 13; + out.etaStrip13.cr12.phi = 12; + out.etaStrip13.cr13.energy = temporary[Eta + 13][Phi + 13].energy; + out.etaStrip13.cr13.eta = 13; + out.etaStrip13.cr13.phi = 13; + out.etaStrip13.cr14.energy = temporary[Eta + 13][Phi + 14].energy; + out.etaStrip13.cr14.eta = 13; + out.etaStrip13.cr14.phi = 14; + out.etaStrip13.cr15.energy = temporary[Eta + 13][Phi + 15].energy; + out.etaStrip13.cr15.eta = 13; + out.etaStrip13.cr15.phi = 15; + out.etaStrip13.cr16.energy = temporary[Eta + 13][Phi + 16].energy; + out.etaStrip13.cr16.eta = 13; + out.etaStrip13.cr16.phi = 16; + out.etaStrip13.cr17.energy = temporary[Eta + 13][Phi + 17].energy; + out.etaStrip13.cr17.eta = 13; + out.etaStrip13.cr17.phi = 17; + out.etaStrip13.cr18.energy = temporary[Eta + 13][Phi + 18].energy; + out.etaStrip13.cr18.eta = 13; + out.etaStrip13.cr18.phi = 18; + out.etaStrip13.cr19.energy = temporary[Eta + 13][Phi + 19].energy; + out.etaStrip13.cr19.eta = 13; + out.etaStrip13.cr19.phi = 19; + + out.etaStrip14.cr0.energy = temporary[Eta + 14][Phi + 0].energy; + out.etaStrip14.cr0.eta = 14; + out.etaStrip14.cr0.phi = 0; + out.etaStrip14.cr1.energy = temporary[Eta + 14][Phi + 1].energy; + out.etaStrip14.cr1.eta = 14; + out.etaStrip14.cr1.phi = 1; + out.etaStrip14.cr2.energy = temporary[Eta + 14][Phi + 2].energy; + out.etaStrip14.cr2.eta = 14; + out.etaStrip14.cr2.phi = 2; + out.etaStrip14.cr3.energy = temporary[Eta + 14][Phi + 3].energy; + out.etaStrip14.cr3.eta = 14; + out.etaStrip14.cr3.phi = 3; + out.etaStrip14.cr4.energy = temporary[Eta + 14][Phi + 4].energy; + out.etaStrip14.cr4.eta = 14; + out.etaStrip14.cr4.phi = 4; + out.etaStrip14.cr5.energy = temporary[Eta + 14][Phi + 5].energy; + out.etaStrip14.cr5.eta = 14; + out.etaStrip14.cr5.phi = 5; + out.etaStrip14.cr6.energy = temporary[Eta + 14][Phi + 6].energy; + out.etaStrip14.cr6.eta = 14; + out.etaStrip14.cr6.phi = 6; + out.etaStrip14.cr7.energy = temporary[Eta + 14][Phi + 7].energy; + out.etaStrip14.cr7.eta = 14; + out.etaStrip14.cr7.phi = 7; + out.etaStrip14.cr8.energy = temporary[Eta + 14][Phi + 8].energy; + out.etaStrip14.cr8.eta = 14; + out.etaStrip14.cr8.phi = 8; + out.etaStrip14.cr9.energy = temporary[Eta + 14][Phi + 9].energy; + out.etaStrip14.cr9.eta = 14; + out.etaStrip14.cr9.phi = 9; + out.etaStrip14.cr10.energy = temporary[Eta + 14][Phi + 10].energy; + out.etaStrip14.cr10.eta = 14; + out.etaStrip14.cr10.phi = 10; + out.etaStrip14.cr11.energy = temporary[Eta + 14][Phi + 11].energy; + out.etaStrip14.cr11.eta = 14; + out.etaStrip14.cr11.phi = 11; + out.etaStrip14.cr12.energy = temporary[Eta + 14][Phi + 12].energy; + out.etaStrip14.cr12.eta = 14; + out.etaStrip14.cr12.phi = 12; + out.etaStrip14.cr13.energy = temporary[Eta + 14][Phi + 13].energy; + out.etaStrip14.cr13.eta = 14; + out.etaStrip14.cr13.phi = 13; + out.etaStrip14.cr14.energy = temporary[Eta + 14][Phi + 14].energy; + out.etaStrip14.cr14.eta = 14; + out.etaStrip14.cr14.phi = 14; + out.etaStrip14.cr15.energy = temporary[Eta + 14][Phi + 15].energy; + out.etaStrip14.cr15.eta = 14; + out.etaStrip14.cr15.phi = 15; + out.etaStrip14.cr16.energy = temporary[Eta + 14][Phi + 16].energy; + out.etaStrip14.cr16.eta = 14; + out.etaStrip14.cr16.phi = 16; + out.etaStrip14.cr17.energy = temporary[Eta + 14][Phi + 17].energy; + out.etaStrip14.cr17.eta = 14; + out.etaStrip14.cr17.phi = 17; + out.etaStrip14.cr18.energy = temporary[Eta + 14][Phi + 18].energy; + out.etaStrip14.cr18.eta = 14; + out.etaStrip14.cr18.phi = 18; + out.etaStrip14.cr19.energy = temporary[Eta + 14][Phi + 19].energy; + out.etaStrip14.cr19.eta = 14; + out.etaStrip14.cr19.phi = 19; + + return out; +} + +//--------------------------------------------------------// + +// Compare two ecaltp_t and return the one with the larger pT. +inline p2eg::ecaltp_t p2eg::bestOf2(const p2eg::ecaltp_t ecaltp0, const p2eg::ecaltp_t ecaltp1) { + p2eg::ecaltp_t x; + x = (ecaltp0.energy > ecaltp1.energy) ? ecaltp0 : ecaltp1; + + return x; +} + +//--------------------------------------------------------// + +// For a given etaStrip_t, find the ecaltp_t (out of 20 of them) with the largest pT, using pairwise comparison +inline p2eg::ecaltp_t p2eg::getPeakBin20N(const p2eg::etaStrip_t etaStrip) { + p2eg::ecaltp_t best01 = p2eg::bestOf2(etaStrip.cr0, etaStrip.cr1); + p2eg::ecaltp_t best23 = p2eg::bestOf2(etaStrip.cr2, etaStrip.cr3); + p2eg::ecaltp_t best45 = p2eg::bestOf2(etaStrip.cr4, etaStrip.cr5); + p2eg::ecaltp_t best67 = p2eg::bestOf2(etaStrip.cr6, etaStrip.cr7); + p2eg::ecaltp_t best89 = p2eg::bestOf2(etaStrip.cr8, etaStrip.cr9); + p2eg::ecaltp_t best1011 = p2eg::bestOf2(etaStrip.cr10, etaStrip.cr11); + p2eg::ecaltp_t best1213 = p2eg::bestOf2(etaStrip.cr12, etaStrip.cr13); + p2eg::ecaltp_t best1415 = p2eg::bestOf2(etaStrip.cr14, etaStrip.cr15); + p2eg::ecaltp_t best1617 = p2eg::bestOf2(etaStrip.cr16, etaStrip.cr17); + p2eg::ecaltp_t best1819 = p2eg::bestOf2(etaStrip.cr18, etaStrip.cr19); + + p2eg::ecaltp_t best0123 = p2eg::bestOf2(best01, best23); + p2eg::ecaltp_t best4567 = p2eg::bestOf2(best45, best67); + p2eg::ecaltp_t best891011 = p2eg::bestOf2(best89, best1011); + p2eg::ecaltp_t best12131415 = p2eg::bestOf2(best1213, best1415); + p2eg::ecaltp_t best16171819 = p2eg::bestOf2(best1617, best1819); + + p2eg::ecaltp_t best01234567 = p2eg::bestOf2(best0123, best4567); + p2eg::ecaltp_t best89101112131415 = p2eg::bestOf2(best891011, best12131415); + + p2eg::ecaltp_t best0to15 = p2eg::bestOf2(best01234567, best89101112131415); + p2eg::ecaltp_t bestOf20 = p2eg::bestOf2(best0to15, best16171819); + + return bestOf20; +} + +//--------------------------------------------------------// + +// For a given etaStripPeak_t (representing the 15 crystals, one per row in eta, not necessarily with the same phi), +// return the crystal with the highest pT). + +inline p2eg::crystalMax p2eg::getPeakBin15N(const p2eg::etaStripPeak_t etaStrip) { + p2eg::crystalMax x; + + p2eg::ecaltp_t best01 = p2eg::bestOf2(etaStrip.pk0, etaStrip.pk1); + p2eg::ecaltp_t best23 = p2eg::bestOf2(etaStrip.pk2, etaStrip.pk3); + p2eg::ecaltp_t best45 = p2eg::bestOf2(etaStrip.pk4, etaStrip.pk5); + p2eg::ecaltp_t best67 = p2eg::bestOf2(etaStrip.pk6, etaStrip.pk7); + p2eg::ecaltp_t best89 = p2eg::bestOf2(etaStrip.pk8, etaStrip.pk9); + p2eg::ecaltp_t best1011 = p2eg::bestOf2(etaStrip.pk10, etaStrip.pk11); + p2eg::ecaltp_t best1213 = p2eg::bestOf2(etaStrip.pk12, etaStrip.pk13); + + p2eg::ecaltp_t best0123 = p2eg::bestOf2(best01, best23); + p2eg::ecaltp_t best4567 = p2eg::bestOf2(best45, best67); + p2eg::ecaltp_t best891011 = p2eg::bestOf2(best89, best1011); + p2eg::ecaltp_t best121314 = p2eg::bestOf2(best1213, etaStrip.pk14); + + p2eg::ecaltp_t best01234567 = p2eg::bestOf2(best0123, best4567); + p2eg::ecaltp_t best891011121314 = p2eg::bestOf2(best891011, best121314); + + p2eg::ecaltp_t bestOf15 = p2eg::bestOf2(best01234567, best891011121314); + + x.energy = bestOf15.energy; + x.etaMax = bestOf15.eta; + x.phiMax = bestOf15.phi; + + return x; +} + +//--------------------------------------------------------// + +// Take a 3x4 ECAL region (i.e. 15x20 in crystals, add crystal energies in squares of 5x5, giving +// 3x4 = 12 ECAL tower sums.) Store these 12 values in towerEt. + +inline void p2eg::getECALTowersEt(p2eg::crystal tempX[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI], + ap_uint<12> towerEt[12]) { + ap_uint<10> temp[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI]; + ap_uint<12> towerEtN[3][4][5]; + for (int i = 0; i < p2eg::CRYSTAL_IN_ETA; i++) { + for (int k = 0; k < p2eg::CRYSTAL_IN_PHI; k++) { + temp[i][k] = tempX[i][k].energy; + } + } + + for (int i = 0; i < p2eg::CRYSTAL_IN_ETA; i = i + 5) { + for (int k = 0; k < p2eg::CRYSTAL_IN_PHI; k = k + 5) { + towerEtN[i / 5][k / 5][0] = temp[i][k] + temp[i][k + 1] + temp[i][k + 2] + temp[i][k + 3] + temp[i][k + 4]; + towerEtN[i / 5][k / 5][1] = + temp[i + 1][k] + temp[i + 1][k + 1] + temp[i + 1][k + 2] + temp[i + 1][k + 3] + temp[i + 1][k + 4]; + towerEtN[i / 5][k / 5][2] = + temp[i + 2][k] + temp[i + 2][k + 1] + temp[i + 2][k + 2] + temp[i + 2][k + 3] + temp[i + 2][k + 4]; + towerEtN[i / 5][k / 5][3] = + temp[i + 3][k] + temp[i + 3][k + 1] + temp[i + 3][k + 2] + temp[i + 3][k + 3] + temp[i + 3][k + 4]; + towerEtN[i / 5][k / 5][4] = + temp[i + 4][k] + temp[i + 4][k + 1] + temp[i + 4][k + 2] + temp[i + 4][k + 3] + temp[i + 4][k + 4]; + } + } + + towerEt[0] = towerEtN[0][0][0] + towerEtN[0][0][1] + towerEtN[0][0][2] + towerEtN[0][0][3] + towerEtN[0][0][4]; + towerEt[1] = towerEtN[0][1][0] + towerEtN[0][1][1] + towerEtN[0][1][2] + towerEtN[0][1][3] + towerEtN[0][1][4]; + towerEt[2] = towerEtN[0][2][0] + towerEtN[0][2][1] + towerEtN[0][2][2] + towerEtN[0][2][3] + towerEtN[0][2][4]; + towerEt[3] = towerEtN[0][3][0] + towerEtN[0][3][1] + towerEtN[0][3][2] + towerEtN[0][3][3] + towerEtN[0][3][4]; + towerEt[4] = towerEtN[1][0][0] + towerEtN[1][0][1] + towerEtN[1][0][2] + towerEtN[1][0][3] + towerEtN[1][0][4]; + towerEt[5] = towerEtN[1][1][0] + towerEtN[1][1][1] + towerEtN[1][1][2] + towerEtN[1][1][3] + towerEtN[1][1][4]; + towerEt[6] = towerEtN[1][2][0] + towerEtN[1][2][1] + towerEtN[1][2][2] + towerEtN[1][2][3] + towerEtN[1][2][4]; + towerEt[7] = towerEtN[1][3][0] + towerEtN[1][3][1] + towerEtN[1][3][2] + towerEtN[1][3][3] + towerEtN[1][3][4]; + towerEt[8] = towerEtN[2][0][0] + towerEtN[2][0][1] + towerEtN[2][0][2] + towerEtN[2][0][3] + towerEtN[2][0][4]; + towerEt[9] = towerEtN[2][1][0] + towerEtN[2][1][1] + towerEtN[2][1][2] + towerEtN[2][1][3] + towerEtN[2][1][4]; + towerEt[10] = towerEtN[2][2][0] + towerEtN[2][2][1] + towerEtN[2][2][2] + towerEtN[2][2][3] + towerEtN[2][2][4]; + towerEt[11] = towerEtN[2][3][0] + towerEtN[2][3][1] + towerEtN[2][3][2] + towerEtN[2][3][3] + towerEtN[2][3][4]; + + ap_uint<12> totalEt; + for (int i = 0; i < 12; i++) { + totalEt += towerEt[i]; + } +} + +//--------------------------------------------------------// + +inline p2eg::clusterInfo p2eg::getClusterPosition(const p2eg::ecalRegion_t ecalRegion) { + p2eg::etaStripPeak_t etaStripPeak; + p2eg::clusterInfo cluster; + + etaStripPeak.pk0 = p2eg::getPeakBin20N(ecalRegion.etaStrip0); + etaStripPeak.pk1 = p2eg::getPeakBin20N(ecalRegion.etaStrip1); + etaStripPeak.pk2 = p2eg::getPeakBin20N(ecalRegion.etaStrip2); + etaStripPeak.pk3 = p2eg::getPeakBin20N(ecalRegion.etaStrip3); + etaStripPeak.pk4 = p2eg::getPeakBin20N(ecalRegion.etaStrip4); + etaStripPeak.pk5 = p2eg::getPeakBin20N(ecalRegion.etaStrip5); + etaStripPeak.pk6 = p2eg::getPeakBin20N(ecalRegion.etaStrip6); + etaStripPeak.pk7 = p2eg::getPeakBin20N(ecalRegion.etaStrip7); + etaStripPeak.pk8 = p2eg::getPeakBin20N(ecalRegion.etaStrip8); + etaStripPeak.pk9 = p2eg::getPeakBin20N(ecalRegion.etaStrip9); + etaStripPeak.pk10 = p2eg::getPeakBin20N(ecalRegion.etaStrip10); + etaStripPeak.pk11 = p2eg::getPeakBin20N(ecalRegion.etaStrip11); + etaStripPeak.pk12 = p2eg::getPeakBin20N(ecalRegion.etaStrip12); + etaStripPeak.pk13 = p2eg::getPeakBin20N(ecalRegion.etaStrip13); + etaStripPeak.pk14 = p2eg::getPeakBin20N(ecalRegion.etaStrip14); + + p2eg::crystalMax peakIn15; + peakIn15 = p2eg::getPeakBin15N(etaStripPeak); + + cluster.seedEnergy = peakIn15.energy; + cluster.energy = 0; + cluster.etaMax = peakIn15.etaMax; + cluster.phiMax = peakIn15.phiMax; + cluster.brems = 0; + cluster.et5x5 = 0; + cluster.et2x5 = 0; + + return cluster; +} + +//--------------------------------------------------------// + +/* +* Return initialized cluster with specified Et, eta, phi, with all other fields (saturation, Et2x5, Et5x5, brems, flags initialized to 0/ false). +*/ +inline p2eg::Cluster p2eg::packCluster(ap_uint<15>& clusterEt, ap_uint<5>& etaMax_t, ap_uint<5>& phiMax_t) { + ap_uint<12> peggedEt; + p2eg::Cluster pack; + + ap_uint<5> towerEta = (etaMax_t) / 5; + ap_uint<2> towerPhi = (phiMax_t) / 5; + ap_uint<3> clusterEta = etaMax_t - 5 * towerEta; + ap_uint<3> clusterPhi = phiMax_t - 5 * towerPhi; + + peggedEt = (clusterEt > 0xFFF) ? (ap_uint<12>)0xFFF : (ap_uint<12>)clusterEt; + + pack = p2eg::Cluster(peggedEt, towerEta, towerPhi, clusterEta, clusterPhi, 0); + + return pack; +} + +//--------------------------------------------------------// + +// Given the cluster seed_eta, seed_phi, and brems, remove the cluster energy +// from the given crystal array temp. Functionally identical to "RemoveTmp". + +inline void p2eg::removeClusterFromCrystal(p2eg::crystal temp[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI], + ap_uint<5> seed_eta, + ap_uint<5> seed_phi, + ap_uint<2> brems) { + // Zero out the crystal energies in a 3 (eta) by 5 (phi) window (the clusters are 3x5 in crystals) + for (int i = 0; i < p2eg::CRYSTAL_IN_ETA; i++) { + for (int k = 0; k < p2eg::CRYSTAL_IN_PHI; k++) { + if ((i >= (seed_eta - 1)) && (i <= (seed_eta + 1)) && (k >= (seed_phi - 2)) && (k <= (seed_phi + 2))) { + temp[i][k].energy = 0; + } + } + } + + // If brems flag is 1, *also* zero the energies in the 3x5 window to the "left" of the cluster + // N.B. in the positive eta cards, "left" in the region = towards negative phi, + // but for negative eta cards, everything is flipped, so "left" in the region" = towards positive phi + if (brems == 1) { + for (int i = 0; i < p2eg::CRYSTAL_IN_ETA; i++) { + for (int k = 0; k < p2eg::CRYSTAL_IN_PHI; k++) { + if ((i >= (seed_eta - 1)) && (i <= (seed_eta + 1)) && (k >= (seed_phi - 2 - 5)) && (k <= (seed_phi + 2 - 5))) { + temp[i][k].energy = 0; + } + } + } + } + // If brems flag is 2, *also* zero the energies in the 3x5 window to the "right" of the cluster + // N.B. in the positive eta cards, "right" in the region = towards POSITIVE phi, + // but for negative eta cards, everything is flipped, so "right" in the region = towards NEGATIVE phi + else if (brems == 2) { + for (int i = 0; i < p2eg::CRYSTAL_IN_ETA; i++) { + for (int k = 0; k < p2eg::CRYSTAL_IN_PHI; k++) { + if ((i >= (seed_eta - 1)) && (i <= (seed_eta + 1)) && (k >= (seed_phi - 2 + 5)) && (k <= (seed_phi + 2 + 5))) { + temp[i][k].energy = 0; + } + } + } + } +} + +//--------------------------------------------------------// + +// Given a 15x20 crystal tempX, and a seed with seed_eta and seed_phi, return a clusterInfo containing +// the cluster energy for a positive bremmstrahulung shift + +inline p2eg::clusterInfo p2eg::getBremsValuesPos(p2eg::crystal tempX[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI], + ap_uint<5> seed_eta, + ap_uint<5> seed_phi) { + ap_uint<12> temp[p2eg::CRYSTAL_IN_ETA + 2][p2eg::CRYSTAL_IN_PHI + 4]; + ap_uint<12> phi0eta[3], phi1eta[3], phi2eta[3], phi3eta[3], phi4eta[3]; + ap_uint<12> eta_slice[3]; + p2eg::clusterInfo cluster_tmp; + + // Set all entries in a new ((15+2)x(20+4)) array to be zero. + for (int i = 0; i < (p2eg::CRYSTAL_IN_ETA + 2); i++) { + for (int j = 0; j < (p2eg::CRYSTAL_IN_PHI + 4); j++) { + temp[i][j] = 0; + } + } + + // Read the energies of the input crystal tempX into the slightly larger array temp, with an offset so temp is tempX + // except shifted +1 in eta, and -3 in phi. + for (int i = 0; i < (p2eg::CRYSTAL_IN_ETA); i++) { + for (int j = 0; j < (p2eg::CRYSTAL_IN_PHI - 3); j++) { + temp[i + 1][j] = tempX[i][j + 3].energy; + } + } + + ap_uint<6> seed_eta1, seed_phi1; + seed_eta1 = seed_eta; //to start from corner + seed_phi1 = seed_phi; //to start from corner + + // now we are in the left bottom corner + // Loop over the shifted array, and at the original location of the seed (seed_eta1/seed_phi1), + // read a 3 (eta) x 5 (phi) rectangle of crystals where the original location of the seed is in the bottom left corner + for (int j = 0; j < p2eg::CRYSTAL_IN_ETA; j++) { + if (j == seed_eta1) { + for (int k = 0; k < p2eg::CRYSTAL_IN_PHI; k++) { + if (k == seed_phi1) { + // Same eta as the seed, read next five crystals in phi + phi0eta[0] = temp[j][k]; + phi1eta[0] = temp[j][k + 1]; + phi2eta[0] = temp[j][k + 2]; + phi3eta[0] = temp[j][k + 3]; + phi4eta[0] = temp[j][k + 4]; + + // +1 eta from the seed, read next five crystals in phi + phi0eta[1] = temp[j + 1][k]; + phi1eta[1] = temp[j + 1][k + 1]; + phi2eta[1] = temp[j + 1][k + 2]; + phi3eta[1] = temp[j + 1][k + 3]; + phi4eta[1] = temp[j + 1][k + 4]; + + // +2 eta from the seed, read next five crystals in phi + phi0eta[2] = temp[j + 2][k]; + phi1eta[2] = temp[j + 2][k + 1]; + phi2eta[2] = temp[j + 2][k + 2]; + phi3eta[2] = temp[j + 2][k + 3]; + phi4eta[2] = temp[j + 2][k + 4]; + + continue; + } + } + } + } + + // Add up the energies in this 3x5 of crystals, initialize a cluster_tmp, and return it + for (int i = 0; i < 3; i++) { + eta_slice[i] = phi0eta[i] + phi1eta[i] + phi2eta[i] + phi3eta[i] + phi4eta[i]; + } + cluster_tmp.energy = (eta_slice[0] + eta_slice[1] + eta_slice[2]); + + return cluster_tmp; +} + +//--------------------------------------------------------// + +// Given a 15x20 crystal tempX, and a seed with seed_eta and seed_phi, return a clusterInfo containing +// the cluster energy for a *negative* bremmstrahlung shift + +inline p2eg::clusterInfo p2eg::getBremsValuesNeg(p2eg::crystal tempX[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI], + ap_uint<5> seed_eta, + ap_uint<5> seed_phi) { + ap_uint<12> temp[p2eg::CRYSTAL_IN_ETA + 2][p2eg::CRYSTAL_IN_PHI + 4]; + ap_uint<12> phi0eta[3], phi1eta[3], phi2eta[3], phi3eta[3], phi4eta[3]; + + ap_uint<12> eta_slice[3]; + + p2eg::clusterInfo cluster_tmp; + + // Initialize all entries in a new ((15+2)x(20+4)) array to be zero. + for (int i = 0; i < (p2eg::CRYSTAL_IN_ETA + 2); i++) { + for (int j = 0; j < (p2eg::CRYSTAL_IN_PHI + 4); j++) { + temp[i][j] = 0; + } + } + + // Read the energies of the input crystal tempX into the slightly larger array temp, with an offset so temp is tempX + // except shifted in +1 in eta and +7 in phi + for (int i = 0; i < (p2eg::CRYSTAL_IN_ETA); i++) { + for (int j = 0; j < (p2eg::CRYSTAL_IN_PHI - 1); j++) { + temp[i + 1][j + 7] = tempX[i][j].energy; + } + } + + ap_uint<6> seed_eta1, seed_phi1; + seed_eta1 = seed_eta; //to start from corner + seed_phi1 = seed_phi; //to start from corner + + // Loop over the shifted array, and at the original location of the seed (seed_eta1/seed_phi1), + // read a 3 (eta) x 5 (phi) rectangle of crystals where the original location of the seed is in the bottom left corner + for (int j = 0; j < p2eg::CRYSTAL_IN_ETA; j++) { + if (j == seed_eta1) { + for (int k = 0; k < p2eg::CRYSTAL_IN_PHI; k++) { + if (k == seed_phi1) { + // Same eta as the seed, read next five crystals in phi + phi0eta[0] = temp[j][k]; + phi1eta[0] = temp[j][k + 1]; + phi2eta[0] = temp[j][k + 2]; + phi3eta[0] = temp[j][k + 3]; + phi4eta[0] = temp[j][k + 4]; + + // +1 eta from the seed, read next five crystals in phi + phi0eta[1] = temp[j + 1][k]; + phi1eta[1] = temp[j + 1][k + 1]; + phi2eta[1] = temp[j + 1][k + 2]; + phi3eta[1] = temp[j + 1][k + 3]; + phi4eta[1] = temp[j + 1][k + 4]; + + // +2 eta from the seed, read next five crystals in phi + phi0eta[2] = temp[j + 2][k]; + phi1eta[2] = temp[j + 2][k + 1]; + phi2eta[2] = temp[j + 2][k + 2]; + phi3eta[2] = temp[j + 2][k + 3]; + phi4eta[2] = temp[j + 2][k + 4]; + continue; + } + } + } + } + + // Add up the energies in this 3x5 of crystals, initialize a cluster_tmp, and return it + for (int i = 0; i < 3; i++) { + eta_slice[i] = phi0eta[i] + phi1eta[i] + phi2eta[i] + phi3eta[i] + phi4eta[i]; + } + cluster_tmp.energy = (eta_slice[0] + eta_slice[1] + eta_slice[2]); + + return cluster_tmp; +} + +//--------------------------------------------------------// + +// Given a 15x20 crystal tempX, and a seed with seed_eta and seed_phi, return a clusterInfo containing +// the cluster energy (central value) + +inline p2eg::clusterInfo p2eg::getClusterValues(p2eg::crystal tempX[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI], + ap_uint<5> seed_eta, + ap_uint<5> seed_phi) { + ap_uint<12> temp[p2eg::CRYSTAL_IN_ETA + 4][p2eg::CRYSTAL_IN_PHI + 4]; + ap_uint<12> phi0eta[5], phi1eta[5], phi2eta[5], phi3eta[5], phi4eta[5]; + ap_uint<12> eta_slice[5]; + ap_uint<12> et2x5_1Tot, et2x5_2Tot, etSum2x5; + ap_uint<12> et5x5Tot; + + p2eg::clusterInfo cluster_tmp; + // Initialize empty (15+4)x(20+4) array + for (int i = 0; i < (p2eg::CRYSTAL_IN_ETA + 4); i++) { + for (int k = 0; k < (p2eg::CRYSTAL_IN_PHI + 4); k++) { + temp[i][k] = 0; + } + } + + // Copy input array energies into temp array with +2 eta and +2 phi offset. + for (int i = 0; i < (p2eg::CRYSTAL_IN_ETA); i++) { + for (int k = 0; k < (p2eg::CRYSTAL_IN_PHI); k++) { + temp[i + 2][k + 2] = tempX[i][k].energy; + } + } + + ap_uint<6> seed_eta1, seed_phi1; + seed_eta1 = seed_eta; //to start from corner + seed_phi1 = seed_phi; //to start from corner + + // now we are in the left bottom corner + // Loop over the shifted array, and at the original location of the seed (seed_eta1/seed_phi1), + // read a 5 (eta) x 5 (phi) rectangle of crystals where the original location of the seed is in the bottom left corner + for (int j = 0; j < p2eg::CRYSTAL_IN_ETA; j++) { + if (j == seed_eta1) { + for (int k = 0; k < p2eg::CRYSTAL_IN_PHI; k++) { + if (k == seed_phi1) { + // Same eta as the seed, read next five crystals in phi + phi0eta[0] = temp[j][k]; + phi1eta[0] = temp[j][k + 1]; + phi2eta[0] = temp[j][k + 2]; + phi3eta[0] = temp[j][k + 3]; + phi4eta[0] = temp[j][k + 4]; + + // +1 eta from the seed, read next five crystals in phi + phi0eta[1] = temp[j + 1][k]; + phi1eta[1] = temp[j + 1][k + 1]; + phi2eta[1] = temp[j + 1][k + 2]; + phi3eta[1] = temp[j + 1][k + 3]; + phi4eta[1] = temp[j + 1][k + 4]; + + // +2 eta from the seed, read next five crystals in phi + phi0eta[2] = temp[j + 2][k]; + phi1eta[2] = temp[j + 2][k + 1]; + phi2eta[2] = temp[j + 2][k + 2]; + phi3eta[2] = temp[j + 2][k + 3]; + phi4eta[2] = temp[j + 2][k + 4]; + + // +3 eta from the seed, read next five crystals in phi + phi0eta[3] = temp[j + 3][k]; + phi1eta[3] = temp[j + 3][k + 1]; + phi2eta[3] = temp[j + 3][k + 2]; + phi3eta[3] = temp[j + 3][k + 3]; + phi4eta[3] = temp[j + 3][k + 4]; + + // +4 eta from the seed, read next five crystals in phi + phi0eta[4] = temp[j + 4][k]; + phi1eta[4] = temp[j + 4][k + 1]; + phi2eta[4] = temp[j + 4][k + 2]; + phi3eta[4] = temp[j + 4][k + 3]; + phi4eta[4] = temp[j + 4][k + 4]; + + continue; + } + } + } + } + + // Add the first three eta strips into the cluster energy + for (int i = 0; i < 5; i++) { + eta_slice[i] = phi0eta[i] + phi1eta[i] + phi2eta[i] + phi3eta[i] + phi4eta[i]; + } + + cluster_tmp.energy = (eta_slice[1] + eta_slice[2] + eta_slice[3]); + + // Get the energy totals in the 5x5 and also in two 2x5 + et5x5Tot = (eta_slice[0] + eta_slice[1] + eta_slice[2] + eta_slice[3] + eta_slice[4]); + et2x5_1Tot = (eta_slice[1] + eta_slice[2]); + et2x5_2Tot = (eta_slice[2] + eta_slice[3]); + + if (et2x5_1Tot >= et2x5_2Tot) + etSum2x5 = et2x5_1Tot; + else + etSum2x5 = et2x5_2Tot; + + cluster_tmp.et5x5 = et5x5Tot; + cluster_tmp.et2x5 = etSum2x5; + + return cluster_tmp; +} + +//--------------------------------------------------------// + +// In 15x20 crystal array temp, return the next cluster, and remove the cluster's energy +// from the crystal array. + +inline p2eg::Cluster p2eg::getClusterFromRegion3x4(p2eg::crystal temp[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI]) { + p2eg::Cluster returnCluster; + p2eg::clusterInfo cluster_tmp; + p2eg::clusterInfo cluster_tmpCenter; + p2eg::clusterInfo cluster_tmpBneg; + p2eg::clusterInfo cluster_tmpBpos; + + p2eg::ecalRegion_t ecalRegion; + ecalRegion = p2eg::initStructure(temp); + + cluster_tmp = p2eg::getClusterPosition(ecalRegion); + + float seedEnergyFloat = cluster_tmp.seedEnergy / 8.0; + + // Do not make cluster if seed is less than 1.0 GeV + if (seedEnergyFloat < 1.0) { + cluster_tmp.energy = 0; + cluster_tmp.phiMax = 0; + cluster_tmp.etaMax = 0; + return p2eg::packCluster(cluster_tmp.energy, cluster_tmp.phiMax, cluster_tmp.etaMax); + } + + ap_uint<5> seed_phi = cluster_tmp.phiMax; + ap_uint<5> seed_eta = cluster_tmp.etaMax; + + cluster_tmpCenter = p2eg::getClusterValues(temp, seed_eta, seed_phi); + cluster_tmpBneg = p2eg::getBremsValuesNeg(temp, seed_eta, seed_phi); + cluster_tmpBpos = p2eg::getBremsValuesPos(temp, seed_eta, seed_phi); + + cluster_tmp.energy = cluster_tmpCenter.energy; + cluster_tmp.brems = 0; + + // Create a cluster + if ((cluster_tmpBneg.energy > cluster_tmpCenter.energy / 8) && (cluster_tmpBneg.energy > cluster_tmpBpos.energy)) { + cluster_tmp.energy = (cluster_tmpCenter.energy + cluster_tmpBneg.energy); + cluster_tmp.brems = 1; + } else if (cluster_tmpBpos.energy > cluster_tmpCenter.energy / 8) { + cluster_tmp.energy = (cluster_tmpCenter.energy + cluster_tmpBpos.energy); + cluster_tmp.brems = 2; + } + + returnCluster = p2eg::packCluster(cluster_tmp.energy, cluster_tmp.etaMax, cluster_tmp.phiMax); + p2eg::removeClusterFromCrystal(temp, seed_eta, seed_phi, cluster_tmp.brems); + + // Add clusterInfo members to the output cluster members + returnCluster.brems = cluster_tmp.brems; + returnCluster.et5x5 = cluster_tmpCenter.et5x5; // get et5x5 from the center value + returnCluster.et2x5 = cluster_tmpCenter.et2x5; // get et2x5 from the center value + + return returnCluster; +} + +//--------------------------------------------------------// + +// Stitch clusters in cluster_list across the boundary specified by +// towerEtaUpper and towerEtaLower (using RCT card notation). Modifies the input vector +// (passed by reference). If two clusters are combined, modify the higher-energy cluster and +// zero out the energy of the smaller-energy cluster. +// cc is the RCT card number (for print-out statements only). + +inline void p2eg::stitchClusterOverRegionBoundary(std::vector& cluster_list, + int towerEtaUpper, + int towerEtaLower, + int cc) { + (void)cc; // for printout statements + + int crystalEtaUpper = 0; + int crystalEtaLower = 4; + + for (size_t i = 0; i < cluster_list.size(); i++) { + for (size_t j = 0; j < cluster_list.size(); j++) { + // Do not double-count + if (i == j) + continue; + + p2eg::Cluster c1 = cluster_list[i]; + p2eg::Cluster c2 = cluster_list[j]; + + p2eg::Cluster newc1; + p2eg::Cluster newc2; + + // Use the .towerEtaInCard() method to get the tower eta in the entire RCT card + if ((c1.clusterEnergy() > 0) && (c1.towerEtaInCard() == towerEtaUpper) && (c1.clusterEta() == crystalEtaUpper)) { + if ((c2.clusterEnergy() > 0) && (c2.towerEtaInCard() == towerEtaLower) && + (c2.clusterEta() == crystalEtaLower)) { + ap_uint<5> phi1 = c1.towerPhi() * 5 + c1.clusterPhi(); + ap_uint<5> phi2 = c2.towerPhi() * 5 + c2.clusterPhi(); + ap_uint<5> dPhi; + dPhi = (phi1 > phi2) ? (phi1 - phi2) : (phi2 - phi1); + + if (dPhi < 2) { + ap_uint<15> totalEnergy = c1.clusterEnergy() + c2.clusterEnergy(); + ap_uint<15> totalEt2x5 = c1.uint_et2x5() + c2.uint_et2x5(); + ap_uint<15> totalEt5x5 = c1.uint_et5x5() + c2.uint_et5x5(); + + bool rct_is_iso = false; // RCT has no isolation information + bool rct_is_looseTkiso = false; // RCT has no isolation information + + // Initialize a cluster with the larger cluster's position and total energy + if (c1.clusterEnergy() > c2.clusterEnergy()) { + newc1 = p2eg::Cluster(totalEnergy, + c1.towerEta(), + c1.towerPhi(), + c1.clusterEta(), + c1.clusterPhi(), + c1.satur(), + totalEt5x5, + totalEt2x5, + c1.getBrems(), + c1.getIsSS(), + c1.getIsLooseTkss(), + rct_is_iso, + rct_is_looseTkiso, + c1.region()); + newc2 = p2eg::Cluster(0, + c2.towerEta(), + c2.towerPhi(), + c2.clusterEta(), + c2.clusterPhi(), + c2.satur(), + 0, + 0, + 0, + false, + false, + rct_is_iso, + rct_is_looseTkiso, + c2.region()); + cluster_list[i] = newc1; + cluster_list[j] = newc2; + } else { + // Analogous to above portion + newc1 = p2eg::Cluster(0, + c1.towerEta(), + c1.towerPhi(), + c1.clusterEta(), + c1.clusterPhi(), + c1.satur(), + 0, + 0, + 0, + false, + false, + rct_is_iso, + rct_is_looseTkiso, + c1.region()); + newc2 = p2eg::Cluster(totalEnergy, + c2.towerEta(), + c2.towerPhi(), + c2.clusterEta(), + c2.clusterPhi(), + c2.satur(), + totalEt5x5, + totalEt2x5, + c2.getBrems(), + c2.getIsSS(), + c2.getIsLooseTkss(), + rct_is_iso, + rct_is_looseTkiso, + c2.region()); + cluster_list[i] = newc1; + cluster_list[j] = newc2; + } + } + } + } + } + } +} + +//--------------------------------------------------------// + +#endif diff --git a/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc b/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc index fbaf2a54b07bb..50995524ad7b7 100644 --- a/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc +++ b/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc @@ -63,6 +63,7 @@ static constexpr int n_clusters_4link = 4 * 3; static constexpr int n_crystals_towerEta = 5; static constexpr int n_crystals_towerPhi = 5; static constexpr int n_crystals_3towers = 3 * 5; +static constexpr int n_crystals_2towers = 2 * 5; static constexpr int n_towers_per_link = 17; static constexpr int n_clusters_per_link = 2; static constexpr int n_clusters_per_L1card = 8; @@ -221,6 +222,45 @@ int getPhiMin_card(int card) { return phimin; } +/* + * Replace in-line region boundary arithmetic with function that accounts for region 0 in negative eta cards + * In the indexing convention of the old emulator, region 0 is the region overlapping with the endcap, and is + * only two towers wide in eta. + */ +int getEtaMin_region(int card, int nregion) { + // Special handling for negative-eta cards + if (card % 2 == 0) { + if (nregion == 0) { + return getEtaMin_card(card); + } else { + return getEtaMin_card(card) + n_crystals_2towers + n_crystals_3towers * (nregion - 1); + } + } + // Positive-eta cards: same as original in-line arithmetic + else { + return getEtaMin_card(card) + n_crystals_3towers * nregion; + } +} + +/* + * Replace in-line region boundary arithmetic that accounts for region 0 in negative eta cards. + * Same as above but for max eta of the region. + */ +int getEtaMax_region(int card, int nregion) { + // Special handling for negative-eta cards + if (card % 2 == 0) { + if (nregion == 0) { + return getEtaMin_card(card) + n_crystals_2towers; + } else { + return getEtaMin_card(card) + n_crystals_2towers + (n_crystals_3towers * nregion); + } + } + // Positive-eta cards: same as original in-line arithmetic + else { + return getEtaMin_card(card) + n_crystals_3towers * (nregion + 1); + } +} + class L1EGCrystalClusterEmulatorProducer : public edm::stream::EDProducer<> { public: explicit L1EGCrystalClusterEmulatorProducer(const edm::ParameterSet&); @@ -260,6 +300,7 @@ class L1EGCrystalClusterEmulatorProducer : public edm::stream::EDProducer<> { float cWeightedEta_; float cWeightedPhi_; float ciso_; // pt of cluster divided by 7x7 ECAL towers + float crawIso_; // raw isolation sum float chovere_; // 5x5 HCAL towers divided by the ECAL cluster pt float craweta_; // coordinates between -1.44 and 1.44 float crawphi_; // coordinates between -pi and pi @@ -299,6 +340,26 @@ class L1EGCrystalClusterEmulatorProducer : public edm::stream::EDProducer<> { inline const GlobalVector& position() const { return position_; }; inline const EBDetId& id() const { return id_; }; + /* + * Check if it falls within the boundary of a card. + */ + bool isInCard(int cc) const { + return (getCrystal_phiID(position().phi()) <= getPhiMax_card(cc) && + getCrystal_phiID(position().phi()) >= getPhiMin_card(cc) && + getCrystal_etaID(position().eta()) <= getEtaMax_card(cc) && + getCrystal_etaID(position().eta()) >= getEtaMin_card(cc)); + }; + + /* + * Check if it falls within the boundary card AND a region in the card. + */ + bool isInCardAndRegion(int cc, int nregion) const { + bool isInRegionEta = (getCrystal_etaID(position().eta()) < getEtaMax_region(cc, nregion) && + getCrystal_etaID(position().eta()) >= getEtaMin_region(cc, nregion)); + return (isInCard(cc) && isInRegionEta); + } + + // Comparison functions with other SimpleCaloHit instances inline float deta(SimpleCaloHit& other) const { return position_.eta() - other.position().eta(); }; int dieta(SimpleCaloHit& other) const { if (isEndcapHit_ || other.isEndcapHit()) @@ -322,6 +383,14 @@ class L1EGCrystalClusterEmulatorProducer : public edm::stream::EDProducer<> { result += 2 * PI; return result; }; + int dieta_byCrystalID(SimpleCaloHit& other) const { + return (getCrystal_etaID(position_.eta()) - getCrystal_etaID(other.position().eta())); + }; + int diphi_byCrystalID(SimpleCaloHit& other) const { + return (getCrystal_phiID(position_.phi()) - getCrystal_phiID(other.position().phi())); + }; + int id_iEta() { return id_.ieta(); } + int id_iPhi() { return id_.iphi(); } float distanceTo(SimpleCaloHit& other) const { // Treat position as a point, measure 3D distance // This is used for endcap hits, where we don't have a rectangular mapping @@ -492,16 +561,8 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: SimpleCaloHit centerhit; for (const auto& hit : ecalhits) { - if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && - getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && - getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && - // Check that the hit is in the good card - getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion && - !hit.used() && hit.pt() >= 1.0 && hit.pt() > centerhit.pt()) // 3 towers x 5 crystals - { - // Highest hit in good region with pt>1 and not used in any other cluster + // Highest hit in good region with pt>1 and not used in any other cluster + if (hit.isInCardAndRegion(cc, nregion) && !hit.used() && hit.pt() >= 1.0 && hit.pt() > centerhit.pt()) { centerhit = hit; build_cluster = true; } @@ -532,12 +593,7 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: float e2x2_4 = 0; float n2x2_4 = 0; for (auto& hit : ecalhits) { - if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && - getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && - getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0 && - getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion) { + if (hit.isInCardAndRegion(cc, nregion) && (hit.pt() > 0)) { if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) { rightlobe += hit.pt(); } @@ -577,13 +633,8 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: n2x5_2++; } } - if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && - getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && - getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && !hit.used() && hit.pt() > 0 && - abs(hit.dieta(centerhit)) <= 1 && abs(hit.diphi(centerhit)) <= 2 && - getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion) { + if (hit.isInCardAndRegion(cc, nregion) && !hit.used() && hit.pt() > 0 && abs(hit.dieta(centerhit)) <= 1 && + abs(hit.diphi(centerhit)) <= 2) { // clusters 3x5 in etaxphi using only the hits in the corresponding card and in the corresponding 3x4 region hit.setUsed(true); mc1.cpt += hit.pt(); @@ -593,13 +644,7 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: } if (do_brem && (rightlobe > 0.10 * mc1.cpt or leftlobe > 0.10 * mc1.cpt)) { for (auto& hit : ecalhits) { - if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && - getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && - getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0 && - getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion && - !hit.used()) { + if (hit.isInCardAndRegion(cc, nregion) && hit.pt() > 0 && !hit.used()) { if (rightlobe > 0.10 * mc1.cpt && (leftlobe < 0.10 * mc1.cpt or rightlobe > leftlobe) && abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) { mc1.cpt += hit.pt(); @@ -640,7 +685,7 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: for (unsigned int jj = 0; jj < unsigned(cluster_list[cc].size()); ++jj) { for (unsigned int kk = jj + 1; kk < unsigned(cluster_list[cc].size()); ++kk) { if (std::abs(cluster_list[cc][jj].ceta_ - cluster_list[cc][kk].ceta_) < 2 && - std::abs(cluster_list[cc][jj].cphi_ - cluster_list[cc][kk].cphi_) < 2) { //Diagonale + exact neighbors + std::abs(cluster_list[cc][jj].cphi_ - cluster_list[cc][kk].cphi_) < 2) { // Diagonal + exact neighbors if (cluster_list[cc][kk].cpt > cluster_list[cc][jj].cpt) { cluster_list[cc][kk].cpt += cluster_list[cc][jj].cpt; cluster_list[cc][kk].c5x5_ += cluster_list[cc][jj].c5x5_; @@ -699,19 +744,15 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: // Loop over calo ecal hits to get the ECAL towers. Take only hits that have not been used to make clusters for (const auto& hit : ecalhits) { - if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && - getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && - getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && - !hit.used()) { // Take all the hits inside the card that have not been used yet - for (int jj = 0; jj < n_links_card; ++jj) { // loop over 4 links per card + if (hit.isInCard(cc) && !hit.used()) { + for (int jj = 0; jj < n_links_card; ++jj) { // loop over 4 links per card if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % 4 == jj) { // Go to ID tower modulo 4 for (int ii = 0; ii < n_towers_per_link; ++ii) { - //Apply Mark's calibration at the same time (row of the lowest pT, as a function of eta) + // Apply Mark's calibration at the same time (row of the lowest pT, as a function of eta) if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) { ECAL_tower_L1Card[jj][ii][cc] += hit.pt() * calib_(0, std::abs(hit.position().eta())); - iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta()); //hit.id().ieta(); - iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi()); //hit.id().iphi(); + iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta()); + iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi()); } } // end of loop over eta towers } @@ -727,23 +768,19 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(phi); } } - } // end of check if inside card } // end of loop over hits to build towers // Loop over hcal hits to get the HCAL towers. for (const auto& hit : hcalhits) { - if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) && - getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) && - getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) && - getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0) { + if (hit.isInCard(cc) && hit.pt() > 0) { for (int jj = 0; jj < n_links_card; ++jj) { if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % n_links_card == jj) { for (int ii = 0; ii < n_towers_per_link; ++ii) { if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) { HCAL_tower_L1Card[jj][ii][cc] += hit.pt(); - iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta()); //hit.id().ieta(); - iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi()); //hit.id().iphi(); + iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta()); + iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi()); } } // end of loop over eta towers } @@ -972,6 +1009,7 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: float hcal_nrj = 0.0; float isolation = 0.0; int ntowers = 0; + for (int iii = 0; iii < n_towers_halfPhi; ++iii) { // The clusters have to be added to the isolation for (unsigned int jjj = 0; jjj < n_clusters_per_L1card && jjj < cluster_list_L2[iii].size(); ++jjj) { if (!(iii == ii && jjj == jj)) { @@ -1016,7 +1054,10 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: } } } - cluster_list_L2[ii][jj].ciso_ = ((isolation) * (25.0 / ntowers)) / cluster_list_L2[ii][jj].cpt; + // If we summed over fewer than 5*5 = 25 towers (because the cluster was near the edge), scale up the isolation sum + int nTowersIn5x5Window = 5 * 5; + cluster_list_L2[ii][jj].ciso_ = ((isolation) * (nTowersIn5x5Window / ntowers)) / cluster_list_L2[ii][jj].cpt; + cluster_list_L2[ii][jj].crawIso_ = ((isolation) * (nTowersIn5x5Window / ntowers)); cluster_list_L2[ii][jj].chovere_ = hcal_nrj / cluster_list_L2[ii][jj].cpt; } } @@ -1098,12 +1139,12 @@ void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm:: -1000, energy_cluster_L2Card[ii][jj][ll], -1, - is_iso&& is_ss, - is_iso&& is_ss, + is_iso && is_ss, + is_iso && is_ss, is_photon, - is_iso&& is_ss, - is_looseTkiso&& is_looseTkss, - is_iso&& is_ss); + is_iso && is_ss, + is_looseTkiso && is_looseTkss, + is_iso && is_ss); // Experimental parameters, don't want to bother with hardcoding them in data format std::map params; params["standaloneWP_showerShape"] = is_ss; diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloEGammaEmulator.cc b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloEGammaEmulator.cc new file mode 100644 index 0000000000000..209b285f3fb29 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/plugins/Phase2L1CaloEGammaEmulator.cc @@ -0,0 +1,749 @@ +/* + * Description: Phase 2 RCT and GCT emulator + */ + +// system include files +#include +#include +#include +// #include +#include // for rand +#include +#include +#include + +// user include files +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h" +#include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h" +#include "Geometry/CaloGeometry/interface/CaloGeometry.h" +#include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h" +#include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "DataFormats/HcalDetId/interface/HcalSubdetector.h" +#include "DataFormats/HcalDetId/interface/HcalDetId.h" + +// ECAL TPs +#include "DataFormats/EcalDigi/interface/EcalDigiCollections.h" + +// HCAL TPs +#include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveDigi.h" + +// Output tower collection +#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.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/L1Trigger/interface/BXVector.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" + +#include "L1Trigger/L1CaloTrigger/interface/ParametricCalibration.h" +#include "L1Trigger/L1TCalorimeter/interface/CaloTools.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1CaloEGammaUtils.h" +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1RCT.h" +#include "L1Trigger/L1CaloTrigger/interface/Phase2L1GCT.h" + +// Declare the Phase2L1CaloEGammaEmulator class and its methods + +class Phase2L1CaloEGammaEmulator : public edm::stream::EDProducer<> { +public: + explicit Phase2L1CaloEGammaEmulator(const edm::ParameterSet&); + ~Phase2L1CaloEGammaEmulator() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions&); + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + + edm::EDGetTokenT ecalTPEBToken_; + edm::EDGetTokenT> hcalTPToken_; + edm::ESGetToken decoderTag_; + + l1tp2::ParametricCalibration calib_; + + edm::ESGetToken caloGeometryTag_; + const CaloSubdetectorGeometry* ebGeometry; + const CaloSubdetectorGeometry* hbGeometry; + edm::ESGetToken hbTopologyTag_; + const HcalTopology* hcTopology_; +}; + +////////////////////////////////////////////////////////////////////////// + +// Phase2L1CaloEGammaEmulator initializer, destructor, and produce methods + +Phase2L1CaloEGammaEmulator::Phase2L1CaloEGammaEmulator(const edm::ParameterSet& iConfig) + : ecalTPEBToken_(consumes(iConfig.getParameter("ecalTPEB"))), + hcalTPToken_( + consumes>(iConfig.getParameter("hcalTP"))), + decoderTag_(esConsumes(edm::ESInputTag("", ""))), + calib_(iConfig.getParameter("calib")), + caloGeometryTag_(esConsumes(edm::ESInputTag("", ""))), + hbTopologyTag_(esConsumes(edm::ESInputTag("", ""))) { + produces("RCT"); + produces("GCT"); + produces("RCT"); + produces("GCT"); + produces("GCTFullTowers"); + produces>("GCTEGammas"); + produces("GCTDigitizedClusterToCorrelator"); + produces("GCTDigitizedTowerToCorrelator"); + produces("GCTDigitizedClusterToGT"); +} + +void Phase2L1CaloEGammaEmulator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + + // Detector geometry + const auto& caloGeometry = iSetup.getData(caloGeometryTag_); + ebGeometry = caloGeometry.getSubdetectorGeometry(DetId::Ecal, EcalBarrel); + hbGeometry = caloGeometry.getSubdetectorGeometry(DetId::Hcal, HcalBarrel); + const auto& hbTopology = iSetup.getData(hbTopologyTag_); + hcTopology_ = &hbTopology; + HcalTrigTowerGeometry theTrigTowerGeometry(hcTopology_); + + const auto& decoder = iSetup.getData(decoderTag_); + + //***************************************************// + // Declare RCT output collections + //***************************************************// + + auto L1EGXtalClusters = std::make_unique(); + auto L1CaloTowers = std::make_unique(); + + //***************************************************// + // Get the ECAL hits + //***************************************************// + edm::Handle pcalohits; + iEvent.getByToken(ecalTPEBToken_, pcalohits); + + std::vector ecalhits; + + for (const auto& hit : *pcalohits.product()) { + if (hit.encodedEt() > 0) // hit.encodedEt() returns an int corresponding to 2x the crystal Et + { + // Et is 10 bit, by keeping the ADC saturation Et at 120 GeV it means that you have to divide by 8 + float et = hit.encodedEt() * p2eg::ECAL_LSB; + if (et < p2eg::cut_500_MeV) { + continue; // Reject hits with < 500 MeV ET + } + + // Get cell coordinates and info + auto cell = ebGeometry->getGeometry(hit.id()); + + p2eg::SimpleCaloHit ehit; + ehit.setId(hit.id()); + ehit.setPosition(GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z())); + ehit.setEnergy(et); + ehit.setEt_uint((ap_uint<10>)hit.encodedEt()); // also save the uint Et + ehit.setPt(); + ecalhits.push_back(ehit); + } + } + + //***************************************************// + // Get the HCAL hits + //***************************************************// + std::vector hcalhits; + edm::Handle> hbhecoll; + iEvent.getByToken(hcalTPToken_, hbhecoll); + + for (const auto& hit : *hbhecoll.product()) { + float et = decoder.hcaletValue(hit.id(), hit.t0()); + ap_uint<10> encodedEt = hit.t0().compressedEt(); + // same thing as SOI_compressedEt() in HcalTriggerPrimitiveDigi.h/// + if (et <= 0) + continue; + + if (!(hcTopology_->validHT(hit.id()))) { + LogError("Phase2L1CaloEGammaEmulator") + << " -- Hcal hit DetID not present in HCAL Geom: " << hit.id() << std::endl; + throw cms::Exception("Phase2L1CaloEGammaEmulator"); + continue; + } + const std::vector& hcId = theTrigTowerGeometry.detIds(hit.id()); + if (hcId.empty()) { + LogError("Phase2L1CaloEGammaEmulator") << "Cannot find any HCalDetId corresponding to " << hit.id() << std::endl; + throw cms::Exception("Phase2L1CaloEGammaEmulator"); + continue; + } + if (hcId[0].subdetId() > 1) { + continue; + } + GlobalVector hcal_tp_position = GlobalVector(0., 0., 0.); + for (const auto& hcId_i : hcId) { + if (hcId_i.subdetId() > 1) { + continue; + } + // get the first HCAL TP/ cell + auto cell = hbGeometry->getGeometry(hcId_i); + if (cell == nullptr) { + continue; + } + GlobalVector tmpVector = GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z()); + hcal_tp_position = tmpVector; + + break; + } + p2eg::SimpleCaloHit hhit; + hhit.setId(hit.id()); + hhit.setIdHcal(hit.id()); + hhit.setPosition(hcal_tp_position); + hhit.setEnergy(et); + hhit.setPt(); + hhit.setEt_uint(encodedEt); + hcalhits.push_back(hhit); + } + + //***************************************************// + // Initialize necessary arrays for tower and clusters + //***************************************************// + + // L1 Outputs definition: Arrays that use firmware convention for indexing + p2eg::tower_t towerHCALCard + [p2eg::n_towers_cardEta][p2eg::n_towers_cardPhi] + [p2eg::n_towers_halfPhi]; // 17x4x36 array (not to be confused with the 12x1 array of ap_uints, towerEtHCAL + p2eg::tower_t towerECALCard[p2eg::n_towers_cardEta][p2eg::n_towers_cardPhi][p2eg::n_towers_halfPhi]; + // There is one vector of clusters per card (up to 12 clusters before stitching across ECAL regions) + std::vector cluster_list[p2eg::n_towers_halfPhi]; + // After merging/stitching the clusters, we only take the 8 highest pt per card + std::vector cluster_list_merged[p2eg::n_towers_halfPhi]; + + //***************************************************// + // Fill RCT ECAL regions with ECAL hits + //***************************************************// + for (int cc = 0; cc < p2eg::n_towers_halfPhi; ++cc) { // Loop over 36 L1 cards + + p2eg::card rctCard; + rctCard.setIdx(cc); + + for (const auto& hit : ecalhits) { + // Check if the hit is in cards 0-35 + if (hit.isInCard(cc)) { + // Get the crystal eta and phi, relative to the bottom left corner of the card + // (0 up to 17*5, 0 up to 4*5) + int local_iEta = hit.crystalLocaliEta(cc); + int local_iPhi = hit.crystalLocaliPhi(cc); + + // Region number (0-5) depends only on the crystal iEta in the card + int regionNumber = p2eg::getRegionNumber(local_iEta); + + // Tower eta and phi index inside the card (17x4) + int inCard_tower_iEta = local_iEta / p2eg::CRYSTALS_IN_TOWER_ETA; + int inCard_tower_iPhi = local_iPhi / p2eg::CRYSTALS_IN_TOWER_PHI; + + // Tower eta and phi index inside the region (3x4) + int inRegion_tower_iEta = inCard_tower_iEta % p2eg::TOWER_IN_ETA; + int inRegion_tower_iPhi = inCard_tower_iPhi % p2eg::TOWER_IN_PHI; + + // Crystal eta and phi index inside the 3x4 region (15x20) + int inRegion_crystal_iEta = local_iEta % (p2eg::TOWER_IN_ETA * p2eg::CRYSTALS_IN_TOWER_ETA); + int inRegion_crystal_iPhi = local_iPhi; + + // Crystal eta and phi index inside the tower (5x5) + int inLink_crystal_iEta = (inRegion_crystal_iEta % p2eg::CRYSTALS_IN_TOWER_ETA); + int inLink_crystal_iPhi = (inRegion_crystal_iPhi % p2eg::CRYSTALS_IN_TOWER_PHI); + + // Add the crystal energy to the rctCard + p2eg::region3x4& myRegion = rctCard.getRegion3x4(regionNumber); + p2eg::linkECAL& myLink = myRegion.getLinkECAL(inRegion_tower_iEta, inRegion_tower_iPhi); + myLink.addCrystalE(inLink_crystal_iEta, inLink_crystal_iPhi, hit.et_uint()); + } + } + + //***************************************************// + // Build RCT towers from HCAL hits + //***************************************************// + for (const auto& hit : hcalhits) { + if (hit.isInCard(cc) && hit.pt() > 0) { + // Get crystal eta and phi, relative to the bottom left corner of the card + // (0 up to 17*5, 0 up to 4*5) + int local_iEta = hit.crystalLocaliEta(cc); + int local_iPhi = hit.crystalLocaliPhi(cc); + + // Region (0-5) the hit falls into + int regionNumber = p2eg::getRegionNumber(local_iEta); + + // Tower eta and phi index inside the card (17x4) + int inCard_tower_iEta = int(local_iEta / p2eg::CRYSTALS_IN_TOWER_ETA); + int inCard_tower_iPhi = int(local_iPhi / p2eg::CRYSTALS_IN_TOWER_PHI); + + // Tower eta and phi index inside the region (3x4) + int inRegion_tower_iEta = inCard_tower_iEta % p2eg::TOWER_IN_ETA; + int inRegion_tower_iPhi = inCard_tower_iPhi % p2eg::TOWER_IN_PHI; + + // Access the right HCAL region and tower and increment the ET + p2eg::towers3x4& myTowers3x4 = rctCard.getTowers3x4(regionNumber); + p2eg::towerHCAL& myTower = myTowers3x4.getTowerHCAL(inRegion_tower_iEta, inRegion_tower_iPhi); + myTower.addEt(hit.et_uint()); + } + } + + //***************************************************// + // Make clusters in each ECAL region independently + //***************************************************// + for (int idxRegion = 0; idxRegion < p2eg::N_REGIONS_PER_CARD; idxRegion++) { + // ECAL crystals array + p2eg::crystal temporary[p2eg::CRYSTAL_IN_ETA][p2eg::CRYSTAL_IN_PHI]; + // HCAL towers in 3x4 region + ap_uint<12> towerEtHCAL[p2eg::TOWER_IN_ETA * p2eg::TOWER_IN_PHI]; + + p2eg::region3x4& myRegion = rctCard.getRegion3x4(idxRegion); + p2eg::towers3x4& myTowers = rctCard.getTowers3x4(idxRegion); + + // In each 3x4 region, loop through the links (one link = one tower) + for (int iLinkEta = 0; iLinkEta < p2eg::TOWER_IN_ETA; iLinkEta++) { + for (int iLinkPhi = 0; iLinkPhi < p2eg::TOWER_IN_PHI; iLinkPhi++) { + // Get the ECAL link (one link per tower) + p2eg::linkECAL& myLink = myRegion.getLinkECAL(iLinkEta, iLinkPhi); + + // We have an array of 3x4 links/towers, each link/tower is 5x5 in crystals. We need to convert this to a 15x20 of crystals + int ref_iEta = (iLinkEta * p2eg::CRYSTALS_IN_TOWER_ETA); + int ref_iPhi = (iLinkPhi * p2eg::CRYSTALS_IN_TOWER_PHI); + + // In the link, get the crystals (5x5 in each link) + for (int iEta = 0; iEta < p2eg::CRYSTALS_IN_TOWER_ETA; iEta++) { + for (int iPhi = 0; iPhi < p2eg::CRYSTALS_IN_TOWER_PHI; iPhi++) { + // Et as unsigned int + ap_uint<10> uEnergy = myLink.getCrystalE(iEta, iPhi); + + // Fill the 'temporary' array with a crystal object + temporary[ref_iEta + iEta][ref_iPhi + iPhi] = p2eg::crystal(uEnergy); + } + } // end of loop over crystals + + // HCAL tower ET + p2eg::towerHCAL& myTower = myTowers.getTowerHCAL(iLinkEta, iLinkPhi); + towerEtHCAL[(iLinkEta * p2eg::TOWER_IN_PHI) + iLinkPhi] = myTower.getEt(); + } + } + + // Iteratively find four clusters and remove them from 'temporary' as we go, and fill cluster_list + for (int c = 0; c < p2eg::N_CLUSTERS_PER_REGION; c++) { + p2eg::Cluster newCluster = p2eg::getClusterFromRegion3x4(temporary); // remove cluster from 'temporary' + newCluster.setRegionIdx(idxRegion); // add the region number + if (newCluster.clusterEnergy() > 0) { + // do not push back 0-energy clusters + cluster_list[cc].push_back(newCluster); + } + } + + // Create towers using remaining ECAL energy, and the HCAL towers were already calculated in towersEtHCAL[12] + ap_uint<12> towerEtECAL[12]; + p2eg::getECALTowersEt(temporary, towerEtECAL); + + // Fill towerHCALCard and towerECALCard arrays + for (int i = 0; i < 12; i++) { + // Get the tower's indices in a (17x4) card + int iEta = (idxRegion * p2eg::TOWER_IN_ETA) + (i / p2eg::TOWER_IN_PHI); + int iPhi = (i % p2eg::TOWER_IN_PHI); + + // If the region number is 5 (i.e. only 2x4 in towers, skip the third row) N_REGIONS_PER_CARD = 6. i.e. we do not want to consider + // i = 8, 9, 10, 11 + if ((idxRegion == (p2eg::N_REGIONS_PER_CARD - 1)) && (i > 7)) { + continue; + } + towerHCALCard[iEta][iPhi][cc] = + p2eg::tower_t(towerEtHCAL[i], 0); // p2eg::tower_t initializer takes an ap-uint<12> for the energy + towerECALCard[iEta][iPhi][cc] = p2eg::tower_t(towerEtECAL[i], 0); + } + } + + //-------------------------------------------// + // Stitching across ECAL regions // + //-------------------------------------------// + const int nRegionBoundariesEta = (p2eg::N_REGIONS_PER_CARD - 1); // 6 regions -> 5 boundaries to check + // Upper and lower boundaries respectively, to check for stitching along + int towerEtaBoundaries[nRegionBoundariesEta][2] = {{15, 14}, {12, 11}, {9, 8}, {6, 5}, {3, 2}}; + + for (int iBound = 0; iBound < nRegionBoundariesEta; iBound++) { + p2eg::stitchClusterOverRegionBoundary( + cluster_list[cc], towerEtaBoundaries[iBound][0], towerEtaBoundaries[iBound][1], cc); + } + + //--------------------------------------------------------------------------------// + // Sort the clusters, take the 8 with highest pT, and return extras to tower + //--------------------------------------------------------------------------------// + if (!cluster_list[cc].empty()) { + std::sort(cluster_list[cc].begin(), cluster_list[cc].end(), p2eg::compareClusterET); + + // If there are more than eight clusters, return the unused energy to the towers + for (unsigned int kk = p2eg::n_clusters_4link; kk < cluster_list[cc].size(); ++kk) { + p2eg::Cluster cExtra = cluster_list[cc][kk]; + if (cExtra.clusterEnergy() > 0) { + // Increment tower ET + // Get tower (eta, phi) (up to (17, 4)) in the RCT card + int whichTowerEtaInCard = ((cExtra.region() * p2eg::TOWER_IN_ETA) + cExtra.towerEta()); + int whichTowerPhiInCard = cExtra.towerPhi(); + ap_uint<12> oldTowerEt = towerECALCard[whichTowerEtaInCard][whichTowerPhiInCard][cc].et(); + ap_uint<12> newTowerEt = (oldTowerEt + cExtra.clusterEnergy()); + ap_uint<4> hoe = towerECALCard[whichTowerEtaInCard][whichTowerPhiInCard][cc].hoe(); + towerECALCard[whichTowerEtaInCard][whichTowerPhiInCard][cc] = p2eg::tower_t(newTowerEt, hoe); + } + } + + // Save up to eight clusters: loop over cluster_list + for (unsigned int kk = 0; kk < cluster_list[cc].size(); ++kk) { + if (kk >= p2eg::n_clusters_4link) + continue; + if (cluster_list[cc][kk].clusterEnergy() > 0) { + cluster_list_merged[cc].push_back(cluster_list[cc][kk]); + } + } + } + + //-------------------------------------------// + // Calibrate clusters + //-------------------------------------------// + for (auto& c : cluster_list_merged[cc]) { + float realEta = c.realEta(cc); + c.calib = calib_(c.getPt(), std::abs(realEta)); + c.applyCalibration(c.calib); + } + + //-------------------------------------------// + // Cluster shower shape flags + //-------------------------------------------// + for (auto& c : cluster_list_merged[cc]) { + c.is_ss = p2eg::passes_ss(c.getPt(), (c.getEt2x5() / c.getEt5x5())); + c.is_looseTkss = p2eg::passes_looseTkss(c.getPt(), (c.getEt2x5() / c.getEt5x5())); + } + + //-------------------------------------------// + // Calibrate towers + //-------------------------------------------// + for (int ii = 0; ii < p2eg::n_towers_cardEta; ++ii) { // 17 towers per card in eta + for (int jj = 0; jj < p2eg::n_towers_cardPhi; ++jj) { // 4 towers per card in phi + float tRealEta = p2eg::getTowerEta_fromAbsID( + p2eg::getAbsID_iEta_fromFirmwareCardTowerLink(cc, ii, jj)); // real eta of center of tower + double tCalib = calib_(0, tRealEta); // calibration factor + towerECALCard[ii][jj][cc].applyCalibration(tCalib); + } + } + + //-------------------------------------------// + // Calculate tower HoE + //-------------------------------------------// + for (int ii = 0; ii < p2eg::n_towers_cardEta; ++ii) { // 17 towers per card in eta + for (int jj = 0; jj < p2eg::n_towers_cardPhi; ++jj) { // 4 towers per card in phi + ap_uint<12> ecalEt = towerECALCard[ii][jj][cc].et(); + ap_uint<12> hcalEt = towerHCALCard[ii][jj][cc].et(); + towerECALCard[ii][jj][cc].getHoverE(ecalEt, hcalEt); + } + } + + //-----------------------------------------------------------// + // Produce output RCT collections for event display and analyzer + //-----------------------------------------------------------// + for (auto& c : cluster_list_merged[cc]) { + reco::Candidate::PolarLorentzVector p4calibrated(c.getPt(), c.realEta(cc), c.realPhi(cc), 0.); + + // Constructor definition at: https://github.com/cms-l1t-offline/cmssw/blob/l1t-phase2-v3.3.11/DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h#L34 + l1tp2::CaloCrystalCluster cluster(p4calibrated, + c.getPt(), // use float + 0, // float h over e + 0, // float iso + 0, // DetId seedCrystal + 0, // puCorrPt + c.getBrems(), // 0, 1, or 2 (as computed in firmware) + 0, // et2x2 (not calculated) + c.getEt2x5(), // et2x5 (as computed in firmware, save float) + 0, // et3x5 (not calculated) + c.getEt5x5(), // et5x5 (as computed in firmware, save float) + c.getIsSS(), // standalone WP + c.getIsSS(), // electronWP98 + false, // photonWP80 + c.getIsSS(), // electronWP90 + c.getIsLooseTkss(), // looseL1TkMatchWP + c.getIsSS() // stage2effMatch + ); + + std::map params; + params["standaloneWP_showerShape"] = c.getIsSS(); + params["trkMatchWP_showerShape"] = c.getIsLooseTkss(); + cluster.setExperimentalParams(params); + + L1EGXtalClusters->push_back(cluster); + } + // Output tower collections + for (int ii = 0; ii < p2eg::n_towers_cardEta; ++ii) { // 17 towers per card in eta + for (int jj = 0; jj < p2eg::n_towers_cardPhi; ++jj) { // 4 towers per card in phi + + l1tp2::CaloTower l1CaloTower; + // Divide by 8.0 to get ET as float (GeV) + l1CaloTower.setEcalTowerEt(towerECALCard[ii][jj][cc].et() * p2eg::ECAL_LSB); + // HCAL TPGs encoded ET: multiply by the LSB (0.5) to convert to GeV + l1CaloTower.setHcalTowerEt(towerHCALCard[ii][jj][cc].et() * p2eg::HCAL_LSB); + int absToweriEta = p2eg::getAbsID_iEta_fromFirmwareCardTowerLink(cc, ii, jj); + int absToweriPhi = p2eg::getAbsID_iPhi_fromFirmwareCardTowerLink(cc, ii, jj); + l1CaloTower.setTowerIEta(absToweriEta); + l1CaloTower.setTowerIPhi(absToweriPhi); + l1CaloTower.setTowerEta(p2eg::getTowerEta_fromAbsID(absToweriEta)); + l1CaloTower.setTowerPhi(p2eg::getTowerPhi_fromAbsID(absToweriPhi)); + + L1CaloTowers->push_back(l1CaloTower); + } + } + } // end of loop over cards + + iEvent.put(std::move(L1EGXtalClusters), "RCT"); + iEvent.put(std::move(L1CaloTowers), "RCT"); + + //******************************************************************* + // Do GCT geometry for inputs + //******************************************************************* + + // Loop over GCT cards (three of them) + p2eg::GCTcard_t gctCards[p2eg::N_GCTCARDS]; + p2eg::GCTtoCorr_t gctToCorr[p2eg::N_GCTCARDS]; + + // Initialize the cards (requires towerECALCard, towerHCALCard arrays, and cluster_list_merged) + for (unsigned int gcc = 0; gcc < p2eg::N_GCTCARDS; gcc++) { + // Each GCT card encompasses 16 RCT cards, listed in GCTcardtoRCTcardnumber[3][16]. i goes from 0 to <16 + for (int i = 0; i < (p2eg::N_RCTCARDS_PHI * 2); i++) { + unsigned int rcc = p2eg::GCTcardtoRCTcardnumber[gcc][i]; + + // Positive eta? Fist row is in positive eta + bool isPositiveEta = (i < p2eg::N_RCTCARDS_PHI); + + // Sum tower ECAL and HCAL energies: 17 towers per link + for (int iTower = 0; iTower < p2eg::N_GCTTOWERS_FIBER; iTower++) { + // 4 links per card + for (int iLink = 0; iLink < p2eg::n_links_card; iLink++) { + p2eg::tower_t t0_ecal = towerECALCard[iTower][iLink][rcc]; + p2eg::tower_t t0_hcal = towerHCALCard[iTower][iLink][rcc]; + p2eg::RCTtower_t t; + t.et = t0_ecal.et() + p2eg::convertHcalETtoEcalET(t0_hcal.et()); + t.hoe = t0_ecal.hoe(); + // Not needed for GCT firmware but will be written into GCT CMSSW outputs : 12 bits each + t.ecalEt = t0_ecal.et(); + t.hcalEt = t0_hcal.et(); + + if (isPositiveEta) { + gctCards[gcc].RCTcardEtaPos[i % p2eg::N_RCTCARDS_PHI].RCTtoGCTfiber[iLink].RCTtowers[iTower] = t; + } else { + gctCards[gcc].RCTcardEtaNeg[i % p2eg::N_RCTCARDS_PHI].RCTtoGCTfiber[iLink].RCTtowers[iTower] = t; + } + } + } + + // Distribute at most 8 RCT clusters across four links: convert to GCT coordinates + for (size_t iCluster = 0; (iCluster < cluster_list_merged[rcc].size()) && + (iCluster < (p2eg::N_RCTGCT_FIBERS * p2eg::N_RCTCLUSTERS_FIBER)); + iCluster++) { + p2eg::Cluster c0 = cluster_list_merged[rcc][iCluster]; + p2eg::RCTcluster_t c; + c.et = c0.clusterEnergy(); + + // tower Eta: c0.towerEta() refers to the tower iEta INSIDE the region, so we need to convert to tower iEta inside the card + c.towEta = (c0.region() * p2eg::TOWER_IN_ETA) + c0.towerEta(); + c.towPhi = c0.towerPhi(); + c.crEta = c0.clusterEta(); + c.crPhi = c0.clusterPhi(); + c.et5x5 = c0.uint_et5x5(); + c.et2x5 = c0.uint_et2x5(); + c.is_ss = c0.getIsSS(); + c.is_looseTkss = c0.getIsLooseTkss(); + c.is_iso = c0.getIsIso(); + c.is_looseTkiso = c0.getIsLooseTkIso(); + c.brems = c0.getBrems(); + c.nGCTCard = gcc; // store gct card index as well + unsigned int iIdxInGCT = i % p2eg::N_RCTCARDS_PHI; + unsigned int iLinkC = iCluster % p2eg::N_RCTGCT_FIBERS; + unsigned int iPosC = iCluster / p2eg::N_RCTGCT_FIBERS; + + if (isPositiveEta) { + gctCards[gcc].RCTcardEtaPos[iIdxInGCT].RCTtoGCTfiber[iLinkC].RCTclusters[iPosC] = c; + } else { + gctCards[gcc].RCTcardEtaNeg[iIdxInGCT].RCTtoGCTfiber[iLinkC].RCTclusters[iPosC] = c; + } + } + // If there were fewer than eight clusters, make sure the remaining fiber clusters are zero'd out. + for (size_t iZeroCluster = cluster_list_merged[rcc].size(); + iZeroCluster < (p2eg::N_RCTGCT_FIBERS * p2eg::N_RCTCLUSTERS_FIBER); + iZeroCluster++) { + unsigned int iIdxInGCT = i % p2eg::N_RCTCARDS_PHI; + unsigned int iLinkC = iZeroCluster % p2eg::N_RCTGCT_FIBERS; + unsigned int iPosC = iZeroCluster / p2eg::N_RCTGCT_FIBERS; + + p2eg::RCTcluster_t cZero; + cZero.et = 0; + cZero.towEta = 0; + cZero.towPhi = 0; + cZero.crEta = 0; + cZero.crPhi = 0; + cZero.et5x5 = 0; + cZero.et2x5 = 0; + cZero.is_ss = false; + cZero.is_looseTkss = false; + cZero.is_iso = false; + cZero.is_looseTkiso = false; + cZero.nGCTCard = gcc; // store gct card index as well + if (isPositiveEta) { + gctCards[gcc].RCTcardEtaPos[iIdxInGCT].RCTtoGCTfiber[iLinkC].RCTclusters[iPosC] = cZero; + } else { + gctCards[gcc].RCTcardEtaNeg[iIdxInGCT].RCTtoGCTfiber[iLinkC].RCTclusters[iPosC] = cZero; + } + } + } + } // end of loop over initializing GCT cards + + //---------------------------------------------------- + // Output collections for the GCT emulator + //---------------------------------------------------- + auto L1GCTClusters = std::make_unique(); + auto L1GCTTowers = std::make_unique(); + auto L1GCTFullTowers = std::make_unique(); + auto L1GCTEGammas = std::make_unique(); + auto L1DigitizedClusterCorrelator = std::make_unique(); + auto L1DigitizedTowerCorrelator = std::make_unique(); + auto L1DigitizedClusterGT = std::make_unique(); + + //---------------------------------------------------- + // Apply the GCT firmware code to each GCT card + //---------------------------------------------------- + + for (unsigned int gcc = 0; gcc < p2eg::N_GCTCARDS; gcc++) { + p2eg::algo_top(gctCards[gcc], + gctToCorr[gcc], + gcc, + L1GCTClusters, + L1GCTTowers, + L1GCTFullTowers, + L1GCTEGammas, + L1DigitizedClusterCorrelator, + L1DigitizedTowerCorrelator, + L1DigitizedClusterGT, + calib_); + } + + iEvent.put(std::move(L1GCTClusters), "GCT"); + iEvent.put(std::move(L1GCTTowers), "GCT"); + iEvent.put(std::move(L1GCTFullTowers), "GCTFullTowers"); + iEvent.put(std::move(L1GCTEGammas), "GCTEGammas"); + iEvent.put(std::move(L1DigitizedClusterCorrelator), "GCTDigitizedClusterToCorrelator"); + iEvent.put(std::move(L1DigitizedTowerCorrelator), "GCTDigitizedTowerToCorrelator"); + iEvent.put(std::move(L1DigitizedClusterGT), "GCTDigitizedClusterToGT"); +} + +////////////////////////////////////////////////////////////////////////// + +void Phase2L1CaloEGammaEmulator::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // l1tPhase2L1CaloEGammaEmulator + edm::ParameterSetDescription desc; + desc.add("ecalTPEB", edm::InputTag("simEcalEBTriggerPrimitiveDigis")); + desc.add("hcalTP", edm::InputTag("simHcalTriggerPrimitiveDigis")); + { + edm::ParameterSetDescription psd0; + psd0.add>("etaBins", + { + 0.087, + 0.174, + 0.261, + 0.348, + 0.435, + 0.522, + 0.609, + 0.696, + 0.783, + 0.87, + 0.957, + 1.044, + 1.131, + 1.218, + 1.305, + 1.392, + 1.479, + }); + psd0.add>("ptBins", + { + 12, + 20, + 30, + 40, + 55, + 90, + 1000000.0, + }); + psd0.add>("scale", + { + 1.298, 1.287, + 1.309, 1.298, + 1.309, 1.309, + 1.309, 1.298, + 1.309, 1.298, + 1.309, 1.309, + 1.309, 1.32, + 1.309, 1.32, + 1.309, 1.1742, + 1.1639, 1.1639, + 1.1639, 1.1639, + 1.1639, 1.1639, + 1.1742, 1.1742, + 1.1639, 1.1639, + 1.1742, 1.1639, + 1.1639, 1.1742, + 1.1742, 1.1536000000000002, + 1.11, 1.11, + 1.11, 1.11, + 1.11, 1.11, + 1.11, 1.11, + 1.11, 1.11, + 1.11, 1.11, + 1.11, 1.11, + 1.11, 1.11, + 1.1, 1.09, + 1.09, 1.09, + 1.09, 1.09, + 1.09, 1.09, + 1.09, 1.09, + 1.09, 1.09, + 1.09, 1.09, + 1.09, 1.09, + 1.09, 1.09, + 1.07, 1.07, + 1.07, 1.07, + 1.07, 1.07, + 1.07, 1.08, + 1.07, 1.07, + 1.08, 1.08, + 1.07, 1.08, + 1.08, 1.08, + 1.08, 1.06, + 1.06, 1.06, + 1.06, 1.05, + 1.05, 1.06, + 1.06, 1.06, + 1.06, 1.06, + 1.06, 1.06, + 1.06, 1.06, + 1.06, 1.06, + 1.04, 1.04, + 1.04, 1.04, + 1.05, 1.04, + 1.05, 1.05, + 1.05, 1.05, + 1.05, 1.05, + 1.05, 1.05, + 1.05, 1.05, + 1.05, + }); + desc.add("calib", psd0); + } + descriptions.addWithDefaultLabel(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(Phase2L1CaloEGammaEmulator); diff --git a/L1Trigger/L1CaloTrigger/python/l1tPhase2L1CaloEGammaEmulator_cfi.py b/L1Trigger/L1CaloTrigger/python/l1tPhase2L1CaloEGammaEmulator_cfi.py new file mode 100644 index 0000000000000..967bc5047a036 --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/l1tPhase2L1CaloEGammaEmulator_cfi.py @@ -0,0 +1,10 @@ +import FWCore.ParameterSet.Config as cms + +from L1Trigger.L1CaloTrigger.phase2L1CaloEGammaEmulator_cfi import phase2L1CaloEGammaEmulator +l1tPhase2L1CaloEGammaEmulator = phase2L1CaloEGammaEmulator.clone() + +from Configuration.ProcessModifiers.premix_stage2_cff import premix_stage2 +premix_stage2.toModify(l1tPhase2L1CaloEGammaEmulator, + ecalTPEB = "DMEcalEBTriggerPrimitiveDigis", + hcalTP = "DMHcalTriggerPrimitiveDigis", +) diff --git a/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeProducer.cc index 8b17d4e609a69..e6dccdd4e0d15 100644 --- a/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeProducer.cc @@ -243,7 +243,7 @@ L1PhaseIITreeProducer::L1PhaseIITreeProducer(const edm::ParameterSet& iConfig) { z0PuppiToken_ = consumes(iConfig.getParameter("zoPuppi")); //l1vertextdrToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("l1vertextdr")); - //l1verticesToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("l1vertices")); + //l1verticesToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("L1Vertices")); l1TkPrimaryVertexToken_ = consumes(iConfig.getParameter("l1TkPrimaryVertex")); diff --git a/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeStep1Producer.cc b/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeStep1Producer.cc index 9af9a06782432..545b2f331b612 100644 --- a/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeStep1Producer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeStep1Producer.cc @@ -221,7 +221,7 @@ L1PhaseIITreeStep1Producer::L1PhaseIITreeStep1Producer(const edm::ParameterSet& // -> Gone after cleaning the simulated info //l1vertextdrToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("l1vertextdr")); - //l1verticesToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("l1vertices")); + //l1verticesToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("L1Vertices")); l1TkPrimaryVertexToken_ = consumes(iConfig.getParameter("l1TkPrimaryVertex")); diff --git a/L1Trigger/L1TNtuples/python/l1PhaseIITreeProducer_cfi.py b/L1Trigger/L1TNtuples/python/l1PhaseIITreeProducer_cfi.py index 39c701f669b77..96b49ccb65816 100644 --- a/L1Trigger/L1TNtuples/python/l1PhaseIITreeProducer_cfi.py +++ b/L1Trigger/L1TNtuples/python/l1PhaseIITreeProducer_cfi.py @@ -54,8 +54,8 @@ l1PFMet = cms.InputTag("l1PFMetPuppi"), zoPuppi = cms.InputTag("l1pfProducerBarrel","z0"), - l1vertextdr = cms.InputTag("VertexProducer","l1vertextdr"), - l1vertices = cms.InputTag("VertexProducer","l1vertices"), + l1vertextdr = cms.InputTag("l1tVertexProducer","l1vertextdr"), + L1Vertices = cms.InputTag("l1tVertexProducer","L1Vertices"), l1TkPrimaryVertex= cms.InputTag("L1TkPrimaryVertex",""), # L1PFTauToken = cms.InputTag("l1pfTauProducer","L1PFTaus"), diff --git a/L1Trigger/L1TNtuples/python/l1PhaseIITreeStep1Producer_cfi.py b/L1Trigger/L1TNtuples/python/l1PhaseIITreeStep1Producer_cfi.py index ed3911287add1..7518a163ffb39 100644 --- a/L1Trigger/L1TNtuples/python/l1PhaseIITreeStep1Producer_cfi.py +++ b/L1Trigger/L1TNtuples/python/l1PhaseIITreeStep1Producer_cfi.py @@ -41,9 +41,9 @@ #zoPuppi = cms.InputTag(""), # does not exist anymore! - #l1vertextdr = cms.InputTag("VertexProducer","l1vertextdr"), #not used anymore - but kept in the loop just to be sure, not filled to ntuples - #l1vertices = cms.InputTag("VertexProducer","l1vertices"), #not used anymore - but kept in the loop just to be sure, not filled to ntuples - l1TkPrimaryVertex= cms.InputTag("L1VertexFinderEmulator","l1verticesEmulation"), #we need to rename this, but these are now emulated vertices! + #l1vertextdr = cms.InputTag("VertexProducer","ertextdr"), #not used anymore - but kept in the loop just to be sure, not filled to ntuples + #L1Vertices = cms.InputTag("l1tVertexProducer","L1Vertices"), #not used anymore - but kept in the loop just to be sure, not filled to ntuples + l1TkPrimaryVertex= cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), #we need to rename this, but these are now emulated vertices! L1NNTauToken = cms.InputTag("L1NNTauProducerPuppi","L1PFTausNN"), # default collection, emulated L1NNTau2vtxToken = cms.InputTag("L1NNTauProducerPuppi2Vtx","L1PFTausNN"), # 2 vtx version @@ -51,10 +51,10 @@ tkTrackerJetToken = cms.InputTag("L1TrackJetsEmulation", "L1TrackJets"), #these are emulated tkTrackerJetDisplacedToken = cms.InputTag("L1TrackJetsExtendedEmulation", "L1TrackJetsExtended"), #emulated - tkMetToken = cms.InputTag("L1TrackerEmuEtMiss","L1TrackerEmuEtMiss"), #emulated + tkMetToken = cms.InputTag("l1tTrackerEmuEtMiss","L1TrackerEmuEtMiss"), #emulated - tkMhtToken = cms.InputTag("L1TrackerEmuHTMiss","L1TrackerEmuHTMiss"), #emulated - tkMhtDisplacedToken = cms.InputTag("L1TrackerEmuHTMissExtended","L1TrackerEmuHTMissExtended"), #emulated + tkMhtToken = cms.InputTag("l1tTrackerEmuHTMiss","L1TrackerEmuHTMiss"), #emulated + tkMhtDisplacedToken = cms.InputTag("l1tTrackerEmuHTMissExtended","L1TrackerEmuHTMissExtended"), #emulated maxL1Extra = cms.uint32(50) ) diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h b/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h index e427d7942a6fc..9243516fcd04f 100644 --- a/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h +++ b/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h @@ -28,6 +28,9 @@ namespace l1tmetemu { const unsigned int kGlobalPhiExtra{4}; const unsigned int kCosLUTSize{10}; const unsigned int kCosLUTMagSize{1}; + const unsigned int kCosLUTTableSize{10}; + const unsigned int kCosLUTBins{1 << kCosLUTTableSize}; + const unsigned int kCosLUTShift{TTTrack_TrackWord::TrackBitWidths::kPhiSize - kCosLUTTableSize}; const unsigned int kAtanLUTSize{64}; const unsigned int kAtanLUTMagSize{2}; @@ -61,7 +64,7 @@ namespace l1tmetemu { METWordphi_t Phi; }; - std::vector generateCosLUT(unsigned int size); + std::vector generateCosLUT(); global_phi_t localToGlobalPhi(TTTrack_TrackWord::phi_t local_phi, global_phi_t sector_shift); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1FastTrackingJetProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1FastTrackingJetProducer.cc index f7113e9e97192..44d8880b7457d 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1FastTrackingJetProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1FastTrackingJetProducer.cc @@ -257,7 +257,7 @@ void L1FastTrackingJetProducer::fillDescriptions(edm::ConfigurationDescriptions& // L1FastTrackingJets edm::ParameterSetDescription desc; desc.add("L1TrackInputTag", edm::InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks")); - desc.add("L1PrimaryVertexTag", "l1vertices"); + desc.add("L1PrimaryVertexTag", "L1Vertices"); desc.add("GenInfo", edm::InputTag("TTTrackAssociatorFromPixelDigis", "Level1TTTracks")); desc.add("trk_zMax", 15.0); desc.add("trk_chi2dofMax", 10.0); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc index 96ce847d7efa5..7382ef37bb818 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulatorProducer.cc @@ -25,6 +25,7 @@ #include "DataFormats/L1Trigger/interface/VertexWord.h" // system include files +#include "DataFormats/Common/interface/Handle.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" @@ -34,6 +35,7 @@ #include "FWCore/Utilities/interface/StreamID.h" #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" #include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/RefVector.h" //own headers #include "L1TrackJetClustering.h" @@ -52,6 +54,7 @@ class L1TrackJetEmulatorProducer : public stream::EDProducer<> { ~L1TrackJetEmulatorProducer() override = default; typedef TTTrack L1TTTrackType; typedef vector L1TTTrackCollectionType; + typedef edm::RefVector L1TTTrackRefCollectionType; static void fillDescriptions(ConfigurationDescriptions &descriptions); private: @@ -96,7 +99,7 @@ class L1TrackJetEmulatorProducer : public stream::EDProducer<> { TTTrack_TrackWord trackword; edm::ESGetToken tTopoToken_; - const EDGetTokenT>> trackToken_; + const EDGetTokenT trackToken_; const EDGetTokenT PVtxToken_; }; @@ -129,7 +132,7 @@ L1TrackJetEmulatorProducer::L1TrackJetEmulatorProducer(const ParameterSet &iConf nDisplacedTracks_(iConfig.getParameter("nDisplacedTracks")), dzPVTrk_(iConfig.getParameter("MaxDzTrackPV")), tTopoToken_(esConsumes(edm::ESInputTag("", ""))), - trackToken_(consumes>>(iConfig.getParameter("L1TrackInputTag"))), + trackToken_(consumes(iConfig.getParameter("L1TrackInputTag"))), PVtxToken_(consumes(iConfig.getParameter("L1PVertexInputTag"))) { zStep_ = 2.0 * trkZMax_ / (zBins_ + 1); // added +1 in denom etaStep_ = glbeta_intern(2.0 * trkEtaMax_ / etaBins_); //etaStep is the width of an etabin @@ -148,7 +151,7 @@ void L1TrackJetEmulatorProducer::produce(Event &iEvent, const EventSetup &iSetup // Read inputs const TrackerTopology &tTopo = iSetup.getData(tTopoToken_); - edm::Handle>> TTTrackHandle; + edm::Handle TTTrackHandle; iEvent.getByToken(trackToken_, TTTrackHandle); edm::Handle PVtx; @@ -422,7 +425,7 @@ void L1TrackJetEmulatorProducer::fillDescriptions(ConfigurationDescriptions &des // Please change this to state exactly what you do use, even if it is no parameters ParameterSetDescription desc; desc.add("L1TrackInputTag", edm::InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks")); - desc.add("L1PVertexInputTag", edm::InputTag("l1tVertexFinderEmulator", "l1verticesEmulation")); + desc.add("L1PVertexInputTag", edm::InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation")); desc.add("MaxDzTrackPV", 1.0); desc.add("trk_zMax", 15.0); desc.add("trk_ptMax", 200.0); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.cc index 9a93ddb686ea6..80da20559d827 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.cc @@ -17,6 +17,7 @@ // system include files #include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/RefVector.h" #include "DataFormats/L1TCorrelator/interface/TkJet.h" #include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" @@ -47,6 +48,7 @@ class L1TrackJetProducer : public stream::EDProducer<> { ~L1TrackJetProducer() override = default; typedef TTTrack L1TTTrackType; typedef vector L1TTTrackCollectionType; + typedef edm::RefVector L1TTTrackRefCollectionType; static void fillDescriptions(ConfigurationDescriptions &descriptions); private: @@ -87,7 +89,7 @@ class L1TrackJetProducer : public stream::EDProducer<> { const float dzPVTrk_; edm::ESGetToken tTopoToken_; - const EDGetTokenT>> trackToken_; + const EDGetTokenT trackToken_; const EDGetTokenT PVtxToken_; }; @@ -119,7 +121,7 @@ L1TrackJetProducer::L1TrackJetProducer(const ParameterSet &iConfig) nDisplacedTracks_(iConfig.getParameter("nDisplacedTracks")), dzPVTrk_(iConfig.getParameter("MaxDzTrackPV")), tTopoToken_(esConsumes(edm::ESInputTag("", ""))), - trackToken_(consumes>>(iConfig.getParameter("L1TrackInputTag"))), + trackToken_(consumes(iConfig.getParameter("L1TrackInputTag"))), PVtxToken_(consumes(iConfig.getParameter("L1PVertexInputTag"))) { zStep_ = 2.0 * trkZMax_ / (zBins_ + 1); // added +1 in denom etaStep_ = 2.0 * trkEtaMax_ / etaBins_; //etaStep is the width of an etabin @@ -137,7 +139,7 @@ void L1TrackJetProducer::produce(Event &iEvent, const EventSetup &iSetup) { // Read inputs const TrackerTopology &tTopo = iSetup.getData(tTopoToken_); - edm::Handle>> TTTrackHandle; + edm::Handle TTTrackHandle; iEvent.getByToken(trackToken_, TTTrackHandle); edm::Handle PVtx; @@ -356,7 +358,7 @@ void L1TrackJetProducer::produce(Event &iEvent, const EventSetup &iSetup) { void L1TrackJetProducer::fillDescriptions(ConfigurationDescriptions &descriptions) { ParameterSetDescription desc; desc.add("L1TrackInputTag", edm::InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks")); - desc.add("L1PVertexInputTag", edm::InputTag("l1tVertexFinderEmulator", "l1verticesEmulation")); + desc.add("L1PVertexInputTag", edm::InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation")); desc.add("MaxDzTrackPV", 1.0); desc.add("trk_zMax", 15.0); desc.add("trk_ptMax", 200.0); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.cc index 5ada2508cc533..aa8fcc97752f8 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.cc @@ -89,9 +89,7 @@ class L1TrackSelectionProducer : public edm::global::EDProducer<> { // ----------member functions ---------------------- void printDebugInfo(const TTTrackCollectionHandle& l1TracksHandle, const TTTrackRefCollectionUPtr& vTTTrackOutput, - const TTTrackRefCollectionUPtr& vTTTrackEmulationOutput, - const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput, - const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const; + const TTTrackRefCollectionUPtr& vTTTrackEmulationOutput) const; void printTrackInfo(edm::LogInfo& log, const L1Track& track, bool printEmulation = false) const; void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; @@ -257,54 +255,6 @@ class L1TrackSelectionProducer : public edm::global::EDProducer<> { private: double reducedChi2RPhiMax_; }; - struct TTTrackDeltaZMaxSelector { - TTTrackDeltaZMaxSelector(const std::vector& deltaZMaxEtaBounds, const std::vector& deltaZMax) - : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {} - TTTrackDeltaZMaxSelector(const edm::ParameterSet& cfg) - : deltaZMaxEtaBounds_(cfg.template getParameter("deltaZMaxEtaBounds")), - deltaZMax_(cfg.template getParameter("deltaZMax")) {} - bool operator()(const L1Track& t, const l1t::Vertex& v) const { - size_t etaIndex = - std::upper_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(t.momentum().eta())) - - deltaZMaxEtaBounds_.begin() - 1; - if (etaIndex > deltaZMax_.size() - 1) - etaIndex = deltaZMax_.size() - 1; - return std::abs(v.z0() - t.z0()) <= deltaZMax_[etaIndex]; - } - - private: - std::vector deltaZMaxEtaBounds_; - std::vector deltaZMax_; - }; - struct TTTrackWordDeltaZMaxSelector { - TTTrackWordDeltaZMaxSelector(const std::vector& deltaZMaxEtaBounds, const std::vector& deltaZMax) - : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {} - TTTrackWordDeltaZMaxSelector(const edm::ParameterSet& cfg) - : deltaZMaxEtaBounds_(cfg.template getParameter("deltaZMaxEtaBounds")), - deltaZMax_(cfg.template getParameter("deltaZMax")) {} - bool operator()(const L1Track& t, const l1t::VertexWord& v) const { - TTTrack_TrackWord::tanl_t etaEmulationBits = t.getTanlWord(); - ap_fixed etaEmulation; - etaEmulation.V = etaEmulationBits.range(); - size_t etaIndex = - std::upper_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(etaEmulation.to_double())) - - deltaZMaxEtaBounds_.begin() - 1; - if (etaIndex > deltaZMax_.size() - 1) - etaIndex = deltaZMax_.size() - 1; - l1t::VertexWord::vtxz0_t fixedTkZ0 = t.undigitizeSignedValue( - t.getZ0Bits(), TTTrack_TrackWord::TrackBitWidths::kZ0Size, TTTrack_TrackWord::stepZ0, 0.0); - - ap_uint ptEmulationBits = t.getTrackWord()( - TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB); - ap_ufixed ptEmulation; - ptEmulation.V = ptEmulationBits.range(); - return std::abs(v.z0() - fixedTkZ0.to_double()) <= deltaZMax_[etaIndex]; - } - - private: - std::vector deltaZMaxEtaBounds_; - std::vector deltaZMax_; - }; typedef AndSelector TTTrackPtMinEtaMaxZ0MaxNStubsMinSelector; @@ -320,16 +270,12 @@ class L1TrackSelectionProducer : public edm::global::EDProducer<> { // ----------member data --------------------------- const edm::EDGetTokenT l1TracksToken_; - edm::EDGetTokenT l1VerticesToken_; - edm::EDGetTokenT l1VerticesEmulationToken_; edm::ESGetToken tTopoToken_; const std::string outputCollectionName_; const edm::ParameterSet cutSet_; const double ptMin_, absEtaMax_, absZ0Max_, bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_; const int nStubsMin_, nPSStubsMin_; - std::vector deltaZMaxEtaBounds_, deltaZMax_; - const double useDisplacedTracksDeltaZOverride_; - bool processSimulatedTracks_, processEmulatedTracks_, doDeltaZCutSim_, doDeltaZCutEmu_; + bool processSimulatedTracks_, processEmulatedTracks_; int debug_; }; @@ -350,10 +296,6 @@ L1TrackSelectionProducer::L1TrackSelectionProducer(const edm::ParameterSet& iCon reducedChi2RPhiMax_(cutSet_.getParameter("reducedChi2RPhiMax")), nStubsMin_(cutSet_.getParameter("nStubsMin")), nPSStubsMin_(cutSet_.getParameter("nPSStubsMin")), - deltaZMaxEtaBounds_(cutSet_.getParameter>("deltaZMaxEtaBounds")), - deltaZMax_(cutSet_.getParameter>("deltaZMax")), - - useDisplacedTracksDeltaZOverride_(iConfig.getParameter("useDisplacedTracksDeltaZOverride")), processSimulatedTracks_(iConfig.getParameter("processSimulatedTracks")), processEmulatedTracks_(iConfig.getParameter("processEmulatedTracks")), debug_(iConfig.getParameter("debug")) { @@ -362,33 +304,11 @@ L1TrackSelectionProducer::L1TrackSelectionProducer(const edm::ParameterSet& iCon throw cms::Exception("You must process at least one of the track collections (simulated or emulated)."); } - if (deltaZMax_.size() != deltaZMaxEtaBounds_.size() - 1) { - throw cms::Exception("The number of deltaZ cuts does not match the number of eta bins!"); - } - - if (useDisplacedTracksDeltaZOverride_ >= 0) { - deltaZMax_ = std::vector(deltaZMax_.size(), useDisplacedTracksDeltaZOverride_); - } - - // Get additional input tags and define the EDM output based on the previous configuration parameters - doDeltaZCutSim_ = false; - doDeltaZCutEmu_ = false; if (processSimulatedTracks_) { produces(outputCollectionName_); - if (iConfig.exists("l1VerticesInputTag")) { - l1VerticesToken_ = consumes(iConfig.getParameter("l1VerticesInputTag")); - doDeltaZCutSim_ = true; - produces(outputCollectionName_ + "Associated"); - } } if (processEmulatedTracks_) { produces(outputCollectionName_ + "Emulation"); - if (iConfig.exists("l1VerticesEmulationInputTag")) { - l1VerticesEmulationToken_ = - consumes(iConfig.getParameter("l1VerticesEmulationInputTag")); - doDeltaZCutEmu_ = true; - produces(outputCollectionName_ + "AssociatedEmulation"); - } } } @@ -400,9 +320,7 @@ L1TrackSelectionProducer::~L1TrackSelectionProducer() {} void L1TrackSelectionProducer::printDebugInfo(const TTTrackCollectionHandle& l1TracksHandle, const TTTrackRefCollectionUPtr& vTTTrackOutput, - const TTTrackRefCollectionUPtr& vTTTrackEmulationOutput, - const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput, - const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const { + const TTTrackRefCollectionUPtr& vTTTrackEmulationOutput) const { edm::LogInfo log("L1TrackSelectionProducer"); log << "The original track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are ... \n"; for (const auto& track : *l1TracksHandle) { @@ -450,49 +368,6 @@ void L1TrackSelectionProducer::printDebugInfo(const TTTrackCollectionHandle& l1T } log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n"; } - if (processSimulatedTracks_) { - log << "The selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, chi2rz, " - "chi2rphi, z0) values are ... \n"; - for (const auto& track : *vTTTrackAssociatedOutput) { - printTrackInfo(log, *track, debug_ >= 4); - } - log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedOutput->size() << "\n\n"; - } - if (processEmulatedTracks_) { - log << "The emulation selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, " - "chi2rz, chi2rphi, z0) values are " - "... \n"; - for (const auto& track : *vTTTrackAssociatedEmulationOutput) { - printTrackInfo(log, *track, debug_ >= 4); - } - log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedEmulationOutput->size() << "\n\n"; - } - if (processSimulatedTracks_ && processEmulatedTracks_) { - TTTrackRefCollection inSimButNotEmu; - TTTrackRefCollection inEmuButNotSim; - std::set_difference(vTTTrackAssociatedOutput->begin(), - vTTTrackAssociatedOutput->end(), - vTTTrackAssociatedEmulationOutput->begin(), - vTTTrackAssociatedEmulationOutput->end(), - std::back_inserter(inSimButNotEmu)); - std::set_difference(vTTTrackAssociatedEmulationOutput->begin(), - vTTTrackAssociatedEmulationOutput->end(), - vTTTrackAssociatedOutput->begin(), - vTTTrackAssociatedOutput->end(), - std::back_inserter(inEmuButNotSim)); - log << "The set of tracks selected via cuts on the simulated values which are not in the set of tracks selected " - "by cutting on the emulated values ... \n"; - for (const auto& track : inSimButNotEmu) { - printTrackInfo(log, *track, debug_ >= 3); - } - log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n" - << "The set of tracks selected via cuts on the emulated values which are not in the set of tracks selected " - "by cutting on the simulated values ... \n"; - for (const auto& track : inEmuButNotSim) { - printTrackInfo(log, *track, debug_ >= 3); - } - log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n"; - } } void L1TrackSelectionProducer::printTrackInfo(edm::LogInfo& log, const L1Track& track, bool printEmulation) const { @@ -521,51 +396,26 @@ void L1TrackSelectionProducer::printTrackInfo(edm::LogInfo& log, const L1Track& // ------------ method called to produce the data ------------ void L1TrackSelectionProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { auto vTTTrackOutput = std::make_unique(); - auto vTTTrackAssociatedOutput = std::make_unique(); auto vTTTrackEmulationOutput = std::make_unique(); - auto vTTTrackAssociatedEmulationOutput = std::make_unique(); // Tracker Topology const TrackerTopology& tTopo = iSetup.getData(tTopoToken_); TTTrackCollectionHandle l1TracksHandle; - edm::Handle l1VerticesHandle; - edm::Handle l1VerticesEmulationHandle; - - l1t::Vertex leadingVertex; - l1t::VertexWord leadingEmulationVertex; iEvent.getByToken(l1TracksToken_, l1TracksHandle); size_t nOutputApproximate = l1TracksHandle->size(); if (processSimulatedTracks_) { - if (doDeltaZCutSim_) { - iEvent.getByToken(l1VerticesToken_, l1VerticesHandle); - leadingVertex = l1VerticesHandle->at(0); - if (debug_ >= 2) { - edm::LogInfo("L1TrackSelectionProducer") << "leading vertex z0 = " << leadingVertex.z0(); - } - } vTTTrackOutput->reserve(nOutputApproximate); - vTTTrackAssociatedOutput->reserve(nOutputApproximate); } if (processEmulatedTracks_) { - if (doDeltaZCutEmu_) { - iEvent.getByToken(l1VerticesEmulationToken_, l1VerticesEmulationHandle); - leadingEmulationVertex = l1VerticesEmulationHandle->at(0); - if (debug_ >= 2) { - edm::LogInfo("L1TrackSelectionProducer") << "leading emulation vertex z0 = " << leadingEmulationVertex.z0(); - } - } vTTTrackEmulationOutput->reserve(nOutputApproximate); - vTTTrackAssociatedEmulationOutput->reserve(nOutputApproximate); } TTTrackPtMinEtaMaxZ0MaxNStubsMinSelector kinSel(ptMin_, absEtaMax_, absZ0Max_, nStubsMin_); TTTrackWordPtMinEtaMaxZ0MaxNStubsMinSelector kinSelEmu(ptMin_, absEtaMax_, absZ0Max_, nStubsMin_); TTTrackBendChi2Chi2RZChi2RPhiMaxSelector chi2Sel(bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_); TTTrackWordBendChi2Chi2RZChi2RPhiMaxSelector chi2SelEmu(bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_); - TTTrackDeltaZMaxSelector deltaZSel(deltaZMaxEtaBounds_, deltaZMax_); - TTTrackWordDeltaZMaxSelector deltaZSelEmu(deltaZMaxEtaBounds_, deltaZMax_); TTTrackNPSStubsMinSelector nPSStubsSel(nPSStubsMin_, tTopo); for (size_t i = 0; i < nOutputApproximate; i++) { @@ -574,40 +424,24 @@ void L1TrackSelectionProducer::produce(edm::StreamID, edm::Event& iEvent, const // Select tracks based on the floating point TTTrack if (processSimulatedTracks_ && kinSel(track) && nPSStubsSel(track) && chi2Sel(track)) { vTTTrackOutput->push_back(TTTrackRef(l1TracksHandle, i)); - if (doDeltaZCutSim_ && deltaZSel(track, leadingVertex)) { - vTTTrackAssociatedOutput->push_back(TTTrackRef(l1TracksHandle, i)); - } } // Select tracks based on the bitwise accurate TTTrack_TrackWord if (processEmulatedTracks_ && kinSelEmu(track) && chi2SelEmu(track)) { vTTTrackEmulationOutput->push_back(TTTrackRef(l1TracksHandle, i)); - if (doDeltaZCutEmu_ && deltaZSelEmu(track, leadingEmulationVertex)) { - vTTTrackAssociatedEmulationOutput->push_back(TTTrackRef(l1TracksHandle, i)); - } } } if (debug_ >= 2) { - printDebugInfo(l1TracksHandle, - vTTTrackOutput, - vTTTrackEmulationOutput, - vTTTrackAssociatedOutput, - vTTTrackAssociatedEmulationOutput); + printDebugInfo(l1TracksHandle, vTTTrackOutput, vTTTrackEmulationOutput); } // Put the outputs into the event if (processSimulatedTracks_) { iEvent.put(std::move(vTTTrackOutput), outputCollectionName_); - if (doDeltaZCutSim_) { - iEvent.put(std::move(vTTTrackAssociatedOutput), outputCollectionName_ + "Associated"); - } } if (processEmulatedTracks_) { iEvent.put(std::move(vTTTrackEmulationOutput), outputCollectionName_ + "Emulation"); - if (doDeltaZCutEmu_) { - iEvent.put(std::move(vTTTrackAssociatedEmulationOutput), outputCollectionName_ + "AssociatedEmulation"); - } } } @@ -615,10 +449,7 @@ void L1TrackSelectionProducer::produce(edm::StreamID, edm::Event& iEvent, const void L1TrackSelectionProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { //L1TrackSelectionProducer edm::ParameterSetDescription desc; - desc.add("l1TracksInputTag", edm::InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks")); - desc.addOptional("l1VerticesInputTag", edm::InputTag("l1tVertexFinder", "l1vertices")); - desc.addOptional("l1VerticesEmulationInputTag", - edm::InputTag("l1tVertexFinderEmulator", "l1verticesEmulation")); + desc.add("l1TracksInputTag", edm::InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks")); desc.add("outputCollectionName", "Level1TTTracksSelected"); { edm::ParameterSetDescription descCutSet; @@ -633,16 +464,8 @@ void L1TrackSelectionProducer::fillDescriptions(edm::ConfigurationDescriptions& descCutSet.add("reducedChi2RZMax", 5.0)->setComment("chi2rz/dof must be less than this value"); descCutSet.add("reducedChi2RPhiMax", 20.0)->setComment("chi2rphi/dof must be less than this value"); - descCutSet.add>("deltaZMaxEtaBounds", {0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4}) - ->setComment("these values define the bin boundaries in |eta|"); - descCutSet.add>("deltaZMax", {0.37, 0.50, 0.60, 0.75, 1.00, 1.60}) - ->setComment( - "delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, " - "[cm]"); desc.add("cutSet", descCutSet); } - desc.add("useDisplacedTracksDeltaZOverride", -1.0) - ->setComment("override the deltaZ cut value for displaced tracks"); desc.add("processSimulatedTracks", true) ->setComment("return selected tracks after cutting on the floating point values"); desc.add("processEmulatedTracks", true) diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackVertexAssociationProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackVertexAssociationProducer.cc new file mode 100644 index 0000000000000..134d77570eacc --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackVertexAssociationProducer.cc @@ -0,0 +1,433 @@ +// -*- C++ -*- +// +// Package: L1Trigger/L1TTrackMatch +// Class: L1TrackVertexAssociationProducer +// +/**\class L1TrackVertexAssociationProducer L1TrackVertexAssociationProducer.cc L1Trigger/L1TTrackMatch/plugins/L1TrackVertexAssociationProducer.cc + + Description: Selects a set of L1Tracks based on a set of predefined criteria. + + Implementation: + Inputs: + std::vector - Each floating point TTTrack inside this collection inherits from + a bit-accurate TTTrack_TrackWord, used for emulation purposes. + Outputs: + std::vector - A collection of TTTracks selected from cuts on the TTTrack properties + std::vector - A collection of TTTracks selected from cuts on the TTTrack_TrackWord properties +*/ +// +// Original Author: Alexx Perloff +// Created: Thu, 16 Dec 2021 19:02:50 GMT +// Derivative Author: Nick Manganelli +// Created: Thu, 16 Feb 2023 16:03:32 GMT +// +// + +// system include files +#include +#include +#include +#include + +// Xilinx HLS includes +#include +#include + +// user include files +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/RefVector.h" +#include "DataFormats/Common/interface/RefToPtr.h" +#include "DataFormats/Common/interface/Ptr.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" +#include "L1Trigger/VertexFinder/interface/L1Track.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "CommonTools/Utils/interface/AndSelector.h" +#include "CommonTools/Utils/interface/EtaRangeSelector.h" +#include "CommonTools/Utils/interface/MinSelector.h" +#include "CommonTools/Utils/interface/MinFunctionSelector.h" +#include "CommonTools/Utils/interface/MinNumberSelector.h" +#include "CommonTools/Utils/interface/PtMinSelector.h" +#include "CommonTools/Utils/interface/Selection.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/EDMException.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "Geometry/Records/interface/TrackerTopologyRcd.h" + +// +// class declaration +// + +class L1TrackVertexAssociationProducer : public edm::global::EDProducer<> { +public: + explicit L1TrackVertexAssociationProducer(const edm::ParameterSet&); + ~L1TrackVertexAssociationProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + // ----------constants, enums and typedefs --------- + // Relevant constants for the converted track word + enum TrackBitWidths { + kPtSize = TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1, // Width of pt + kPtMagSize = 9, // Width of pt magnitude (unsigned) + kEtaSize = TTTrack_TrackWord::TrackBitWidths::kTanlSize, // Width of eta + kEtaMagSize = 3, // Width of eta magnitude (signed) + }; + + typedef TTTrack TTTrackType; + typedef std::vector TTTrackCollectionType; + typedef edm::Handle TTTrackCollectionHandle; + typedef edm::RefVector TTTrackRefCollectionType; + typedef std::unique_ptr TTTrackRefCollectionUPtr; + + // ----------member functions ---------------------- + void printDebugInfo(const edm::Handle& l1SelectedTracksHandle, + const edm::Handle& l1SelectedTracksEmulationHandle, + const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput, + const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const; + void printTrackInfo(edm::LogInfo& log, const TTTrackType& track, bool printEmulation = false) const; + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + // ----------selectors ----------------------------- + // Based on recommendations from https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideGenericSelectors + struct TTTrackDeltaZMaxSelector { + TTTrackDeltaZMaxSelector(const std::vector& deltaZMaxEtaBounds, const std::vector& deltaZMax) + : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {} + TTTrackDeltaZMaxSelector(const edm::ParameterSet& cfg) + : deltaZMaxEtaBounds_(cfg.template getParameter("deltaZMaxEtaBounds")), + deltaZMax_(cfg.template getParameter("deltaZMax")) {} + bool operator()(const TTTrackType& t, const l1t::Vertex& v) const { + size_t etaIndex = + std::upper_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(t.momentum().eta())) - + deltaZMaxEtaBounds_.begin() - 1; + if (etaIndex > deltaZMax_.size() - 1) + etaIndex = deltaZMax_.size() - 1; + return std::abs(v.z0() - t.z0()) <= deltaZMax_[etaIndex]; + } + + private: + std::vector deltaZMaxEtaBounds_; + std::vector deltaZMax_; + }; + struct TTTrackWordDeltaZMaxSelector { + TTTrackWordDeltaZMaxSelector(const std::vector& deltaZMaxEtaBounds, const std::vector& deltaZMax) + : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {} + TTTrackWordDeltaZMaxSelector(const edm::ParameterSet& cfg) + : deltaZMaxEtaBounds_(cfg.template getParameter("deltaZMaxEtaBounds")), + deltaZMax_(cfg.template getParameter("deltaZMax")) {} + bool operator()(const TTTrackType& t, const l1t::VertexWord& v) const { + TTTrack_TrackWord::tanl_t etaEmulationBits = t.getTanlWord(); + ap_fixed etaEmulation; + etaEmulation.V = etaEmulationBits.range(); + size_t etaIndex = + std::upper_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(etaEmulation.to_double())) - + deltaZMaxEtaBounds_.begin() - 1; + if (etaIndex > deltaZMax_.size() - 1) + etaIndex = deltaZMax_.size() - 1; + l1t::VertexWord::vtxz0_t fixedTkZ0 = t.undigitizeSignedValue( + t.getZ0Bits(), TTTrack_TrackWord::TrackBitWidths::kZ0Size, TTTrack_TrackWord::stepZ0, 0.0); + + ap_uint ptEmulationBits = t.getTrackWord()( + TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB); + ap_ufixed ptEmulation; + ptEmulation.V = ptEmulationBits.range(); + return std::abs(v.z0() - fixedTkZ0.to_double()) <= deltaZMax_[etaIndex]; + } + + private: + std::vector deltaZMaxEtaBounds_; + std::vector deltaZMax_; + }; + + // ----------member data --------------------------- + const bool processSimulatedTracks_, processEmulatedTracks_; + const edm::EDGetTokenT l1VerticesToken_; + const edm::EDGetTokenT l1SelectedTracksToken_; + const edm::EDGetTokenT l1VerticesEmulationToken_; + const edm::EDGetTokenT l1SelectedTracksEmulationToken_; + const std::string outputCollectionName_; + const edm::ParameterSet cutSet_; + std::vector deltaZMaxEtaBounds_, deltaZMax_; + const double useDisplacedTracksDeltaZOverride_; + int debug_; +}; + +// +// constructors and destructor +// +L1TrackVertexAssociationProducer::L1TrackVertexAssociationProducer(const edm::ParameterSet& iConfig) + : processSimulatedTracks_(iConfig.getParameter("processSimulatedTracks")), + processEmulatedTracks_(iConfig.getParameter("processEmulatedTracks")), + l1VerticesToken_(processSimulatedTracks_ + ? consumes(iConfig.getParameter("l1VerticesInputTag")) + : edm::EDGetTokenT()), + l1SelectedTracksToken_( + processSimulatedTracks_ + ? consumes(iConfig.getParameter("l1SelectedTracksInputTag")) + : edm::EDGetTokenT()), + l1VerticesEmulationToken_( + processEmulatedTracks_ + ? consumes(iConfig.getParameter("l1VerticesEmulationInputTag")) + : edm::EDGetTokenT()), + l1SelectedTracksEmulationToken_(processEmulatedTracks_ + ? consumes(iConfig.getParameter( + "l1SelectedTracksEmulationInputTag")) + : edm::EDGetTokenT()), + outputCollectionName_(iConfig.getParameter("outputCollectionName")), + cutSet_(iConfig.getParameter("cutSet")), + + deltaZMaxEtaBounds_(cutSet_.getParameter>("deltaZMaxEtaBounds")), + deltaZMax_(cutSet_.getParameter>("deltaZMax")), + useDisplacedTracksDeltaZOverride_(iConfig.getParameter("useDisplacedTracksDeltaZOverride")), + debug_(iConfig.getParameter("debug")) { + // Confirm the the configuration makes sense + if (!processSimulatedTracks_ && !processEmulatedTracks_) { + throw cms::Exception("You must process at least one of the track collections (simulated or emulated)."); + } + + if (deltaZMax_.size() != deltaZMaxEtaBounds_.size() - 1) { + throw cms::Exception("The number of deltaZ cuts does not match the number of eta bins!"); + } + + if (useDisplacedTracksDeltaZOverride_ >= 0) { + deltaZMax_ = std::vector(deltaZMax_.size(), useDisplacedTracksDeltaZOverride_); + } + + // Get additional input tags and define the EDM output based on the previous configuration parameters + if (processSimulatedTracks_) + produces(outputCollectionName_); + if (processEmulatedTracks_) + produces(outputCollectionName_ + "Emulation"); +} + +L1TrackVertexAssociationProducer::~L1TrackVertexAssociationProducer() {} + +// +// member functions +// + +void L1TrackVertexAssociationProducer::printDebugInfo( + const edm::Handle& l1SelectedTracksHandle, + const edm::Handle& l1SelectedTracksEmulationHandle, + const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput, + const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const { + edm::LogInfo log("L1TrackVertexAssociationProducer"); + if (processSimulatedTracks_) { + log << "The original selected track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are " + "... \n"; + for (const auto& track : *l1SelectedTracksHandle) { + printTrackInfo(log, *track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << l1SelectedTracksHandle->size() << "\n\n"; + } + if (processEmulatedTracks_) { + log << "The original selected emulated track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) " + "values are ... \n"; + for (const auto& track : *l1SelectedTracksEmulationHandle) { + printTrackInfo(log, *track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << l1SelectedTracksEmulationHandle->size() << "\n\n"; + } + if (processSimulatedTracks_ && processEmulatedTracks_) { + TTTrackRefCollectionType inSimButNotEmu; + TTTrackRefCollectionType inEmuButNotSim; + std::set_difference(l1SelectedTracksHandle->begin(), + l1SelectedTracksHandle->end(), + l1SelectedTracksEmulationHandle->begin(), + l1SelectedTracksEmulationHandle->end(), + std::back_inserter(inSimButNotEmu)); + std::set_difference(l1SelectedTracksEmulationHandle->begin(), + l1SelectedTracksEmulationHandle->end(), + l1SelectedTracksHandle->begin(), + l1SelectedTracksHandle->end(), + std::back_inserter(inEmuButNotSim)); + log << "The set of tracks selected via cuts on the simulated values which are not in the set of tracks selected " + "by cutting on the emulated values ... \n"; + for (const auto& track : inSimButNotEmu) { + printTrackInfo(log, *track, debug_ >= 3); + } + log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n" + << "The set of tracks selected via cuts on the emulated values which are not in the set of tracks selected " + "by cutting on the simulated values ... \n"; + for (const auto& track : inEmuButNotSim) { + printTrackInfo(log, *track, debug_ >= 3); + } + log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n"; + } + if (processSimulatedTracks_) { + log << "The selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, chi2rz, " + "chi2rphi, z0) values are ... \n"; + for (const auto& track : *vTTTrackAssociatedOutput) { + printTrackInfo(log, *track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedOutput->size() << "\n\n"; + } + if (processEmulatedTracks_) { + log << "The emulation selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, " + "chi2rz, chi2rphi, z0) values are " + "... \n"; + for (const auto& track : *vTTTrackAssociatedEmulationOutput) { + printTrackInfo(log, *track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedEmulationOutput->size() << "\n\n"; + } + if (processSimulatedTracks_ && processEmulatedTracks_) { + TTTrackRefCollectionType inSimButNotEmu; + TTTrackRefCollectionType inEmuButNotSim; + std::set_difference(vTTTrackAssociatedOutput->begin(), + vTTTrackAssociatedOutput->end(), + vTTTrackAssociatedEmulationOutput->begin(), + vTTTrackAssociatedEmulationOutput->end(), + std::back_inserter(inSimButNotEmu)); + std::set_difference(vTTTrackAssociatedEmulationOutput->begin(), + vTTTrackAssociatedEmulationOutput->end(), + vTTTrackAssociatedOutput->begin(), + vTTTrackAssociatedOutput->end(), + std::back_inserter(inEmuButNotSim)); + log << "The set of vertex associated tracks selected via cuts on the simulated values which are not in the set of " + "tracks selected " + "by cutting on the emulated values ... \n"; + for (const auto& track : inSimButNotEmu) { + printTrackInfo(log, *track, debug_ >= 3); + } + log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n" + << "The set of vertex associated tracks selected via cuts on the emulated values which are not in the set of " + "tracks selected " + "by cutting on the simulated values ... \n"; + for (const auto& track : inEmuButNotSim) { + printTrackInfo(log, *track, debug_ >= 3); + } + log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n"; + } +} + +void L1TrackVertexAssociationProducer::printTrackInfo(edm::LogInfo& log, + const TTTrackType& track, + bool printEmulation) const { + log << "\t(" << track.momentum().perp() << ", " << track.momentum().eta() << ", " << track.momentum().phi() << ", " + << track.getStubRefs().size() << ", " << track.stubPtConsistency() << ", " << track.chi2ZRed() << ", " + << track.chi2XYRed() << ", " << track.z0() << ")\n"; + + if (printEmulation) { + ap_uint ptEmulationBits = track.getTrackWord()( + TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB); + ap_ufixed ptEmulation; + ptEmulation.V = ptEmulationBits.range(); + TTTrack_TrackWord::tanl_t etaEmulationBits = track.getTanlWord(); + ap_fixed etaEmulation; + etaEmulation.V = etaEmulationBits.range(); + double floatTkZ0 = track.undigitizeSignedValue( + track.getZ0Bits(), TTTrack_TrackWord::TrackBitWidths::kZ0Size, TTTrack_TrackWord::stepZ0, 0.0); + double floatTkPhi = track.undigitizeSignedValue( + track.getPhiBits(), TTTrack_TrackWord::TrackBitWidths::kPhiSize, TTTrack_TrackWord::stepPhi0, 0.0); + log << "\t\t(" << ptEmulation.to_double() << ", " << etaEmulation.to_double() << ", " << floatTkPhi << ", " + << track.getNStubs() << ", " << track.getBendChi2() << ", " << track.getChi2RZ() << ", " << track.getChi2RPhi() + << ", " << floatTkZ0 << ")\n"; + } +} + +// ------------ method called to produce the data ------------ +void L1TrackVertexAssociationProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + auto vTTTrackAssociatedOutput = std::make_unique(); + auto vTTTrackAssociatedEmulationOutput = std::make_unique(); + + // TTTrackCollectionHandle l1TracksHandle; + edm::Handle l1SelectedTracksHandle; + edm::Handle l1SelectedTracksEmulationHandle; + edm::Handle l1VerticesHandle; + edm::Handle l1VerticesEmulationHandle; + + l1t::Vertex leadingVertex; + l1t::VertexWord leadingEmulationVertex; + + TTTrackDeltaZMaxSelector deltaZSel(deltaZMaxEtaBounds_, deltaZMax_); + TTTrackWordDeltaZMaxSelector deltaZSelEmu(deltaZMaxEtaBounds_, deltaZMax_); + + if (processSimulatedTracks_) { + iEvent.getByToken(l1SelectedTracksToken_, l1SelectedTracksHandle); + iEvent.getByToken(l1VerticesToken_, l1VerticesHandle); + size_t nOutputApproximate = l1SelectedTracksHandle->size(); + leadingVertex = l1VerticesHandle->at(0); + if (debug_ >= 2) { + edm::LogInfo("L1TrackVertexAssociationProducer") << "leading vertex z0 = " << leadingVertex.z0(); + } + vTTTrackAssociatedOutput->reserve(nOutputApproximate); + for (const auto& trackword : *l1SelectedTracksHandle) { + auto track = l1tVertexFinder::L1Track(edm::refToPtr(trackword)); + // Select tracks based on the floating point TTTrack + if (deltaZSel(*trackword, leadingVertex)) { + vTTTrackAssociatedOutput->push_back(trackword); + } + } + iEvent.put(std::move(vTTTrackAssociatedOutput), outputCollectionName_); + } + if (processEmulatedTracks_) { + iEvent.getByToken(l1SelectedTracksEmulationToken_, l1SelectedTracksEmulationHandle); + iEvent.getByToken(l1VerticesEmulationToken_, l1VerticesEmulationHandle); + size_t nOutputApproximateEmulation = l1SelectedTracksEmulationHandle->size(); + leadingEmulationVertex = l1VerticesEmulationHandle->at(0); + if (debug_ >= 2) { + edm::LogInfo("L1TrackVertexAssociationProducer") + << "leading emulation vertex z0 = " << leadingEmulationVertex.z0(); + } + vTTTrackAssociatedEmulationOutput->reserve(nOutputApproximateEmulation); + for (const auto& trackword : *l1SelectedTracksEmulationHandle) { + // Select tracks based on the bitwise accurate TTTrack_TrackWord + if (deltaZSelEmu(*trackword, leadingEmulationVertex)) { + vTTTrackAssociatedEmulationOutput->push_back(trackword); + } + } + iEvent.put(std::move(vTTTrackAssociatedEmulationOutput), outputCollectionName_ + "Emulation"); + } + + if (processSimulatedTracks_ && processEmulatedTracks_ && debug_ >= 2) { + printDebugInfo(l1SelectedTracksHandle, + l1SelectedTracksEmulationHandle, + vTTTrackAssociatedOutput, + vTTTrackAssociatedEmulationOutput); + } +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1TrackVertexAssociationProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("l1SelectedTracksInputTag", + edm::InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelected")); + desc.add("l1SelectedTracksEmulationInputTag", + edm::InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelectedEmulation")); + desc.add("l1VerticesInputTag", edm::InputTag("l1tVertexFinder", "L1Vertices")); + desc.add("l1VerticesEmulationInputTag", + edm::InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation")); + desc.add("outputCollectionName", "Level1TTTracksSelectedAssociated"); + { + edm::ParameterSetDescription descCutSet; + descCutSet.add>("deltaZMaxEtaBounds", {0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4}) + ->setComment("these values define the bin boundaries in |eta|"); + descCutSet.add>("deltaZMax", {0.37, 0.50, 0.60, 0.75, 1.00, 1.60}) + ->setComment( + "delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, " + "[cm]"); + desc.add("cutSet", descCutSet); + } + desc.add("useDisplacedTracksDeltaZOverride", -1.0) + ->setComment("override the deltaZ cut value for displaced tracks"); + desc.add("processSimulatedTracks", true) + ->setComment("return selected tracks after cutting on the floating point values"); + desc.add("processEmulatedTracks", true) + ->setComment("return selected tracks after cutting on the bitwise emulated values"); + desc.add("debug", 0)->setComment("Verbosity levels: 0, 1, 2, 3"); + descriptions.addWithDefaultLabel(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1TrackVertexAssociationProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc index f9652eeefd365..aa20f48176d57 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc @@ -82,7 +82,6 @@ L1TrackerEtMissEmulatorProducer::L1TrackerEtMissEmulatorProducer(const edm::Para // Get Emulator config parameters cordicSteps_ = (int)iConfig.getParameter("nCordicSteps"); debug_ = (int)iConfig.getParameter("debug"); - // Name of output ED Product L1MetCollectionName_ = (std::string)iConfig.getParameter("L1MetCollectionName"); @@ -90,12 +89,8 @@ L1TrackerEtMissEmulatorProducer::L1TrackerEtMissEmulatorProducer(const edm::Para cordicDebug_ = true; } - // To have same bin spacing between 0 and pi/2 as between original phi - // granularity - int cosLUTbins = std::floor(l1tmetemu::kMaxCosLUTPhi / TTTrack_TrackWord::stepPhi0); - // Compute LUTs - cosLUT_ = l1tmetemu::generateCosLUT(cosLUTbins); + cosLUT_ = l1tmetemu::generateCosLUT(); // Print LUTs if (debug_ == 1) { @@ -185,45 +180,52 @@ void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::Eve // through cosLUT_ gives sin Sum sector Et -ve when cos or sin phi are -ve sector_totals[track->phiSector()] += 1; if (globalPhi >= phiQuadrants_[0] && globalPhi < phiQuadrants_[1]) { - temppx = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[globalPhi]); - temppy = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[phiQuadrants_[1] - 1 - globalPhi]); + temppx = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi) >> l1tmetemu::kCosLUTShift]); + temppy = + ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[1] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]); if (debug_ == 2) { edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") << "Sector: " << track->phiSector() << " Quadrant: " << 1 << "\n" - << "Emu Phi: " << globalPhi << " Emu Cos(Phi): " << cosLUT_[globalPhi] - << " Emu Sin(Phi): " << cosLUT_[phiQuadrants_[1] - 1 - globalPhi] << "\n"; + << "Emu Phi: " << globalPhi << " Emu Cos(Phi): " << cosLUT_[(globalPhi) >> l1tmetemu::kCosLUTShift] + << " Emu Sin(Phi): " << cosLUT_[(phiQuadrants_[1] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift] << "\n"; } } else if (globalPhi >= phiQuadrants_[1] && globalPhi < phiQuadrants_[2]) { - temppx = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[phiQuadrants_[2] - 1 - globalPhi]); - temppy = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[globalPhi - phiQuadrants_[1]]); + temppx = + -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[2] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]); + temppy = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[1]) >> l1tmetemu::kCosLUTShift]); if (debug_ == 2) { edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") << "Sector: " << track->phiSector() << " Quadrant: " << 2 << "\n" - << "Emu Phi: " << globalPhi << " Emu Cos(Phi): -" << cosLUT_[phiQuadrants_[2] - 1 - globalPhi] - << " Emu Sin(Phi): " << cosLUT_[globalPhi - phiQuadrants_[1]] << "\n"; + << "Emu Phi: " << globalPhi << " Emu Cos(Phi): -" + << cosLUT_[(phiQuadrants_[2] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift] + << " Emu Sin(Phi): " << cosLUT_[(globalPhi - phiQuadrants_[1]) >> l1tmetemu::kCosLUTShift] << "\n"; } } else if (globalPhi >= phiQuadrants_[2] && globalPhi < phiQuadrants_[3]) { - temppx = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[globalPhi - phiQuadrants_[2]]); - temppy = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[phiQuadrants_[3] - 1 - globalPhi]); + temppx = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[2]) >> l1tmetemu::kCosLUTShift]); + temppy = + -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[3] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]); if (debug_ == 2) { edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") << "Sector: " << track->phiSector() << " Quadrant: " << 3 << "\n" - << "Emu Phi: " << globalPhi << " Emu Cos(Phi): -" << cosLUT_[globalPhi - phiQuadrants_[2]] - << " Emu Sin(Phi): -" << cosLUT_[phiQuadrants_[3] - 1 - globalPhi] << "\n"; + << "Emu Phi: " << globalPhi << " Emu Cos(Phi): -" + << cosLUT_[(globalPhi - phiQuadrants_[2]) >> l1tmetemu::kCosLUTShift] << " Emu Sin(Phi): -" + << cosLUT_[(phiQuadrants_[3] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift] << "\n"; } } else if (globalPhi >= phiQuadrants_[3] && globalPhi < phiQuadrants_[4]) { - temppx = ((l1tmetemu::Et_t)ptEmulation * cosLUT_[phiQuadrants_[4] - 1 - globalPhi]); - temppy = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[globalPhi - phiQuadrants_[3]]); + temppx = + ((l1tmetemu::Et_t)ptEmulation * cosLUT_[(phiQuadrants_[4] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift]); + temppy = -((l1tmetemu::Et_t)ptEmulation * cosLUT_[(globalPhi - phiQuadrants_[3]) >> l1tmetemu::kCosLUTShift]); if (debug_ == 2) { edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") << "Sector: " << track->phiSector() << " Quadrant: " << 4 << "\n" - << " Emu Phi: " << globalPhi << " Emu Cos(Phi): " << cosLUT_[phiQuadrants_[4] - 1 - globalPhi] - << " Emu Sin(Phi): -" << cosLUT_[globalPhi - phiQuadrants_[3]] << "\n"; + << " Emu Phi: " << globalPhi + << " Emu Cos(Phi): " << cosLUT_[(phiQuadrants_[4] - 1 - globalPhi) >> l1tmetemu::kCosLUTShift] + << " Emu Sin(Phi): -" << cosLUT_[(globalPhi - phiQuadrants_[3]) >> l1tmetemu::kCosLUTShift] << "\n"; } } else { temppx = 0; diff --git a/L1Trigger/L1TTrackMatch/python/L1TkMETAnalyser_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkMETAnalyser_cfi.py index 5c36564b50c06..ba1ae0ea3eb1f 100644 --- a/L1Trigger/L1TTrackMatch/python/L1TkMETAnalyser_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/L1TkMETAnalyser_cfi.py @@ -1,7 +1,7 @@ import FWCore.ParameterSet.Config as cms L1TkMETAnalyser = cms.EDAnalyzer('L1TkMETAnalyser', - TrackMETInputTag = cms.InputTag("l1tTrackerEtMiss","l1tTrackerEtMiss"), + TrackMETInputTag = cms.InputTag("l1tTrackerEtMiss","L1TrackerEtMiss"), TrackMETEmuInputTag = cms.InputTag("l1tTrackerEmuEtMiss","L1TrackerEmuEtMiss"), TrackMETHWInputTag = cms.InputTag("GTTOutputFileReader"), HW_Analysis = cms.bool(False) diff --git a/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py b/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py index 3ca0ab90d2387..6b642ed5781a2 100644 --- a/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py +++ b/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py @@ -50,8 +50,9 @@ # from L1Trigger.L1TTrackMatch.L1TkCaloJetProducer_cfi import L1TkCaloJets # pL1TkCaloJets = cms.Path( L1TkCaloJets) +from L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi import l1tTrackSelectionProducer from L1Trigger.VertexFinder.l1tVertexProducer_cfi import l1tVertexProducer -pVertexProducer = cms.Path( l1tVertexProducer ) +pVertexProducer = cms.Path( l1tTrackSelectionProducer * l1tVertexProducer ) # from L1Trigger.L1TTrackMatch.l1tTrackerEtMiss_cfi import l1tTrackerEtMiss # pL1TrkMET = cms.Path( l1tTrackerEtMiss ) diff --git a/L1Trigger/L1TTrackMatch/python/l1tFastTrackingJetProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/l1tFastTrackingJetProducer_cfi.py index f28047728f903..c81bf7a14ef39 100644 --- a/L1Trigger/L1TTrackMatch/python/l1tFastTrackingJetProducer_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/l1tFastTrackingJetProducer_cfi.py @@ -2,7 +2,7 @@ l1tFastTrackingJets = cms.EDProducer("L1FastTrackingJetProducer", L1TrackInputTag = cms.InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks"), - L1PrimaryVertexTag=cms.InputTag("l1tVertexProducer", "l1vertices"), + L1PrimaryVertexTag=cms.InputTag("l1tVertexProducer", "L1Vertices"), GenInfo = cms.InputTag("TTTrackAssociatorFromPixelDigis", "Level1TTTracks"), trk_zMax = cms.double(15.), # max track z0 [cm] trk_chi2dofMax = cms.double(10.), # max track chi2/dof @@ -24,7 +24,7 @@ l1tFastTrackingJetsExtended = cms.EDProducer("L1FastTrackingJetProducer", L1TrackInputTag = cms.InputTag("l1tTTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), - L1PrimaryVertexTag=cms.InputTag("l1tVertexProducer", "l1vertices"), + L1PrimaryVertexTag=cms.InputTag("l1tVertexProducer", "L1Vertices"), GenInfo = cms.InputTag("TTTrackAssociatorFromPixelDigisExtended", "Level1TTTracks"), trk_zMax = cms.double(15.), # max track z0 [cm] trk_chi2dofMax = cms.double(40.), # max track chi2 for extended tracks diff --git a/L1Trigger/L1TTrackMatch/python/l1tTrackFastJets_cfi.py b/L1Trigger/L1TTrackMatch/python/l1tTrackFastJets_cfi.py index 70f71f9ef6299..183244e7d0ad1 100644 --- a/L1Trigger/L1TTrackMatch/python/l1tTrackFastJets_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/l1tTrackFastJets_cfi.py @@ -2,7 +2,7 @@ l1tTrackFastJets = cms.EDProducer("L1TrackFastJetProducer", L1TrackInputTag = cms.InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks"), - L1PrimaryVertexTag=cms.InputTag("l1tVertexProducer", "l1vertices"), + L1PrimaryVertexTag=cms.InputTag("l1tVertexFinder", "L1Vertices"), trk_zMax = cms.double(15.), # max track z0 [cm] trk_chi2dofMax = cms.double(10.), # max track chi2/dof trk_bendChi2Max = cms.double(2.2),# max bendChi2 cut @@ -20,7 +20,7 @@ l1tTrackFastJetsExtended = cms.EDProducer("L1TrackFastJetProducer", L1TrackInputTag = cms.InputTag("l1tTTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), - L1PrimaryVertexTag=cms.InputTag("l1tVertexProducer", "l1vertices"), + L1PrimaryVertexTag=cms.InputTag("l1tVertexFinder", "L1Vertices"), trk_zMax = cms.double(15.), # max track z0 [cm] trk_chi2dofMax = cms.double(40.), # max track chi2 for extended tracks trk_bendChi2Max = cms.double(2.4),#Bendchi2 cut for extended tracks diff --git a/L1Trigger/L1TTrackMatch/python/l1tTrackJetsEmulation_cfi.py b/L1Trigger/L1TTrackMatch/python/l1tTrackJetsEmulation_cfi.py index 9276870a56a70..9a227295a7257 100644 --- a/L1Trigger/L1TTrackMatch/python/l1tTrackJetsEmulation_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/l1tTrackJetsEmulation_cfi.py @@ -1,8 +1,8 @@ import FWCore.ParameterSet.Config as cms l1tTrackJetsEmulation = cms.EDProducer('L1TrackJetEmulatorProducer', - L1TrackInputTag= cms.InputTag("l1tGTTInputProducer", "Level1TTTracksConverted"), - L1PVertexInputTag= cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation"), + L1TrackInputTag= cms.InputTag("l1tTrackVertexAssociationProducerForJets", "Level1TTTracksSelectedAssociatedEmulation"), + L1PVertexInputTag=cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), MaxDzTrackPV = cms.double(1.0), trk_zMax = cms.double (15.) , # maximum track z trk_ptMax = cms.double(200.), # maximumum track pT before saturation [GeV] @@ -32,7 +32,8 @@ ) l1tTrackJetsExtendedEmulation = l1tTrackJetsEmulation.clone( - L1TrackInputTag= ("l1tGTTInputProducerExtended", "Level1TTTracksExtendedConverted"), + L1TrackInputTag= cms.InputTag("l1tTrackVertexAssociationProducerExtendedForJets", "Level1TTTracksExtendedSelectedAssociatedEmulation"), + L1PVertexInputTag=cms.InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation"), minTrkJetpT= 5.0, # minimum track pt to be considered for track jet MaxDzTrackPV = 5.0, d0_cutNStubs4= -1, # -1 excludes nstub=4 from disp tag diff --git a/L1Trigger/L1TTrackMatch/python/l1tTrackJets_cfi.py b/L1Trigger/L1TTrackMatch/python/l1tTrackJets_cfi.py index 173907323a35b..353d8c5e126e3 100644 --- a/L1Trigger/L1TTrackMatch/python/l1tTrackJets_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/l1tTrackJets_cfi.py @@ -2,8 +2,8 @@ #prompt jet selection l1tTrackJets = cms.EDProducer('L1TrackJetProducer', - L1TrackInputTag= cms.InputTag("l1tTTTracksFromTrackletEmulation","Level1TTTracks"), - L1PVertexInputTag = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation"), + L1TrackInputTag = cms.InputTag("l1tTrackVertexAssociationProducerForJets", "Level1TTTracksSelectedAssociated"), + L1PVertexInputTag = cms.InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation"), MaxDzTrackPV = cms.double( 1.0 ), #max distance from PV;negative=no cut trk_zMax = cms.double (15.) , # maximum track z trk_ptMax = cms.double(200.), # maximumum track pT before saturation [GeV] @@ -34,16 +34,16 @@ #displaced jets l1tTrackJetsExtended = l1tTrackJets.clone( - L1TrackInputTag= ("l1tTTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), + L1TrackInputTag = cms.InputTag("l1tTrackVertexAssociationProducerExtendedForJets", "Level1TTTracksExtendedSelectedAssociated"), MaxDzTrackPV = 5.0 , # tracks with dz(trk,PV)>cut excluded - minTrkJetpT= 5., # min track jet pt to be considered for most energetic zbin finding - d0_cutNStubs5= 0.22, # -1 excludes nstub>4 from disp tag process - displaced=True, #Flag for displaced tracks - nStubs4DisplacedChi2= 3.3, #Disp tracks selection [trk4 from disp tag process + displaced = True, #Flag for displaced tracks + nStubs4DisplacedChi2 = 3.3, #Disp tracks selection [trk 0, tracks with PT above maxPt are considered as # mismeasured and are treated according to highPtTracks below. # When maxPt < 0, no special treatment is done for high PT tracks. @@ -14,7 +14,7 @@ ) l1tTrackerEtMissExtended = l1tTrackerEtMiss.clone( #NOT OPTIMIZED, STUDIED, OR USED - L1TrackInputTag = ("l1tTrackSelectionProducerExtended", "Level1TTTracksExtendedSelected"), - L1TrackAssociatedInputTag = ("l1tTrackSelectionProducerExtended", "Level1TTTracksExtendedSelectedAssociated"), - L1MetCollectionName = "l1tTrackerExtendedEtMiss", + L1TrackInputTag = ("l1tTrackSelectionProducerExtendedForEtMiss", "Level1TTTracksExtendedSelected"), + L1TrackAssociatedInputTag = ("l1tTrackVertexAssociationProducerExtendedForEtMiss", "Level1TTTracksExtendedSelectedAssociated"), + L1MetCollectionName = "L1TrackerExtendedEtMiss", ) diff --git a/L1Trigger/L1TTrackMatch/python/l1tTrackerHTMiss_cfi.py b/L1Trigger/L1TTrackMatch/python/l1tTrackerHTMiss_cfi.py index b7a19f27cc159..79fac31823c8b 100644 --- a/L1Trigger/L1TTrackMatch/python/l1tTrackerHTMiss_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/l1tTrackerHTMiss_cfi.py @@ -2,7 +2,7 @@ l1tTkCaloHTMiss = cms.EDProducer("L1TkHTMissProducer", L1TkJetInputTag = cms.InputTag("l1tTkCaloJets", "L1TkCaloJets"), - L1VertexInputTag = cms.InputTag("l1tVertexProducer", "l1vertices"), + L1VertexInputTag = cms.InputTag("l1tVertexFinder", "L1Vertices"), jet_maxEta = cms.double(2.2), # maximum eta of jets for HT jet_minPt = cms.double(15.0), # minimum pt of jets for HT [GeV] jet_minNtracksHighPt=cms.int32(0), #Add track jet quality criteria pT>100 @@ -20,7 +20,7 @@ l1tTrackerHTMiss = cms.EDProducer("L1TkHTMissProducer", L1TkJetInputTag = cms.InputTag("l1tTrackJets", "L1TrackJets"), - L1VertexInputTag = cms.InputTag("l1tVertexProducer", "l1vertices"), + L1VertexInputTag = cms.InputTag("l1tVertexFinder", "L1Vertices"), jet_maxEta = cms.double(2.4), jet_minPt = cms.double(5.0), jet_minNtracksLowPt=cms.int32(2), @@ -36,7 +36,7 @@ l1tTrackerHTMissExtended = cms.EDProducer("L1TkHTMissProducer", L1TkJetInputTag = cms.InputTag("l1tTrackJetsExtended", "L1TrackJetsExtended"), - L1VertexInputTag = cms.InputTag("l1tVertexProducer", "l1vertices"), + L1VertexInputTag = cms.InputTag("l1tVertexFinder", "L1Vertices"), jet_maxEta = cms.double(2.4), jet_minPt = cms.double(5.0), jet_minNtracksLowPt=cms.int32(2), diff --git a/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuAlgo.cc b/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuAlgo.cc index 6f82bfd0bef2e..e1ef12f242b08 100644 --- a/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuAlgo.cc +++ b/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuAlgo.cc @@ -3,15 +3,16 @@ using namespace std; namespace l1tmetemu { - std::vector generateCosLUT(unsigned int size) { // Fill cosine LUT with integer values + std::vector generateCosLUT() { // Fill cosine LUT with integer values float phi = 0; std::vector cosLUT; - for (unsigned int LUT_idx = 0; LUT_idx < size; LUT_idx++) { + double stepPhi = TTTrack_TrackWord::stepPhi0 * (1 << l1tmetemu::kCosLUTShift); + for (unsigned int LUT_idx = 0; LUT_idx < l1tmetemu::kCosLUTBins; LUT_idx++) { cosLUT.push_back((cos_lut_fixed_t)(cos(phi))); - phi += TTTrack_TrackWord::stepPhi0; + phi += stepPhi; //std::cout << LUT_idx << "," << (cos_lut_fixed_t)(cos(phi)) << std::endl; } - cosLUT.push_back((cos_lut_fixed_t)(0)); //Prevent overflow in last bin + cosLUT[1023] = (cos_lut_fixed_t)(0); //Match F/W for Integration Tests return cosLUT; } diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackMET_cfg.py b/L1Trigger/L1TTrackMatch/test/L1TrackMET_cfg.py index c8ebed5fd351f..6c441a3ba61cc 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackMET_cfg.py +++ b/L1Trigger/L1TTrackMatch/test/L1TrackMET_cfg.py @@ -71,17 +71,18 @@ # Primary vertex ############################################################ +process.load('L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi') process.load('L1Trigger.VertexFinder.l1tVertexProducer_cfi') process.l1tVertexProducer.l1TracksInputTag = cms.InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks") - +producerSum += process.l1tTrackSelectionProducer producerSum += process.l1tVertexProducer producerName = 'VertexProducer{0}'.format("fastHisto") producerName = producerName.replace(".","p") # legalize the name producer = process.l1tVertexProducer.clone() producer.VertexReconstruction.Algorithm = cms.string("fastHisto") -process.l1tTrackerEtMiss.L1VertexInputTag = cms.InputTag(producerName,"l1vertices") +process.l1tTrackerEtMiss.L1VertexInputTag = cms.InputTag(producerName,"L1Vertices") setattr(process, producerName, producer) @@ -99,7 +100,7 @@ EmuproducerName = EmuproducerName.replace(".","p") # legalize the name Emuproducer = process.l1tVertexProducer.clone() Emuproducer.VertexReconstruction.Algorithm = cms.string("fastHistoEmulation") -process.l1tTrackerEmuEtMiss.L1VertexInputTag = cms.InputTag(EmuproducerName,"l1verticesEmulation") +process.l1tTrackerEmuEtMiss.L1VertexInputTag = cms.InputTag(EmuproducerName,"L1VerticesEmulation") if GTTInput: Emuproducer.l1TracksInputTag = cms.InputTag("l1tGTTInputProducer","Level1TTTracksConverted") diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc index 41eeaf5baf170..a0631dc9bb7c7 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc +++ b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc @@ -142,16 +142,36 @@ class L1TrackObjectNtupleMaker : public edm::one::EDAnalyzer ttTrackGTTToken_; edm::EDGetTokenT ttTrackSelectedToken_; edm::EDGetTokenT ttTrackSelectedEmulationToken_; + edm::EDGetTokenT ttTrackSelectedAssociatedToken_; + edm::EDGetTokenT ttTrackSelectedAssociatedEmulationToken_; + edm::EDGetTokenT ttTrackSelectedForJetsToken_; + edm::EDGetTokenT ttTrackSelectedEmulationForJetsToken_; + edm::EDGetTokenT ttTrackSelectedAssociatedForJetsToken_; + edm::EDGetTokenT ttTrackSelectedAssociatedEmulationForJetsToken_; + edm::EDGetTokenT ttTrackSelectedForEtMissToken_; + edm::EDGetTokenT ttTrackSelectedEmulationForEtMissToken_; + edm::EDGetTokenT ttTrackSelectedAssociatedForEtMissToken_; + edm::EDGetTokenT ttTrackSelectedAssociatedEmulationForEtMissToken_; edm::EDGetTokenT ttTrackExtendedToken_; edm::EDGetTokenT> ttTrackMCTruthExtendedToken_; edm::EDGetTokenT ttTrackExtendedGTTToken_; edm::EDGetTokenT ttTrackExtendedSelectedToken_; edm::EDGetTokenT ttTrackExtendedSelectedEmulationToken_; + edm::EDGetTokenT ttTrackExtendedSelectedAssociatedToken_; + edm::EDGetTokenT ttTrackExtendedSelectedAssociatedEmulationToken_; + edm::EDGetTokenT ttTrackExtendedSelectedForJetsToken_; + edm::EDGetTokenT ttTrackExtendedSelectedEmulationForJetsToken_; + edm::EDGetTokenT ttTrackExtendedSelectedAssociatedForJetsToken_; + edm::EDGetTokenT ttTrackExtendedSelectedAssociatedEmulationForJetsToken_; + edm::EDGetTokenT ttTrackExtendedSelectedForEtMissToken_; + edm::EDGetTokenT ttTrackExtendedSelectedEmulationForEtMissToken_; + edm::EDGetTokenT ttTrackExtendedSelectedAssociatedForEtMissToken_; + edm::EDGetTokenT ttTrackExtendedSelectedAssociatedEmulationForEtMissToken_; edm::EDGetTokenT> TrackingParticleToken_; edm::EDGetTokenT> TrackingVertexToken_; @@ -273,6 +313,16 @@ class L1TrackObjectNtupleMaker : public edm::one::EDAnalyzer* m_trk_gtt_phi; std::vector* m_trk_selected_index; std::vector* m_trk_selected_emulation_index; + std::vector* m_trk_selected_associated_index; + std::vector* m_trk_selected_associated_emulation_index; + std::vector* m_trk_selected_forjets_index; + std::vector* m_trk_selected_emulation_forjets_index; + std::vector* m_trk_selected_associated_forjets_index; + std::vector* m_trk_selected_associated_emulation_forjets_index; + std::vector* m_trk_selected_foretmiss_index; + std::vector* m_trk_selected_emulation_foretmiss_index; + std::vector* m_trk_selected_associated_foretmiss_index; + std::vector* m_trk_selected_associated_emulation_foretmiss_index; // all L1 tracks (extended) std::vector* m_trkExt_pt; @@ -309,6 +359,16 @@ class L1TrackObjectNtupleMaker : public edm::one::EDAnalyzer* m_trkExt_gtt_phi; std::vector* m_trkExt_selected_index; std::vector* m_trkExt_selected_emulation_index; + std::vector* m_trkExt_selected_associated_index; + std::vector* m_trkExt_selected_associated_emulation_index; + std::vector* m_trkExt_selected_forjets_index; + std::vector* m_trkExt_selected_emulation_forjets_index; + std::vector* m_trkExt_selected_associated_forjets_index; + std::vector* m_trkExt_selected_associated_emulation_forjets_index; + std::vector* m_trkExt_selected_foretmiss_index; + std::vector* m_trkExt_selected_emulation_foretmiss_index; + std::vector* m_trkExt_selected_associated_foretmiss_index; + std::vector* m_trkExt_selected_associated_emulation_foretmiss_index; // all tracking particles std::vector* m_tp_pt; @@ -498,6 +558,23 @@ L1TrackObjectNtupleMaker::L1TrackObjectNtupleMaker(edm::ParameterSet const& iCon L1TrackGTTInputTag = iConfig.getParameter("L1TrackGTTInputTag"); L1TrackSelectedInputTag = iConfig.getParameter("L1TrackSelectedInputTag"); L1TrackSelectedEmulationInputTag = iConfig.getParameter("L1TrackSelectedEmulationInputTag"); + L1TrackSelectedAssociatedInputTag = iConfig.getParameter("L1TrackSelectedAssociatedInputTag"); + L1TrackSelectedAssociatedEmulationInputTag = + iConfig.getParameter("L1TrackSelectedAssociatedEmulationInputTag"); + L1TrackSelectedForJetsInputTag = iConfig.getParameter("L1TrackSelectedForJetsInputTag"); + L1TrackSelectedEmulationForJetsInputTag = + iConfig.getParameter("L1TrackSelectedEmulationForJetsInputTag"); + L1TrackSelectedAssociatedForJetsInputTag = + iConfig.getParameter("L1TrackSelectedAssociatedForJetsInputTag"); + L1TrackSelectedAssociatedEmulationForJetsInputTag = + iConfig.getParameter("L1TrackSelectedAssociatedEmulationForJetsInputTag"); + L1TrackSelectedForEtMissInputTag = iConfig.getParameter("L1TrackSelectedForEtMissInputTag"); + L1TrackSelectedEmulationForEtMissInputTag = + iConfig.getParameter("L1TrackSelectedEmulationForEtMissInputTag"); + L1TrackSelectedAssociatedForEtMissInputTag = + iConfig.getParameter("L1TrackSelectedAssociatedForEtMissInputTag"); + L1TrackSelectedAssociatedEmulationForEtMissInputTag = + iConfig.getParameter("L1TrackSelectedAssociatedEmulationForEtMissInputTag"); TrackFastJetsInputTag = iConfig.getParameter("TrackFastJetsInputTag"); TrackJetsInputTag = iConfig.getParameter("TrackJetsInputTag"); TrackJetsEmuInputTag = iConfig.getParameter("TrackJetsEmuInputTag"); @@ -511,6 +588,20 @@ L1TrackObjectNtupleMaker::L1TrackObjectNtupleMaker(edm::ParameterSet const& iCon ttTrackGTTToken_ = consumes(L1TrackGTTInputTag); ttTrackSelectedToken_ = consumes(L1TrackSelectedInputTag); ttTrackSelectedEmulationToken_ = consumes(L1TrackSelectedEmulationInputTag); + ttTrackSelectedAssociatedToken_ = consumes(L1TrackSelectedAssociatedInputTag); + ttTrackSelectedAssociatedEmulationToken_ = + consumes(L1TrackSelectedAssociatedEmulationInputTag); + ttTrackSelectedForJetsToken_ = consumes(L1TrackSelectedForJetsInputTag); + ttTrackSelectedEmulationForJetsToken_ = consumes(L1TrackSelectedEmulationForJetsInputTag); + ttTrackSelectedAssociatedForJetsToken_ = consumes(L1TrackSelectedAssociatedForJetsInputTag); + ttTrackSelectedAssociatedEmulationForJetsToken_ = + consumes(L1TrackSelectedAssociatedEmulationForJetsInputTag); + ttTrackSelectedForEtMissToken_ = consumes(L1TrackSelectedForEtMissInputTag); + ttTrackSelectedEmulationForEtMissToken_ = consumes(L1TrackSelectedEmulationForEtMissInputTag); + ttTrackSelectedAssociatedForEtMissToken_ = + consumes(L1TrackSelectedAssociatedForEtMissInputTag); + ttTrackSelectedAssociatedEmulationForEtMissToken_ = + consumes(L1TrackSelectedAssociatedEmulationForEtMissInputTag); TrackFastJetsToken_ = consumes>(TrackFastJetsInputTag); TrackJetsToken_ = consumes(TrackJetsInputTag); TrackJetsEmuToken_ = consumes(TrackJetsEmuInputTag); @@ -527,6 +618,26 @@ L1TrackObjectNtupleMaker::L1TrackObjectNtupleMaker(edm::ParameterSet const& iCon L1TrackExtendedSelectedInputTag = iConfig.getParameter("L1TrackExtendedSelectedInputTag"); L1TrackExtendedSelectedEmulationInputTag = iConfig.getParameter("L1TrackExtendedSelectedEmulationInputTag"); + L1TrackExtendedSelectedAssociatedInputTag = + iConfig.getParameter("L1TrackExtendedSelectedAssociatedInputTag"); + L1TrackExtendedSelectedAssociatedEmulationInputTag = + iConfig.getParameter("L1TrackExtendedSelectedAssociatedEmulationInputTag"); + L1TrackExtendedSelectedForJetsInputTag = + iConfig.getParameter("L1TrackExtendedSelectedForJetsInputTag"); + L1TrackExtendedSelectedEmulationForJetsInputTag = + iConfig.getParameter("L1TrackExtendedSelectedEmulationForJetsInputTag"); + L1TrackExtendedSelectedAssociatedForJetsInputTag = + iConfig.getParameter("L1TrackExtendedSelectedAssociatedForJetsInputTag"); + L1TrackExtendedSelectedAssociatedEmulationForJetsInputTag = + iConfig.getParameter("L1TrackExtendedSelectedAssociatedEmulationForJetsInputTag"); + L1TrackExtendedSelectedForEtMissInputTag = + iConfig.getParameter("L1TrackExtendedSelectedForEtMissInputTag"); + L1TrackExtendedSelectedEmulationForEtMissInputTag = + iConfig.getParameter("L1TrackExtendedSelectedEmulationForEtMissInputTag"); + L1TrackExtendedSelectedAssociatedForEtMissInputTag = + iConfig.getParameter("L1TrackExtendedSelectedAssociatedForEtMissInputTag"); + L1TrackExtendedSelectedAssociatedEmulationForEtMissInputTag = + iConfig.getParameter("L1TrackExtendedSelectedAssociatedEmulationForEtMissInputTag"); TrackFastJetsExtendedInputTag = iConfig.getParameter("TrackFastJetsExtendedInputTag"); TrackJetsExtendedInputTag = iConfig.getParameter("TrackJetsExtendedInputTag"); TrackJetsExtendedEmuInputTag = iConfig.getParameter("TrackJetsExtendedEmuInputTag"); @@ -541,6 +652,23 @@ L1TrackObjectNtupleMaker::L1TrackObjectNtupleMaker(edm::ParameterSet const& iCon ttTrackExtendedGTTToken_ = consumes(L1TrackExtendedGTTInputTag); ttTrackExtendedSelectedToken_ = consumes(L1TrackExtendedSelectedInputTag); ttTrackExtendedSelectedEmulationToken_ = consumes(L1TrackExtendedSelectedEmulationInputTag); + ttTrackExtendedSelectedAssociatedToken_ = consumes(L1TrackExtendedSelectedAssociatedInputTag); + ttTrackExtendedSelectedAssociatedEmulationToken_ = + consumes(L1TrackExtendedSelectedAssociatedEmulationInputTag); + ttTrackExtendedSelectedForJetsToken_ = consumes(L1TrackExtendedSelectedForJetsInputTag); + ttTrackExtendedSelectedEmulationForJetsToken_ = + consumes(L1TrackExtendedSelectedEmulationForJetsInputTag); + ttTrackExtendedSelectedAssociatedForJetsToken_ = + consumes(L1TrackExtendedSelectedAssociatedForJetsInputTag); + ttTrackExtendedSelectedAssociatedEmulationForJetsToken_ = + consumes(L1TrackExtendedSelectedAssociatedEmulationForJetsInputTag); + ttTrackExtendedSelectedForEtMissToken_ = consumes(L1TrackExtendedSelectedForEtMissInputTag); + ttTrackExtendedSelectedEmulationForEtMissToken_ = + consumes(L1TrackExtendedSelectedEmulationForEtMissInputTag); + ttTrackExtendedSelectedAssociatedForEtMissToken_ = + consumes(L1TrackExtendedSelectedAssociatedForEtMissInputTag); + ttTrackExtendedSelectedAssociatedEmulationForEtMissToken_ = + consumes(L1TrackExtendedSelectedAssociatedEmulationForEtMissInputTag); TrackFastJetsExtendedToken_ = consumes>(TrackFastJetsExtendedInputTag); TrackJetsExtendedToken_ = consumes(TrackJetsExtendedInputTag); TrackJetsExtendedEmuToken_ = consumes(TrackJetsExtendedEmuInputTag); @@ -574,6 +702,226 @@ L1TrackObjectNtupleMaker::~L1TrackObjectNtupleMaker() {} void L1TrackObjectNtupleMaker::endJob() { // things to be done at the exit of the event Loop // edm::LogVerbatim("Tracklet") << "L1TrackObjectNtupleMaker::endJob"; + // clean up raw pointers + delete m_trk_pt; + delete m_trk_eta; + delete m_trk_phi; + delete m_trk_phi_local; + delete m_trk_z0; + delete m_trk_d0; + delete m_trk_chi2; + delete m_trk_chi2dof; + delete m_trk_chi2rphi; + delete m_trk_chi2rz; + delete m_trk_bendchi2; + delete m_trk_MVA1; + delete m_trk_nstub; + delete m_trk_lhits; + delete m_trk_dhits; + delete m_trk_seed; + delete m_trk_hitpattern; + delete m_trk_phiSector; + delete m_trk_genuine; + delete m_trk_loose; + delete m_trk_unknown; + delete m_trk_combinatoric; + delete m_trk_fake; + delete m_trk_matchtp_pdgid; + delete m_trk_matchtp_pt; + delete m_trk_matchtp_eta; + delete m_trk_matchtp_phi; + delete m_trk_matchtp_z0; + delete m_trk_matchtp_dxy; + delete m_trk_gtt_pt; + delete m_trk_gtt_eta; + delete m_trk_gtt_phi; + delete m_trk_selected_index; + delete m_trk_selected_emulation_index; + delete m_trk_selected_associated_index; + delete m_trk_selected_associated_emulation_index; + delete m_trk_selected_forjets_index; + delete m_trk_selected_emulation_forjets_index; + delete m_trk_selected_associated_forjets_index; + delete m_trk_selected_associated_emulation_forjets_index; + delete m_trk_selected_foretmiss_index; + delete m_trk_selected_emulation_foretmiss_index; + delete m_trk_selected_associated_foretmiss_index; + delete m_trk_selected_associated_emulation_foretmiss_index; + + delete m_trkExt_pt; + delete m_trkExt_eta; + delete m_trkExt_phi; + delete m_trkExt_phi_local; + delete m_trkExt_z0; + delete m_trkExt_d0; + delete m_trkExt_chi2; + delete m_trkExt_chi2dof; + delete m_trkExt_chi2rphi; + delete m_trkExt_chi2rz; + delete m_trkExt_bendchi2; + delete m_trkExt_MVA; + delete m_trkExt_nstub; + delete m_trkExt_lhits; + delete m_trkExt_dhits; + delete m_trkExt_seed; + delete m_trkExt_hitpattern; + delete m_trkExt_phiSector; + delete m_trkExt_genuine; + delete m_trkExt_loose; + delete m_trkExt_unknown; + delete m_trkExt_combinatoric; + delete m_trkExt_fake; + delete m_trkExt_matchtp_pdgid; + delete m_trkExt_matchtp_pt; + delete m_trkExt_matchtp_eta; + delete m_trkExt_matchtp_phi; + delete m_trkExt_matchtp_z0; + delete m_trkExt_matchtp_dxy; + delete m_trkExt_gtt_pt; + delete m_trkExt_gtt_eta; + delete m_trkExt_gtt_phi; + delete m_trkExt_selected_index; + delete m_trkExt_selected_emulation_index; + delete m_trkExt_selected_associated_index; + delete m_trkExt_selected_associated_emulation_index; + delete m_trkExt_selected_forjets_index; + delete m_trkExt_selected_emulation_forjets_index; + delete m_trkExt_selected_associated_forjets_index; + delete m_trkExt_selected_associated_emulation_forjets_index; + delete m_trkExt_selected_foretmiss_index; + delete m_trkExt_selected_emulation_foretmiss_index; + delete m_trkExt_selected_associated_foretmiss_index; + delete m_trkExt_selected_associated_emulation_foretmiss_index; + + delete m_tp_pt; + delete m_tp_eta; + delete m_tp_phi; + delete m_tp_dxy; + delete m_tp_d0; + delete m_tp_z0; + delete m_tp_d0_prod; + delete m_tp_z0_prod; + delete m_tp_pdgid; + delete m_tp_nmatch; + delete m_tp_nstub; + delete m_tp_eventid; + delete m_tp_charge; + + delete m_gen_pt; + delete m_gen_phi; + delete m_gen_pdgid; + delete m_gen_z0; + + delete m_matchtrk_pt; + delete m_matchtrk_eta; + delete m_matchtrk_phi; + delete m_matchtrk_z0; + delete m_matchtrk_d0; + delete m_matchtrk_chi2; + delete m_matchtrk_chi2dof; + delete m_matchtrk_chi2rphi; + delete m_matchtrk_chi2rz; + delete m_matchtrk_bendchi2; + delete m_matchtrk_MVA1; + delete m_matchtrk_nstub; + delete m_matchtrk_dhits; + delete m_matchtrk_lhits; + delete m_matchtrk_seed; + delete m_matchtrk_hitpattern; + + delete m_matchtrkExt_pt; + delete m_matchtrkExt_eta; + delete m_matchtrkExt_phi; + delete m_matchtrkExt_z0; + delete m_matchtrkExt_d0; + delete m_matchtrkExt_chi2; + delete m_matchtrkExt_chi2dof; + delete m_matchtrkExt_chi2rphi; + delete m_matchtrkExt_chi2rz; + delete m_matchtrkExt_bendchi2; + delete m_matchtrkExt_MVA; + delete m_matchtrkExt_nstub; + delete m_matchtrkExt_dhits; + delete m_matchtrkExt_lhits; + delete m_matchtrkExt_seed; + delete m_matchtrkExt_hitpattern; + + delete m_allstub_x; + delete m_allstub_y; + delete m_allstub_z; + delete m_allstub_isBarrel; + delete m_allstub_layer; + delete m_allstub_isPSmodule; + delete m_allstub_trigDisplace; + delete m_allstub_trigOffset; + delete m_allstub_trigPos; + delete m_allstub_trigBend; + delete m_allstub_matchTP_pdgid; + delete m_allstub_matchTP_pt; + delete m_allstub_matchTP_eta; + delete m_allstub_matchTP_phi; + delete m_allstub_genuine; + + delete m_pv_L1reco; + delete m_pv_L1reco_sum; + delete m_pv_L1reco_emu; + delete m_pv_L1reco_sum_emu; + delete m_pv_MC; + delete m_MC_lep; + + delete m_trkjet_eta; + delete m_trkjet_vz; + delete m_trkjet_phi; + delete m_trkjet_p; + delete m_trkjet_pt; + delete m_trkjet_ntracks; + delete m_trkjet_nDisplaced; + delete m_trkjet_nTight; + delete m_trkjet_nTightDisplaced; + delete m_trkjet_ntdtrk; + + delete m_trkjetem_pt; + delete m_trkjetem_phi; + delete m_trkjetem_eta; + delete m_trkjetem_z; + delete m_trkjetem_ntracks; + delete m_trkjetem_nxtracks; + + delete m_trkfastjet_eta; + delete m_trkfastjet_vz; + delete m_trkfastjet_phi; + delete m_trkfastjet_p; + delete m_trkfastjet_pt; + delete m_trkfastjet_ntracks; + delete m_trkfastjet_tp_sumpt; + delete m_trkfastjet_truetp_sumpt; + + delete m_trkjetExt_eta; + delete m_trkjetExt_vz; + delete m_trkjetExt_phi; + delete m_trkjetExt_p; + delete m_trkjetExt_pt; + delete m_trkjetExt_ntracks; + delete m_trkjetExt_nDisplaced; + delete m_trkjetExt_nTight; + delete m_trkjetExt_nTightDisplaced; + delete m_trkjetExt_ntdtrk; + + delete m_trkjetemExt_pt; + delete m_trkjetemExt_phi; + delete m_trkjetemExt_eta; + delete m_trkjetemExt_z; + delete m_trkjetemExt_ntracks; + delete m_trkjetemExt_nxtracks; + + delete m_trkfastjetExt_eta; + delete m_trkfastjetExt_vz; + delete m_trkfastjetExt_phi; + delete m_trkfastjetExt_p; + delete m_trkfastjetExt_pt; + delete m_trkfastjetExt_ntracks; + delete m_trkfastjetExt_tp_sumpt; + delete m_trkfastjetExt_truetp_sumpt; } //////////// @@ -624,6 +972,16 @@ void L1TrackObjectNtupleMaker::beginJob() { m_trk_gtt_phi = new std::vector; m_trk_selected_index = new std::vector; m_trk_selected_emulation_index = new std::vector; + m_trk_selected_associated_index = new std::vector; + m_trk_selected_associated_emulation_index = new std::vector; + m_trk_selected_forjets_index = new std::vector; + m_trk_selected_emulation_forjets_index = new std::vector; + m_trk_selected_associated_forjets_index = new std::vector; + m_trk_selected_associated_emulation_forjets_index = new std::vector; + m_trk_selected_foretmiss_index = new std::vector; + m_trk_selected_emulation_foretmiss_index = new std::vector; + m_trk_selected_associated_foretmiss_index = new std::vector; + m_trk_selected_associated_emulation_foretmiss_index = new std::vector; m_trkExt_pt = new std::vector; m_trkExt_eta = new std::vector; @@ -659,6 +1017,16 @@ void L1TrackObjectNtupleMaker::beginJob() { m_trkExt_gtt_phi = new std::vector; m_trkExt_selected_index = new std::vector; m_trkExt_selected_emulation_index = new std::vector; + m_trkExt_selected_associated_index = new std::vector; + m_trkExt_selected_associated_emulation_index = new std::vector; + m_trkExt_selected_forjets_index = new std::vector; + m_trkExt_selected_emulation_forjets_index = new std::vector; + m_trkExt_selected_associated_forjets_index = new std::vector; + m_trkExt_selected_associated_emulation_forjets_index = new std::vector; + m_trkExt_selected_foretmiss_index = new std::vector; + m_trkExt_selected_emulation_foretmiss_index = new std::vector; + m_trkExt_selected_associated_foretmiss_index = new std::vector; + m_trkExt_selected_associated_emulation_foretmiss_index = new std::vector; m_tp_pt = new std::vector; m_tp_eta = new std::vector; @@ -827,6 +1195,18 @@ void L1TrackObjectNtupleMaker::beginJob() { eventTree->Branch("trk_gtt_phi", &m_trk_gtt_phi); eventTree->Branch("trk_gtt_selected_index", &m_trk_selected_index); eventTree->Branch("trk_gtt_selected_emulation_index", &m_trk_selected_emulation_index); + eventTree->Branch("trk_gtt_selected_associated_index", &m_trk_selected_associated_index); + eventTree->Branch("trk_gtt_selected_associated_emulation_index", &m_trk_selected_associated_emulation_index); + eventTree->Branch("trk_gtt_selected_forjets_index", &m_trk_selected_forjets_index); + eventTree->Branch("trk_gtt_selected_emulation_forjets_index", &m_trk_selected_emulation_forjets_index); + eventTree->Branch("trk_gtt_selected_associated_forjets_index", &m_trk_selected_associated_forjets_index); + eventTree->Branch("trk_gtt_selected_associated_emulation_forjets_index", + &m_trk_selected_associated_emulation_forjets_index); + eventTree->Branch("trk_gtt_selected_foretmiss_index", &m_trk_selected_foretmiss_index); + eventTree->Branch("trk_gtt_selected_emulation_foretmiss_index", &m_trk_selected_emulation_foretmiss_index); + eventTree->Branch("trk_gtt_selected_associated_foretmiss_index", &m_trk_selected_associated_foretmiss_index); + eventTree->Branch("trk_gtt_selected_associated_emulation_foretmiss_index", + &m_trk_selected_associated_emulation_foretmiss_index); } if (SaveAllTracks && (Displaced == "Displaced" || Displaced == "Both")) { @@ -864,6 +1244,18 @@ void L1TrackObjectNtupleMaker::beginJob() { eventTree->Branch("trkExt_gtt_phi", &m_trkExt_gtt_phi); eventTree->Branch("trkExt_gtt_selected_index", &m_trkExt_selected_index); eventTree->Branch("trkExt_gtt_selected_emulation_index", &m_trkExt_selected_emulation_index); + eventTree->Branch("trkExt_gtt_selected_associated_index", &m_trkExt_selected_associated_index); + eventTree->Branch("trkExt_gtt_selected_associated_emulation_index", &m_trkExt_selected_associated_emulation_index); + eventTree->Branch("trkExt_gtt_selected_forjets_index", &m_trkExt_selected_forjets_index); + eventTree->Branch("trkExt_gtt_selected_emulation_forjets_index", &m_trkExt_selected_emulation_forjets_index); + eventTree->Branch("trkExt_gtt_selected_associated_forjets_index", &m_trkExt_selected_associated_forjets_index); + eventTree->Branch("trkExt_gtt_selected_associated_emulation_forjets_index", + &m_trkExt_selected_associated_emulation_forjets_index); + eventTree->Branch("trkExt_gtt_selected_foretmiss_index", &m_trkExt_selected_foretmiss_index); + eventTree->Branch("trkExt_gtt_selected_emulation_foretmiss_index", &m_trkExt_selected_emulation_foretmiss_index); + eventTree->Branch("trkExt_gtt_selected_associated_foretmiss_index", &m_trkExt_selected_associated_foretmiss_index); + eventTree->Branch("trkExt_gtt_selected_associated_emulation_foretmiss_index", + &m_trkExt_selected_associated_emulation_foretmiss_index); } eventTree->Branch("tp_pt", &m_tp_pt); eventTree->Branch("tp_eta", &m_tp_eta); @@ -1076,6 +1468,16 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trk_gtt_phi->clear(); m_trk_selected_index->clear(); m_trk_selected_emulation_index->clear(); + m_trk_selected_associated_index->clear(); + m_trk_selected_associated_emulation_index->clear(); + m_trk_selected_forjets_index->clear(); + m_trk_selected_emulation_forjets_index->clear(); + m_trk_selected_associated_forjets_index->clear(); + m_trk_selected_associated_emulation_forjets_index->clear(); + m_trk_selected_foretmiss_index->clear(); + m_trk_selected_emulation_foretmiss_index->clear(); + m_trk_selected_associated_foretmiss_index->clear(); + m_trk_selected_associated_emulation_foretmiss_index->clear(); } if (SaveAllTracks && (Displaced == "Displaced" || Displaced == "Both")) { m_trkExt_pt->clear(); @@ -1112,6 +1514,16 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trkExt_gtt_phi->clear(); m_trkExt_selected_index->clear(); m_trkExt_selected_emulation_index->clear(); + m_trkExt_selected_associated_index->clear(); + m_trkExt_selected_associated_emulation_index->clear(); + m_trkExt_selected_forjets_index->clear(); + m_trkExt_selected_emulation_forjets_index->clear(); + m_trkExt_selected_associated_forjets_index->clear(); + m_trkExt_selected_associated_emulation_forjets_index->clear(); + m_trkExt_selected_foretmiss_index->clear(); + m_trkExt_selected_emulation_foretmiss_index->clear(); + m_trkExt_selected_associated_foretmiss_index->clear(); + m_trkExt_selected_associated_emulation_foretmiss_index->clear(); } m_tp_pt->clear(); m_tp_eta->clear(); @@ -1317,8 +1729,28 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even edm::Handle TTTrackExtendedGTTHandle; edm::Handle TTTrackSelectedHandle; edm::Handle TTTrackSelectedEmulationHandle; + edm::Handle TTTrackSelectedAssociatedHandle; + edm::Handle TTTrackSelectedAssociatedEmulationHandle; + edm::Handle TTTrackSelectedForJetsHandle; + edm::Handle TTTrackSelectedEmulationForJetsHandle; + edm::Handle TTTrackSelectedAssociatedForJetsHandle; + edm::Handle TTTrackSelectedAssociatedEmulationForJetsHandle; + edm::Handle TTTrackSelectedForEtMissHandle; + edm::Handle TTTrackSelectedEmulationForEtMissHandle; + edm::Handle TTTrackSelectedAssociatedForEtMissHandle; + edm::Handle TTTrackSelectedAssociatedEmulationForEtMissHandle; + edm::Handle TTTrackExtendedSelectedAssociatedHandle; + edm::Handle TTTrackExtendedSelectedAssociatedEmulationHandle; edm::Handle TTTrackExtendedSelectedHandle; edm::Handle TTTrackExtendedSelectedEmulationHandle; + edm::Handle TTTrackExtendedSelectedAssociatedForJetsHandle; + edm::Handle TTTrackExtendedSelectedAssociatedEmulationForJetsHandle; + edm::Handle TTTrackExtendedSelectedForJetsHandle; + edm::Handle TTTrackExtendedSelectedEmulationForJetsHandle; + edm::Handle TTTrackExtendedSelectedAssociatedForEtMissHandle; + edm::Handle TTTrackExtendedSelectedAssociatedEmulationForEtMissHandle; + edm::Handle TTTrackExtendedSelectedForEtMissHandle; + edm::Handle TTTrackExtendedSelectedEmulationForEtMissHandle; L1TrackCollection::const_iterator iterL1Track; if (Displaced == "Prompt" || Displaced == "Both") { @@ -1334,6 +1766,17 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even iEvent.getByToken(ttTrackGTTToken_, TTTrackGTTHandle); iEvent.getByToken(ttTrackSelectedToken_, TTTrackSelectedHandle); iEvent.getByToken(ttTrackSelectedEmulationToken_, TTTrackSelectedEmulationHandle); + iEvent.getByToken(ttTrackSelectedAssociatedToken_, TTTrackSelectedAssociatedHandle); + iEvent.getByToken(ttTrackSelectedAssociatedEmulationToken_, TTTrackSelectedAssociatedEmulationHandle); + iEvent.getByToken(ttTrackSelectedForJetsToken_, TTTrackSelectedForJetsHandle); + iEvent.getByToken(ttTrackSelectedEmulationForJetsToken_, TTTrackSelectedEmulationForJetsHandle); + iEvent.getByToken(ttTrackSelectedAssociatedForJetsToken_, TTTrackSelectedAssociatedForJetsHandle); + iEvent.getByToken(ttTrackSelectedAssociatedEmulationForJetsToken_, TTTrackSelectedAssociatedEmulationForJetsHandle); + iEvent.getByToken(ttTrackSelectedForEtMissToken_, TTTrackSelectedForEtMissHandle); + iEvent.getByToken(ttTrackSelectedEmulationForEtMissToken_, TTTrackSelectedEmulationForEtMissHandle); + iEvent.getByToken(ttTrackSelectedAssociatedForEtMissToken_, TTTrackSelectedAssociatedForEtMissHandle); + iEvent.getByToken(ttTrackSelectedAssociatedEmulationForEtMissToken_, + TTTrackSelectedAssociatedEmulationForEtMissHandle); } if (Displaced == "Displaced" || Displaced == "Both") { iEvent.getByToken(TrackFastJetsExtendedToken_, TrackFastJetsExtendedHandle); @@ -1347,6 +1790,20 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even iEvent.getByToken(ttTrackExtendedGTTToken_, TTTrackExtendedGTTHandle); iEvent.getByToken(ttTrackExtendedSelectedToken_, TTTrackExtendedSelectedHandle); iEvent.getByToken(ttTrackExtendedSelectedEmulationToken_, TTTrackExtendedSelectedEmulationHandle); + iEvent.getByToken(ttTrackExtendedSelectedAssociatedToken_, TTTrackExtendedSelectedAssociatedHandle); + iEvent.getByToken(ttTrackExtendedSelectedAssociatedEmulationToken_, + TTTrackExtendedSelectedAssociatedEmulationHandle); + iEvent.getByToken(ttTrackExtendedSelectedForJetsToken_, TTTrackExtendedSelectedForJetsHandle); + iEvent.getByToken(ttTrackExtendedSelectedEmulationForJetsToken_, TTTrackExtendedSelectedEmulationForJetsHandle); + iEvent.getByToken(ttTrackExtendedSelectedAssociatedForJetsToken_, TTTrackExtendedSelectedAssociatedForJetsHandle); + iEvent.getByToken(ttTrackExtendedSelectedAssociatedEmulationForJetsToken_, + TTTrackExtendedSelectedAssociatedEmulationForJetsHandle); + iEvent.getByToken(ttTrackExtendedSelectedForEtMissToken_, TTTrackExtendedSelectedForEtMissHandle); + iEvent.getByToken(ttTrackExtendedSelectedEmulationForEtMissToken_, TTTrackExtendedSelectedEmulationForEtMissHandle); + iEvent.getByToken(ttTrackExtendedSelectedAssociatedForEtMissToken_, + TTTrackExtendedSelectedAssociatedForEtMissHandle); + iEvent.getByToken(ttTrackExtendedSelectedAssociatedEmulationForEtMissToken_, + TTTrackExtendedSelectedAssociatedEmulationForEtMissHandle); } //Loop over gen particles @@ -1670,6 +2127,23 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trk_gtt_phi->push_back(l1track_ref->momentum().phi()); m_trk_selected_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackSelectedHandle)); m_trk_selected_emulation_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackSelectedEmulationHandle)); + m_trk_selected_associated_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackSelectedAssociatedHandle)); + m_trk_selected_associated_emulation_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackSelectedAssociatedEmulationHandle)); + m_trk_selected_forjets_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackSelectedForJetsHandle)); + m_trk_selected_emulation_forjets_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackSelectedEmulationForJetsHandle)); + m_trk_selected_associated_forjets_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackSelectedAssociatedForJetsHandle)); + m_trk_selected_associated_emulation_forjets_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackSelectedAssociatedEmulationForJetsHandle)); + m_trk_selected_foretmiss_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackSelectedForEtMissHandle)); + m_trk_selected_emulation_foretmiss_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackSelectedEmulationForEtMissHandle)); + m_trk_selected_associated_foretmiss_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackSelectedAssociatedForEtMissHandle)); + m_trk_selected_associated_emulation_foretmiss_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackSelectedAssociatedEmulationForEtMissHandle)); } //end track loop } //end if SaveAllTracks @@ -1864,6 +2338,26 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trkExt_selected_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedHandle)); m_trkExt_selected_emulation_index->push_back( getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedEmulationHandle)); + m_trkExt_selected_associated_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedAssociatedHandle)); + m_trkExt_selected_associated_emulation_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedAssociatedEmulationHandle)); + m_trkExt_selected_forjets_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedForJetsHandle)); + m_trkExt_selected_emulation_forjets_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedEmulationForJetsHandle)); + m_trkExt_selected_associated_forjets_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedAssociatedForJetsHandle)); + m_trkExt_selected_associated_emulation_forjets_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedAssociatedEmulationForJetsHandle)); + m_trkExt_selected_foretmiss_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedForEtMissHandle)); + m_trkExt_selected_emulation_foretmiss_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedEmulationForEtMissHandle)); + m_trkExt_selected_associated_foretmiss_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedAssociatedForEtMissHandle)); + m_trkExt_selected_associated_emulation_foretmiss_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedAssociatedEmulationForEtMissHandle)); } //end track loop } //end if SaveAllTracks (displaced) diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py index f4f0ea8e8d126..e2519cb5dff7e 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py +++ b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py @@ -83,6 +83,7 @@ process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") process.load("L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.l1tTrackVertexAssociationProducer_cfi") process.load("L1Trigger.L1TTrackMatch.l1tTrackJets_cfi") process.load("L1Trigger.L1TTrackMatch.l1tGTTInputProducer_cfi") process.load("L1Trigger.L1TTrackMatch.l1tTrackJetsEmulation_cfi") @@ -97,30 +98,19 @@ ############################################################ # Primary vertex ############################################################ -process.l1tVertexFinder = process.l1tVertexProducer.clone() process.pPV = cms.Path(process.l1tVertexFinder) -process.l1tVertexFinderEmulator = process.l1tVertexProducer.clone() -process.l1tVertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" -process.l1tVertexFinderEmulator.l1TracksInputTag = cms.InputTag("l1tGTTInputProducer","Level1TTTracksConverted") -process.l1tVertexFinderEmulator.VertexReconstruction.VxMinTrackPt = cms.double(0.0) process.pPVemu = cms.Path(process.l1tVertexFinderEmulator) -process.l1tTrackFastJets.L1PrimaryVertexTag = cms.InputTag("l1tVertexFinder", "l1vertices") -process.l1tTrackFastJetsExtended.L1PrimaryVertexTag = cms.InputTag("l1tVertexFinder", "l1vertices") -process.l1tTrackJets.L1PVertexInputTag = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation") -process.l1tTrackJetsExtended.L1PVertexInputTag = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation") -process.l1tTrackerEtMiss.L1VertexInputTag = cms.InputTag("l1tVertexFinder", "l1vertices") -process.l1tTrackerHTMiss.L1VertexInputTag = cms.InputTag("l1tVertexFinder", "l1vertices") -process.l1tTrackerEtMissExtended.L1VertexInputTag = cms.InputTag("l1tVertexFinder", "l1vertices") -process.l1tTrackerHTMissExtended.L1VertexInputTag = cms.InputTag("l1tVertexFinder", "l1vertices") -process.l1tTrackerEmuEtMiss.L1VertexInputTag = cms.InputTag("l1tVertexFinderEmulator", "l1verticesEmulation") - - # HYBRID: prompt tracking if (L1TRKALGO == 'HYBRID'): process.TTTracksEmu = cms.Path(process.L1THybridTracks) process.TTTracksEmuWithTruth = cms.Path(process.L1THybridTracksWithAssociators) - process.pL1TrackSelection = cms.Path(process.l1tTrackSelectionProducer) + process.pL1TrackSelection = cms.Path(process.l1tTrackSelectionProducer * + process.l1tTrackSelectionProducerForJets * + process.l1tTrackSelectionProducerForEtMiss) + process.pL1TrackVertexAssociation = cms.Path(process.l1tTrackVertexAssociationProducer* + process.l1tTrackVertexAssociationProducerForJets* + process.l1tTrackVertexAssociationProducerForEtMiss) process.pL1TrackJets = cms.Path(process.l1tTrackJets) process.pL1TrackFastJets=cms.Path(process.l1tTrackFastJets) process.pL1GTTInput = cms.Path(process.l1tGTTInputProducer) @@ -135,7 +125,13 @@ elif (L1TRKALGO == 'HYBRID_DISPLACED'): process.TTTracksEmu = cms.Path(process.L1TExtendedHybridTracks) process.TTTracksEmuWithTruth = cms.Path(process.L1TExtendedHybridTracksWithAssociators) - process.pL1TrackSelection = cms.Path(process.l1tTrackSelectionProducerExtended) + process.pL1TrackSelection = cms.Path(process.l1tTrackSelectionProducer * + process.l1tTrackSelectionProducerExtended * + process.l1tTrackSelectionProducerExtendedForJets * + process.l1tTrackSelectionProducerExtendedForEtMiss) + process.pL1TrackVertexAssociation = cms.Path(process.l1tTrackVertexAssociationProducerExtended * + process.l1tTrackVertexAssociationProducerExtendedForJets * + process.l1tTrackVertexAssociationProducerExtendedForEtMiss) process.pL1TrackJets = cms.Path(process.l1tTrackJetsExtended) process.pL1TrackFastJets = cms.Path(process.l1tTrackFastJetsExtended) process.pL1GTTInput = cms.Path(process.l1tGTTInputProducerExtended) @@ -149,7 +145,12 @@ elif (L1TRKALGO == 'HYBRID_PROMPTANDDISP'): process.TTTracksEmu = cms.Path(process.L1TPromptExtendedHybridTracks) process.TTTracksEmuWithTruth = cms.Path(process.L1TPromptExtendedHybridTracksWithAssociators) - process.pL1TrackSelection = cms.Path(process.l1tTrackSelectionProducer*process.l1tTrackSelectionProducerExtended) + process.pL1TrackSelection = cms.Path(process.l1tTrackSelectionProducer * process.l1tTrackSelectionProducerExtended * + process.l1tTrackSelectionProducerForJets * process.l1tTrackSelectionProducerExtendedForJets * + process.l1tTrackSelectionProducerForEtMiss * process.l1tTrackSelectionProducerExtendedForEtMiss) + process.pL1TrackVertexAssociation = cms.Path(process.l1tTrackVertexAssociationProducer * process.l1tTrackVertexAssociationProducerExtended * + process.l1tTrackVertexAssociationProducerForJets * process.l1tTrackVertexAssociationProducerExtendedForJets * + process.l1tTrackVertexAssociationProducerForEtMiss * process.l1tTrackVertexAssociationProducerExtendedForEtMiss) process.pL1TrackJets = cms.Path(process.l1tTrackJets*process.l1tTrackJetsExtended) process.pL1TrackFastJets = cms.Path(process.l1tTrackFastJets*process.l1tTrackFastJetsExtended) process.pL1GTTInput = cms.Path(process.l1tGTTInputProducer*process.l1tGTTInputProducerExtended) @@ -193,8 +194,34 @@ L1TrackExtendedGTTInputTag = cms.InputTag("l1tGTTInputProducerExtended","Level1TTTracksExtendedConverted"), # TTTracks, extended, GTT converted L1TrackSelectedInputTag = cms.InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelected"), # TTTracks, prompt, selected L1TrackSelectedEmulationInputTag = cms.InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelectedEmulation"), # TTTracks, prompt, emulation, selected - L1TrackExtendedSelectedInputTag = cms.InputTag("l1tTrackSelectionProducerExtended", "Level1TTTracksExtendedSelected"), # TTTracks, extended, selected - L1TrackExtendedSelectedEmulationInputTag = cms.InputTag("l1tTrackSelectionProducerExtended", "Level1TTTracksExtendedSelectedEmulation"), # TTTracks, extended, emulation, selected + L1TrackSelectedAssociatedInputTag = cms.InputTag("l1tTrackVertexAssociationProducer", "Level1TTTracksSelectedAssociated"), # TTTracks, prompt, selected, associated + L1TrackSelectedAssociatedEmulationInputTag = cms.InputTag("l1tTrackVertexAssociationProducer", "Level1TTTracksSelectedAssociatedEmulation"), # TTTracks, prompt, emulation, selected, associated + + L1TrackSelectedForJetsInputTag = cms.InputTag("l1tTrackSelectionProducerForJets", "Level1TTTracksSelected"), # TTTracks, prompt, selected + L1TrackSelectedEmulationForJetsInputTag = cms.InputTag("l1tTrackSelectionProducerForJets", "Level1TTTracksSelectedEmulation"), # TTTracks, prompt, emulation, selected + L1TrackSelectedAssociatedForJetsInputTag = cms.InputTag("l1tTrackVertexAssociationProducerForJets", "Level1TTTracksSelectedAssociated"), # TTTracks, prompt, selected, associated + L1TrackSelectedAssociatedEmulationForJetsInputTag = cms.InputTag("l1tTrackVertexAssociationProducerForJets", "Level1TTTracksSelectedAssociatedEmulation"), # TTTracks, prompt, emulation, selected, associated + + L1TrackSelectedForEtMissInputTag = cms.InputTag("l1tTrackSelectionProducerForEtMiss", "Level1TTTracksSelected"), # TTTracks, prompt, selected + L1TrackSelectedEmulationForEtMissInputTag = cms.InputTag("l1tTrackSelectionProducerForEtMiss", "Level1TTTracksSelectedEmulation"), # TTTracks, prompt, emulation, selected + L1TrackSelectedAssociatedForEtMissInputTag = cms.InputTag("l1tTrackVertexAssociationProducerForEtMiss", "Level1TTTracksSelectedAssociated"), # TTTracks, prompt, selected, associated + L1TrackSelectedAssociatedEmulationForEtMissInputTag = cms.InputTag("l1tTrackVertexAssociationProducerForEtMiss", "Level1TTTracksSelectedAssociatedEmulation"), # TTTracks, prompt, emulation, selected, associated + + L1TrackExtendedSelectedInputTag = cms.InputTag("l1tTrackSelectionProducerExtended", "Level1TTTracksExtendedSelected"), # TTTracks, extended, selected + L1TrackExtendedSelectedEmulationInputTag = cms.InputTag("l1tTrackSelectionProducerExtended", "Level1TTTracksExtendedSelectedEmulation"), # TTTracks, extended, emulation, selected + L1TrackExtendedSelectedAssociatedInputTag = cms.InputTag("l1tTrackVertexAssociationProducerExtended", "Level1TTTracksExtendedSelectedAssociated"), # TTTracks, extended, selected, associated + L1TrackExtendedSelectedAssociatedEmulationInputTag = cms.InputTag("l1tTrackVertexAssociationProducerExtended", "Level1TTTracksExtendedSelectedAssociatedEmulation"), # TTTracks, extended, emulation, selected, associated + + L1TrackExtendedSelectedForJetsInputTag = cms.InputTag("l1tTrackSelectionProducerExtendedForJets", "Level1TTTracksExtendedSelected"), # TTTracks, extended, selected + L1TrackExtendedSelectedEmulationForJetsInputTag = cms.InputTag("l1tTrackSelectionProducerExtendedForJets", "Level1TTTracksExtendedSelectedEmulation"), # TTTracks, extended, emulation, selected + L1TrackExtendedSelectedAssociatedForJetsInputTag = cms.InputTag("l1tTrackVertexAssociationProducerExtendedForJets", "Level1TTTracksExtendedSelectedAssociated"), # TTTracks, extended, selected, associated + L1TrackExtendedSelectedAssociatedEmulationForJetsInputTag = cms.InputTag("l1tTrackVertexAssociationProducerExtendedForJets", "Level1TTTracksExtendedSelectedAssociatedEmulation"), # TTTracks, extended, emulation, selected, associated + + L1TrackExtendedSelectedForEtMissInputTag = cms.InputTag("l1tTrackSelectionProducerExtendedForEtMiss", "Level1TTTracksExtendedSelected"), # TTTracks, extended, selected + L1TrackExtendedSelectedEmulationForEtMissInputTag = cms.InputTag("l1tTrackSelectionProducerExtendedForEtMiss", "Level1TTTracksExtendedSelectedEmulation"), # TTTracks, extended, emulation, selected + L1TrackExtendedSelectedAssociatedForEtMissInputTag = cms.InputTag("l1tTrackVertexAssociationProducerExtendedForEtMiss", "Level1TTTracksExtendedSelectedAssociated"), # TTTracks, extended, selected, associated + L1TrackExtendedSelectedAssociatedEmulationForEtMissInputTag = cms.InputTag("l1tTrackVertexAssociationProducerExtendedForEtMiss", "Level1TTTracksExtendedSelectedAssociatedEmulation"), # TTTracks, extended, emulation, selected, associated + L1StubInputTag = cms.InputTag("TTStubsFromPhase2TrackerDigis","StubAccepted"), MCTruthClusterInputTag = cms.InputTag("TTClusterAssociatorFromPixelDigis", "ClusterAccepted"), MCTruthStubInputTag = cms.InputTag("TTStubAssociatorFromPixelDigis", "StubAccepted"), @@ -213,13 +240,13 @@ TrackMETInputTag = cms.InputTag("l1tTrackerEtMiss","L1TrackerEtMiss"), TrackMETExtendedInputTag = cms.InputTag("l1tTrackerEtMissExtended","L1TrackerExtendedEtMiss"), TrackMETEmuInputTag = cms.InputTag("l1tTrackerEmuEtMiss","L1TrackerEmuEtMiss"), - TrackMHTInputTag = cms.InputTag("L1TrackerHTMiss","L1TrackerHTMiss"), #includes HT + TrackMHTInputTag = cms.InputTag("l1tTrackerHTMiss","L1TrackerHTMiss"), #includes HT TrackMHTExtendedInputTag = cms.InputTag("l1tTrackerHTMissExtended","L1TrackerHTMissExtended"), TrackMHTEmuInputTag = cms.InputTag("l1tTrackerEmuHTMiss",process.l1tTrackerEmuHTMiss.L1MHTCollectionName.value()), TrackMHTEmuExtendedInputTag = cms.InputTag("l1tTrackerEmuHTMissExtended",process.l1tTrackerEmuHTMissExtended.L1MHTCollectionName.value()), GenParticleInputTag = cms.InputTag("genParticles",""), - RecoVertexInputTag=cms.InputTag("l1tVertexFinder", "l1vertices"), - RecoVertexEmuInputTag=cms.InputTag("l1tVertexFinderEmulator", "l1verticesEmulation"), + RecoVertexInputTag=cms.InputTag("l1tVertexFinder", "L1Vertices"), + RecoVertexEmuInputTag=cms.InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation"), ) process.ntuple = cms.Path(process.L1TrackNtuple) @@ -238,7 +265,4 @@ # use this if cluster/stub associators not available # process.schedule = cms.Schedule(process.TTClusterStubTruth,process.TTTracksEmuWithTruth,process.ntuple) -process.schedule = cms.Schedule(process.TTClusterStub, process.TTClusterStubTruth, process.dtc, process.TTTracksEmuWithTruth, process.pL1GTTInput, process.pPV, process.pPVemu, process.pL1TrackSelection, process.pL1TrackJets, process.pL1TrackJetsEmu,process.pL1TrackFastJets, process.pTkMET, process.pTkMETEmu, process.pTkMHT, process.pTkMHTEmulator, process.ntuple) - - - +process.schedule = cms.Schedule(process.TTClusterStub, process.TTClusterStubTruth, process.dtc, process.TTTracksEmuWithTruth, process.pL1GTTInput, process.pL1TrackSelection, process.pPV, process.pPVemu,process.pL1TrackVertexAssociation, process.pL1TrackJets, process.pL1TrackJetsEmu,process.pL1TrackFastJets, process.pTkMET, process.pTkMETEmu, process.pTkMHT, process.pTkMHTEmulator, process.ntuple) diff --git a/L1Trigger/Phase2L1GMT/plugins/Isolation.h b/L1Trigger/Phase2L1GMT/plugins/Isolation.h index d5aa0ee635d7f..20f46e6b79ea0 100644 --- a/L1Trigger/Phase2L1GMT/plugins/Isolation.h +++ b/L1Trigger/Phase2L1GMT/plugins/Isolation.h @@ -65,7 +65,6 @@ namespace Phase2L1GMT { reliso_thrT(iConfig.getParameter("RelIsoThresholdT")), verbose_(iConfig.getParameter("verbose")), dumpForHLS_(iConfig.getParameter("IsodumpForHLS")) { - dumpForHLS_ = true; if (dumpForHLS_) { dumpInput.open("Isolation_Mu_Track_infolist.txt", std::ofstream::out); dumpOutput.open("Isolation_Mu_Isolation.txt", std::ofstream::out); diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTFilter.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTFilter.cc new file mode 100644 index 0000000000000..88f2557788058 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTFilter.cc @@ -0,0 +1,104 @@ +#include +#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/L1TMuonPhase2/interface/TrackerMuon.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" +#include "Node.h" + +// +// class declaration +// +using namespace Phase2L1GMT; +using namespace l1t; + +class Phase2L1TGMTFilter : public edm::stream::EDProducer<> { +public: + explicit Phase2L1TGMTFilter(const edm::ParameterSet&); + ~Phase2L1TGMTFilter() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void beginStream(edm::StreamID) override; + void produce(edm::Event&, const edm::EventSetup&) override; + void endStream() override; + edm::EDGetTokenT > srcMuons_; + bool applyLowPtFilter_; + int ptBarrelMin_; + int ptEndcapMin_; + double etaBE_; +}; + +Phase2L1TGMTFilter::Phase2L1TGMTFilter(const edm::ParameterSet& iConfig) + : srcMuons_(consumes >(iConfig.getParameter("srcMuons"))), + applyLowPtFilter_(iConfig.getParameter("applyLowPtFilter")), + ptBarrelMin_(iConfig.getParameter("ptBarrelMin")), + ptEndcapMin_(iConfig.getParameter("ptEndcapMin")), + etaBE_(iConfig.getParameter("etaBE")) { + produces >("l1tTkMuonsGmtLowPtFix").setBranchAlias("tkMuLowPtFix"); +} + +Phase2L1TGMTFilter::~Phase2L1TGMTFilter() { + // do anything here that needs to be done at destruction time + // (e.g. close files, deallocate resources etc.) +} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void Phase2L1TGMTFilter::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + Handle > muonHandle; + iEvent.getByToken(srcMuons_, muonHandle); + + std::vector out; + + for (uint i = 0; i < muonHandle->size(); ++i) { + auto mu = muonHandle->at(i); + bool noSAMatch = true; + if (applyLowPtFilter_) { + if ((fabs(mu.phEta()) < etaBE_ && mu.phPt() < ptBarrelMin_) || + (fabs(mu.phEta()) > etaBE_ && mu.phPt() < ptEndcapMin_)) { + // if quality is already set to 0 don't continue the loop. + for (const auto& r : mu.muonRef()) { + if (r.isNonnull()) { + noSAMatch = false; + break; + } + } + if (noSAMatch) + mu.setHwQual(0); + } + } + out.push_back(mu); // store all muons otherwise + } + + // store results + std::unique_ptr > out1 = std::make_unique >(out); + iEvent.put(std::move(out1)); +} + +// ------------ method called once each stream before processing any runs, lumis or events ------------ +void Phase2L1TGMTFilter::beginStream(edm::StreamID) {} + +// ------------ method called once each stream after processing all runs, lumis and events ------------ +void Phase2L1TGMTFilter::endStream() {} + +void Phase2L1TGMTFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(Phase2L1TGMTFilter); diff --git a/L1Trigger/Phase2L1GMT/python/gmt_cfi.py b/L1Trigger/Phase2L1GMT/python/gmt_cfi.py index e5d24cf7bd955..af95f691ec255 100644 --- a/L1Trigger/Phase2L1GMT/python/gmt_cfi.py +++ b/L1Trigger/Phase2L1GMT/python/gmt_cfi.py @@ -76,6 +76,17 @@ ) + +l1tGMTFilteredMuons = cms.EDProducer('Phase2L1TGMTFilter', + srcMuons = cms.InputTag("l1tTkMuonsGmt",""), + applyLowPtFilter = cms.bool(True), + ptBarrelMin = cms.int32(8), + ptEndcapMin = cms.int32(8), + etaBE = cms.double(0.9) + +) + + l1tStandaloneMuons = cms.EDProducer('Phase2L1TGMTSAMuonProducer', muonToken = cms.InputTag('simGmtStage2Digis'), Nprompt = cms.uint32(12), diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h index 15004caa2f803..dc786b910eecd 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h @@ -19,17 +19,18 @@ class L1TCorrelatorLayer1PatternFileWriter { enum class Partition { Barrel, HGCal, HGCalNoTk, HF }; Partition partition_; - const unsigned int tmuxFactor_ = 6; // not really configurable in current architecture + const unsigned int tmuxFactor_; bool writeInputs_, writeOutputs_; std::map> channelIdsInput_, channelIdsOutput_; std::map channelSpecsInput_, channelSpecsOutput_; - const unsigned int tfTimeslices_ = 3, tfLinksFactor_ = 1; // not really configurable in current architecture - const unsigned int hgcTimeslices_ = 3, hgcLinksFactor_ = 4; // not really configurable in current architecture - const unsigned int gctTimeslices_ = 1, gctSectors_ = 3; // not really configurable in current architecture - const unsigned int gctLinksEcal_ = 1, gctLinksHad_ = 2; // could be made configurable later - const unsigned int gmtTimeslices_ = 3, gmtLinksFactor_ = 1; // not really configurable in current architecture - const unsigned int gttTimeslices_ = 1, gttLinksFactor_ = 1; // not really configurable in current architecture + const unsigned int tfTmuxFactor_ = 18, tfLinksFactor_ = 1; // numbers not really configurable in current architecture + const unsigned int hgcTmuxFactor_ = 18, hgcLinksFactor_ = 4; // not really configurable in current architecture + const unsigned int gctTmuxFactor_ = 1, gctSectors_ = 3; // not really configurable in current architecture + const unsigned int gctLinksEcal_ = 1, gctLinksHad_ = 2; // could be made configurable later + const unsigned int gmtTmuxFactor_ = 18, gmtLinksFactor_ = 1; // not really configurable in current architecture + const unsigned int gttTmuxFactor_ = 6, gttLinksFactor_ = 1; // not really configurable in current architecture + const unsigned int tfTimeslices_, hgcTimeslices_, gctTimeslices_, gmtTimeslices_, gttTimeslices_; uint32_t gmtNumberOfMuons_; uint32_t gttNumberOfPVs_; uint32_t gttLatency_; @@ -70,6 +71,7 @@ class L1TCorrelatorLayer1PatternFileWriter { void writeGMT(const l1ct::Event& event, l1t::demo::EventData& out); void writeGTT(const l1ct::Event& event, l1t::demo::EventData& out); void writePuppi(const l1ct::Event& event, l1t::demo::EventData& out); + void writeEgamma(const l1ct::OutputBoard& egboard, std::vector>& out); void writeEgamma(const l1ct::Event& event, l1t::demo::EventData& out); }; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h index 5b54130f93b0c..596838f963715 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h @@ -52,6 +52,8 @@ namespace l1ct { unsigned int outii, unsigned int pauseii, bool useAlsoVtxCoords); + // note: this one will work only in CMSSW + BufferedFoldedMultififoRegionizerEmulator(const edm::ParameterSet& iConfig); ~BufferedFoldedMultififoRegionizerEmulator() override; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h index c906a502c5caa..c62dd73eb49e1 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h @@ -2,6 +2,7 @@ #define multififo_regionizer_ref_h #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pfeginput_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.h" #include diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1BJetPFJetProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1BJetPFJetProducer.cc index db4bda78a6884..553ddd655cc21 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1BJetPFJetProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1BJetPFJetProducer.cc @@ -111,7 +111,7 @@ void L1BJetProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptio desc.add("nParticles", 10); desc.add("minPt", 20); desc.add("maxEta", 2.4); - desc.add("vtx", edm::InputTag("L1VertexFinderEmulator", "l1verticesEmulation")); + desc.add("vtx", edm::InputTag("L1VertexFinderEmulator", "L1VerticesEmulation")); descriptions.add("L1BJetProducer", desc); } L1BJetProducer::~L1BJetProducer() {} diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1CTJetFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1CTJetFileWriter.cc index f3d21a7c85e1f..82957e57178e1 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1CTJetFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1CTJetFileWriter.cc @@ -55,6 +55,7 @@ L1CTJetFileWriter::L1CTJetFileWriter(const edm::ParameterSet& iConfig) jetsToken_(consumes>(iConfig.getParameter("jets"))), fileWriterOutputToGT_(l1t::demo::parseFileFormat(iConfig.getParameter("format")), iConfig.getParameter("outputFilename"), + iConfig.getParameter("outputFileExtension"), nFramesPerBX_, ctl2BoardTMUX_, maxLinesPerFile_, @@ -108,11 +109,12 @@ void L1CTJetFileWriter::fillDescriptions(edm::ConfigurationDescriptions& descrip edm::ParameterSetDescription desc; desc.add("jets"); desc.add("outputFilename"); + desc.add("outputFileExtension", "txt"); desc.add("nJets", 12); desc.add("nFramesPerBX", 9); desc.add("TMUX", 6); desc.add("maxLinesPerFile", 1024); - desc.add("format", "EMP"); + desc.add("format", "EMPv2"); descriptions.addDefault(desc); } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc index 5cf255385f433..450269d466a7e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc @@ -8,6 +8,8 @@ #include "FWCore/Framework/interface/Event.h" #include "FWCore/Utilities/interface/InputTag.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" #include "DataFormats/L1TParticleFlow/interface/PFJet.h" @@ -23,6 +25,8 @@ class L1SeedConePFJetProducer : public edm::global::EDProducer<> { explicit L1SeedConePFJetProducer(const edm::ParameterSet&); ~L1SeedConePFJetProducer() override; + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + private: /// ///////////////// /// /// MANDATORY METHODS /// @@ -213,5 +217,18 @@ std::vector L1SeedConePFJetProducer::convertHWToEDM( return edmJets; } +void L1SeedConePFJetProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("L1PFObjects", edm::InputTag("l1tLayer1", "Puppi")); + desc.add("nJets", 16); + desc.add("coneSize", 0.4); + desc.add("HW", false); + desc.add("debug", false); + desc.add("doCorrections", false); + desc.add("correctorFile", ""); + desc.add("correctorDir", ""); + descriptions.add("l1tSeedConePFJetProducer", desc); +} + #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(L1SeedConePFJetProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index d6bd40e646190..6d3779404c679 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -24,6 +24,7 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/hgcalinput_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h" @@ -249,6 +250,9 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet } else if (regalgo == "Multififo") { regionizer_ = std::make_unique( iConfig.getParameter("regionizerAlgoParameters")); + } else if (regalgo == "BufferedFoldedMultififo") { + regionizer_ = std::make_unique( + iConfig.getParameter("regionizerAlgoParameters")); } else if (regalgo == "MultififoBarrel") { const auto &pset = iConfig.getParameter("regionizerAlgoParameters"); regionizer_ = diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc index 54399d8a497a3..6097408bf20e3 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -97,6 +97,7 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { dataWriter_ = std::make_unique( l1t::demo::parseFileFormat(conf.getParameter("format")), conf.getParameter("outputFilename"), + conf.getParameter("outputFileExtension"), nFramesPerBX, conf.getParameter("TMUX"), conf.getParameter("maxLinesPerFile"), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/L1BJetProducer_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/L1BJetProducer_cff.py index 9d61f9a7c5283..9b17cf5afd8ae 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/L1BJetProducer_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/L1BJetProducer_cff.py @@ -12,7 +12,7 @@ nParticles = cms.int32(10), minPt = cms.double(10), maxEta = cms.double(2.4), - vtx = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation"), + vtx = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), ) l1tBJetProducerPuppiCorrectedEmulator = l1tBJetProducerPuppi.clone( jets = cms.InputTag("l1tSCPFL1PuppiExtendedCorrectedEmulator", ""), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 4a0774bdfc3b0..06962889d01ed 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -19,7 +19,7 @@ muons = cms.InputTag('l1tSAMuonsGmt','promptSAMuons'), emClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromL1EGClusters:selected')), hadClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromCombinedCaloHCal:calibrated')), - vtxCollection = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation"), + vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), vtxCollectionEmulation = cms.bool(True), emPtCut = cms.double(0.5), hadPtCut = cms.double(1.0), @@ -161,7 +161,7 @@ muons = cms.InputTag('l1tSAMuonsGmt','promptSAMuons'), emClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromHGC3DClusters:egamma')), # used only for E/gamma hadClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromHGC3DClusters')), - vtxCollection = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation"), + vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), vtxCollectionEmulation = cms.bool(True), nVtx = cms.int32(1), emPtCut = cms.double(0.5), @@ -314,7 +314,7 @@ muons = cms.InputTag('l1tSAMuonsGmt','promptSAMuons'), emClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromHGC3DClusters:egamma')), # used only for E/gamma hadClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromHGC3DClusters')), - vtxCollection = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation"), + vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), vtxCollectionEmulation = cms.bool(True), nVtx = cms.int32(1), emPtCut = cms.double(0.5), @@ -326,17 +326,31 @@ hgcalInputConversionParameters = cms.PSet( slim = cms.bool(True) ), - regionizerAlgo = cms.string("Ideal"), - pfAlgo = cms.string("PFAlgoDummy"), - puAlgo = cms.string("LinearizedPuppi"), + regionizerAlgo = cms.string("Multififo"), regionizerAlgoParameters = cms.PSet( useAlsoVtxCoords = cms.bool(True), - ), + nEndcaps = cms.uint32(2), + nClocks = cms.uint32(54), + nTkLinks = cms.uint32(0), + nCaloLinks = cms.uint32(3), + nTrack = cms.uint32(0), + nCalo = cms.uint32(12), + nEmCalo = cms.uint32(12), + nMu = cms.uint32(4), + egInterceptMode = cms.PSet( + afterFifo = cms.bool(True), + emIDMask = cms.uint32(0x1E), + nHADCALO_IN = cms.uint32(12), + nEMCALO_OUT = cms.uint32(12), + ) + ), + pfAlgo = cms.string("PFAlgoDummy"), pfAlgoParameters = cms.PSet( nCalo = cms.uint32(12), nMu = cms.uint32(4), # unused debug = cms.untracked.bool(False) ), + puAlgo = cms.string("LinearizedPuppi"), puAlgoParameters = cms.PSet( nTrack = cms.uint32(0), # unused nIn = cms.uint32(12), @@ -404,7 +418,7 @@ useTrackerMuons = cms.bool(False), emClusters = cms.VInputTag(), hadClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromCombinedCaloHF:calibrated')), - vtxCollection = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation"), + vtxCollection = cms.InputTag("l1tVertexFinderEmulator","L1VerticesEmulation"), vtxCollectionEmulation = cms.bool(True), nVtx = cms.int32(1), emPtCut = cms.double(0.5), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index e79e4bae5f6c8..9bd1434d9cd3d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -1,178 +1,271 @@ import FWCore.ParameterSet.Config as cms -eventsPerFile_ = 12 -gttLatency_ = 156+120 -gttNumberOfPVs_ = 10 +_eventsPerFile = 12 +_gttLatency = 156+120 +_gttNumberOfPVs = 10 ##################################################################################################################### ## Barrel configurations: 54 regions, 6 puppi output links, only write out the layer 1 outputs for now -barrelWriterOutputOnly_ = cms.PSet( +_barrelWriterOutputOnly = cms.PSet( partition = cms.string("Barrel"), + tmuxFactor = cms.uint32(6), outputLinksPuppi = cms.vuint32(*range(6)), outputLinkEgamma = cms.int32(6), nEgammaObjectsOut = cms.uint32(16), + nInputFramesPerBX = cms.uint32(9), nOutputFramesPerBX = cms.uint32(9), - fileFormat = cms.string("EMP"), + fileFormat = cms.string("EMPv2"), + inputFileExtension = cms.string("txt.gz"), + outputFileExtension = cms.string("txt.gz"), + maxLinesPerInputFile = cms.uint32(1024), maxLinesPerOutputFile = cms.uint32(1024), - eventsPerFile = cms.uint32(eventsPerFile_), -) -## Barrel (54) split in 3 eta slices -barrelWriterOutputOnlyEtaConfigs = [ - barrelWriterOutputOnly_.clone( - outputRegions = cms.vuint32(*[18*ie+i for i in range(18)]), - outputFileName = cms.string("l1BarrelEta%d-outputs-ideal" % (ie+1)), - outputBoard = cms.int32(-1), ## can't output e/gamma in eta split regions - outputLinkEgamma = cms.int32(-1), ## since the boards are defined in phi regions - ) for ie in range(3) -] + eventsPerFile = cms.uint32(_eventsPerFile), +) ## Barrel (54) split in 3 phi slices barrelWriterOutputOnlyPhiConfigs = [ - barrelWriterOutputOnly_.clone( + _barrelWriterOutputOnly.clone( outputRegions = cms.vuint32(*[3*ip+9*ie+i for ie in range(6) for i in range(3) ]), outputBoard = cms.int32(ip), - outputFileName = cms.string("l1BarrelPhi%d-outputs-ideal" % (ip+1)) - ) for ip in range(3) -] -## Barrel9 (27) split in phi eta slices -barrel9WriterOutputOnlyPhiConfigs = [ - barrelWriterOutputOnly_.clone( - outputRegions = cms.vuint32(*[3*ip+9*ie+i for ie in range(3) for i in range(3) ]), - outputBoard = cms.int32(ip), - outputFileName = cms.string("l1Barrel9Phi%d-outputs-ideal" % (ip+1)) + outputFileName = cms.string("l1BarrelPhi%d-outputs" % (ip+1)) ) for ip in range(3) ] -barrelWriterConfigs = barrelWriterOutputOnlyPhiConfigs # + barrelWriterOutputOnlyEtaConfigs -barrel9WriterConfigs = [] #barrel9WriterOutputOnlyPhiConfigs +barrelSerenityPhi1Config = barrelWriterOutputOnlyPhiConfigs[0].clone( + tfTimeSlices = cms.VPSet(*[cms.PSet(tfSectors = cms.VPSet(*[ cms.PSet(tfLink = cms.int32(-1)) for s in range(18) ])) for t in range(3)]), + gctSectors = cms.VPSet(*[cms.PSet( + gctLinksHad = cms.vint32(-1,-1), + gctLinksEcal = cms.vint32(-1), + ) for s in range(3)]), + gmtTimeSlices = cms.VPSet(*[cms.PSet(gmtLink = cms.int32(4*17+t)) for t in range(3)]), + gmtNumberOfMuons = cms.uint32(12), + gttLatency = cms.uint32(156+10), + gttNumberOfPVs = cms.uint32(_gttNumberOfPVs), + inputFileName = cms.string("l1BarrelPhi1Serenity-inputs-vu9p"), + outputFileName = cms.string("l1BarrelPhi1Serenity-outputs") +) +barrelSerenityVU9PPhi1Config = barrelSerenityPhi1Config.clone( + gttLink = cms.int32(4*28+3), + inputFileName = cms.string("l1BarrelPhi1Serenity-inputs-vu9p"), + outputFileName = cms.string("l1BarrelPhi1Serenity-outputs") +) +barrelSerenityVU13PPhi1Config = barrelSerenityPhi1Config.clone( + gttLink = cms.int32(4*31+3), + inputFileName = cms.string("l1BarrelPhi1Serenity-inputs-vu13p"), +) +for t in range(3): + for ie in range(2): + for i,s in enumerate([8, 0, 1, 2, 3]): + loglink = 3*(i+5*ie)+t + physlink = loglink+4*1 if loglink < 15 else (loglink-15)+4*25 + barrelSerenityVU9PPhi1Config.tfTimeSlices[t].tfSectors[s+9*ie].tfLink = physlink + physlink = loglink+4*0 if loglink < 15 else (loglink-15)+4*28 + barrelSerenityVU13PPhi1Config.tfTimeSlices[t].tfSectors[s+9*ie].tfLink = physlink +for i,s in enumerate([0,1]): + barrelSerenityVU9PPhi1Config.gctSectors[s].gctLinksHad = [3*i+4*18, 3*i+4*18+1] + barrelSerenityVU9PPhi1Config.gctSectors[s].gctLinksEcal = [3*i+4*18+2] + barrelSerenityVU13PPhi1Config.gctSectors[s].gctLinksHad = [3*i+4*18, 3*i+4*18+1] + barrelSerenityVU13PPhi1Config.gctSectors[s].gctLinksEcal = [3*i+4*18+2] + +barrelWriterConfigs = barrelWriterOutputOnlyPhiConfigs ##################################################################################################################### ## HGcal configuration: write out both inputs and outputs -hgcalWriterConfig_ = cms.PSet( +_hgcalWriterConfig = cms.PSet( partition = cms.string("HGCal"), - outputRegions = cms.vuint32(*[i+9 for i in range(9)]), - outputBoard = cms.int32(1), + tmuxFactor = cms.uint32(6), nEgammaObjectsOut = cms.uint32(16), nInputFramesPerBX = cms.uint32(9), nOutputFramesPerBX = cms.uint32(9), - fileFormat = cms.string("EMP"), + fileFormat = cms.string("EMPv2"), + inputFileExtension = cms.string("txt.gz"), + outputFileExtension = cms.string("txt.gz"), maxLinesPerInputFile = cms.uint32(1024), maxLinesPerOutputFile = cms.uint32(1024), - eventsPerFile = cms.uint32(eventsPerFile_), + eventsPerFile = cms.uint32(_eventsPerFile), tfTimeSlices = cms.VPSet(*[cms.PSet(tfSectors = cms.VPSet()) for i in range(3)]), hgcTimeSlices = cms.VPSet(*[cms.PSet(hgcSectors = cms.VPSet()) for i in range(3)]), gmtTimeSlices = cms.VPSet(cms.PSet(),cms.PSet(),cms.PSet()), gmtNumberOfMuons = cms.uint32(12), gttLink = cms.int32(-1), - gttLatency = cms.uint32(gttLatency_), - gttNumberOfPVs = cms.uint32(gttNumberOfPVs_) + gttLatency = cms.uint32(_gttLatency), + gttNumberOfPVs = cms.uint32(_gttNumberOfPVs), + outputLinksPuppi = cms.vuint32(*range(3)), + outputLinkEgamma = cms.int32(3), ) ## Ideal configuration: 27 input links from tf, 36 from hgc, 3 from gmt, 1 from gtt, in this order; output 3 puppi + 1 e/gamma -hgcalPosIdealWriterConfig = hgcalWriterConfig_.clone() -for t in range(3): - hgcalPosIdealWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # neg - hgcalPosIdealWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t)) for i in range(9) ] # pos - hgcalPosIdealWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # neg - hgcalPosIdealWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[27+12*i+4*t+j for j in range(4)])) for i in range(3) ] # pos - hgcalPosIdealWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(27+36+t) -hgcalPosIdealWriterConfig.gttLink = 27+36+3 -hgcalPosIdealWriterConfig.outputLinksPuppi = cms.vuint32(0,1,2) -hgcalPosIdealWriterConfig.outputLinkEgamma = cms.int32(5) -hgcalPosIdealWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-ideal") -hgcalPosIdealWriterConfig.outputFileName = cms.string("l1HGCalPos-outputs-ideal") -hgcalNegIdealWriterConfig = hgcalPosIdealWriterConfig.clone( - inputFileName = "", - outputFileName = "l1HGCalNeg-outputs-ideal", +_hgcalPosWriterConfig = _hgcalWriterConfig.clone( + outputRegions = cms.vuint32(*[i+9 for i in range(9)]), + outputBoard = cms.int32(1), +) +_hgcalNegWriterConfig = _hgcalPosWriterConfig.clone( outputRegions = [i for i in range(9)], outputBoard = 0, ) -## Current configuration for VU9P at B904 for layer1 - layer2 tests with puppi and e/gamma outputs on links 56-59 -hgcalPosVU9PB904egWriterConfig = hgcalWriterConfig_.clone() +hgcalPosOutputWriterConfig = _hgcalPosWriterConfig.clone( + outputFileName = cms.string("l1HGCalPos-outputs") +) +hgcalNegOutputWriterConfig = _hgcalNegWriterConfig.clone( + outputFileName = cms.string("l1HGCalNeg-outputs") +) +## Current configurations for VU9P +hgcalPosVU9PWriterConfig = _hgcalPosWriterConfig.clone() +hgcalNegVU9PWriterConfig = _hgcalNegWriterConfig.clone() for t in range(3): - hgcalPosVU9PB904egWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # neg - hgcalPosVU9PB904egWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*2)) for i in range(4) ] # pos, left quads - hgcalPosVU9PB904egWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*25)) for i in range(5) ] # pos, right quads - hgcalPosVU9PB904egWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # neg - hgcalPosVU9PB904egWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[4*11+12*i+4*t+j for j in range(4)])) for i in range(3) ] # pos - hgcalPosVU9PB904egWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4+t) -hgcalPosVU9PB904egWriterConfig.gttLink = 4+3 -hgcalPosVU9PB904egWriterConfig.outputLinksPuppi = cms.vuint32(56,57,58) -hgcalPosVU9PB904egWriterConfig.outputLinkEgamma = cms.int32(59) -hgcalPosVU9PB904egWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-vu9p_B904eg") -hgcalPosVU9PB904egWriterConfig.outputFileName = cms.string("l1HGCalPos-outputs-vu9p_B904eg") -## Current configuration for VU13P -hgcalPosVU13PWriterConfig = hgcalWriterConfig_.clone() + hgcalPosVU9PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # neg + hgcalPosVU9PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*2)) for i in range(4) ] # pos, left quads + hgcalPosVU9PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*25)) for i in range(5) ] # pos, right quads + hgcalNegVU9PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*2)) for i in range(4) ] # neg, left quads + hgcalNegVU9PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*25)) for i in range(5) ] # neg, right quads + hgcalNegVU9PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # pos + hgcalPosVU9PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # neg + hgcalPosVU9PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[4*11+12*i+4*t+j for j in range(4)])) for i in range(3) ] # pos + hgcalNegVU9PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[4*11+12*i+4*t+j for j in range(4)])) for i in range(3) ] # neg + hgcalNegVU9PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # pos + hgcalPosVU9PWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4+t) + hgcalNegVU9PWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4+t) +hgcalPosVU9PWriterConfig.gttLink = 4+3 +hgcalNegVU9PWriterConfig.gttLink = 4+3 +hgcalPosVU9PWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-vu9p") +hgcalNegVU9PWriterConfig.inputFileName = cms.string("l1HGCalNeg-inputs-vu9p") +## Current configurations for VU13P +hgcalPosVU13PWriterConfig = _hgcalPosWriterConfig.clone() +hgcalNegVU13PWriterConfig = _hgcalNegWriterConfig.clone() for t in range(3): - hgcalPosVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # neg - hgcalPosVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*0)) for i in range(5) ] # pos, left quads + hgcalPosVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # neg + hgcalPosVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*0)) for i in range(5) ] # pos, left quads hgcalPosVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*28)) for i in range(4) ] # pos, right quads + hgcalNegVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*0)) for i in range(5) ] # neg, left quads + hgcalNegVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*28)) for i in range(4) ] # neg, right quads + hgcalNegVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # pos hgcalPosVU13PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # neg for isec,q0 in (0,12),(1,17),(2,20): hgcalPosVU13PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[4*q0+4*t+j for j in range(4)])) ] # pos - hgcalPosVU13PWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4*27+t) -hgcalPosVU13PWriterConfig.gttLink = 4*27+3 -hgcalPosVU13PWriterConfig.outputLinksPuppi = cms.vuint32(0,1,2) -hgcalPosVU13PWriterConfig.outputLinkEgamma = cms.int32(3) -hgcalPosVU13PWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-vu13p") -hgcalPosVU13PWriterConfig.outputFileName = cms.string("l1HGCalPos-outputs-vu13p") -hgcalNegVU13PWriterConfig = hgcalWriterConfig_.clone() -for t in range(3): - hgcalNegVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*0)) for i in range(5) ] # neg, left quads - hgcalNegVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*28)) for i in range(4) ] # neg, right quads - hgcalNegVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # pos - for isec,q0 in (0,12),(1,17),(2,20): hgcalNegVU13PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[4*q0+4*t+j for j in range(4)])) ] # neg hgcalNegVU13PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # pos + hgcalPosVU13PWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4*27+t) hgcalNegVU13PWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4*27+t) +hgcalPosVU13PWriterConfig.gttLink = 4*27+3 hgcalNegVU13PWriterConfig.gttLink = 4*27+3 -hgcalNegVU13PWriterConfig.outputLinksPuppi = cms.vuint32(0,1,2) -hgcalNegVU13PWriterConfig.outputLinkEgamma = cms.int32(3) +hgcalPosVU13PWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-vu13p") hgcalNegVU13PWriterConfig.inputFileName = cms.string("l1HGCalNeg-inputs-vu13p") -hgcalNegVU13PWriterConfig.outputFileName = cms.string("l1HGCalNeg-outputs-vu13p") - -## Enable both +## Enable outputs and both boards hgcalWriterConfigs = [ - hgcalPosIdealWriterConfig, - hgcalNegIdealWriterConfig, - hgcalPosVU9PB904egWriterConfig, + hgcalPosOutputWriterConfig, + hgcalNegOutputWriterConfig, + hgcalPosVU9PWriterConfig, + hgcalNegVU9PWriterConfig, hgcalPosVU13PWriterConfig, hgcalNegVU13PWriterConfig ] ##################################################################################################################### ## Forward HGCal configuration: only outputs for now, 18 regions, 12 candidates x region, 4 output fibers -hgcalNoTKWriterOutputOnlyConfig = cms.PSet( +_hgcalNoTKWriterConfig = cms.PSet( partition = cms.string("HGCalNoTk"), + tmuxFactor = cms.uint32(6), outputRegions = cms.vuint32(*range(18)), + nInputFramesPerBX = cms.uint32(9), nOutputFramesPerBX = cms.uint32(9), - fileFormat = cms.string("EMP"), + fileFormat = cms.string("EMPv2"), + inputFileExtension = cms.string("txt.gz"), + outputFileExtension = cms.string("txt.gz"), + maxLinesPerInputFile = cms.uint32(1024), maxLinesPerOutputFile = cms.uint32(1024), - eventsPerFile = cms.uint32(eventsPerFile_), - outputLinksPuppi = cms.vuint32(0,1,2,4), - outputFileName = cms.string("l1HGCalNoTk-outputs-ideal") + eventsPerFile = cms.uint32(_eventsPerFile), ) +hgcalNoTKOutputWriterConfig = _hgcalNoTKWriterConfig.clone( + outputLinksPuppi = cms.vuint32(*range(4)), + outputFileName = cms.string("l1HGCalNoTK-outputs") +) +hgcalNoTKVU13PWriterConfig = _hgcalNoTKWriterConfig.clone( + hgcTimeSlices = cms.VPSet(*[cms.PSet(hgcSectors = cms.VPSet()) for i in range(3)]), + gmtTimeSlices = cms.VPSet(*[cms.PSet(gmtLink = cms.int32(-1)) for i in range(3)]), + gmtNumberOfMuons = cms.uint32(12), + gttLink = cms.int32(-1), + gttLatency = cms.uint32(_gttLatency), + gttNumberOfPVs = cms.uint32(_gttNumberOfPVs), +) +for t in range(3): + for isec in range(6): + q0 = 3*isec + 6 + hgcalNoTKVU13PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[4*q0+4*t+j for j in range(4)])) ] # pos +hgcalNoTKVU13PWriterConfig.inputFileName = cms.string("l1HGCalNoTK-inputs-vu13p") # vu9p uses the same cabling for now hgcalNoTKWriterConfigs = [ - hgcalNoTKWriterOutputOnlyConfig + hgcalNoTKOutputWriterConfig, + hgcalNoTKVU13PWriterConfig +] + +##################################################################################################################### +## HGCal TM18 configuration +_hgcalWriterTM18 = _hgcalWriterConfig.clone( + tmuxFactor = cms.uint32(18), + tfTimeSlices = None, + tfSectors = cms.VPSet(*[cms.PSet(tfLink = cms.int32(-1)) for i in range(18)]), + hgcTimeSlices = None, + hgcSectors = cms.VPSet(*[cms.PSet() for i in range(6)]), + gmtTimeSlices = None, + gmtLink = cms.int32(4*27+0), + gttLink = 4*27+3, + eventsPerFile = 6, +) +hgcalWriterOutputTM18WriterConfig = _hgcalWriterTM18.clone( + outputFileName = cms.string("l1HGCalTM18-outputs"), + outputRegions = cms.vuint32(*range(18)), + outputLinksPuppi = cms.vuint32(*range(2)), + outputLinkEgamma = cms.int32(2), +) +hgcalWriterVU9PTM18WriterConfig = _hgcalWriterTM18.clone( + inputFileName = cms.string("l1HGCalTM18-inputs-vu9p"), + gttLatency = cms.uint32(167), # shorter, to fit 6 events in 1024 lines + maxLinesPerInputFile = cms.uint32(1024+167), # anything beyond 986 will be nulls +) +hgcalWriterVU13PTM18WriterConfig = hgcalWriterVU9PTM18WriterConfig.clone( + inputFileName = cms.string("l1HGCalTM18-inputs-vu13p"), +) +for ie in range(2): + for iphi in range(9): + isec, ilink = 9*ie+iphi, 2*iphi+ie + hgcalWriterVU9PTM18WriterConfig.tfSectors[isec].tfLink = (ilink if ilink < 12 else (4*28+(ilink-12))) + hgcalWriterVU13PTM18WriterConfig.tfSectors[isec].tfLink = (ilink if ilink < 12 else (4*30+(ilink-12))) + for iphi in range(3): + isec, ilink = 3*ie+iphi, 2*iphi+ie + hgcalWriterVU9PTM18WriterConfig.hgcSectors[isec].hgcLinks = cms.vint32(*range(4*(12+ilink),4*(12+ilink)+4)) + hgcalWriterVU13PTM18WriterConfig.hgcSectors[isec].hgcLinks = cms.vint32(*range(4*(13+ilink),4*(13+ilink)+4)) + +hgcalTM18WriterConfigs = [ + hgcalWriterOutputTM18WriterConfig, + hgcalWriterVU9PTM18WriterConfig, + hgcalWriterVU13PTM18WriterConfig ] +hgcalNoTKOutputTM18WriterConfig = _hgcalWriterTM18.clone( + outputFileName = cms.string("l1HGCalTM18-outputs-fwd"), + outputRegions = cms.vuint32(*range(18)), + outputBoard = cms.int32(-1),#0,1), + outputLinksPuppi = cms.vuint32(*range(2)), + outputLinkEgamma = cms.int32(-1), +) ##################################################################################################################### -## HF configuration: not enabled for the moment +## HF configuration (to be better defined later) ##################################################################################################################### ## HF configuration not realistic, 3 links per endcap, write out the layer 1 outputs for now -hfWriterOutputOnly_ = cms.PSet( +_hfWriterOutputOnly = cms.PSet( partition = cms.string("HF"), + tmuxFactor = cms.uint32(6), outputLinksPuppi = cms.vuint32(*range(3)), nOutputFramesPerBX = cms.uint32(9), - fileFormat = cms.string("EMP"), + fileFormat = cms.string("EMPv2"), + outputFileExtension = cms.string("txt.gz"), maxLinesPerOutputFile = cms.uint32(1024), - eventsPerFile = cms.uint32(eventsPerFile_), + eventsPerFile = cms.uint32(_eventsPerFile), ) hfWriterConfigs = [ - hfWriterOutputOnly_.clone( + _hfWriterOutputOnly.clone( outputRegions = cms.vuint32(*[9*ie+i for i in range(9)]), - outputFileName = cms.string("l1HF%s-outputs-ideal" % ("Pos" if ie else "Neg")), + outputFileName = cms.string("l1HF%s-outputs" % ("Pos" if ie else "Neg")), ) for ie in range(2) ] diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py index e42be9d3b8211..18e28d46752f0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py @@ -72,8 +72,9 @@ writeOutPattern=cms.bool(False), inPatternFile=cms.PSet( nFramesPerBX=cms.uint32(9), # 360 MHz clock or 25 Gb/s link - format=cms.string("EMP"), + format=cms.string("EMPv2"), outputFilename=cms.string("L1TCTL2EG_InPattern"), + outputFileExtension=cms.string("txt.gz"), TMUX=cms.uint32(6), maxLinesPerFile=cms.uint32(1024), channels=cms.VPSet( @@ -117,14 +118,15 @@ ), outPatternFile=cms.PSet( nFramesPerBX=cms.uint32(9), # 360 MHz clock or 25 Gb/s link - format=cms.string("EMP"), + format=cms.string("EMPv2"), outputFilename=cms.string("L1TCTL2EG_OutPattern"), + outputFileExtension=cms.string("txt.gz"), TMUX=cms.uint32(6), maxLinesPerFile=cms.uint32(1024), channels=cms.VPSet( cms.PSet( TMUX=cms.uint32(6), - nWords=cms.uint32(36), # 36 = 12*3/2words ele + 12*3/2words phhotons + nWords=cms.uint32(36), # 36 = 12*3/2words ele + 12*3/2words photons interface=cms.string("eglayer2"), id=cms.uint32(0), channels=cms.vuint32(0) @@ -134,8 +136,9 @@ # NOTE: to write out the GT input from 6TS # outPatternFile=cms.PSet( # nFramesPerBX=cms.uint32(9), # 360 MHz clock or 25 Gb/s link - # format=cms.string("EMP"), + # format=cms.string("EMPv2"), # outputFilename=cms.string("L1TCTL2EG_ToGTPattern"), + # outputFileExtension=cms.string("txt.gz"), # TMUX=cms.uint32(1), # maxLinesPerFile=cms.uint32(1024), # channels=cms.VPSet( diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py index 60d58d2ac23dd..a2a34b149513a 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py @@ -1,6 +1,7 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.Phase2L1ParticleFlow.l1tSeedConePFJetProducer_cfi import l1tSeedConePFJetProducer, l1tSeedConePFJetEmulatorProducer +from L1Trigger.Phase2L1ParticleFlow.l1tSeedConePFJetProducer_cfi import l1tSeedConePFJetProducer +from L1Trigger.Phase2L1ParticleFlow.l1tSeedConePFJetEmulatorProducer_cfi import l1tSeedConePFJetEmulatorProducer from L1Trigger.Phase2L1ParticleFlow.l1tDeregionizerProducer_cfi import l1tDeregionizerProducer as l1tLayer2Deregionizer, l1tDeregionizerProducerExtended as l1tLayer2DeregionizerExtended l1tSCPFL1PF = l1tSeedConePFJetProducer.clone(L1PFObjects = 'l1tLayer1:PF') l1tSCPFL1Puppi = l1tSeedConePFJetProducer.clone() diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tJetFileWriter_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tJetFileWriter_cfi.py index 6dd9b1f64370e..a53db5cb667fe 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1tJetFileWriter_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1tJetFileWriter_cfi.py @@ -7,5 +7,6 @@ TMUX = cms.uint32(6), maxLinesPerFile = cms.uint32(1024), outputFilename = cms.string("L1CTSCJetsPatterns"), - format = cms.string("EMP") + format = cms.string("EMPv2"), + outputFileExtension = cms.string("txt.gz") ) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetEmulatorProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetEmulatorProducer_cfi.py new file mode 100644 index 0000000000000..2c859e0a97af7 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetEmulatorProducer_cfi.py @@ -0,0 +1,2 @@ +from L1Trigger.Phase2L1ParticleFlow.l1tSeedConePFJetProducer_cfi import l1tSeedConePFJetProducer as _l1tSeedConePFJetProducer +l1tSeedConePFJetEmulatorProducer = _l1tSeedConePFJetProducer.clone(HW = True) \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetProducer_cfi.py deleted file mode 100644 index eb7fd2fd1e081..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetProducer_cfi.py +++ /dev/null @@ -1,15 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -l1tSeedConePFJetProducer = cms.EDProducer("L1SeedConePFJetProducer", - L1PFObjects = cms.InputTag("l1tLayer1","Puppi"), - nJets = cms.uint32(16), - coneSize = cms.double(0.4), - HW = cms.bool(False), - debug = cms.bool(False), - doCorrections = cms.bool(False), - correctorFile = cms.string(""), - correctorDir = cms.string("") - ) - -l1tSeedConePFJetEmulatorProducer = l1tSeedConePFJetProducer.clone(HW = True) - diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc index 018f156978ca0..a8176b96846d5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -5,10 +5,16 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const edm::ParameterSet& iConfig, const l1ct::Event& eventTemplate) : partition_(parsePartition(iConfig.getParameter("partition"))), + tmuxFactor_(iConfig.getParameter("tmuxFactor")), writeInputs_(iConfig.existsAs("inputFileName") && !iConfig.getParameter("inputFileName").empty()), writeOutputs_(iConfig.existsAs("outputFileName") && !iConfig.getParameter("outputFileName").empty()), + tfTimeslices_(std::max(1u, tfTmuxFactor_ / tmuxFactor_)), + hgcTimeslices_(std::max(1u, hgcTmuxFactor_ / tmuxFactor_)), + gctTimeslices_(std::max(1u, gctTmuxFactor_ / tmuxFactor_)), + gmtTimeslices_(std::max(1u, gmtTmuxFactor_ / tmuxFactor_)), + gttTimeslices_(std::max(1u, gttTmuxFactor_ / tmuxFactor_)), outputBoard_(-1), outputLinkEgamma_(-1), fileFormat_(iConfig.getParameter("fileFormat")), @@ -19,7 +25,7 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) { configTimeSlices(iConfig, "tf", eventTemplate.raw.track.size(), tfTimeslices_, tfLinksFactor_); - channelSpecsInput_["tf"] = {tmuxFactor_ * tfTimeslices_, tfTimeslices_}; + channelSpecsInput_["tf"] = {tfTmuxFactor_, tfTimeslices_}; } if (partition_ == Partition::Barrel) { auto sectorConfig = iConfig.getParameter>("gctSectors"); @@ -56,11 +62,12 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const configTimeSlices(iConfig, "gtt", 1, gttTimeslices_, gttLinksFactor_); gttLatency_ = iConfig.getParameter("gttLatency"); gttNumberOfPVs_ = iConfig.getParameter("gttNumberOfPVs"); - channelSpecsInput_["gtt"] = l1t::demo::ChannelSpec{tmuxFactor_, gttTimeslices_, gttLatency_}; + channelSpecsInput_["gtt"] = l1t::demo::ChannelSpec{tmuxFactor_ * gttTimeslices_, 1, gttLatency_}; } inputFileWriter_ = std::make_unique(l1t::demo::parseFileFormat(fileFormat_), iConfig.getParameter("inputFileName"), + iConfig.getParameter("inputFileExtension"), nInputFramesPerBX_, tmuxFactor_, iConfig.getParameter("maxLinesPerInputFile"), @@ -79,20 +86,23 @@ L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const channelSpecsOutput_["puppi"] = {tmuxFactor_, 0}; nPuppiFramesPerRegion_ = (nOutputFramesPerBX_ * tmuxFactor_) / outputRegions_.size(); if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) { - outputBoard_ = iConfig.getParameter("outputBoard"); outputLinkEgamma_ = iConfig.getParameter("outputLinkEgamma"); nEgammaObjectsOut_ = iConfig.getParameter("nEgammaObjectsOut"); if (outputLinkEgamma_ != -1) { channelIdsOutput_[l1t::demo::LinkId{"egamma", 0}].push_back(outputLinkEgamma_); - channelSpecsOutput_["egamma"] = {tmuxFactor_, nOutputFramesPerBX_ * tmuxFactor_ - 3 * nEgammaObjectsOut_}; + if (partition_ == Partition::HGCal && tmuxFactor_ == 18) { + // the format is different, as we put together both endcaps + channelSpecsOutput_["egamma"] = {tmuxFactor_, nOutputFramesPerBX_ * tmuxFactor_ / 2 - 3 * nEgammaObjectsOut_}; + } else { + outputBoard_ = iConfig.getParameter("outputBoard"); + channelSpecsOutput_["egamma"] = {tmuxFactor_, nOutputFramesPerBX_ * tmuxFactor_ - 3 * nEgammaObjectsOut_}; + } } } - if ((outputBoard_ == -1) != (outputLinkEgamma_ == -1)) { - throw cms::Exception("Configuration", "Inconsistent configuration of outputLinkEgamma, outputBoard"); - } outputFileWriter_ = std::make_unique(l1t::demo::parseFileFormat(fileFormat_), iConfig.getParameter("outputFileName"), + iConfig.getParameter("outputFileExtension"), nOutputFramesPerBX_, tmuxFactor_, iConfig.getParameter("maxLinesPerOutputFile"), @@ -245,12 +255,12 @@ void L1TCorrelatorLayer1PatternFileWriter::writeHGC(const l1ct::Event& event, l1 // put header word and (dummy) towers ret[il].resize(31); ap_uint<64>& head64 = ret[il][0]; - head64(63, 48) = 0xABC0; // Magic - head64(47, 38) = 0; // Opaque - head64(39, 32) = (eventIndex_ % 3) * 6; // TM slice - head64(31, 24) = iS; // Sector - head64(23, 16) = il; // link - head64(15, 0) = eventIndex_ % 3564; // BX + head64(63, 48) = 0xABC0; // Magic + head64(47, 38) = 0; // Opaque + head64(39, 32) = (eventIndex_ % hgcTimeslices_) * tmuxFactor_; // TM slice + head64(31, 24) = iS; // Sector + head64(23, 16) = il; // link + head64(15, 0) = eventIndex_ % 3564; // BX for (unsigned int j = 0; j < 30; ++j) { ret[il][j + 1] = 4 * j + il; } @@ -329,21 +339,34 @@ void L1TCorrelatorLayer1PatternFileWriter::writePuppi(const l1ct::Event& event, } } -void L1TCorrelatorLayer1PatternFileWriter::writeEgamma(const l1ct::Event& event, l1t::demo::EventData& out) { - std::vector> ret; - const auto& pho = event.board_out[outputBoard_].egphoton; - const auto& ele = event.board_out[outputBoard_].egelectron; - ret.reserve(3 * nEgammaObjectsOut_); +void L1TCorrelatorLayer1PatternFileWriter::writeEgamma(const l1ct::OutputBoard& egboard, + std::vector>& ret) { + unsigned int s0 = ret.size(); + const auto& pho = egboard.egphoton; + const auto& ele = egboard.egelectron; + ret.reserve(s0 + 3 * nEgammaObjectsOut_); for (const auto& p : pho) { ret.emplace_back(p.pack()); } - ret.resize(nEgammaObjectsOut_, ap_uint<64>(0)); + ret.resize(s0 + nEgammaObjectsOut_, ap_uint<64>(0)); for (const auto& p : ele) { ap_uint<128> dword = p.pack(); ret.push_back(dword(63, 0)); ret.push_back(dword(127, 64)); } - ret.resize(3 * nEgammaObjectsOut_, ap_uint<64>(0)); + ret.resize(s0 + 3 * nEgammaObjectsOut_, ap_uint<64>(0)); +} + +void L1TCorrelatorLayer1PatternFileWriter::writeEgamma(const l1ct::Event& event, l1t::demo::EventData& out) { + std::vector> ret; + if (partition_ == Partition::HGCal && tmuxFactor_ == 18) { + // the format is different, as we put together both endcaps + writeEgamma(event.board_out[0], ret); + ret.resize(nOutputFramesPerBX_ * tmuxFactor_ / 2, ap_uint<64>(0)); + writeEgamma(event.board_out[1], ret); + } else { + writeEgamma(event.board_out[outputBoard_], ret); + } out.add(l1t::demo::LinkId{"egamma", 0}, ret); } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/buffered_folded_multififo_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/buffered_folded_multififo_regionizer_ref.cpp index a9dbeba35ee2d..e03e29850148d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/buffered_folded_multififo_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/buffered_folded_multififo_regionizer_ref.cpp @@ -3,6 +3,28 @@ #include #include +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::BufferedFoldedMultififoRegionizerEmulator::BufferedFoldedMultififoRegionizerEmulator( + const edm::ParameterSet& iConfig) + : BufferedFoldedMultififoRegionizerEmulator(iConfig.getParameter("nClocks"), + iConfig.getParameter("nTrack"), + iConfig.getParameter("nCalo"), + iConfig.getParameter("nEmCalo"), + iConfig.getParameter("nMu"), + /*streaming=*/true, + /*outii=*/6, + /*pauseii=*/3, + iConfig.getParameter("useAlsoVtxCoords")) { + debug_ = iConfig.getUntrackedParameter("debug", false); + if (iConfig.existsAs("egInterceptMode")) { + const auto& emSelCfg = iConfig.getParameter("egInterceptMode"); + setEgInterceptMode(emSelCfg.getParameter("afterFifo"), emSelCfg); + } +} +#endif + l1ct::BufferedFoldedMultififoRegionizerEmulator::BufferedFoldedMultififoRegionizerEmulator(unsigned int nclocks, unsigned int ntk, unsigned int ncalo, diff --git a/L1Trigger/Phase2L1ParticleFlow/test/.gitignore b/L1Trigger/Phase2L1ParticleFlow/test/.gitignore index 26f0a8dafc043..61181e36e734f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/.gitignore +++ b/L1Trigger/Phase2L1ParticleFlow/test/.gitignore @@ -1,2 +1,4 @@ *.txt +*.txt.gz +*.txt.xz *.dump diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py index 72c77480e8d2f..b44fc03b45edb 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py @@ -31,10 +31,8 @@ process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_cff') process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer2EG_cff') process.load('L1Trigger.L1TTrackMatch.l1tGTTInputProducer_cfi') +process.load('L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi') process.load('L1Trigger.VertexFinder.l1tVertexProducer_cfi') -process.l1tVertexFinderEmulator = process.l1tVertexProducer.clone() -process.l1tVertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" -process.l1tVertexFinderEmulator.l1TracksInputTag = cms.InputTag("l1tGTTInputProducer", "Level1TTTracksConverted") from L1Trigger.Phase2L1GMT.gmt_cfi import l1tStandaloneMuons process.l1tSAMuonsGmt = l1tStandaloneMuons.clone() @@ -75,6 +73,7 @@ process.runPF = cms.Path( process.l1tSAMuonsGmt + process.l1tGTTInputProducer + + process.l1tTrackSelectionProducer + process.l1tVertexFinderEmulator + process.l1tLayer1Barrel + process.l1tLayer1BarrelSerenity + diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index 21d6d105095f9..249725522860e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -1,13 +1,15 @@ import argparse import sys -# example: cmsRun L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py -- --dumpFilesOFF -# example: cmsRun L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py -- --dumpFilesOFF +# example: cmsRun L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py -- --patternFilesOFF +# example: cmsRun L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py -- --dumpFilesOFF --serenity parser = argparse.ArgumentParser(prog=sys.argv[0], description='Optional parameters') parser.add_argument("--dumpFilesOFF", help="switch on dump file production", action="store_true", default=False) parser.add_argument("--patternFilesOFF", help="switch on Layer-1 pattern file production", action="store_true", default=False) +parser.add_argument("--serenity", help="use Serenity settigns as default everwhere, i.e. also for barrel", action="store_true", default=False) +parser.add_argument("--tm18", help="Add TM18 emulators for the endcaps", action="store_true", default=False) argv = sys.argv[:] if '--' in argv: @@ -23,7 +25,7 @@ import FWCore.ParameterSet.Config as cms from Configuration.StandardSequences.Eras import eras -process = cms.Process("RESP", eras.Phase2C9) +process = cms.Process("RESP", eras.Phase2C17I13M9) process.load('Configuration.StandardSequences.Services_cff') process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi") @@ -41,47 +43,34 @@ "drop l1tTkPrimaryVertexs_*_*_*") ) -process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') -process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.Geometry.GeometryExtended2026D88Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D88_cff') process.load('Configuration.StandardSequences.MagneticField_cff') process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') # needed to read HCal TPs process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, '123X_mcRun4_realistic_v3', '') +process.GlobalTag = GlobalTag(process.GlobalTag, '125X_mcRun4_realistic_v2', '') process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_cff') process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer2EG_cff') process.load('L1Trigger.L1TTrackMatch.l1tGTTInputProducer_cfi') +process.load('L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi') +process.l1tTrackSelectionProducer.processSimulatedTracks = False # these would need stubs, and are not used anyway process.load('L1Trigger.VertexFinder.l1tVertexProducer_cfi') -process.l1tVertexFinderEmulator = process.l1tVertexProducer.clone() -process.l1tVertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" -process.l1tVertexFinderEmulator.l1TracksInputTag = cms.InputTag("l1tGTTInputProducer", "Level1TTTracksConverted") from L1Trigger.Phase2L1GMT.gmt_cfi import l1tStandaloneMuons process.l1tSAMuonsGmt = l1tStandaloneMuons.clone() -from L1Trigger.Phase2L1ParticleFlow.l1tSeedConePFJetProducer_cfi import l1tSeedConePFJetEmulatorProducer +from L1Trigger.Phase2L1ParticleFlow.l1tSeedConePFJetEmulatorProducer_cfi import l1tSeedConePFJetEmulatorProducer from L1Trigger.Phase2L1ParticleFlow.l1tDeregionizerProducer_cfi import l1tDeregionizerProducer from L1Trigger.Phase2L1ParticleFlow.l1tJetFileWriter_cfi import l1tSeededConeJetFileWriter process.l1tLayer2Deregionizer = l1tDeregionizerProducer.clone() -process.l1tLayer2SeedConeJetsCorrected = l1tSeedConePFJetEmulatorProducer.clone(L1PFObject = cms.InputTag('l1tLayer2Deregionizer', 'Puppi'), +process.l1tLayer2SeedConeJetsCorrected = l1tSeedConePFJetEmulatorProducer.clone(L1PFObjects = cms.InputTag('l1tLayer2Deregionizer', 'Puppi'), doCorrections = cms.bool(True), correctorFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs_20220308.root"), correctorDir = cms.string('L1PuppiSC4EmuJets')) process.l1tLayer2SeedConeJetWriter = l1tSeededConeJetFileWriter.clone(jets = "l1tLayer2SeedConeJetsCorrected") -process.l1tLayer1Barrel9 = process.l1tLayer1Barrel.clone() -process.l1tLayer1Barrel9.puAlgo.nFinalSort = 32 -process.l1tLayer1Barrel9.regions[0].etaBoundaries = [ -1.5, -0.5, 0.5, 1.5 ] -process.l1tLayer1Barrel9.boards=cms.VPSet( - cms.PSet( - regions=cms.vuint32(*[0+9*ie+i for ie in range(3) for i in range(3)])), - cms.PSet( - regions=cms.vuint32(*[3+9*ie+i for ie in range(3) for i in range(3)])), - cms.PSet( - regions=cms.vuint32(*[6+9*ie+i for ie in range(3) for i in range(3)])), - ) - process.l1tLayer1BarrelTDR = process.l1tLayer1Barrel.clone() process.l1tLayer1BarrelTDR.regionizerAlgo = cms.string("TDR") process.l1tLayer1BarrelTDR.regionizerAlgoParameters = cms.PSet( @@ -115,10 +104,16 @@ process.l1tLayer1BarrelSerenity.puAlgoParameters.nOut = 27 process.l1tLayer1BarrelSerenity.puAlgoParameters.finalSortAlgo = "FoldedHybrid" +if args.serenity: + process.l1tLayer1.pfProducers[0] = "l1tLayer1BarrelSerenity" + process.l1tLayer2EG.tkElectrons[1].pfProducer = "l1tLayer1BarrelSerenity:L1TkElePerBoard" + process.l1tLayer2EG.tkEms[2].pfProducer = "l1tLayer1BarrelSerenity:L1TkEmPerBoard" + from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_patternWriters_cff import * +from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_patternWriters_cff import _eventsPerFile if not args.patternFilesOFF: process.l1tLayer1Barrel.patternWriters = cms.untracked.VPSet(*barrelWriterConfigs) - # process.l1tLayer1Barrel9.patternWriters = cms.untracked.VPSet(*barrel9WriterConfigs) # not enabled for now + process.l1tLayer1BarrelSerenity.patternWriters = cms.untracked.VPSet(barrelSerenityVU9PPhi1Config,barrelSerenityVU13PPhi1Config) process.l1tLayer1HGCal.patternWriters = cms.untracked.VPSet(*hgcalWriterConfigs) process.l1tLayer1HGCalNoTK.patternWriters = cms.untracked.VPSet(*hgcalNoTKWriterConfigs) process.l1tLayer1HF.patternWriters = cms.untracked.VPSet(*hfWriterConfigs) @@ -126,11 +121,11 @@ process.runPF = cms.Path( process.l1tSAMuonsGmt + process.l1tGTTInputProducer + + process.l1tTrackSelectionProducer + process.l1tVertexFinderEmulator + process.l1tLayer1Barrel + process.l1tLayer1BarrelTDR + process.l1tLayer1BarrelSerenity + - process.l1tLayer1Barrel9 + process.l1tLayer1HGCal + process.l1tLayer1HGCalElliptic + process.l1tLayer1HGCalNoTK + @@ -150,26 +145,38 @@ if not args.patternFilesOFF: process.l1tLayer2EG.writeInPattern = True process.l1tLayer2EG.writeOutPattern = True - process.l1tLayer2EG.inPatternFile.maxLinesPerFile = eventsPerFile_*54 - process.l1tLayer2EG.outPatternFile.maxLinesPerFile = eventsPerFile_*54 + process.l1tLayer2EG.inPatternFile.maxLinesPerFile = _eventsPerFile*54 + process.l1tLayer2EG.outPatternFile.maxLinesPerFile = _eventsPerFile*54 ##################################################################################################################### ## Layer 2 seeded-cone jets if not args.patternFilesOFF: process.runPF.insert(process.runPF.index(process.l1tLayer2SeedConeJetsCorrected)+1, process.l1tLayer2SeedConeJetWriter) - process.l1tLayer2SeedConeJetWriter.maxLinesPerFile = eventsPerFile_*54 + process.l1tLayer2SeedConeJetWriter.maxLinesPerFile = _eventsPerFile*54 if not args.dumpFilesOFF: - for det in "Barrel", "BarrelTDR", "BarrelSerenity", "Barrel9", "HGCal", "HGCalElliptic", "HGCalNoTK", "HF": + for det in "Barrel", "BarrelTDR", "BarrelSerenity", "HGCal", "HGCalElliptic", "HGCalNoTK", "HF": l1pf = getattr(process, 'l1tLayer1'+det) l1pf.dumpFileName = cms.untracked.string("TTbar_PU200_"+det+".dump") -process.source.fileNames = [ '/store/cmst3/group/l1tr/gpetrucc/11_1_0/NewInputs110X/110121.done/TTbar_PU200/inputs110X_%d.root' % i for i in (1,3,7,8,9) ] -process.l1tPFClustersFromL1EGClusters.src = cms.InputTag("L1EGammaClusterEmuProducer",) -process.l1tPFClustersFromCombinedCaloHCal.phase2barrelCaloTowers = [cms.InputTag("L1EGammaClusterEmuProducer",)] -process.l1tPFClustersFromHGC3DClusters.src = cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering") -process.l1tPFClustersFromCombinedCaloHF.hcalCandidates = [ cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering")] -process.l1tPFTracksFromL1Tracks.L1TrackTag = cms.InputTag("TTTracksFromTrackletEmulation","Level1TTTracks") -process.l1tGTTInputProducer.l1TracksInputTag = cms.InputTag("TTTracksFromTrackletEmulation","Level1TTTracks") - +if args.tm18: + process.l1tLayer1HGCalTM18 = process.l1tLayer1HGCal.clone() + process.l1tLayer1HGCalTM18.regionizerAlgo = "BufferedFoldedMultififo" + process.l1tLayer1HGCalTM18.regionizerAlgoParameters.nClocks = 162 + process.l1tLayer1HGCalTM18.regionizerAlgoParameters.nTkLinks = 1 + process.l1tLayer1HGCalTM18.regionizerAlgoParameters.nCaloLinks = 1 + process.l1tLayer1HGCalNoTKTM18 = process.l1tLayer1HGCalNoTK.clone() + process.l1tLayer1HGCalNoTKTM18.regionizerAlgo = "BufferedFoldedMultififo" + process.l1tLayer1HGCalNoTKTM18.regionizerAlgoParameters.nClocks = 162 + process.l1tLayer1HGCalNoTKTM18.regionizerAlgoParameters.nCaloLinks = 1 + process.runPF.insert(process.runPF.index(process.l1tLayer1HGCal)+1, process.l1tLayer1HGCalTM18) + process.runPF.insert(process.runPF.index(process.l1tLayer1HGCalNoTK)+1, process.l1tLayer1HGCalNoTKTM18) + if not args.patternFilesOFF: + process.l1tLayer1HGCalTM18.patternWriters = cms.untracked.VPSet(*hgcalTM18WriterConfigs) + process.l1tLayer1HGCalNoTKTM18.patternWriters = cms.untracked.VPSet(hgcalNoTKOutputTM18WriterConfig) + if not args.dumpFilesOFF: + for det in "HGCalTM18", "HGCalNoTKTM18": + getattr(process, 'l1tLayer1'+det).dumpFileName = cms.untracked.string("TTbar_PU200_"+det+".dump") + +process.source.fileNames = [ '/store/cmst3/group/l1tr/gpetrucc/12_5_X/NewInputs125X/150223/TTbar_PU200/inputs125X_1.root' ] diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py index 08cfe713e3133..8241ce1e31c2f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py @@ -31,10 +31,8 @@ process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_cff') process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer2EG_cff') process.load('L1Trigger.L1TTrackMatch.l1tGTTInputProducer_cfi') +process.load('L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi') process.load('L1Trigger.VertexFinder.l1tVertexProducer_cfi') -process.l1tVertexFinderEmulator = process.l1tVertexProducer.clone() -process.l1tVertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" -process.l1tVertexFinderEmulator.l1TracksInputTag = cms.InputTag("l1tGTTInputProducer", "Level1TTTracksConverted") from L1Trigger.Phase2L1GMT.gmt_cfi import l1tStandaloneMuons process.l1tSAMuonsGmt = l1tStandaloneMuons.clone() @@ -70,6 +68,7 @@ process.runPF = cms.Path( process.l1tSAMuonsGmt + process.l1tGTTInputProducer + + process.l1tTrackSelectionProducer + process.l1tVertexFinderEmulator + process.l1tLayer1Barrel + #process.l1tLayer1Barrel9 + diff --git a/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.cc b/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.cc index aaf0060d73161..331aa1c239230 100644 --- a/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.cc +++ b/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.cc @@ -230,7 +230,7 @@ void HPSPFTauProducer::fillDescriptions(edm::ConfigurationDescriptions& descript desc.add("maxSeedChargedPFCandEta", 2.4); desc.add("applyPreselection", false); desc.add("isolationConeSize", 0.4); - desc.add("srcL1Vertices", edm::InputTag("l1tVertexFinderEmulator", "l1verticesEmulation")); + desc.add("srcL1Vertices", edm::InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation")); desc.add("maxChargedIso", 1000.0); { edm::ParameterSetDescription psd0; diff --git a/L1Trigger/Phase2L1Taus/python/l1emulator_cff.py b/L1Trigger/Phase2L1Taus/python/l1emulator_cff.py index 40d3022377c6a..ccf7ba9eb5eac 100644 --- a/L1Trigger/Phase2L1Taus/python/l1emulator_cff.py +++ b/L1Trigger/Phase2L1Taus/python/l1emulator_cff.py @@ -24,6 +24,9 @@ TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag( cms.InputTag(L1TRK_NAME, L1TRK_LABEL) ) l1emulator += TrackTriggerAssociatorTracks +from L1Trigger.L1TTrackMatch.l1tTrackSelectionProducer_cfi import * +l1emulator += l1tTrackSelectionProducer + from L1Trigger.VertexFinder.l1tVertexProducer_cfi import * l1emulator += l1tVertexProducer diff --git a/L1Trigger/VertexFinder/interface/VertexProducer.h b/L1Trigger/VertexFinder/interface/VertexProducer.h index f9d683ff0334a..5f4d93bcc74ee 100644 --- a/L1Trigger/VertexFinder/interface/VertexProducer.h +++ b/L1Trigger/VertexFinder/interface/VertexProducer.h @@ -1,8 +1,9 @@ #ifndef __L1Trigger_VertexFinder_VertexProducer_h__ #define __L1Trigger_VertexFinder_VertexProducer_h__ +#include "DataFormats/Common/interface/Ptr.h" +#include "DataFormats/Common/interface/RefToPtr.h" #include "DataFormats/L1Trigger/interface/Vertex.h" -#include "FWCore/Framework/interface/global/EDProducer.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "DataFormats/L1Trigger/interface/VertexWord.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" @@ -33,12 +34,15 @@ class VertexProducer : public edm::global::EDProducer<> { ~VertexProducer() override {} private: - typedef edm::View> TTTrackCollectionView; + typedef TTTrack TTTrackType; + typedef std::vector TTTrackCollectionType; + typedef edm::RefVector TTTrackRefCollectionType; + typedef edm::View TTTrackCollectionView; void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; private: - const edm::EDGetTokenT l1TracksToken_; + const edm::EDGetTokenT l1TracksToken_; const edm::ESGetToken tTopoToken; const std::string outputCollectionName_; diff --git a/L1Trigger/VertexFinder/plugins/VertexProducer.cc b/L1Trigger/VertexFinder/plugins/VertexProducer.cc index 3fe3288bf9dd2..eee1b8522e8bb 100644 --- a/L1Trigger/VertexFinder/plugins/VertexProducer.cc +++ b/L1Trigger/VertexFinder/plugins/VertexProducer.cc @@ -2,7 +2,7 @@ #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "DataFormats/L1Trigger/interface/Vertex.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" -#include "FWCore/Framework/interface/EDProducer.h" +#include "FWCore/Framework/interface/global/EDProducer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -17,7 +17,7 @@ using namespace l1tVertexFinder; using namespace std; VertexProducer::VertexProducer(const edm::ParameterSet& iConfig) - : l1TracksToken_(consumes(iConfig.getParameter("l1TracksInputTag"))), + : l1TracksToken_(consumes(iConfig.getParameter("l1TracksInputTag"))), tTopoToken(esConsumes()), outputCollectionName_(iConfig.getParameter("l1VertexCollectionName")), settings_(AlgoSettings(iConfig)) { @@ -68,7 +68,7 @@ VertexProducer::VertexProducer(const edm::ParameterSet& iConfig) } void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { - edm::Handle l1TracksHandle; + edm::Handle l1TracksHandle; iEvent.getByToken(l1TracksToken_, l1TracksHandle); std::vector l1Tracks; @@ -76,11 +76,8 @@ void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Event if (settings_.debug() > 1) { edm::LogInfo("VertexProducer") << "produce::Processing " << l1TracksHandle->size() << " tracks"; } - for (const auto& track : l1TracksHandle->ptrs()) { - auto l1track = L1Track(track); - // Check the minimum pT of the tracks - // This is left here because it represents the smallest pT to be sent by the track finding boards - // This has less to do with the algorithms than the constraints of what will be sent to the vertexing algorithm + for (const auto& track : *l1TracksHandle) { + auto l1track = L1Track(edm::refToPtr(track)); if (l1track.pt() >= settings_.vx_TrackMinPt()) { l1Tracks.push_back(l1track); } else { @@ -90,6 +87,7 @@ void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Event } } } + if (settings_.debug() > 1) { edm::LogInfo("VertexProducer") << "produce::Processing " << l1Tracks.size() << " tracks after minimum pt cut of" << settings_.vx_TrackMinPt() << " GeV"; diff --git a/L1Trigger/VertexFinder/python/l1tVertexNTupler_cfi.py b/L1Trigger/VertexFinder/python/l1tVertexNTupler_cfi.py index 1710cbed7ec96..c8409705f7fc2 100644 --- a/L1Trigger/VertexFinder/python/l1tVertexNTupler_cfi.py +++ b/L1Trigger/VertexFinder/python/l1tVertexNTupler_cfi.py @@ -8,7 +8,7 @@ l1TracksTPInputTags = cms.InputTag("l1tTPStubValueMapProducer:allMatchedTPs"), l1TracksTPValueMapInputTags = cms.InputTag("l1tTPStubValueMapProducer:TPs"), l1TracksBranchNames = cms.vstring('hybrid'), - l1VertexInputTags = cms.VInputTag( cms.InputTag("l1tVertexProducer", "l1vertices") ), + l1VertexInputTags = cms.VInputTag( cms.InputTag("l1tVertexProducer", "L1Vertices") ), l1VertexTrackInputs = cms.vstring('hybrid'), l1VertexBranchNames = cms.vstring('fastHisto'), emulationVertexInputTags = cms.VInputTag(), diff --git a/L1Trigger/VertexFinder/python/l1tVertexProducer_cfi.py b/L1Trigger/VertexFinder/python/l1tVertexProducer_cfi.py index c425c1bfa9a9d..682246189ed49 100644 --- a/L1Trigger/VertexFinder/python/l1tVertexProducer_cfi.py +++ b/L1Trigger/VertexFinder/python/l1tVertexProducer_cfi.py @@ -1,10 +1,9 @@ import FWCore.ParameterSet.Config as cms -l1tVertexProducer = cms.EDProducer('VertexProducer', - - l1TracksInputTag = cms.InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks"), - - l1VertexCollectionName = cms.string("l1vertices"), +l1tVertexProducer = cms.EDProducer('VertexProducer', + l1TracksInputTag = cms.InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelected"), + + l1VertexCollectionName = cms.string("L1Vertices"), #Emulation postfix is appended when fastHistoEmulation is chosen as the algorithm # === Vertex Reconstruction configuration VertexReconstruction = cms.PSet( @@ -35,9 +34,9 @@ # TDR settings: [-14.95, 15.0, 0.1] # L1TkPrimaryVertexProducer: [-30.0, 30.0, 0.09983361065] # HLS Firmware: [-14.4, 14.4, 0.4] - # Track word limits (128 binns): [-20.46921512, 20.46921512, 0.31983148625] - # Track word limits (256 binns): [-20.46921512, 20.46921512, 0.159915743125] - FH_HistogramParameters = cms.vdouble(-20.46921512, 20.46921512, 0.31983148625), + # Track word limits (128 binns): [-20.46912512, 20.46912512, 0.31983008] + # Track word limits (256 binns): [-20.46912512, 20.46912512, 0.15991504] + FH_HistogramParameters = cms.vdouble(-20.46912512, 20.46912512, 0.15991504), # The number of vertixes to return (i.e. N windows with the highest combined pT) FH_NVtx = cms.uint32(10), # fastHisto algorithm assumed vertex half-width [cm] @@ -72,3 +71,9 @@ # Debug printout debug = cms.uint32(0) ) + +l1tVertexFinder = l1tVertexProducer.clone() + +l1tVertexFinderEmulator = l1tVertexProducer.clone() +l1tVertexFinderEmulator.VertexReconstruction.Algorithm = cms.string("fastHistoEmulation") +l1tVertexFinderEmulator.l1TracksInputTag = cms.InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelectedEmulation") diff --git a/L1Trigger/VertexFinder/src/VertexFinder.cc b/L1Trigger/VertexFinder/src/VertexFinder.cc index 3e6353d2633f7..d224bf00fd400 100644 --- a/L1Trigger/VertexFinder/src/VertexFinder.cc +++ b/L1Trigger/VertexFinder/src/VertexFinder.cc @@ -634,7 +634,7 @@ namespace l1tVertexFinder { int nbins = std::ceil((settings_->vx_histogram_max() - settings_->vx_histogram_min()) / settings_->vx_histogram_binwidth()); std::vector> hist(nbins); - std::vector> sums(nbins - settings_->vx_windowSize()); + std::vector> sums(nbins - settings_->vx_windowSize() + 1); std::vector bounds(nbins + 1); strided_iota(std::begin(bounds), std::next(std::begin(bounds), nbins + 1), @@ -770,9 +770,9 @@ namespace l1tVertexFinder { }; enum HistogramBitWidths { - kBinSize = 10, // Width of a single bin in z - kBinFixedSize = 7, // Width of a single z0 bin in fixed point representation - kBinFixedMagSize = 4, // Width (magnitude) of a single z0 bin in fixed point representation + kBinSize = 8, // Width of a single bin in z + kBinFixedSize = 8, // Width of a single z0 bin in fixed point representation + kBinFixedMagSize = 5, // Width (magnitude) of a single z0 bin in fixed point representation kSlidingSumSize = 11, // Width of the sum of a window of bins kInverseSize = 14, // Width of the inverse sum kInverseMagSize = 1, // Width of the inverse sum magnitude (unsigned) @@ -780,7 +780,11 @@ namespace l1tVertexFinder { kWeightedSlidingSumMagSize = 10, // Width of the pT weighted sliding sum magnitude (signed) kWindowSize = 3, // Number of bins in the window used to sum histogram bins kSumPtLinkSize = 9, // Number of bits used to represent the sum of track pts in a single bin from a single link + kSumPtWindowBits = BitsToRepresent(HistogramBitWidths::kWindowSize * (1 << HistogramBitWidths::kSumPtLinkSize)), + // Number of bits to represent the untruncated sum of track pts in a single bin from a single link + kSumPtUntruncatedLinkSize = TrackBitWidths::kPtSize + 2, + kSumPtUntruncatedLinkMagSize = TrackBitWidths::kPtMagSize + 2, }; static constexpr unsigned int kTableSize = @@ -798,6 +802,13 @@ namespace l1tVertexFinder { // Histogram bin in fixed point representation, before truncation typedef ap_ufixed histbin_fixed_t; + // This type is slightly arbitrary, but 2 bits larger than untruncated track pt to store sums in histogram bins + // with truncation just before vertex-finding + typedef ap_ufixed + histbin_pt_sum_fixed_t; // This value is slightly arbitrary, but small enough that the windows sums aren't too big. typedef ap_ufixed link_pt_sum_fixed_t; @@ -856,10 +867,9 @@ namespace l1tVertexFinder { auto init_inversion_table = [&]() -> std::vector { std::vector table_out(kTableSize, 0.); for (unsigned int ii = 0; ii < kTableSize; ii++) { - // First, convert from table index to X-value (unsigned 8-bit, range 0 to +1533) - float in_val = 1533.0 * (ii / float(kTableSize)); - // Next, compute lookup table function - table_out.at(ii) = (in_val > 0) ? (1.0 / in_val) : 0.0; + // Compute lookup table function. This matches the format of the GTT HLS code. + // Biased generation f(x) = 1 / (x + 1) is inverted by g(y) = inversion(x - 1) = 1 / (x - 1 + 1) = 1 / y + table_out.at(ii) = (1.0 / (ii + 1)); } return table_out; }; @@ -924,7 +934,9 @@ namespace l1tVertexFinder { } if (maximums != 0) { - inv = inversion(maximums); + //match F/W inversion_lut offset (inversion[x] = 1 / (x + 1); inversion[x - 1] = 1 / x;), for consistency + slidingsum_t offsetmaximums = maximums - 1; + inv = inversion(offsetmaximums); zvtx_sliding = zvtx_sliding_sum * inv; } else { zvtx_sliding = (settings_->vx_windowSize() / 2.0) + (((int(settings_->vx_windowSize()) % 2) != 0) ? 0.5 : 0.0); @@ -953,8 +965,9 @@ namespace l1tVertexFinder { // Create the histogram unsigned int nbins = std::round((settings_->vx_histogram_max() - settings_->vx_histogram_min()) / settings_->vx_histogram_binwidth()); - unsigned int nsums = nbins - settings_->vx_windowSize(); + unsigned int nsums = nbins - settings_->vx_windowSize() + 1; std::vector hist(nbins, 0); + std::vector hist_untruncated(nbins, 0); // Loop over the tracks and fill the histogram if (settings_->debug() > 2) { @@ -963,11 +976,10 @@ namespace l1tVertexFinder { for (const L1Track& track : fitTracks_) { // Get the track pt and z0 // Convert them to an appropriate data format - // Truncation and saturdation taken care of by the data type specification + // Truncation and saturation taken care of by the data type specification, now delayed to end of histogramming pt_t tkpt = 0; tkpt.V = track.getTTTrackPtr()->getTrackWord()(TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB); - track_pt_fixed_t pt_tmp = tkpt; z0_t tkZ0 = track.getTTTrackPtr()->getZ0Word(); if ((settings_->vx_DoQualityCuts() && track_quality_check(tkpt)) || (!settings_->vx_DoQualityCuts())) { @@ -986,16 +998,16 @@ namespace l1tVertexFinder { << "\n" << "tkZ0 = " << tkZ0.to_double() << "(" << tkZ0.to_string(2) << ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2) - << ")\tpt_tmp = " << pt_tmp << "\tbin = " << bin.first.to_int() << "\n" + << ")\tbin = " << bin.first.to_int() << "\n" << "pt sum in bin " << bin.first.to_int() - << " BEFORE adding track = " << hist.at(bin.first).to_double(); + << " BEFORE adding track = " << hist_untruncated.at(bin.first).to_double(); } if (bin.second) { - hist.at(bin.first) = hist.at(bin.first) + pt_tmp; + hist_untruncated.at(bin.first) = hist_untruncated.at(bin.first) + tkpt; } if (settings_->debug() > 2) { edm::LogInfo("VertexProducer") << "fastHistoEmulation::\npt sum in bin " << bin.first.to_int() - << " AFTER adding track = " << hist.at(bin.first).to_double(); + << " AFTER adding track = " << hist_untruncated.at(bin.first).to_double(); } } else { if (settings_->debug() > 2) { @@ -1003,12 +1015,29 @@ namespace l1tVertexFinder { << "track word = " << track.getTTTrackPtr()->getTrackWord().to_string(2) << "\n" << "tkZ0 = " << tkZ0.to_double() << "(" << tkZ0.to_string(2) - << ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2) - << ")\tpt_tmp = " << pt_tmp; + << ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2) << ")"; } } } // end loop over tracks + // HLS histogramming used to truncate track pt before adding, using + // track_pt_fixed_t pt_tmp = tkpt; + // Now, truncation should happen after histograms are filled but prior to the vertex-finding part of the algo + for (unsigned int hb = 0; hb < hist.size(); ++hb) { + link_pt_sum_fixed_t bin_trunc = hist_untruncated.at(hb).range( + HistogramBitWidths::kSumPtUntruncatedLinkSize - 1, + HistogramBitWidths::kSumPtUntruncatedLinkSize - HistogramBitWidths::kSumPtUntruncatedLinkMagSize); + hist.at(hb) = bin_trunc; + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") << "fastHistoEmulation::truncating histogram bin pt once filling is complete \n" + << "hist_untruncated.at(" << hb << ") = " << hist_untruncated.at(hb).to_double() + << "(" << hist_untruncated.at(hb).to_string(2) + << ")\tbin_trunc = " << bin_trunc.to_double() << "(" << bin_trunc.to_string(2) + << ")\n\thist.at(" << hb << ") = " << hist.at(hb).to_double() << "(" + << hist.at(hb).to_string(2) << ")"; + } + } + // Loop through all bins, taking into account the fact that the last bin is nbins-window_width+1, // and compute the sums using sliding windows ... sum_i_i+(w-1) where i in (0,nbins-w) and w is the window size std::vector hist_window_sums(nsums, 0); diff --git a/L1Trigger/VertexFinder/test/vertexNTupler_cfg.py b/L1Trigger/VertexFinder/test/vertexNTupler_cfg.py index 8212c07d3b82b..6f353689979f7 100644 --- a/L1Trigger/VertexFinder/test/vertexNTupler_cfg.py +++ b/L1Trigger/VertexFinder/test/vertexNTupler_cfg.py @@ -107,10 +107,10 @@ producer.l1TracksInputTag = cms.InputTag("l1tGTTInputProducer","Level1TTTracksConverted") producerSum = process.L1GTTInputProducer + producerSum - process.l1tVertexNTupler.emulationVertexInputTags.append( cms.InputTag(producerName, 'l1verticesEmulation') ) + process.l1tVertexNTupler.emulationVertexInputTags.append( cms.InputTag(producerName, 'L1VerticesEmulation') ) process.l1tVertexNTupler.emulationVertexBranchNames.append(algo) else: - process.l1tVertexNTupler.l1VertexInputTags.append( cms.InputTag(producerName, 'l1vertices') ) + process.l1tVertexNTupler.l1VertexInputTags.append( cms.InputTag(producerName, 'L1Vertices') ) process.l1tVertexNTupler.l1VertexBranchNames.append(algo) process.l1tVertexNTupler.l1VertexTrackInputs.append('hybrid') @@ -146,7 +146,7 @@ setattr(process, producerName, producer) producerNames += [producerName] process.l1tVertexNTupler.extraVertexDescriptions += ['DBSCAN(dist={0},minPt={1},minDensity={2},seedTrackPt{3})'.format(dist, minPt, minDensity, seedTrackPt)] - process.l1tVertexNTupler.extraVertexInputTags.append( cms.InputTag(producerName, 'l1vertices')) + process.l1tVertexNTupler.extraVertexInputTags.append( cms.InputTag(producerName, 'L1Vertices')) producerSum += producer print "Total number of producers =", len(additionalProducerAlgorithms)+1