diff --git a/DataFormats/L1TCorrelator/interface/TkElectron.h b/DataFormats/L1TCorrelator/interface/TkElectron.h index 9f1ac1eaeeff0..9d66291cbc939 100644 --- a/DataFormats/L1TCorrelator/interface/TkElectron.h +++ b/DataFormats/L1TCorrelator/interface/TkElectron.h @@ -39,16 +39,19 @@ namespace l1t { float trkzVtx() const { return trkzVtx_; } double trackCurvature() const { return trackCurvature_; } - + float compositeBdtScore() const { return compositeBdtScore_; } // ---------- member functions --------------------------- void setTrkzVtx(float TrkzVtx) { trkzVtx_ = TrkzVtx; } void setTrackCurvature(double trackCurvature) { trackCurvature_ = trackCurvature; } + void setCompositeBdtScore(float score) { compositeBdtScore_ = score; } + private: edm::Ptr trkPtr_; float trkzVtx_; double trackCurvature_; + float compositeBdtScore_; }; } // namespace l1t #endif diff --git a/DataFormats/L1TCorrelator/src/classes_def.xml b/DataFormats/L1TCorrelator/src/classes_def.xml index 0685c6bc1356e..47267dc2b8eaa 100644 --- a/DataFormats/L1TCorrelator/src/classes_def.xml +++ b/DataFormats/L1TCorrelator/src/classes_def.xml @@ -44,7 +44,8 @@ - + + diff --git a/DataFormats/L1TParticleFlow/interface/PFCandidate.h b/DataFormats/L1TParticleFlow/interface/PFCandidate.h index c6d52246a6fa5..567eb6f80b7fb 100644 --- a/DataFormats/L1TParticleFlow/interface/PFCandidate.h +++ b/DataFormats/L1TParticleFlow/interface/PFCandidate.h @@ -48,9 +48,13 @@ namespace l1t { void setZ0(float z0) { setVertex(reco::Particle::Point(0, 0, z0)); } void setDxy(float dxy) { dxy_ = dxy; } + void setCaloEta(float caloeta) { caloEta_ = caloeta; } + void setCaloPhi(float calophi) { caloPhi_ = calophi; } float z0() const { return vz(); } float dxy() const { return dxy_; } + float caloEta() const { return caloEta_; } + float caloPhi() const { return caloPhi_; } int16_t hwZ0() const { return hwZ0_; } int16_t hwDxy() const { return hwDxy_; } @@ -70,7 +74,7 @@ namespace l1t { PFClusterRef clusterRef_; PFTrackRef trackRef_; MuonRef muonRef_; - float dxy_, puppiWeight_; + float dxy_, puppiWeight_, caloEta_, caloPhi_; int16_t hwZ0_, hwDxy_; uint16_t hwTkQuality_, hwPuppiWeight_, hwEmID_; diff --git a/DataFormats/L1TParticleFlow/interface/PFCluster.h b/DataFormats/L1TParticleFlow/interface/PFCluster.h index 1851746b51d19..2272ccbe353db 100644 --- a/DataFormats/L1TParticleFlow/interface/PFCluster.h +++ b/DataFormats/L1TParticleFlow/interface/PFCluster.h @@ -22,10 +22,14 @@ namespace l1t { float ptError = 0, int hwpt = 0, int hweta = 0, - int hwphi = 0) + int hwphi = 0, + float absZBarycenter = 0., + float sigmaRR = 0.) : L1Candidate(PolarLorentzVector(pt, eta, phi, 0), hwpt, hweta, hwphi, /*hwQuality=*/isEM ? 1 : 0), hOverE_(hOverE), - ptError_(ptError) { + ptError_(ptError), + absZBarycenter_(absZBarycenter), + sigmaRR_(sigmaRR) { setPdgId(isEM ? 22 : 130); // photon : non-photon(K0) } PFCluster( @@ -37,6 +41,12 @@ namespace l1t { float hOverE() const { return hOverE_; } void setHOverE(float hOverE) { hOverE_ = hOverE; } + void setSigmaRR(float sigmaRR) { sigmaRR_ = sigmaRR; } + float absZBarycenter() const { return absZBarycenter_; } + + void setAbsZBarycenter(float absZBarycenter) { absZBarycenter_ = absZBarycenter; } + float sigmaRR() const { return sigmaRR_; } + float emEt() const { if (hOverE_ == -1) return 0; @@ -68,6 +78,9 @@ namespace l1t { private: float hOverE_, ptError_, egVsPionMVAOut_, egVsPUMVAOut_; + // HGC dedicated quantities (0ed by default) + float absZBarycenter_, sigmaRR_; + ConstituentsAndFractions constituents_; }; diff --git a/DataFormats/L1TParticleFlow/interface/datatypes.h b/DataFormats/L1TParticleFlow/interface/datatypes.h index f56e7b36c2495..ea97db771bb6b 100644 --- a/DataFormats/L1TParticleFlow/interface/datatypes.h +++ b/DataFormats/L1TParticleFlow/interface/datatypes.h @@ -39,6 +39,12 @@ namespace l1ct { typedef ap_uint<10> em2calo_dr_t; typedef ap_uint<13> tk2calo_dq_t; typedef ap_uint<4> egquality_t; + typedef ap_uint<3> stub_t; + typedef ap_ufixed<10, 1, AP_TRN, AP_SAT> srrtot_t; + typedef ap_uint<8> meanz_t; // mean - SCALE_MEANZ = 320 + typedef ap_ufixed<10, 5, AP_TRN, AP_SAT> hoe_t; + typedef ap_uint<4> redChi2Bin_t; + // FIXME: adjust range 10-11bits -> 1/4 - 1/2TeV is probably more than enough for all reasonable use cases typedef ap_ufixed<11, 9, AP_TRN, AP_SAT> iso_t; @@ -149,6 +155,10 @@ namespace l1ct { constexpr float Z0_LSB = 0.05; constexpr float DXY_LSB = 0.05; constexpr float PUPPIW_LSB = 1.0 / 256; + constexpr float MEANZ_SCALE = 320.; + constexpr float SRRTOT_LSB = 0.0019531250; + constexpr float HOE_LSB = 0.031250000; + inline float floatPt(pt_t pt) { return pt.to_float(); } inline float floatPt(dpt_t pt) { return pt.to_float(); } inline float floatPt(pt2_t pt2) { return pt2.to_float(); } @@ -164,6 +174,9 @@ namespace l1ct { inline float floatDxy(dxy_t dxy) { return dxy.to_float() * DXY_LSB; } inline float floatPuppiW(puppiWgt_t puppiw) { return puppiw.to_float() * PUPPIW_LSB; } inline float floatIso(iso_t iso) { return iso.to_float(); } + inline float floatSrrTot(srrtot_t srrtot) { return srrtot.to_float(); }; + inline float floatMeanZ(meanz_t meanz) { return meanz + MEANZ_SCALE; }; + inline float floatHoe(hoe_t hoe) { return hoe.to_float(); }; inline pt_t makePt(int pt) { return ap_ufixed<16, 14>(pt) >> 2; } inline dpt_t makeDPt(int dpt) { return ap_fixed<18, 16>(dpt) >> 2; } @@ -194,6 +207,9 @@ namespace l1ct { inline iso_t makeIso(float iso) { return iso_t(0.25 * round(iso * 4)); } inline int makeDR2FromFloatDR(float dr) { return ceil(dr * dr / ETAPHI_LSB / ETAPHI_LSB); } + inline srrtot_t makeSrrTot(float var) { return srrtot_t(SRRTOT_LSB * round(var / SRRTOT_LSB)); }; + inline meanz_t makeMeanZ(float var) { return round(var - MEANZ_SCALE); }; + inline hoe_t makeHoe(float var) { return hoe_t(HOE_LSB * round(var / HOE_LSB)); }; inline float maxAbsEta() { return ((1 << (eta_t::width - 1)) - 1) * ETAPHI_LSB; } inline float maxAbsPhi() { return ((1 << (phi_t::width - 1)) - 1) * ETAPHI_LSB; } diff --git a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h index a257ed2efbda6..20eab02e10be1 100644 --- a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h +++ b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h @@ -39,7 +39,7 @@ namespace l1ct { }; struct TkObjEmu : public TkObj { - uint16_t hwChi2, hwStubs; + uint16_t hwChi2; float simPt, simCaloEta, simCaloPhi, simVtxEta, simVtxPhi, simZ0, simD0; const l1t::PFTrack *src; bool read(std::fstream &from); @@ -48,7 +48,6 @@ namespace l1ct { TkObj::clear(); src = nullptr; hwChi2 = 0; - hwStubs = 0; simPt = 0; simCaloEta = 0; simCaloPhi = 0; @@ -196,6 +195,7 @@ namespace l1ct { const l1t::PFTrack *srcTrack; // we use an index to the standalone object needed to retrieve a Ref when putting int sta_idx; + float bdtScore; bool read(std::fstream &from); bool write(std::fstream &to) const; void clear() { @@ -203,6 +203,7 @@ namespace l1ct { srcCluster = nullptr; srcTrack = nullptr; sta_idx = -1; + bdtScore = -999; clearIsoVars(); } @@ -334,7 +335,7 @@ namespace l1ct { }; struct Event { - enum { VERSION = 11 }; + enum { VERSION = 13 }; uint32_t run, lumi; uint64_t event; RawInputs raw; diff --git a/DataFormats/L1TParticleFlow/interface/layer1_objs.h b/DataFormats/L1TParticleFlow/interface/layer1_objs.h index 83765fc4b2b10..ccfca85a645bb 100644 --- a/DataFormats/L1TParticleFlow/interface/layer1_objs.h +++ b/DataFormats/L1TParticleFlow/interface/layer1_objs.h @@ -12,10 +12,13 @@ namespace l1ct { phi_t hwPhi; // relative to the region center, at calo pt_t hwEmPt; emid_t hwEmID; + srrtot_t hwSrrTot; + meanz_t hwMeanZ; + hoe_t hwHoe; inline bool operator==(const HadCaloObj &other) const { return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwEmPt == other.hwEmPt && - hwEmID == other.hwEmID; + hwEmID == other.hwEmID && hwSrrTot == other.hwSrrTot && hwMeanZ == other.hwMeanZ && hwHoe == other.hwHoe; } inline bool operator>(const HadCaloObj &other) const { return hwPt > other.hwPt; } @@ -27,6 +30,9 @@ namespace l1ct { hwPhi = 0; hwEmPt = 0; hwEmID = 0; + hwSrrTot = 0; + hwMeanZ = 0; + hwHoe = 0; } int intPt() const { return Scales::intPt(hwPt); } @@ -37,10 +43,14 @@ namespace l1ct { float floatEmPt() const { return Scales::floatPt(hwEmPt); } float floatEta() const { return Scales::floatEta(hwEta); } float floatPhi() const { return Scales::floatPhi(hwPhi); } + float floatSrrTot() const { return Scales::floatSrrTot(hwSrrTot); }; + float floatMeanZ() const { return Scales::floatMeanZ(hwMeanZ); }; + float floatHoe() const { return Scales::floatHoe(hwHoe); }; bool hwIsEM() const { return hwEmID != 0; } - static const int BITWIDTH = pt_t::width + eta_t::width + phi_t::width + pt_t::width + emid_t::width; + static const int BITWIDTH = pt_t::width + eta_t::width + phi_t::width + pt_t::width + emid_t::width + + srrtot_t::width + meanz_t::width + hoe_t::width; inline ap_uint pack() const { ap_uint ret; unsigned int start = 0; @@ -49,6 +59,9 @@ namespace l1ct { pack_into_bits(ret, start, hwPhi); pack_into_bits(ret, start, hwEmPt); pack_into_bits(ret, start, hwEmID); + pack_into_bits(ret, start, hwSrrTot); + pack_into_bits(ret, start, hwMeanZ); + pack_into_bits(ret, start, hwHoe); return ret; } inline static HadCaloObj unpack(const ap_uint &src) { @@ -59,6 +72,9 @@ namespace l1ct { unpack_from_bits(src, start, ret.hwPhi); unpack_from_bits(src, start, ret.hwEmPt); unpack_from_bits(src, start, ret.hwEmID); + unpack_from_bits(src, start, ret.hwSrrTot); + unpack_from_bits(src, start, ret.hwMeanZ); + unpack_from_bits(src, start, ret.hwHoe); return ret; } }; @@ -70,10 +86,13 @@ namespace l1ct { eta_t hwEta; // relative to the region center, at calo phi_t hwPhi; // relative to the region center, at calo emid_t hwEmID; + srrtot_t hwSrrTot; + meanz_t hwMeanZ; + hoe_t hwHoe; inline bool operator==(const EmCaloObj &other) const { return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwPtErr == other.hwPtErr && - hwEmID == other.hwEmID; + hwEmID == other.hwEmID && hwSrrTot == other.hwSrrTot && hwMeanZ == other.hwMeanZ && hwHoe == other.hwHoe; } inline bool operator>(const EmCaloObj &other) const { return hwPt > other.hwPt; } @@ -85,6 +104,9 @@ namespace l1ct { hwEta = 0; hwPhi = 0; hwEmID = 0; + hwSrrTot = 0; + hwMeanZ = 0; + hwHoe = 0; } int intPt() const { return Scales::intPt(hwPt); } @@ -95,8 +117,12 @@ namespace l1ct { float floatPtErr() const { return Scales::floatPt(hwPtErr); } float floatEta() const { return Scales::floatEta(hwEta); } float floatPhi() const { return Scales::floatPhi(hwPhi); } + float floatSrrTot() const { return Scales::floatSrrTot(hwSrrTot); }; + float floatMeanZ() const { return Scales::floatMeanZ(hwMeanZ); }; + float floatHoe() const { return Scales::floatHoe(hwHoe); }; - static const int BITWIDTH = pt_t::width + eta_t::width + phi_t::width + pt_t::width + emid_t::width; + static const int BITWIDTH = pt_t::width + eta_t::width + phi_t::width + pt_t::width + emid_t::width + + srrtot_t::width + meanz_t::width + hoe_t::width; inline ap_uint pack() const { ap_uint ret; unsigned int start = 0; @@ -105,6 +131,9 @@ namespace l1ct { pack_into_bits(ret, start, hwPhi); pack_into_bits(ret, start, hwPtErr); pack_into_bits(ret, start, hwEmID); + pack_into_bits(ret, start, hwSrrTot); + pack_into_bits(ret, start, hwMeanZ); + pack_into_bits(ret, start, hwHoe); return ret; } inline static EmCaloObj unpack(const ap_uint &src) { @@ -115,6 +144,10 @@ namespace l1ct { unpack_from_bits(src, start, ret.hwPhi); unpack_from_bits(src, start, ret.hwPtErr); unpack_from_bits(src, start, ret.hwEmID); + unpack_from_bits(src, start, ret.hwSrrTot); + unpack_from_bits(src, start, ret.hwMeanZ); + unpack_from_bits(src, start, ret.hwHoe); + return ret; } }; @@ -130,6 +163,11 @@ namespace l1ct { z0_t hwZ0; dxy_t hwDxy; tkquality_t hwQuality; + stub_t hwStubs; + redChi2Bin_t hwRedChi2RZ; // 4 bits + redChi2Bin_t hwRedChi2RPhi; // 4 bits + //FIXME: is this actually filled? 3 bits would be enough + redChi2Bin_t hwRedChi2Bend; // 4 bits enum TkQuality { PFLOOSE = 1, PFTIGHT = 2 }; bool isPFLoose() const { return hwQuality[0]; } @@ -140,7 +178,8 @@ namespace l1ct { inline bool operator==(const TkObj &other) const { return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwDEta == other.hwDEta && hwDPhi == other.hwDPhi && hwZ0 == other.hwZ0 && hwDxy == other.hwDxy && hwCharge == other.hwCharge && - hwQuality == other.hwQuality; + hwQuality == other.hwQuality && hwStubs == other.hwStubs && hwRedChi2RZ == other.hwRedChi2RZ && + hwRedChi2RPhi == other.hwRedChi2RPhi && hwRedChi2Bend == other.hwRedChi2Bend; } inline bool operator>(const TkObj &other) const { return hwPt > other.hwPt; } @@ -156,6 +195,10 @@ namespace l1ct { hwDxy = 0; hwCharge = false; hwQuality = 0; + hwStubs = 0; + hwRedChi2RZ = 0; + hwRedChi2RPhi = 0; + hwRedChi2Bend = 0; } int intPt() const { return Scales::intPt(hwPt); } @@ -175,7 +218,8 @@ namespace l1ct { float floatDxy() const { return Scales::floatDxy(hwDxy); } static const int BITWIDTH = pt_t::width + eta_t::width + phi_t::width + tkdeta_t::width + tkdphi_t::width + 1 + - z0_t::width + dxy_t::width + tkquality_t::width; + z0_t::width + dxy_t::width + tkquality_t::width + stub_t::width + redChi2Bin_t::width + + redChi2Bin_t::width + redChi2Bin_t::width; inline ap_uint pack() const { ap_uint ret; unsigned int start = 0; @@ -188,6 +232,10 @@ namespace l1ct { pack_into_bits(ret, start, hwZ0); pack_into_bits(ret, start, hwDxy); pack_into_bits(ret, start, hwQuality); + pack_into_bits(ret, start, hwStubs); + pack_into_bits(ret, start, hwRedChi2RZ); + pack_into_bits(ret, start, hwRedChi2RPhi); + pack_into_bits(ret, start, hwRedChi2Bend); return ret; } inline static TkObj unpack(const ap_uint &src) { @@ -202,6 +250,10 @@ namespace l1ct { unpack_from_bits(src, start, ret.hwZ0); unpack_from_bits(src, start, ret.hwDxy); unpack_from_bits(src, start, ret.hwQuality); + unpack_from_bits(src, start, ret.hwStubs); + unpack_from_bits(src, start, ret.hwRedChi2RZ); + unpack_from_bits(src, start, ret.hwRedChi2RPhi); + unpack_from_bits(src, start, ret.hwRedChi2Bend); return ret; } }; diff --git a/DataFormats/L1TParticleFlow/src/PFCandidate.cc b/DataFormats/L1TParticleFlow/src/PFCandidate.cc index 964e55687ec86..36907c32df2ad 100644 --- a/DataFormats/L1TParticleFlow/src/PFCandidate.cc +++ b/DataFormats/L1TParticleFlow/src/PFCandidate.cc @@ -5,6 +5,8 @@ l1t::PFCandidate::PFCandidate( : L1Candidate(p, hwpt, hweta, hwphi, /*hwQuality=*/int(kind)), dxy_(0), puppiWeight_(puppiWeight), + caloEta_(0), + caloPhi_(0), hwZ0_(0), hwDxy_(0), hwTkQuality_(0), diff --git a/DataFormats/L1TParticleFlow/src/classes_def.xml b/DataFormats/L1TParticleFlow/src/classes_def.xml index 5f90ab44bb63d..c0ec668e42d2e 100644 --- a/DataFormats/L1TParticleFlow/src/classes_def.xml +++ b/DataFormats/L1TParticleFlow/src/classes_def.xml @@ -1,6 +1,7 @@ - + + @@ -19,7 +20,8 @@ - + + @@ -67,4 +69,3 @@ - diff --git a/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp b/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp index f0b56b1c25022..3f1284413bbf7 100644 --- a/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp +++ b/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp @@ -34,14 +34,14 @@ bool l1ct::EmCaloObjEmu::write(std::fstream& to) const { return writeObj(from, *this) && readVar(from, hwChi2) && readVar(from, hwStubs) && readVar(from, simPt) && - readVar(from, simCaloEta) && readVar(from, simCaloPhi) && readVar(from, simVtxEta) && - readVar(from, simVtxPhi) && readVar(from, simZ0) && readVar(from, simD0); + return readObj(from, *this) && readVar(from, hwChi2) && readVar(from, simPt) && readVar(from, simCaloEta) && + readVar(from, simCaloPhi) && readVar(from, simVtxEta) && readVar(from, simVtxPhi) && readVar(from, simZ0) && + readVar(from, simD0); } bool l1ct::TkObjEmu::write(std::fstream& to) const { - return writeObj(*this, to) && writeVar(hwChi2, to) && writeVar(hwStubs, to) && writeVar(simPt, to) && - writeVar(simCaloEta, to) && writeVar(simCaloPhi, to) && writeVar(simVtxEta, to) && writeVar(simVtxPhi, to) && - writeVar(simZ0, to) && writeVar(simD0, to); + return writeObj(*this, to) && writeVar(hwChi2, to) && writeVar(simPt, to) && writeVar(simCaloEta, to) && + writeVar(simCaloPhi, to) && writeVar(simVtxEta, to) && writeVar(simVtxPhi, to) && writeVar(simZ0, to) && + writeVar(simD0, to); } bool l1ct::MuObjEmu::read(std::fstream& from) { diff --git a/L1Trigger/L1THGCalUtilities/plugins/ntuples/HGCalTriggerNtupleHGCMulticlusters.cc b/L1Trigger/L1THGCalUtilities/plugins/ntuples/HGCalTriggerNtupleHGCMulticlusters.cc index 34c72aa4df886..6a495b3e5e96e 100644 --- a/L1Trigger/L1THGCalUtilities/plugins/ntuples/HGCalTriggerNtupleHGCMulticlusters.cc +++ b/L1Trigger/L1THGCalUtilities/plugins/ntuples/HGCalTriggerNtupleHGCMulticlusters.cc @@ -181,12 +181,12 @@ void HGCalTriggerNtupleHGCMulticlusters::fill(const edm::Event& e, const HGCalTr cl3d_layer_pt_.emplace_back(layer_pt); } - // Retrieve indices of trigger cells inside cluster - cl3d_clusters_id_.emplace_back(cl3d_itr->constituents().size()); - std::transform(cl3d_itr->constituents_begin(), - cl3d_itr->constituents_end(), - cl3d_clusters_id_.back().begin(), - [](const std::pair>& id_cl) { return id_cl.second->detId(); }); + // // Retrieve indices of trigger cells inside cluster + // cl3d_clusters_id_.emplace_back(cl3d_itr->constituents().size()); + // std::transform(cl3d_itr->constituents_begin(), + // cl3d_itr->constituents_end(), + // cl3d_clusters_id_.back().begin(), + // [](const std::pair>& id_cl) { return id_cl.second->detId(); }); } } diff --git a/L1Trigger/Phase2L1ParticleFlow/data/compositeID.json b/L1Trigger/Phase2L1ParticleFlow/data/compositeID.json new file mode 100644 index 0000000000000..d5207a5df03a4 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/data/compositeID.json @@ -0,0 +1 @@ +{"max_depth": 4, "n_trees": 10, "n_classes": 2, "n_features": 10, "trees": [[{"feature": [0, 1, 0, 2, 2, 1, 0, 7, 7, 3, 1, 1, 2, 1, 5, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.078125, 6.375, 0.171875, 0.0029296875, 0.0048828125, 10.625, 0.296875, 13.625, 17.875, 10.5, 36.875, 5.875, 0.0029296875, 9.125, 16.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.0346931517, 0.435883969, -0.559285283, -0.394629419, 0.588079631, -0.554562628, -0.550440431, 0.105620749, -0.548011541, -0.271393329, 0.533511758, 0.0196027886, -0.555460036, -0.20581615, -0.545141757, -0.597242296], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [0, 1, 0, 2, 2, 1, 5, 3, 7, 3, 1, 2, 2, 1, 1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.078125, 7.625, 0.203125, 0.0029296875, 0.0029296875, 9.875, 19.5, -6.5, 18.875, -10.5, 15.875, 0.0029296875, 0.0029296875, 10.375, 49.25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.287821323, 0.279561549, -0.438109398, -0.284507036, -0.496723443, 0.463173628, -0.110402688, 0.408169329, -0.156323507, -0.425076902, 0.408051938, -0.029376477, -0.432124108, -0.0886833891, -0.462875575, -0.249756515], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [0, 1, 0, 2, 2, 1, 0, 3, 7, 3, 1, 7, 2, 2, 1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.078125, 9.125, 0.203125, 0.0029296875, 0.0029296875, 8.375, 0.421875, 7.5, 22.125, 10.5, 20.875, 31.625, 0.0029296875, 0.0029296875, 5.625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.251400441, -0.382646173, -0.369759053, -0.189072713, 0.401628137, -0.414337307, 0.0466323867, 0.375292629, -0.373206437, -0.114594132, 0.33987537, -0.0458339825, -0.0837149173, -0.372966707, -0.403597027, -0.395437241], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [0, 1, 5, 2, 2, 1, 1, 3, 7, 2, 0, 7, 2, 5, 0, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.109375, 9.875, 19.5, 0.0029296875, 0.0048828125, 7.625, 33.625, -7.5, 17.875, 0.0029296875, 0.015625, 31.375, 0.0029296875, 22.5, 0.484375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.319117695, 0.203186303, -0.326289624, -0.140005887, 0.365609556, 0.239198551, -0.250760943, -0.504288733, -0.348215073, -0.183860049, 0.340074927, -0.0966066122, -0.336261004, -0.367752582, 0.158031642, -0.323690653], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [0, 1, 1, 5, 6, 5, 5, 7, 5, 1, 6, 1, 5, 4, 1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.046875, 4.875, 14.625, 14.5, -10.5, 18.5, 21.5, 110.25, 24.5, 15.375, 9.5, 5.125, 21.5, 0.875, 34.875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.337250501, 0.0333464593, 0.136750802, -0.517995358, -0.369201928, 0.240907267, 0.340516388, -0.129052043, -0.309370518, -0.0476103425, -0.297872573, -0.34534353, 0.29169783, -0.156954423, -0.328685343, -0.0667880774], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [0, 1, 0, 2, 2, 1, 0, 3, 3, 5, 1, 7, 2, 2, 0, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.109375, 12.125, 0.296875, 0.0029296875, 0.0029296875, 6.625, 0.421875, 5.5, -4.5, 26.5, 23.625, 25.875, 0.0048828125, 0.0029296875, 0.578125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.190712884, -0.260112375, -0.344277024, -0.143385604, 0.329174787, -0.631823301, 0.00465062493, 0.299573749, -0.301214039, -0.11696256, 0.0814454108, -0.362270325, -0.038969487, -0.29261294, -0.312097639, -0.332171798], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [0, 1, 0, 7, 6, 1, 0, 5, 3, 2, 6, 7, 2, 2, 0, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.046875, 11.625, 0.265625, 22.625, -7.5, 5.875, 0.421875, 15.5, -7.5, 0.0029296875, 6.5, 16.625, 0.0029296875, 0.0029296875, 0.578125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.203315035, 0.0597705357, -0.333177835, 0.240727827, 0.185267359, -0.291025013, 0.318895489, 0.127784654, -0.288417011, -0.113826856, 0.223361507, -0.068100743, -0.00587132573, -0.265845954, -0.29394269, -0.321429193], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [0, 1, 5, 3, 5, 1, 1, 3, 0, 2, 1, 7, 3, 5, 0, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.046875, 14.875, 19.5, 6.5, 26.5, 4.875, 33.375, -5.5, 0.015625, 0.0029296875, 22.625, 17.625, -7.5, 25.5, 0.703125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.187546685, 0.191446036, -0.105438367, -0.346857011, 0.312934309, 0.216284767, -1.04561698, 0.178618178, -0.280277967, -0.105060332, -0.370037019, 0.112582333, -0.249790415, -0.314210504, 0.228648365, -0.283507437], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [1, 0, 5, 2, 0, 2, 1, 6, 3, 7, 5, 3, 6, 4, 4, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [17.625, 0.328125, 23.5, 0.0029296875, 0.453125, 0.0029296875, 49.25, 12.5, 7.5, 20.625, 19.5, 11.5, -5.5, 0.625, 1.875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.140260428, -0.234142423, -0.0984049514, -0.316746235, -0.268205643, 0.00539158285, -0.273065537, -0.308457315, 0.306505382, -0.415359676, -0.316766709, 0.183405831, -0.0757411942, -0.340209842, 0.299729317, -0.324592829], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}], [{"feature": [0, 1, 5, 7, 1, 3, 1, 0, 3, 4, 6, 8, 3, 7, 0, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2], "threshold": [0.046875, 16.125, 21.5, 11.125, 25.125, -6.5, 33.375, 0.015625, 8.5, 1.125, 3.5, 142.5, 5.5, 33.875, 0.703125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "children_left": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "children_right": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1], "value": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0291854218, -0.200783119, 0.161875248, -0.272349954, 0.224006355, -1.3098768, 0.30716297, 0.233704045, -0.326755196, -0.0891666412, 0.116110913, -0.270737797, -0.299332291, -0.201232493, 0.103073023, -0.260977447], "parent": [-1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14], "depth": [0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], "iLeaf": [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]}]], "init_predict": [0, 0], "norm": 1} \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/common/inversion.h b/L1Trigger/Phase2L1ParticleFlow/interface/common/inversion.h new file mode 100644 index 0000000000000..1e12217261065 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/common/inversion.h @@ -0,0 +1,60 @@ +#ifndef CC_INVERSION_H__ +#define CC_INVERSION_H__ + +constexpr int ceillog2(int x) { return (x <= 2) ? 1 : 1 + ceillog2((x + 1) / 2); } + +template +inline float real_val_from_idx(unsigned i) { + // Treat the index as the top N bits + static constexpr int NB = ceillog2(N); // number of address bits for table + data_T x(0); + // The MSB of 1 is implicit in the table + x[x.width - 1] = 1; + // So we can use the next NB bits for real data + x(x.width - 2, x.width - NB - 1) = i; + return (float)x; +} + +template +inline unsigned idx_from_real_val(data_T x) { + // Slice the top N bits to get an index into the table + static constexpr int NB = ceillog2(N); // number of address bits for table + // Slice the top-1 NB bits of the value + // the MSB of '1' is implicit, so only slice below that + ap_uint y = x(x.width - 2, x.width - NB - 1); + return (unsigned)y(NB - 1, 0); +} + +template +void init_invert_table(table_T table_out[N]) { + // The template data_T is the data type used to address the table + for (unsigned i = 0; i < N; i++) { + float x = real_val_from_idx(i); + table_T inv_x = 1 / x; + table_out[i] = inv_x; + } +} + +template +table_t invert_with_shift(in_t in) { + table_t inv_table[N]; + init_invert_table(inv_table); + + // find the first '1' in the denominator + int msb = 0; + for (int b = 0; b < in.width; b++) { +#pragma HLS unroll + if (in[b]) + msb = b; + } + // shift up the denominator such that the left-most bit (msb) is '1' + in_t in_shifted = in << (in.width - msb - 1); + // lookup the inverse of the shifted input + int idx = idx_from_real_val(in_shifted); + table_t inv_in = inv_table[idx]; + // shift the output back + table_t out = inv_in << (in.width - msb - 1); + return out; +} + +#endif \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/conifer.h b/L1Trigger/Phase2L1ParticleFlow/interface/conifer.h index 61ee6d89b9e85..75b6bd0fc5bae 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/conifer.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/conifer.h @@ -1,6 +1,6 @@ #ifndef CONIFER_CPP_H__ #define CONIFER_CPP_H__ -#include "FWCore/Utilities/interface/Exception.h" +//#include "FWCore/Utilities/interface/Exception.h" #include "nlohmann/json.hpp" #include @@ -115,18 +115,19 @@ namespace conifer { std::vector decision_function(std::vector x) const { /* Do the prediction */ - if (x.size() != n_features) { - throw cms::Exception("RuntimeError") - << "Conifer : Size of feature vector mismatches expected n_features" << std::endl; - } + //if (x.size() != n_features) { + // throw cms::Exception("RuntimeError") + // << "Conifer : Size of feature vector mismatches expected n_features" << std::endl; + //} std::vector values; std::vector> values_trees; values_trees.resize(n_classes); values.resize(n_classes, U(0)); for (unsigned int i = 0; i < n_classes; i++) { - std::transform(trees.begin(), trees.end(), std::back_inserter(values_trees.at(i)), [&i, &x](auto tree_v) { - return tree_v.at(i).decision_function(x); - }); + std::transform(trees.begin(), + trees.end(), + std::back_inserter(values_trees.at(i)), + [&i, &x](std::vector> tree_v) { return tree_v.at(i).decision_function(x); }); if (useAddTree) { values.at(i) = init_predict_.at(i); values.at(i) += reduce>(values_trees.at(i), add); @@ -152,4 +153,4 @@ namespace conifer { } // namespace conifer -#endif \ No newline at end of file +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h index b75be595ee9df..3b850524a05a1 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h @@ -4,6 +4,8 @@ #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" #include "DataFormats/L1TParticleFlow/interface/egamma.h" #include "DataFormats/L1TParticleFlow/interface/pf.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/conifer.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/inversion.h" namespace edm { class ParameterSet; @@ -30,6 +32,8 @@ namespace l1ct { std::vector dEtaValues; std::vector dPhiValues; float trkQualityPtMin; // GeV + bool doCompositeTkEle; + unsigned int nCOMPCAND_PER_CLUSTER; bool writeEgSta; struct IsoParameters { @@ -53,6 +57,18 @@ namespace l1ct { bool doPfIso; EGIsoEleObjEmu::IsoType hwIsoTypeTkEle; EGIsoObjEmu::IsoType hwIsoTypeTkEm; + + //bool doCompositeTkEle; + struct CompIDParameters { + CompIDParameters(const edm::ParameterSet &); + CompIDParameters(double BDTcut_wp97p5, double BDTcut_wp95p0) + : BDTcut_wp97p5(BDTcut_wp97p5), BDTcut_wp95p0(BDTcut_wp95p0) {} + double BDTcut_wp97p5; + double BDTcut_wp95p0; + }; + + CompIDParameters compIDparams; + int debug = 0; PFTkEGAlgoEmuConfig(const edm::ParameterSet &iConfig); @@ -72,6 +88,8 @@ namespace l1ct { const std::vector &dEtaValues = {0.015, 0.01}, const std::vector &dPhiValues = {0.07, 0.07}, float trkQualityPtMin = 10., + bool doCompositeTkEle = false, + unsigned int nCompCandPerCluster = 4, bool writeEgSta = false, const IsoParameters &tkIsoParams_tkEle = {2., 0.6, 0.03, 0.2}, const IsoParameters &tkIsoParams_tkEm = {2., 0.6, 0.07, 0.3}, @@ -81,6 +99,8 @@ namespace l1ct { bool doPfIso = false, EGIsoEleObjEmu::IsoType hwIsoTypeTkEle = EGIsoEleObjEmu::IsoType::TkIso, EGIsoObjEmu::IsoType hwIsoTypeTkEm = EGIsoObjEmu::IsoType::TkIsoPV, + // FIXME: maybe we round these? + const CompIDParameters &myCompIDparams = {0.7927004, 0.9826955}, int debug = 0) : nTRACK(nTrack), @@ -95,10 +115,15 @@ namespace l1ct { emClusterPtMin(emClusterPtMin), dEtaMaxBrem(dEtaMaxBrem), dPhiMaxBrem(dPhiMaxBrem), + //absEtaBoundaries(std::move(absEtaBoundaries)), + //dEtaValues(std::move(dEtaValues)), + //dPhiValues(std::move(dPhiValues)), absEtaBoundaries(absEtaBoundaries), dEtaValues(dEtaValues), dPhiValues(dPhiValues), trkQualityPtMin(trkQualityPtMin), + doCompositeTkEle(doCompositeTkEle), + nCOMPCAND_PER_CLUSTER(nCompCandPerCluster), writeEgSta(writeEgSta), tkIsoParams_tkEle(tkIsoParams_tkEle), tkIsoParams_tkEm(tkIsoParams_tkEm), @@ -108,12 +133,13 @@ namespace l1ct { doPfIso(doPfIso), hwIsoTypeTkEle(hwIsoTypeTkEle), hwIsoTypeTkEm(hwIsoTypeTkEm), + compIDparams(myCompIDparams), debug(debug) {} }; class PFTkEGAlgoEmulator { public: - PFTkEGAlgoEmulator(const PFTkEGAlgoEmuConfig &config) : cfg(config), debug_(cfg.debug) {} + PFTkEGAlgoEmulator(const PFTkEGAlgoEmuConfig &config); virtual ~PFTkEGAlgoEmulator() {} @@ -135,10 +161,27 @@ namespace l1ct { private: void link_emCalo2emCalo(const std::vector &emcalo, std::vector &emCalo2emCalo) const; - void link_emCalo2tk(const PFRegionEmu &r, - const std::vector &emcalo, - const std::vector &track, - std::vector &emCalo2tk) const; + void link_emCalo2tk_elliptic(const PFRegionEmu &r, + const std::vector &emcalo, + const std::vector &track, + std::vector &emCalo2tk) const; + + void link_emCalo2tk_composite(const PFRegionEmu &r, + const std::vector &emcalo, + const std::vector &track, + std::vector &emCalo2tk, + std::vector &emCaloTkBdtScore) const; + + struct CompositeCandidate { + unsigned int cluster_idx; + unsigned int track_idx; + double dpt; // For sorting + }; + + float compute_composite_score(CompositeCandidate &cand, + const std::vector &emcalo, + const std::vector &track, + const PFTkEGAlgoEmuConfig::CompIDParameters ¶ms) const; //FIXME: still needed float deltaPhi(float phi1, float phi2) const; @@ -152,6 +195,7 @@ namespace l1ct { const std::vector &track, const std::vector &emCalo2emCalo, const std::vector &emCalo2tk, + const std::vector &emCaloTkBdtScore, std::vector &egstas, std::vector &egobjs, std::vector &egeleobjs) const; @@ -165,6 +209,7 @@ namespace l1ct { const unsigned int hwQual, const pt_t ptCorr, const int tk_idx, + const float bdtScore, const std::vector &components = {}) const; EGObjEmu &addEGStaToPF(std::vector &egobjs, @@ -182,7 +227,8 @@ namespace l1ct { const EmCaloObjEmu &calo, const TkObjEmu &track, const unsigned int hwQual, - const pt_t ptCorr) const; + const pt_t ptCorr, + const float bdtScore) const; // FIXME: reimplemented from PFAlgoEmulatorBase template @@ -309,6 +355,7 @@ namespace l1ct { z0_t z0) const; PFTkEGAlgoEmuConfig cfg; + conifer::BDT, ap_fixed<12, 3, AP_RND_CONV, AP_SAT>, false> *composite_bdt_; int debug_; }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h index 585156036ca9a..eb3f2f3f19173 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h @@ -151,6 +151,15 @@ namespace l1ct { const std::vector &tanlLUT() const { return tanlLUT_; } const std::vector &ptLUT() const { return ptLUT_; } + unsigned int countSetBits(unsigned int n) const { + unsigned int count = 0; + while (n) { + n &= (n - 1); + count++; + } + return count; + } + protected: // utilities template diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index e173c3c773bdb..77acecb32eb7e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -38,6 +38,7 @@ #include "DataFormats/L1Trigger/interface/EGamma.h" #include "DataFormats/L1TCorrelator/interface/TkEm.h" #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" +#include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" //-------------------------------------------------------------------------------------------------- class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { @@ -72,7 +73,6 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { std::unique_ptr l1tkegalgo_; std::unique_ptr l1tkegsorter_; - bool writeEgSta_; // Region dump const std::string regionDumpName_; bool writeRawHgcalCluster_; @@ -114,6 +114,7 @@ class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { std::unique_ptr fetchEmCalo() const; std::unique_ptr fetchTracks() const; std::unique_ptr fetchPF() const; + std::unique_ptr> fetchDecodedTracks() const; void putPuppi(edm::Event &iEvent) const; void putEgStaObjects(edm::Event &iEvent, @@ -175,6 +176,9 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet #if 0 // LATER produces("TKVtx"); #endif +#ifdef PUT_DECODED_TK + produces>("DecodedTK"); +#endif for (const auto &tag : iConfig.getParameter>("emClusters")) { emCands_.push_back(consumes(tag)); @@ -361,6 +365,10 @@ void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSe iEvent.put(fetchHadCalo(), "Calo"); iEvent.put(fetchTracks(), "TK"); +#ifdef PUT_DECODED_TK + iEvent.put(fetchDecodedTracks(), "DecodedTK"); +#endif + // Then do the vertexing, and save it out std::vector z0s; std::vector> ptsums; @@ -633,7 +641,6 @@ void L1TCorrelatorLayer1Producer::addDecodedTrack(l1ct::DetectorSector> &sec, const l1t::PFCluster &c) { ap_uint<256> cwrd = 0; - ap_uint<14> w_pt = round(c.pt() / 0.25); + ap_ufixed<14, 12, AP_RND_CONV, AP_SAT> w_pt = c.pt(); ap_uint<14> w_empt = round(c.emEt() / 0.25); constexpr float ETAPHI_LSB = M_PI / 720; ap_int<9> w_eta = round(sec.region.localEta(c.eta()) / ETAPHI_LSB); ap_int<9> w_phi = round(sec.region.localPhi(c.phi()) / ETAPHI_LSB); ap_uint<10> w_qual = c.hwQual(); - cwrd(13, 0) = w_pt; + ap_uint<13> w_srrtot = round(c.sigmaRR() / l1ct::Scales::SRRTOT_LSB); + ap_uint<12> w_meanz = round(c.absZBarycenter()); + // FIXME: the calibration can actually make hoe become negative....we add a small protection for now + // We use ap_ufixed to handle saturation and rounding + ap_ufixed<10, 5, AP_RND_CONV, AP_SAT> w_hoe = c.hOverE(); + + cwrd(13, 0) = w_pt.range(); cwrd(27, 14) = w_empt; cwrd(72, 64) = w_eta; cwrd(81, 73) = w_phi; cwrd(115, 106) = w_qual; + // FIXME: we add the variables use by composite-ID. The definitin will have to be reviewd once the + // hgc format is better defined. For now we use + // hwMeanZ = word 1 bits 30-19 + // hwSrrTot = word 3 bits 21 - 9 + // hoe = word 1 bits 63-52 (currently spare) + cwrd(213, 201) = w_srrtot; + cwrd(94, 83) = w_meanz; + + // std::cout << "[addRawHgcalCluster] meanz IN: " << c.absZBarycenter() << " OUT: " << w_meanz << std::endl; + // std::cout << " hoe IN: " << c.hOverE() << " OUT: " << w_hoe << std::endl; + // std::cout << " hwSrrTot IN: " << c.sigmaRR() << " OUT: " << w_srrtot << std::endl; + // std::cout << " . eta: " << w_eta << " phi: " << w_phi << std::endl; + // FIXME: we use a spare space in the word for hoe which is not in the current interface + cwrd(127, 116) = w_hoe.range(); + sec.obj.push_back(cwrd); } void L1TCorrelatorLayer1Producer::addDecodedEmCalo(l1ct::DetectorSector &sec, const l1t::PFCluster &c) { l1ct::EmCaloObjEmu calo; + // set the endcap-sepcific variables to default value: + calo.clear(); calo.hwPt = l1ct::Scales::makePtFromFloat(c.pt()); calo.hwEta = l1ct::Scales::makeGlbEta(c.eta()) - sec.region.hwEtaCenter; // important to enforce that the region boundary is on a discrete value @@ -838,6 +876,37 @@ std::unique_ptr L1TCorrelatorLayer1Producer::fetchTr return ret; } +std::unique_ptr> L1TCorrelatorLayer1Producer::fetchDecodedTracks() const { + auto ret = std::make_unique>(); + for (const auto &r : event_.decoded.track) { + const auto ® = r.region; + for (const auto &p : r.obj) { + if (p.hwPt == 0 || !reg.isFiducial(p)) + continue; + reco::Particle::PolarLorentzVector p4( + p.floatPt(), reg.floatGlbEta(p.hwVtxEta()), reg.floatGlbPhi(p.hwVtxPhi()), 0); + + reco::Particle::Point vtx(0, 0, p.floatZ0()); + + ret->emplace_back(l1t::PFTrack(p.intCharge(), + reco::Particle::LorentzVector(p4), + vtx, + p.src->track(), + 0, + reg.floatGlbEta(p.hwEta), + reg.floatGlbPhi(p.hwPhi), + -1, + -1, + p.hwQuality.to_int(), + false, + p.intPt(), + p.intEta(), + p.intPhi())); + } + } + return ret; +} + std::unique_ptr L1TCorrelatorLayer1Producer::fetchPF() const { auto ret = std::make_unique(); for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) { @@ -858,6 +927,9 @@ std::unique_ptr L1TCorrelatorLayer1Producer::fetchPF ret->back().setHwZ0(p.hwZ0); ret->back().setHwDxy(p.hwDxy); ret->back().setHwTkQuality(p.hwTkQuality); + ret->back().setCaloEta(reg.floatGlbEtaOf(p)); + ret->back().setCaloPhi(reg.floatGlbPhiOf(p)); + setRefs_(ret->back(), p); } for (const auto &p : event_.out[ir].pfneutral) { @@ -868,6 +940,8 @@ std::unique_ptr L1TCorrelatorLayer1Producer::fetchPF p.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron; ret->emplace_back(type, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi()); ret->back().setHwEmID(p.hwEmID); + ret->back().setCaloEta(reg.floatGlbEtaOf(p)); + ret->back().setCaloPhi(reg.floatGlbPhiOf(p)); setRefs_(ret->back(), p); } } @@ -1039,6 +1113,7 @@ void L1TCorrelatorLayer1Producer::putEgObjects(edm::Event &iEvent, tkele.setHwQual(egele.hwQual); tkele.setPFIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PfIso)); tkele.setEgBinaryWord(egele.pack()); + tkele.setCompositeBdtScore(egele.bdtScore); tkeles->push_back(tkele); nele_obj.push_back(tkeles->size() - 1); } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc index 7d393fe347bd9..0a76d751f90c0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc @@ -129,7 +129,8 @@ void l1tpf::PFClusterProducerFromHGC3DClusters::produce(edm::Event &iEvent, cons //float em_old = cluster.emEt(); float em_new = it->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM); float pt_new = had_old + em_new; - float hoe_new = em_new > 0 ? (had_old / em_new) : -1; + // FIXME: -1 can be a problem for later stages of the processing. For now we set it to something which saturates the hoe variable + float hoe_new = em_new > 0 ? (had_old / em_new) : 999; cluster = l1t::PFCluster(pt_new, it->eta(), it->phi(), hoe_new, /*isEM=*/isEM); //printf("Scenario %d: pt %7.2f eta %+5.3f em %7.2f, EMI %7.2f, h/e % 8.3f --> pt %7.2f, em %7.2f, h/e % 8.3f\n", // 2, pt, it->eta(), em_old, em_new, hoe, cluster.pt(), cluster.emEt(), cluster.hOverE()); @@ -156,6 +157,10 @@ void l1tpf::PFClusterProducerFromHGC3DClusters::produce(edm::Event &iEvent, cons corrector_.correctPt(cluster); cluster.setPtError(resol_(cluster.pt(), std::abs(cluster.eta()))); + // We se the cluster shape variables used downstream + cluster.setAbsZBarycenter(fabs(it->zBarycenter())); + cluster.setSigmaRR(it->sigmaRRTot()); + out->push_back(cluster); out->back().addConstituent(edm::Ptr(multiclusters, multiclusters->key(it))); if (hasEmId_) { diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py index 3d1621b655d56..2f941d652a651 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py @@ -50,7 +50,13 @@ doTkIso=cms.bool(True), doPfIso=cms.bool(True), hwIsoTypeTkEle=cms.uint32(0), - hwIsoTypeTkEm=cms.uint32(2) + hwIsoTypeTkEm=cms.uint32(2), + doCompositeTkEle=cms.bool(False), + nCOMPCAND_PER_CLUSTER=cms.uint32(3), + compositeParametersTkEle=cms.PSet( # Parameters used to normalize input features + BDTcut_wp97p5=cms.double(0.7927004), + BDTcut_wp95p0=cms.double(0.9826955), + ), ) tkEgSorterParameters = cms.PSet( diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 134223d2ae8e3..ebe7d8b796d05 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -261,7 +261,9 @@ doBremRecovery=True, doEndcapHwQual=True, writeBeforeBremRecovery=False, - writeEGSta=True), + writeEGSta=True, + doCompositeTkEle=True, + trkQualityPtMin=0.), # This should be 10 GeV when doCompositeTkEle=False tkEgSorterParameters=tkEgSorterParameters.clone( nObjToSort = 5 ), diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pfeginput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pfeginput_ref.cpp index 71716e7f542c2..560e0eb96df7f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pfeginput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pfeginput_ref.cpp @@ -31,6 +31,10 @@ void EGInputSelectorEmulator::select_eginput(const l1ct::HadCaloObjEmu &in, out.hwPtErr = 0; // shift to get rid of PFEM ID bit (more usable final EG quality) out.hwEmID = (in.hwEmID >> 1); + + out.hwSrrTot = in.hwSrrTot; + out.hwMeanZ = in.hwMeanZ; + out.hwHoe = in.hwHoe; valid_out = (in.hwEmID & cfg.idMask) != 0; } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp index 2fc881879455d..aebebe59f83df 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp @@ -7,6 +7,10 @@ #include #include #include +#include + +// #include "DataFormats/L1TParticleFlow/interface/PFTrack.h" +// #include "DataFormats/L1TParticleFlow/interface/PFCluster.h" using namespace l1ct; @@ -30,6 +34,8 @@ l1ct::PFTkEGAlgoEmuConfig::PFTkEGAlgoEmuConfig(const edm::ParameterSet &pset) dEtaValues(pset.getParameter>("dEtaValues")), dPhiValues(pset.getParameter>("dPhiValues")), trkQualityPtMin(pset.getParameter("trkQualityPtMin")), + doCompositeTkEle(pset.getParameter("doCompositeTkEle")), + nCOMPCAND_PER_CLUSTER(pset.getParameter("nCOMPCAND_PER_CLUSTER")), writeEgSta(pset.getParameter("writeEGSta")), tkIsoParams_tkEle(pset.getParameter("tkIsoParametersTkEle")), tkIsoParams_tkEm(pset.getParameter("tkIsoParametersTkEm")), @@ -39,6 +45,7 @@ l1ct::PFTkEGAlgoEmuConfig::PFTkEGAlgoEmuConfig(const edm::ParameterSet &pset) doPfIso(pset.getParameter("doPfIso")), hwIsoTypeTkEle(static_cast(pset.getParameter("hwIsoTypeTkEle"))), hwIsoTypeTkEm(static_cast(pset.getParameter("hwIsoTypeTkEm"))), + compIDparams(pset.getParameter("compositeParametersTkEle")), debug(pset.getUntrackedParameter("debug", 0)) {} l1ct::PFTkEGAlgoEmuConfig::IsoParameters::IsoParameters(const edm::ParameterSet &pset) @@ -47,8 +54,26 @@ l1ct::PFTkEGAlgoEmuConfig::IsoParameters::IsoParameters(const edm::ParameterSet pset.getParameter("dRMin"), pset.getParameter("dRMax")) {} +l1ct::PFTkEGAlgoEmuConfig::CompIDParameters::CompIDParameters(const edm::ParameterSet &pset) + : CompIDParameters(pset.getParameter("BDTcut_wp97p5"), pset.getParameter("BDTcut_wp95p0")) {} + #endif +PFTkEGAlgoEmulator::PFTkEGAlgoEmulator(const PFTkEGAlgoEmuConfig &config) + : cfg(config), composite_bdt_(nullptr), debug_(cfg.debug) { + if (cfg.doCompositeTkEle) { + //FIXME: make the name of the file configurable +#ifdef CMSSW_GIT_HASH + auto resolvedFileName = edm::FileInPath("L1Trigger/Phase2L1ParticleFlow/data/compositeID.json").fullPath(); +#else + auto resolvedFileName = "compositeID.json"; +#endif + composite_bdt_ = + new conifer::BDT, ap_fixed<12, 3, AP_RND_CONV, AP_SAT>, false>( + resolvedFileName); + } +} + void PFTkEGAlgoEmulator::toFirmware(const PFInputRegion &in, PFRegion ®ion, EmCaloObj emcalo[/*nCALO*/], @@ -109,10 +134,10 @@ void PFTkEGAlgoEmulator::link_emCalo2emCalo(const std::vector &emc } } -void PFTkEGAlgoEmulator::link_emCalo2tk(const PFRegionEmu &r, - const std::vector &emcalo, - const std::vector &track, - std::vector &emCalo2tk) const { +void PFTkEGAlgoEmulator::link_emCalo2tk_elliptic(const PFRegionEmu &r, + const std::vector &emcalo, + const std::vector &track, + std::vector &emCalo2tk) const { unsigned int nTrackMax = std::min(track.size(), cfg.nTRACK_EGIN); for (int ic = 0, nc = emcalo.size(); ic < nc; ++ic) { auto &calo = emcalo[ic]; @@ -146,6 +171,100 @@ void PFTkEGAlgoEmulator::link_emCalo2tk(const PFRegionEmu &r, } } +void PFTkEGAlgoEmulator::link_emCalo2tk_composite(const PFRegionEmu &r, + const std::vector &emcalo, + const std::vector &track, + std::vector &emCalo2tk, + std::vector &emCaloTkBdtScore) const { + unsigned int nTrackMax = std::min(track.size(), cfg.nTRACK_EGIN); + for (int ic = 0, nc = emcalo.size(); ic < nc; ++ic) { + auto &calo = emcalo[ic]; + + std::vector candidates; + + for (unsigned int itk = 0; itk < nTrackMax; ++itk) { + const auto &tk = track[itk]; + if (tk.floatPt() <= cfg.trkQualityPtMin) + continue; + + float d_phi = deltaPhi(tk.floatPhi(), calo.floatPhi()); + float d_eta = tk.floatEta() - calo.floatEta(); // We only use it squared + float dR = sqrt((d_phi * d_phi) + (d_eta * d_eta)); + + if (dR < 0.2) { + // Only store indices, dR and dpT for now. The other quantities are computed only for the best nCandPerCluster. + CompositeCandidate cand; + cand.cluster_idx = ic; + cand.track_idx = itk; + cand.dpt = fabs(tk.floatPt() - calo.floatPt()); + candidates.push_back(cand); + } + } + // FIXME: find best sort criteria, for now we use dpt + std::sort(candidates.begin(), + candidates.end(), + [](const CompositeCandidate &a, const CompositeCandidate &b) -> bool { return a.dpt < b.dpt; }); + unsigned int nCandPerCluster = std::min(candidates.size(), cfg.nCOMPCAND_PER_CLUSTER); + if (nCandPerCluster == 0) + continue; + + float bdtWP_MVA = cfg.compIDparams.BDTcut_wp97p5; + float bdtWP_XGB = + 1. / (1. + std::sqrt((1. - bdtWP_MVA) / (1. + bdtWP_MVA))); // Convert WP value from ROOT.TMVA to XGboost + float maxScore = -999; + int ibest = -1; + for (unsigned int icand = 0; icand < nCandPerCluster; icand++) { + auto &cand = candidates[icand]; + const std::vector &emcalo_sel = emcalo; + float score = compute_composite_score(cand, emcalo_sel, track, cfg.compIDparams); + if (score > maxScore) { + // if((score > bdtWP_XGB) && (score > maxScore)) { + maxScore = score; + ibest = icand; + } + } + if (ibest != -1) { + emCalo2tk[ic] = candidates[ibest].track_idx; + emCaloTkBdtScore[ic] = maxScore; + } + } +} + +float PFTkEGAlgoEmulator::compute_composite_score(CompositeCandidate &cand, + const std::vector &emcalo, + const std::vector &track, + const PFTkEGAlgoEmuConfig::CompIDParameters ¶ms) const { + // Get the cluster/track objects that form the composite candidate + const auto &calo = emcalo[cand.cluster_idx]; + const auto &tk = track[cand.track_idx]; + + // Call and normalize input feature values, then cast to ap_fixed. + // Note that for some features (e.g. track pT) we call the floating point representation, but that's already quantized! + // Several other features, such as chi2 or most cluster features, are not quantized before casting them to ap_fixed. + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> hoe = calo.hwHoe; + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> tkpt = tk.hwPt; + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> srrtot = calo.hwSrrTot; + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> deta = tk.hwEta - calo.hwEta; + ap_fixed<18, 9> calo_invPt = invert_with_shift, 1024>(calo.hwPt); // TODO: this is a guess + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> dpt = tk.hwPt * calo_invPt; + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> meanz = calo.hwMeanZ; + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> dphi = tk.hwPhi - calo.hwPhi; + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> chi2 = tk.hwRedChi2RPhi; + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> tkz0 = tk.hwZ0; + ap_fixed<21, 12, AP_RND_CONV, AP_SAT> nstubs = tk.hwStubs; + + // Run BDT inference + std::vector> inputs = { + hoe, tkpt, srrtot, deta, dpt, meanz, dphi, chi2, tkz0, nstubs}; + std::vector> bdt_score = composite_bdt_->decision_function(inputs); + + float bdt_score_CON = bdt_score[0]; + float bdt_score_XGB = 1 / (1 + exp(-bdt_score_CON)); // Map Conifer score to XGboost score. (same as scipy.expit) + + // std::cout<<"BDT score of composite candidate = "< &emcalo, std::vector &emcalo_sel) const { @@ -171,7 +290,6 @@ void PFTkEGAlgoEmulator::run(const PFInputRegion &in, OutputRegion &out) const { << std::endl; } } - // FIXME: can be removed in the endcap since now running with the "interceptor". // Might still be needed in barrel // filter and select first N elements of input clusters @@ -183,12 +301,18 @@ void PFTkEGAlgoEmulator::run(const PFInputRegion &in, OutputRegion &out) const { link_emCalo2emCalo(emcalo_sel, emCalo2emCalo); std::vector emCalo2tk(emcalo_sel.size(), -1); - link_emCalo2tk(in.region, emcalo_sel, in.track, emCalo2tk); + std::vector emCaloTkBdtScore(emcalo_sel.size(), -999); + + if (cfg.doCompositeTkEle) { + link_emCalo2tk_composite(in.region, emcalo_sel, in.track, emCalo2tk, emCaloTkBdtScore); + } else { + link_emCalo2tk_elliptic(in.region, emcalo_sel, in.track, emCalo2tk); + } out.egsta.clear(); std::vector egobjs; std::vector egeleobjs; - eg_algo(in.region, emcalo_sel, in.track, emCalo2emCalo, emCalo2tk, out.egsta, egobjs, egeleobjs); + eg_algo(in.region, emcalo_sel, in.track, emCalo2emCalo, emCalo2tk, emCaloTkBdtScore, out.egsta, egobjs, egeleobjs); unsigned int nEGOut = std::min(cfg.nEM_EGOUT, egobjs.size()); unsigned int nEGEleOut = std::min(cfg.nEM_EGOUT, egeleobjs.size()); @@ -205,6 +329,7 @@ void PFTkEGAlgoEmulator::eg_algo(const PFRegionEmu ®ion, const std::vector &track, const std::vector &emCalo2emCalo, const std::vector &emCalo2tk, + const std::vector &emCaloTkBdtScore, std::vector &egstas, std::vector &egobjs, std::vector &egeleobjs) const { @@ -220,6 +345,7 @@ void PFTkEGAlgoEmulator::eg_algo(const PFRegionEmu ®ion, << " phi " << calo.hwPhi << std::endl; int itk = emCalo2tk[ic]; + float bdt = emCaloTkBdtScore[ic]; // check if brem recovery is on if (!cfg.doBremRecovery || cfg.writeBeforeBremRecovery) { @@ -232,7 +358,7 @@ void PFTkEGAlgoEmulator::eg_algo(const PFRegionEmu ®ion, egQual = calo.hwEmID | 0x8; } - addEgObjsToPF(egstas, egobjs, egeleobjs, emcalo, track, ic, egQual, calo.hwPt, itk); + addEgObjsToPF(egstas, egobjs, egeleobjs, emcalo, track, ic, egQual, calo.hwPt, itk, bdt); } if (!cfg.doBremRecovery) @@ -255,7 +381,7 @@ void PFTkEGAlgoEmulator::eg_algo(const PFRegionEmu ®ion, // 2. create EG objects with brem recovery // NOTE: duplicating the object is suboptimal but this is done for keeping things as in TDR code... - addEgObjsToPF(egstas, egobjs, egeleobjs, emcalo, track, ic, calo.hwEmID, ptBremReco, itk, components); + addEgObjsToPF(egstas, egobjs, egeleobjs, emcalo, track, ic, calo.hwEmID, ptBremReco, itk, bdt, components); } } @@ -309,7 +435,8 @@ EGIsoEleObjEmu &PFTkEGAlgoEmulator::addEGIsoEleToPF(std::vector const EmCaloObjEmu &calo, const TkObjEmu &track, const unsigned int hwQual, - const pt_t ptCorr) const { + const pt_t ptCorr, + const float bdtScore) const { EGIsoEleObjEmu egiso; egiso.clear(); egiso.hwPt = ptCorr; @@ -328,6 +455,7 @@ EGIsoEleObjEmu &PFTkEGAlgoEmulator::addEGIsoEleToPF(std::vector egiso.hwCharge = track.hwCharge; egiso.srcCluster = calo.src; egiso.srcTrack = track.src; + egiso.bdtScore = bdtScore; egobjs.push_back(egiso); if (debug_ > 2) @@ -346,6 +474,7 @@ void PFTkEGAlgoEmulator::addEgObjsToPF(std::vector &egstas, const unsigned int hwQual, const pt_t ptCorr, const int tk_idx, + const float bdtScore, const std::vector &components) const { int sta_idx = -1; if (writeEgSta()) { @@ -355,7 +484,7 @@ void PFTkEGAlgoEmulator::addEgObjsToPF(std::vector &egstas, EGIsoObjEmu &egobj = addEGIsoToPF(egobjs, emcalo[calo_idx], hwQual, ptCorr); egobj.sta_idx = sta_idx; if (tk_idx != -1) { - EGIsoEleObjEmu &eleobj = addEGIsoEleToPF(egeleobjs, emcalo[calo_idx], track[tk_idx], hwQual, ptCorr); + EGIsoEleObjEmu &eleobj = addEGIsoEleToPF(egeleobjs, emcalo[calo_idx], track[tk_idx], hwQual, ptCorr, bdtScore); eleobj.sta_idx = sta_idx; } } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/hgcalinputt_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/hgcalinputt_ref.cpp index d1777586ca753..719b73ca92684 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/hgcalinputt_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/hgcalinputt_ref.cpp @@ -8,6 +8,10 @@ l1ct::HadCaloObjEmu l1ct::HgcalClusterDecoderEmulator::decode(const ap_uint<256> ap_int<9> w_eta = in(72, 64); ap_int<9> w_phi = in(81, 73); ap_uint<10> w_qual = in(115, 106); + ap_uint<13> w_srrtot = in(213, 201); + ap_uint<12> w_meanz = in(94, 83); + // FIXME: we use a spare space in the word for hoe which is not in the current interface + ap_uint<12> w_hoe = in(127, 116); l1ct::HadCaloObjEmu out; out.clear(); @@ -17,5 +21,12 @@ l1ct::HadCaloObjEmu l1ct::HgcalClusterDecoderEmulator::decode(const ap_uint<256> out.hwEmPt = w_empt * l1ct::pt_t(l1ct::Scales::INTPT_LSB); out.hwEmID = w_qual; + // FIXME: variables use by composite-ID need to be added here + out.hwSrrTot = w_srrtot * l1ct::srrtot_t(l1ct::Scales::SRRTOT_LSB); + out.hwMeanZ = l1ct::meanz_t(w_meanz - l1ct::Scales::MEANZ_SCALE); + out.hwHoe = hoe_t(w_hoe * l1ct::Scales::HOE_LSB); + + // std::cout << "[HadCaloObjEmu] meanz in: " << w_meanz << " out: " << out.hwMeanZ << std::endl; + return out; } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/tkinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/tkinput_ref.cpp index 4f707e49cc3cc..f01a3eaf03e76 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/tkinput_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/tkinput_ref.cpp @@ -162,7 +162,6 @@ std::pair l1ct::TrackInputEmulator::decodeTrack(ap_uint<96 fDEta = floatDEtaHGCal(z0, Rinv, tanl); fDPhi = floatDPhiHGCal(z0, Rinv, tanl); } - ret.hwDPhi = std::round(fDPhi); ret.hwDEta = std::round(fDEta); ret.hwPhi = std::round(fvtxPhi - fDPhi * ret.intCharge()); @@ -171,6 +170,11 @@ std::pair l1ct::TrackInputEmulator::decodeTrack(ap_uint<96 ret.hwZ0 = l1ct::Scales::makeZ0(floatZ0(z0)); } + ap_uint<7> w_hitPattern = tkword(15, 9); + ret.hwStubs = countSetBits(w_hitPattern); + ret.hwRedChi2RZ = tkword(35, 32); + ret.hwRedChi2RPhi = tkword(67, 64); + ret.hwRedChi2Bend = tkword(18, 16); oksel = ret.hwQuality != 0; } return std::make_pair(ret, oksel);