diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h new file mode 100644 index 0000000000000..2895848dd11fe --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h @@ -0,0 +1,184 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_egamma_pftkegsorter_barrel_ref_h +#define L1Trigger_Phase2L1ParticleFlow_egamma_pftkegsorter_barrel_ref_h + +#include +#include + +#include "pftkegsorter_ref.h" +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_hybrid_sort_ref.h" + +namespace l1ct { + class PFTkEGSorterBarrelEmulator : public PFTkEGSorterEmulator { + public: + PFTkEGSorterBarrelEmulator(const unsigned int nObjToSort = 10, const unsigned int nObjSorted = 16) + : PFTkEGSorterEmulator(nObjToSort, nObjSorted) {} + +#ifdef CMSSW_GIT_HASH + PFTkEGSorterBarrelEmulator(const edm::ParameterSet& iConfig) + : PFTkEGSorterEmulator(iConfig.getParameter("nObjToSort"), + iConfig.getParameter("nObjSorted")) {} +#endif + + ~PFTkEGSorterBarrelEmulator() override {} + + void toFirmware_pho(const OutputRegion& outregions, EGIsoObj photons_in[/*nObjSorted_*/]) const { + for (unsigned int i = 0; i < nObjToSort_; i++) { + EGIsoObj pho; + if (i < outregions.egphoton.size()) { + pho = outregions.egphoton[i]; + } else + pho.clear(); + + photons_in[i] = pho; + } + } + + void toFirmware_ele(const OutputRegion& outregions, EGIsoEleObj eles_in[/*nObjSorted_*/]) const { + for (unsigned int i = 0; i < nObjToSort_; i++) { + EGIsoEleObj ele; + if (i < outregions.egelectron.size()) { + ele = outregions.egelectron[i]; + } else + ele.clear(); + + eles_in[i] = ele; + } + } + + void runPho(const std::vector& pfregions, + const std::vector& outregions, + const std::vector& region_index, + std::vector& eg_sorted_inBoard) override { + run(pfregions, outregions, region_index, eg_sorted_inBoard); + } + void runEle(const std::vector& pfregions, + const std::vector& outregions, + const std::vector& region_index, + std::vector& eg_sorted_inBoard) override { + run(pfregions, outregions, region_index, eg_sorted_inBoard); + } + + template + void run(const std::vector& pfregions, + const std::vector& outregions, + const std::vector& region_index, + std::vector& eg_sorted_inBoard) { + // we copy to be able to resize them + std::vector> objs_in; + objs_in.reserve(nObjToSort_); + for (unsigned int i : region_index) { + std::vector objs; + extractEGObjEmu(pfregions[i].region, outregions[i], objs); + if (debug_) + dbgCout() << "objs size " << objs.size() << "\n"; + resize_input(objs); + objs_in.push_back(objs); + if (debug_) + dbgCout() << "objs (re)size and total objs size " << objs.size() << " " << objs_in.size() << "\n"; + } + + merge(objs_in, eg_sorted_inBoard); + + if (debug_) { + dbgCout() << "objs.size() size " << eg_sorted_inBoard.size() << "\n"; + for (const auto& out : eg_sorted_inBoard) + dbgCout() << "kinematics of sorted objects " << out.hwPt << " " << out.hwEta << " " << out.hwPhi << "\n"; + } + } + + private: + void extractEGObjEmu(const PFRegionEmu& region, + const l1ct::OutputRegion& outregion, + std::vector& eg) { + extractEGObjEmu(region, outregion.egphoton, eg); + } + void extractEGObjEmu(const PFRegionEmu& region, + const l1ct::OutputRegion& outregion, + std::vector& eg) { + extractEGObjEmu(region, outregion.egelectron, eg); + } + template + void extractEGObjEmu(const PFRegionEmu& region, + const std::vector& regional_objects, + std::vector& global_objects) { + for (const auto& reg_obj : regional_objects) { + global_objects.emplace_back(reg_obj); + global_objects.back().hwEta = region.hwGlbEta(reg_obj.hwEta); + global_objects.back().hwPhi = region.hwGlbPhi(reg_obj.hwPhi); + } + } + + template + void resize_input(std::vector& in) const { + if (in.size() > nObjToSort_) { + in.resize(nObjToSort_); + } else if (in.size() < nObjToSort_) { + for (unsigned int i = 0, diff = (nObjToSort_ - in.size()); i < diff; ++i) { + in.push_back(T()); + in.back().clear(); + } + } + } + + template + void merge_regions(const std::vector& in_region1, + const std::vector& in_region2, + std::vector& out, + unsigned int nOut) const { + // we crate a bitonic list + out = in_region1; + if (debug_) + for (const auto& tmp : out) + dbgCout() << "out " << tmp.hwPt << " " << tmp.hwEta << " " << tmp.hwPhi << "\n"; + std::reverse(out.begin(), out.end()); + if (debug_) + for (const auto& tmp : out) + dbgCout() << "out reverse " << tmp.hwPt << " " << tmp.hwEta << " " << tmp.hwPhi << "\n"; + std::copy(in_region2.begin(), in_region2.end(), std::back_inserter(out)); + if (debug_) + for (const auto& tmp : out) + dbgCout() << "out inserted " << tmp.hwPt << " " << tmp.hwEta << " " << tmp.hwPhi << "\n"; + + hybridBitonicMergeRef(&out[0], out.size(), 0, false); + + if (out.size() > nOut) { + out.resize(nOut); + if (debug_) + for (const auto& tmp : out) + dbgCout() << "final " << tmp.hwPt << " " << tmp.hwEta << " " << tmp.hwPhi << "\n"; + } + } + + template + void merge(const std::vector>& in_objs, std::vector& out) const { + unsigned int nregions = in_objs.size(); + std::vector pair_merge(nObjSorted_); + if (nregions == 18) { // merge pairs, and accumulate pairs + for (unsigned int i = 0; i < nregions; i += 2) { + merge_regions(in_objs[i + 0], in_objs[i + 1], pair_merge, nObjSorted_); + if (i == 0) + out = pair_merge; + else + merge_regions(out, pair_merge, out, nObjSorted_); + } + } else if (nregions == 9) { // simple accumulation + for (unsigned int i = 0; i < nregions; ++i) { + for (unsigned int j = 0, nj = in_objs[i].size(); j < nObjSorted_; ++j) { + if (j < nj) + pair_merge[j] = in_objs[i][j]; + else + pair_merge[j].clear(); + } + if (i == 0) + out = pair_merge; + else + merge_regions(out, pair_merge, out, nObjSorted_); + } + } else + throw std::runtime_error("This sorter requires 18 or 9 regions"); + } + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h index 4a417fd48d04a..fffb556552b0d 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h @@ -1,5 +1,5 @@ -#ifndef FIRMWARE_PFTKEGSORTER_REF_H -#define FIRMWARE_PFTKEGSORTER_REF_H +#ifndef L1Trigger_Phase2L1ParticleFlow_egamma_pftkegsorter_ref_h +#define L1Trigger_Phase2L1ParticleFlow_egamma_pftkegsorter_ref_h #include #include @@ -11,10 +11,6 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #endif -namespace edm { - class ParameterSet; -} - namespace l1ct { class PFTkEGSorterEmulator { public: @@ -28,10 +24,23 @@ namespace l1ct { #endif - ~PFTkEGSorterEmulator(){}; + virtual ~PFTkEGSorterEmulator() {} void setDebug(bool debug = true) { debug_ = debug; }; + virtual void runPho(const std::vector& pfregions, + const std::vector& outregions, + const std::vector& region_index, + std::vector& eg_sorted_inBoard) { + run(pfregions, outregions, region_index, eg_sorted_inBoard); + } + virtual void runEle(const std::vector& pfregions, + const std::vector& outregions, + const std::vector& region_index, + std::vector& eg_sorted_inBoard) { + run(pfregions, outregions, region_index, eg_sorted_inBoard); + } + template void run(const std::vector& pfregions, const std::vector& outregions, @@ -64,7 +73,7 @@ namespace l1ct { } } - private: + protected: unsigned int nObjToSort_, nObjSorted_; bool debug_; diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h index ae76062083fea..ec194e127ef9c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h @@ -8,11 +8,7 @@ #include #include -#ifdef CMSSW_GIT_HASH #include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" -#else -#include "../../utils/dbgPrintf.h" -#endif namespace l1ct { namespace tdr_regionizer { diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc index d8335cf0c5a64..d6bd40e646190 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -32,6 +32,7 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_common_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_barrel_ref.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h" #include "DataFormats/L1TCorrelator/interface/TkElectron.h" @@ -278,8 +279,15 @@ L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet l1tkegalgo_ = std::make_unique( l1ct::PFTkEGAlgoEmuConfig(iConfig.getParameter("tkEgAlgoParameters"))); - l1tkegsorter_ = - std::make_unique(iConfig.getParameter("tkEgSorterParameters")); + const std::string &egsortalgo = iConfig.getParameter("tkEgSorterAlgo"); + if (egsortalgo == "Barrel") { + l1tkegsorter_ = std::make_unique( + iConfig.getParameter("tkEgSorterParameters")); + } else if (egsortalgo == "Endcap") { + l1tkegsorter_ = + std::make_unique(iConfig.getParameter("tkEgSorterParameters")); + } else + throw cms::Exception("Configuration", "Unsupported tkEgSorterAlgo"); if (l1tkegalgo_->writeEgSta()) produces>("L1Eg"); @@ -482,8 +490,8 @@ void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSe // l1tkegsorter_->setDebug(true); for (auto &board : event_.board_out) { - l1tkegsorter_->run(event_.pfinputs, event_.out, board.region_index, board.egphoton); - l1tkegsorter_->run(event_.pfinputs, event_.out, board.region_index, board.egelectron); + l1tkegsorter_->runPho(event_.pfinputs, event_.out, board.region_index, board.egphoton); + l1tkegsorter_->runEle(event_.pfinputs, event_.out, board.region_index, board.egelectron); } // save PF into the event diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py index f18dd5c81e4ec..4a0774bdfc3b0 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -108,6 +108,7 @@ nEMCALO_EGIN = 10, nEM_EGOUT = 10, ), + tkEgSorterAlgo = cms.string("Barrel"), tkEgSorterParameters=tkEgSorterParameters.clone( nObjToSort = 10 ), @@ -271,6 +272,7 @@ writeEGSta=True, doCompositeTkEle=True, trkQualityPtMin=0.), # This should be 10 GeV when doCompositeTkEle=False + tkEgSorterAlgo = cms.string("Endcap"), tkEgSorterParameters=tkEgSorterParameters.clone( nObjToSort = 5 ), @@ -368,6 +370,7 @@ doEndcapHwQual=True, writeBeforeBremRecovery=False, writeEGSta=True), + tkEgSorterAlgo = cms.string("Endcap"), tkEgSorterParameters=tkEgSorterParameters.clone( nObjToSort=5 ), @@ -452,6 +455,7 @@ nEM_EGOUT = 5, # to be defined doBremRecovery=True, writeEGSta=True), + tkEgSorterAlgo = cms.string("Endcap"), tkEgSorterParameters=tkEgSorterParameters.clone(), caloSectors = cms.VPSet( cms.PSet( diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp index 984dca69f36a5..da9baff109831 100644 --- a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp @@ -156,6 +156,16 @@ void PFTkEGAlgoEmulator::link_emCalo2tk_elliptic(const PFRegionEmu &r, float dEtaMax = cfg.dEtaValues[eta_index]; float dPhiMax = cfg.dPhiValues[eta_index]; + if (debug_ > 2 && calo.hwPt > 0) { + dbgCout() << "[REF] tried to link calo " << ic << " (pt " << calo.intPt() << ", eta " << calo.intEta() + << ", phi " << calo.intPhi() << ") " + << " to tk " << itk << " (pt " << tk.intPt() << ", eta " << tk.intEta() << ", phi " << tk.intPhi() + << "): " + << " eta_index " << eta_index << ", " + << " dEta " << d_eta << " (max " << dEtaMax << "), dPhi " << d_phi << " (max " << dPhiMax << ") " + << " ellipse = " + << (((d_phi / dPhiMax) * (d_phi / dPhiMax)) + ((d_eta / dEtaMax) * (d_eta / dEtaMax))) << "\n"; + } if ((((d_phi / dPhiMax) * (d_phi / dPhiMax)) + ((d_eta / dEtaMax) * (d_eta / dEtaMax))) < 1.) { // NOTE: for now we implement only best pt match. This is NOT what is done in the L1TkElectronTrackProducer if (fabs(tk.floatPt() - calo.floatPt()) < dPtMin) { diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py index c8eddfb3b029c..72c77480e8d2f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py @@ -38,6 +38,28 @@ from L1Trigger.Phase2L1GMT.gmt_cfi import l1tStandaloneMuons process.l1tSAMuonsGmt = l1tStandaloneMuons.clone() +process.l1tLayer1BarrelSerenity = process.l1tLayer1Barrel.clone() +process.l1tLayer1BarrelSerenity.regionizerAlgo = "MultififoBarrel" +process.l1tLayer1BarrelSerenity.regionizerAlgoParameters = cms.PSet( + barrelSetup = cms.string("Full54"), + useAlsoVtxCoords = cms.bool(True), + nClocks = cms.uint32(54), + nHCalLinks = cms.uint32(2), + nECalLinks = cms.uint32(1), + nTrack = cms.uint32(22), + nCalo = cms.uint32(15), + nEmCalo = cms.uint32(12), + nMu = cms.uint32(2)) +process.l1tLayer1BarrelSerenity.pfAlgoParameters.nTrack = 22 +process.l1tLayer1BarrelSerenity.pfAlgoParameters.nSelCalo = 15 +process.l1tLayer1BarrelSerenity.pfAlgoParameters.nCalo = 15 +process.l1tLayer1BarrelSerenity.pfAlgoParameters.nAllNeutral = 27 +process.l1tLayer1BarrelSerenity.puAlgoParameters.nTrack = 22 +process.l1tLayer1BarrelSerenity.puAlgoParameters.nIn = 27 +process.l1tLayer1BarrelSerenity.puAlgoParameters.nOut = 27 +process.l1tLayer1BarrelSerenity.puAlgoParameters.finalSortAlgo = "FoldedHybrid" + + process.l1tLayer1Barrel9 = process.l1tLayer1Barrel.clone() process.l1tLayer1Barrel9.puAlgo.nFinalSort = 32 process.l1tLayer1Barrel9.regions[0].etaBoundaries = [ -1.5, -0.5, 0.5, 1.5 ] @@ -55,6 +77,7 @@ process.l1tGTTInputProducer + process.l1tVertexFinderEmulator + process.l1tLayer1Barrel + + process.l1tLayer1BarrelSerenity + process.l1tLayer1Barrel9 + process.l1tLayer1HGCal + process.l1tLayer1HGCalNoTK + @@ -63,7 +86,7 @@ process.runPF.associate(process.L1TLayer1TaskInputsTask) -for det in "Barrel", "Barrel9", "HGCal", "HGCalNoTK", "HF": +for det in "Barrel", "BarrelSerenity", "Barrel9", "HGCal", "HGCalNoTK", "HF": l1pf = getattr(process, 'l1tLayer1'+det) l1pf.dumpFileName = cms.untracked.string("TTbar_PU200_"+det+".dump") diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py index fceae54226913..29f94aed7b5ba 100644 --- a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_binaryFiles_cfg.py @@ -82,6 +82,27 @@ regions=cms.vuint32(*[6+9*ie+i for ie in range(3) for i in range(3)])), ) +process.l1tLayer1BarrelSerenity = process.l1tLayer1Barrel.clone() +process.l1tLayer1BarrelSerenity.regionizerAlgo = "MultififoBarrel" +process.l1tLayer1BarrelSerenity.regionizerAlgoParameters = cms.PSet( + barrelSetup = cms.string("Full54"), + useAlsoVtxCoords = cms.bool(True), + nClocks = cms.uint32(54), + nHCalLinks = cms.uint32(2), + nECalLinks = cms.uint32(1), + nTrack = cms.uint32(22), + nCalo = cms.uint32(15), + nEmCalo = cms.uint32(12), + nMu = cms.uint32(2)) +process.l1tLayer1BarrelSerenity.pfAlgoParameters.nTrack = 22 +process.l1tLayer1BarrelSerenity.pfAlgoParameters.nSelCalo = 15 +process.l1tLayer1BarrelSerenity.pfAlgoParameters.nCalo = 15 +process.l1tLayer1BarrelSerenity.pfAlgoParameters.nAllNeutral = 27 +process.l1tLayer1BarrelSerenity.puAlgoParameters.nTrack = 22 +process.l1tLayer1BarrelSerenity.puAlgoParameters.nIn = 27 +process.l1tLayer1BarrelSerenity.puAlgoParameters.nOut = 27 +process.l1tLayer1BarrelSerenity.puAlgoParameters.finalSortAlgo = "FoldedHybrid" + from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_patternWriters_cff import * if not args.patternFilesOFF: process.l1tLayer1Barrel.patternWriters = cms.untracked.VPSet(*barrelWriterConfigs) @@ -95,6 +116,7 @@ process.l1tGTTInputProducer + process.l1tVertexFinderEmulator + process.l1tLayer1Barrel + + process.l1tLayer1BarrelSerenity + process.l1tLayer1Barrel9 + process.l1tLayer1HGCal + process.l1tLayer1HGCalElliptic + @@ -125,7 +147,7 @@ process.l1tLayer2SeedConeJetWriter.maxLinesPerFile = eventsPerFile_*54 if not args.dumpFilesOFF: - for det in "Barrel", "Barrel9", "HGCal", "HGCalNoTK", "HF", "HGCalElliptic": + for det in "Barrel", "BarrelSerenity", "Barrel9", "HGCal", "HGCalElliptic", "HGCalNoTK", "HF": l1pf = getattr(process, 'l1tLayer1'+det) l1pf.dumpFileName = cms.untracked.string("TTbar_PU200_"+det+".dump")