diff --git a/DataFormats/L1TParticleFlow/interface/PFJet.h b/DataFormats/L1TParticleFlow/interface/PFJet.h index 301fd1a36ff76..e1cfc282659c0 100644 --- a/DataFormats/L1TParticleFlow/interface/PFJet.h +++ b/DataFormats/L1TParticleFlow/interface/PFJet.h @@ -3,6 +3,7 @@ #include #include "DataFormats/L1Trigger/interface/L1Candidate.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" #include "DataFormats/Common/interface/Ptr.h" namespace l1t { @@ -10,7 +11,7 @@ namespace l1t { class PFJet : public L1Candidate { public: /// constituent information. note that this is not going to be available in the hardware! - typedef std::vector> Constituents; + typedef std::vector> Constituents; PFJet() {} PFJet(float pt, float eta, float phi, float mass = 0, int hwpt = 0, int hweta = 0, int hwphi = 0) @@ -28,13 +29,13 @@ namespace l1t { /// constituent information. note that this is not going to be available in the hardware! const Constituents& constituents() const { return constituents_; } /// adds a candidate to this cluster; note that this only records the information, it's up to you to also set the 4-vector appropriately - void addConstituent(const edm::Ptr& cand) { constituents_.emplace_back(cand); } + void addConstituent(const edm::Ptr& cand) { constituents_.emplace_back(cand); } // candidate interface size_t numberOfDaughters() const override { return constituents_.size(); } const reco::Candidate* daughter(size_type i) const override { return constituents_[i].get(); } using reco::LeafCandidate::daughter; // avoid hiding the base - edm::Ptr daughterPtr(size_type i) const { return constituents_[i]; } + edm::Ptr daughterPtr(size_type i) const { return constituents_[i]; } // Get and set the encodedJet_ bits. The Jet is encoded in 128 bits as a 2-element array of uint64_t std::array encodedJet() { return encodedJet_; } diff --git a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h index d725a00e3908d..8262d6b645940 100644 --- a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h +++ b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h @@ -175,18 +175,20 @@ namespace l1ct { hwIsoVars[1] = 0; hwIsoVars[2] = 0; hwIsoVars[3] = 0; + hwIsoVars[4] = 0; + hwIsoVars[5] = 0; } using EGIsoObj::floatIso; - enum IsoType { TkIso = 0, PfIso = 1, TkIsoPV = 2, PfIsoPV = 3 }; + enum IsoType { TkIso = 0, PfIso = 1, TkIsoPV = 2, PfIsoPV = 3, PuppiIso = 4, PuppiIsoPV = 5 }; float floatIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]); } float floatRelIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]) / floatPt(); } float hwIsoVar(IsoType type) const { return hwIsoVars[type]; } void setHwIso(IsoType type, iso_t value) { hwIsoVars[type] = value; } - iso_t hwIsoVars[4]; + iso_t hwIsoVars[6]; }; struct EGIsoEleObjEmu : public EGIsoEleObj { @@ -207,18 +209,19 @@ namespace l1ct { void clearIsoVars() { hwIsoVars[0] = 0; hwIsoVars[1] = 0; + hwIsoVars[2] = 0; } using EGIsoEleObj::floatIso; - enum IsoType { TkIso = 0, PfIso = 1 }; + enum IsoType { TkIso = 0, PfIso = 1, PuppiIso = 2 }; float floatIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]); } float floatRelIso(IsoType type) const { return Scales::floatIso(hwIsoVars[type]) / floatPt(); } float hwIsoVar(IsoType type) const { return hwIsoVars[type]; } void setHwIso(IsoType type, iso_t value) { hwIsoVars[type] = value; } - iso_t hwIsoVars[2]; + iso_t hwIsoVars[3]; }; struct PVObjEmu : public PVObj { diff --git a/DataFormats/L1TParticleFlow/src/classes_def.xml b/DataFormats/L1TParticleFlow/src/classes_def.xml index b1ed9da86adda..5f90ab44bb63d 100644 --- a/DataFormats/L1TParticleFlow/src/classes_def.xml +++ b/DataFormats/L1TParticleFlow/src/classes_def.xml @@ -33,7 +33,8 @@ - + + diff --git a/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py b/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py index 271baa788fe79..6399f341f7984 100644 --- a/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py +++ b/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py @@ -199,6 +199,8 @@ def _appendPhase2Digis(obj): 'keep *_l1tPFTracksFromL1TracksHGCal_*_*', 'keep *_l1tSCPFL1PuppiCorrectedEmulator_*_*', 'keep *_l1tSCPFL1PuppiCorrectedEmulatorMHT_*_*', + 'keep *_l1tSCPFL1PuppiExtendedCorrectedEmulator_*_*', + 'keep *_l1tSCPFL1PuppiExtendedCorrectedEmulatorMHT_*_*', 'keep *_l1tPhase1JetProducer9x9_*_*', 'keep *_l1tPhase1JetCalibrator9x9_*_*', 'keep *_l1tPhase1JetSumsProducer9x9_*_*', @@ -210,6 +212,9 @@ def _appendPhase2Digis(obj): 'keep *_l1tLayer1HGCalNoTK_*_*', 'keep *_l1tLayer1HF_*_*', 'keep *_l1tLayer1_*_*', + 'keep *_l1tLayer1BarrelExtended_*_*', + 'keep *_l1tLayer1HGCalExtended_*_*', + 'keep *_l1tLayer1Extended_*_*', 'keep *_l1tLayer1EG_*_*', 'keep *_l1tLayer2EG_*_*', 'keep *_l1tMETPFProducer_*_*', @@ -217,6 +222,8 @@ def _appendPhase2Digis(obj): 'keep *_l1tNNTauProducerPuppi_*_*', 'keep *_l1tHPSPFTauProducerPF_*_*', 'keep *_l1tHPSPFTauProducerPuppi_*_*', + 'keep *_l1tBJetProducerPuppi_*_*', + 'keep *_l1tBJetProducerPuppiCorrectedEmulator_*_*', 'keep *_TTStubsFromPhase2TrackerDigis_*_*', 'keep *_TTClustersFromPhase2TrackerDigis_*_*', 'keep *_l1tTTTracksFromExtendedTrackletEmulation_*_*', diff --git a/L1Trigger/Configuration/python/SimL1Emulator_cff.py b/L1Trigger/Configuration/python/SimL1Emulator_cff.py index 9da727a5074aa..17600bf2e63a9 100644 --- a/L1Trigger/Configuration/python/SimL1Emulator_cff.py +++ b/L1Trigger/Configuration/python/SimL1Emulator_cff.py @@ -218,6 +218,13 @@ from L1Trigger.Phase2L1ParticleFlow.L1NNTauProducer_cff import * _phase2_siml1emulator.add(l1tNNTauProducerPuppi) + +# BJets +# ######################################################################## +from L1Trigger.Phase2L1ParticleFlow.L1BJetProducer_cff import * +_phase2_siml1emulator.add(L1TBJetsTask) + + # --> add modules from Configuration.Eras.Modifier_phase2_trigger_cff import phase2_trigger phase2_trigger.toReplaceWith( SimL1EmulatorTask , _phase2_siml1emulator) diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/BJetId.h b/L1Trigger/Phase2L1ParticleFlow/interface/BJetId.h new file mode 100644 index 0000000000000..cffbafce13e9c --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/BJetId.h @@ -0,0 +1,42 @@ +#ifndef L1TRIGGER_PHASE2L1PARTICLEFLOWS_BJETID_H +#define L1TRIGGER_PHASE2L1PARTICLEFLOWS_BJETID_H + +#include +#include "PhysicsTools/TensorFlow/interface/TensorFlow.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" + +struct BJetTFCache { + BJetTFCache(const std::string &graphPath) : graphDef(tensorflow::loadGraphDef(graphPath)) { + session = tensorflow::createSession(graphDef.get()); + } + ~BJetTFCache() { tensorflow::closeSession(session); } + std::unique_ptr graphDef; + tensorflow::Session *session; +}; + +class BJetId { +public: + BJetId(const std::string &iInput, const std::string &iOutput, const BJetTFCache *cache, int iNParticles); + ~BJetId(); + + void setNNVectorVar(); + float EvaluateNN(); + float compute(const l1t::PFJet &iJet, float vz, bool useRawPt); + +private: + std::vector NNvectorVar_; + std::string fInput_; + std::string fOutput_; + int fNParticles_; + unique_ptr fPt_; + unique_ptr fEta_; + unique_ptr fPhi_; + unique_ptr fId_; + unique_ptr fCharge_; + unique_ptr fDZ_; + unique_ptr fDX_; + unique_ptr fDY_; + tensorflow::Session *sessionRef_; +}; +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h b/L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h index 64f0a663b14c2..4dc5618f83ec8 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h @@ -101,6 +101,9 @@ namespace l1tpf_calo { T &operator()(float eta, float phi) { return data_[grid_->find_cell(eta, phi)]; } const T &operator()(float eta, float phi) const { return data_[grid_->find_cell(eta, phi)]; } + float eta(float eta, float phi) const { return grid().eta(grid_->find_cell(eta, phi)); } + float phi(float eta, float phi) const { return grid().phi(grid_->find_cell(eta, phi)); } + const Grid &grid() const { return *grid_; } unsigned int size() const { return data_.size(); } @@ -146,6 +149,7 @@ namespace l1tpf_calo { std::vector data_; const T empty_; }; + typedef GridData EtaPhiCenterGrid; typedef GridData EtGrid; typedef GridData IndexGrid; @@ -169,9 +173,11 @@ namespace l1tpf_calo { struct CombinedCluster : public Cluster { float ecal_et, hcal_et; + float ecal_eta, ecal_phi; void clear() { Cluster::clear(); ecal_et = hcal_et = 0; + ecal_eta = ecal_phi = 0; } }; @@ -183,7 +189,16 @@ namespace l1tpf_calo { ~SingleCaloClusterer(); void clear(); void add(const reco::Candidate &c) { add(c.pt(), c.eta(), c.phi()); } - void add(float pt, float eta, float phi) { rawet_(eta, phi) += pt; } + void add(float pt, float eta, float phi) { + rawet_(eta, phi) += pt; + if (preciseEtaPhi_) { + float newet = rawet_(eta, phi); + float prevw = (newet - pt) / newet; + float nextw = pt / newet; + eta_center_(eta, phi) = eta_center_(eta, phi) * prevw + eta * nextw; + phi_center_(eta, phi) = phi_center_(eta, phi) * prevw + phi * nextw; + } + } void run(); /// possibly grow clusters by adding unclustered energy on the sides @@ -191,6 +206,8 @@ namespace l1tpf_calo { void grow(); const EtGrid &raw() const { return rawet_; } + const EtaPhiCenterGrid &etaCenter() const { return eta_center_; } + const EtaPhiCenterGrid &phiCenter() const { return phi_center_; } const IndexGrid &indexGrid() const { return clusterIndex_; } const std::vector &clusters() const { return clusters_; } const Cluster &cluster(int i) const { @@ -199,6 +216,8 @@ namespace l1tpf_calo { /// non-const access to the energy: be careful to use it only before 'run()' EtGrid &raw() { return rawet_; } + EtaPhiCenterGrid &etaCenter() { return eta_center_; } + EtaPhiCenterGrid &phiCenter() { return phi_center_; } // for the moment, generic interface that takes a cluster and returns the corrected pt template @@ -223,13 +242,20 @@ namespace l1tpf_calo { }; /* if there's more than one local maximum neighbour, they all take half of the value (no fp division) */ const Grid *grid_; EtGrid rawet_, unclustered_; + EtaPhiCenterGrid eta_center_; + EtaPhiCenterGrid phi_center_; PreClusterGrid precluster_; IndexGrid clusterIndex_, cellKey_; + bool preciseEtaPhi_; + std::vector etaBounds_; + std::vector phiBounds_; + std::vector maxClustersEtaPhi_; //eta x phi std::vector clusters_; const Cluster nullCluster_; float zsEt_, seedEt_, minClusterEt_, minEtToGrow_; EnergyShareAlgo energyShareAlgo_; bool energyWeightedPosition_; // do the energy-weighted cluster position instead of the cell center + std::vector neighborCells_; }; class SimpleCaloLinkerBase { @@ -262,6 +288,9 @@ namespace l1tpf_calo { const SingleCaloClusterer &ecal_, &hcal_; IndexGrid clusterIndex_; std::vector clusters_; + std::vector etaBounds_; + std::vector phiBounds_; + std::vector maxClustersEtaPhi_; //eta x phi float hoeCut_, minPhotonEt_, minHadronRawEt_, minHadronEt_; bool noEmInHGC_; }; @@ -287,6 +316,31 @@ namespace l1tpf_calo { SingleCaloClusterer combClusterer_; }; + class CombinedCaloLinker : public SimpleCaloLinkerBase { + public: + CombinedCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal); + ~CombinedCaloLinker() override; + void clear() override; + void run() override; + + protected: + SingleCaloClusterer combClusterer_; + }; + + class GridSelector { + public: + GridSelector(std::vector etaBounds, std::vector phiBounds, std::vector maxClusters); + ~GridSelector() {} + void fill(float pt, float eta, float phi, unsigned int index); + std::vector returnSorted(); + + private: + const std::vector etaBounds_; + const std::vector phiBounds_; + const std::vector maxClustersEtaPhi_; + std::vector>> regionPtIndices_; //pt and index pairs in each region + }; + // makes a calo linker (pointer will be owned by the callee) std::unique_ptr makeCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/conifer.h b/L1Trigger/Phase2L1ParticleFlow/interface/conifer.h new file mode 100644 index 0000000000000..eb258b6088127 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/conifer.h @@ -0,0 +1,155 @@ +#ifndef L1TRIGGER_PHASE2L1PARTICLEFLOW_CONNIFER_H +#define L1TRIGGER_PHASE2L1PARTICLEFLOW_CONNIFER_H +#include "FWCore/Utilities/interface/Exception.h" +#include "nlohmann/json.hpp" +#include + +namespace conifer { + + /* --- +* Balanced tree reduce implementation. +* Reduces an array of inputs to a single value using the template binary operator 'Op', +* for example summing all elements with Op_add, or finding the maximum with Op_max +* Use only when the input array is fully unrolled. Or, slice out a fully unrolled section +* before applying and accumulate the result over the rolled dimension. +* Required for emulation to guarantee equality of ordering. +* --- */ + constexpr int floorlog2(int x) { return (x < 2) ? 0 : 1 + floorlog2(x / 2); } + + template + constexpr int pow(int x) { + return x == 0 ? 1 : B * pow(x - 1); + } + + constexpr int pow2(int x) { return pow<2>(x); } + + template + T reduce(std::vector x, Op op) { + int N = x.size(); + int leftN = pow2(floorlog2(N - 1)) > 0 ? pow2(floorlog2(N - 1)) : 0; + //static constexpr int rightN = N - leftN > 0 ? N - leftN : 0; + if (N == 1) { + return x.at(0); + } else if (N == 2) { + return op(x.at(0), x.at(1)); + } else { + std::vector left(x.begin(), x.begin() + leftN); + std::vector right(x.begin() + leftN, x.end()); + return op(reduce(left, op), reduce(right, op)); + } + } + + template + class OpAdd { + public: + T operator()(T a, T b) { return a + b; } + }; + + template + class DecisionTree { + private: + std::vector feature; + std::vector children_left; + std::vector children_right; + std::vector threshold_; + std::vector value_; + std::vector threshold; + std::vector value; + + public: + U decision_function(std::vector x) const { + /* Do the prediction */ + int i = 0; + while (feature[i] != -2) { // continue until reaching leaf + bool comparison = x[feature[i]] <= threshold_[i]; + i = comparison ? children_left[i] : children_right[i]; + } + return value_[i]; + } + + void init_() { + /* Since T, U types may not be readable from the JSON, read them to double and the cast them here */ + std::transform( + threshold.begin(), threshold.end(), std::back_inserter(threshold_), [](double t) -> T { return (T)t; }); + std::transform(value.begin(), value.end(), std::back_inserter(value_), [](double v) -> U { return (U)v; }); + } + + // Define how to read this class to/from JSON + NLOHMANN_DEFINE_TYPE_INTRUSIVE(DecisionTree, feature, children_left, children_right, threshold, value); + + }; // class DecisionTree + + template + class BDT { + private: + unsigned int n_classes; + unsigned int n_trees; + unsigned int n_features; + std::vector init_predict; + std::vector init_predict_; + // vector of decision trees: outer dimension tree, inner dimension class + std::vector>> trees; + OpAdd add; + + public: + // Define how to read this class to/from JSON + NLOHMANN_DEFINE_TYPE_INTRUSIVE(BDT, n_classes, n_trees, n_features, init_predict, trees); + + BDT(std::string filename) { + /* Construct the BDT from conifer cpp backend JSON file */ + std::ifstream ifs(filename); + nlohmann::json j = nlohmann::json::parse(ifs); + from_json(j, *this); + /* Do some transformation to initialise things into the proper emulation T, U types */ + if (n_classes == 2) + n_classes = 1; + std::transform(init_predict.begin(), init_predict.end(), std::back_inserter(init_predict_), [](double ip) -> U { + return (U)ip; + }); + for (unsigned int i = 0; i < n_trees; i++) { + for (unsigned int j = 0; j < n_classes; j++) { + trees.at(i).at(j).init_(); + } + } + } + + 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; + } + 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); + }); + if (useAddTree) { + values.at(i) = init_predict_.at(i); + values.at(i) += reduce>(values_trees.at(i), add); + } else { + values.at(i) = std::accumulate(values_trees.at(i).begin(), values_trees.at(i).end(), U(init_predict_.at(i))); + } + } + + return values; + } + + std::vector _decision_function_double(std::vector x) const { + /* Do the prediction with data in/out as double, cast to T, U before prediction */ + std::vector xt; + std::transform(x.begin(), x.end(), std::back_inserter(xt), [](double xi) -> T { return (T)xi; }); + std::vector y = decision_function(xt); + std::vector yd; + std::transform(y.begin(), y.end(), std::back_inserter(yd), [](U yi) -> double { return (double)yi; }); + return yd; + } + + }; // class BDT + +} // namespace conifer + +#endif \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/src/corrector.h b/L1Trigger/Phase2L1ParticleFlow/interface/corrector.h similarity index 81% rename from L1Trigger/Phase2L1ParticleFlow/src/corrector.h rename to L1Trigger/Phase2L1ParticleFlow/interface/corrector.h index 3ade23a229eb0..dacf7bd8afe66 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/corrector.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/corrector.h @@ -14,10 +14,14 @@ namespace l1t { namespace l1tpf { class corrector { public: - corrector() : is2d_(false), neta_(0), nemf_(0), emfMax_(-1) {} - corrector(const std::string &iFile, float emfMax = -1, bool debug = false); - corrector(const std::string &iFile, const std::string &directory, float emfMax = -1, bool debug = false); - corrector(TDirectory *src, float emfMax = -1, bool debug = false); + corrector() : is2d_(false), neta_(0), nemf_(0), emfMax_(-1), emulate_(false) {} + corrector(const std::string &iFile, float emfMax = -1, bool debug = false, bool emulate = false); + corrector(const std::string &iFile, + const std::string &directory, + float emfMax = -1, + bool debug = false, + bool emulate = false); + corrector(TDirectory *src, float emfMax = -1, bool debug = false, bool emulate = false); // create an empty corrector (you'll need to fill the graphs later) corrector(const TH1 *index, float emfMax = -1); ~corrector(); @@ -54,12 +58,15 @@ namespace l1tpf { private: std::unique_ptr index_; std::vector corrections_; + std::vector correctionsEmulated_; bool is2d_; unsigned int neta_, nemf_; float emfMax_; + bool emulate_; - void init_(const std::string &iFile, const std::string &directory, bool debug); + void init_(const std::string &iFile, const std::string &directory, bool debug, bool emulate); void init_(TDirectory *src, bool debug); + void initEmulation_(TDirectory *src, bool debug); }; } // namespace l1tpf #endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h b/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h index 1a50810c2179b..41b421e4dadba 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h @@ -2,46 +2,67 @@ #define L1Trigger_Phase2L1ParticleFlow_deregionizer_input_h #include +#include #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +namespace edm { + class ParameterSet; +} + namespace l1ct { class DeregionizerInput { public: - static const unsigned int nEtaRegions = - 6 /*7 with HF*/; // Fold ([-0.5,0.0] and [0.0,+0.5]) and ([+-0.5,+-1.0] and [+-1.0,+-1.5]) eta slices into phi - static const unsigned int nPhiRegions = - 18; // 9 phi slices * 2 to account for the barrel having x2 PF regions per eta slice in the barrel + // struct to represent how each correlator layer 1 board output is structured + struct BoardInfo { + uint nOutputFramesPerBX_; + uint nPuppiFramesPerRegion_; + uint nLinksPuppi_; + uint nPuppiPerRegion_; + uint order_; + std::vector regions_; + }; - DeregionizerInput(std::vector ®ionEtaCenter, - std::vector ®ionPhiCenter, - const std::vector &inputRegions); + // struct to represent how each puppi object is positioned in the input frame + struct LinkPlacementInfo { + uint board_; + uint link_; + uint clock_cycle_; + // for sorting + bool operator<(const LinkPlacementInfo &other) const { + bool cc_lt = this->clock_cycle_ < other.clock_cycle_; + bool cc_eq = this->clock_cycle_ == other.clock_cycle_; + bool board_lt = this->board_ < other.board_; + bool board_eq = this->board_ == other.board_; + bool link_lt = this->link_ < other.link_; + return cc_eq ? (board_eq ? link_lt : board_lt) : cc_lt; + } + }; + typedef LinkPlacementInfo LPI; + typedef std::pair PlacedPuppi; - void setDebug(bool debug = true) { debug_ = debug; } + std::vector boardInfos_; - enum regionIndex { - centralBarl = 0, - negBarl = 1, - posBarl = 2, - negHGCal = 3, - posHGCal = 4, - forwardHGCal = 5 /*, HF = 6*/ - }; - void orderRegions(int order[nEtaRegions]); + // note: this one for use in standalone testbench + DeregionizerInput(std::vector boardInfos) : boardInfos_(boardInfos) {} - const std::vector > > &orderedInRegionsPuppis() const { - return orderedInRegionsPuppis_; - }; + // note: this one will work only in CMSSW + DeregionizerInput(const std::vector linkConfigs); - private: - std::vector regionEtaCenter_; - std::vector regionPhiCenter_; - std::vector > > orderedInRegionsPuppis_; + ~DeregionizerInput(){}; - bool debug_ = false; + std::vector> inputOrderInfo( + const std::vector &inputRegions) const; + std::vector>> orderInputs( + const std::vector &inputRegions) const; + + void setDebug(bool debug = true) { debug_ = debug; } - unsigned int orderRegionsInPhi(const float eta, const float phi, const float etaComp) const; - void initRegions(const std::vector &inputRegions); + private: + bool debug_ = false; + // these are not configurable in current design + static constexpr uint nInputFramesPerBX_ = 9; + static constexpr uint tmuxFactor_ = 6; }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h index 7a68a0db80a9e..f418857520362 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h @@ -25,13 +25,10 @@ namespace l1ct { void setDebug(bool debug = true) { debug_ = debug; } - void run(const DeregionizerInput in, + void run(std::vector>> in, std::vector &out, std::vector &truncated); - std::vector > splitPFregions( - const std::vector > > ®ionPuppis, const int i, const int j); - private: unsigned int nPuppiFinalBuffer_, nPuppiPerClk_, nPuppiFirstBuffers_, nPuppiSecondBuffers_, nPuppiThirdBuffers_; bool debug_; @@ -41,6 +38,9 @@ namespace l1ct { const std::vector &inLeft, const std::vector &inRight); + static std::vector mergeXtoY(const std::vector &inLeft, + const std::vector &inRight); + static void accumulateToY(const unsigned int Y, const std::vector &in, std::vector &out, diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h new file mode 100644 index 0000000000000..175b9d8d2cc5f --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h @@ -0,0 +1,62 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_L1EGPuppiIsoAlgo_h +#define L1Trigger_Phase2L1ParticleFlow_L1EGPuppiIsoAlgo_h + +#include +#include +#include +#include + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "DataFormats/L1TParticleFlow/interface/egamma.h" +#include "DataFormats/L1TParticleFlow/interface/puppi.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +namespace l1ct { + + struct L1EGPuppiIsoAlgoConfig { + enum { kPFIso, kPuppiIso }; + + int pfIsoType_; + pt_t ptMin_; + ap_int dZMax_; + int dRMin2_; + int dRMax2_; + bool pfCandReuse_; + + L1EGPuppiIsoAlgoConfig(const std::string& pfIsoTypeStr, + const float ptMin, + const float dZMax, + const float dRMin, + const float dRMax, + const bool pfCandReuse) + : pfIsoType_(pfIsoTypeStr == "PF" ? kPFIso : kPuppiIso), + ptMin_(Scales::makePtFromFloat(ptMin)), + dZMax_(Scales::makeZ0(dZMax)), + dRMin2_(Scales::makeDR2FromFloatDR(dRMin)), + dRMax2_(Scales::makeDR2FromFloatDR(dRMax)), + pfCandReuse_(pfCandReuse) {} + }; + + typedef std::vector EGIsoObjsEmu; + typedef std::vector EGIsoEleObjsEmu; + typedef std::vector PuppiObjs; + + class L1EGPuppiIsoAlgo { + public: + L1EGPuppiIsoAlgo(const L1EGPuppiIsoAlgoConfig& config) : config_(config) {} + L1EGPuppiIsoAlgo(const edm::ParameterSet& pSet); + virtual ~L1EGPuppiIsoAlgo() = default; + + void run(const EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, EGIsoObjsEmu& outL1EGs, z0_t z0 = 0) const; + void run(EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, z0_t z0 = 0) const; + void run(EGIsoEleObjsEmu& l1Eles, const PuppiObjs& l1PFCands) const; + + private: + iso_t calcIso(const EGIsoObj& l1EG, std::list& workPFCands, z0_t z0 = 0) const; + + const L1EGPuppiIsoAlgoConfig config_; + }; + +} // namespace l1ct +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h index e0f59a04b2f31..4a417fd48d04a 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h @@ -40,16 +40,16 @@ namespace l1ct { std::vector eg_unsorted_inBoard = eg_sorted_inBoard; mergeEGObjFromRegions(pfregions, outregions, region_index, eg_unsorted_inBoard); - if (debug_) { - dbgCout() << "\nUNSORTED\n"; + if (debug_ && !eg_unsorted_inBoard.empty()) { + dbgCout() << "\nUNSORTED " << typeid(T).name() << "\n"; for (int j = 0, nj = eg_unsorted_inBoard.size(); j < nj; j++) dbgCout() << "EG[" << j << "]: pt = " << eg_unsorted_inBoard[j].hwPt << ",\t eta = " << eg_unsorted_inBoard[j].hwEta << ",\t phi = " << eg_unsorted_inBoard[j].hwPhi << "\n"; } - if (debug_) - dbgCout() << "\nSORTED\n"; + if (debug_ && !eg_unsorted_inBoard.empty()) + dbgCout() << "\nSORTED " << typeid(T).name() << "\n"; eg_sorted_inBoard = eg_unsorted_inBoard; std::reverse(eg_sorted_inBoard.begin(), eg_sorted_inBoard.end()); @@ -57,7 +57,7 @@ namespace l1ct { if (eg_sorted_inBoard.size() > nObjSorted_) eg_sorted_inBoard.resize(nObjSorted_); - if (debug_) { + if (debug_ && !eg_unsorted_inBoard.empty()) { for (int j = 0, nj = eg_sorted_inBoard.size(); j < nj; j++) dbgCout() << "EG[" << j << "]: pt = " << eg_sorted_inBoard[j].hwPt << ",\t eta = " << eg_sorted_inBoard[j].hwEta << ",\t phi = " << eg_sorted_inBoard[j].hwPhi << "\n"; @@ -103,19 +103,19 @@ namespace l1ct { for (unsigned int i : region_index) { const auto& region = pfregions[i].region; - if (debug_) + std::vector eg_tmp; + extractEGObjEmu(region, outregions[i], eg_tmp); + if (debug_ && !eg_tmp.empty()) dbgCout() << "\nOutput Region " << i << ": eta = " << region.floatEtaCenter() << " and phi = " << region.floatPhiCenter() << " \n"; - std::vector eg_tmp; - extractEGObjEmu(region, outregions[i], eg_tmp); - for (int j = 0, nj = (eg_tmp.size() > nObjToSort_ ? nObjToSort_ : eg_tmp.size()); j < nj; j++) { + for (int j = 0, nj = std::min(eg_tmp.size(), nObjToSort_); j < nj; j++) { if (debug_) dbgCout() << "EG[" << j << "] pt = " << eg_tmp[j].hwPt << ",\t eta = " << eg_tmp[j].hwEta << ",\t phi = " << eg_tmp[j].hwPhi << "\n"; eg_unsorted_inBoard.push_back(eg_tmp[j]); } - if (debug_) + if (debug_ && !eg_tmp.empty()) dbgCout() << "\n"; } } diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h new file mode 100644 index 0000000000000..0e5435f3690f2 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h @@ -0,0 +1,142 @@ +#ifndef L1TRIGGER_PHASE2L1PARTICLEFLOW_BUFFERED_FOLDED_MULTIFIFO_REGIONZER_REF_H +#define L1TRIGGER_PHASE2L1PARTICLEFLOW_BUFFERED_FOLDED_MULTIFIFO_REGIONZER_REF_H + +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/folded_multififo_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" +#include +#include + +namespace l1ct { + namespace multififo_regionizer { + template + inline bool local_eta_window(const T& t, const l1ct::glbeta_t& etaMin, const l1ct::glbeta_t& etaMax); + template <> + inline bool local_eta_window(const l1ct::TkObjEmu& t, + const l1ct::glbeta_t& etaMin, + const l1ct::glbeta_t& etaMax); + + template + class EtaBuffer { + public: + EtaBuffer() {} + EtaBuffer(unsigned int maxitems, const l1ct::glbeta_t& etaMin = 0, const l1ct::glbeta_t& etaMax = 0) + : size_(maxitems), iwrite_(0), iread_(0), etaMin_(etaMin), etaMax_(etaMax) {} + void maybe_push(const T& t); + void writeNewEvent() { + iwrite_ = 1 - iwrite_; + items_[iwrite_].clear(); + } + void readNewEvent() { iread_ = 1 - iread_; } + T pop(); + unsigned int writeSize() const { return items_[iwrite_].size(); } + unsigned int readSize() const { return items_[iread_].size(); } + + private: + unsigned int size_, iwrite_, iread_; + l1ct::glbeta_t etaMin_, etaMax_; + std::deque items_[2]; + }; + } // namespace multififo_regionizer +} // namespace l1ct +namespace l1ct { + class BufferedFoldedMultififoRegionizerEmulator : public FoldedMultififoRegionizerEmulator { + public: + enum class FoldMode { EndcapEta2 }; + + BufferedFoldedMultififoRegionizerEmulator(unsigned int nclocks, + unsigned int ntk, + unsigned int ncalo, + unsigned int nem, + unsigned int nmu, + bool streaming, + unsigned int outii, + unsigned int pauseii, + bool useAlsoVtxCoords); + + ~BufferedFoldedMultififoRegionizerEmulator() override; + + void initSectorsAndRegions(const RegionizerDecodedInputs& in, const std::vector& out) override; + + void run(const RegionizerDecodedInputs& in, std::vector& out) override; + + void fillLinks(unsigned int iclock, std::vector& links, std::vector& valid); + void fillLinks(unsigned int iclock, std::vector& links, std::vector& valid); + void fillLinks(unsigned int iclock, std::vector& links, std::vector& valid); + void fillLinks(unsigned int iclock, std::vector& links, std::vector& valid); + + // clock-cycle emulation + bool step(bool newEvent, + const std::vector& links_tk, + const std::vector& links_hadCalo, + const std::vector& links_emCalo, + const std::vector& links_mu, + std::vector& out_tk, + std::vector& out_hadCalo, + std::vector& out_emCalo, + std::vector& out_mu, + bool mux = true); + + template + void toFirmware(const std::vector& emu, TFw fw[]) { + for (unsigned int i = 0, n = emu.size(); i < n; ++i) { + fw[i] = emu[i]; + } + } + + protected: + std::vector> tkBuffers_; + std::vector> caloBuffers_; + std::vector> muBuffers_; + + void findEtaBounds_(const l1ct::PFRegionEmu& sec, + const std::vector& reg, + l1ct::glbeta_t& etaMin, + l1ct::glbeta_t& etaMax); + + template + void fillLinksPosNeg_(unsigned int iclock, + const std::vector>& secNeg, + const std::vector>& secPos, + std::vector& links, + std::vector& valid); + }; +} // namespace l1ct + +template +inline bool l1ct::multififo_regionizer::local_eta_window(const T& t, + const l1ct::glbeta_t& etaMin, + const l1ct::glbeta_t& etaMax) { + return (etaMin == etaMax) || (etaMin <= t.hwEta && t.hwEta <= etaMax); +} +template <> +inline bool l1ct::multififo_regionizer::local_eta_window(const l1ct::TkObjEmu& t, + const l1ct::glbeta_t& etaMin, + const l1ct::glbeta_t& etaMax) { + return (etaMin == etaMax) || (etaMin <= t.hwEta && t.hwEta <= etaMax) || + (etaMin <= t.hwVtxEta() && t.hwVtxEta() <= etaMax); +} +template +void l1ct::multififo_regionizer::EtaBuffer::maybe_push(const T& t) { + if ((t.hwPt != 0) && local_eta_window(t, etaMin_, etaMax_)) { + if (items_[iwrite_].size() < size_) { + items_[iwrite_].push_back(t); + } else { + // uncommenting the message below may be useful for debugging + //dbgCout() << "WARNING: sector buffer is full for " << typeid(T).name() << ", pt = " << t.intPt() + // << ", eta = " << t.intEta() << ", phi = " << t.intPhi() << "\n"; + } + } +} + +template +T l1ct::multififo_regionizer::EtaBuffer::pop() { + T ret; + ret.clear(); + if (!items_[iread_].empty()) { + ret = items_[iread_].front(); + items_[iread_].pop_front(); + } + return ret; +} + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/folded_multififo_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/folded_multififo_regionizer_ref.h new file mode 100644 index 0000000000000..810f16bee4904 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/folded_multififo_regionizer_ref.h @@ -0,0 +1,89 @@ +#ifndef L1TRIGGER_PHASE2L1PARTICLEFLOW_FOLDED_MULTIFIFO_REGIONIZER_REF_H +#define L1TRIGGER_PHASE2L1PARTICLEFLOW_FOLDED_MULTIFIFO_REGIONIZER_REF_H + +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h" +#include + +namespace l1ct { + struct EGInputSelectorEmuConfig; +} // namespace l1ct + +namespace l1ct { + class FoldedMultififoRegionizerEmulator : public RegionizerEmulator { + public: + enum class FoldMode { EndcapEta2 }; + + FoldedMultififoRegionizerEmulator(unsigned int nclocks, + unsigned int ntklinks, + unsigned int ncalolinks, + unsigned int ntk, + unsigned int ncalo, + unsigned int nem, + unsigned int nmu, + bool streaming, + unsigned int outii, + unsigned int pauseii, + bool useAlsoVtxCoords); + + ~FoldedMultififoRegionizerEmulator() override; + + void setEgInterceptMode(bool afterFifo, const l1ct::EGInputSelectorEmuConfig& interceptorConfig); + void initSectorsAndRegions(const RegionizerDecodedInputs& in, const std::vector& out) override; + + void run(const RegionizerDecodedInputs& in, std::vector& out) override; + + // clock-cycle emulation + bool step(bool newEvent, + const std::vector& links_tk, + const std::vector& links_hadCalo, + const std::vector& links_emCalo, + const std::vector& links_mu, + std::vector& out_tk, + std::vector& out_hadCalo, + std::vector& out_emCalo, + std::vector& out_mu, + bool mux = true); + + // link emulation from decoded inputs (for simulation) + void fillEvent(const RegionizerDecodedInputs& in); + + template + void fillLinks(unsigned int iclock, std::vector& links, std::vector& valid) { + Fold& fold = fold_[whichFold(iclock)]; + fold.regionizer->fillLinks(iclock % clocksPerFold_, fold.sectors, links, valid); + } + + // convert links to firmware + template + void toFirmware(const std::vector& emu, TFw fw[]) { + fold_.front().regionizer->toFirmware(emu, fw); + } + + protected: + const unsigned int NTK_SECTORS, NCALO_SECTORS; + const unsigned int NTK_LINKS, NCALO_LINKS, HCAL_LINKS, ECAL_LINKS, NMU_LINKS; + unsigned int nclocks_, ntk_, ncalo_, nem_, nmu_, outii_, pauseii_, nregions_; + bool streaming_; + FoldMode foldMode_; + bool init_; + struct Fold { + unsigned int index; + std::unique_ptr regionizer; + RegionizerDecodedInputs sectors; + std::vector regions; + Fold(unsigned int i, std::unique_ptr&& ptr) + : index(i), regionizer(std::move(ptr)) {} + }; + std::vector fold_; + unsigned int clocksPerFold_; + unsigned int iclock_; + + unsigned int whichFold(const l1ct::PFRegion& reg); + unsigned int whichFold(unsigned int iclock) { return (iclock % nclocks_) / clocksPerFold_; } + bool inFold(const l1ct::PFRegion& reg, const Fold& fold); + void splitSectors(const RegionizerDecodedInputs& in); + void splitRegions(const std::vector& out); + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h index 63aad616bc3b0..1575f888f6cbc 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h @@ -19,12 +19,15 @@ namespace l1ct { public: MultififoRegionizerEmulator(unsigned int nendcaps, unsigned int nclocks, + unsigned int ntklinks, + unsigned int ncalolinks, unsigned int ntk, unsigned int ncalo, unsigned int nem, unsigned int nmu, bool streaming, unsigned int outii, + unsigned int pauseii, bool useAlsoVtxCoords); enum class BarrelSetup { Full54, Full27, Central18, Central9, Phi18, Phi9 }; @@ -40,12 +43,14 @@ namespace l1ct { unsigned int outii, unsigned int pauseii, bool useAlsoVtxCoords); - - // note: this one will work only in CMSSW + // note: these ones will work only in CMSSW MultififoRegionizerEmulator(const edm::ParameterSet& iConfig); + MultififoRegionizerEmulator(const std::string& barrelSetup, const edm::ParameterSet& iConfig); ~MultififoRegionizerEmulator() override; + static BarrelSetup parseBarrelSetup(const std::string& setup); + void setEgInterceptMode(bool afterFifo, const l1ct::EGInputSelectorEmuConfig& interceptorConfig); void initSectorsAndRegions(const RegionizerDecodedInputs& in, const std::vector& out) override; @@ -86,10 +91,27 @@ namespace l1ct { PFInputRegion& out); // link emulation from decoded inputs (for simulation) - void fillLinks(unsigned int iclock, const RegionizerDecodedInputs& in, std::vector& links); - void fillLinks(unsigned int iclock, const RegionizerDecodedInputs& in, std::vector& links); - void fillLinks(unsigned int iclock, const RegionizerDecodedInputs& in, std::vector& links); - void fillLinks(unsigned int iclock, const RegionizerDecodedInputs& in, std::vector& links); + void fillLinks(unsigned int iclock, + const RegionizerDecodedInputs& in, + std::vector& links, + std::vector& valid); + void fillLinks(unsigned int iclock, + const RegionizerDecodedInputs& in, + std::vector& links, + std::vector& valid); + void fillLinks(unsigned int iclock, + const RegionizerDecodedInputs& in, + std::vector& links, + std::vector& valid); + void fillLinks(unsigned int iclock, + const RegionizerDecodedInputs& in, + std::vector& links, + std::vector& valid); + template + void fillLinks(unsigned int iclock, const RegionizerDecodedInputs& in, std::vector& links) { + std::vector unused; + fillLinks(iclock, in, links, unused); + } // convert links to firmware void toFirmware(const std::vector& emu, TkObj fw[/*NTK_SECTORS*NTK_LINKS*/]); @@ -97,6 +119,8 @@ namespace l1ct { void toFirmware(const std::vector& emu, EmCaloObj fw[/*NCALO_SECTORS*NCALO_LINKS*/]); void toFirmware(const std::vector& emu, MuObj fw[/*NMU_LINKS*/]); + void reset(); + private: const unsigned int NTK_SECTORS, NCALO_SECTORS; // max objects per sector per clock cycle const unsigned int NTK_LINKS, NCALO_LINKS, HCAL_LINKS, ECAL_LINKS, NMU_LINKS; @@ -113,7 +137,10 @@ namespace l1ct { std::vector tkRoutes_, caloRoutes_, emCaloRoutes_, muRoutes_; template - void fillCaloLinks_(unsigned int iclock, const std::vector>& in, std::vector& links); + void fillCaloLinks(unsigned int iclock, + const std::vector>& in, + std::vector& links, + std::vector& valid); }; } // namespace l1ct diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/DeregionizerProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/DeregionizerProducer.cc index bb73a1fb61506..46276ce37aea4 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/DeregionizerProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/DeregionizerProducer.cc @@ -22,7 +22,13 @@ class DeregionizerProducer : public edm::stream::EDProducer<> { private: edm::ParameterSet config_; edm::EDGetTokenT token_; + std::vector linkConfigs_; + const unsigned int nInputFramesPerBX_; l1ct::DeregionizerEmulator emulator_; + l1ct::DeregionizerInput input_; + std::vector boardOrder_, nOutputFramesPerBX_, nPuppiFramesPerRegion_, nLinksPuppi_, nPuppiPerRegion_; + std::vector> outputRegions_; + const unsigned int tmuxFactor_ = 6; // not really configurable in current architecture std::unordered_map clusterRefMap_; std::unordered_map trackRefMap_; @@ -36,7 +42,10 @@ class DeregionizerProducer : public edm::stream::EDProducer<> { DeregionizerProducer::DeregionizerProducer(const edm::ParameterSet &iConfig) : config_(iConfig), token_(consumes(iConfig.getParameter("RegionalPuppiCands"))), - emulator_(iConfig) { + linkConfigs_(iConfig.getParameter>("linkConfigs")), + nInputFramesPerBX_(iConfig.getParameter("nInputFramesPerBX")), + emulator_(iConfig), + input_(linkConfigs_) { produces("Puppi"); produces("TruncatedPuppi"); } @@ -55,7 +64,6 @@ void DeregionizerProducer::produce(edm::Event &iEvent, const edm::EventSetup &iS iEvent.getByToken(token_, src); - std::vector regionEtas, regionPhis; std::vector outputRegions; std::vector hwOut; std::vector edmOut; @@ -86,16 +94,12 @@ void DeregionizerProducer::produce(edm::Event &iEvent, const edm::EventSetup &iS << "] = " << tempOutputRegion.puppi.back().floatEta() << ", phi[" << i << "] = " << tempOutputRegion.puppi.back().floatPhi(); } - if (!tempOutputRegion.puppi.empty()) { - regionEtas.push_back(eta); - regionPhis.push_back(phi); - outputRegions.push_back(tempOutputRegion); - } + outputRegions.push_back(tempOutputRegion); } - l1ct::DeregionizerInput in = l1ct::DeregionizerInput(regionEtas, regionPhis, outputRegions); + std::vector>> layer2In = input_.orderInputs(outputRegions); - emulator_.run(in, hwOut, hwTruncOut); + emulator_.run(layer2In, hwOut, hwTruncOut); DeregionizerProducer::hwToEdm_(hwOut, edmOut); DeregionizerProducer::hwToEdm_(hwTruncOut, edmTruncOut); @@ -171,7 +175,6 @@ void DeregionizerProducer::setRefs_(l1t::PFCandidate &pf, const l1ct::PuppiObjEm } void DeregionizerProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { - // DeregionizerProducer edm::ParameterSetDescription desc; desc.add("RegionalPuppiCands", edm::InputTag("l1tLayer1", "PuppiRegional")); desc.add("nPuppiFinalBuffer", 128); @@ -179,9 +182,11 @@ void DeregionizerProducer::fillDescriptions(edm::ConfigurationDescriptions &desc desc.add("nPuppiFirstBuffers", 12); desc.add("nPuppiSecondBuffers", 32); desc.add("nPuppiThirdBuffers", 64); + desc.add("nInputFramesPerBX", 9); + edm::ParameterSetDescription linkConfigDummyValidator; + linkConfigDummyValidator.setAllowAnything(); + desc.addVPSet("linkConfigs", linkConfigDummyValidator); descriptions.add("DeregionizerProducer", desc); - // or use the following to generate the label from the module's C++ type - //descriptions.addWithDefaultLabel(desc); } #include "FWCore/Framework/interface/MakerMacros.h" diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1BJetProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1BJetProducer.cc new file mode 100644 index 0000000000000..ef9c2fa8b335a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1BJetProducer.cc @@ -0,0 +1,114 @@ +#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/InputTag.h" + +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" +#include "DataFormats/JetReco/interface/Jet.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/BJetId.h" +#include "DataFormats/Common/interface/ValueMap.h" + +#include "DataFormats/L1Trigger/interface/VertexWord.h" + +#include +#include + +using namespace l1t; + +class L1BJetProducer : public edm::stream::EDProducer> { +public: + explicit L1BJetProducer(const edm::ParameterSet&, const BJetTFCache*); + ~L1BJetProducer() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + static std::unique_ptr initializeGlobalCache(const edm::ParameterSet&); + static void globalEndJob(const BJetTFCache*); + +private: + std::unique_ptr fBJetId_; + void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; + + edm::EDGetTokenT> const jets_; + bool const fUseRawPt_; + double const fMinPt_; + double const fMaxEta_; + unsigned int const fMaxJets_; + int const fNParticles_; + edm::EDGetTokenT> const fVtxEmu_; +}; + +L1BJetProducer::L1BJetProducer(const edm::ParameterSet& cfg, const BJetTFCache* cache) + : jets_(consumes>(cfg.getParameter("jets"))), + fUseRawPt_(cfg.getParameter("useRawPt")), + fMinPt_(cfg.getParameter("minPt")), + fMaxEta_(cfg.getParameter("maxEta")), + fMaxJets_(cfg.getParameter("maxJets")), + fNParticles_(cfg.getParameter("nParticles")), + fVtxEmu_(consumes>(cfg.getParameter("vtx"))) { + fBJetId_ = std::make_unique( + cfg.getParameter("NNInput"), cfg.getParameter("NNOutput"), cache, fNParticles_); + produces>("L1PFBJets"); +} +std::unique_ptr L1BJetProducer::initializeGlobalCache(const edm::ParameterSet& cfg) { + edm::FileInPath fp(cfg.getParameter("NNFileName")); + auto cache = std::make_unique(fp.fullPath()); + return cache; +} +void L1BJetProducer::globalEndJob(const BJetTFCache* cache) {} +void L1BJetProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + edm::Handle> jets; + iEvent.getByToken(jets_, jets); + + float vz = 0.; + double ptsum = 0; + edm::Handle> vtxEmuHandle; + iEvent.getByToken(fVtxEmu_, vtxEmuHandle); + for (const auto& vtx : *vtxEmuHandle) { + if (ptsum == 0 || vtx.pt() > ptsum) { + ptsum = vtx.pt(); + vz = vtx.z0(); + } + } + + std::vector bScores; + + for (const auto& srcjet : *jets) { + if (((fUseRawPt_ ? srcjet.rawPt() : srcjet.pt()) < fMinPt_) || std::abs(srcjet.eta()) > fMaxEta_ || + bScores.size() >= fMaxJets_) { + bScores.push_back(-1.); + continue; + } + float NN = fBJetId_->compute(srcjet, vz, fUseRawPt_); + bScores.push_back(NN); + } + + auto outT = std::make_unique>(); + edm::ValueMap::Filler fillerT(*outT); + fillerT.insert(jets, bScores.begin(), bScores.end()); + fillerT.fill(); + + iEvent.put(std::move(outT), "L1PFBJets"); +} + +void L1BJetProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // L1BJetProducer + edm::ParameterSetDescription desc; + desc.add("jets", edm::InputTag("scPFL1Puppi")); + desc.add("useRawPt", true); + desc.add("NNFileName", + edm::FileInPath("L1Trigger/Phase2L1ParticleFlow/data/modelTT_PUP_Off_dXY_XYCut_Graph.pb")); + desc.add("NNInput", "input:0"); + desc.add("NNOutput", "sequential/dense_2/Sigmoid"); + desc.add("maxJets", 10); + desc.add("nParticles", 10); + desc.add("minPt", 20); + desc.add("maxEta", 2.4); + desc.add("vtx", edm::InputTag("L1VertexFinderEmulator", "l1verticesEmulation")); + descriptions.add("L1BJetProducer", desc); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1BJetProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc index 17ffc93ec114a..14ad91953db40 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc @@ -1,6 +1,7 @@ #include #include +#include //////////////////// // FRAMEWORK HEADERS @@ -8,9 +9,11 @@ #include "FWCore/Framework/interface/Event.h" #include "FWCore/Utilities/interface/InputTag.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/MakerMacros.h" #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" #include "DataFormats/L1TParticleFlow/interface/PFJet.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/corrector.h" #include "DataFormats/Math/interface/deltaR.h" // bitwise emulation headers @@ -21,6 +24,7 @@ class L1SeedConePFJetProducer : public edm::global::EDProducer<> { public: explicit L1SeedConePFJetProducer(const edm::ParameterSet&); ~L1SeedConePFJetProducer() override; + static void fillDescriptions(edm::ConfigurationDescriptions& description); private: /// ///////////////// /// @@ -28,25 +32,26 @@ class L1SeedConePFJetProducer : public edm::global::EDProducer<> { void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override; /// ///////////////// /// - float coneSize; - unsigned nJets; - bool HW; - bool debug; + const float coneSize; + const unsigned nJets; + const bool HW; + const bool debug; + const bool doCorrections; L1SCJetEmu emulator; edm::EDGetTokenT> l1PFToken; + l1tpf::corrector corrector; std::vector processEvent_SW(std::vector>& parts) const; std::vector processEvent_HW(std::vector>& parts) const; l1t::PFJet makeJet_SW(const std::vector>& parts) const; - static std::pair, - std::unordered_map>> - convertEDMToHW(std::vector>& edmParticles); + std::pair, std::unordered_map>> + convertEDMToHW(std::vector>& edmParticles) const; - static std::vector convertHWToEDM( + std::vector convertHWToEDM( std::vector hwJets, - std::unordered_map> constituentMap); + std::unordered_map> constituentMap) const; }; L1SeedConePFJetProducer::L1SeedConePFJetProducer(const edm::ParameterSet& cfg) @@ -54,9 +59,14 @@ L1SeedConePFJetProducer::L1SeedConePFJetProducer(const edm::ParameterSet& cfg) nJets(cfg.getParameter("nJets")), HW(cfg.getParameter("HW")), debug(cfg.getParameter("debug")), + doCorrections(cfg.getParameter("doCorrections")), emulator(L1SCJetEmu(debug, coneSize, nJets)), l1PFToken(consumes>(cfg.getParameter("L1PFObjects"))) { produces(); + if (doCorrections) { + corrector = l1tpf::corrector( + cfg.getParameter("correctorFile"), cfg.getParameter("correctorDir"), -1., debug, HW); + } } void L1SeedConePFJetProducer::produce(edm::StreamID /*unused*/, @@ -119,6 +129,10 @@ l1t::PFJet L1SeedConePFJetProducer::makeJet_SW(const std::vector L1SeedConePFJetProducer::processEvent_SW(std::vector seed = work.at(0); - // Get the particles within a _coneSize of the seed + // Get the particles within a coneSize of the seed std::vector> particlesInCone; std::copy_if( work.begin(), work.end(), std::back_inserter(particlesInCone), [&](const edm::Ptr& part) { @@ -160,7 +174,7 @@ std::vector L1SeedConePFJetProducer::processEvent_HW(std::vector, std::unordered_map>> -L1SeedConePFJetProducer::convertEDMToHW(std::vector>& edmParticles) { +L1SeedConePFJetProducer::convertEDMToHW(std::vector>& edmParticles) const { std::vector hwParticles; std::unordered_map> candidateMap; std::for_each(edmParticles.begin(), edmParticles.end(), [&](edm::Ptr& edmParticle) { @@ -175,22 +189,43 @@ L1SeedConePFJetProducer::convertEDMToHW(std::vector>& std::vector L1SeedConePFJetProducer::convertHWToEDM( std::vector hwJets, - std::unordered_map> constituentMap) { + std::unordered_map> constituentMap) const { std::vector edmJets; std::for_each(hwJets.begin(), hwJets.end(), [&](L1SCJetEmu::Jet jet) { - l1t::PFJet edmJet( - jet.floatPt(), jet.floatEta(), jet.floatPhi(), /*mass=*/0., jet.intPt(), jet.intEta(), jet.intPhi()); + if (doCorrections) { + float correctedPt = corrector.correctedPt(jet.floatPt(), jet.floatEta()); + jet.hwPt = correctedPt; + } + l1gt::Jet gtJet = jet.toGT(); + l1t::PFJet edmJet(l1gt::Scales::floatPt(gtJet.v3.pt), + l1gt::Scales::floatEta(gtJet.v3.eta), + l1gt::Scales::floatPhi(gtJet.v3.phi), + /*mass=*/0., + gtJet.v3.pt.V, + gtJet.v3.eta.V, + gtJet.v3.phi.V); + edmJet.setEncodedJet(jet.toGT().pack()); // get back the references to the constituents std::vector> constituents; std::for_each(jet.constituents.begin(), jet.constituents.end(), [&](auto constituent) { edmJet.addConstituent(constituentMap[constituent.srcCand]); }); - l1gt::Jet gtJet = jet.toGT(); - edmJet.setEncodedJet(jet.toGT().pack()); edmJets.push_back(edmJet); }); return edmJets; } -#include "FWCore/Framework/interface/MakerMacros.h" +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.addWithDefaultLabel(desc); +} + DEFINE_FWK_MODULE(L1SeedConePFJetProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc index 57e5d8b9c0c02..301712fa15c41 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc @@ -7,7 +7,7 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Utilities/interface/InputTag.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/corrector.h" #include @@ -19,21 +19,24 @@ class L1TCorrectedPFJetProducer : public edm::global::EDProducer<> { private: void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; - edm::EDGetTokenT> jets_; + edm::EDGetTokenT> jets_; l1tpf::corrector corrector_; }; L1TCorrectedPFJetProducer::L1TCorrectedPFJetProducer(const edm::ParameterSet& iConfig) - : jets_(consumes>(iConfig.getParameter("jets"))), + : jets_(consumes>(iConfig.getParameter("jets"))), corrector_(iConfig.getParameter("correctorFile"), - iConfig.getParameter("correctorDir")) { + iConfig.getParameter("correctorDir"), + -1, + false, + iConfig.getParameter("emulate")) { produces>(); } L1TCorrectedPFJetProducer::~L1TCorrectedPFJetProducer() {} void L1TCorrectedPFJetProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const { - edm::Handle> jets; + edm::Handle> jets; iEvent.getByToken(jets_, jets); auto out = std::make_unique>(); @@ -41,6 +44,10 @@ void L1TCorrectedPFJetProducer::produce(edm::StreamID, edm::Event& iEvent, const // start out as copy out->emplace_back(srcjet.p4()); auto& jet = out->back(); + // copy daughters + for (const auto& dau : srcjet.constituents()) { + jet.addConstituent(dau); + } // apply corrections jet.calibratePt(corrector_.correctedPt(jet.pt(), jet.eta())); } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index 3eee113d3b15a..f5599d121d0b9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -206,6 +206,10 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet } else if (regalgo == "Multififo") { regionizer_ = std::make_unique( iConfig.getParameter("regionizerAlgoParameters")); + } else if (regalgo == "MultififoBarrel") { + const auto &pset = iConfig.getParameter("regionizerAlgoParameters"); + regionizer_ = + std::make_unique(pset.getParameter("barrelSetup"), pset); } else if (regalgo == "TDR") { regionizer_ = std::make_unique( iConfig.getParameter("regionizerAlgoParameters")); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc index 75265d23765a0..99b0251eff85b 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -3,6 +3,7 @@ #include "DataFormats/L1TCorrelator/interface/TkEm.h" #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" #include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/global/EDProducer.h" @@ -12,9 +13,8 @@ #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h" -//#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egsorter_ref.cpp" #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h" -//#include "L1Trigger/Phase2L1ParticleFlow/src/newfirmware/egamma/l2egencoder_ref.cpp" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h" #include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h" #include "L1Trigger/DemonstratorTools/interface/utilities.h" @@ -54,6 +54,7 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { void convertToEmu(const l1t::TkElectron &tkele, RefRemapper &refRemapper, l1ct::OutputBoard &boarOut) const; void convertToEmu(const l1t::TkEm &tkele, RefRemapper &refRemapper, l1ct::OutputBoard &boarOut) const; + void convertToPuppi(const l1t::PFCandidateCollection &l1PFCands, l1ct::PuppiObjs &puppiObjs) const; template class PFInstanceInputs { @@ -194,6 +195,9 @@ class L1TCtL2EgProducer : public edm::global::EDProducer<> { std::string tkEleInstanceLabel_; l1ct::L2EgSorterEmulator l2egsorter; l1ct::L2EgEncoderEmulator l2encoder; + edm::EDGetTokenT> pfObjsToken_; + l1ct::L1EGPuppiIsoAlgo l2EgPuppiIsoAlgo_; + l1ct::L1EGPuppiIsoAlgo l2ElePuppiIsoAlgo_; bool doInPtrn_; bool doOutPtrn_; std::unique_ptr inPtrnWrt_; @@ -209,6 +213,9 @@ L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf) tkEleInstanceLabel_(conf.getParameter("tkEleInstanceLabel")), l2egsorter(conf.getParameter("sorter")), l2encoder(conf.getParameter("encoder")), + pfObjsToken_(consumes>(conf.getParameter("l1PFObjects"))), + l2EgPuppiIsoAlgo_(conf.getParameter("puppiIsoParametersTkEm")), + l2ElePuppiIsoAlgo_(conf.getParameter("puppiIsoParametersTkEle")), doInPtrn_(conf.getParameter("writeInPattern")), doOutPtrn_(conf.getParameter("writeOutPattern")), inPtrnWrt_(nullptr), @@ -300,6 +307,13 @@ void L1TCtL2EgProducer::produce(edm::StreamID, edm::Event &iEvent, const edm::Ev std::vector out_eles_emu; l2egsorter.run(*boards, out_photons_emu, out_eles_emu); + // PUPPI isolation + auto &pfObjs = iEvent.get(pfObjsToken_); + l1ct::PuppiObjs puppiObjs; + convertToPuppi(pfObjs, puppiObjs); + l2EgPuppiIsoAlgo_.run(out_photons_emu, puppiObjs); + l2ElePuppiIsoAlgo_.run(out_eles_emu, puppiObjs); + if (doOutPtrn_) { l1t::demo::EventData outData; outData.add({"eglayer2", 0}, l2encoder.encodeLayer2EgObjs(out_photons_emu, out_eles_emu)); @@ -335,6 +349,7 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkElectron &tkele, // NOTE: The emulator and FW data-format stores absolute iso while the CMSSW object stores relative iso emu.setHwIso(EGIsoEleObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkele.trkIsol() * tkele.pt())); emu.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkele.pfIsol() * tkele.pt())); + emu.setHwIso(EGIsoEleObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkele.puppiIsol() * tkele.pt())); // std::cout << "[convertToEmu] TkEle pt: " << emu.hwPt << " eta: " << emu.hwEta << " phi: " << emu.hwPhi << " staidx: " << emu.sta_idx << std::endl; boarOut.egelectron.push_back(emu); @@ -356,12 +371,21 @@ void L1TCtL2EgProducer::convertToEmu(const l1t::TkEm &tkem, // NOTE: The emulator and FW data-format stores absolute iso while the CMSSW object stores relative iso emu.setHwIso(EGIsoObjEmu::IsoType::TkIso, l1ct::Scales::makeIso(tkem.trkIsol() * tkem.pt())); emu.setHwIso(EGIsoObjEmu::IsoType::PfIso, l1ct::Scales::makeIso(tkem.pfIsol() * tkem.pt())); + emu.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, l1ct::Scales::makeIso(tkem.puppiIsol() * tkem.pt())); emu.setHwIso(EGIsoObjEmu::IsoType::TkIsoPV, l1ct::Scales::makeIso(tkem.trkIsolPV() * tkem.pt())); emu.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, l1ct::Scales::makeIso(tkem.pfIsolPV() * tkem.pt())); // std::cout << "[convertToEmu] TkEM pt: " << emu.hwPt << " eta: " << emu.hwEta << " phi: " << emu.hwPhi << " staidx: " << emu.sta_idx << std::endl; boarOut.egphoton.push_back(emu); } +void L1TCtL2EgProducer::convertToPuppi(const l1t::PFCandidateCollection &l1PFCands, l1ct::PuppiObjs &puppiObjs) const { + for (const auto &l1PFCand : l1PFCands) { + l1ct::PuppiObj obj; + obj.initFromBits(l1PFCand.encodedPuppi64()); + puppiObjs.emplace_back(obj); + } +} + l1t::TkEm L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoObjEmu &egiso, const RefRemapper &refRemapper) const { // std::cout << "[convertFromEmu] TkEm pt: " << egiso.hwPt << " eta: " << egiso.hwEta << " phi: " << egiso.hwPhi << " staidx: " << egiso.sta_idx << std::endl; // NOTE: the TkEM object is created with the accuracy as in GT object (not the Correlator internal one)! @@ -376,6 +400,7 @@ l1t::TkEm L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoObjEmu &egiso, cons tkem.setHwQual(gteg.quality); tkem.setPFIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIso)); tkem.setPFIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIsoPV)); + tkem.setPuppiIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PuppiIso)); tkem.setEgBinaryWord(gteg.pack()); return tkem; } @@ -394,6 +419,7 @@ l1t::TkElectron L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoEleObjEmu &eg egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::TkIso)); tkele.setHwQual(gteg.quality); tkele.setPFIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PfIso)); + tkele.setPuppiIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PuppiIso)); tkele.setEgBinaryWord(gteg.pack()); return tkele; } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc index 50c1e7157c740..37758637cbad0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc @@ -22,7 +22,7 @@ #include "DataFormats/Math/interface/deltaPhi.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/corrector.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h" diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc index 8e60240bdb205..7d393fe347bd9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc @@ -7,7 +7,7 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DataFormats/L1TParticleFlow/interface/PFCluster.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/corrector.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/HGC3DClusterEgID.h" #include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc index 1a54b25340f61..9d05716eade59 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc @@ -5,9 +5,10 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DataFormats/L1TParticleFlow/interface/PFCluster.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/corrector.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" #include "DataFormats/L1Trigger/interface/EGamma.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/CaloClusterer.h" namespace l1tpf { class PFClusterProducerFromL1EGClusters : public edm::stream::EDProducer<> { @@ -18,6 +19,9 @@ namespace l1tpf { private: edm::EDGetTokenT> src_; double etCut_; + std::vector const etaBounds_; + std::vector const phiBounds_; + std::vector const maxClustersEtaPhi_; l1tpf::corrector corrector_; l1tpf::ParametricResolution resol_; @@ -29,16 +33,34 @@ namespace l1tpf { l1tpf::PFClusterProducerFromL1EGClusters::PFClusterProducerFromL1EGClusters(const edm::ParameterSet &iConfig) : src_(consumes>(iConfig.getParameter("src"))), etCut_(iConfig.getParameter("etMin")), + etaBounds_(iConfig.getParameter>("etaBounds")), + phiBounds_(iConfig.getParameter>("phiBounds")), + maxClustersEtaPhi_(iConfig.getParameter>("maxClustersEtaPhi")), corrector_(iConfig.getParameter("corrector"), -1), resol_(iConfig.getParameter("resol")) { - produces(); + produces("all"); + produces("selected"); + if ((etaBounds_.size() - 1) * (phiBounds_.size() - 1) != maxClustersEtaPhi_.size()) { + throw cms::Exception("Configuration") + << "Size mismatch between eta/phi bounds and max clusters: " << (etaBounds_.size() - 1) << " x " + << (phiBounds_.size() - 1) << " != " << maxClustersEtaPhi_.size() << "\n"; + } + if (!std::is_sorted(etaBounds_.begin(), etaBounds_.end())) { + throw cms::Exception("Configuration") << "etaBounds is not sorted\n"; + } + if (!std::is_sorted(phiBounds_.begin(), phiBounds_.end())) { + throw cms::Exception("Configuration") << "phiBounds is not sorted\n"; + } } void l1tpf::PFClusterProducerFromL1EGClusters::produce(edm::Event &iEvent, const edm::EventSetup &) { std::unique_ptr out(new l1t::PFClusterCollection()); + std::unique_ptr out_sel(new l1t::PFClusterCollection()); edm::Handle> clusters; iEvent.getByToken(src_, clusters); + l1tpf_calo::GridSelector selector = l1tpf_calo::GridSelector(etaBounds_, phiBounds_, maxClustersEtaPhi_); + unsigned int index = 0; for (auto it = clusters->begin(), ed = clusters->end(); it != ed; ++it, ++index) { if (it->pt() <= etCut_) @@ -52,9 +74,26 @@ void l1tpf::PFClusterProducerFromL1EGClusters::produce(edm::Event &iEvent, const cluster.setHwQual(it->hwQual()); out->push_back(cluster); out->back().addConstituent(edm::Ptr(clusters, index)); + selector.fill(cluster.pt(), cluster.eta(), cluster.phi(), index); + } + std::vector indices = selector.returnSorted(); + for (unsigned int ii = 0; ii < indices.size(); ii++) { + unsigned int theIndex = indices[ii]; + l1t::PFCluster cluster((clusters->begin() + theIndex)->pt(), + (clusters->begin() + theIndex)->eta(), + (clusters->begin() + theIndex)->phi(), + /*hOverE=*/0., + /*isEM=*/true); // it->hovere() seems to return random values + if (corrector_.valid()) + corrector_.correctPt(cluster); + cluster.setPtError(resol_(cluster.pt(), std::abs(cluster.eta()))); + cluster.setHwQual((clusters->begin() + theIndex)->hwQual()); + out_sel->push_back(cluster); + out_sel->back().addConstituent(edm::Ptr(clusters, theIndex)); } - iEvent.put(std::move(out)); + iEvent.put(std::move(out), "all"); + iEvent.put(std::move(out_sel), "selected"); } using l1tpf::PFClusterProducerFromL1EGClusters; DEFINE_FWK_MODULE(PFClusterProducerFromL1EGClusters); diff --git a/L1Trigger/Phase2L1ParticleFlow/python/L1BJetProducer_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/L1BJetProducer_cff.py new file mode 100644 index 0000000000000..51e98c3326277 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/L1BJetProducer_cff.py @@ -0,0 +1,20 @@ +import FWCore.ParameterSet.Config as cms + +from L1Trigger.Phase2L1ParticleFlow.l1pfJetMet_cff import L1TPFJetsExtendedTask + +from L1Trigger.Phase2L1ParticleFlow.L1BJetProducer_cfi import L1BJetProducer +l1tBJetProducerPuppi = L1BJetProducer.clone( + jets = ("l1tSCPFL1PuppiExtended", ""), + maxJets = 6, + minPt = 10, + vtx = ("l1tVertexFinderEmulator","l1verticesEmulation") +) + + +l1tBJetProducerPuppiCorrectedEmulator = l1tBJetProducerPuppi.clone( + jets = ("l1tSCPFL1PuppiExtendedCorrectedEmulator", "") +) + +L1TBJetsTask = cms.Task( + L1TPFJetsExtendedTask, l1tBJetProducerPuppi, l1tBJetProducerPuppiCorrectedEmulator +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1SeedConePFJetEmulatorProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1SeedConePFJetEmulatorProducer_cfi.py new file mode 100644 index 0000000000000..be71e5e4d4969 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1SeedConePFJetEmulatorProducer_cfi.py @@ -0,0 +1,2 @@ +from L1Trigger.Phase2L1ParticleFlow.l1SeedConePFJetProducer_cfi import l1SeedConePFJetProducer as _l1SeedConePFJetProducer +l1SeedConePFJetEmulatorProducer = _l1SeedConePFJetProducer.clone(HW = True) \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index 9005fdf100820..e0b2e6542ae5d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -2,7 +2,7 @@ import math -from L1Trigger.Phase2L1ParticleFlow.l1tPFTracksFromL1Tracks_cfi import l1tPFTracksFromL1Tracks +from L1Trigger.Phase2L1ParticleFlow.l1tPFTracksFromL1Tracks_cfi import l1tPFTracksFromL1Tracks, l1tPFTracksFromL1TracksExtended from L1Trigger.Phase2L1ParticleFlow.l1tPFClustersFromL1EGClusters_cfi import l1tPFClustersFromL1EGClusters from L1Trigger.Phase2L1ParticleFlow.pfClustersFromCombinedCalo_cff import l1tPFClustersFromCombinedCaloHCal, l1tPFClustersFromCombinedCaloHF from L1Trigger.Phase2L1ParticleFlow.l1tPFClustersFromHGC3DClusters_cfi import l1tPFClustersFromHGC3DClusters @@ -17,7 +17,7 @@ l1tLayer1Barrel = cms.EDProducer("L1TCorrelatorLayer1Producer", tracks = cms.InputTag('l1tPFTracksFromL1Tracks'), muons = cms.InputTag('l1tSAMuonsGmt','promptSAMuons'), - emClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromL1EGClusters')), + emClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromL1EGClusters:selected')), hadClusters = cms.VInputTag(cms.InputTag('l1tPFClustersFromCombinedCaloHCal:calibrated')), vtxCollection = cms.InputTag("l1tVertexFinderEmulator","l1verticesEmulation"), vtxCollectionEmulation = cms.bool(True), @@ -137,6 +137,8 @@ ) ) +l1tLayer1BarrelExtended = l1tLayer1Barrel.clone(tracks = cms.InputTag('l1tPFTracksFromL1TracksExtended')) + _hgcalSectors = cms.VPSet( cms.PSet( etaBoundaries = cms.vdouble(-3.0, -1.5), @@ -196,6 +198,8 @@ useAlsoVtxCoords = cms.bool(True), nEndcaps = cms.uint32(2), nClocks = cms.uint32(54), + nTkLinks = cms.uint32(2), + nCaloLinks = cms.uint32(3), nTrack = cms.uint32(30), nCalo = cms.uint32(20), nEmCalo = cms.uint32(10), @@ -286,6 +290,7 @@ writeRawHgcalCluster = cms.untracked.bool(True) ) +l1tLayer1HGCalExtended = l1tLayer1HGCal.clone(tracks = ('l1tPFTracksFromL1TracksExtended')) l1tLayer1HGCalNoTK = cms.EDProducer("L1TCorrelatorLayer1Producer", tracks = cms.InputTag(''), @@ -469,6 +474,12 @@ regionalLabelsToMerge = cms.vstring("Puppi"), ) + +l1tLayer1Extended = l1tLayer1.clone( + pfProducers = [ ("l1tLayer1BarrelExtended"), ("l1tLayer1HGCalExtended"), + ("l1tLayer1HGCalNoTK"),("l1tLayer1HF")] +) + l1tLayer1EG = cms.EDProducer( "L1TEGMultiMerger", tkElectrons=cms.VPSet( @@ -516,14 +527,18 @@ l1tPFClustersFromCombinedCaloHCal, l1tPFClustersFromCombinedCaloHF, l1tPFClustersFromHGC3DClusters, - l1tPFTracksFromL1Tracks + l1tPFTracksFromL1Tracks, + l1tPFTracksFromL1TracksExtended ) L1TLayer1Task = cms.Task( l1tLayer1Barrel, + l1tLayer1BarrelExtended, l1tLayer1HGCal, + l1tLayer1HGCalExtended, l1tLayer1HGCalNoTK, l1tLayer1HF, l1tLayer1, + l1tLayer1Extended, l1tLayer1EG ) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py index 6a856e48db502..e79e4bae5f6c8 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -115,7 +115,20 @@ hgcalPosVU13PWriterConfig.outputLinkEgamma = cms.int32(3) hgcalPosVU13PWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-vu13p") hgcalPosVU13PWriterConfig.outputFileName = cms.string("l1HGCalPos-outputs-vu13p") -## Enable both +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 + hgcalNegVU13PWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4*27+t) +hgcalNegVU13PWriterConfig.gttLink = 4*27+3 +hgcalNegVU13PWriterConfig.outputLinksPuppi = cms.vuint32(0,1,2) +hgcalNegVU13PWriterConfig.outputLinkEgamma = cms.int32(3) +hgcalNegVU13PWriterConfig.inputFileName = cms.string("l1HGCalNeg-inputs-vu13p") +hgcalNegVU13PWriterConfig.outputFileName = cms.string("l1HGCalNeg-outputs-vu13p") ## Enable both @@ -123,7 +136,8 @@ hgcalPosIdealWriterConfig, hgcalNegIdealWriterConfig, hgcalPosVU9PB904egWriterConfig, - hgcalPosVU13PWriterConfig + hgcalPosVU13PWriterConfig, + hgcalNegVU13PWriterConfig ] ##################################################################################################################### diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py index 56e93b10e5957..f9d9196a1611e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py @@ -1,5 +1,7 @@ import FWCore.ParameterSet.Config as cms +from L1Trigger.Phase2L1ParticleFlow.l1tDeregionizerProducer_cfi import l1tDeregionizerProducer as l1tLayer2Deregionizer + l1tLayer2EG = cms.EDProducer( "L1TCtL2EgProducer", tkElectrons=cms.VPSet( @@ -36,6 +38,7 @@ channels=cms.vint32(-1) ), ), + l1PFObjects = cms.InputTag("l1tLayer2Deregionizer", "Puppi"), egStaInstanceLabel=cms.string("L1CtEgEE"), tkEmInstanceLabel=cms.string("L1CtTkEm"), tkEleInstanceLabel=cms.string("L1CtTkElectron"), @@ -49,6 +52,22 @@ nTKELE_OUT=cms.uint32(12), nTKPHO_OUT=cms.uint32(12), ), + puppiIsoParametersTkEm = cms.PSet( + pfIsoType = cms.string("PUPPI"), + pfPtMin = cms.double(1.), + dZ = cms.double(0.6), + dRMin = cms.double(0.07), + dRMax = cms.double(0.3), + pfCandReuse = cms.bool(True) + ), + puppiIsoParametersTkEle = cms.PSet( + pfIsoType = cms.string("PUPPI"), + pfPtMin = cms.double(1.), + dZ = cms.double(0.6), + dRMin = cms.double(0.03), + dRMax = cms.double(0.2), + pfCandReuse = cms.bool(True) + ), writeInPattern=cms.bool(False), writeOutPattern=cms.bool(False), inPatternFile=cms.PSet( @@ -133,5 +152,6 @@ L1TLayer2EGTask = cms.Task( + l1tLayer2Deregionizer, l1tLayer2EG ) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py index 62d2dafeb1c21..87328acd0f8b9 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py @@ -1,23 +1,29 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.Phase2L1ParticleFlow.l1tSeedConePFJetProducer_cfi import l1tSeedConePFJetProducer, l1tSeedConePFJetEmulatorProducer -from L1Trigger.Phase2L1ParticleFlow.l1tDeregionizerProducer_cfi import l1tDeregionizerProducer as l1tLayer2Deregionizer -l1tSCPFL1PF = l1tSeedConePFJetProducer.clone(L1PFObjects = 'l1tLayer1:PF') -l1tSCPFL1Puppi = l1tSeedConePFJetProducer.clone() -l1tSCPFL1PuppiEmulator = l1tSeedConePFJetEmulatorProducer.clone(L1PFObjects = 'l1tLayer2Deregionizer:Puppi') +from L1Trigger.Phase2L1ParticleFlow.l1SeedConePFJetProducer_cfi import l1SeedConePFJetProducer +from L1Trigger.Phase2L1ParticleFlow.l1SeedConePFJetEmulatorProducer_cfi import l1SeedConePFJetEmulatorProducer +from L1Trigger.Phase2L1ParticleFlow.l1tDeregionizerProducer_cfi import l1tDeregionizerProducer as l1tLayer2Deregionizer, l1tDeregionizerProducerExtended as l1tLayer2DeregionizerExtended +l1tSCPFL1PF = l1SeedConePFJetProducer.clone(L1PFObjects = 'l1tLayer1:PF') +l1tSCPFL1Puppi = l1SeedConePFJetProducer.clone() +l1tSCPFL1PuppiEmulator = l1SeedConePFJetEmulatorProducer.clone(L1PFObjects = 'l1tLayer2Deregionizer:Puppi') +l1tSCPFL1PuppiCorrectedEmulator = l1SeedConePFJetEmulatorProducer.clone(L1PFObjects = 'l1tLayer2Deregionizer:Puppi', + doCorrections = True, + correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs_20220308.root", + correctorDir = "L1PuppiSC4EmuJets") _correctedJets = cms.EDProducer("L1TCorrectedPFJetProducer", jets = cms.InputTag("_tag_"), - correctorFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_110X.root"), - correctorDir = cms.string("_dir_") + correctorFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs_20220308.root"), + correctorDir = cms.string("_dir_"), + copyDaughters = cms.bool(False), + emulate = cms.bool(False) ) + # Using phase2_hgcalV10 to customize the config for all 106X samples, since there's no other modifier for it from Configuration.Eras.Modifier_phase2_hgcalV10_cff import phase2_hgcalV10 phase2_hgcalV10.toModify(_correctedJets, correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_106X.root") from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 -phase2_hgcalV11.toModify(_correctedJets, correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_110X.root") - -l1tSCPFL1PuppiCorrectedEmulator = _correctedJets.clone(jets = 'l1tSCPFL1PuppiEmulator', correctorDir = 'L1PuppiSC4EmuDeregJets') +phase2_hgcalV11.toModify(_correctedJets, correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs_20220308.root") from L1Trigger.Phase2L1ParticleFlow.l1tMHTPFProducer_cfi import l1tMHTPFProducer l1tSCPFL1PuppiCorrectedEmulatorMHT = l1tMHTPFProducer.clone() @@ -26,6 +32,21 @@ l1tLayer2Deregionizer, l1tSCPFL1PF, l1tSCPFL1Puppi, l1tSCPFL1PuppiEmulator, l1tSCPFL1PuppiCorrectedEmulator, l1tSCPFL1PuppiCorrectedEmulatorMHT ) +l1tSCPFL1PuppiExtended = l1SeedConePFJetProducer.clone(L1PFObjects = 'l1tLayer1Extended:Puppi') +l1tSCPFL1PuppiExtendedEmulator = l1SeedConePFJetEmulatorProducer.clone(L1PFObjects = 'l1tLayer2DeregionizerExtended:Puppi') +l1tSCPFL1PuppiExtendedCorrectedEmulator = l1SeedConePFJetEmulatorProducer.clone(L1PFObjects = 'l1tLayer2DeregionizerExtended:Puppi', + doCorrections = True, + correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs_20220308.root", + correctorDir = "L1PuppiSC4EmuJets") + +L1TPFJetsTask = cms.Task( + l1tLayer2Deregionizer, l1tSCPFL1PF, l1tSCPFL1Puppi, l1tSCPFL1PuppiEmulator, l1tSCPFL1PuppiCorrectedEmulator, l1tSCPFL1PuppiCorrectedEmulatorMHT +) + +L1TPFJetsExtendedTask = cms.Task( + l1tLayer2DeregionizerExtended, l1tSCPFL1PuppiExtended, l1tSCPFL1PuppiExtendedEmulator, l1tSCPFL1PuppiExtendedCorrectedEmulator +) + L1TPFJetsEmulationTask = cms.Task( l1tLayer2Deregionizer, l1tSCPFL1PuppiEmulator, l1tSCPFL1PuppiCorrectedEmulator, l1tSCPFL1PuppiCorrectedEmulatorMHT ) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tDeregionizerProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tDeregionizerProducer_cfi.py index 2ac0b378a0f13..cef07825d3fed 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1tDeregionizerProducer_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1tDeregionizerProducer_cfi.py @@ -1,10 +1,69 @@ import FWCore.ParameterSet.Config as cms +# Specifications for Correlator Layer 1 output mapping onto links +barrelConfig_ = cms.PSet( + partition = cms.string("Barrel"), + nLinksPuppi = cms.uint32(6), + nPuppiPerRegion = cms.uint32(18), + nOutputFramesPerBX = cms.uint32(9), +) + +barrelPhiConfigs = [ + barrelConfig_.clone( + outputRegions = cms.vuint32(*[3*ip+9*ie+i for ie in range(6) for i in range(3) ]), + outputBoard = cms.int32(ip), + ) for ip in range(3) +] + +hgcalConfig_ = cms.PSet( + partition = cms.string("HGCal"), + nLinksPuppi = cms.uint32(3), + nPuppiPerRegion = cms.uint32(18), + nOutputFramesPerBX = cms.uint32(9), + outputRegions = cms.vuint32(*[54 + i+9 for i in range(9)]), + outputBoard = cms.int32(3), +) + +hgcalPosConfig = hgcalConfig_.clone( + outputBoard = 4 +) +hgcalNegConfig = hgcalConfig_.clone( + outputRegions = [54 + i for i in range(9)] +) + +hgcalNoTKConfig = cms.PSet( + partition = cms.string("HGCalNoTk"), + nLinksPuppi = cms.uint32(4), + nPuppiPerRegion = cms.uint32(12), + nOutputFramesPerBX = cms.uint32(9), + outputRegions = cms.vuint32(*range(72,72+18)), + outputBoard = cms.int32(5), +) + +hfConfig_ = cms.PSet( + partition = cms.string("HF"), + nLinksPuppi = cms.uint32(3), + nPuppiPerRegion = cms.uint32(18), + nOutputFramesPerBX = cms.uint32(9), +) +hfConfigs = [ + hfConfig_.clone( + outputRegions = cms.vuint32(*[90+9*ie+i for i in range(9)]), + outputBoard = cms.int32(6 + ie), + ) for ie in range(2) +] + +linkConfigs = cms.VPSet(*barrelPhiConfigs, hgcalPosConfig, hgcalNegConfig, hgcalNoTKConfig, *hfConfigs) + l1tDeregionizerProducer = cms.EDProducer("DeregionizerProducer", RegionalPuppiCands = cms.InputTag("l1tLayer1","PuppiRegional"), nPuppiFinalBuffer = cms.uint32(128), nPuppiPerClk = cms.uint32(6), nPuppiFirstBuffers = cms.uint32(12), nPuppiSecondBuffers = cms.uint32(32), - nPuppiThirdBuffers = cms.uint32(64) + nPuppiThirdBuffers = cms.uint32(64), + nInputFramesPerBX = cms.uint32(9), + linkConfigs = linkConfigs, ) + +l1tDeregionizerProducerExtended = l1tDeregionizerProducer.clone(RegionalPuppiCands = cms.InputTag("l1tLayer1Extended","PuppiRegional")) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctJetFileWriter_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tJetFileWriter_cfi.py similarity index 85% rename from L1Trigger/Phase2L1ParticleFlow/python/l1ctJetFileWriter_cfi.py rename to L1Trigger/Phase2L1ParticleFlow/python/l1tJetFileWriter_cfi.py index 3d1dbe877ebaf..6dd9b1f64370e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctJetFileWriter_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1tJetFileWriter_cfi.py @@ -1,7 +1,7 @@ import FWCore.ParameterSet.Config as cms l1tSeededConeJetFileWriter = cms.EDAnalyzer('L1CTJetFileWriter', - jets = cms.InputTag("l1tSCPFL1PuppiEmulator"), + jets = cms.InputTag("l1tSCPFL1PuppiEmulatorCorrected"), nJets = cms.uint32(12), nFramesPerBX = cms.uint32(9), # 360 MHz clock or 25 Gb/s link TMUX = cms.uint32(6), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromCombinedCalo_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromCombinedCalo_cfi.py index e1eb04d8f2375..83f575957731a 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromCombinedCalo_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromCombinedCalo_cfi.py @@ -1,7 +1,7 @@ import FWCore.ParameterSet.Config as cms l1tPFClustersFromCombinedCalo = cms.EDProducer("L1TPFCaloProducer", - ecalCandidates = cms.VInputTag(cms.InputTag('l1tPFClustersFromL1EGClusters')), # using EM from towers in HGC, no longer reading also 'pfClustersFromHGC3DClustersEM' + ecalCandidates = cms.VInputTag(cms.InputTag('l1tPFClustersFromL1EGClusters:all')), hcalCandidates = cms.VInputTag(), hcalDigis = cms.VInputTag(cms.InputTag('simHcalTriggerPrimitiveDigis')), hcalDigisBarrel = cms.bool(False), @@ -17,6 +17,9 @@ grid = cms.string("phase2"), zsEt = cms.double(0.4), seedEt = cms.double(0.5), + etaBounds = cms.vdouble(-1.), + phiBounds = cms.vdouble(-1.), + maxClustersEtaPhi = cms.vuint32(), minClusterEt = cms.double(0.5), energyWeightedPosition = cms.bool(True), energyShareAlgo = cms.string("fractions"), @@ -25,6 +28,9 @@ grid = cms.string("phase2"), zsEt = cms.double(0.4), seedEt = cms.double(0.5), + etaBounds = cms.vdouble(-1.), + phiBounds = cms.vdouble(-1.), + maxClustersEtaPhi = cms.vuint32(), minClusterEt = cms.double(0.8), energyWeightedPosition = cms.bool(True), energyShareAlgo = cms.string("fractions"), @@ -34,6 +40,9 @@ zsEt = cms.double(0.0), ## Ecal and Hcal are already ZS-ed above seedEt = cms.double(1.0), + etaBounds = cms.vdouble(-1.), + phiBounds = cms.vdouble(-1.), + maxClustersEtaPhi = cms.vuint32(), minClusterEt = cms.double(1.0), energyWeightedPosition = cms.bool(True), energyShareAlgo = cms.string("fractions"), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromL1EGClusters_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromL1EGClusters_cfi.py index 51bd652351ead..245385ee8ca07 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromL1EGClusters_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1tPFClustersFromL1EGClusters_cfi.py @@ -3,6 +3,9 @@ l1tPFClustersFromL1EGClusters = cms.EDProducer("PFClusterProducerFromL1EGClusters", src = cms.InputTag("l1tEGammaClusterEmuProducer",), etMin = cms.double(0.5), + etaBounds = cms.vdouble(-1.5,0.,1.5), + phiBounds = cms.vdouble([3.14159265359*(float(x)/9.) for x in range(-9,10)]), + maxClustersEtaPhi = cms.vuint32([8] * 36), corrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/emcorr_barrel.root"), resol = cms.PSet( etaBins = cms.vdouble( 0.700, 1.200, 1.600), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tPFTracksFromL1Tracks_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tPFTracksFromL1Tracks_cfi.py index 4134c0d189be5..332adb8a08d82 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1tPFTracksFromL1Tracks_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1tPFTracksFromL1Tracks_cfi.py @@ -25,3 +25,16 @@ redigitizeTrackWord = cms.bool(True), ) +l1tPFTracksFromL1TracksExtended = l1tPFTracksFromL1Tracks.clone( + L1TrackTag = ("l1tTTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), + nParam = 5, + qualityBits = [ + "momentum.perp > 2 && getStubRefs.size >= 4 && chi2Red < 15 && POCA.x < 1.0 && POCA.x > -1.0 && POCA.y < 1.0 && POCA.y > -1.0", + "momentum.perp > 2 && getStubRefs.size >= 6 && chi2Red < 15 && chi2 < 50 && POCA.x < 1.0 && POCA.x > -1.0 && POCA.y < 1.0 && POCA.y > -1.0", # historical reasons + "momentum.perp > 5 && getStubRefs.size >= 4 && POCA.x < 1.0 && POCA.x > -1.0 && POCA.y < 1.0 && POCA.y > -1.0" + #using restriction on track x,y for now + #long term fix would be to alter track propagation in L1Trigger/Phase2L1ParticleFlow/plugins/PFTrackProducerFromL1Tracks.cc + ], + redigitizeTrackWord = True, +) + diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetProducer_cfi.py deleted file mode 100644 index 6f1aa6083a33e..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1tSeedConePFJetProducer_cfi.py +++ /dev/null @@ -1,12 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -l1tSeedConePFJetProducer = cms.EDProducer("L1SeedConePFJetProducer", - L1PFObjects = cms.InputTag("l1tLayer1","Puppi"), - nJets = cms.uint32(10), - coneSize = cms.double(0.4), - HW = cms.bool(False), - debug = cms.bool(False) - ) - -l1tSeedConePFJetEmulatorProducer = l1tSeedConePFJetProducer.clone(HW = True) - diff --git a/L1Trigger/Phase2L1ParticleFlow/src/BJetId.cc b/L1Trigger/Phase2L1ParticleFlow/src/BJetId.cc new file mode 100644 index 0000000000000..eaf8087bf85e6 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/BJetId.cc @@ -0,0 +1,88 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/BJetId.h" +#include "DataFormats/Math/interface/deltaPhi.h" +#include + +BJetId::BJetId(const std::string &iInput, const std::string &iOutput, const BJetTFCache *cache, int iNParticles) + : sessionRef_(cache->session) { + NNvectorVar_.clear(); + fNParticles_ = iNParticles; + + fPt_ = std::make_unique(fNParticles_); + fEta_ = std::make_unique(fNParticles_); + fPhi_ = std::make_unique(fNParticles_); + fId_ = std::make_unique(fNParticles_); + fCharge_ = std::make_unique(fNParticles_); + fDZ_ = std::make_unique(fNParticles_); + fDX_ = std::make_unique(fNParticles_); + fDY_ = std::make_unique(fNParticles_); + fInput_ = iInput; + fOutput_ = iOutput; +} + +BJetId::~BJetId() {} +void BJetId::setNNVectorVar() { + NNvectorVar_.clear(); + for (int i0 = 0; i0 < fNParticles_; i0++) { + if (fPt_.get()[i0] == 0) { + for (int i1 = 0; i1 < 13; i1++) + NNvectorVar_.push_back(0); + continue; + } + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Electron && fCharge_.get()[i0] < 0); // Electron + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Electron && fCharge_.get()[i0] > 0); // Positron + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Muon && fCharge_.get()[i0] < 0); // Muon + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Muon && fCharge_.get()[i0] > 0); // Anti-Muon + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Photon); // Photon + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::NeutralHadron); // Neutral Had + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::ChargedHadron && fCharge_.get()[i0] < 0); // Pion + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::ChargedHadron && fCharge_.get()[i0] > 0); // Anti-Pion + NNvectorVar_.push_back(fDZ_.get()[i0]); //dZ + NNvectorVar_.push_back(std::hypot(fDX_.get()[i0], fDY_.get()[i0])); //d0 + NNvectorVar_.push_back(fPt_.get()[i0]); //pT as a fraction of jet pT + NNvectorVar_.push_back(fEta_.get()[i0]); //dEta from jet axis + NNvectorVar_.push_back(fPhi_.get()[i0]); //dPhi from jet axis + } +} +float BJetId::EvaluateNN() { + tensorflow::Tensor input(tensorflow::DT_FLOAT, {1, (unsigned int)NNvectorVar_.size(), 1}); + for (unsigned int i = 0; i < NNvectorVar_.size(); i++) { + input.tensor()(0, i, 0) = float(NNvectorVar_[i]); + } + std::vector outputs; + tensorflow::run(sessionRef_, {{fInput_, input}}, {fOutput_}, &outputs); + return outputs[0].matrix()(0, 0); +} //end EvaluateNN + +float BJetId::compute(const l1t::PFJet &iJet, float vz, bool useRawPt) { + for (int i0 = 0; i0 < fNParticles_; i0++) { + fPt_.get()[i0] = 0; + fEta_.get()[i0] = 0; + fPhi_.get()[i0] = 0; + fId_.get()[i0] = 0; + fCharge_.get()[i0] = 0; + fDZ_.get()[i0] = 0; + fDX_.get()[i0] = 0; + fDY_.get()[i0] = 0; + } + auto iParts = iJet.constituents(); + std::sort(iParts.begin(), iParts.end(), [](edm::Ptr i, edm::Ptr j) { + return (i->pt() > j->pt()); + }); + float jetpt = useRawPt ? iJet.rawPt() : iJet.pt(); + for (unsigned int i0 = 0; i0 < iParts.size(); i0++) { + if (i0 >= (unsigned int)fNParticles_) + break; + fPt_.get()[i0] = iParts[i0]->pt() / jetpt; + fEta_.get()[i0] = iParts[i0]->eta() - iJet.eta(); + fPhi_.get()[i0] = deltaPhi(iParts[i0]->phi(), iJet.phi()); + fId_.get()[i0] = iParts[i0]->id(); + fCharge_.get()[i0] = iParts[i0]->charge(); + if (iParts[i0]->pfTrack().isNonnull()) { + fDX_.get()[i0] = iParts[i0]->pfTrack()->vx(); + fDY_.get()[i0] = iParts[i0]->pfTrack()->vy(); + fDZ_.get()[i0] = iParts[i0]->pfTrack()->vz() - vz; + } + } + setNNVectorVar(); + return EvaluateNN(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/CaloClusterer.cc b/L1Trigger/Phase2L1ParticleFlow/src/CaloClusterer.cc index 06e95297e8c3f..269bcc7de53c0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/CaloClusterer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/CaloClusterer.cc @@ -167,9 +167,15 @@ l1tpf_calo::SingleCaloClusterer::SingleCaloClusterer(const edm::ParameterSet &ps : grid_(getGrid(pset.getParameter("grid"))), rawet_(*grid_), unclustered_(*grid_), + eta_center_(*grid_), + phi_center_(*grid_), precluster_(*grid_), clusterIndex_(*grid_), cellKey_(*grid_), + preciseEtaPhi_(pset.existsAs("usePreciseEtaPhi") ? pset.getParameter("usePreciseEtaPhi") : false), + etaBounds_(pset.getParameter>("etaBounds")), + phiBounds_(pset.getParameter>("phiBounds")), + maxClustersEtaPhi_(pset.getParameter>("maxClustersEtaPhi")), clusters_(), nullCluster_(), zsEt_(pset.getParameter("zsEt")), @@ -188,12 +194,34 @@ l1tpf_calo::SingleCaloClusterer::SingleCaloClusterer(const edm::ParameterSet &ps energyShareAlgo_ = EnergyShareAlgo::Crude; else throw cms::Exception("Configuration") << "Unsupported energyShareAlgo '" << energyShareAlgo << "'\n"; + if (pset.existsAs>("neighborCells")) { + neighborCells_ = pset.getParameter>( + "neighborCells"); //anything other than 3x3 is incompatible with grow() I think... + } else { + neighborCells_ = std::vector({0, 1, 2, 3, 4, 5, 6, 7}); //default to 3x3 + // in relative eta,phi: 5 = (+1, 0), 6 = (+1, 0), 7 = (+1,+1) + // 3 = ( 0,-1), 4 = ( 0,+1), + // 0 = (-1,-1), 1 = (-1, 0), 2 = (-1,+1), + } + if ((etaBounds_.size() - 1) * (phiBounds_.size() - 1) != maxClustersEtaPhi_.size()) { + throw cms::Exception("Configuration") + << "Size mismatch between eta/phi bounds and max clusters: " << (etaBounds_.size() - 1) << " x " + << (phiBounds_.size() - 1) << " != " << maxClustersEtaPhi_.size() << "\n"; + } + if (!std::is_sorted(etaBounds_.begin(), etaBounds_.end())) { + throw cms::Exception("Configuration") << "etaBounds is not sorted\n"; + } + if (!std::is_sorted(phiBounds_.begin(), phiBounds_.end())) { + throw cms::Exception("Configuration") << "phiBounds is not sorted\n"; + } } l1tpf_calo::SingleCaloClusterer::~SingleCaloClusterer() {} void l1tpf_calo::SingleCaloClusterer::clear() { rawet_.zero(); + eta_center_.zero(); + phi_center_.zero(); clusters_.clear(); clusterIndex_.fill(-1); } @@ -220,7 +248,9 @@ void l1tpf_calo::SingleCaloClusterer::run() { precluster_[i].ptLocalMax = rawet_[i]; //// uncommment code below for debugging the clustering //printf(" candidate precluster pt %7.2f at %4d (ieta %+3d iphi %2d)\n", rawet_[i], i, grid_->ieta(i), grid_->iphi(i)); - for (int ineigh = 0; ineigh <= 3; ++ineigh) { + for (const auto &ineigh : neighborCells_) { + if (ineigh >= 4) + continue; if (rawet_.neigh(i, ineigh) > rawet_[i]) precluster_[i].ptLocalMax = 0; //// uncommment code below for debugging the clustering @@ -228,7 +258,9 @@ void l1tpf_calo::SingleCaloClusterer::run() { //if (ncell == -1) printf(" \t neigh %d is null\n", ineigh); //else printf(" \t neigh %d at %4d (ieta %+3d iphi %2d) has pt %7.2f: comparison %1d \n", ineigh, ncell, grid_->ieta(ncell), grid_->iphi(ncell), rawet_[ncell], precluster_[i].ptLocalMax > 0); } - for (int ineigh = 4; ineigh < 8; ++ineigh) { + for (const auto &ineigh : neighborCells_) { + if (ineigh < 4) + continue; if (rawet_.neigh(i, ineigh) >= rawet_[i]) precluster_[i].ptLocalMax = 0; //// uncommment code below for debugging the clustering @@ -244,7 +276,7 @@ void l1tpf_calo::SingleCaloClusterer::run() { switch (energyShareAlgo_) { case EnergyShareAlgo::Fractions: { float tot = 0; - for (int ineigh = 0; ineigh < 8; ++ineigh) { + for (const auto &ineigh : neighborCells_) { tot += precluster_.neigh(i, ineigh).ptLocalMax; } precluster_[i].ptOverNeighLocalMaxSum = tot ? rawet_[i] / tot : 0; @@ -254,14 +286,14 @@ void l1tpf_calo::SingleCaloClusterer::run() { break; case EnergyShareAlgo::Greedy: { float maxet = 0; - for (int ineigh = 0; ineigh < 8; ++ineigh) { + for (const auto &ineigh : neighborCells_) { maxet = std::max(maxet, precluster_.neigh(i, ineigh).ptLocalMax); } precluster_[i].ptOverNeighLocalMaxSum = maxet; } break; case EnergyShareAlgo::Crude: { int number = 0; - for (int ineigh = 0; ineigh < 8; ++ineigh) { + for (const auto &ineigh : neighborCells_) { number += (precluster_.neigh(i, ineigh).ptLocalMax > 0); } precluster_[i].ptOverNeighLocalMaxSum = (number > 1 ? 0.5 : 1.0) * rawet_[i]; @@ -283,7 +315,7 @@ void l1tpf_calo::SingleCaloClusterer::run() { float avg_phi = 0; cluster.clear(); cluster.constituents.emplace_back(i, 1.0); - for (int ineigh = 0; ineigh < 8; ++ineigh) { + for (const auto &ineigh : neighborCells_) { int ineighcell = grid_->neighbour(i, ineigh); if (ineighcell == -1) continue; // skip dummy cells @@ -314,7 +346,7 @@ void l1tpf_calo::SingleCaloClusterer::run() { if (tot > minClusterEt_) { cluster.et = tot; unclustered_[i] = 0; - for (int ineigh = 0; ineigh < 8; ++ineigh) { + for (const auto &ineigh : neighborCells_) { int ineighcell = grid_->neighbour(i, ineigh); if (ineighcell == -1) continue; // skip dummy cells @@ -369,15 +401,26 @@ std::unique_ptr l1tpf_calo::SingleCaloClusterer::fetch float ptMin) const { auto ret = std::make_unique(); const EtGrid &src = (unclusteredOnly ? unclustered_ : rawet_); + const EtaPhiCenterGrid &eta_shift = eta_center_; + const EtaPhiCenterGrid &phi_shift = phi_center_; + l1tpf_calo::GridSelector selector = l1tpf_calo::GridSelector(etaBounds_, phiBounds_, maxClustersEtaPhi_); + int totalClusters = 0; for (unsigned int i = 0, ncells = grid_->size(); i < ncells; ++i) { if (src[i] <= ptMin) continue; if ((unclusteredOnly == false) && (ptMin == 0)) { - assert(cellKey_[i] == int(ret->size())); + assert(cellKey_[i] == totalClusters); } - ret->emplace_back(src[i], grid_->eta(i), grid_->phi(i)); - ret->back().setHwEta(grid_->ieta(i)); - ret->back().setHwPhi(grid_->iphi(i)); + totalClusters++; + selector.fill(src[i], grid_->eta(i), grid_->phi(i), i); + } + std::vector indices = selector.returnSorted(); + for (unsigned int ii = 0; ii < indices.size(); ii++) { + unsigned int theIndex = indices[ii]; + ret->emplace_back( + src[theIndex], grid_->eta(theIndex) + eta_shift[theIndex], grid_->phi(theIndex) + phi_shift[theIndex]); + ret->back().setHwEta(grid_->ieta(theIndex)); + ret->back().setHwPhi(grid_->iphi(theIndex)); } return ret; } @@ -415,6 +458,9 @@ l1tpf_calo::SimpleCaloLinkerBase::SimpleCaloLinkerBase(const edm::ParameterSet & hcal_(hcal), clusterIndex_(*grid_), clusters_(), + etaBounds_(pset.getParameter>("etaBounds")), + phiBounds_(pset.getParameter>("phiBounds")), + maxClustersEtaPhi_(pset.getParameter>("maxClustersEtaPhi")), hoeCut_(pset.getParameter("hoeCut")), minPhotonEt_(pset.getParameter("minPhotonEt")), minHadronRawEt_(pset.getParameter("minHadronRawEt")), @@ -424,6 +470,17 @@ l1tpf_calo::SimpleCaloLinkerBase::SimpleCaloLinkerBase(const edm::ParameterSet & throw cms::Exception("LogicError", "Inconsistent grid between ecal and linker\n"); if (grid_ != &hcal.raw().grid()) throw cms::Exception("LogicError", "Inconsistent grid between hcal and linker\n"); + if ((etaBounds_.size() - 1) * (phiBounds_.size() - 1) != maxClustersEtaPhi_.size()) { + throw cms::Exception("Configuration") + << "Size mismatch between eta/phi bounds and max clusters: " << (etaBounds_.size() - 1) << " x " + << (phiBounds_.size() - 1) << " != " << maxClustersEtaPhi_.size() << "\n"; + } + if (!std::is_sorted(etaBounds_.begin(), etaBounds_.end())) { + throw cms::Exception("Configuration") << "etaBounds is not sorted\n"; + } + if (!std::is_sorted(phiBounds_.begin(), phiBounds_.end())) { + throw cms::Exception("Configuration") << "phiBounds is not sorted\n"; + } } l1tpf_calo::SimpleCaloLinkerBase::~SimpleCaloLinkerBase() {} @@ -438,7 +495,10 @@ std::unique_ptr l1tpf_calo::SimpleCaloLinkerBase::fetc const edm::OrphanHandle &hcal) const { bool setRefs = (ecal.isValid() && hcal.isValid()); auto ret = std::make_unique(); + l1tpf_calo::GridSelector selector = l1tpf_calo::GridSelector(etaBounds_, phiBounds_, maxClustersEtaPhi_); + unsigned int index = 0; for (const CombinedCluster &cluster : clusters_) { + index++; if (cluster.et > 0) { bool photon = (cluster.hcal_et < hoeCut_ * cluster.ecal_et); if (photon && noEmInHGC_) { @@ -446,20 +506,27 @@ std::unique_ptr l1tpf_calo::SimpleCaloLinkerBase::fetc continue; } } - if (cluster.et > (photon ? minPhotonEt_ : minHadronEt_)) { - ret->emplace_back(cluster.et, - cluster.eta, - cluster.phi, - cluster.ecal_et > 0 ? std::max(cluster.et - cluster.ecal_et, 0.f) / cluster.ecal_et : -1, - photon); - if (setRefs) { - for (const auto &pair : cluster.constituents) { - assert(pair.first != 0); - if (pair.first > 0) { // 1+hcal index - ret->back().addConstituent(edm::Ptr(hcal, +pair.first - 1), pair.second); - } else { // -1-ecal index - ret->back().addConstituent(edm::Ptr(ecal, -pair.first + 1), pair.second); - } + selector.fill(cluster.et, cluster.eta, cluster.phi, index - 1); + } + } + std::vector indices = selector.returnSorted(); + for (unsigned int ii = 0; ii < indices.size(); ii++) { + unsigned int theIndex = indices[ii]; + const CombinedCluster &cluster = clusters_[theIndex]; + bool photon = (cluster.hcal_et < hoeCut_ * cluster.ecal_et); + if (cluster.et > (photon ? minPhotonEt_ : minHadronEt_)) { + ret->emplace_back(cluster.et, + photon ? cluster.ecal_eta : cluster.eta, + photon ? cluster.ecal_phi : cluster.phi, + cluster.ecal_et > 0 ? std::max(cluster.et - cluster.ecal_et, 0.f) / cluster.ecal_et : -1, + photon); + if (setRefs) { + for (const auto &pair : cluster.constituents) { + assert(pair.first != 0); + if (pair.first > 0) { // 1+hcal index + ret->back().addConstituent(edm::Ptr(hcal, +pair.first - 1), pair.second); + } else { // -1-ecal index + ret->back().addConstituent(edm::Ptr(ecal, -pair.first + 1), pair.second); } } } @@ -624,6 +691,108 @@ void l1tpf_calo::FlatCaloLinker::run() { } } +l1tpf_calo::CombinedCaloLinker::CombinedCaloLinker(const edm::ParameterSet &pset, + const SingleCaloClusterer &ecal, + const SingleCaloClusterer &hcal) + : SimpleCaloLinkerBase(pset, ecal, hcal), combClusterer_(pset) {} + +l1tpf_calo::CombinedCaloLinker::~CombinedCaloLinker() {} + +void l1tpf_calo::CombinedCaloLinker::clear() { + clearBase(); + combClusterer_.clear(); +} + +void l1tpf_calo::CombinedCaloLinker::run() { + combClusterer_.clear(); + + const EtGrid &hraw = hcal_.raw(); + const EtGrid &eraw = ecal_.raw(); + const EtaPhiCenterGrid &eeta = ecal_.etaCenter(); + const EtaPhiCenterGrid &ephi = ecal_.phiCenter(); + combClusterer_.raw() = eraw; + combClusterer_.raw() += hraw; + + combClusterer_.run(); + clusterIndex_ = combClusterer_.indexGrid(); + const std::vector &clustersSrc = combClusterer_.clusters(); + unsigned int nclust = clustersSrc.size(); + clusters_.resize(nclust); + for (unsigned int ic = 0; ic < nclust; ++ic) { + const Cluster &src = clustersSrc[ic]; + CombinedCluster &dst = clusters_[ic]; + dst.et = src.et; + dst.eta = src.eta; + dst.phi = src.phi; + dst.ecal_et = 0; + dst.hcal_et = 0; + float pt_max = 0.; + float eta_ecal = 0.; + float phi_ecal = 0.; + for (const auto &pair : src.constituents) { + if (eraw[pair.first]) { + float ept = pair.second * eraw[pair.first]; + dst.ecal_et += ept; + dst.constituents.emplace_back(-pair.first - 1, pair.second); + if (ept > pt_max) { + eta_ecal = eeta[pair.first]; + phi_ecal = ephi[pair.first]; + pt_max = ept; + } + } + if (hraw[pair.first]) { + dst.hcal_et += pair.second * hraw[pair.first]; + dst.constituents.emplace_back(+pair.first + 1, pair.second); + } + } + dst.ecal_eta = eta_ecal; + dst.ecal_phi = phi_ecal; + } +} + +l1tpf_calo::GridSelector::GridSelector(std::vector etaBounds, + std::vector phiBounds, + std::vector maxClusters) + : etaBounds_(etaBounds), + phiBounds_(phiBounds), + maxClustersEtaPhi_(maxClusters), + regionPtIndices_(!maxClusters.empty() ? maxClusters.size() : 1) {} + +void l1tpf_calo::GridSelector::fill(float pt, float eta, float phi, unsigned int index) { + if (!maxClustersEtaPhi_.empty()) { + unsigned int etai = etaBounds_.size(); + for (unsigned int ie = 0; ie < etaBounds_.size() - 1; ie++) { + if (eta >= etaBounds_[ie] && eta < etaBounds_[ie + 1]) { + etai = ie; + break; + } + } + unsigned int phii = phiBounds_.size(); + for (unsigned int ip = 0; ip < phiBounds_.size() - 1; ip++) { + if (phi >= phiBounds_[ip] && phi < phiBounds_[ip + 1]) { + phii = ip; + break; + } + } + if (etai < etaBounds_.size() && phii < phiBounds_.size()) { + regionPtIndices_[etai * (phiBounds_.size() - 1) + phii].emplace_back(pt, index); + } + } else { + regionPtIndices_[0].emplace_back(pt, index); + } +} + +std::vector l1tpf_calo::GridSelector::returnSorted() { + std::vector indices; + for (auto ®ionPtIndex : regionPtIndices_) { + std::sort(regionPtIndex.begin(), regionPtIndex.end(), std::greater>()); + for (const auto &p : regionPtIndex) { + indices.push_back(p.second); + } + } + return indices; +} + std::unique_ptr l1tpf_calo::makeCaloLinker(const edm::ParameterSet &pset, const SingleCaloClusterer &ecal, const SingleCaloClusterer &hcal) { @@ -632,6 +801,8 @@ std::unique_ptr l1tpf_calo::makeCaloLinker(con return std::make_unique(pset, ecal, hcal); } else if (algo == "flat") { return std::make_unique(pset, ecal, hcal); + } else if (algo == "combined") { + return std::make_unique(pset, ecal, hcal); } else { throw cms::Exception("Configuration") << "Unsupported linker algo '" << algo << "'\n"; } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc b/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc index d8c04b82690bd..3edd861eb159c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc +++ b/L1Trigger/Phase2L1ParticleFlow/src/corrector.cc @@ -1,4 +1,4 @@ -#include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/corrector.h" #include #include @@ -11,46 +11,89 @@ #include #include #include + +#ifdef CMSSW_GIT_HASH #include "FWCore/Utilities/interface/CPUTimer.h" #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/ParameterSet/interface/FileInPath.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "DataFormats/L1TParticleFlow/interface/PFCluster.h" +#else +#include +#include +#include +#endif -l1tpf::corrector::corrector(const std::string &filename, float emfMax, bool debug) : emfMax_(emfMax) { +/* --- + * Note: #ifdef CMSSW_GIT_HASH is used to determine whether compilation is in CMSSW context or not + * since this same implementation is used in the standalone tests of corrections in comparison to + * L1T firmware + * --- */ + +l1tpf::corrector::corrector(const std::string &filename, float emfMax, bool debug, bool emulate) + : emfMax_(emfMax), emulate_(emulate) { if (!filename.empty()) - init_(filename, "", debug); + init_(filename, "", debug, emulate); } -l1tpf::corrector::corrector(const std::string &filename, const std::string &directory, float emfMax, bool debug) - : emfMax_(emfMax) { + +l1tpf::corrector::corrector( + const std::string &filename, const std::string &directory, float emfMax, bool debug, bool emulate) + : emfMax_(emfMax), emulate_(emulate) { if (!filename.empty()) - init_(filename, directory, debug); + init_(filename, directory, debug, emulate); } -l1tpf::corrector::corrector(TDirectory *src, float emfMax, bool debug) : emfMax_(emfMax) { init_(src, debug); } +l1tpf::corrector::corrector(TDirectory *src, float emfMax, bool debug, bool emulate) + : emfMax_(emfMax), emulate_(emulate) { + init_(src, debug); +} -void l1tpf::corrector::init_(const std::string &filename, const std::string &directory, bool debug) { +void l1tpf::corrector::init_(const std::string &filename, const std::string &directory, bool debug, bool emulate) { std::string resolvedFileName = filename; - if (filename[0] != '/') + if (filename[0] != '/') { +#ifdef CMSSW_GIT_HASH resolvedFileName = edm::FileInPath(filename).fullPath(); +#else + resolvedFileName = std::filesystem::absolute(filename); +#endif + } TFile *lFile = TFile::Open(resolvedFileName.c_str()); - if (!lFile || lFile->IsZombie()) + if (!lFile || lFile->IsZombie()) { +#ifdef CMSSW_GIT_HASH throw cms::Exception("Configuration", "cannot read file " + filename); +#else + throw std::runtime_error("Cannot read file " + filename); +#endif + } TDirectory *dir = directory.empty() ? lFile : lFile->GetDirectory(directory.c_str()); - if (!dir) + if (!dir) { +#ifdef CMSSW_GIT_HASH throw cms::Exception("Configuration", "cannot find directory '" + directory + "' in file " + filename); +#else + throw std::runtime_error("Cannot find directory '" + directory + "' in file " + filename); +#endif + } init_(dir, debug); + if (emulate) + initEmulation_(dir, debug); lFile->Close(); } void l1tpf::corrector::init_(TDirectory *lFile, bool debug) { TH1 *index = (TH1 *)lFile->Get("INDEX"); - if (!index) + if (!index) { +#ifdef CMSSW_GIT_HASH throw cms::Exception("Configuration") << "invalid input file " << lFile->GetPath() << ": INDEX histogram not found.\n"; +#else + std::stringstream ss; + ss << "invalid input file " << lFile->GetPath() << ": INDEX histogram nit found.\n"; + throw std::runtime_error(ss.str()); +#endif + } index_.reset((TH1 *)index->Clone()); index_->SetDirectory(nullptr); @@ -82,9 +125,15 @@ void l1tpf::corrector::init_(TDirectory *lFile, bool debug) { snprintf(buff, 31, "eta_bin%d", ieta + 1); } TGraph *graph = graphs[buff]; - if (debug) + if (debug) { +#ifdef CMSSW_GIT_HASH edm::LogPrint("corrector") << " eta bin " << ieta << " emf bin " << iemf << " graph " << buff << (graph ? " " : " ") << "\n"; +#else + std::cout << " eta bin " << ieta << " emf bin " << iemf << " graph " << buff + << (graph ? " " : " ") << "\n"; +#endif + } if (graph) { ngraphs++; corrections_[ieta * nemf_ + iemf] = (TGraph *)graph->Clone(); @@ -96,6 +145,39 @@ void l1tpf::corrector::init_(TDirectory *lFile, bool debug) { } } +void l1tpf::corrector::initEmulation_(TDirectory *lFile, bool debug) { + std::unordered_map hists; + TKey *key; + TIter nextkey(lFile->GetListOfKeys()); + while ((key = (TKey *)nextkey())) { + if (strncmp(key->GetName(), "emul_eta", 8) == 0) { + TH1 *hist = (TH1 *)key->ReadObj(); + hists[key->GetName()] = hist; + } + } + + neta_ = index_->GetNbinsX(); + correctionsEmulated_.resize(neta_); + std::fill(correctionsEmulated_.begin(), correctionsEmulated_.end(), nullptr); + char buff[32]; + int nhists = 0; + for (unsigned int ieta = 0; ieta < neta_; ++ieta) { + snprintf(buff, 31, "emul_eta_bin%d", ieta + 1); + TH1 *hist = hists[buff]; + if (debug) +#ifdef CMSSW_GIT_HASH + edm::LogPrint("corrector") << " eta bin " << ieta << " hist " << buff << (hist ? " " : " ") << "\n"; +#else + std::cout << " eta bin " << ieta << " hist " << buff << (hist ? " " : " ") << "\n"; +#endif + if (hist) { + nhists++; + correctionsEmulated_[ieta] = (TH1 *)hist->Clone(); + correctionsEmulated_[ieta]->SetDirectory(nullptr); + } + } +} + l1tpf::corrector::corrector(const TH1 *index, float emfMax) : index_((TH1 *)index->Clone("INDEX")), is2d_(index->InheritsFrom("TH2")), @@ -113,48 +195,84 @@ l1tpf::corrector::~corrector() { p = nullptr; } corrections_.clear(); + for (TH1 *&p : correctionsEmulated_) { + delete p; + p = nullptr; + } + correctionsEmulated_.clear(); } l1tpf::corrector::corrector(corrector &&corr) : index_(std::move(corr.index_)), corrections_(std::move(corr.corrections_)), + correctionsEmulated_(std::move(corr.correctionsEmulated_)), is2d_(corr.is2d_), neta_(corr.neta_), nemf_(corr.nemf_), - emfMax_(corr.emfMax_) {} + emfMax_(corr.emfMax_), + emulate_(corr.emulate_) {} l1tpf::corrector &l1tpf::corrector::operator=(corrector &&corr) { std::swap(is2d_, corr.is2d_); std::swap(neta_, corr.neta_); std::swap(nemf_, corr.nemf_); std::swap(emfMax_, corr.emfMax_); + std::swap(emulate_, corr.emulate_); index_.swap(corr.index_); corrections_.swap(corr.corrections_); + correctionsEmulated_.swap(corr.correctionsEmulated_); return *this; } float l1tpf::corrector::correctedPt(float pt, float emPt, float eta) const { + unsigned int ipt, ieta; float total = std::max(pt, emPt), abseta = std::abs(eta); float emf = emPt / total; if (emfMax_ > 0 && emf > emfMax_) return total; // no correction - unsigned int ieta = std::min(std::max(1, index_->GetXaxis()->FindBin(abseta)), neta_) - 1; + ieta = std::min(std::max(1, index_->GetXaxis()->FindBin(abseta)), neta_) - 1; unsigned int iemf = is2d_ && abseta < 3.0 ? std::min(std::max(1, index_->GetYaxis()->FindBin(emf)), nemf_) - 1 : 0; - TGraph *graph = corrections_[ieta * nemf_ + iemf]; - if (!graph) { - throw cms::Exception("RuntimeError") << "Error trying to read calibration for eta " << eta << " emf " << emf - << " which are not available." << std::endl; + float ptcorr = 0; + if (!emulate_) { // not emulation - read from the TGraph as normal + TGraph *graph = corrections_[ieta * nemf_ + iemf]; + if (!graph) { +#ifdef CMSSW_GIT_HASH + throw cms::Exception("RuntimeError") << "Error trying to read calibration for eta " << eta << " emf " << emf + << " which are not available." << std::endl; +#else + std::stringstream ss; + ss << "Error trying to read calibration for eta " << eta << " emf " << emf << " which are not available." + << std::endl; + throw std::runtime_error(ss.str()); +#endif + } + ptcorr = std::min(graph->Eval(total), 4 * total); + } else { // emulation - read from the pt binned histogram + TH1 *hist = correctionsEmulated_[ieta]; + if (!hist) { +#ifdef CMSSW_GIT_HASH + throw cms::Exception("RuntimeError") + << "Error trying to read emulated calibration for eta " << eta << " which are not available." << std::endl; +#else + std::stringstream ss; + ss << "Error trying to read emulated calibration for eta " << eta << " which are not available." << std::endl; + throw std::runtime_error(ss.str()); +#endif + } + ipt = hist->GetXaxis()->FindBin(pt); + ptcorr = hist->GetBinContent(ipt); } - float ptcorr = std::min(graph->Eval(total), 4 * total); return ptcorr; } +#ifdef CMSSW_GIT_HASH void l1tpf::corrector::correctPt(l1t::PFCluster &cluster, float preserveEmEt) const { float newpt = correctedPt(cluster.pt(), cluster.emEt(), cluster.eta()); cluster.calibratePt(newpt, preserveEmEt); } +#endif void l1tpf::corrector::setGraph(const TGraph &graph, int ieta, int iemf) { char buff[32]; @@ -185,4 +303,10 @@ void l1tpf::corrector::writeToFile(TDirectory *dest) const { dest->WriteTObject((TGraph *)p->Clone(), p->GetName()); } } + + for (const TH1 *p : correctionsEmulated_) { + if (p != nullptr) { + dest->WriteTObject((TH1 *)p->Clone(), p->GetName()); + } + } } diff --git a/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_input.cpp b/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_input.cpp index 1c0c8ef939cdc..102b31f2ec0d6 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_input.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_input.cpp @@ -1,87 +1,77 @@ -#include -#include #include #include "L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" -l1ct::DeregionizerInput::DeregionizerInput(std::vector ®ionEtaCenter, - std::vector ®ionPhiCenter, - const std::vector &inputRegions) - : regionEtaCenter_(regionEtaCenter), regionPhiCenter_(regionPhiCenter) { - orderedInRegionsPuppis_ = std::vector > >(nEtaRegions); - for (int i = 0, n = nEtaRegions; i < n; i++) - orderedInRegionsPuppis_[i].resize(nPhiRegions); - initRegions(inputRegions); -} - -// +pi read first & account for 2 small eta regions per phi slice -unsigned int l1ct::DeregionizerInput::orderRegionsInPhi(const float eta, const float phi, const float etaComp) const { - unsigned int y; - if (fabs(phi) < 0.35) - y = (eta < etaComp ? 0 : 1); - else if (fabs(phi) < 1.05) - y = (phi > 0 ? (eta < etaComp ? 2 : 3) : (eta < etaComp ? 16 : 17)); - else if (fabs(phi) < 1.75) - y = (phi > 0 ? (eta < etaComp ? 4 : 5) : (eta < etaComp ? 14 : 15)); - else if (fabs(phi) < 2.45) - y = (phi > 0 ? (eta < etaComp ? 6 : 7) : (eta < etaComp ? 12 : 13)); - else - y = (phi > 0 ? (eta < etaComp ? 8 : 9) : (eta < etaComp ? 10 : 11)); - return y; +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" +l1ct::DeregionizerInput::DeregionizerInput(const std::vector linkConfigs) { + for (const auto &pset : linkConfigs) { + DeregionizerInput::BoardInfo boardInfo; + boardInfo.nOutputFramesPerBX_ = pset.getParameter("nOutputFramesPerBX"); + boardInfo.nLinksPuppi_ = pset.getParameter("nLinksPuppi"); + boardInfo.nPuppiPerRegion_ = pset.getParameter("nPuppiPerRegion"); + boardInfo.order_ = pset.getParameter("outputBoard"); + boardInfo.regions_ = pset.getParameter>("outputRegions"); + boardInfo.nPuppiFramesPerRegion_ = (boardInfo.nOutputFramesPerBX_ * tmuxFactor_) / boardInfo.regions_.size(); + boardInfos_.push_back(boardInfo); + } } +#endif -void l1ct::DeregionizerInput::initRegions(const std::vector &inputRegions) { - for (int i = 0, n = inputRegions.size(); i < n; i++) { - unsigned int x, y; - float eta = regionEtaCenter_[i]; - float phi = regionPhiCenter_[i]; - - if (fabs(eta) < 0.5) { - x = 0; - y = orderRegionsInPhi(eta, phi, 0.0); - } else if (fabs(eta) < 1.5) { - x = (eta < 0.0 ? 1 : 2); - y = (eta < 0.0 ? orderRegionsInPhi(eta, phi, -1.0) : orderRegionsInPhi(eta, phi, 1.0)); - } else if (fabs(eta) < 2.5) { - x = (eta < 0.0 ? 3 : 4); - y = orderRegionsInPhi(eta, phi, 999.0); // Send all candidates in 3 clks, then wait 3 clks for the barrel - } else /*if ( fabs(eta) < 3.0 )*/ { - x = 5; - y = orderRegionsInPhi(eta, phi, 0.0); // Send eta<0 in 3 clks, eta>0 in the next 3 clks +std::vector l1ct::DeregionizerInput::inputOrderInfo( + const std::vector &inputRegions) const { + // Vector of all puppis in event paired with LinkPlacementInfo + std::vector linkPlacedPuppis; + for (BoardInfo boardInfo : boardInfos_) { + for (uint iRegion = 0; iRegion < boardInfo.regions_.size(); iRegion++) { + uint iRegionEvent = boardInfo.regions_.at(iRegion); + auto puppi = inputRegions.at(iRegionEvent).puppi; + unsigned int npuppi = puppi.size(); + for (unsigned int i = 0; i < boardInfo.nLinksPuppi_ * boardInfo.nPuppiFramesPerRegion_; ++i) { + if (i < npuppi) { + uint iClock = + iRegion * boardInfo.nPuppiPerRegion_ / boardInfo.nLinksPuppi_ + i % boardInfo.nPuppiFramesPerRegion_; + uint iLink = i / boardInfo.nPuppiFramesPerRegion_; + LPI lpi = {boardInfo.order_, iLink, iClock}; + linkPlacedPuppis.push_back(std::make_pair(puppi.at(i), lpi)); + } + } } - /*else x = 6;*/ // HF - - orderedInRegionsPuppis_[x][y].insert(orderedInRegionsPuppis_[x][y].end(), - inputRegions[i].puppi.begin(), - inputRegions[i].puppi.end()); // For now, merging HF with forward HGCal - - while (!orderedInRegionsPuppis_[x][y].empty() && orderedInRegionsPuppis_[x][y].back().hwPt == 0) - orderedInRegionsPuppis_[x][y].pop_back(); // Zero suppression } + return linkPlacedPuppis; } -void l1ct::DeregionizerInput::orderRegions(int order[nEtaRegions]) { - std::vector > > tmpOrderedInRegionsPuppis; - for (int i = 0, n = nEtaRegions; i < n; i++) - tmpOrderedInRegionsPuppis.push_back(orderedInRegionsPuppis_[order[i]]); - orderedInRegionsPuppis_ = tmpOrderedInRegionsPuppis; - - if (debug_) { - for (int i = 0, nx = orderedInRegionsPuppis_.size(); i < nx; i++) { - dbgCout() << "\n"; - dbgCout() << "Eta region index : " << i << "\n"; - for (int j = 0, ny = orderedInRegionsPuppis_[i].size(); j < ny; j++) { - dbgCout() << " ---> Phi region index : " << j << "\n"; - for (int iPup = 0, nPup = orderedInRegionsPuppis_[i][j].size(); iPup < nPup; iPup++) { - dbgCout() << " > puppi[" << iPup << "]" - << " pt = " << orderedInRegionsPuppis_[i][j][iPup].hwPt << "\n"; +std::vector>> l1ct::DeregionizerInput::orderInputs( + const std::vector &inputRegions) const { + std::vector linkPlacedPuppis = inputOrderInfo(inputRegions); + std::vector>> layer2inReshape(nInputFramesPerBX_ * tmuxFactor_); + for (uint iClock = 0; iClock < nInputFramesPerBX_ * tmuxFactor_; iClock++) { + std::vector> orderedPupsOnClock(boardInfos_.size()); + // Find all the puppis on this clock cycle + for (BoardInfo boardInfo : boardInfos_) { + // find all puppis on this clock cycle, from this board + std::vector orderedPupsOnClockOnBoard; + for (uint iLink = 0; iLink < boardInfo.nLinksPuppi_; iLink++) { + // find all puppis from this clock cycle, from this board, from this link + auto onClockOnBoardOnLink = [&](PlacedPuppi p) { + return (p.second.clock_cycle_ == iClock) && (p.second.board_ == boardInfo.order_) && + (p.second.link_ == iLink); + }; + std::vector allPupsOnClockOnBoardOnLink; + std::copy_if(std::begin(linkPlacedPuppis), + std::end(linkPlacedPuppis), + std::back_inserter(allPupsOnClockOnBoardOnLink), + onClockOnBoardOnLink); + linkPlacedPuppis.erase( + std::remove_if(std::begin(linkPlacedPuppis), std::end(linkPlacedPuppis), onClockOnBoardOnLink), + std::end(linkPlacedPuppis)); // erase already placed pups + if (!allPupsOnClockOnBoardOnLink.empty()) { + orderedPupsOnClockOnBoard.push_back(allPupsOnClockOnBoardOnLink.at(0).first); } } - dbgCout() << " ----------------- " - << "\n"; + orderedPupsOnClock.at(boardInfo.order_) = orderedPupsOnClockOnBoard; } - dbgCout() << "Regions ordered!" - << "\n"; - dbgCout() << "\n"; + layer2inReshape.at(iClock) = orderedPupsOnClock; } -} + return layer2inReshape; +} \ No newline at end of file diff --git a/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_ref.cpp index 7b900c4b0b2ea..29dac7bf626e7 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_ref.cpp @@ -33,23 +33,11 @@ l1ct::DeregionizerEmulator::DeregionizerEmulator(const unsigned int nPuppiFinalB nPuppiSecondBuffers < nPuppiThirdBuffers && nPuppiThirdBuffers <= nPuppiFinalBuffer); } -std::vector > l1ct::DeregionizerEmulator::splitPFregions( - const std::vector > > ®ionPuppis, const int i, const int j) { - int k = nPuppiPerClk_ * j; - std::vector > subregionPuppis; - for (int l = 0, n = regionPuppis.size(); l < n; l++) { - const auto &puppis = regionPuppis[l][i]; - std::vector tmp(std::min(puppis.begin() + k, puppis.end()), - std::min(puppis.begin() + k + nPuppiPerClk_, puppis.end())); - subregionPuppis.push_back(tmp); - } - return subregionPuppis; -} - std::vector l1ct::DeregionizerEmulator::mergeXtoY(const unsigned int X, const unsigned int Y, const std::vector &inLeft, const std::vector &inRight) { + // merge X to Y with truncation std::vector out; out.insert(out.end(), inLeft.begin(), std::min(inLeft.end(), inLeft.begin() + X)); @@ -58,6 +46,17 @@ std::vector l1ct::DeregionizerEmulator::mergeXtoY(const unsig return out; } +std::vector l1ct::DeregionizerEmulator::mergeXtoY(const std::vector &inLeft, + const std::vector &inRight) { + // merge X to Y with no truncation + std::vector out; + + out.insert(out.end(), inLeft.begin(), inLeft.end()); + out.insert(out.end(), inRight.begin(), inRight.end()); + + return out; +} + void l1ct::DeregionizerEmulator::accumulateToY(const unsigned int Y, const std::vector &in, std::vector &out, @@ -80,69 +79,20 @@ static void debugPrint(const std::string &header, const std::vector puppi[" << iPup << "] pT = " << pup[iPup].hwPt << "\n"; } -void l1ct::DeregionizerEmulator::run(const l1ct::DeregionizerInput in, +void l1ct::DeregionizerEmulator::run(std::vector>> in, std::vector &out, std::vector &truncated) { - const auto ®ionPuppis = in.orderedInRegionsPuppis(); - std::vector intermediateTruncated; - - for (int i = 0, n = in.nPhiRegions; i < n; i++) { - // Each PF region (containing at most 18 puppi candidates) is split in 3(*nPuppiPerClk=18) - for (int j = 0; j < 3; j++) { - std::vector > subregionPuppis = splitPFregions(regionPuppis, i, j); - - // Merge PF regions in pairs - std::vector buffer01 = - mergeXtoY(nPuppiPerClk_, nPuppiFirstBuffers_, subregionPuppis[0], subregionPuppis[1]); - std::vector buffer23 = - mergeXtoY(nPuppiPerClk_, nPuppiFirstBuffers_, subregionPuppis[2], subregionPuppis[3]); - std::vector buffer45 = - mergeXtoY(nPuppiPerClk_, nPuppiFirstBuffers_, subregionPuppis[4], subregionPuppis[5]); - - // Merge 4 first regions together, forward the last 2 - std::vector buffer0123 = - mergeXtoY(nPuppiFirstBuffers_, nPuppiSecondBuffers_, buffer01, buffer23); - std::vector buffer45ext; - accumulateToY(nPuppiSecondBuffers_, buffer45, buffer45ext, intermediateTruncated); - - // Merge all regions together and forward them to the final buffer - std::vector buffer012345 = - mergeXtoY(nPuppiSecondBuffers_, nPuppiThirdBuffers_, buffer0123, buffer45ext); - accumulateToY(nPuppiFinalBuffer_, buffer012345, out, truncated); - - if (debug_) { - dbgCout() << "\n"; - dbgCout() << "Phi region index : " << i << "," << j << "\n"; - - debugPrint("Eta region : 0", subregionPuppis[0]); - debugPrint("Eta region : 1", subregionPuppis[1]); - debugPrint("Eta region : 0+1", buffer01); - dbgCout() << "------------------ " - << "\n"; - - debugPrint("Eta region : 2", subregionPuppis[2]); - debugPrint("Eta region : 3", subregionPuppis[3]); - debugPrint("Eta region : 2+3", buffer23); - dbgCout() << "------------------ " - << "\n"; - - debugPrint("Eta region : 4", subregionPuppis[4]); - debugPrint("Eta region : 5", subregionPuppis[5]); - debugPrint("Eta region : 4+5", buffer45); - dbgCout() << "------------------ " - << "\n"; - - debugPrint("Eta region : 0+1+2+3", buffer0123); - dbgCout() << "------------------ " - << "\n"; - - debugPrint("Eta region : 0+1+2+3+4+5", buffer012345); - dbgCout() << "------------------ " - << "\n"; - - debugPrint("Inclusive", out); - } + for (int i = 0, n = in.size(); i < n; i++) { + std::vector> pupsOnClock = in[i]; + std::vector intermediateTruncated; + // Merge PF regions from this cycle. No truncation happens here + std::vector buffer; + for (const auto &pupsOnClockOnBoard : pupsOnClock) { + buffer = mergeXtoY(buffer, pupsOnClockOnBoard); } + + // accumulate PF regions over cycles, truncation may happen here + accumulateToY(nPuppiFinalBuffer_, buffer, out, truncated); } if (debug_) { diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc new file mode 100644 index 0000000000000..4d77d7866c0c0 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/L1EGPuppiIsoAlgo.cc @@ -0,0 +1,132 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/L1EGPuppiIsoAlgo.h" + +using namespace l1ct; + +L1EGPuppiIsoAlgo::L1EGPuppiIsoAlgo(const edm::ParameterSet& pSet) + : config_(pSet.getParameter("pfIsoType"), + pSet.getParameter("pfPtMin"), + pSet.getParameter("dZ"), + pSet.getParameter("dRMin"), + pSet.getParameter("dRMax"), + pSet.getParameter("pfCandReuse")) {} + +void L1EGPuppiIsoAlgo::run(const EGIsoObjsEmu& l1EGs, + const PuppiObjs& l1PFCands, + EGIsoObjsEmu& outL1EGs, + z0_t z0) const { + outL1EGs.reserve(l1EGs.size()); + + // make a list of pointers to PF candidates + // the pointer will be removed from the list once the candidate has been used and the the module is configured to to so + std::list workPFCands; + std::list workPFCandsPV; + for (const auto& l1PFCand : l1PFCands) { + workPFCands.emplace_back(&l1PFCand); + workPFCandsPV.emplace_back(&l1PFCand); + } + + for (const auto& l1EG : l1EGs) { + auto outL1EG(l1EG); + iso_t iso = 0; + iso_t isoPV = 0; + if (!workPFCands.empty()) { + iso = calcIso(l1EG, workPFCands); + isoPV = calcIso(l1EG, workPFCandsPV, z0); + } + + if (config_.pfIsoType_ == L1EGPuppiIsoAlgoConfig::kPFIso) { + outL1EG.setHwIso(EGIsoObjEmu::IsoType::PfIso, iso); + outL1EG.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, isoPV); + } else { + outL1EG.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, iso); + outL1EG.setHwIso(EGIsoObjEmu::IsoType::PuppiIsoPV, isoPV); + } + outL1EGs.emplace_back(outL1EG); + } +} + +void L1EGPuppiIsoAlgo::run(EGIsoObjsEmu& l1EGs, const PuppiObjs& l1PFCands, z0_t z0) const { + // make a list of pointers to PF candidates + // the pointer will be removed from the list once the candidate has been used and the the module is configured to to so + std::list workPFCands; + std::list workPFCandsPV; + for (const auto& l1PFCand : l1PFCands) { + workPFCands.emplace_back(&l1PFCand); + workPFCandsPV.emplace_back(&l1PFCand); + } + + for (auto& l1EG : l1EGs) { + iso_t iso = 0; + iso_t isoPV = 0; + if (!workPFCands.empty()) { + iso = calcIso(l1EG, workPFCands); + isoPV = calcIso(l1EG, workPFCandsPV, z0); + } + + if (config_.pfIsoType_ == L1EGPuppiIsoAlgoConfig::kPFIso) { + l1EG.setHwIso(EGIsoObjEmu::IsoType::PfIso, iso); + l1EG.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, isoPV); + } else { + l1EG.setHwIso(EGIsoObjEmu::IsoType::PuppiIso, iso); + l1EG.setHwIso(EGIsoObjEmu::IsoType::PuppiIsoPV, isoPV); + } + } +} + +void L1EGPuppiIsoAlgo::run(EGIsoEleObjsEmu& l1Eles, const PuppiObjs& l1PFCands) const { + // make a list of pointers to PF candidates + // the pointer will be removed from the list once the candidate has been used and the the module is configured to to so + std::list workPFCands; + for (const auto& l1PFCand : l1PFCands) { + workPFCands.emplace_back(&l1PFCand); + } + + for (auto& l1Ele : l1Eles) { + iso_t iso = 0; + if (!workPFCands.empty()) { + iso = calcIso(l1Ele, workPFCands); + } + + if (config_.pfIsoType_ == L1EGPuppiIsoAlgoConfig::kPFIso) { + l1Ele.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, iso); + } else { + l1Ele.setHwIso(EGIsoEleObjEmu::IsoType::PuppiIso, iso); + } + } +} + +iso_t L1EGPuppiIsoAlgo::calcIso(const EGIsoObj& l1EG, std::list& workPFCands, z0_t z0) const { + iso_t sumPt = 0; + + auto pfIt = workPFCands.cbegin(); + while (pfIt != workPFCands.cend()) { + // use the PF candidate pT if it is within the cone and optional dz cut for charged PF candidates + const auto workPFCand = *pfIt; + z0_t pfCandZ0 = 0; + if (workPFCand->hwId.charged()) { + pfCandZ0 = workPFCand->hwZ0(); + } + + // calculate dz + ap_int dz = z0 - pfCandZ0; + if (dz < 0) { + dz = -dz; + } + + if (workPFCand->intCharge() == 0 || (workPFCand->intCharge() != 0 && dz < config_.dZMax_)) { + const auto dR2 = dr2_int(l1EG.hwEta, l1EG.hwPhi, workPFCand->hwEta, workPFCand->hwPhi); + if (dR2 >= config_.dRMin2_ && dR2 < config_.dRMax2_ && workPFCand->hwPt >= config_.ptMin_) { + sumPt += workPFCand->hwPt; + // remove the candidate from the collection if the module is configured to not reuse them + if (!config_.pfCandReuse_) { + // this returns an iterator to the next element already so no need to increase here + pfIt = workPFCands.erase(pfIt); + continue; + } + } + } + ++pfIt; + } + + return sumPt; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/buffered_folded_multififo_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/buffered_folded_multififo_regionizer_ref.cpp new file mode 100644 index 0000000000000..a9dbeba35ee2d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/buffered_folded_multififo_regionizer_ref.cpp @@ -0,0 +1,289 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h" + +#include +#include + +l1ct::BufferedFoldedMultififoRegionizerEmulator::BufferedFoldedMultififoRegionizerEmulator(unsigned int nclocks, + unsigned int ntk, + unsigned int ncalo, + unsigned int nem, + unsigned int nmu, + bool streaming, + unsigned int outii, + unsigned int pauseii, + bool useAlsoVtxCoords) + : FoldedMultififoRegionizerEmulator(nclocks, + /*NTK_LINKS*/ 1, + /*NCALO_LINKS*/ 1, + ntk, + ncalo, + nem, + nmu, + streaming, + outii, + pauseii, + useAlsoVtxCoords), + tkBuffers_(ntk ? 2 * NTK_SECTORS : 0), + caloBuffers_(ncalo ? 2 * NCALO_SECTORS : 0), + muBuffers_(nmu ? 2 : 0) {} + +l1ct::BufferedFoldedMultififoRegionizerEmulator::~BufferedFoldedMultififoRegionizerEmulator() {} + +void l1ct::BufferedFoldedMultififoRegionizerEmulator::findEtaBounds_(const l1ct::PFRegionEmu& sec, + const std::vector& reg, + l1ct::glbeta_t& etaMin, + l1ct::glbeta_t& etaMax) { + etaMin = reg[0].region.hwEtaCenter - reg[0].region.hwEtaHalfWidth - reg[0].region.hwEtaExtra - sec.hwEtaCenter; + etaMax = reg[0].region.hwEtaCenter + reg[0].region.hwEtaHalfWidth + reg[0].region.hwEtaExtra - sec.hwEtaCenter; + for (const auto& r : reg) { + etaMin = std::min( + etaMin, r.region.hwEtaCenter - r.region.hwEtaHalfWidth - r.region.hwEtaExtra - sec.hwEtaCenter); + etaMax = std::max( + etaMax, r.region.hwEtaCenter + r.region.hwEtaHalfWidth + r.region.hwEtaExtra - sec.hwEtaCenter); + } +} +void l1ct::BufferedFoldedMultififoRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedInputs& in, + const std::vector& out) { + assert(!init_); + FoldedMultififoRegionizerEmulator::initSectorsAndRegions(in, out); + for (int ie = 0; ie < 2; ++ie) { + l1ct::glbeta_t etaMin, etaMax; + findEtaBounds_(fold_[ie].sectors.track[0].region, fold_[ie].regions, etaMin, etaMax); + for (unsigned int isec = 0; ntk_ > 0 && isec < NTK_SECTORS; ++isec) { + tkBuffers_[2 * isec + ie] = l1ct::multififo_regionizer::EtaBuffer(nclocks_ / 2, etaMin, etaMax); + } + findEtaBounds_(fold_[ie].sectors.hadcalo[0].region, fold_[ie].regions, etaMin, etaMax); + for (unsigned int isec = 0; ncalo_ > 0 && isec < NCALO_SECTORS; ++isec) { + caloBuffers_[2 * isec + ie] = + l1ct::multififo_regionizer::EtaBuffer(nclocks_ / 2, etaMin, etaMax); + } + findEtaBounds_(fold_[ie].sectors.muon.region, fold_[ie].regions, etaMin, etaMax); + if (nmu_ > 0) { + muBuffers_[ie] = l1ct::multififo_regionizer::EtaBuffer(nclocks_ / 2, etaMin, etaMax); + } + } +} + +template +void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinksPosNeg_( + unsigned int iclock, + const std::vector>& secNeg, + const std::vector>& secPos, + std::vector& links, + std::vector& valid) { + unsigned int nlinks = secNeg.size(); + links.resize(2 * nlinks); + valid.resize(2 * nlinks); + for (unsigned int isec = 0, ilink = 0; isec < nlinks; ++isec) { + for (int ec = 0; ec < 2; ++ec, ++ilink) { + const l1ct::DetectorSector& sec = (ec ? secPos : secNeg)[isec]; + if (iclock < sec.size() && iclock < nclocks_ - 1) { + valid[ilink] = true; + links[ilink] = sec.obj[iclock]; + } else { + valid[ilink] = false; + links[ilink].clear(); + } + } + } +} +void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinks(unsigned int iclock, + std::vector& links, + std::vector& valid) { + if (ntk_) + fillLinksPosNeg_(iclock, fold_[0].sectors.track, fold_[1].sectors.track, links, valid); +} + +void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinks(unsigned int iclock, + std::vector& links, + std::vector& valid) { + if (ncalo_) + fillLinksPosNeg_(iclock, fold_[0].sectors.hadcalo, fold_[1].sectors.hadcalo, links, valid); +} +void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinks(unsigned int iclock, + std::vector& links, + std::vector& valid) { + // nothing to do normally +} + +void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinks(unsigned int iclock, + std::vector& links, + std::vector& valid) { + if (nmu_ == 0) + return; + assert(NMU_LINKS == 1); + links.resize(NMU_LINKS); + valid.resize(links.size()); + const auto& in = fold_.front().sectors.muon.obj; + if (iclock < in.size() && iclock < nclocks_ - 1) { + links[0] = in[iclock]; + valid[0] = true; + } else { + links[0].clear(); + valid[0] = false; + } +} + +bool l1ct::BufferedFoldedMultififoRegionizerEmulator::step(bool newEvent, + const std::vector& links_tk, + const std::vector& links_hadCalo, + const std::vector& links_emCalo, + const std::vector& links_mu, + std::vector& out_tk, + std::vector& out_hadCalo, + std::vector& out_emCalo, + std::vector& out_mu, + bool mux) { + iclock_ = (newEvent ? 0 : iclock_ + 1); + int ifold = (iclock_ / clocksPerFold_); + bool newSubEvent = iclock_ % clocksPerFold_ == 0; + + if (newEvent) { + for (auto& b : tkBuffers_) + b.writeNewEvent(); + for (auto& b : caloBuffers_) + b.writeNewEvent(); + for (auto& b : muBuffers_) + b.writeNewEvent(); + } + + assert(links_tk.size() == tkBuffers_.size() || ntk_ == 0); + for (unsigned int i = 0; ntk_ > 0 && i < 2 * NTK_SECTORS; ++i) { + tkBuffers_[i].maybe_push(links_tk[i]); + } + assert(links_hadCalo.size() == caloBuffers_.size() || ncalo_ == 0); + for (unsigned int i = 0; ncalo_ > 0 && i < 2 * NCALO_SECTORS; ++i) { + caloBuffers_[i].maybe_push(links_hadCalo[i]); + } + for (unsigned int i = 0; nmu_ > 0 && i < 2; ++i) { + muBuffers_[i].maybe_push(links_mu[0]); + } + if (newSubEvent && !newEvent) { + for (auto& b : tkBuffers_) + b.readNewEvent(); + for (auto& b : caloBuffers_) + b.readNewEvent(); + for (auto& b : muBuffers_) + b.readNewEvent(); + } + std::vector mylinks_tk(ntk_ ? NTK_SECTORS : 0); + std::vector mylinks_hadCalo(ncalo_ ? NCALO_SECTORS : 0); + std::vector mylinks_emCalo(0); + std::vector mylinks_mu(nmu_ ? 1 : 0); + for (unsigned int i = 0, ib = 1 - ifold; ntk_ > 0 && i < NTK_SECTORS; ++i, ib += 2) { + mylinks_tk[i] = tkBuffers_[ib].pop(); + } + for (unsigned int i = 0, ib = 1 - ifold; ncalo_ > 0 && i < NCALO_SECTORS; ++i, ib += 2) { + mylinks_hadCalo[i] = caloBuffers_[ib].pop(); + } + if (nmu_) { + mylinks_mu[0] = muBuffers_[1 - ifold].pop(); + } + + bool ret = false; + if (!mux) { + Fold& f = fold_[1 - ifold]; + ret = f.regionizer->step(newSubEvent, + mylinks_tk, + mylinks_hadCalo, + mylinks_emCalo, + mylinks_mu, + out_tk, + out_hadCalo, + out_emCalo, + out_mu, + false); + } else { + unsigned int inputFold = 1 - ifold; + unsigned int outputFold = ifold; + std::vector nolinks_tk(mylinks_tk.size()); + std::vector nolinks_hadCalo(mylinks_hadCalo.size()); + std::vector nolinks_emCalo(mylinks_emCalo.size()); + std::vector nolinks_mu(mylinks_mu.size()); + std::vector noout_tk; + std::vector noout_hadCalo; + std::vector noout_emCalo; + std::vector noout_mu; + for (auto& f : fold_) { + bool fret = f.regionizer->step(newSubEvent, + f.index == inputFold ? mylinks_tk : nolinks_tk, + f.index == inputFold ? mylinks_hadCalo : nolinks_hadCalo, + f.index == inputFold ? mylinks_emCalo : nolinks_emCalo, + f.index == inputFold ? mylinks_mu : nolinks_mu, + f.index == outputFold ? out_tk : noout_tk, + f.index == outputFold ? out_hadCalo : noout_hadCalo, + f.index == outputFold ? out_emCalo : noout_emCalo, + f.index == outputFold ? out_mu : noout_mu, + true); + if (f.index == outputFold) + ret = fret; + } + } + return ret; +} + +void l1ct::BufferedFoldedMultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in, + std::vector& out) { + if (!init_) + initSectorsAndRegions(in, out); + else { + fillEvent(in); + for (auto& f : fold_) + f.regionizer->reset(); + } + + std::vector tk_links_in, tk_out; + std::vector em_links_in, em_out; + std::vector calo_links_in, calo_out; + std::vector mu_links_in, mu_out; + + // read and sort the inputs + std::vector unused; + for (unsigned int iclock = 0; iclock < nclocks_; ++iclock) { + fillLinks(iclock, tk_links_in, unused); + fillLinks(iclock, em_links_in, unused); + fillLinks(iclock, calo_links_in, unused); + fillLinks(iclock, mu_links_in, unused); + + bool newevt = (iclock == 0), mux = true; + step(newevt, tk_links_in, calo_links_in, em_links_in, mu_links_in, tk_out, calo_out, em_out, mu_out, mux); + } + + // set up an empty event + for (auto& l : tk_links_in) + l.clear(); + for (auto& l : em_links_in) + l.clear(); + for (auto& l : calo_links_in) + l.clear(); + for (auto& l : mu_links_in) + l.clear(); + + // read and put the inputs in the regions + assert(out.size() == nregions_); + for (unsigned int iclock = 0; iclock < nclocks_; ++iclock) { + bool newevt = (iclock == 0), mux = true; + step(newevt, tk_links_in, calo_links_in, em_links_in, mu_links_in, tk_out, calo_out, em_out, mu_out, mux); + + unsigned int ireg = iclock / (outii_ + pauseii_); + if ((iclock % (outii_ + pauseii_)) >= outii_) + continue; + if (ireg >= nregions_) + break; + + if (streaming_) { + Fold& f = fold_[whichFold(iclock)]; + f.regionizer->destream(iclock % clocksPerFold_, tk_out, em_out, calo_out, mu_out, out[ireg]); + } else { + if (iclock % (outii_ + pauseii_) == 0) { + out[ireg].track = tk_out; + out[ireg].emcalo = em_out; + out[ireg].hadcalo = calo_out; + out[ireg].muon = mu_out; + } + } + } + + for (auto& f : fold_) + f.regionizer->reset(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/folded_multififo_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/folded_multififo_regionizer_ref.cpp new file mode 100644 index 0000000000000..cf5bba7229e72 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/folded_multififo_regionizer_ref.cpp @@ -0,0 +1,243 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/folded_multififo_regionizer_ref.h" + +#include +#include + +l1ct::FoldedMultififoRegionizerEmulator::FoldedMultififoRegionizerEmulator(unsigned int nclocks, + unsigned int ntklinks, + unsigned int ncalolinks, + unsigned int ntk, + unsigned int ncalo, + unsigned int nem, + unsigned int nmu, + bool streaming, + unsigned int outii, + unsigned int pauseii, + bool useAlsoVtxCoords) + : RegionizerEmulator(useAlsoVtxCoords), + NTK_SECTORS(9), + NCALO_SECTORS(3), + NTK_LINKS(ntklinks), + NCALO_LINKS(ncalolinks), + HCAL_LINKS(0), + ECAL_LINKS(0), + NMU_LINKS(1), + nclocks_(nclocks), + ntk_(ntk), + ncalo_(ncalo), + nem_(nem), + nmu_(nmu), + outii_(outii), + pauseii_(pauseii), + streaming_(streaming), + foldMode_(FoldMode::EndcapEta2), + init_(false) { + // now we initialize the routes: track finder + for (unsigned int ie = 0; ie < 2; ++ie) { + fold_.emplace_back(ie, + std::make_unique( + /*nendcaps=*/1, + nclocks / 2, + NTK_LINKS, + NCALO_LINKS, + ntk, + ncalo, + nem, + nmu, + streaming, + outii, + pauseii, + useAlsoVtxCoords)); + } + clocksPerFold_ = nclocks / 2; +} + +l1ct::FoldedMultififoRegionizerEmulator::~FoldedMultififoRegionizerEmulator() {} + +void l1ct::FoldedMultififoRegionizerEmulator::setEgInterceptMode( + bool afterFifo, const l1ct::EGInputSelectorEmuConfig& interceptorConfig) { + for (auto& f : fold_) + f.regionizer->setEgInterceptMode(afterFifo, interceptorConfig); +} + +void l1ct::FoldedMultififoRegionizerEmulator::splitSectors(const RegionizerDecodedInputs& in) { + for (auto& f : fold_) { + f.sectors.track.clear(); + f.sectors.hadcalo.clear(); + f.sectors.emcalo.clear(); + } + for (const auto& src : in.track) { + for (auto& f : fold_) { + if (inFold(src.region, f)) + f.sectors.track.emplace_back(src); + } + } + for (const auto& src : in.hadcalo) { + for (auto& f : fold_) { + if (inFold(src.region, f)) + f.sectors.hadcalo.emplace_back(src); + } + } + for (const auto& src : in.emcalo) { + for (auto& f : fold_) { + if (inFold(src.region, f)) + f.sectors.emcalo.emplace_back(src); + } + } + for (auto& f : fold_) + f.sectors.muon = in.muon; +} + +void l1ct::FoldedMultififoRegionizerEmulator::splitRegions(const std::vector& out) { + for (auto& f : fold_) { + f.regions.clear(); + } + for (const auto& o : out) { + fold_[whichFold(o.region)].regions.push_back(o); + } +} + +void l1ct::FoldedMultififoRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedInputs& in, + const std::vector& out) { + assert(!init_); + init_ = true; + splitSectors(in); + splitRegions(out); + for (auto& f : fold_) { + f.regionizer->initSectorsAndRegions(f.sectors, f.regions); + } + nregions_ = out.size(); +} + +bool l1ct::FoldedMultififoRegionizerEmulator::step(bool newEvent, + const std::vector& links_tk, + const std::vector& links_hadCalo, + const std::vector& links_emCalo, + const std::vector& links_mu, + std::vector& out_tk, + std::vector& out_hadCalo, + std::vector& out_emCalo, + std::vector& out_mu, + bool mux) { + iclock_ = (newEvent ? 0 : iclock_ + 1); + bool newSubEvent = iclock_ % clocksPerFold_ == 0; + bool ret = false; + if (!mux) { + Fold& f = fold_[whichFold(iclock_)]; + ret = f.regionizer->step( + newSubEvent, links_tk, links_hadCalo, links_emCalo, links_mu, out_tk, out_hadCalo, out_emCalo, out_mu, false); + } else { + unsigned int inputFold = whichFold(iclock_); + unsigned int outputFold = (inputFold + 1) % fold_.size(); // to be seen if this is general or not + std::vector nolinks_tk(links_tk.size()); + std::vector nolinks_hadCalo(links_hadCalo.size()); + std::vector nolinks_emCalo(links_emCalo.size()); + std::vector nolinks_mu(links_mu.size()); + std::vector noout_tk; + std::vector noout_hadCalo; + std::vector noout_emCalo; + std::vector noout_mu; + for (auto& f : fold_) { + bool fret = f.regionizer->step(newSubEvent, + f.index == inputFold ? links_tk : nolinks_tk, + f.index == inputFold ? links_hadCalo : nolinks_hadCalo, + f.index == inputFold ? links_emCalo : nolinks_emCalo, + f.index == inputFold ? links_mu : nolinks_mu, + f.index == outputFold ? out_tk : noout_tk, + f.index == outputFold ? out_hadCalo : noout_hadCalo, + f.index == outputFold ? out_emCalo : noout_emCalo, + f.index == outputFold ? out_mu : noout_mu, + true); + if (f.index == outputFold) + ret = fret; + } + } + return ret; +} + +void l1ct::FoldedMultififoRegionizerEmulator::fillEvent(const l1ct::RegionizerDecodedInputs& in) { + splitSectors(in); + for (auto& f : fold_) { + for (auto& o : f.regions) { + o.clear(); + } + } +} + +unsigned int l1ct::FoldedMultififoRegionizerEmulator::whichFold(const l1ct::PFRegion& reg) { + switch (foldMode_) { + case FoldMode::EndcapEta2: + return (reg.floatEtaCenter() >= 0); + } + assert(false); + return 0; +} +bool l1ct::FoldedMultififoRegionizerEmulator::inFold(const l1ct::PFRegion& reg, const Fold& fold) { + switch (foldMode_) { + case FoldMode::EndcapEta2: + return int(reg.floatEtaCenter() >= 0) == int(fold.index); + } + assert(false); + return false; +} + +void l1ct::FoldedMultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { + if (!init_) + initSectorsAndRegions(in, out); + else { + fillEvent(in); + for (auto& f : fold_) + f.regionizer->reset(); + } + + std::vector tk_links_in, tk_out; + std::vector em_links_in, em_out; + std::vector calo_links_in, calo_out; + std::vector mu_links_in, mu_out; + + std::vector unused; + for (unsigned int iclock = 0; iclock < 2 * nclocks_; ++iclock) { + if (iclock < nclocks_) { + fillLinks(iclock, tk_links_in, unused); + fillLinks(iclock, em_links_in, unused); + fillLinks(iclock, calo_links_in, unused); + fillLinks(iclock, mu_links_in, unused); + } else { + // set up an empty event + for (auto& l : tk_links_in) + l.clear(); + for (auto& l : em_links_in) + l.clear(); + for (auto& l : calo_links_in) + l.clear(); + for (auto& l : mu_links_in) + l.clear(); + } + + bool newevt = (iclock % nclocks_) == 0, mux = true; + step(newevt, tk_links_in, calo_links_in, em_links_in, mu_links_in, tk_out, calo_out, em_out, mu_out, mux); + + if (iclock >= nclocks_ / 2) { + unsigned int ireg = ((iclock - nclocks_ / 2) / (outii_ + pauseii_)); + if (((iclock - nclocks_ / 2) % (outii_ + pauseii_)) >= outii_) + continue; + if (ireg >= nregions_) + break; + + if (streaming_) { + Fold& f = fold_[whichFold(iclock)]; + f.regionizer->destream(iclock % clocksPerFold_, tk_out, em_out, calo_out, mu_out, out[ireg]); + } else { + if ((iclock - nclocks_ / 2) % (outii_ + pauseii_) == 0) { + out[ireg].track = tk_out; + out[ireg].emcalo = em_out; + out[ireg].hadcalo = calo_out; + out[ireg].muon = mu_out; + } + } + } + } + + for (auto& f : fold_) + f.regionizer->reset(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/multififo_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/multififo_regionizer_ref.cpp index feb87ce4b9dfe..e4536206a1330 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/multififo_regionizer_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/multififo_regionizer_ref.cpp @@ -4,6 +4,7 @@ #include #include +#include #ifdef CMSSW_GIT_HASH #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -11,12 +12,15 @@ l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(const edm::ParameterSet& iConfig) : MultififoRegionizerEmulator(iConfig.getParameter("nEndcaps"), iConfig.getParameter("nClocks"), + iConfig.getParameter("nTkLinks"), + iConfig.getParameter("nCaloLinks"), iConfig.getParameter("nTrack"), iConfig.getParameter("nCalo"), iConfig.getParameter("nEmCalo"), iConfig.getParameter("nMu"), /*streaming=*/false, /*outii=*/1, + /*pauseii=*/0, iConfig.getParameter("useAlsoVtxCoords")) { debug_ = iConfig.getUntrackedParameter("debug", false); if (iConfig.existsAs("egInterceptMode")) { @@ -24,22 +28,42 @@ l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(const edm::Parame setEgInterceptMode(emSelCfg.getParameter("afterFifo"), emSelCfg); } } + +l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(const std::string& barrelSetup, + const edm::ParameterSet& iConfig) + : MultififoRegionizerEmulator(parseBarrelSetup(barrelSetup), + iConfig.getParameter("nHCalLinks"), + iConfig.getParameter("nECalLinks"), + iConfig.getParameter("nClocks"), + iConfig.getParameter("nTrack"), + iConfig.getParameter("nCalo"), + iConfig.getParameter("nEmCalo"), + iConfig.getParameter("nMu"), + /*streaming=*/false, + /*outii=*/1, + /*pauseii=*/0, + iConfig.getParameter("useAlsoVtxCoords")) { + debug_ = iConfig.getUntrackedParameter("debug", false); +} #endif l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(unsigned int nendcaps, unsigned int nclocks, + unsigned int ntklinks, + unsigned int ncalolinks, unsigned int ntk, unsigned int ncalo, unsigned int nem, unsigned int nmu, bool streaming, unsigned int outii, + unsigned int pauseii, bool useAlsoVtxCoords) : RegionizerEmulator(useAlsoVtxCoords), NTK_SECTORS(9), NCALO_SECTORS(3), - NTK_LINKS(2), - NCALO_LINKS(3), + NTK_LINKS(ntklinks), + NCALO_LINKS(ncalolinks), HCAL_LINKS(0), ECAL_LINKS(0), NMU_LINKS(1), @@ -50,22 +74,22 @@ l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(unsigned int nend nem_(nem), nmu_(nmu), outii_(outii), - pauseii_(0), + pauseii_(pauseii), streaming_(streaming), emInterceptMode_(noIntercept), init_(false), - tkRegionizer_(ntk, streaming ? (ntk + outii - 1) / outii : ntk, streaming, outii, 0, useAlsoVtxCoords), - hadCaloRegionizer_(ncalo, streaming ? (ncalo + outii - 1) / outii : ncalo, streaming, outii, 0), - emCaloRegionizer_(nem, streaming ? (nem + outii - 1) / outii : nem, streaming, outii, 0), - muRegionizer_(nmu, streaming ? std::max(1u, (nmu + outii - 1) / outii) : nmu, streaming, outii, 0) { + tkRegionizer_(ntk, streaming ? (ntk + outii - 1) / outii : ntk, streaming, outii, pauseii, useAlsoVtxCoords), + hadCaloRegionizer_(ncalo, streaming ? (ncalo + outii - 1) / outii : ncalo, streaming, outii, pauseii), + emCaloRegionizer_(nem, streaming ? (nem + outii - 1) / outii : nem, streaming, outii, pauseii), + muRegionizer_(nmu, streaming ? std::max(1u, (nmu + outii - 1) / outii) : nmu, streaming, outii, pauseii) { // now we initialize the routes: track finder for (unsigned int ie = 0; ie < nendcaps && ntk > 0; ++ie) { for (unsigned int is = 0; is < NTK_SECTORS; ++is) { // 9 tf sectors for (unsigned int il = 0; il < NTK_LINKS; ++il) { // max tracks per sector per clock unsigned int isp = (is + 1) % NTK_SECTORS, ism = (is + NTK_SECTORS - 1) % NTK_SECTORS; tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, is + NTK_SECTORS * ie, il); - tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, isp + NTK_SECTORS * ie, il + 2); - tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, ism + NTK_SECTORS * ie, il + 4); + tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, isp + NTK_SECTORS * ie, il + NTK_LINKS); + tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, ism + NTK_SECTORS * ie, il + 2 * NTK_LINKS); } } } @@ -234,6 +258,16 @@ l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(BarrelSetup barre l1ct::MultififoRegionizerEmulator::~MultififoRegionizerEmulator() {} +l1ct::MultififoRegionizerEmulator::BarrelSetup l1ct::MultififoRegionizerEmulator::parseBarrelSetup( + const std::string& setup) { + if (setup == "Full54") + return BarrelSetup::Full54; + if (setup == "Full27") + return BarrelSetup::Full27; + throw std::invalid_argument("barrelSetup for CMSSW can only be Full54 or Full27"); + return BarrelSetup::Full54; +} + void l1ct::MultififoRegionizerEmulator::setEgInterceptMode(bool afterFifo, const l1ct::EGInputSelectorEmuConfig& interceptorConfig) { emInterceptMode_ = afterFifo ? interceptPostFifo : interceptPreFifo; @@ -361,37 +395,45 @@ bool l1ct::MultififoRegionizerEmulator::step(bool newEvent, void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock, const l1ct::RegionizerDecodedInputs& in, - std::vector& links) { + std::vector& links, + std::vector& valid) { if (ntk_ == 0) return; links.resize(NTK_SECTORS * NTK_LINKS * (nendcaps_ ? nendcaps_ : 2)); + valid.resize(links.size()); for (unsigned int is = 0, idx = 0; is < NTK_SECTORS * (nendcaps_ ? nendcaps_ : 2); ++is) { // tf sectors const l1ct::DetectorSector& sec = in.track[is]; for (unsigned int il = 0; il < NTK_LINKS; ++il, ++idx) { unsigned int ioffs = iclock * NTK_LINKS + il; if (ioffs < sec.size() && iclock < nclocks_ - 1) { links[idx] = sec[ioffs]; + valid[idx] = true; } else { links[idx].clear(); + valid[idx] = false; } } } } template -void l1ct::MultififoRegionizerEmulator::fillCaloLinks_(unsigned int iclock, - const std::vector>& in, - std::vector& links) { +void l1ct::MultififoRegionizerEmulator::fillCaloLinks(unsigned int iclock, + const std::vector>& in, + std::vector& links, + std::vector& valid) { unsigned int NLINKS = (nendcaps_ ? NCALO_LINKS : (typeid(T) == typeid(l1ct::HadCaloObjEmu) ? HCAL_LINKS : ECAL_LINKS)); links.resize(NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1) * NLINKS); + valid.resize(links.size()); for (unsigned int is = 0, idx = 0; is < NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1); ++is) { for (unsigned int il = 0; il < NLINKS; ++il, ++idx) { unsigned int ioffs = iclock * NLINKS + il; if (ioffs < in[is].size() && iclock < nclocks_ - 1) { links[idx] = in[is][ioffs]; + valid[idx] = true; } else { links[idx].clear(); + valid[idx] = false; } } } @@ -399,31 +441,37 @@ void l1ct::MultififoRegionizerEmulator::fillCaloLinks_(unsigned int iclock, void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock, const l1ct::RegionizerDecodedInputs& in, - std::vector& links) { + std::vector& links, + std::vector& valid) { if (ncalo_ == 0) return; - fillCaloLinks_(iclock, in.hadcalo, links); + fillCaloLinks(iclock, in.hadcalo, links, valid); } void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock, const l1ct::RegionizerDecodedInputs& in, - std::vector& links) { + std::vector& links, + std::vector& valid) { if (nem_ == 0 || emInterceptMode_ != noIntercept) return; - fillCaloLinks_(iclock, in.emcalo, links); + fillCaloLinks(iclock, in.emcalo, links, valid); } void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock, const l1ct::RegionizerDecodedInputs& in, - std::vector& links) { + std::vector& links, + std::vector& valid) { if (nmu_ == 0) return; assert(NMU_LINKS == 1); links.resize(NMU_LINKS); + valid.resize(links.size()); if (iclock < in.muon.size() && iclock < nclocks_ - 1) { links[0] = in.muon[iclock]; + valid[0] = true; } else { links[0].clear(); + valid[0] = false; } } @@ -489,13 +537,17 @@ void l1ct::MultififoRegionizerEmulator::destream(int iclock, muRegionizer_.destream(iclock, mu_out, out.muon); } -void l1ct::MultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { - if (!init_) - initSectorsAndRegions(in, out); +void l1ct::MultififoRegionizerEmulator::reset() { tkRegionizer_.reset(); emCaloRegionizer_.reset(); hadCaloRegionizer_.reset(); muRegionizer_.reset(); +} + +void l1ct::MultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { + if (!init_) + initSectorsAndRegions(in, out); + reset(); std::vector tk_links_in, tk_out; std::vector em_links_in, em_out; std::vector calo_links_in, calo_out; @@ -546,8 +598,5 @@ void l1ct::MultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in, s } } - tkRegionizer_.reset(); - emCaloRegionizer_.reset(); - hadCaloRegionizer_.reset(); - muRegionizer_.reset(); + reset(); } diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py index 6952481e84eb1..c8eddfb3b029c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py @@ -60,7 +60,7 @@ process.l1tLayer1HGCalNoTK + process.l1tLayer1HF ) -process.runPF.associate(process.l1tLayer1TaskInputsTask) +process.runPF.associate(process.L1TLayer1TaskInputsTask) for det in "Barrel", "Barrel9", "HGCal", "HGCalNoTK", "HF": @@ -68,4 +68,10 @@ 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.l1tPFClustersFromCombinedCaloHCal.phase2barrelCaloTowers = [cms.InputTag("l1tEGammaClusterEmuProducer",)] +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") + diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py index e55a90022aa50..1612a4c908c2c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py @@ -32,7 +32,7 @@ process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer2EG_cff') process.load('L1Trigger.L1TTrackMatch.l1tGTTInputProducer_cfi') process.load('L1Trigger.VertexFinder.l1tVertexProducer_cfi') -process.l1tVertexFinderEmulator = process.VertexProducer.clone() +process.l1tVertexFinderEmulator = process.l1tVertexProducer.clone() process.l1tVertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" process.l1tVertexFinderEmulator.l1TracksInputTag = cms.InputTag("l1tGTTInputProducer", "Level1TTTracksConverted") from L1Trigger.Phase2L1GMT.gmt_cfi import l1tStandaloneMuons @@ -42,8 +42,11 @@ from L1Trigger.Phase2L1ParticleFlow.l1tDeregionizerProducer_cfi import l1tDeregionizerProducer from L1Trigger.Phase2L1ParticleFlow.l1tJetFileWriter_cfi import l1tSeededConeJetFileWriter process.l1tLayer2Deregionizer = l1tDeregionizerProducer.clone() -process.l1tLayer2SeedConeJets = l1tSeedConePFJetEmulatorProducer.clone(L1PFObject = cms.InputTag('l1tLayer2Deregionizer', 'Puppi')) -process.l1tLayer2SeedConeJetWriter = l1tSeededConeJetFileWriter.clone(jets = "l1tLayer2SeedConeJets") +process.l1tLayer2SeedConeJetsCorrected = l1tSeedConePFJetEmulatorProducer.clone(L1PFObject = ('l1tLayer2Deregionizer', 'Puppi'), + doCorrections = True, + correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs_20220308.root", + correctorDir = "L1PuppiSC4EmuJets") +process.l1tLayer2SeedConeJetWriter = l1tSeededConeJetFileWriter.clone(jets = "l1tLayer2SeedConeJetsCorrected") process.l1tLayer1Barrel9 = process.l1tLayer1Barrel.clone() process.l1tLayer1Barrel9.puAlgo.nFinalSort = 32 @@ -74,12 +77,12 @@ process.l1tLayer1HGCalNoTK + process.l1tLayer1HF + process.l1tLayer1 + - process.l1tLayer2EG + process.l1tLayer2Deregionizer + - process.l1tLayer2SeedConeJets + - process.l1tLayer2SeedConeJetWriter + process.l1tLayer2SeedConeJetsCorrected + + process.l1tLayer2SeedConeJetWriter + + process.l1tLayer2EG ) -process.runPF.associate(process.l1tLayer1TaskInputsTask) +process.runPF.associate(process.L1TLayer1TaskInputsTask) ##################################################################################################################### @@ -95,4 +98,10 @@ process.l1tLayer2SeedConeJetWriter.maxLinesPerFile = eventsPerFile_*54 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.pfClustersFromCombinedCaloHCal.phase2barrelCaloTowers = [cms.InputTag("l1tEGammaClusterEmuProducer",)] +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") + diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py index 50e3db4e23812..073f0f910e342 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py @@ -41,8 +41,11 @@ from L1Trigger.Phase2L1ParticleFlow.l1tDeregionizerProducer_cfi import l1tDeregionizerProducer from L1Trigger.Phase2L1ParticleFlow.l1tJetFileWriter_cfi import l1tSeededConeJetFileWriter process.l1tLayer2Deregionizer = l1tDeregionizerProducer.clone() -process.l1tLayer2SeedConeJets = l1tSeedConePFJetEmulatorProducer.clone(L1PFObject = cms.InputTag('l1tLayer2Deregionizer', 'Puppi')) -process.l1tLayer2SeedConeJetWriter = l1tSeededConeJetFileWriter.clone(jets = "l1tLayer2SeedConeJets") +process.l1tLayer2SeedConeJetsCorrected = l1tSeedConePFJetEmulatorProducer.clone(L1PFObject = ('l1tLayer2Deregionizer', 'Puppi'), + doCorrections = True, + correctorFile = "L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs_20220308.root", + correctorDir = "L1PuppiSC4EmuJets") +process.l1tLayer2SeedConeJetWriter = l1tSeededConeJetFileWriter.clone(jets = "l1tLayer2SeedConeJetsCorrected") process.l1tLayer1Barrel9 = process.l1tLayer1Barrel.clone() process.l1tLayer1Barrel9.puAlgo.nFinalSort = 32 @@ -56,14 +59,14 @@ regions=cms.vuint32(*[6+9*ie+i for ie in range(3) for i in range(3)])), ) -from L1Trigger.Phase2L1ParticleFlow.l1tLayer1_patternWriters_cff import * +from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_patternWriters_cff import * process.l1tLayer1Barrel.patternWriters = cms.untracked.VPSet(*barrelWriterConfigs) #process.l1tLayer1Barrel9.patternWriters = cms.untracked.VPSet(*barrel9WriterConfigs) # not enabled for now process.l1tLayer1HGCal.patternWriters = cms.untracked.VPSet(*hgcalWriterConfigs) process.l1tLayer1HGCalNoTK.patternWriters = cms.untracked.VPSet(*hgcalNoTKWriterConfigs) process.l1tLayer1HF.patternWriters = cms.untracked.VPSet(*hfWriterConfigs) -process.L1TPFInputsTask = cms.Task( +process.PFInputsTask = cms.Task( process.TTClustersFromPhase2TrackerDigis, process.TTStubsFromPhase2TrackerDigis, process.TrackerDTCProducer, @@ -78,12 +81,12 @@ process.l1tLayer1HGCalNoTK + process.l1tLayer1HF + process.l1tLayer1 + - process.l1tLayer2EG + process.l1tLayer2Deregionizer + - process.l1tLayer2SeedConeJets + - process.l1tLayer2SeedConeJetWriter + process.l1tLayer2SeedConeJetsCorrected + + process.l1tLayer2SeedConeJetWriter + + process.l1tLayer2EG ) -process.runPF.associate(process.L1TPFInputsTask) +process.runPF.associate(process.PFInputsTask) process.schedule = cms.Schedule(process.runPF)