diff --git a/Calibration/EcalAlCaRecoProducers/plugins/BuildFile.xml b/Calibration/EcalAlCaRecoProducers/plugins/BuildFile.xml index c4d23a0df9da9..8258f6f71dc06 100644 --- a/Calibration/EcalAlCaRecoProducers/plugins/BuildFile.xml +++ b/Calibration/EcalAlCaRecoProducers/plugins/BuildFile.xml @@ -18,4 +18,5 @@ + diff --git a/DQMOffline/EGamma/plugins/BuildFile.xml b/DQMOffline/EGamma/plugins/BuildFile.xml index ac3f04a905a6e..c36fd13399c13 100644 --- a/DQMOffline/EGamma/plugins/BuildFile.xml +++ b/DQMOffline/EGamma/plugins/BuildFile.xml @@ -16,6 +16,7 @@ + diff --git a/DQMOffline/L1Trigger/interface/L1TPhase2MuonOffline.h b/DQMOffline/L1Trigger/interface/L1TPhase2MuonOffline.h new file mode 100644 index 0000000000000..114012c552d5b --- /dev/null +++ b/DQMOffline/L1Trigger/interface/L1TPhase2MuonOffline.h @@ -0,0 +1,210 @@ +#ifndef DQMOFFLINE_L1TRIGGER_L1TPHASE2MUONOFFLINE_H +#define DQMOFFLINE_L1TRIGGER_L1TPHASE2MUONOFFLINE_H + +/** + * \file L1TPhase2MuonOffline.h + * + * \author S. Folgueras +* + */ + +// DataFormats +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" +#include "DataFormats/Candidate/interface/Candidate.h" +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticle.h" +#include "DataFormats/Math/interface/deltaR.h" +#include "DataFormats/Math/interface/deltaPhi.h" + +// FWCore +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/LuminosityBlock.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +// DQMServices +#include "DQMServices/Core/interface/DQMStore.h" +#include "DQMServices/Core/interface/DQMEDAnalyzer.h" + +// HLTrigger +#include "HLTrigger/HLTcore/interface/HLTConfigProvider.h" + +// Common tools +//#include "MuonAnalysis/MuonAssociators/interface/PropagateToMuon.h" +#include "TrackingTools/TransientTrack/interface/TransientTrack.h" +#include "TrackingTools/TransientTrack/interface/TrackTransientTrack.h" +#include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" +#include "TrackingTools/PatternTools/interface/Trajectory.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h" +#include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" +#include "TrackingTools/Records/interface/TrackingComponentsRecord.h" +#include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h" + +#include +#include "TRegexp.h" +#include +#include + +class GenMuonGMTPair; + +// +// DQM class declaration +// + +class L1TPhase2MuonOffline : public DQMEDAnalyzer { + public: + L1TPhase2MuonOffline(const edm::ParameterSet& ps); + ~L1TPhase2MuonOffline() override; + + enum MuType { kSAMuon, kTkMuon, kNMuTypes }; + enum VarType { kPt, kEta, kPhi, kIso, kQual, kZ0, kD0, kNVarTypes }; + enum EffType { kEffPt, kEffPhi, kEffEta, kEffTypes }; + enum ResType { kResPt, kRes1OverPt, kResQOverPt, kResPhi, kResEta, kResCh, kNResTypes }; + enum EtaRegion { kEtaRegionAll, kEtaRegionBmtf, kEtaRegionOmtf, kEtaRegionEmtf, kNEtaRegions }; + enum QualLevel { kQualOpen, kQualDouble, kQualSingle, kNQualLevels }; + + protected: + void dqmBeginRun(const edm::Run& run, const edm::EventSetup& iSetup) override; + void analyze(const edm::Event& e, const edm::EventSetup& c) override; + + void bookControlHistos(DQMStore::IBooker&, MuType type); + void bookEfficiencyHistos(DQMStore::IBooker& ibooker, MuType type); + void bookResolutionHistos(DQMStore::IBooker& ibooker, MuType type); + void bookHistograms(DQMStore::IBooker& ibooker, const edm::Run& run, const edm::EventSetup& iSetup) override; + + + //Fill Histos + void fillControlHistos(); + void fillEfficiencyHistos(); + void fillResolutionHistos(); + + +private: + // Cut and Matching + void getMuonGmtPairs(edm::Handle& gmtCands); + + + // Handles and Tokens + edm::EDGetTokenT gmtMuonToken_; + edm::EDGetTokenT gmtTkMuonToken_; + edm::EDGetTokenT> genParticleToken_; + + edm::Handle gmtSAMuon_; + edm::Handle gmtTkMuon_; + edm::Handle> genparticles_; + + // PropagateToMuon muonpropagator_; + + // vectors of enum values to loop over (and store quantities) + const std::vector muonTypes_; + const std::vector effTypes_; + const std::vector resTypes_; + const std::vector varTypes_; + const std::vector etaRegions_; + const std::vector qualLevels_; + + // maps with histogram name bits + std::map effNames_; + std::map effLabels_; + std::map resNames_; + std::map resLabels_; + std::map etaNames_; + std::map qualNames_; + std::map muonNames_; + + // config params + std::string histFolder_; + std::vector cutsVPSet_; + + std::vector effVsPtBins_; + std::vector effVsPhiBins_; + std::vector effVsEtaBins_; + + bool useAtVtxCoord_; + bool isParticleGun_; + float maxGmtMuonDR_; + + // Helper methods + void matchMuonsToGen(std::vector genmus); + std::vector getHistBinsEff(EffType eff); + std::tuple getHistBinsRes(ResType res); + + // Keys for histogram maps + /*typedef std::tuple histoKeyResType_; + typedef std::tuple histoKeyEffType_; + typedef std::tuple histoKeyVarType_; + */ + // Histograms and histogram containers + // std::map, MonitorElement*> efficiencyHistos_; + // std::map, MonitorElement*> resolutionHistos_; + // TH1F* efficiencyNum_[kNMuTypes][kNEtaRegions][kNQualLevels][kEffTypes]; + // TH1F* efficiencyDen_[kNMuTypes][kNEtaRegions][kNQualLevels][kEffTypes]; + + MonitorElement* efficiencyNum_[kNMuTypes][kNEtaRegions][kNQualLevels][kEffTypes]; + MonitorElement* efficiencyDen_[kNMuTypes][kNEtaRegions][kNQualLevels][kEffTypes]; + MonitorElement* resolutionHistos_[kNMuTypes][kNEtaRegions][kNQualLevels][kNResTypes]; + MonitorElement* controlHistos_[kNMuTypes][kNVarTypes]; + + // helper variables + std::vector gmtSAMuonPairs_; + std::vector gmtTkMuonPairs_; + std::vector> cuts_; + + float lsb_pt ; + float lsb_phi; + float lsb_eta; + float lsb_z0 ; + float lsb_d0 ; +}; + +// +// helper class to manage GMT-GenMuon pairing +// +class GenMuonGMTPair { +public: + GenMuonGMTPair(const reco::GenParticle* mu, const l1t::L1Candidate* gmtmu); + GenMuonGMTPair(const GenMuonGMTPair& muongmtPair); + ~GenMuonGMTPair(){}; + + float dR(); + float pt() const { return mu_->pt(); }; + float eta() const { return mu_->eta(); }; + float phi() const { return mu_->phi(); }; + int charge() const { return mu_->charge(); }; + + // Now properties of the L1 candidate: + float gmtPt() const { return gmtmu_ ? gmtmu_->pt() : -1.; }; + float gmtEta() const { return gmtmu_ ? gmtEta_ : -5.; }; + float gmtPhi() const { return gmtmu_ ? gmtPhi_ : -5.; }; + int gmtCharge() const { return gmtmu_ ? gmtmu_->charge() : -5; }; + int gmtQual() const { return gmtmu_ ? gmtmu_->hwQual() : -1; }; + + L1TPhase2MuonOffline::EtaRegion etaRegion() const; + double getDeltaVar(const L1TPhase2MuonOffline::ResType) const; + double getVar(const L1TPhase2MuonOffline::EffType) const; + +private: + const reco::GenParticle* mu_; + const l1t::L1Candidate* gmtmu_; + + // L1T muon eta and phi coordinates to be used + // Can be the coordinates from the 2nd muon station or from the vertex + float gmtEta_; + float gmtPhi_; + + float muEta_; + float muPhi_; +}; + + +#endif diff --git a/DQMOffline/L1Trigger/interface/L1TPhase2OuterTrackerTkMET.h b/DQMOffline/L1Trigger/interface/L1TPhase2OuterTrackerTkMET.h index 55aaf5c4279dc..3dcdc392c949e 100644 --- a/DQMOffline/L1Trigger/interface/L1TPhase2OuterTrackerTkMET.h +++ b/DQMOffline/L1Trigger/interface/L1TPhase2OuterTrackerTkMET.h @@ -16,7 +16,7 @@ #include "DataFormats/Common/interface/DetSetVectorNew.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" // #include "DataFormats/L1TVertex/interface/Vertex.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" class DQMStore; class L1TPhase2OuterTrackerTkMET : public DQMEDAnalyzer { @@ -41,7 +41,7 @@ class L1TPhase2OuterTrackerTkMET : public DQMEDAnalyzer { private: edm::ParameterSet conf_; const edm::ESGetToken m_topoToken; - edm::EDGetTokenT pvToken; + edm::EDGetTokenT pvToken; edm::EDGetTokenT > > ttTrackToken_; float maxZ0; // in cm diff --git a/DQMOffline/L1Trigger/python/L1TPhase2MuonDQMEfficiency_cfi.py b/DQMOffline/L1Trigger/python/L1TPhase2MuonDQMEfficiency_cfi.py new file mode 100644 index 0000000000000..761ed7247c863 --- /dev/null +++ b/DQMOffline/L1Trigger/python/L1TPhase2MuonDQMEfficiency_cfi.py @@ -0,0 +1,37 @@ +import FWCore.ParameterSet.Config as cms + +# generate the efficiency strings for the DQMGenericClient from the pt and quality cuts +def generateEfficiencyStrings(ptQualCuts): + numDenDir = "nums_and_dens/" + varStrings = ['Pt', 'Eta', 'Phi'] + etaStrings = ['etaMin0_etaMax0p83', 'etaMin0p83_etaMax1p24', 'etaMin1p24_etaMax2p4', 'etaMin0_etaMax2p4'] + qualStrings = {'qualOpen', 'qualDouble', 'qualSingle'} + muonStrings = ['SAMuon','TkMuon'] + + efficiencyStrings = [] + + for muonString in muonStrings: + for qualString in qualStrings: + for etaString in etaStrings: + effNumDenPrefix = numDenDir+"Eff_"+muonString+"_"+etaString+"_"+qualString+"_" + effNamePrefix = "efficiencies/eff_"+muonString+"_"+etaString+"_"+qualString+"_" + + for varString in varStrings: + effDenName = effNumDenPrefix+varString+"_Den" + effNumName = effNumDenPrefix+varString+"_Num" + effName = effNamePrefix+varString + + efficiencyStrings.append(effName+" '"+effName+";;L1 muon efficiency' "+effNumName+" "+effDenName) + return efficiencyStrings + +from DQMServices.Core.DQMEDHarvester import DQMEDHarvester +from DQMOffline.L1Trigger.L1TPhase2MuonOffline_cfi import ptQualCuts + +l1tPhase2MuonEfficiency = DQMEDHarvester("DQMGenericClient", + subDirs = cms.untracked.vstring(["L1T/L1TPhase2/Muons/SAMuon","L1T/L1TPhase2/Muons/TkMuon"]), + efficiency = cms.vstring(), + efficiencyProfile = cms.untracked.vstring(generateEfficiencyStrings(ptQualCuts)), + resolution = cms.vstring(), + outputFileName = cms.untracked.string(""), + verbose = cms.untracked.uint32(4) +) diff --git a/DQMOffline/L1Trigger/python/L1TPhase2MuonOffline_cfi.py b/DQMOffline/L1Trigger/python/L1TPhase2MuonOffline_cfi.py new file mode 100644 index 0000000000000..953ccf5075056 --- /dev/null +++ b/DQMOffline/L1Trigger/python/L1TPhase2MuonOffline_cfi.py @@ -0,0 +1,52 @@ +from builtins import range +import FWCore.ParameterSet.Config as cms + +# define binning for efficiency plots +# pt +import itertools +effVsPtBins=list(itertools.chain(range(0, 30, 1), range(30, 50, 2), + range(50, 70, 5), range(70, 100, 10), + range(100, 200, 25), range(200, 300, 50), + range(300, 500, 100), range(500, 700, 200), + range(700, 1000, 300))) +effVsPtBins.append(1000) + +# phi +nPhiBins = 34 +phiMin = -3.4 +phiMax = 3.4 +effVsPhiBins = [i*(phiMax-phiMin)/nPhiBins + phiMin for i in range(nPhiBins+1)] + +# eta +nEtaBins = 50 +etaMin = -2.5 +etaMax = 2.5 +effVsEtaBins = [i*(etaMax-etaMin)/nEtaBins + etaMin for i in range(nEtaBins+1)] + +# vtx +effVsVtxBins = range(0, 101) + +# A list of pt cut + quality cut pairs for which efficiency plots should be made +ptQualCuts = [[22, 12], [15, 8], [3, 4]] +cutsPSets = [] +for ptQualCut in ptQualCuts: + cutsPSets.append(cms.untracked.PSet(ptCut = cms.untracked.int32(ptQualCut[0]), + qualCut = cms.untracked.int32(ptQualCut[1]))) + +from DQMServices.Core.DQMEDAnalyzer import DQMEDAnalyzer +l1tPhase2MuonOffline = DQMEDAnalyzer('L1TPhase2MuonOffline', + histFolder = cms.untracked.string('L1T/L1TPhase2/Muons/'), + cuts = cms.untracked.VPSet(cutsPSets), + useL1AtVtxCoord = cms.untracked.bool(False), + + genParticlesInputTag = cms.untracked.InputTag("genParticles"), + gmtMuonToken = cms.InputTag("L1SAMuonsGmt", "promptSAMuons"), + gmtTkMuonToken = cms.InputTag("L1TkMuonsGmt",""), + + efficiencyVsPtBins = cms.untracked.vdouble(effVsPtBins), + efficiencyVsPhiBins = cms.untracked.vdouble(effVsPhiBins), + efficiencyVsEtaBins = cms.untracked.vdouble(effVsEtaBins), + efficiencyVsVtxBins = cms.untracked.vdouble(effVsVtxBins), +) + + diff --git a/DQMOffline/L1Trigger/python/L1TPhase2Offline_cfi.py b/DQMOffline/L1Trigger/python/L1TPhase2Offline_cfi.py index ea17998d17ee3..dfd9ba626ffaf 100644 --- a/DQMOffline/L1Trigger/python/L1TPhase2Offline_cfi.py +++ b/DQMOffline/L1Trigger/python/L1TPhase2Offline_cfi.py @@ -6,7 +6,7 @@ OuterTrackerTkMET = DQMEDAnalyzer('L1TPhase2OuterTrackerTkMET', TopFolderName = cms.string('L1T/L1TPhase2/'), TTTracksTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), - L1VertexInputTag = cms.InputTag("L1TkPrimaryVertex"), + L1VertexInputTag = cms.InputTag("L1VertexFinderEmulator", "l1verticesEmulation"), maxZ0 = cms.double ( 15. ) , # in cm maxEta = cms.double ( 2.4 ) , chi2dofMax = cms.double( 10. ), @@ -93,9 +93,9 @@ genParticlesInputTag = cms.untracked.InputTag("genParticles"), isParticleGun = cms.bool(False), objects = cms.PSet( - L1PF = cms.VInputTag("l1pfCandidates:PF",), + L1PF = cms.VInputTag("l1ctLayer1:PF",), L1PF_sel = cms.string("pt > 0"), - L1Puppi = cms.VInputTag("l1pfCandidates:Puppi",), + L1Puppi = cms.VInputTag("l1ctLayer1:Puppi",), L1Puppi_sel = cms.string("pt > 0"), ), @@ -131,10 +131,12 @@ xmax=cms.untracked.double(5.), ), ), - ) +from DQMOffline.L1Trigger.L1TPhase2MuonOffline_cfi import * + l1tPhase2OfflineDQM = cms.Sequence( l1tPhase2CorrelatorOfflineDQM + - OuterTrackerTkMET + OuterTrackerTkMET + + l1tPhase2MuonOffline ) diff --git a/DQMOffline/L1Trigger/python/L1TriggerDqmOffline_SecondStep_cff.py b/DQMOffline/L1Trigger/python/L1TriggerDqmOffline_SecondStep_cff.py index ec3c8ddf765a1..6d9709f8c7068 100644 --- a/DQMOffline/L1Trigger/python/L1TriggerDqmOffline_SecondStep_cff.py +++ b/DQMOffline/L1Trigger/python/L1TriggerDqmOffline_SecondStep_cff.py @@ -16,6 +16,7 @@ from DQMOffline.L1Trigger.L1TTauDiff_cfi import * from DQMOffline.L1Trigger.L1TMuonDQMEfficiency_cff import * +from DQMOffline.L1Trigger.L1TPhase2MuonDQMEfficiency_cfi import * # harvesting sequence for all datasets DQMHarvestL1TMon = cms.Sequence( @@ -52,6 +53,6 @@ # harvesting sequence for phase 2 DQMHarvestL1TPhase2 = cms.Sequence( - + l1tPhase2MuonEfficiency ) diff --git a/DQMOffline/L1Trigger/src/L1TPhase2MuonOffline.cc b/DQMOffline/L1Trigger/src/L1TPhase2MuonOffline.cc new file mode 100644 index 0000000000000..7b96986f39166 --- /dev/null +++ b/DQMOffline/L1Trigger/src/L1TPhase2MuonOffline.cc @@ -0,0 +1,432 @@ +/** + * \file L1TPhase2MuonOffline.cc + * + * \author S. Folgueras + * + */ + +#include "DQMOffline/L1Trigger/interface/L1TPhase2MuonOffline.h" + +// To convert from HW to Physical coordinates +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" + +using namespace reco; +using namespace trigger; +using namespace edm; +using namespace std; +using namespace l1t; + +//__________RECO-GMT Muon Pair Helper Class____________________________ +GenMuonGMTPair::GenMuonGMTPair(const reco::GenParticle* muon, const l1t::L1Candidate* gmtmu) + : mu_(muon), gmtmu_(gmtmu) { + + + if (gmtmu) { + gmtEta_ = gmtmu_->eta(); + gmtPhi_ = gmtmu_->phi(); + } else { + gmtEta_ = -5.; + gmtPhi_ = -5.; + } + if (mu_) { + muEta_ = mu_->eta(); + muPhi_ = mu_->phi(); + } else { + muEta_ = 999.; + muPhi_ = 999.; + } + +}; + +GenMuonGMTPair::GenMuonGMTPair(const GenMuonGMTPair& muonGmtPair) { + mu_ = muonGmtPair.mu_; + gmtmu_ = muonGmtPair.gmtmu_; + + gmtEta_ = muonGmtPair.gmtEta_; + gmtPhi_ = muonGmtPair.gmtPhi_; + + muEta_ = muonGmtPair.muEta_; + muPhi_ = muonGmtPair.muPhi_; +} + +float GenMuonGMTPair::dR() { + float dEta = gmtmu_ ? (gmtEta_ - muEta_) : 999.; + float dPhi = gmtmu_ ? reco::deltaPhi(gmtPhi_, muPhi_) : 999.; + return sqrt(dEta * dEta + dPhi * dPhi); +} + +L1TPhase2MuonOffline::EtaRegion GenMuonGMTPair::etaRegion() const { + if (std::abs(muEta_) < 0.83) + return L1TPhase2MuonOffline::kEtaRegionBmtf; + if (std::abs(muEta_) < 1.24) + return L1TPhase2MuonOffline::kEtaRegionOmtf; + if (std::abs(muEta_) < 2.4) + return L1TPhase2MuonOffline::kEtaRegionEmtf; + return L1TPhase2MuonOffline::kEtaRegionAll; +} + +double GenMuonGMTPair::getDeltaVar(const L1TPhase2MuonOffline::ResType type) const { + if (type == L1TPhase2MuonOffline::kResPt) + return (gmtPt() - pt()) / pt(); + if (type == L1TPhase2MuonOffline::kRes1OverPt) + return (pt() - gmtPt()) / gmtPt(); // (1/gmtPt - 1/pt) / (1/pt) + if (type == L1TPhase2MuonOffline::kResQOverPt) + return (gmtCharge() * charge() * pt() - gmtPt()) / + gmtPt(); // (gmtCharge/gmtPt - charge/pt) / (charge/pt) with gmtCharge/charge = gmtCharge*charge + if (type == L1TPhase2MuonOffline::kResPhi) + return reco::deltaPhi(gmtPhi(), muPhi_); + if (type == L1TPhase2MuonOffline::kResEta) + return gmtEta() - muEta_; + if (type == L1TPhase2MuonOffline::kResCh) + return gmtCharge() - charge(); + return -999.; +} + +double GenMuonGMTPair::getVar(const L1TPhase2MuonOffline::EffType type) const { + if (type == L1TPhase2MuonOffline::kEffPt) + return pt(); + if (type == L1TPhase2MuonOffline::kEffPhi) + return muPhi_; + if (type == L1TPhase2MuonOffline::kEffEta) + return muEta_; + return -999.; +} + +//__________DQM_base_class_______________________________________________ +L1TPhase2MuonOffline::L1TPhase2MuonOffline(const ParameterSet& ps) : + gmtMuonToken_(consumes(ps.getParameter("gmtMuonToken"))), + gmtTkMuonToken_(consumes(ps.getParameter("gmtTkMuonToken"))), + genParticleToken_(consumes>(ps.getUntrackedParameter("genParticlesInputTag"))), + muonTypes_({kSAMuon, kTkMuon}), + effTypes_({kEffPt, kEffPhi, kEffEta}), + resTypes_({kResPt, kResQOverPt, kResPhi, kResEta}), + etaRegions_({kEtaRegionAll, kEtaRegionBmtf, kEtaRegionOmtf, kEtaRegionEmtf}), + qualLevels_({kQualOpen, kQualDouble, kQualSingle}), + resNames_({{kResPt, "pt"}, + {kRes1OverPt, "1overpt"}, + {kResQOverPt, "qoverpt"}, + {kResPhi, "phi"}, + {kResEta, "eta"}, + {kResCh, "charge"}}), + resLabels_({{kResPt, "(p_{T}^{L1} - p_{T}^{reco})/p_{T}^{reco}"}, + {kRes1OverPt, "(p_{T}^{reco} - p_{T}^{L1})/p_{T}^{L1}"}, + {kResQOverPt, "(q^{L1}*q^{reco}*p_{T}^{reco} - p_{T}^{L1})/p_{T}^{L1}"}, + {kResPhi, "#phi_{L1} - #phi_{reco}"}, + {kResEta, "#eta_{L1} - #eta_{reco}"}, + {kResCh, "charge^{L1} - charge^{reco}"}}), + etaNames_({{kEtaRegionAll, "etaMin0_etaMax2p4"}, + {kEtaRegionBmtf, "etaMin0_etaMax0p83"}, + {kEtaRegionOmtf, "etaMin0p83_etaMax1p24"}, + {kEtaRegionEmtf, "etaMin1p24_etaMax2p4"}}), + qualNames_({{kQualOpen, "qualOpen"}, + {kQualDouble, "qualDouble"}, + {kQualSingle, "qualSingle"}}), + muonNames_({{kSAMuon, "SAMuon"}, {kTkMuon, "TkMuon"}}), + histFolder_(ps.getUntrackedParameter("histFolder")), + cutsVPSet_(ps.getUntrackedParameter>("cuts")), + effVsPtBins_(ps.getUntrackedParameter>("efficiencyVsPtBins")), + effVsPhiBins_(ps.getUntrackedParameter>("efficiencyVsPhiBins")), + effVsEtaBins_(ps.getUntrackedParameter>("efficiencyVsEtaBins")), + maxGmtMuonDR_(0.3){ + + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::L1TPhase2MuonOffline()" << endl; + + // Get Muon constants + lsb_pt = Phase2L1GMT::LSBpt; + lsb_phi = Phase2L1GMT::LSBphi; + lsb_eta = Phase2L1GMT::LSBeta; + lsb_z0 = Phase2L1GMT::LSBSAz0; + lsb_d0 = Phase2L1GMT::LSBSAd0; + + for (const auto& c : cutsVPSet_) { + const auto qCut = c.getUntrackedParameter("qualCut"); + QualLevel qLevel = kQualOpen; + if (qCut > 11) { + qLevel = kQualSingle; + } else if (qCut > 7) { + qLevel = kQualDouble; + } else if (qCut > 3) { + qLevel = kQualOpen; + } + cuts_.emplace_back(std::make_pair(c.getUntrackedParameter("ptCut"), qLevel)); + } + +} + +//_____________________________________________________________________ +L1TPhase2MuonOffline::~L1TPhase2MuonOffline() {} +//---------------------------------------------------------------------- +void L1TPhase2MuonOffline::dqmBeginRun(const edm::Run& run, const edm::EventSetup& iSetup) { + edm::LogInfo("L1TPhase2MuonOFfline") << "L1TPhase2MuonOffline::dqmBeginRun" << endl; +} + + +//_____________________________________________________________________ +void L1TPhase2MuonOffline::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run& run, const edm::EventSetup& iSetup) { + edm::LogInfo("L1TPhase2MuonOFfline") << "L1TPhase2MuonOffline::bookHistograms" << endl; + + //book histos + for (const auto mutype : muonTypes_) { + bookControlHistos(ibooker, mutype); + bookEfficiencyHistos(ibooker, mutype); + bookResolutionHistos(ibooker, mutype); + } +} + +//_____________________________________________________________________ +void L1TPhase2MuonOffline::analyze(const Event& iEvent, const EventSetup& eventSetup) { + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::analyze() " << endl; + + // COLLECT GEN MUONS + iEvent.getByToken(genParticleToken_, genparticles_); + + std::vector genmus; + for (const reco::GenParticle& gen : *genparticles_) { + if (std::abs(gen.pdgId()) != 13) continue; + genmus.push_back(&gen); + } + edm::LogInfo("L1TPhase2MuonOffline") << + "L1TPhase2MuonOffline::analyze() N of genmus: "<< genmus.size() << endl; + + // Collect both muon collection: + iEvent.getByToken(gmtMuonToken_, gmtSAMuon_); + iEvent.getByToken(gmtTkMuonToken_, gmtTkMuon_); + + + // Fill Control histograms + edm::LogInfo("L1TPhase2MuonOffline") << "Fill Control histograms for GMT Muons" << endl; + fillControlHistos(); + + + // Match each muon to a gen muon, if possible. + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::analyze() calling matchMuonsToGen() "<< endl; + matchMuonsToGen(genmus); + + + // Fill efficiency and resolution once, matching has been done... + fillEfficiencyHistos(); + fillResolutionHistos(); + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::analyze() Computation finished" << endl; +} + +//_____________________________________________________________________ +void L1TPhase2MuonOffline::bookControlHistos(DQMStore::IBooker& ibooker, MuType mutype) { + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::bookControlHistos()" << endl; + + ibooker.setCurrentFolder(histFolder_ + "/" + muonNames_[mutype] + "/control_variables"); + + controlHistos_[mutype][kPt] = ibooker.book1D(muonNames_[mutype]+"Pt" , "MuonPt; p_{T}" , 50, 0., 100.); + controlHistos_[mutype][kPhi] = ibooker.book1D(muonNames_[mutype]+"Phi" , "MuonPhi; #phi" , 66, -3.3, 3.3); + controlHistos_[mutype][kEta] = ibooker.book1D(muonNames_[mutype]+"Eta" , "MuonEta; #eta" , 50, -2.5, 2.5); + controlHistos_[mutype][kIso] = ibooker.book1D(muonNames_[mutype]+"Iso" , "MuonIso; RelIso" , 50, 0, 1.0); + controlHistos_[mutype][kQual] = ibooker.book1D(muonNames_[mutype]+"Qual", "MuonQual; Quality", 15, 0.5, 15.5); + controlHistos_[mutype][kZ0] = ibooker.book1D(muonNames_[mutype]+"Z0" , "MuonZ0; Z_{0}" , 50, 0, 50.0); + controlHistos_[mutype][kD0] = ibooker.book1D(muonNames_[mutype]+"D0" , "MuonD0; D_{0}" , 50, 0, 200.); +} +void L1TPhase2MuonOffline::bookEfficiencyHistos(DQMStore::IBooker& ibooker, MuType mutype) { + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::bookEfficiencyHistos()" << endl; + + ibooker.setCurrentFolder(histFolder_ + "/" + muonNames_[mutype] + "/nums_and_dens"); + + std::string histoname = ""; + for (const auto eta : etaRegions_) { + for (const auto q : qualLevels_) { + histoname = "Eff_" + muonNames_[mutype] + "_" + etaNames_[eta] + "_" + qualNames_[q]; + + auto histBins = getHistBinsEff(kEffPt); + efficiencyNum_[mutype][eta][q][kEffPt] = ibooker.book1D(histoname + "_Pt_Num", "MuonPt; p_{T} ;", histBins.size()-1, &histBins[0]); + efficiencyDen_[mutype][eta][q][kEffPt] = ibooker.book1D(histoname + "_Pt_Den", "MuonPt; p_{T} ;", histBins.size()-1, &histBins[0]); + + histBins = getHistBinsEff(kEffEta); + efficiencyNum_[mutype][eta][q][kEffEta] = ibooker.book1D(histoname + "_Eta_Num", "MuonEta; #eta ;", histBins.size()-1, &histBins[0]); + efficiencyDen_[mutype][eta][q][kEffEta] = ibooker.book1D(histoname + "_Eta_Den", "MuonEta; #eta ;", histBins.size()-1, &histBins[0]); + + histBins = getHistBinsEff(kEffPhi); + efficiencyNum_[mutype][eta][q][kEffPhi] = ibooker.book1D(histoname + "_Phi_Num", "MuonPhi; #phi ;", histBins.size()-1, &histBins[0]); + efficiencyDen_[mutype][eta][q][kEffPhi] = ibooker.book1D(histoname + "_Phi_Den", "MuonPhi; #phi ;", histBins.size()-1, &histBins[0]); + + } + } +} +void L1TPhase2MuonOffline::bookResolutionHistos(DQMStore::IBooker& ibooker, MuType mutype) { + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::bookResolutionHistos()" << endl; + + ibooker.setCurrentFolder(histFolder_ + "/" + muonNames_[mutype] + "/resolution"); + std::string histoname = ""; + for (const auto eta : etaRegions_) { + for (const auto q : qualLevels_) { + for (const auto var : resTypes_){ + histoname = "Res_" + muonNames_[mutype] + "_" + etaNames_[eta] + "_" + qualNames_[q] + "_" + resNames_[var]; + auto nbins = std::get<0>(getHistBinsRes(var)); + auto xmin = std::get<1>(getHistBinsRes(var)); + auto xmax = std::get<2>(getHistBinsRes(var)); + resolutionHistos_[mutype][eta][q][var] = ibooker.book1D(histoname, resNames_[var] +";" + resLabels_[var], nbins, xmin, xmax); + } + } + } +} + +//____________________________________________________________________ +void L1TPhase2MuonOffline::fillControlHistos(){ + + for (auto& muIt : *gmtSAMuon_) { + controlHistos_[kSAMuon][kPt] ->Fill(lsb_pt * muIt.hwPt()); + controlHistos_[kSAMuon][kPhi] ->Fill(lsb_phi * muIt.hwPhi()); + controlHistos_[kSAMuon][kEta] ->Fill(lsb_eta * muIt.hwEta()); + controlHistos_[kSAMuon][kIso] ->Fill(muIt.hwIso()); + controlHistos_[kSAMuon][kQual]->Fill(muIt.hwQual()); + controlHistos_[kSAMuon][kZ0] ->Fill(lsb_z0 * muIt.hwZ0()); + controlHistos_[kSAMuon][kD0] ->Fill(lsb_d0 * muIt.hwD0()); + } + + for (auto& muIt : *gmtTkMuon_) { + controlHistos_[kTkMuon][kPt] ->Fill(lsb_pt * muIt.hwPt()); + controlHistos_[kTkMuon][kPhi] ->Fill(lsb_phi * muIt.hwPhi()); + controlHistos_[kTkMuon][kEta] ->Fill(lsb_eta * muIt.hwEta()); + controlHistos_[kTkMuon][kIso] ->Fill(muIt.hwIso()); + controlHistos_[kTkMuon][kQual]->Fill(muIt.hwQual()); + controlHistos_[kTkMuon][kZ0] ->Fill(lsb_z0 * muIt.hwZ0()); + controlHistos_[kTkMuon][kD0] ->Fill(lsb_d0 * muIt.hwD0()); + } +} +void L1TPhase2MuonOffline::fillEfficiencyHistos(){ + + for (auto muIt : gmtSAMuonPairs_){ + auto eta = muIt.etaRegion(); + for (const auto var : effTypes_) { + auto varToFill = muIt.getVar(var); + for (const auto& cut : cuts_){ + const auto gmtPtCut = cut.first; + const auto q = cut.second; + + efficiencyDen_[kSAMuon][eta][q][var]->Fill(varToFill) ; + if (muIt.gmtPt() < 0) continue; // gmt muon does not exits + + if (muIt.gmtQual() < q*4) continue; //quality requirements + if (var != kEffPt && muIt.gmtPt() < gmtPtCut) continue; // pt requirement + + efficiencyNum_[kSAMuon][eta][q][var]->Fill(varToFill); + } + } + } + + /// FOR TK MUONS + for (auto muIt : gmtTkMuonPairs_){ + auto eta = muIt.etaRegion(); + for (const auto var : effTypes_) { + auto varToFill = muIt.getVar(var); + for (const auto& cut : cuts_){ + const auto gmtPtCut = cut.first; + const auto q = cut.second; + + efficiencyDen_[kTkMuon][eta][q][var]->Fill(varToFill) ; + if (muIt.gmtPt() < 0) continue; // gmt muon does not exits + + if (muIt.gmtQual() < q*4) continue; //quality requirements + if (var != kEffPt && muIt.gmtPt() < gmtPtCut) continue; // pt requirement + + efficiencyNum_[kTkMuon][eta][q][var]->Fill(varToFill); + } + } + } + +} +void L1TPhase2MuonOffline::fillResolutionHistos(){ + + for (auto muIt : gmtSAMuonPairs_){ + if (muIt.gmtPt() < 0) continue; + + auto eta = muIt.etaRegion(); + for (const auto q : qualLevels_) { + if (muIt.gmtQual() < q*4) continue; + for (const auto var : resTypes_) { + auto varToFill = muIt.getDeltaVar(var); + + resolutionHistos_[kSAMuon][eta][q][var]->Fill(varToFill) ; + } + } + } + + for (auto muIt : gmtTkMuonPairs_){ + if (muIt.gmtPt() < 0) continue; + + auto eta = muIt.etaRegion(); + for (const auto q : qualLevels_) { + if (muIt.gmtQual() < q*4) continue; + for (const auto var : resTypes_) { + auto varToFill = muIt.getDeltaVar(var); + + resolutionHistos_[kTkMuon][eta][q][var]->Fill(varToFill) ; + } + } + } +} +//_____________________________________________________________________ +void L1TPhase2MuonOffline::matchMuonsToGen(std::vector genmus) { + gmtSAMuonPairs_.clear(); + gmtTkMuonPairs_.clear(); + + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::matchMuonsToGen() " << endl; + + + for (const reco::GenParticle * gen : genmus){ + edm::LogInfo("L1TPhase2MuonOffline") << "Looping on genmus: "<< gen << endl; + GenMuonGMTPair pairBestCand(&(*gen), nullptr); + for (auto& muIt : *gmtSAMuon_) { + GenMuonGMTPair pairTmpCand(&(*gen), &(muIt)); + if ((pairTmpCand.dR() < maxGmtMuonDR_) && (pairTmpCand.dR() < pairBestCand.dR())) { + pairBestCand = pairTmpCand; + } + } + gmtSAMuonPairs_.emplace_back(pairBestCand); + + GenMuonGMTPair pairBestCand2(&(*gen), nullptr); + for (auto& tkmuIt : *gmtTkMuon_) { + GenMuonGMTPair pairTmpCand(&(*gen), &(tkmuIt)); + if ((pairTmpCand.dR() < maxGmtMuonDR_) && (pairTmpCand.dR() < pairBestCand2.dR())) { + pairBestCand2 = pairTmpCand; + } + } + gmtTkMuonPairs_.emplace_back(pairBestCand2); + + } + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::matchMuonsToGen() gmtSAMuons: " << gmtSAMuonPairs_.size()<< endl; + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::matchMuonsToGen() gmtTkMuons: " << gmtTkMuonPairs_.size()<< endl; + edm::LogInfo("L1TPhase2MuonOffline") << "L1TPhase2MuonOffline::matchMuonsToGen() END " << endl; +} + + +std::vector L1TPhase2MuonOffline::getHistBinsEff(EffType eff) { + if (eff == kEffPt) { + std::vector effVsPtBins(effVsPtBins_.begin(), effVsPtBins_.end()); + return effVsPtBins; + } + if (eff == kEffPhi) { + std::vector effVsPhiBins(effVsPhiBins_.begin(), effVsPhiBins_.end()); + return effVsPhiBins; + } + if (eff == kEffEta) { + std::vector effVsEtaBins(effVsEtaBins_.begin(), effVsEtaBins_.end()); + return effVsEtaBins; + } + return {0., 1.}; +} + +std::tuple L1TPhase2MuonOffline::getHistBinsRes(ResType res) { + if (res == kResPt) + return {50, -2., 2.}; + if (res == kRes1OverPt) + return {50, -2., 2.}; + if (res == kResQOverPt) + return {50, -2., 2.}; + if (res == kResPhi) + return {96, -0.2, 0.2}; + if (res == kResEta) + return {100, -0.1, 0.1}; + if (res == kResCh) + return {5, -2, 3}; + return {1, 0, 1}; +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1TPhase2MuonOffline); diff --git a/DQMOffline/L1Trigger/src/L1TPhase2OuterTrackerTkMET.cc b/DQMOffline/L1Trigger/src/L1TPhase2OuterTrackerTkMET.cc index 130126b4cc49c..23c319b75ff3e 100644 --- a/DQMOffline/L1Trigger/src/L1TPhase2OuterTrackerTkMET.cc +++ b/DQMOffline/L1Trigger/src/L1TPhase2OuterTrackerTkMET.cc @@ -41,7 +41,7 @@ L1TPhase2OuterTrackerTkMET::L1TPhase2OuterTrackerTkMET(const edm::ParameterSet& topFolderName_ = conf_.getParameter("TopFolderName"); ttTrackToken_ = consumes > >(conf_.getParameter("TTTracksTag")); - pvToken = consumes(conf_.getParameter("L1VertexInputTag")); + pvToken = consumes(conf_.getParameter("L1VertexInputTag")); maxZ0 = conf_.getParameter("maxZ0"); DeltaZ = conf_.getParameter("DeltaZ"); @@ -65,7 +65,7 @@ L1TPhase2OuterTrackerTkMET::~L1TPhase2OuterTrackerTkMET() { // ------------ method called for each event ------------ void L1TPhase2OuterTrackerTkMET::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { // L1 Primaries - edm::Handle L1VertexHandle; + edm::Handle L1VertexHandle; iEvent.getByToken(pvToken, L1VertexHandle); edm::Handle > > TTTrackHandle; @@ -92,7 +92,7 @@ void L1TPhase2OuterTrackerTkMET::analyze(const edm::Event& iEvent, const edm::Ev double etTot_PU = 0; int nTracks_counter = 0; - float zVTX = L1VertexHandle->begin()->zvertex(); + float zVTX = L1VertexHandle->begin()->z0(); unsigned int tkCnt = 0; for (const auto& trackIter : *TTTrackHandle) { edm::Ptr > tempTrackPtr(TTTrackHandle, tkCnt++); /// Make the pointer diff --git a/DataFormats/L1TCorrelator/interface/TkElectronFwd.h b/DataFormats/L1TCorrelator/interface/TkElectronFwd.h index f1a8e09dc8885..afef20cfa5da5 100644 --- a/DataFormats/L1TCorrelator/interface/TkElectronFwd.h +++ b/DataFormats/L1TCorrelator/interface/TkElectronFwd.h @@ -10,6 +10,7 @@ #include #include "DataFormats/Common/interface/Ref.h" #include "DataFormats/Common/interface/RefVector.h" +#include "DataFormats/L1Trigger/interface/RegionalOutput.h" namespace l1t { class TkElectron; @@ -19,5 +20,7 @@ namespace l1t { typedef edm::Ref TkElectronRef; typedef edm::RefVector TkElectronRefVector; typedef std::vector TkElectronVectorRef; + typedef l1t::RegionalOutput TkElectronRegionalOutput; + } // namespace l1t #endif diff --git a/DataFormats/L1TCorrelator/interface/TkEm.h b/DataFormats/L1TCorrelator/interface/TkEm.h index bad489b51c043..d3d9c36a41c7f 100644 --- a/DataFormats/L1TCorrelator/interface/TkEm.h +++ b/DataFormats/L1TCorrelator/interface/TkEm.h @@ -13,6 +13,7 @@ #include "DataFormats/L1Trigger/interface/EGamma.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include namespace l1t { @@ -37,19 +38,46 @@ namespace l1t { const double l1RefEt() const { return egRef_->et(); } - float trkIsol() const { return trkIsol_; } // not constrained to the PV, just track ptSum - - float trkIsolPV() const { return trkIsolPV_; } // constrained to the PV by DZ + float trkIsol() const { return trkIsol_; } // not constrained to the PV, just track ptSum + float trkIsolPV() const { return trkIsolPV_; } // constrained to the PV by DZ + float pfIsol() const { return pfIsol_; } // not constrained to the PV, just track ptSum + float pfIsolPV() const { return pfIsolPV_; } // constrained to the PV by DZ + float puppiIsol() const { return puppiIsol_; } // not constrained to the PV, just track ptSum + float puppiIsolPV() const { return puppiIsolPV_; } // constrained to the PV by DZ // ---------- member functions --------------------------- void setTrkIsol(float TrkIsol) { trkIsol_ = TrkIsol; } void setTrkIsolPV(float TrkIsolPV) { trkIsolPV_ = TrkIsolPV; } + void setPFIsol(float pfIsol) { pfIsol_ = pfIsol; } + void setPFIsolPV(float pfIsolPV) { pfIsolPV_ = pfIsolPV; } + void setPuppiIsol(float puppiIsol) { puppiIsol_ = puppiIsol; } + void setPuppiIsolPV(float puppiIsolPV) { puppiIsolPV_ = puppiIsolPV; } + void setEGRef(const edm::Ref& egRef) { egRef_ = egRef; } + + template + void setEgBinaryWord(ap_uint word) { + egBinaryWord0_ = word; + egBinaryWord1_ = (word >> 32); + egBinaryWord2_ = (word >> 64); + } + + template + ap_uint egBinaryWord() const { + return ap_uint(egBinaryWord0_) | (ap_uint(egBinaryWord1_) << 32) | (ap_uint(egBinaryWord2_) << 64); + } private: edm::Ref egRef_; float trkIsol_; float trkIsolPV_; + float pfIsol_; + float pfIsolPV_; + float puppiIsol_; + float puppiIsolPV_; + uint32_t egBinaryWord0_; + uint32_t egBinaryWord1_; + uint32_t egBinaryWord2_; }; } // namespace l1t diff --git a/DataFormats/L1TCorrelator/interface/TkEmFwd.h b/DataFormats/L1TCorrelator/interface/TkEmFwd.h index 24045ab56dadb..8a190eec390ff 100644 --- a/DataFormats/L1TCorrelator/interface/TkEmFwd.h +++ b/DataFormats/L1TCorrelator/interface/TkEmFwd.h @@ -10,6 +10,7 @@ #include #include "DataFormats/Common/interface/Ref.h" #include "DataFormats/Common/interface/RefVector.h" +#include "DataFormats/L1Trigger/interface/RegionalOutput.h" namespace l1t { @@ -20,6 +21,8 @@ namespace l1t { typedef edm::Ref TkEmRef; typedef edm::RefVector TkEmRefVector; typedef std::vector TkEmVectorRef; + typedef l1t::RegionalOutput TkEmRegionalOutput; + } // namespace l1t #endif diff --git a/DataFormats/L1TCorrelator/interface/TkEtMiss.h b/DataFormats/L1TCorrelator/interface/TkEtMiss.h index a9cd6e5d26e8a..8fdcd13246938 100644 --- a/DataFormats/L1TCorrelator/interface/TkEtMiss.h +++ b/DataFormats/L1TCorrelator/interface/TkEtMiss.h @@ -3,7 +3,7 @@ #include "DataFormats/L1Trigger/interface/L1Candidate.h" #include "DataFormats/Common/interface/Ref.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" namespace l1t { class TkEtMiss : public L1Candidate { @@ -15,7 +15,7 @@ namespace l1t { const double& etTotal, const double& etMissPU, const double& etTotalPU, - const edm::Ref& aVtxRef = edm::Ref(), + const edm::Ref& aVtxRef = edm::Ref(), int bx = 0); TkEtMiss(const LorentzVector& p4, @@ -25,6 +25,8 @@ namespace l1t { const double& etTotalPU, int bx = 0); + TkEtMiss(const LorentzVector& p4, EtMissType type, const double& EtPhi, const int& NumTracks, int bx = 0); + // ---------- const member functions --------------------- EtMissType type() const { return type_; } // kMET or kMHT // For type = kMET, this is |MET|; for type = kMHT, this is |MHT| @@ -35,7 +37,10 @@ namespace l1t { double etMissPU() const { return etMissPU_; } double etTotalPU() const { return etTotalPU_; } int bx() const { return bx_; } - const edm::Ref& vtxRef() const { return vtxRef_; } + const edm::Ref& vtxRef() const { return vtxRef_; } + + double etPhi() const { return etPhi_; } + int etQual() const { return etQual_; } // ---------- member functions --------------------------- void setEtTotal(const double& etTotal) { etTot_ = etTotal; } @@ -47,7 +52,12 @@ namespace l1t { double etTot_; double etMissPU_; double etTotalPU_; - edm::Ref vtxRef_; + edm::Ref vtxRef_; + + double etMiss_; + double etPhi_; + int etQual_; + int bx_; }; } // namespace l1t diff --git a/DataFormats/L1TCorrelator/interface/TkHTMiss.h b/DataFormats/L1TCorrelator/interface/TkHTMiss.h index c13684cdbe57b..174511c34aa09 100644 --- a/DataFormats/L1TCorrelator/interface/TkHTMiss.h +++ b/DataFormats/L1TCorrelator/interface/TkHTMiss.h @@ -7,7 +7,7 @@ #include "DataFormats/Common/interface/Ref.h" #include "DataFormats/Common/interface/RefProd.h" #include "DataFormats/Common/interface/Ref.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" #include "DataFormats/L1TCorrelator/interface/TkJet.h" #include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" @@ -18,7 +18,7 @@ namespace l1t { TkHTMiss(const LorentzVector& p4, double EtTotal, const edm::RefProd& jetCollRef = edm::RefProd(), - const edm::Ref& aVtxRef = edm::Ref(), + const edm::Ref& aVtxRef = edm::Ref(), int bx = 0); // ---------- const member functions --------------------- @@ -32,7 +32,7 @@ namespace l1t { int bx() const { return bx_; } float vtx() const { return zvtx_; } const edm::RefProd& jetCollectionRef() const { return jetCollectionRef_; } - const edm::Ref& vtxRef() const { return vtxRef_; } + const edm::Ref& vtxRef() const { return vtxRef_; } // ---------- member functions --------------------------- void setEtTotal(double EtTotal) { etTot_ = EtTotal; } @@ -49,7 +49,7 @@ namespace l1t { double etTotalPU_; // HT from jets that don't come from zvtx edm::RefProd jetCollectionRef_; - edm::Ref vtxRef_; + edm::Ref vtxRef_; int bx_; }; diff --git a/DataFormats/L1TCorrelator/interface/TkJet.h b/DataFormats/L1TCorrelator/interface/TkJet.h index 744bc2a2bd013..82f983d23f168 100644 --- a/DataFormats/L1TCorrelator/interface/TkJet.h +++ b/DataFormats/L1TCorrelator/interface/TkJet.h @@ -32,7 +32,8 @@ namespace l1t { unsigned int ntracks = 0, unsigned int tighttracks = 0, unsigned int displacedtracks = 0, - unsigned int tightdisplacedtracks = 0); + unsigned int tightdisplacedtracks = 0, + bool displacedTag = false); // ---------- const member functions --------------------- @@ -45,6 +46,7 @@ namespace l1t { unsigned int nTighttracks() const { return tighttracks_; } unsigned int nDisptracks() const { return displacedtracks_; } unsigned int nTightDisptracks() const { return tightdisplacedtracks_; } + bool isDisplaced() const { return displacedTag_; } // ---------- member functions --------------------------- void setJetVtx(float JetVtx) { JetVtx_ = JetVtx; } @@ -56,6 +58,7 @@ namespace l1t { std::vector > trkPtrs_; float JetVtx_; unsigned int ntracks_, tighttracks_, displacedtracks_, tightdisplacedtracks_; + bool displacedTag_; }; } // namespace l1t diff --git a/DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h b/DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h deleted file mode 100644 index 4981e387beae0..0000000000000 --- a/DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef DataFormatsL1TCorrelator_TkPrimaryVertex_h -#define DataFormatsL1TCorrelator_TkPrimaryVertex_h - -// Package: L1TCorrelator -// Class : TkPrimaryVertex - -// First version of a class for L1-zvertex -#include -#include "DataFormats/Common/interface/Ref.h" -#include "DataFormats/Common/interface/RefVector.h" - -namespace l1t { - - class TkPrimaryVertex { - public: - TkPrimaryVertex() : zvertex_(-999), sum_(-999) {} - - ~TkPrimaryVertex() {} - - TkPrimaryVertex(float z, float s) : zvertex_(z), sum_(s) {} - - float zvertex() const { return zvertex_; } - float sum() const { return sum_; } - - private: - float zvertex_; - float sum_; - }; - - typedef std::vector TkPrimaryVertexCollection; - typedef edm::Ref TkPrimaryVertexRef; - typedef edm::RefVector TkPrimaryVertexRefVector; - typedef std::vector TkPrimaryVertexVectorRef; - -} // namespace l1t -#endif diff --git a/DataFormats/L1TCorrelator/src/TkEm.cc b/DataFormats/L1TCorrelator/src/TkEm.cc index 7a598ebed8a38..276f13c1ec0bf 100644 --- a/DataFormats/L1TCorrelator/src/TkEm.cc +++ b/DataFormats/L1TCorrelator/src/TkEm.cc @@ -11,7 +11,17 @@ using namespace l1t; TkEm::TkEm() {} TkEm::TkEm(const LorentzVector& p4, const edm::Ref& egRef, float tkisol) - : L1Candidate(p4), egRef_(egRef), trkIsol_(tkisol), trkIsolPV_(-999) {} + : TkEm(p4, egRef, tkisol, -999) {} TkEm::TkEm(const LorentzVector& p4, const edm::Ref& egRef, float tkisol, float tkisolPV) - : L1Candidate(p4), egRef_(egRef), trkIsol_(tkisol), trkIsolPV_(tkisolPV) {} + : L1Candidate(p4), + egRef_(egRef), + trkIsol_(tkisol), + trkIsolPV_(tkisolPV), + pfIsol_(-999), + pfIsolPV_(-999), + puppiIsol_(-999), + puppiIsolPV_(-999), + egBinaryWord0_(0), + egBinaryWord1_(0), + egBinaryWord2_(0) {} diff --git a/DataFormats/L1TCorrelator/src/TkEtMiss.cc b/DataFormats/L1TCorrelator/src/TkEtMiss.cc index 51d1d28cdb3b1..c91bcb830baf1 100644 --- a/DataFormats/L1TCorrelator/src/TkEtMiss.cc +++ b/DataFormats/L1TCorrelator/src/TkEtMiss.cc @@ -9,7 +9,7 @@ TkEtMiss::TkEtMiss(const LorentzVector& p4, const double& etTotal, const double& etMissPU, const double& etTotalPU, - const edm::Ref& avtxRef, + const edm::Ref& avtxRef, int bx) : L1Candidate(p4), type_(type), @@ -26,3 +26,6 @@ TkEtMiss::TkEtMiss(const LorentzVector& p4, const double& etTotalPU, int bx) : L1Candidate(p4), type_(type), etTot_(etTotal), etMissPU_(etMissPU), etTotalPU_(etTotalPU), bx_(bx) {} + +TkEtMiss::TkEtMiss(const LorentzVector& p4, EtMissType type, const double& EtPhi, const int& qual, int bx) + : L1Candidate(p4), type_(type), etPhi_(EtPhi), etQual_(qual), bx_(bx) {} diff --git a/DataFormats/L1TCorrelator/src/TkHTMiss.cc b/DataFormats/L1TCorrelator/src/TkHTMiss.cc index 114213222c4b2..3ec5c764be902 100644 --- a/DataFormats/L1TCorrelator/src/TkHTMiss.cc +++ b/DataFormats/L1TCorrelator/src/TkHTMiss.cc @@ -7,10 +7,10 @@ TkHTMiss::TkHTMiss() {} TkHTMiss::TkHTMiss(const LorentzVector& p4, double etTotal, const edm::RefProd& jetCollRef, - const edm::Ref& avtxRef, + const edm::Ref& avtxRef, int bx) : L1Candidate(p4), etTot_(etTotal), jetCollectionRef_(jetCollRef), vtxRef_(avtxRef), bx_(bx) { if (vtxRef_.isNonnull()) { - setVtx(vtxRef()->zvertex()); + setVtx(vtxRef()->z0()); } } diff --git a/DataFormats/L1TCorrelator/src/TkJet.cc b/DataFormats/L1TCorrelator/src/TkJet.cc index 2ac5a2dc8ee64..f14763b305644 100644 --- a/DataFormats/L1TCorrelator/src/TkJet.cc +++ b/DataFormats/L1TCorrelator/src/TkJet.cc @@ -21,14 +21,17 @@ TkJet::TkJet(const LorentzVector& p4, unsigned int ntracks, unsigned int tighttracks, unsigned int displacedtracks, - unsigned int tightdisplacedtracks) + unsigned int tightdisplacedtracks, + bool displacedTag) : L1Candidate(p4), trkPtrs_(trkPtrs), JetVtx_(jetvtx), ntracks_(ntracks), tighttracks_(tighttracks), displacedtracks_(displacedtracks), - tightdisplacedtracks_(tightdisplacedtracks) {} + tightdisplacedtracks_(tightdisplacedtracks), + displacedTag_(displacedTag) {} + int TkJet::bx() const { // in the producer TkJetProducer.cc, we keep only jets with bx = 0 return 0; diff --git a/DataFormats/L1TCorrelator/src/classes.h b/DataFormats/L1TCorrelator/src/classes.h index fd0aabbb89293..bf296c0e0d74f 100644 --- a/DataFormats/L1TCorrelator/src/classes.h +++ b/DataFormats/L1TCorrelator/src/classes.h @@ -14,7 +14,6 @@ // includes needed for the L1TrackTriggerObjects -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" #include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" #include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" diff --git a/DataFormats/L1TCorrelator/src/classes_def.xml b/DataFormats/L1TCorrelator/src/classes_def.xml index a9c156c248963..0685c6bc1356e 100644 --- a/DataFormats/L1TCorrelator/src/classes_def.xml +++ b/DataFormats/L1TCorrelator/src/classes_def.xml @@ -1,28 +1,27 @@ - - - - - - - - - + + + - + + + + + + @@ -45,15 +44,21 @@ - + + + + + + - + + @@ -62,8 +67,9 @@ - - + + + @@ -109,4 +115,3 @@ - diff --git a/DataFormats/L1TMuonPhase2/BuildFile.xml b/DataFormats/L1TMuonPhase2/BuildFile.xml new file mode 100644 index 0000000000000..9633dd38014e9 --- /dev/null +++ b/DataFormats/L1TMuonPhase2/BuildFile.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/DataFormats/L1TMuonPhase2/interface/MuonStub.h b/DataFormats/L1TMuonPhase2/interface/MuonStub.h new file mode 100644 index 0000000000000..eb571d3ca0598 --- /dev/null +++ b/DataFormats/L1TMuonPhase2/interface/MuonStub.h @@ -0,0 +1,143 @@ +//------------------------------------------------- +// +/** \class MuonStub + * + * Class that creates a super-primitive for all chambers + * + * + * M.Bachtis (UCLA) + */ +// +//-------------------------------------------------- +#ifndef L1TMUPHASE2GMTSTUB_H +#define L1TMUPHASE2GMTSTUB_H +//--------------- +// C++ Headers -- +//--------------- + +#include +#include + +//---------------------- +// Base Class Headers -- +//---------------------- + +//------------------------------------ +// Collaborating Class Declarations -- +//------------------------------------ + +//#include "DataFormats/L1TMuon/interface/BMTF/L1MuBMTrackSegLoc.h" +#include "DataFormats/L1Trigger/interface/BXVector.h" +#include "DataFormats/Common/interface/Ref.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +// --------------------- +// -- Class Interface -- +// --------------------- + +namespace l1t { + + class MuonStub; + + typedef std::vector MuonStubCollection; + typedef edm::Ref MuonStubRef; + typedef std::vector > MuonStubRefVector; + + class MuonStub { + public: + /// default constructor + MuonStub(); + + /// constructor + MuonStub(int etaRegion, + int phiRegion, + int depthRegion, + uint tfLayer, + int coord1, + int coord2, + int id, + int bx, + int quality, + int eta1 = 0, + int eta2 = 0, + int etaQuality = -1, + int type = 0); + ~MuonStub(); + /// return wheel + inline int etaRegion() const { return etaRegion_; } + /// return sector + inline int phiRegion() const { return phiRegion_; } + /// return station + inline int depthRegion() const { return depthRegion_; } + /// return track finder layer + inline uint tfLayer() const { return tfLayer_; } + /// return phi + inline int coord1() const { return coord1_; } + /// return phib + inline int coord2() const { return coord2_; } + /// return quality code + inline int quality() const { return quality_; } + /// return tag (second TS tag) + inline int id() const { return id_; } + /// return bunch crossing + inline int bxNum() const { return bxNum_; } + + /// return eta + inline int eta1() const { return eta1_; } + inline int eta2() const { return eta2_; } + /// return first eta quality + inline int etaQuality() const { return etaQuality_; } + //return type + inline int type() const { return type_; } + + inline bool isBarrel() const { return (type_ == 1); } + inline bool isEndcap() const { return (type_ == 0); } + + inline double offline_coord1() const { return offline_coord1_; } + inline double offline_coord2() const { return offline_coord2_; } + inline double offline_eta1() const { return offline_eta1_; } + inline double offline_eta2() const { return offline_eta2_; } + + void setOfflineQuantities(double coord1, double coord2, double eta1, double eta2) { + offline_coord1_ = coord1; + offline_coord2_ = coord2; + offline_eta1_ = eta1; + offline_eta2_ = eta2; + } + void setEta(int eta1, int eta2, int etaQ) { + eta1_ = eta1; + eta2_ = eta2; + etaQuality_ = etaQ; + } + + void setID(int id) { id_ = id; } + /// equal operator + bool operator==(const MuonStub&) const; + /// unequal operator + bool operator!=(const MuonStub&) const; + + void print() const; + + private: + int etaRegion_; //In the barrel this is wheel. In the endcap it is 6-ring + int phiRegion_; //In the barrel it is sector. In the endcap it is chamber + int depthRegion_; //Station + uint tfLayer_; //TF Layer + int coord1_; // global position angle in units of 30 degrees/2048 + int coord2_; // bending angle only in barrel for now + int id_; // stub id in case of more stubs per chamber + int quality_; // + int bxNum_; // bunch crossing identifier + int eta1_; // eta coordinate - in units of 3.0/512. + int eta2_; // eta coordinate - in units of 3.0/512. + int etaQuality_; // quality of the eta information + int type_; //Type: 0 TwinMux or DT, 1 RPC Barrel, 2 CSC, 3 RPC endcap + /////////members that are not hardware but used for offline studies/////////////////////////////// + double offline_coord1_; //offline coordinate 1 + double offline_coord2_; //offline coordinate two + double offline_eta1_; //offline eta1 + double offline_eta2_; //offline eta2 + }; + +} // namespace l1t +#endif diff --git a/DataFormats/L1TMuonPhase2/interface/SAMuon.h b/DataFormats/L1TMuonPhase2/interface/SAMuon.h new file mode 100644 index 0000000000000..8e23b34c82e5b --- /dev/null +++ b/DataFormats/L1TMuonPhase2/interface/SAMuon.h @@ -0,0 +1,69 @@ +#ifndef DataFormatsL1TMuonPhase2_SAMuon_h +#define DataFormatsL1TMuonPhase2_SAMuon_h + +#include "DataFormats/L1Trigger/interface/L1Candidate.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/Ptr.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" + +namespace l1t { + + class SAMuon; + + typedef std::vector SAMuonCollection; + typedef edm::Ref SAMuonRef; + typedef std::vector > SAMuonRefVector; + + class SAMuon : public L1Candidate { + public: + SAMuon(); + + SAMuon(const l1t::Muon& mu, bool charge, uint pt, int eta, int phi, int z0, int d0, uint quality); + + ~SAMuon() override; + + const bool hwCharge() const { return hwCharge_; } + const int hwZ0() const { return hwZ0_; } + const int hwD0() const { return hwD0_; } + const uint hwBeta() const { return hwBeta_; } + void setBeta(uint beta) { hwBeta_ = beta; } + + // For HLT + const double phZ0() const { return Phase2L1GMT::LSBSAz0*hwZ0();} + const double phD0() const { return Phase2L1GMT::LSBSAd0*hwD0();} + const double phPt() const { return Phase2L1GMT::LSBpt*hwPt();} + const double phEta() const { return Phase2L1GMT::LSBeta*hwEta();} + const double phPhi() const { return Phase2L1GMT::LSBphi*hwPhi();} + const int phCharge() const {return pow(-1,hwCharge()); } + + const uint64_t word() const { return word_; } + void setWord(uint64_t word) { word_ = word; } + void print() const; + + bool operator<(const SAMuon& other) const { + if (hwPt() == other.hwPt()) + return (hwEta() < other.hwEta()); + else + return (hwPt() < other.hwPt()); + } + bool operator>(const SAMuon& other) const { + if (hwPt() == other.hwPt()) + return (hwEta() > other.hwEta()); + else + return (hwPt() > other.hwPt()); + } + + private: + bool hwCharge_; + int hwZ0_; + int hwD0_; + uint hwBeta_; + uint64_t word_; + }; +} // namespace l1t + +#endif diff --git a/DataFormats/L1TMuonPhase2/interface/TrackerMuon.h b/DataFormats/L1TMuonPhase2/interface/TrackerMuon.h new file mode 100644 index 0000000000000..1836b7b55bed6 --- /dev/null +++ b/DataFormats/L1TMuonPhase2/interface/TrackerMuon.h @@ -0,0 +1,84 @@ +#ifndef DataFormatsL1TMuonPhase2_TrackerMuon_h +#define DataFormatsL1TMuonPhase2_TrackerMuon_h + +#include "DataFormats/L1Trigger/interface/L1Candidate.h" +#include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/Ptr.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" + +namespace l1t { + + class TrackerMuon; + + typedef std::vector TrackerMuonCollection; + typedef edm::Ref TrackerMuonRef; + typedef std::vector > TrackerMuonRefVector; + + class TrackerMuon : public L1Candidate { + public: + typedef TTTrack L1TTTrackType; + typedef std::vector L1TTTrackCollection; + + TrackerMuon(); + + TrackerMuon( + const edm::Ptr& trk, bool charge, uint pt, int eta, int phi, int z0, int d0, uint quality); + + ~TrackerMuon() override; + + const edm::Ptr& trkPtr() const { return trkPtr_; } + const edm::Ref& muonRef() const { return muRef_; } + + const bool hwCharge() const { return hwCharge_; } + const int hwZ0() const { return hwZ0_; } + const int hwD0() const { return hwD0_; } + const int hwIsoSum() const { return hwIsoSum_; } + const int hwIsoSumAp() const { return hwIsoSumAp_; } + const uint hwBeta() const { return hwBeta_; } + void setBeta(uint beta) { hwBeta_ = beta; } + void setMuonRef(const edm::Ref& p) { muRef_ = p; } + void setHwIsoSum(int isoSum) { hwIsoSum_ = isoSum; } + void setHwIsoSumAp(int isoSum) { hwIsoSumAp_ = isoSum; } + + // For HLT + const double phZ0() const { return Phase2L1GMT::LSBGTz0*hwZ0();} + const double phD0() const { return Phase2L1GMT::LSBGTd0*hwD0();} + const double phPt() const { return Phase2L1GMT::LSBpt*hwPt();} + const double phEta() const { return Phase2L1GMT::LSBeta*hwEta();} + const double phPhi() const { return Phase2L1GMT::LSBphi*hwPhi();} + const int phCharge() const {return pow(-1,hwCharge()); } + + const std::array word() const { return word_; } + void setWord(std::array word) { word_ = word; } + void print() const; + const MuonStubRefVector stubs() const { return stubs_; } + void addStub(const MuonStubRef& stub) { stubs_.push_back(stub); } + + bool operator<(const TrackerMuon& other) const { return (hwPt() < other.hwPt()); } + bool operator>(const TrackerMuon& other) const { return (hwPt() > other.hwPt()); } + + private: + // used for the Naive producer + edm::Ptr trkPtr_; + bool hwCharge_; + int hwZ0_; + int hwD0_; + uint hwBeta_; + // The tracker muon is encoded in 96 bits as a 2-element array of uint64_t + std::array word_ = {{0, 0}}; + //Store the eneryg sum for isolation + int hwIsoSum_; + //Store the eneryg sum for isolation with ap_type + int hwIsoSumAp_; + + edm::Ref muRef_; + MuonStubRefVector stubs_; + }; +} // namespace l1t + +#endif diff --git a/DataFormats/L1TMuonPhase2/src/MuonStub.cc b/DataFormats/L1TMuonPhase2/src/MuonStub.cc new file mode 100644 index 0000000000000..779da226920b6 --- /dev/null +++ b/DataFormats/L1TMuonPhase2/src/MuonStub.cc @@ -0,0 +1,89 @@ +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" + +#include +#include +#include + +using namespace std; +using namespace l1t; +MuonStub::MuonStub() + : etaRegion_(0), + phiRegion_(0), + depthRegion_(0), + coord1_(0), + coord2_(0), + id_(0), + quality_(-1), + bxNum_(17), + eta1_(0), + eta2_(0), + etaQuality_(-1), + type_(0) {} + +MuonStub::MuonStub(int etaRegion, + int phiRegion, + int depthRegion, + uint tfLayer, + int coord1, + int coord2, + int id, + int bx, + int quality, + int eta1, + int eta2, + int etaQuality, + int type) + : etaRegion_(etaRegion), + phiRegion_(phiRegion), + depthRegion_(depthRegion), + tfLayer_(tfLayer), + coord1_(coord1), + coord2_(coord2), + id_(id), + quality_(quality), + bxNum_(bx), + eta1_(eta1), + eta2_(eta2), + etaQuality_(etaQuality), + type_(type) {} + +MuonStub::~MuonStub() {} + +bool MuonStub::operator==(const MuonStub& id) const { + if (etaRegion_ != id.etaRegion_) + return false; + if (phiRegion_ != id.phiRegion_) + return false; + if (depthRegion_ != id.depthRegion_) + return false; + if (id_ != id.id_) + return false; + if (coord1_ != id.coord1_) + return false; + if (coord2_ != id.coord2_) + return false; + if (quality_ != id.quality_) + return false; + if (bxNum_ != id.bxNum_) + return false; + if (eta1_ != id.eta1_) + return false; + if (eta2_ != id.eta2_) + return false; + if (etaQuality_ != id.etaQuality_) + return false; + if (type_ != id.type_) + return false; + return true; +} + +// +// output stream operator for phi track segments +// + +void MuonStub::print() const { + LogDebug("MuonStub") << " MuonStub : BX=" << bxNum_ << " etaRegion=" << etaRegion_ << " phiRegion=" << phiRegion_ + << " depth=" << depthRegion_ << " ID=" << id_ << " coord1=" << coord1_ << " coord2=" << coord2_ + << " quality=" << quality_ << " eta1=" << eta1_ << " eta2=" << eta2_ + << " etaQuality=" << etaQuality_ << " type=" << type_; +} diff --git a/DataFormats/L1TMuonPhase2/src/SAMuon.cc b/DataFormats/L1TMuonPhase2/src/SAMuon.cc new file mode 100644 index 0000000000000..a6e19d5d7e991 --- /dev/null +++ b/DataFormats/L1TMuonPhase2/src/SAMuon.cc @@ -0,0 +1,17 @@ +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" + +using namespace l1t; + +SAMuon::SAMuon() : hwZ0_(0), hwD0_(0), word_(0) {} + +SAMuon::SAMuon(const l1t::Muon& mu, bool charge, uint pt, int eta, int phi, int z0, int d0, uint quality) + : L1Candidate(mu.p4(), pt, eta, phi, quality), hwCharge_(charge), hwZ0_(z0), hwD0_(d0), word_(0) {} + +SAMuon::~SAMuon() {} + +void SAMuon::print() const { + LogDebug("SAMuon") << "Standalone Muon: charge=" << hwCharge_ << " pt=" << hwPt() << "," << p4().pt() + << " eta=" << hwEta() << "," << p4().eta() << " phi=" << hwPhi() << "," << p4().phi() + << " z0=" << hwZ0_ << " d0=" << hwD0_ << " isolation=" << hwIso() << " beta=" << hwBeta_ + << " quality=" << hwQual(); +} diff --git a/DataFormats/L1TMuonPhase2/src/TrackerMuon.cc b/DataFormats/L1TMuonPhase2/src/TrackerMuon.cc new file mode 100644 index 0000000000000..7beba2607bba5 --- /dev/null +++ b/DataFormats/L1TMuonPhase2/src/TrackerMuon.cc @@ -0,0 +1,28 @@ + +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" + +using namespace l1t; + +TrackerMuon::TrackerMuon() : hwZ0_(0), hwD0_(0) {} + +TrackerMuon::TrackerMuon( + const edm::Ptr& trk, bool charge, uint pt, int eta, int phi, int z0, int d0, uint quality) + : L1Candidate(LorentzVector(trk->momentum().x(), trk->momentum().y(), trk->momentum().z(), trk->momentum().mag()), + pt, + eta, + phi, + quality), + trkPtr_(trk), + hwCharge_(charge), + hwZ0_(z0), + hwD0_(d0), + hwBeta_(15) {} + +TrackerMuon::~TrackerMuon() {} + +void TrackerMuon::print() const { + LogDebug("TrackerMuon") << "Tracker Muon : charge=" << hwCharge_ << " pt=" << hwPt() << "," << p4().pt() + << " eta=" << hwEta() << "," << p4().eta() << " phi=" << hwPhi() << "," << p4().phi() + << " z0=" << hwZ0_ << " d0=" << hwD0_ << " isolation=" << hwIso() << " beta=" << hwBeta_ + << " quality=" << hwQual(); +} diff --git a/DataFormats/L1TMuonPhase2/src/classes.h b/DataFormats/L1TMuonPhase2/src/classes.h new file mode 100644 index 0000000000000..c970357cc3958 --- /dev/null +++ b/DataFormats/L1TMuonPhase2/src/classes.h @@ -0,0 +1,6 @@ +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/Common/interface/RefToBase.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" +#include diff --git a/DataFormats/L1TMuonPhase2/src/classes_def.xml b/DataFormats/L1TMuonPhase2/src/classes_def.xml new file mode 100644 index 0000000000000..0425108cccf9e --- /dev/null +++ b/DataFormats/L1TMuonPhase2/src/classes_def.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DataFormats/L1TParticleFlow/BuildFile.xml b/DataFormats/L1TParticleFlow/BuildFile.xml index 5fe29ba1b852b..8944fa359f2c4 100644 --- a/DataFormats/L1TParticleFlow/BuildFile.xml +++ b/DataFormats/L1TParticleFlow/BuildFile.xml @@ -5,6 +5,7 @@ + diff --git a/DataFormats/L1TParticleFlow/interface/HPSPFTau.h b/DataFormats/L1TParticleFlow/interface/HPSPFTau.h index 68b3e8c43d028..1de175bb66f58 100644 --- a/DataFormats/L1TParticleFlow/interface/HPSPFTau.h +++ b/DataFormats/L1TParticleFlow/interface/HPSPFTau.h @@ -5,7 +5,7 @@ #include "DataFormats/JetReco/interface/CaloJet.h" #include "DataFormats/Candidate/interface/LeafCandidate.h" // reco::LeafCandidate #include "DataFormats/Candidate/interface/Particle.h" // reco::Particle::LorentzVector -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" #include @@ -52,7 +52,7 @@ namespace l1t { const l1t::PFCandidateRefVector& sumPhotons() const { return sumPhotons_; } const l1t::PFCandidateRefVector& sumMuons() const { return sumMuons_; } - const l1t::TkPrimaryVertexRef& primaryVertex() const { return primaryVertex_; } + const l1t::VertexWordRef& primaryVertex() const { return primaryVertex_; } enum Kind { kUndefined, kOneProng0Pi0, kOneProng1Pi0, kThreeProng0Pi0, kThreeProng1Pi0 }; Kind tauType() const { return tauType_; } @@ -67,6 +67,7 @@ namespace l1t { float sumNeutralIso() const { return sumNeutralIso_; } float sumCombinedIso() const { return sumCombinedIso_; } float sumChargedIsoPileup() const { return sumChargedIsoPileup_; } + float z() const { return z_; } bool passTightIso() const { return passTightIso_; } bool passMediumIso() const { return passMediumIso_; } @@ -119,7 +120,7 @@ namespace l1t { void setSumPhotons(l1t::PFCandidateRefVector sumPhotons) { sumPhotons_ = sumPhotons; } void setSumMuons(l1t::PFCandidateRefVector sumMuons) { sumMuons_ = sumMuons; } - void setPrimaryVertex(l1t::TkPrimaryVertexRef primaryVertex) { primaryVertex_ = primaryVertex; } + void setPrimaryVertex(l1t::VertexWordRef primaryVertex) { primaryVertex_ = primaryVertex; } void setTauType(Kind tauType) { tauType_ = tauType; } @@ -133,6 +134,7 @@ namespace l1t { void setSumNeutralIso(float sumNeutralIso) { sumNeutralIso_ = sumNeutralIso; } void setSumCombinedIso(float sumCombinedIso) { sumCombinedIso_ = sumCombinedIso; } void setSumChargedIsoPileup(float sumChargedIsoPileup) { sumChargedIsoPileup_ = sumChargedIsoPileup; } + void setZ(float Z) { z_ = Z; } void setPassTightIso(bool passTightIso) { passTightIso_ = passTightIso; } void setPassMediumIso(bool passMediumIso) { passMediumIso_ = passMediumIso; } @@ -174,7 +176,7 @@ namespace l1t { l1t::PFCandidateRefVector sumPhotons_; l1t::PFCandidateRefVector sumMuons_; - l1t::TkPrimaryVertexRef primaryVertex_; + l1t::VertexWordRef primaryVertex_; Kind tauType_; reco::Particle::LorentzVector stripP4_; @@ -197,6 +199,8 @@ namespace l1t { bool passMediumRelIso_; bool passLooseRelIso_; bool passVLooseRelIso_; + + float z_; }; } // namespace l1t @@ -204,7 +208,7 @@ namespace l1t { /// print to stream std::ostream& operator<<(std::ostream& os, const l1t::HPSPFTau& l1PFTau); -void printPFCand(ostream& os, const l1t::PFCandidate& l1PFCand, const l1t::TkPrimaryVertexRef& primaryVertex); +void printPFCand(ostream& os, const l1t::PFCandidate& l1PFCand, const l1t::VertexWordRef& primaryVertex); void printPFCand(ostream& os, const l1t::PFCandidate& l1PFCand, float primaryVertexZ); #endif diff --git a/DataFormats/L1TParticleFlow/interface/PFCandidate.h b/DataFormats/L1TParticleFlow/interface/PFCandidate.h index 93cb7d4aff9ff..c6d52246a6fa5 100644 --- a/DataFormats/L1TParticleFlow/interface/PFCandidate.h +++ b/DataFormats/L1TParticleFlow/interface/PFCandidate.h @@ -3,15 +3,16 @@ #include #include "DataFormats/L1Trigger/interface/L1Candidate.h" -#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" #include "DataFormats/L1TParticleFlow/interface/PFCluster.h" #include "DataFormats/L1TParticleFlow/interface/PFTrack.h" +#include "DataFormats/L1Trigger/interface/RegionalOutput.h" namespace l1t { class PFCandidate : public L1Candidate { public: - typedef edm::Ptr MuonRef; + typedef l1t::SAMuonRef MuonRef; enum ParticleType { ChargedHadron = 0, Electron = 1, NeutralHadron = 2, Photon = 3, Muon = 4 }; PFCandidate() {} @@ -45,11 +46,35 @@ namespace l1t { /// PUPPI weight (-1 if not available) float puppiWeight() const { return puppiWeight_; } + void setZ0(float z0) { setVertex(reco::Particle::Point(0, 0, z0)); } + void setDxy(float dxy) { dxy_ = dxy; } + + float z0() const { return vz(); } + float dxy() const { return dxy_; } + + int16_t hwZ0() const { return hwZ0_; } + int16_t hwDxy() const { return hwDxy_; } + uint16_t hwTkQuality() const { return hwTkQuality_; } + uint16_t hwPuppiWeight() const { return hwPuppiWeight_; } + uint16_t hwEmID() const { return hwEmID_; } + uint64_t encodedPuppi64() const { return encodedPuppi64_; } + + void setHwZ0(int16_t hwZ0) { hwZ0_ = hwZ0; } + void setHwDxy(int16_t hwDxy) { hwDxy_ = hwDxy; } + void setHwTkQuality(uint16_t hwTkQuality) { hwTkQuality_ = hwTkQuality; } + void setHwPuppiWeight(uint16_t hwPuppiWeight) { hwPuppiWeight_ = hwPuppiWeight; } + void setHwEmID(uint16_t hwEmID) { hwEmID_ = hwEmID; } + void setEncodedPuppi64(uint64_t encodedPuppi64) { encodedPuppi64_ = encodedPuppi64; } + private: PFClusterRef clusterRef_; PFTrackRef trackRef_; MuonRef muonRef_; - float puppiWeight_; + float dxy_, puppiWeight_; + + int16_t hwZ0_, hwDxy_; + uint16_t hwTkQuality_, hwPuppiWeight_, hwEmID_; + uint64_t encodedPuppi64_; void setPdgIdFromParticleType(int charge, ParticleType kind); }; @@ -57,5 +82,6 @@ namespace l1t { typedef std::vector PFCandidateCollection; typedef edm::Ref PFCandidateRef; typedef edm::RefVector PFCandidateRefVector; + typedef l1t::RegionalOutput PFCandidateRegionalOutput; } // namespace l1t #endif diff --git a/DataFormats/L1TParticleFlow/interface/PFCluster.h b/DataFormats/L1TParticleFlow/interface/PFCluster.h index ba2f5a991e524..1851746b51d19 100644 --- a/DataFormats/L1TParticleFlow/interface/PFCluster.h +++ b/DataFormats/L1TParticleFlow/interface/PFCluster.h @@ -58,6 +58,7 @@ namespace l1t { bool isEM() const { return hwQual(); } void setIsEM(bool isEM) { setHwQual(isEM); } + unsigned int hwEmID() const { return hwQual(); } float egVsPionMVAOut() const { return egVsPionMVAOut_; } void setEgVsPionMVAOut(float egVsPionMVAOut) { egVsPionMVAOut_ = egVsPionMVAOut; } diff --git a/DataFormats/L1TParticleFlow/interface/PFJet.h b/DataFormats/L1TParticleFlow/interface/PFJet.h index b1aac33e439d2..301fd1a36ff76 100644 --- a/DataFormats/L1TParticleFlow/interface/PFJet.h +++ b/DataFormats/L1TParticleFlow/interface/PFJet.h @@ -36,9 +36,14 @@ namespace l1t { using reco::LeafCandidate::daughter; // avoid hiding the base 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_; } + void setEncodedJet(std::array jet) { encodedJet_ = jet; } + private: float rawPt_; Constituents constituents_; + std::array encodedJet_ = {{0, 0}}; }; typedef std::vector PFJetCollection; diff --git a/DataFormats/L1TParticleFlow/interface/PFTau.h b/DataFormats/L1TParticleFlow/interface/PFTau.h index 3899d703bef95..92aabc0977ca6 100644 --- a/DataFormats/L1TParticleFlow/interface/PFTau.h +++ b/DataFormats/L1TParticleFlow/interface/PFTau.h @@ -17,6 +17,8 @@ namespace l1t { static constexpr float PFTAU_PF_LOOSE_CUT = 10.0; static constexpr float PFTAU_PF_TIGHT_CUT = 5.0; + static constexpr float PTSCALING_MASSCUT = 40.0; + static constexpr double PFTAU_NN_PT_CUTOFF = 100.0; class PFTau : public L1Candidate { @@ -41,21 +43,40 @@ namespace l1t { float chargedIso() const { return iso_; } float fullIso() const { return fullIso_; } int id() const { return id_; } + + void setZ0(float z0) { setVertex(reco::Particle::Point(0, 0, z0)); } + void setDxy(float dxy) { dxy_ = dxy; } + + float z0() const { return vz(); } + float dxy() const { return dxy_; } + + bool passMass() const { return (mass() < 2 + pt() / PTSCALING_MASSCUT); } bool passLooseNN() const { return iso_ * (PFTAU_NN_OFFSET + PFTAU_NN_SLOPE * (min(pt(), PFTAU_NN_PT_CUTOFF))) * PFTAU_NN_OVERALL_SCALE > PFTAU_NN_LOOSE_CUT; } + bool passLooseNNMass() const { + if (!passMass()) + return false; + return passLooseNN(); + } bool passLoosePF() const { return fullIso_ < PFTAU_PF_LOOSE_CUT; } bool passTightNN() const { return iso_ * (PFTAU_NN_OFFSET + PFTAU_NN_SLOPE * (min(pt(), PFTAU_NN_PT_CUTOFF))) * PFTAU_NN_OVERALL_SCALE > PFTAU_NN_TIGHT_CUT; } + bool passTightNNMass() const { + if (!passMass()) + return false; + return passTightNN(); + } bool passTightPF() const { return fullIso_ < PFTAU_PF_TIGHT_CUT; } private: float iso_; float fullIso_; int id_; + float dxy_; }; typedef std::vector PFTauCollection; diff --git a/DataFormats/L1TParticleFlow/interface/PFTrack.h b/DataFormats/L1TParticleFlow/interface/PFTrack.h index 8c226e39696c4..50cb946063d6e 100644 --- a/DataFormats/L1TParticleFlow/interface/PFTrack.h +++ b/DataFormats/L1TParticleFlow/interface/PFTrack.h @@ -36,7 +36,8 @@ namespace l1t { trkPtError_(trkPtError), caloPtError_(caloPtError), isMuon_(isMuon), - nPar_(nPar) { + nPar_(nPar), + trackWord_(*tkPtr) { setCharge(charge); setVertex(vtx); } @@ -72,6 +73,9 @@ namespace l1t { float normalizedChi2() const { return track()->chi2Red(); } float chi2() const { return track()->chi2(); } + const TTTrack_TrackWord& trackWord() const { return trackWord_; } + TTTrack_TrackWord& trackWord() { return trackWord_; } + private: TrackRef trackRef_; float caloEta_, caloPhi_; @@ -79,6 +83,7 @@ namespace l1t { float caloPtError_; bool isMuon_; unsigned int nPar_; + TTTrack_TrackWord trackWord_; }; typedef std::vector PFTrackCollection; diff --git a/DataFormats/L1TParticleFlow/interface/bit_encoding.h b/DataFormats/L1TParticleFlow/interface/bit_encoding.h new file mode 100644 index 0000000000000..9aa7446e75962 --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/bit_encoding.h @@ -0,0 +1,61 @@ +#ifndef DATAFORMATS_L1TPARTICLEFLOW_ENCODING_H +#define DATAFORMATS_L1TPARTICLEFLOW_ENCODING_H + +#include +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" + +template +inline void pack_into_bits(U& u, unsigned int& start, const T& data) { + const unsigned int w = T::width; + u(start + w - 1, start) = data(w - 1, 0); + start += w; +} + +template +inline void unpack_from_bits(const U& u, unsigned int& start, T& data) { + const unsigned int w = T::width; + data(w - 1, 0) = u(start + w - 1, start); + start += w; +} + +template +inline void pack_bool_into_bits(U& u, unsigned int& start, bool data) { + u[start++] = data; +} + +template +inline void unpack_bool_from_bits(const U& u, unsigned int& start, bool& data) { + data = u[start++]; +} + +template +inline void l1pf_pattern_pack(const T objs[N], ap_uint data[]) { +#ifdef __SYNTHESIS__ +#pragma HLS inline +#pragma HLS inline region recursive +#endif + assert(T::BITWIDTH <= NB); + for (unsigned int i = 0; i < N; ++i) { +#ifdef __SYNTHESIS__ +#pragma HLS unroll +#endif + data[i + OFFS] = objs[i].pack(); + } +} + +template +inline void l1pf_pattern_unpack(const ap_uint data[], T objs[N]) { +#ifdef __SYNTHESIS__ +#pragma HLS inline +#pragma HLS inline region recursive +#endif + assert(T::BITWIDTH <= NB); + for (unsigned int i = 0; i < N; ++i) { +#ifdef __SYNTHESIS__ +#pragma HLS unroll +#endif + objs[i] = T::unpack(data[i + OFFS]); + } +} + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/datatypes.h b/DataFormats/L1TParticleFlow/interface/datatypes.h new file mode 100644 index 0000000000000..f56e7b36c2495 --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/datatypes.h @@ -0,0 +1,212 @@ +#ifndef DataFormats_L1TParticleFlow_datatypes_h +#define DataFormats_L1TParticleFlow_datatypes_h + +#if (!defined(__CLANG__)) && defined(__GNUC__) && defined(CMSSW_GIT_HASH) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wint-in-bool-context" +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif +#include +#if (!defined(__CLANG__)) && defined(__GNUC__) && defined(CMSSW_GIT_HASH) +#pragma GCC diagnostic pop +#endif + +#include +#include +#include + +namespace l1ct { + + typedef ap_ufixed<14, 12, AP_TRN, AP_SAT> pt_t; + typedef ap_ufixed<10, 8, AP_TRN, AP_SAT> pt10_t; + typedef ap_fixed<16, 14, AP_TRN, AP_SAT> dpt_t; + typedef ap_ufixed<28, 24, AP_TRN, AP_SAT> pt2_t; + typedef ap_int<10> eta_t; + typedef ap_int<10> phi_t; + typedef ap_int<6> tkdeta_t; + typedef ap_uint<7> tkdphi_t; + typedef ap_int<12> glbeta_t; + typedef ap_int<11> glbphi_t; + typedef ap_int<5> vtx_t; + typedef ap_int<10> z0_t; // 40cm / 0.1 + typedef ap_int<8> dxy_t; // tbd + typedef ap_uint<3> tkquality_t; // tbd + typedef ap_uint<9> puppiWgt_t; // 256 = 1.0 + typedef ap_uint<6> emid_t; + typedef ap_uint<14> tk2em_dr_t; + typedef ap_uint<14> tk2calo_dr_t; + typedef ap_uint<10> em2calo_dr_t; + typedef ap_uint<13> tk2calo_dq_t; + typedef ap_uint<4> egquality_t; + // FIXME: adjust range 10-11bits -> 1/4 - 1/2TeV is probably more than enough for all reasonable use cases + typedef ap_ufixed<11, 9, AP_TRN, AP_SAT> iso_t; + + struct ParticleID { + ap_uint<3> bits; + enum PID { + NONE = 0, + HADZERO = 0, + PHOTON = 1, + HADMINUS = 2, + HADPLUS = 3, + ELEMINUS = 4, + ELEPLUS = 5, + MUMINUS = 6, + MUPLUS = 7 + }; + enum PTYPE { HAD = 0, EM = 1, MU = 2 }; + + ParticleID(PID val = NONE) : bits(val) {} + ParticleID &operator=(PID val) { + bits = val; + return *this; + } + + int rawId() const { return bits.to_int(); } + bool isPhoton() const { +#ifndef __SYNTHESIS__ + assert(neutral()); +#endif + return bits[0]; + } + bool isMuon() const { return bits[2] && bits[1]; } + bool isElectron() const { return bits[2] && !bits[1]; } + bool isChargedHadron() const { return !bits[2] && bits[1]; } + bool charge() const { +#ifndef __SYNTHESIS__ + assert(charged()); +#endif + return bits[0]; /* 1 if positive, 0 if negative */ + } + + bool chargeOrNull() const { // doesn't throw on null id + return bits[0]; + } + bool charged() const { return bits[1] || bits[2]; }; + bool neutral() const { return !charged(); } + int intCharge() const { return charged() ? (charge() ? +1 : -1) : 0; } + + void clear() { bits = 0; } + + static ParticleID mkChHad(bool charge) { return ParticleID(charge ? HADPLUS : HADMINUS); } + static ParticleID mkElectron(bool charge) { return ParticleID(charge ? ELEPLUS : ELEMINUS); } + static ParticleID mkMuon(bool charge) { return ParticleID(charge ? MUPLUS : MUMINUS); } + + inline bool operator==(const ParticleID &other) const { return bits == other.bits; } + + inline int pdgId() const { + switch (bits.to_int()) { + case HADZERO: + return 130; + case PHOTON: + return 22; + case HADMINUS: + return -211; + case HADPLUS: + return +211; + case ELEMINUS: + return +11; + case ELEPLUS: + return -11; + case MUMINUS: + return +13; + case MUPLUS: + return -13; + } + return 0; + } + + inline int oldId() const { + //{ PID_Charged=0, PID_Neutral=1, PID_Photon=2, PID_Electron=3, PID_Muon=4 }; + switch (bits.to_int()) { + case HADZERO: + return 1; + case PHOTON: + return 2; + case HADMINUS: + return 0; + case HADPLUS: + return 0; + case ELEMINUS: + return 3; + case ELEPLUS: + return 3; + case MUMINUS: + return 4; + case MUPLUS: + return 4; + } + return -1; + } + }; + + namespace Scales { + constexpr int INTPHI_PI = 720; + constexpr int INTPHI_TWOPI = 2 * INTPHI_PI; + constexpr float INTPT_LSB = 0.25; + constexpr float ETAPHI_LSB = M_PI / INTPHI_PI; + constexpr float Z0_LSB = 0.05; + constexpr float DXY_LSB = 0.05; + constexpr float PUPPIW_LSB = 1.0 / 256; + inline float floatPt(pt_t pt) { return pt.to_float(); } + inline float floatPt(dpt_t pt) { return pt.to_float(); } + inline float floatPt(pt2_t pt2) { return pt2.to_float(); } + inline int intPt(pt_t pt) { return (ap_ufixed<16, 14>(pt) << 2).to_int(); } + inline int intPt(dpt_t pt) { return (ap_fixed<18, 16>(pt) << 2).to_int(); } + inline float floatEta(eta_t eta) { return eta.to_float() * ETAPHI_LSB; } + inline float floatPhi(phi_t phi) { return phi.to_float() * ETAPHI_LSB; } + inline float floatEta(tkdeta_t eta) { return eta.to_float() * ETAPHI_LSB; } + inline float floatPhi(tkdphi_t phi) { return phi.to_float() * ETAPHI_LSB; } + inline float floatEta(glbeta_t eta) { return eta.to_float() * ETAPHI_LSB; } + inline float floatPhi(glbphi_t phi) { return phi.to_float() * ETAPHI_LSB; } + inline float floatZ0(z0_t z0) { return z0.to_float() * Z0_LSB; } + inline float floatDxy(dxy_t dxy) { return dxy.to_float() * DXY_LSB; } + inline float floatPuppiW(puppiWgt_t puppiw) { return puppiw.to_float() * PUPPIW_LSB; } + inline float floatIso(iso_t iso) { return iso.to_float(); } + + inline pt_t makePt(int pt) { return ap_ufixed<16, 14>(pt) >> 2; } + inline dpt_t makeDPt(int dpt) { return ap_fixed<18, 16>(dpt) >> 2; } + inline pt_t makePtFromFloat(float pt) { return pt_t(0.25 * round(pt * 4)); } + inline dpt_t makeDPtFromFloat(float dpt) { return dpt_t(dpt); } + inline z0_t makeZ0(float z0) { return z0_t(round(z0 / Z0_LSB)); } + + inline ap_uint ptToInt(pt_t pt) { + // note: this can be synthethized, e.g. when pT is used as intex in a LUT + ap_uint ret = 0; + ret(pt_t::width - 1, 0) = pt(pt_t::width - 1, 0); + return ret; + } + + inline ap_int ptToInt(dpt_t pt) { + // note: this can be synthethized, e.g. when pT is used as intex in a LUT + ap_uint ret = 0; + ret(dpt_t::width - 1, 0) = pt(dpt_t::width - 1, 0); + return ret; + } + + inline phi_t makePhi(float phi) { return round(phi / ETAPHI_LSB); } + inline eta_t makeEta(float eta) { return round(eta / ETAPHI_LSB); } + inline glbeta_t makeGlbEta(float eta) { return round(eta / ETAPHI_LSB); } + inline glbeta_t makeGlbEtaRoundEven(float eta) { return 2 * std::round(eta / ETAPHI_LSB / 2); } + + inline glbphi_t makeGlbPhi(float phi) { return round(phi / ETAPHI_LSB); } + inline iso_t makeIso(float iso) { return iso_t(0.25 * round(iso * 4)); } + + inline int makeDR2FromFloatDR(float dr) { return ceil(dr * dr / ETAPHI_LSB / ETAPHI_LSB); } + + inline float maxAbsEta() { return ((1 << (eta_t::width - 1)) - 1) * ETAPHI_LSB; } + inline float maxAbsPhi() { return ((1 << (phi_t::width - 1)) - 1) * ETAPHI_LSB; } + inline float maxAbsGlbEta() { return ((1 << (glbeta_t::width - 1)) - 1) * ETAPHI_LSB; } + inline float maxAbsGlbPhi() { return ((1 << (glbphi_t::width - 1)) - 1) * ETAPHI_LSB; } + }; // namespace Scales + + inline int dr2_int(eta_t eta1, phi_t phi1, eta_t eta2, phi_t phi2) { + ap_int deta = (eta1 - eta2); + ap_int dphi = (phi1 - phi2); + return deta * deta + dphi * dphi; + } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/egamma.h b/DataFormats/L1TParticleFlow/interface/egamma.h new file mode 100644 index 0000000000000..457b1700d1021 --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/egamma.h @@ -0,0 +1,173 @@ +#ifndef DataFormats_L1TParticleFlow_egamma_h +#define DataFormats_L1TParticleFlow_egamma_h + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/gt_datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/bit_encoding.h" + +namespace l1ct { + + struct EGIsoObj { + pt_t hwPt; + glbeta_t hwEta; // at calo face + glbphi_t hwPhi; + egquality_t hwQual; + iso_t hwIso; + + int intPt() const { return Scales::intPt(hwPt); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + int intQual() const { return hwQual.to_int(); } + int intIso() const { return hwIso.to_int(); } + + float floatPt() const { return Scales::floatPt(hwPt); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + float floatIso() const { return Scales::floatIso(hwIso); } + + inline bool operator==(const EGIsoObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwQual == other.hwQual && + hwIso == other.hwIso; + } + + inline bool operator>(const EGIsoObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const EGIsoObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwQual = 0; + hwIso = 0; + } + + static const int BITWIDTH = pt_t::width + glbeta_t::width + glbphi_t::width + egquality_t::width + iso_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwQual); + pack_into_bits(ret, start, hwIso); + return ret; + } + inline static EGIsoObj unpack(const ap_uint &src) { + EGIsoObj ret; + ret.initFromBits(src); + return ret; + } + + inline void initFromBits(const ap_uint &src) { + unsigned int start = 0; + unpack_from_bits(src, start, hwPt); + unpack_from_bits(src, start, hwEta); + unpack_from_bits(src, start, hwPhi); + unpack_from_bits(src, start, hwQual); + unpack_from_bits(src, start, hwIso); + } + + l1gt::Photon toGT() const { + l1gt::Photon pho; + pho.valid = hwPt != 0; + pho.v3.pt = CTtoGT_pt(hwPt); + pho.v3.phi = CTtoGT_phi(hwPhi); + pho.v3.eta = CTtoGT_eta(hwEta); + pho.quality = hwQual; + pho.isolation = hwIso; + return pho; + } + }; + + inline void clear(EGIsoObj &c) { c.clear(); } + + struct EGIsoEleObj : public EGIsoObj { + // WARNING: for whatever reason, maybe connected with datamember alignment, + // in 2019.2 synthesis fails if DEta & DPhi are put before Z0 & Dxy + z0_t hwZ0; + tkdeta_t hwDEta; // relative to the region center, at calo + tkdphi_t hwDPhi; // relative to the region center, at calo + bool hwCharge; + + phi_t hwVtxPhi() const { return hwCharge ? hwPhi + hwDPhi : hwPhi - hwDPhi; } + eta_t hwVtxEta() const { return hwEta + hwDEta; } + + inline bool operator==(const EGIsoEleObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwQual == other.hwQual && + hwIso == other.hwIso && hwDEta == other.hwDEta && hwDPhi == other.hwDPhi && hwZ0 == other.hwZ0 && + hwCharge == other.hwCharge; + } + + inline bool operator>(const EGIsoEleObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const EGIsoEleObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwQual = 0; + hwIso = 0; + hwDEta = 0; + hwDPhi = 0; + hwZ0 = 0; + hwCharge = false; + } + + int intCharge() const { return hwCharge ? +1 : -1; } + float floatDEta() const { return Scales::floatEta(hwDEta); } + float floatDPhi() const { return Scales::floatPhi(hwDPhi); } + float floatVtxEta() const { return Scales::floatEta(hwVtxEta()); } + float floatVtxPhi() const { return Scales::floatPhi(hwVtxPhi()); } + float floatZ0() const { return Scales::floatZ0(hwZ0); } + + static const int BITWIDTH = EGIsoObj::BITWIDTH + tkdeta_t::width + tkdphi_t::width + z0_t::width + 1; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwQual); + pack_into_bits(ret, start, hwIso); + pack_into_bits(ret, start, hwDEta); + pack_into_bits(ret, start, hwDPhi); + pack_into_bits(ret, start, hwZ0); + pack_bool_into_bits(ret, start, hwCharge); + return ret; + } + inline static EGIsoEleObj unpack(const ap_uint &src) { + EGIsoEleObj ret; + ret.initFromBits(src); + return ret; + } + + inline void initFromBits(const ap_uint &src) { + unsigned int start = 0; + unpack_from_bits(src, start, hwPt); + unpack_from_bits(src, start, hwEta); + unpack_from_bits(src, start, hwPhi); + unpack_from_bits(src, start, hwQual); + unpack_from_bits(src, start, hwIso); + unpack_from_bits(src, start, hwDEta); + unpack_from_bits(src, start, hwDPhi); + unpack_from_bits(src, start, hwZ0); + unpack_bool_from_bits(src, start, hwCharge); + } + + l1gt::Electron toGT() const { + l1gt::Electron ele; + ele.valid = hwPt != 0; + ele.v3.pt = CTtoGT_pt(hwPt); + ele.v3.phi = CTtoGT_phi(hwPhi); + ele.v3.eta = CTtoGT_eta(hwEta); + ele.quality = hwQual; + ele.charge = hwCharge; + ele.z0 = hwZ0; + ele.isolation = hwIso; + return ele; + } + }; + + inline void clear(EGIsoEleObj &c) { c.clear(); } +} // namespace l1ct +#endif diff --git a/DataFormats/L1TParticleFlow/interface/emulator_io.h b/DataFormats/L1TParticleFlow/interface/emulator_io.h new file mode 100644 index 0000000000000..5bcd6e5a416bf --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/emulator_io.h @@ -0,0 +1,101 @@ +#ifndef FIRMWARE_utils_emulator_io_h +#define FIRMWARE_utils_emulator_io_h + +#include +#include +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" + +namespace l1ct { + + template + inline bool writeVar(const T &src, std::fstream &to) { + to.write(reinterpret_cast(&src), sizeof(T)); + return to.good(); + } + + template + inline bool readVar(std::fstream &from, T &to) { + from.read(reinterpret_cast(&to), sizeof(T)); + return from.good(); + } + + template + bool writeAP(const T &src, std::fstream &to) { + for (unsigned int i = 0, n = T::width; i < n; i += 32) { + ap_uint<32> word = src(std::min(i + 31, n - 1), i); + uint32_t w32 = word.to_uint(); + if (!writeVar(w32, to)) + return false; + } + return true; + } + + template + bool readAP(std::fstream &from, T &to) { + uint32_t w32; + for (unsigned int i = 0, n = T::width; i < n; i += 32) { + if (!readVar(from, w32)) + return false; + ap_uint<32> word = w32; + to(std::min(i + 31, n - 1), i) = word(std::min(31u, n - i - 1), 0); + } + return true; + } + + template + bool writeObj(const T &obj, std::fstream &to) { + return writeAP(obj.pack(), to); + } + + template + bool readObj(std::fstream &from, T &obj) { + ap_uint packed; + if (!readAP(from, packed)) + return false; + obj = T::unpack(packed); + return true; + } + + template + bool writeMany(const std::vector &objs, std::fstream &to) { + uint32_t number = objs.size(); + writeVar(number, to); + for (uint32_t i = 0; i < number; ++i) { + objs[i].write(to); + } + return to.good(); + } + + template + bool writeMany(const std::vector> &objs, std::fstream &to) { + uint32_t number = objs.size(); + writeVar(number, to); + for (uint32_t i = 0; i < number; ++i) { + writeAP(objs[i], to); + } + return to.good(); + } + + template + bool readMany(std::fstream &from, std::vector &objs) { + uint32_t number = 0; + readVar(from, number); + objs.resize(number); + for (uint32_t i = 0; i < number; ++i) + objs[i].read(from); + return from.good(); + } + + template + bool readMany(std::fstream &from, std::vector> &objs) { + uint32_t number = 0; + readVar(from, number); + objs.resize(number); + for (uint32_t i = 0; i < number; ++i) + readAP(from, objs[i]); + return from.good(); + } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/gt_datatypes.h b/DataFormats/L1TParticleFlow/interface/gt_datatypes.h new file mode 100644 index 0000000000000..12cec406492f7 --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/gt_datatypes.h @@ -0,0 +1,276 @@ +#ifndef DataFormats_L1TParticleFlow_gt_datatypes_h +#define DataFormats_L1TParticleFlow_gt_datatypes_h + +#if (!defined(__CLANG__)) && defined(__GNUC__) && defined(CMSSW_GIT_HASH) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wint-in-bool-context" +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif +#include +#if (!defined(__CLANG__)) && defined(__GNUC__) && defined(CMSSW_GIT_HASH) +#pragma GCC diagnostic pop +#endif + +#include "DataFormats/L1TParticleFlow/interface/bit_encoding.h" +#include +#include + +namespace l1gt { + // Using rounding & saturation modes to avoid unnecessary rounding errors + // Don't saturate phi since -Ï€ to +Ï€ periodicity is handled by numerical wrap around + // Rounding and saturation settings are lost when sending the data over the link + // Unless the receiving end uses the same data types + + // Common fields + typedef ap_ufixed<16, 11, AP_RND_CONV, AP_SAT> pt_t; + typedef ap_fixed<13, 13, AP_RND_CONV> phi_t; + typedef ap_fixed<14, 14, AP_RND_CONV, AP_SAT> eta_t; + typedef ap_fixed<10, 9, AP_RND_CONV, AP_SAT> z0_t; + typedef ap_uint<1> valid_t; + + // E/gamma fields + typedef ap_fixed<11, 9> iso_t; + typedef ap_uint<4> egquality_t; + + // tau fields + typedef ap_ufixed<10, 8> tauseed_pt_t; + + namespace Scales { + const int INTPHI_PI = 1 << (phi_t::width - 1); + const float INTPT_LSB = 1.0 / (1 << (pt_t::width - pt_t::iwidth)); + const int INTPHI_TWOPI = 2 * INTPHI_PI; + constexpr float ETAPHI_LSB = M_PI / INTPHI_PI; + inline float floatPt(pt_t pt) { return pt.to_float(); } + inline float floatEta(eta_t eta) { return eta.to_float() * ETAPHI_LSB; } + inline float floatPhi(phi_t phi) { return phi.to_float() * ETAPHI_LSB; } + } // namespace Scales + + struct ThreeVector { + pt_t pt; + phi_t phi; + eta_t eta; + + inline bool operator==(const ThreeVector &other) const { + return pt == other.pt && phi == other.phi && eta == other.eta; + } + + static const int BITWIDTH = pt_t::width + phi_t::width + eta_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, pt); + pack_into_bits(ret, start, phi); + pack_into_bits(ret, start, eta); + return ret; + } + + inline static ThreeVector unpack_ap(const ap_uint &src) { + ThreeVector ret; + ret.initFromBits(src); + return ret; + } + + inline void initFromBits(const ap_uint &src) { + unsigned int start = 0; + unpack_from_bits(src, start, pt); + unpack_from_bits(src, start, phi); + unpack_from_bits(src, start, eta); + } + }; + + struct Jet { + valid_t valid; + ThreeVector v3; + z0_t z0; + + inline bool operator==(const Jet &other) const { return valid == other.valid && z0 == other.z0 && v3 == other.v3; } + + static const int BITWIDTH = 128; + inline ap_uint pack_ap() const { + ap_uint ret = 0; + unsigned int start = 0; + pack_into_bits(ret, start, valid); + pack_into_bits(ret, start, v3.pack()); + pack_into_bits(ret, start, z0); + return ret; + } + + inline std::array pack() const { + std::array packed; + ap_uint bits = this->pack_ap(); + packed[0] = bits(63, 0); + packed[1] = bits(127, 64); + return packed; + } + + inline static Jet unpack_ap(const ap_uint &src) { + Jet ret; + ret.initFromBits(src); + return ret; + } + + inline void initFromBits(const ap_uint &src) { + unsigned int start = 0; + unpack_from_bits(src, start, valid); + unpack_from_bits(src, start, v3.pt); + unpack_from_bits(src, start, v3.phi); + unpack_from_bits(src, start, v3.eta); + unpack_from_bits(src, start, z0); + } + + inline static Jet unpack(const std::array &src) { + ap_uint bits; + bits(63, 0) = src[0]; + bits(127, 64) = src[1]; + return unpack_ap(bits); + } + + inline static Jet unpack(long long unsigned int &src) { + // unpack from single 64b int + ap_uint bits = src; + return unpack_ap(bits); + } + + }; // struct Jet + + struct Sum { + valid_t valid; + pt_t vector_pt; + phi_t vector_phi; + pt_t scalar_pt; + + inline bool operator==(const Sum &other) const { + return valid == other.valid && vector_pt == other.vector_pt && vector_phi == other.vector_phi && + scalar_pt == other.scalar_pt; + } + + inline void clear() { + valid = 0; + vector_pt = 0; + vector_phi = 0; + scalar_pt = 0; + } + + static const int BITWIDTH = 64; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, valid); + pack_into_bits(ret, start, vector_pt); + pack_into_bits(ret, start, vector_phi); + pack_into_bits(ret, start, scalar_pt); + return ret; + } + + inline static Sum unpack_ap(const ap_uint &src) { + Sum ret; + ret.initFromBits(src); + return ret; + } + + inline void initFromBits(const ap_uint &src) { + unsigned int start = 0; + unpack_from_bits(src, start, valid); + unpack_from_bits(src, start, vector_pt); + unpack_from_bits(src, start, vector_phi); + unpack_from_bits(src, start, scalar_pt); + } + }; // struct Sum + + struct Tau { + valid_t valid; + ThreeVector v3; + tauseed_pt_t seed_pt; + z0_t seed_z0; + ap_uint<1> charge; + ap_uint<2> type; + iso_t isolation; + ap_uint<2> id0; + ap_uint<2> id1; + + static const int BITWIDTH = 128; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, valid); + pack_into_bits(ret, start, v3.pack()); + pack_into_bits(ret, start, seed_pt); + pack_into_bits(ret, start, seed_z0); + pack_into_bits(ret, start, charge); + pack_into_bits(ret, start, type); + pack_into_bits(ret, start, isolation); + pack_into_bits(ret, start, id0); + pack_into_bits(ret, start, id1); + return ret; + } + }; // struct Tau + + struct Electron { + valid_t valid; + ThreeVector v3; + egquality_t quality; + ap_uint<1> charge; + z0_t z0; + iso_t isolation; + + static const int BITWIDTH = 96; + inline ap_uint pack() const { + ap_uint ret(0); + unsigned int start = 0; + pack_into_bits(ret, start, valid); + pack_into_bits(ret, start, v3.pack()); + pack_into_bits(ret, start, quality); + pack_into_bits(ret, start, isolation); + pack_into_bits(ret, start, charge); + pack_into_bits(ret, start, z0); + return ret; + } + }; + + struct Photon { + valid_t valid; + ThreeVector v3; + egquality_t quality; + iso_t isolation; + + inline ap_uint<96> pack() const { + ap_uint<96> ret(0); + unsigned int start = 0; + pack_into_bits(ret, start, valid); + pack_into_bits(ret, start, v3.pack()); + pack_into_bits(ret, start, quality); + pack_into_bits(ret, start, isolation); + return ret; + } + }; + +} // namespace l1gt + +namespace l1ct { + + typedef ap_fixed<18, 5, AP_RND_CONV, AP_SAT> etaphi_sf_t; // use a DSP input width + + namespace Scales { + const etaphi_sf_t ETAPHI_CTtoGT_SCALE = (Scales::ETAPHI_LSB / l1gt::Scales::ETAPHI_LSB); + } + + inline l1gt::pt_t CTtoGT_pt(pt_t x) { + // the CT & GT pT are both ap_fixed with different power-of-2 LSBs + // -> conversion is just a cast + return (l1gt::pt_t)x; + } + + inline l1gt::eta_t CTtoGT_eta(glbeta_t x) { + // rescale the eta into the GT coordinates + return x * Scales::ETAPHI_CTtoGT_SCALE; + } + + inline l1gt::phi_t CTtoGT_phi(glbphi_t x) { + // rescale the phi into the GT coordinates + return x * Scales::ETAPHI_CTtoGT_SCALE; + } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/jets.h b/DataFormats/L1TParticleFlow/interface/jets.h new file mode 100644 index 0000000000000..277502b2d0147 --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/jets.h @@ -0,0 +1,95 @@ +#ifndef DataFormats_L1TParticleFlow_jets_h +#define DataFormats_L1TParticleFlow_jets_h + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/gt_datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/bit_encoding.h" +#include +#include + +namespace l1ct { + + struct Jet { + pt_t hwPt; + glbeta_t hwEta; + glbphi_t hwPhi; + + inline bool operator==(const Jet &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi; + } + + inline bool operator>(const Jet &other) const { return hwPt > other.hwPt; } + inline bool operator<(const Jet &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + } + + int intPt() const { return Scales::intPt(hwPt); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + + static const int BITWIDTH = pt_t::width + glbeta_t::width + glbphi_t::width; + inline ap_uint pack_ap() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + return ret; + } + + inline std::array pack() const { + std::array packed; + ap_uint bits = this->pack_ap(); + packed[0] = bits; + //packed[1] = bits[slice]; // for when there are more than 64 bits in the word + return packed; + } + + inline static Jet unpack_ap(const ap_uint &src) { + Jet ret; + ret.initFromBits(src); + return ret; + } + + inline void initFromBits(const ap_uint &src) { + unsigned int start = 0; + unpack_from_bits(src, start, hwPt); + unpack_from_bits(src, start, hwEta); + unpack_from_bits(src, start, hwPhi); + } + + inline static Jet unpack(const std::array &src) { + // just one set while the word has fewer than 64 bits + ap_uint bits = src[0]; + return unpack_ap(bits); + } + + inline static Jet unpack(long long unsigned int &src) { + // unpack from single 64b int + ap_uint bits = src; + return unpack_ap(bits); + } + + l1gt::Jet toGT() const { + l1gt::Jet j; + j.valid = hwPt != 0; + j.v3.pt = CTtoGT_pt(hwPt); + j.v3.phi = CTtoGT_phi(hwPhi); + j.v3.eta = CTtoGT_eta(hwEta); + j.z0 = 0; + return j; + } + }; + + inline void clear(Jet &c) { c.clear(); } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/layer1_emulator.h b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h new file mode 100644 index 0000000000000..0fcaa3580f7af --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/layer1_emulator.h @@ -0,0 +1,378 @@ +#ifndef DataFormats_L1TParticleFlow_layer1_emulator_h +#define DataFormats_L1TParticleFlow_layer1_emulator_h + +#include +#include +#include "DataFormats/L1TParticleFlow/interface/layer1_objs.h" +#include "DataFormats/L1TParticleFlow/interface/pf.h" +#include "DataFormats/L1TParticleFlow/interface/puppi.h" +#include "DataFormats/L1TParticleFlow/interface/egamma.h" +#include "DataFormats/L1TParticleFlow/interface/emulator_io.h" + +namespace l1t { + class PFTrack; + class PFCluster; + class PFCandidate; + class SAMuon; +} // namespace l1t + +namespace l1ct { + + struct HadCaloObjEmu : public HadCaloObj { + const l1t::PFCluster *src; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + HadCaloObj::clear(); + src = nullptr; + } + }; + + struct EmCaloObjEmu : public EmCaloObj { + const l1t::PFCluster *src; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + EmCaloObj::clear(); + src = nullptr; + } + }; + + struct TkObjEmu : public TkObj { + uint16_t hwChi2, hwStubs; + float simPt, simCaloEta, simCaloPhi, simVtxEta, simVtxPhi, simZ0, simD0; + const l1t::PFTrack *src; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + TkObj::clear(); + src = nullptr; + hwChi2 = 0; + hwStubs = 0; + simPt = 0; + simCaloEta = 0; + simCaloPhi = 0; + simVtxEta = 0; + simVtxPhi = 0; + simZ0 = 0; + simD0 = 0; + } + }; + + struct MuObjEmu : public MuObj { + const l1t::SAMuon *src; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + MuObj::clear(); + src = nullptr; + } + }; + + struct PFChargedObjEmu : public PFChargedObj { + const l1t::PFCluster *srcCluster; + const l1t::PFTrack *srcTrack; + const l1t::SAMuon *srcMu; + const l1t::PFCandidate *srcCand; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + PFChargedObj::clear(); + srcCluster = nullptr; + srcTrack = nullptr; + srcMu = nullptr; + srcCand = nullptr; + } + }; + + struct PFNeutralObjEmu : public PFNeutralObj { + const l1t::PFCluster *srcCluster; + const l1t::PFCandidate *srcCand; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + PFNeutralObj::clear(); + srcCluster = nullptr; + srcCand = nullptr; + } + }; + + struct PFRegionEmu : public PFRegion { + PFRegionEmu() : PFRegion() {} + PFRegionEmu(float etaCenter, float phicenter); + PFRegionEmu(float etamin, float etamax, float phicenter, float phiwidth, float etaextra, float phiextra); + + // global coordinates + bool contains(float eta, float phi) const; + bool containsHw(glbeta_t glbeta, glbphi_t phi) const; + float localEta(float globalEta) const; + float localPhi(float globalPhi) const; + + bool read(std::fstream &from); + bool write(std::fstream &to) const; + }; + + struct PuppiObjEmu : public PuppiObj { + const l1t::PFCluster *srcCluster; + const l1t::PFTrack *srcTrack; + const l1t::SAMuon *srcMu; + const l1t::PFCandidate *srcCand; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + PuppiObj::clear(); + srcCluster = nullptr; + srcTrack = nullptr; + srcMu = nullptr; + srcCand = nullptr; + } + inline void fill(const PFRegionEmu ®ion, const PFChargedObjEmu &src) { + PuppiObj::fill(region, src); + srcCluster = src.srcCluster; + srcTrack = src.srcTrack; + srcMu = src.srcMu; + srcCand = src.srcCand; + } + inline void fill(const PFRegionEmu ®ion, const PFNeutralObjEmu &src, pt_t puppiPt, puppiWgt_t puppiWgt) { + PuppiObj::fill(region, src, puppiPt, puppiWgt); + srcCluster = src.srcCluster; + srcTrack = nullptr; + srcMu = nullptr; + srcCand = src.srcCand; + } + inline void fill(const PFRegionEmu ®ion, const HadCaloObjEmu &src, pt_t puppiPt, puppiWgt_t puppiWgt) { + PuppiObj::fill(region, src, puppiPt, puppiWgt); + srcCluster = src.src; + srcTrack = nullptr; + srcMu = nullptr; + srcCand = nullptr; + } + }; + + struct EGObjEmu : public EGIsoObj { + const l1t::PFCluster *srcCluster; + void clear() { + srcCluster = nullptr; + EGIsoObj::clear(); + } + }; + + struct EGIsoObjEmu : public EGIsoObj { + const l1t::PFCluster *srcCluster; + // we use an index to the standalone object needed to retrieve a Ref when putting + int sta_idx; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + EGIsoObj::clear(); + srcCluster = nullptr; + sta_idx = -1; + clearIsoVars(); + } + + void clearIsoVars() { + hwIsoVars[0] = 0; + hwIsoVars[1] = 0; + hwIsoVars[2] = 0; + hwIsoVars[3] = 0; + } + + using EGIsoObj::floatIso; + + enum IsoType { TkIso = 0, PfIso = 1, TkIsoPV = 2, PfIsoPV = 3 }; + + 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]; + }; + + struct EGIsoEleObjEmu : public EGIsoEleObj { + const l1t::PFCluster *srcCluster; + const l1t::PFTrack *srcTrack; + // we use an index to the standalone object needed to retrieve a Ref when putting + int sta_idx; + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear() { + EGIsoEleObj::clear(); + srcCluster = nullptr; + srcTrack = nullptr; + sta_idx = -1; + clearIsoVars(); + } + + void clearIsoVars() { + hwIsoVars[0] = 0; + hwIsoVars[1] = 0; + } + + using EGIsoEleObj::floatIso; + + enum IsoType { TkIso = 0, PfIso = 1 }; + + 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]; + }; + + struct PVObjEmu : public PVObj { + bool read(std::fstream &from); + bool write(std::fstream &to) const; + }; + + template + struct DetectorSector { + PFRegionEmu region; + std::vector obj; + DetectorSector() {} + DetectorSector(float etamin, float etamax, float phicenter, float phiwidth, float etaextra = 0, float phiextra = 0) + : region(etamin, etamax, phicenter, phiwidth, etaextra, phiextra) {} + // convenience forwarding of some methods + typedef typename std::vector::const_iterator const_iterator; + typedef typename std::vector::iterator iterator; + inline const T &operator[](unsigned int i) const { return obj[i]; } + inline T &operator[](unsigned int i) { return obj[i]; } + inline const_iterator begin() const { return obj.begin(); } + inline iterator begin() { return obj.begin(); } + inline const_iterator end() const { return obj.end(); } + inline iterator end() { return obj.end(); } + inline unsigned int size() const { return obj.size(); } + inline void resize(unsigned int size) { obj.resize(size); } + inline void clear() { obj.clear(); } + }; + + struct RawInputs { + std::vector>> track; + DetectorSector> muon; // muons are global + std::vector>> hgcalcluster; + + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear(); + }; + + struct RegionizerDecodedInputs { + std::vector> hadcalo; + std::vector> emcalo; + std::vector> track; + DetectorSector muon; // muons are global + + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear(); + }; + + struct PFInputRegion { + PFRegionEmu region; + std::vector hadcalo; + std::vector emcalo; + std::vector track; + std::vector muon; + + PFInputRegion() {} + PFInputRegion(float etamin, float etamax, float phicenter, float phiwidth, float etaextra, float phiextra) + : region(etamin, etamax, phicenter, phiwidth, etaextra, phiextra) {} + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear(); + }; + + struct OutputRegion { + std::vector pfcharged; + std::vector pfphoton; + std::vector pfneutral; + std::vector pfmuon; + std::vector puppi; + std::vector egsta; + std::vector egphoton; + std::vector egelectron; + + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear(); + + // for multiplicities + enum ObjType { + anyType = 0, + chargedType = 1, + neutralType = 2, + electronType = 3, + muonType = 4, + chargedHadronType = 5, + neutralHadronType = 6, + photonType = 7, + nPFTypes = 8, + egisoType = 8, + egisoeleType = 9, + nObjTypes = 10 + }; + static constexpr const char *objTypeName[nObjTypes] = { + "", "Charged", "Neutral", "Electron", "Muon", "ChargedHadron", "NeutralHadron", "Photon", "EGIso", "EGIsoEle"}; + unsigned int nObj(ObjType type, bool puppi) const; + }; + + struct OutputBoard { + float eta; + float phi; + // NOTE: region_index is not written to the dump file + std::vector region_index; + std::vector egphoton; + std::vector egelectron; + + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear(); + }; + + struct Event { + enum { VERSION = 11 }; + uint32_t run, lumi; + uint64_t event; + RawInputs raw; + RegionizerDecodedInputs decoded; + std::vector pfinputs; + std::vector pvs; + std::vector> pvs_emu; + std::vector out; + std::vector board_out; + + Event() : run(0), lumi(0), event(0) {} + + bool read(std::fstream &from); + bool write(std::fstream &to) const; + void clear(); + void init(uint32_t run, uint32_t lumi, uint64_t event); + inline l1ct::PVObjEmu pv(unsigned int ipv = 0) const { + l1ct::PVObjEmu ret; + if (ipv < pvs.size()) + ret = pvs[ipv]; + else + ret.clear(); + return ret; + } + inline ap_uint<64> pv_emu(unsigned int ipv = 0) const { + ap_uint<64> ret = 0; + if (ipv < pvs_emu.size()) + ret = pvs_emu[ipv]; + return ret; + } + }; + + template + void toFirmware(const std::vector &in, unsigned int NMAX, T2 out[/*NMAX*/]) { + unsigned int n = std::min(in.size(), NMAX); + for (unsigned int i = 0; i < n; ++i) + out[i] = in[i]; + for (unsigned int i = n; i < NMAX; ++i) + out[i].clear(); + } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/layer1_objs.h b/DataFormats/L1TParticleFlow/interface/layer1_objs.h new file mode 100644 index 0000000000000..83765fc4b2b10 --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/layer1_objs.h @@ -0,0 +1,320 @@ +#ifndef DataFormats_L1TParticleFlow_layer1_objs_h +#define DataFormats_L1TParticleFlow_layer1_objs_h + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/bit_encoding.h" + +namespace l1ct { + + struct HadCaloObj { + pt_t hwPt; + eta_t hwEta; // relative to the region center, at calo + phi_t hwPhi; // relative to the region center, at calo + pt_t hwEmPt; + emid_t hwEmID; + + inline bool operator==(const HadCaloObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwEmPt == other.hwEmPt && + hwEmID == other.hwEmID; + } + + inline bool operator>(const HadCaloObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const HadCaloObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwEmPt = 0; + hwEmID = 0; + } + + int intPt() const { return Scales::intPt(hwPt); } + int intEmPt() const { return Scales::intPt(hwEmPt); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatEmPt() const { return Scales::floatPt(hwEmPt); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + + bool hwIsEM() const { return hwEmID != 0; } + + static const int BITWIDTH = pt_t::width + eta_t::width + phi_t::width + pt_t::width + emid_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwEmPt); + pack_into_bits(ret, start, hwEmID); + return ret; + } + inline static HadCaloObj unpack(const ap_uint &src) { + HadCaloObj ret; + unsigned int start = 0; + unpack_from_bits(src, start, ret.hwPt); + unpack_from_bits(src, start, ret.hwEta); + unpack_from_bits(src, start, ret.hwPhi); + unpack_from_bits(src, start, ret.hwEmPt); + unpack_from_bits(src, start, ret.hwEmID); + return ret; + } + }; + + inline void clear(HadCaloObj &c) { c.clear(); } + + struct EmCaloObj { + pt_t hwPt, hwPtErr; + eta_t hwEta; // relative to the region center, at calo + phi_t hwPhi; // relative to the region center, at calo + emid_t hwEmID; + + inline bool operator==(const EmCaloObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwPtErr == other.hwPtErr && + hwEmID == other.hwEmID; + } + + inline bool operator>(const EmCaloObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const EmCaloObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwPtErr = 0; + hwEta = 0; + hwPhi = 0; + hwEmID = 0; + } + + int intPt() const { return Scales::intPt(hwPt); } + int intPtErr() const { return Scales::intPt(hwPtErr); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatPtErr() const { return Scales::floatPt(hwPtErr); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + + static const int BITWIDTH = pt_t::width + eta_t::width + phi_t::width + pt_t::width + emid_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwPtErr); + pack_into_bits(ret, start, hwEmID); + return ret; + } + inline static EmCaloObj unpack(const ap_uint &src) { + EmCaloObj ret; + unsigned int start = 0; + unpack_from_bits(src, start, ret.hwPt); + unpack_from_bits(src, start, ret.hwEta); + unpack_from_bits(src, start, ret.hwPhi); + unpack_from_bits(src, start, ret.hwPtErr); + unpack_from_bits(src, start, ret.hwEmID); + return ret; + } + }; + inline void clear(EmCaloObj &c) { c.clear(); } + + struct TkObj { + pt_t hwPt; + eta_t hwEta; // relative to the region center, at calo + phi_t hwPhi; // relative to the region center, at calo + tkdeta_t hwDEta; // vtx - calo + tkdphi_t hwDPhi; // |vtx - calo| (sign is derived by the charge) + bool hwCharge; // 1 = positive, 0 = negative + z0_t hwZ0; + dxy_t hwDxy; + tkquality_t hwQuality; + + enum TkQuality { PFLOOSE = 1, PFTIGHT = 2 }; + bool isPFLoose() const { return hwQuality[0]; } + bool isPFTight() const { return hwQuality[1]; } + phi_t hwVtxPhi() const { return hwCharge ? hwPhi + hwDPhi : hwPhi - hwDPhi; } + eta_t hwVtxEta() const { return hwEta + hwDEta; } + + inline bool operator==(const TkObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwDEta == other.hwDEta && + hwDPhi == other.hwDPhi && hwZ0 == other.hwZ0 && hwDxy == other.hwDxy && hwCharge == other.hwCharge && + hwQuality == other.hwQuality; + } + + inline bool operator>(const TkObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const TkObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwDEta = 0; + hwDPhi = 0; + hwZ0 = 0; + hwDxy = 0; + hwCharge = false; + hwQuality = 0; + } + + int intPt() const { return Scales::intPt(hwPt); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + int intVtxEta() const { return hwVtxEta().to_int(); } + int intVtxPhi() const { return hwVtxPhi().to_int(); } + int intCharge() const { return hwCharge ? +1 : -1; } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + float floatDEta() const { return Scales::floatEta(hwDEta); } + float floatDPhi() const { return Scales::floatPhi(hwDPhi); } + float floatVtxEta() const { return Scales::floatEta(hwVtxEta()); } + float floatVtxPhi() const { return Scales::floatPhi(hwVtxPhi()); } + float floatZ0() const { return Scales::floatZ0(hwZ0); } + float floatDxy() const { return Scales::floatDxy(hwDxy); } + + static const int BITWIDTH = pt_t::width + eta_t::width + phi_t::width + tkdeta_t::width + tkdphi_t::width + 1 + + z0_t::width + dxy_t::width + tkquality_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwDEta); + pack_into_bits(ret, start, hwDPhi); + pack_bool_into_bits(ret, start, hwCharge); + pack_into_bits(ret, start, hwZ0); + pack_into_bits(ret, start, hwDxy); + pack_into_bits(ret, start, hwQuality); + return ret; + } + inline static TkObj unpack(const ap_uint &src) { + TkObj ret; + unsigned int start = 0; + unpack_from_bits(src, start, ret.hwPt); + unpack_from_bits(src, start, ret.hwEta); + unpack_from_bits(src, start, ret.hwPhi); + unpack_from_bits(src, start, ret.hwDEta); + unpack_from_bits(src, start, ret.hwDPhi); + unpack_bool_from_bits(src, start, ret.hwCharge); + unpack_from_bits(src, start, ret.hwZ0); + unpack_from_bits(src, start, ret.hwDxy); + unpack_from_bits(src, start, ret.hwQuality); + return ret; + } + }; + inline void clear(TkObj &c) { c.clear(); } + + struct MuObj { + pt_t hwPt; + glbeta_t hwEta; // relative to the region center, at calo + glbphi_t hwPhi; // relative to the region center, at calo + tkdeta_t hwDEta; // vtx - calo + tkdphi_t hwDPhi; // |vtx - calo| (sign is derived by the charge) + bool hwCharge; // 1 = positive, 0 = negative + z0_t hwZ0; + dxy_t hwDxy; + ap_uint<3> hwQuality; + glbphi_t hwVtxPhi() const { return hwCharge ? hwPhi + hwDPhi : hwPhi - hwDPhi; } + glbeta_t hwVtxEta() const { return hwEta + hwDEta; } + + inline bool operator==(const MuObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwDEta == other.hwDEta && + hwDPhi == other.hwDPhi && hwZ0 == other.hwZ0 && hwDxy == other.hwDxy && hwCharge == other.hwCharge && + hwQuality == other.hwQuality; + } + + inline bool operator>(const MuObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const MuObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwDEta = 0; + hwDPhi = 0; + hwZ0 = 0; + hwDxy = 0; + hwCharge = false; + hwQuality = 0; + } + + int intPt() const { return Scales::intPt(hwPt); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + int intVtxEta() const { return hwVtxEta().to_int(); } + int intVtxPhi() const { return hwVtxPhi().to_int(); } + int intCharge() const { return hwCharge ? +1 : -1; } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + float floatDEta() const { return Scales::floatEta(hwDEta); } + float floatDPhi() const { return Scales::floatPhi(hwDPhi); } + float floatVtxEta() const { return Scales::floatEta(hwVtxEta()); } + float floatVtxPhi() const { return Scales::floatPhi(hwVtxPhi()); } + float floatZ0() const { return Scales::floatZ0(hwZ0); } + float floatDxy() const { return Scales::floatDxy(hwDxy); } + + static const int BITWIDTH = pt_t::width + glbeta_t::width + glbphi_t::width + tkdeta_t::width + tkdphi_t::width + + 1 + z0_t::width + dxy_t::width + ap_uint<3>::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwDEta); + pack_into_bits(ret, start, hwDPhi); + pack_bool_into_bits(ret, start, hwCharge); + pack_into_bits(ret, start, hwZ0); + pack_into_bits(ret, start, hwDxy); + pack_into_bits(ret, start, hwQuality); + return ret; + } + inline static MuObj unpack(const ap_uint &src) { + MuObj ret; + unsigned int start = 0; + unpack_from_bits(src, start, ret.hwPt); + unpack_from_bits(src, start, ret.hwEta); + unpack_from_bits(src, start, ret.hwPhi); + unpack_from_bits(src, start, ret.hwDEta); + unpack_from_bits(src, start, ret.hwDPhi); + unpack_bool_from_bits(src, start, ret.hwCharge); + unpack_from_bits(src, start, ret.hwZ0); + unpack_from_bits(src, start, ret.hwDxy); + unpack_from_bits(src, start, ret.hwQuality); + return ret; + } + }; + inline void clear(MuObj &c) { c.clear(); } + + struct PVObj { + z0_t hwZ0; + + inline bool operator==(const PVObj &other) const { return hwZ0 == other.hwZ0; } + + inline void clear() { hwZ0 = 0; } + + float floatZ0() const { return Scales::floatZ0(hwZ0); } + + static const int BITWIDTH = z0_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwZ0); + return ret; + } + inline static PVObj unpack(const ap_uint &src) { + PVObj ret; + unsigned int start = 0; + unpack_from_bits(src, start, ret.hwZ0); + return ret; + } + }; + inline void clear(PVObj &c) { c.clear(); } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/pf.h b/DataFormats/L1TParticleFlow/interface/pf.h new file mode 100644 index 0000000000000..fc422ca77f3fa --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/pf.h @@ -0,0 +1,267 @@ +#ifndef DataFormats_L1TParticleFlow_pf_h +#define DataFormats_L1TParticleFlow_pf_h + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/bit_encoding.h" + +namespace l1ct { + + struct PFCommonObj { + pt_t hwPt; + eta_t hwEta; // relative to the region center, at calo + phi_t hwPhi; // relative to the region center, at calo + ParticleID hwId; + + int intPt() const { return Scales::intPt(hwPt); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + int intId() const { return hwId.rawId(); } + int oldId() const { return hwPt > 0 ? hwId.oldId() : 0; } + int pdgId() const { return hwId.pdgId(); } + int intCharge() const { return hwId.intCharge(); } + + static const int _PFCOMMON_BITWIDTH = pt_t::width + eta_t::width + phi_t::width + 3; + template + inline void pack_common(U &out, unsigned int &start) const { + pack_into_bits(out, start, hwPt); + pack_into_bits(out, start, hwEta); + pack_into_bits(out, start, hwPhi); + pack_into_bits(out, start, hwId.bits); + } + template + inline void unpack_common(const U &src, unsigned int &start) { + unpack_from_bits(src, start, hwPt); + unpack_from_bits(src, start, hwEta); + unpack_from_bits(src, start, hwPhi); + unpack_from_bits(src, start, hwId.bits); + } + }; + + struct PFChargedObj : public PFCommonObj { + // WARNING: for whatever reason, maybe connected with datamember alignment, + // in 2019.2 synthesis fails if DEta & DPhi are put before Z0 & Dxy + z0_t hwZ0; + dxy_t hwDxy; + tkdeta_t hwDEta; // relative to the region center, at calo + tkdphi_t hwDPhi; // relative to the region center, at calo + tkquality_t hwTkQuality; + + phi_t hwVtxPhi() const { return hwId.chargeOrNull() ? hwPhi + hwDPhi : hwPhi - hwDPhi; } + eta_t hwVtxEta() const { return hwEta + hwDEta; } + + inline bool operator==(const PFChargedObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwId == other.hwId && + hwDEta == other.hwDEta && hwDPhi == other.hwDPhi && hwZ0 == other.hwZ0 && hwDxy == other.hwDxy && + hwTkQuality == other.hwTkQuality; + } + + inline bool operator>(const PFChargedObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const PFChargedObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwId.clear(); + hwDEta = 0; + hwDPhi = 0; + hwZ0 = 0; + hwDxy = 0; + hwTkQuality = 0; + } + + int intVtxEta() const { return hwVtxEta().to_int(); } + int intVtxPhi() const { return hwVtxPhi().to_int(); } + float floatDEta() const { return Scales::floatEta(hwDEta); } + float floatDPhi() const { return Scales::floatPhi(hwDPhi); } + float floatVtxEta() const { return Scales::floatEta(hwVtxEta()); } + float floatVtxPhi() const { return Scales::floatPhi(hwVtxPhi()); } + float floatZ0() const { return Scales::floatZ0(hwZ0); } + float floatDxy() const { return Scales::floatDxy(hwDxy); } + + static const int BITWIDTH = + _PFCOMMON_BITWIDTH + tkdeta_t::width + tkdphi_t::width + z0_t::width + dxy_t::width + tkquality_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_common(ret, start); + pack_into_bits(ret, start, hwDEta); + pack_into_bits(ret, start, hwDPhi); + pack_into_bits(ret, start, hwZ0); + pack_into_bits(ret, start, hwDxy); + pack_into_bits(ret, start, hwTkQuality); + return ret; + } + inline static PFChargedObj unpack(const ap_uint &src) { + PFChargedObj ret; + unsigned int start = 0; + ret.unpack_common(src, start); + unpack_from_bits(src, start, ret.hwDEta); + unpack_from_bits(src, start, ret.hwDPhi); + unpack_from_bits(src, start, ret.hwZ0); + unpack_from_bits(src, start, ret.hwDxy); + unpack_from_bits(src, start, ret.hwTkQuality); + return ret; + } + }; + inline void clear(PFChargedObj &c) { c.clear(); } + + struct PFNeutralObj : public PFCommonObj { + pt_t hwEmPt; + emid_t hwEmID; + ap_uint<6> hwPUID; + + inline bool operator==(const PFNeutralObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwId == other.hwId && + hwEmPt == other.hwEmPt && hwEmID == other.hwEmID && hwPUID == other.hwPUID; + } + + inline bool operator>(const PFNeutralObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const PFNeutralObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwId.clear(); + hwEmPt = 0; + hwEmID = 0; + hwPUID = 0; + } + + int intEmPt() const { return Scales::intPt(hwEmPt); } + float floatEmPt() const { return Scales::floatPt(hwEmPt); } + + static const int BITWIDTH = _PFCOMMON_BITWIDTH + pt_t::width + ap_uint<6>::width + ap_uint<6>::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_common(ret, start); + pack_into_bits(ret, start, hwEmPt); + pack_into_bits(ret, start, hwEmID); + pack_into_bits(ret, start, hwPUID); + return ret; + } + inline static PFNeutralObj unpack(const ap_uint &src) { + PFNeutralObj ret; + unsigned int start = 0; + ret.unpack_common(src, start); + unpack_from_bits(src, start, ret.hwEmPt); + unpack_from_bits(src, start, ret.hwEmID); + unpack_from_bits(src, start, ret.hwPUID); + return ret; + } + }; + + inline void clear(PFNeutralObj &c) { c.clear(); } + + struct PFRegion { + glbeta_t hwEtaCenter; + glbphi_t hwPhiCenter; + eta_t hwEtaHalfWidth; + phi_t hwPhiHalfWidth; + eta_t hwEtaExtra; + phi_t hwPhiExtra; + + inline int intEtaCenter() const { return hwEtaCenter.to_int(); } + inline int intPhiCenter() const { return hwPhiCenter.to_int(); } + inline float floatEtaCenter() const { return Scales::floatEta(hwEtaCenter); } + inline float floatPhiCenter() const { return Scales::floatPhi(hwPhiCenter); } + inline float floatEtaHalfWidth() const { return Scales::floatEta(hwEtaHalfWidth); } + inline float floatPhiHalfWidth() const { return Scales::floatPhi(hwPhiHalfWidth); } + inline float floatEtaExtra() const { return Scales::floatEta(hwEtaExtra); } + inline float floatPhiExtra() const { return Scales::floatPhi(hwPhiExtra); } + inline float floatPhiHalfWidthExtra() const { return floatPhiHalfWidth() + floatPhiExtra(); } + inline float floatEtaMin() const { return Scales::floatEta(glbeta_t(hwEtaCenter - hwEtaHalfWidth)); } + inline float floatEtaMax() const { return Scales::floatEta(glbeta_t(hwEtaCenter + hwEtaHalfWidth)); } + inline float floatEtaMinExtra() const { + return Scales::floatEta(glbeta_t(hwEtaCenter - hwEtaHalfWidth - hwEtaExtra)); + } + inline float floatEtaMaxExtra() const { + return Scales::floatEta(glbeta_t(hwEtaCenter + hwEtaHalfWidth + hwEtaExtra)); + } + + inline glbeta_t hwGlbEta(eta_t hwEta) const { return hwEtaCenter + hwEta; } + inline glbeta_t hwGlbEta(glbeta_t hwEta) const { return hwEtaCenter + hwEta; } + inline glbphi_t hwGlbPhi(glbphi_t hwPhi) const { + ap_int ret = hwPhiCenter + hwPhi; + if (ret > Scales::INTPHI_PI) + return ret - Scales::INTPHI_TWOPI; + else if (ret <= -Scales::INTPHI_PI) + return ret + Scales::INTPHI_TWOPI; + else + return ret; + } + + template + inline glbeta_t hwGlbEtaOf(const T &t) const { + return hwGlbEta(t.hwEta); + } + template + inline glbphi_t hwGlbPhiOf(const T &t) const { + return hwGlbPhi(t.hwPhi); + } + + inline float floatGlbEta(eta_t hwEta) const { return Scales::floatEta(hwGlbEta(hwEta)); } + inline float floatGlbPhi(phi_t hwPhi) const { return Scales::floatPhi(hwGlbPhi(hwPhi)); } + inline float floatGlbEta(glbeta_t hwEta) const { return Scales::floatEta(hwGlbEta(hwEta)); } + inline float floatGlbPhi(glbphi_t hwPhi) const { return Scales::floatPhi(hwGlbPhi(hwPhi)); } + + template + inline float floatGlbEtaOf(const T &t) const { + return floatGlbEta(t.hwEta); + } + template + inline float floatGlbPhiOf(const T &t) const { + return floatGlbPhi(t.hwPhi); + } + + inline bool isFiducial(eta_t hwEta, phi_t hwPhi) const { + return hwEta <= hwEtaHalfWidth && hwEta > -hwEtaHalfWidth && hwPhi <= hwPhiHalfWidth && hwPhi > -hwPhiHalfWidth; + } + template // forcing down to eta_t and phi_t may have overflows & crops + inline bool isInside(ET hwEta, PT hwPhi) const { + return hwEta <= hwEtaHalfWidth + hwEtaExtra && hwEta >= -hwEtaHalfWidth - hwEtaExtra && + hwPhi <= hwPhiHalfWidth + hwPhiExtra && hwPhi >= -hwPhiHalfWidth - hwPhiExtra; + } + + template + inline bool isFiducial(const T &t) const { + return isFiducial(t.hwEta, t.hwPhi); + } + template + inline bool isInside(const T &t) const { + return isInside(t.hwEta, t.hwPhi); + } + + static const int BITWIDTH = glbeta_t::width + glbphi_t::width + 2 * eta_t::width + 2 * phi_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwEtaCenter); + pack_into_bits(ret, start, hwPhiCenter); + pack_into_bits(ret, start, hwEtaHalfWidth); + pack_into_bits(ret, start, hwPhiHalfWidth); + pack_into_bits(ret, start, hwEtaExtra); + pack_into_bits(ret, start, hwPhiExtra); + return ret; + } + inline static PFRegion unpack(const ap_uint &src) { + PFRegion ret; + unsigned int start = 0; + unpack_from_bits(src, start, ret.hwEtaCenter); + unpack_from_bits(src, start, ret.hwPhiCenter); + unpack_from_bits(src, start, ret.hwEtaHalfWidth); + unpack_from_bits(src, start, ret.hwPhiHalfWidth); + unpack_from_bits(src, start, ret.hwEtaExtra); + unpack_from_bits(src, start, ret.hwPhiExtra); + return ret; + } + }; + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/puppi.h b/DataFormats/L1TParticleFlow/interface/puppi.h new file mode 100644 index 0000000000000..e372b80172c22 --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/puppi.h @@ -0,0 +1,189 @@ +#ifndef DataFormats_L1TParticleFlow_puppi_h +#define DataFormats_L1TParticleFlow_puppi_h + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/bit_encoding.h" +#include "DataFormats/L1TParticleFlow/interface/layer1_objs.h" +#include "DataFormats/L1TParticleFlow/interface/pf.h" + +namespace l1ct { + + struct PuppiObj { + pt_t hwPt; + glbeta_t hwEta; // wider range to support global coordinates + glbphi_t hwPhi; + ParticleID hwId; + + static const int BITS_Z0_START = 0; + static const int BITS_DXY_START = BITS_Z0_START + z0_t::width; + static const int BITS_TKQUAL_START = BITS_DXY_START + dxy_t::width; + static const int DATA_CHARGED_BITS_TOTAL = BITS_TKQUAL_START + tkquality_t::width; + + static const int BITS_PUPPIW_START = 0; + static const int BITS_EMID_START = BITS_PUPPIW_START + puppiWgt_t::width; + static const int DATA_NEUTRAL_BITS_TOTAL = BITS_EMID_START + emid_t::width; + + static const int DATA_BITS_TOTAL = + DATA_CHARGED_BITS_TOTAL >= DATA_NEUTRAL_BITS_TOTAL ? DATA_CHARGED_BITS_TOTAL : DATA_NEUTRAL_BITS_TOTAL; + + ap_uint hwData; + + inline z0_t hwZ0() const { +#ifndef __SYNTHESIS__ + assert(hwId.charged() || hwPt == 0); +#endif + return z0_t(hwData(BITS_Z0_START + z0_t::width - 1, BITS_Z0_START)); + } + + inline void setHwZ0(z0_t z0) { +#ifndef __SYNTHESIS__ + assert(hwId.charged() || hwPt == 0); +#endif + hwData(BITS_Z0_START + z0_t::width - 1, BITS_Z0_START) = z0(z0_t::width - 1, 0); + } + + inline dxy_t hwDxy() const { +#ifndef __SYNTHESIS__ + assert(hwId.charged() || hwPt == 0); +#endif + return dxy_t(hwData(BITS_DXY_START + dxy_t::width - 1, BITS_DXY_START)); + } + + inline void setHwDxy(dxy_t dxy) { +#ifndef __SYNTHESIS__ + assert(hwId.charged() || hwPt == 0); +#endif + hwData(BITS_DXY_START + dxy_t::width - 1, BITS_DXY_START) = dxy(7, 0); + } + + inline tkquality_t hwTkQuality() const { +#ifndef __SYNTHESIS__ + assert(hwId.charged() || hwPt == 0); +#endif + return tkquality_t(hwData(BITS_TKQUAL_START + tkquality_t::width - 1, BITS_TKQUAL_START)); + } + + inline void setHwTkQuality(tkquality_t qual) { +#ifndef __SYNTHESIS__ + assert(hwId.charged() || hwPt == 0); +#endif + hwData(BITS_TKQUAL_START + tkquality_t::width - 1, BITS_TKQUAL_START) = qual(tkquality_t::width - 1, 0); + } + + inline puppiWgt_t hwPuppiW() const { +#ifndef __SYNTHESIS__ + assert(hwId.neutral()); +#endif + return puppiWgt_t(hwData(BITS_PUPPIW_START + puppiWgt_t::width - 1, BITS_PUPPIW_START)); + } + + inline void setHwPuppiW(puppiWgt_t w) { +#ifndef __SYNTHESIS__ + assert(hwId.neutral()); +#endif + hwData(BITS_PUPPIW_START + puppiWgt_t::width - 1, BITS_PUPPIW_START) = w(puppiWgt_t::width - 1, 0); + } + + inline puppiWgt_t hwEmID() const { +#ifndef __SYNTHESIS__ + assert(hwId.neutral()); +#endif + return puppiWgt_t(hwData(BITS_EMID_START + emid_t::width - 1, BITS_EMID_START)); + } + + inline void setHwEmID(emid_t w) { +#ifndef __SYNTHESIS__ + assert(hwId.neutral()); +#endif + hwData(BITS_EMID_START + emid_t::width - 1, BITS_EMID_START) = w(emid_t::width - 1, 0); + } + + inline bool operator==(const PuppiObj &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwId == other.hwId && + hwData == other.hwData; + } + + inline bool operator>(const PuppiObj &other) const { return hwPt > other.hwPt; } + inline bool operator<(const PuppiObj &other) const { return hwPt < other.hwPt; } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwId.clear(); + hwData = 0; + } + + inline void fill(const PFRegion ®ion, const PFChargedObj &src) { + hwEta = region.hwGlbEta(src.hwVtxEta()); + hwPhi = region.hwGlbPhi(src.hwVtxPhi()); + hwId = src.hwId; + hwPt = src.hwPt; + hwData = 0; + setHwZ0(src.hwZ0); + setHwDxy(src.hwDxy); + setHwTkQuality(src.hwTkQuality); + } + inline void fill(const PFRegion ®ion, const PFNeutralObj &src, pt_t puppiPt, puppiWgt_t puppiWgt) { + hwEta = region.hwGlbEta(src.hwEta); + hwPhi = region.hwGlbPhi(src.hwPhi); + hwId = src.hwId; + hwPt = puppiPt; + hwData = 0; + setHwPuppiW(puppiWgt); + setHwEmID(src.hwEmID); + } + inline void fill(const PFRegion ®ion, const HadCaloObj &src, pt_t puppiPt, puppiWgt_t puppiWgt) { + hwEta = region.hwGlbEta(src.hwEta); + hwPhi = region.hwGlbPhi(src.hwPhi); + hwId = src.hwIsEM() ? ParticleID::PHOTON : ParticleID::HADZERO; + hwPt = puppiPt; + hwData = 0; + setHwPuppiW(puppiWgt); + setHwEmID(src.hwEmID); + } + + int intPt() const { return Scales::intPt(hwPt); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + int intId() const { return hwId.rawId(); } + int pdgId() const { return hwId.pdgId(); } + int oldId() const { return hwPt > 0 ? hwId.oldId() : 0; } + int intCharge() const { return hwId.intCharge(); } + float floatZ0() const { return Scales::floatZ0(hwZ0()); } + float floatDxy() const { return Scales::floatDxy(hwDxy()); } + float floatPuppiW() const { return hwId.neutral() ? Scales::floatPuppiW(hwPuppiW()) : 1.0f; } + + static const int BITWIDTH = pt_t::width + glbeta_t::width + glbphi_t::width + 3 + DATA_BITS_TOTAL; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwId.bits); + pack_into_bits(ret, start, hwData); + return ret; + } + inline void initFromBits(const ap_uint &src) { + unsigned int start = 0; + unpack_from_bits(src, start, hwPt); + unpack_from_bits(src, start, hwEta); + unpack_from_bits(src, start, hwPhi); + unpack_from_bits(src, start, hwId.bits); + unpack_from_bits(src, start, hwData); + } + inline static PuppiObj unpack(const ap_uint &src) { + PuppiObj ret; + ret.initFromBits(src); + return ret; + } + }; + inline void clear(PuppiObj &c) { c.clear(); } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/sums.h b/DataFormats/L1TParticleFlow/interface/sums.h new file mode 100644 index 0000000000000..195566f61afbe --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/sums.h @@ -0,0 +1,64 @@ +#ifndef DataFormats_L1TParticleFlow_sums_h +#define DataFormats_L1TParticleFlow_sums_h + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/gt_datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/bit_encoding.h" + +namespace l1ct { + + struct Sum { + pt_t hwPt; + glbphi_t hwPhi; + pt_t hwSumPt; + + inline bool operator==(const Sum &other) const { + return hwPt == other.hwPt && hwPhi == other.hwPhi && hwSumPt == other.hwSumPt; + } + + inline void clear() { + hwPt = 0; + hwPhi = 0; + hwSumPt = 0; + } + + int intPt() const { return Scales::intPt(hwPt); } + int intPhi() const { return hwPhi.to_int(); } + int intSumPt() const { return Scales::intPt(hwSumPt); } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + float floatSumPt() const { return Scales::floatPt(hwSumPt); } + + static const int BITWIDTH = pt_t::width + glbphi_t::width + pt_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwSumPt); + return ret; + } + inline static Sum unpack(const ap_uint &src) { + Sum ret; + unsigned int start = 0; + unpack_from_bits(src, start, ret.hwPt); + unpack_from_bits(src, start, ret.hwPhi); + unpack_from_bits(src, start, ret.hwSumPt); + return ret; + } + + l1gt::Sum toGT() const { + l1gt::Sum sum; + sum.valid = (hwPt != 0) || (hwSumPt != 0); + sum.vector_pt = CTtoGT_pt(hwPt); + sum.vector_phi = CTtoGT_phi(hwPhi); + sum.scalar_pt = CTtoGT_phi(hwSumPt); + return sum; + } + }; + + inline void clear(Sum &c) { c.clear(); } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/interface/taus.h b/DataFormats/L1TParticleFlow/interface/taus.h new file mode 100644 index 0000000000000..251f2cb5aea1e --- /dev/null +++ b/DataFormats/L1TParticleFlow/interface/taus.h @@ -0,0 +1,111 @@ +#ifndef DataFormats_L1TParticleFlow_taus_h +#define DataFormats_L1TParticleFlow_taus_h + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" +#include "DataFormats/L1TParticleFlow/interface/bit_encoding.h" + +namespace l1ct { + + struct Tau { + typedef ap_uint<2> type_t; + typedef ap_uint<10> rawid_t; + typedef ap_uint<2> lepid_t; + + pt_t hwPt; + glbeta_t hwEta; + glbphi_t hwPhi; + pt_t hwSeedPt; + z0_t hwSeedZ0; + bool hwCharge; + type_t hwType; + rawid_t hwRawId; // will contain isolation or MVA output + lepid_t hwIdVsMu; + lepid_t hwIdVsEle; + rawid_t hwIsoOrMVA; + + inline bool operator==(const Tau &other) const { + return hwPt == other.hwPt && hwEta == other.hwEta && hwPhi == other.hwPhi && hwSeedPt == other.hwSeedPt && + hwSeedZ0 == other.hwSeedZ0 && hwCharge == other.hwCharge && hwType == other.hwType && + hwIsoOrMVA == other.hwIsoOrMVA && hwIdVsMu == other.hwIdVsMu && hwIdVsEle == other.hwIdVsEle; + } + + inline bool operator>(const Tau &other) const { return hwPt > other.hwPt; } + inline bool operator<(const Tau &other) const { return hwPt < other.hwPt; } + + inline pt_t hwAbsIso() const { + pt10_t ret; + ret(9, 0) = hwRawId(9, 0); + return ret; + } + + inline void setAbsIso(pt10_t absIso) { hwRawId(9, 0) = absIso(9, 0); } + + inline void clear() { + hwPt = 0; + hwEta = 0; + hwPhi = 0; + hwSeedPt = 0; + hwSeedZ0 = 0; + hwCharge = 0; + hwType = 0; + hwIsoOrMVA = 0; + hwIdVsMu = 0; + hwIdVsEle = 0; + hwIsoOrMVA = 0; + } + + int intPt() const { return Scales::intPt(hwPt); } + int intEta() const { return hwEta.to_int(); } + int intPhi() const { return hwPhi.to_int(); } + int intSeedPt() const { return Scales::intPt(hwSeedPt); } + float floatPt() const { return Scales::floatPt(hwPt); } + float floatEta() const { return Scales::floatEta(hwEta); } + float floatPhi() const { return Scales::floatPhi(hwPhi); } + float floatSeedPt() const { return Scales::floatPt(hwSeedPt); } + float floatSeedZ0() const { return Scales::floatZ0(hwSeedZ0); } + int intCharge() const { return hwCharge ? +1 : -1; } + int pdgId() const { return -15 * intCharge(); } + int intType() const { return hwType.to_int(); } + + float floatAbsIso() const { return Scales::floatPt(hwAbsIso()); } + + static const int BITWIDTH = pt_t::width + glbeta_t::width + glbphi_t::width + pt10_t::width + z0_t::width + 1 + + type_t::width + rawid_t::width + 2 * lepid_t::width; + inline ap_uint pack() const { + ap_uint ret; + unsigned int start = 0; + pack_into_bits(ret, start, hwPt); + pack_into_bits(ret, start, hwEta); + pack_into_bits(ret, start, hwPhi); + pack_into_bits(ret, start, hwSeedPt); + pack_into_bits(ret, start, hwSeedZ0); + pack_bool_into_bits(ret, start, hwCharge); + pack_into_bits(ret, start, hwType); + pack_into_bits(ret, start, hwRawId); + pack_into_bits(ret, start, hwIdVsMu); + pack_into_bits(ret, start, hwIdVsEle); + pack_into_bits(ret, start, hwIsoOrMVA); + return ret; + } + inline static Tau unpack(const ap_uint &src) { + Tau ret; + unsigned int start = 0; + unpack_from_bits(src, start, ret.hwPt); + unpack_from_bits(src, start, ret.hwEta); + unpack_from_bits(src, start, ret.hwPhi); + unpack_from_bits(src, start, ret.hwSeedPt); + unpack_from_bits(src, start, ret.hwSeedZ0); + unpack_from_bits(src, start, ret.hwType); + unpack_from_bits(src, start, ret.hwRawId); + unpack_from_bits(src, start, ret.hwIdVsMu); + unpack_from_bits(src, start, ret.hwIdVsEle); + unpack_from_bits(src, start, ret.hwIsoOrMVA); + return ret; + } + }; + + inline void clear(Tau &c) { c.clear(); } + +} // namespace l1ct + +#endif diff --git a/DataFormats/L1TParticleFlow/src/HPSPFTau.cc b/DataFormats/L1TParticleFlow/src/HPSPFTau.cc index a346c1b963943..0150060684503 100644 --- a/DataFormats/L1TParticleFlow/src/HPSPFTau.cc +++ b/DataFormats/L1TParticleFlow/src/HPSPFTau.cc @@ -60,8 +60,8 @@ ostream& operator<<(ostream& os, const l1t::HPSPFTau& l1PFTau) { return os; } -void printPFCand(ostream& os, const l1t::PFCandidate& l1PFCand, const l1t::TkPrimaryVertexRef& primaryVertex) { - float primaryVertexZ = (primaryVertex.isNonnull()) ? primaryVertex->zvertex() : 0.; +void printPFCand(ostream& os, const l1t::PFCandidate& l1PFCand, const l1t::VertexWordRef& primaryVertex) { + float primaryVertexZ = (primaryVertex.isNonnull()) ? primaryVertex->z0() : 0.; printPFCand(os, l1PFCand, primaryVertexZ); } diff --git a/DataFormats/L1TParticleFlow/src/PFCandidate.cc b/DataFormats/L1TParticleFlow/src/PFCandidate.cc index 38baece81f2f4..964e55687ec86 100644 --- a/DataFormats/L1TParticleFlow/src/PFCandidate.cc +++ b/DataFormats/L1TParticleFlow/src/PFCandidate.cc @@ -2,7 +2,15 @@ l1t::PFCandidate::PFCandidate( ParticleType kind, int charge, const PolarLorentzVector& p, float puppiWeight, int hwpt, int hweta, int hwphi) - : L1Candidate(p, hwpt, hweta, hwphi, /*hwQuality=*/int(kind)), puppiWeight_(puppiWeight) { + : L1Candidate(p, hwpt, hweta, hwphi, /*hwQuality=*/int(kind)), + dxy_(0), + puppiWeight_(puppiWeight), + hwZ0_(0), + hwDxy_(0), + hwTkQuality_(0), + hwPuppiWeight_(0), + hwEmID_(0), + encodedPuppi64_(0) { setCharge(charge); setPdgIdFromParticleType(charge, kind); } diff --git a/DataFormats/L1TParticleFlow/src/PFCluster.cc b/DataFormats/L1TParticleFlow/src/PFCluster.cc index f2b9a24144e45..a22811dd6cf98 100644 --- a/DataFormats/L1TParticleFlow/src/PFCluster.cc +++ b/DataFormats/L1TParticleFlow/src/PFCluster.cc @@ -5,7 +5,7 @@ void l1t::PFCluster::calibratePt(float newpt, float preserveEmEt) { ptError_ *= newpt / pt(); setP4(PolarLorentzVector(newpt, eta(), phi(), mass())); if (preserveEmEt) { - float hNew = std::max(pt() - currEmEt, 0); + float hNew = pt() - currEmEt; hOverE_ = (currEmEt > 0 ? hNew / currEmEt : -1); } } diff --git a/DataFormats/L1TParticleFlow/src/classes_def.xml b/DataFormats/L1TParticleFlow/src/classes_def.xml index 112f0566c7b84..b1ed9da86adda 100644 --- a/DataFormats/L1TParticleFlow/src/classes_def.xml +++ b/DataFormats/L1TParticleFlow/src/classes_def.xml @@ -9,7 +9,8 @@ - + + @@ -18,15 +19,22 @@ - + + + + + + + - + + @@ -35,7 +43,8 @@ - + + @@ -44,9 +53,11 @@ - - + + + + diff --git a/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp b/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp new file mode 100644 index 0000000000000..f0b56b1c25022 --- /dev/null +++ b/DataFormats/L1TParticleFlow/src/layer1_emulator.cpp @@ -0,0 +1,439 @@ +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include +#include +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "DataFormats/Math/interface/deltaPhi.h" +#else +namespace reco { + template + inline T reduceRange(T x) { + T o2pi = 1. / (2. * M_PI); + if (std::abs(x) <= T(M_PI)) + return x; + T n = std::round(x * o2pi); + return x - n * T(2. * M_PI); + } + inline double deltaPhi(double phi1, double phi2) { return reduceRange(phi1 - phi2); } +} // namespace reco +#endif + +bool l1ct::HadCaloObjEmu::read(std::fstream& from) { + src = nullptr; // not persistent + return readObj(from, *this); +} +bool l1ct::HadCaloObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::EmCaloObjEmu::read(std::fstream& from) { + src = nullptr; // not persistent + return readObj(from, *this); +} +bool l1ct::EmCaloObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::TkObjEmu::read(std::fstream& from) { + src = nullptr; // not persistent + return readObj(from, *this) && readVar(from, hwChi2) && readVar(from, hwStubs) && readVar(from, simPt) && + readVar(from, simCaloEta) && readVar(from, simCaloPhi) && readVar(from, simVtxEta) && + readVar(from, simVtxPhi) && readVar(from, simZ0) && readVar(from, simD0); +} +bool l1ct::TkObjEmu::write(std::fstream& to) const { + return writeObj(*this, to) && writeVar(hwChi2, to) && writeVar(hwStubs, to) && writeVar(simPt, to) && + writeVar(simCaloEta, to) && writeVar(simCaloPhi, to) && writeVar(simVtxEta, to) && writeVar(simVtxPhi, to) && + writeVar(simZ0, to) && writeVar(simD0, to); +} + +bool l1ct::MuObjEmu::read(std::fstream& from) { + src = nullptr; // not persistent + return readObj(from, *this); +} +bool l1ct::MuObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::PFChargedObjEmu::read(std::fstream& from) { + srcTrack = nullptr; // not persistent + srcCluster = nullptr; // not persistent + srcMu = nullptr; // not persistent + srcCand = nullptr; // not persistent + return readObj(from, *this); +} +bool l1ct::PFChargedObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::PFNeutralObjEmu::read(std::fstream& from) { + srcCluster = nullptr; // not persistent + srcCand = nullptr; // not persistent + return readObj(from, *this); +} +bool l1ct::PFNeutralObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::PuppiObjEmu::read(std::fstream& from) { + srcTrack = nullptr; // not persistent + srcCluster = nullptr; // not persistent + srcMu = nullptr; // not persistent + srcCand = nullptr; // not persistent + return readObj(from, *this); +} +bool l1ct::PuppiObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::EGIsoObjEmu::read(std::fstream& from) { + srcCluster = nullptr; // not persistent + sta_idx = -1; + clearIsoVars(); // not persistent + return readObj(from, *this); +} + +bool l1ct::EGIsoObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::EGIsoEleObjEmu::read(std::fstream& from) { + srcCluster = nullptr; + srcTrack = nullptr; + sta_idx = -1; + clearIsoVars(); // not persistent + return readObj(from, *this); +} + +bool l1ct::EGIsoEleObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +l1ct::PFRegionEmu::PFRegionEmu(float etaCenter, float phicenter) { + hwEtaCenter = Scales::makeGlbEta(etaCenter); + hwPhiCenter = Scales::makeGlbPhi(phicenter); + hwEtaHalfWidth = 0; + hwPhiHalfWidth = 0; + hwEtaExtra = 0; + hwPhiExtra = 0; +} +l1ct::PFRegionEmu::PFRegionEmu( + float etamin, float etamax, float phicenter, float phiwidth, float etaextra, float phiextra) { + glbeta_t hwEtaMin = Scales::makeGlbEtaRoundEven(etamin); + glbeta_t hwEtaMax = Scales::makeGlbEtaRoundEven(etamax); + + hwEtaCenter = glbeta_t((hwEtaMin + hwEtaMax) / 2); + hwPhiCenter = Scales::makeGlbPhi(phicenter); + hwEtaHalfWidth = hwEtaCenter - hwEtaMin; + hwPhiHalfWidth = Scales::makeGlbPhi(0.5 * phiwidth); + hwEtaExtra = Scales::makeGlbEta(etaextra); + hwPhiExtra = Scales::makeGlbPhi(phiextra); +} + +bool l1ct::PFRegionEmu::contains(float eta, float phi) const { + float dphi = reco::deltaPhi(phi, floatPhiCenter()); + return (floatEtaMinExtra() <= eta && eta <= floatEtaMaxExtra() && -floatPhiHalfWidthExtra() <= dphi && + dphi <= floatPhiHalfWidthExtra()); +} +bool l1ct::PFRegionEmu::containsHw(glbeta_t glbeta, glbphi_t glbphi) const { + glbeta_t loceta = glbeta - hwEtaCenter; + ap_int locphi = glbphi - hwPhiCenter; + if (locphi > Scales::INTPHI_PI) + locphi -= Scales::INTPHI_TWOPI; + else if (locphi <= -Scales::INTPHI_PI) + locphi += Scales::INTPHI_TWOPI; + return isInside(loceta, locphi); +} + +float l1ct::PFRegionEmu::localEta(float globalEta) const { return globalEta - floatEtaCenter(); } +float l1ct::PFRegionEmu::localPhi(float globalPhi) const { return reco::deltaPhi(globalPhi, floatPhiCenter()); } + +bool l1ct::PFRegionEmu::read(std::fstream& from) { return readObj(from, *this); } +bool l1ct::PFRegionEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::PVObjEmu::read(std::fstream& from) { return readObj(from, *this); } +bool l1ct::PVObjEmu::write(std::fstream& to) const { return writeObj(*this, to); } + +bool l1ct::RawInputs::read(std::fstream& from) { + uint32_t number; + + if (!readVar(from, number)) + return false; + track.resize(number); + for (auto& v : track) { + if (!(v.region.read(from) && readMany(from, v.obj))) + return false; + } + + if (!(muon.region.read(from) && readMany(from, muon.obj))) + return false; + + if (!readVar(from, number)) + return false; + hgcalcluster.resize(number); + for (auto& v : hgcalcluster) { + if (!(v.region.read(from) && readMany(from, v.obj))) + return false; + } + + return true; +} + +bool l1ct::RawInputs::write(std::fstream& to) const { + uint32_t number; + + number = track.size(); + if (!writeVar(number, to)) + return false; + for (const auto& v : track) { + if (!(v.region.write(to) && writeMany(v.obj, to))) + return false; + } + + if (!(muon.region.write(to) && writeMany(muon.obj, to))) + return false; + + number = hgcalcluster.size(); + if (!writeVar(number, to)) + return false; + for (const auto& v : hgcalcluster) { + if (!(v.region.write(to) && writeMany(v.obj, to))) + return false; + } + + return true; +} +void l1ct::RawInputs::clear() { + for (auto& r : track) + r.clear(); + muon.clear(); + for (auto& h : hgcalcluster) + h.clear(); +} + +bool l1ct::RegionizerDecodedInputs::read(std::fstream& from) { + uint32_t number; + + if (!readVar(from, number)) + return false; + hadcalo.resize(number); + for (auto& v : hadcalo) { + if (!(v.region.read(from) && readMany(from, v.obj))) + return false; + } + + if (!readVar(from, number)) + return false; + emcalo.resize(number); + for (auto& v : emcalo) { + if (!(v.region.read(from) && readMany(from, v.obj))) + return false; + } + + if (!readVar(from, number)) + return false; + track.resize(number); + for (auto& v : track) { + if (!(v.region.read(from) && readMany(from, v.obj))) + return false; + } + + if (!(muon.region.read(from) && readMany(from, muon.obj))) + return false; + + return true; +} + +bool l1ct::RegionizerDecodedInputs::write(std::fstream& to) const { + uint32_t number; + + number = hadcalo.size(); + if (!writeVar(number, to)) + return false; + for (const auto& v : hadcalo) { + if (!(v.region.write(to) && writeMany(v.obj, to))) + return false; + } + + number = emcalo.size(); + if (!writeVar(number, to)) + return false; + for (const auto& v : emcalo) { + if (!(v.region.write(to) && writeMany(v.obj, to))) + return false; + } + + number = track.size(); + if (!writeVar(number, to)) + return false; + for (const auto& v : track) { + if (!(v.region.write(to) && writeMany(v.obj, to))) + return false; + } + + if (!(muon.region.write(to) && writeMany(muon.obj, to))) + return false; + + return true; +} +void l1ct::RegionizerDecodedInputs::clear() { + for (auto& r : hadcalo) + r.clear(); + for (auto& r : emcalo) + r.clear(); + for (auto& r : track) + r.clear(); + muon.clear(); +} + +bool l1ct::PFInputRegion::read(std::fstream& from) { + return region.read(from) && readMany(from, hadcalo) && readMany(from, emcalo) && readMany(from, track) && + readMany(from, muon); +} +bool l1ct::PFInputRegion::write(std::fstream& to) const { + return region.write(to) && writeMany(hadcalo, to) && writeMany(emcalo, to) && writeMany(track, to) && + writeMany(muon, to); +} +void l1ct::PFInputRegion::clear() { + hadcalo.clear(); + emcalo.clear(); + track.clear(); + muon.clear(); +} + +bool l1ct::OutputRegion::read(std::fstream& from) { + return readMany(from, pfcharged) && readMany(from, pfneutral) && readMany(from, pfphoton) && readMany(from, pfmuon) && + readMany(from, puppi) && readMany(from, egphoton) && readMany(from, egelectron); +} +bool l1ct::OutputRegion::write(std::fstream& to) const { + return writeMany(pfcharged, to) && writeMany(pfneutral, to) && writeMany(pfphoton, to) && writeMany(pfmuon, to) && + writeMany(puppi, to) && writeMany(egphoton, to) && writeMany(egelectron, to); +} + +void l1ct::OutputRegion::clear() { + pfcharged.clear(); + pfphoton.clear(); + pfneutral.clear(); + pfmuon.clear(); + puppi.clear(); + egsta.clear(); + egphoton.clear(); + egelectron.clear(); +} + +// begin helper functions +namespace { + template + unsigned int count_nonnull(const TV& v) { + typedef typename TV::value_type T; + return std::count_if(v.begin(), v.end(), [](const T& p) { return p.hwPt > 0; }); + } + template + unsigned int count_nonnull_if(const TV& v, F pred) { + unsigned int n = 0; + for (auto& p : v) { + if (p.hwPt > 0 && pred(p.hwId)) + ++n; + } + return n; + } +} // namespace +// end helper functions +unsigned int l1ct::OutputRegion::nObj(ObjType type, bool usePuppi) const { + switch (type) { + case anyType: + if (usePuppi) + return ::count_nonnull(puppi); + else + return ::count_nonnull(pfcharged) + ::count_nonnull(pfphoton) + ::count_nonnull(pfneutral); + case chargedType: + if (usePuppi) + return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.charged(); }); + else + return ::count_nonnull(pfcharged); + case neutralType: + if (usePuppi) + return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.neutral(); }); + else + return ::count_nonnull(pfphoton) + ::count_nonnull(pfneutral); + case electronType: + if (usePuppi) + return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isElectron(); }); + else + return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isElectron(); }); + case muonType: + if (usePuppi) + return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isMuon(); }); + else + return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isMuon(); }); + case chargedHadronType: + if (usePuppi) + return ::count_nonnull_if(puppi, [](const l1ct::ParticleID& i) { return i.isChargedHadron(); }); + else + return ::count_nonnull_if(pfcharged, [](const l1ct::ParticleID& i) { return i.isChargedHadron(); }); + case neutralHadronType: + if (usePuppi) + return ::count_nonnull_if(puppi, + [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::HADZERO; }); + else + return ::count_nonnull_if(pfneutral, + [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::HADZERO; }); + case photonType: + if (usePuppi) + return ::count_nonnull_if(puppi, + [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; }); + else + return ::count_nonnull_if(pfneutral, + [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; }) + + ::count_nonnull_if(pfphoton, + [](const l1ct::ParticleID& i) { return i.rawId() == l1ct::ParticleID::PHOTON; }); + case egisoType: + assert(!usePuppi); + return ::count_nonnull(egphoton); + case egisoeleType: + assert(!usePuppi); + return ::count_nonnull(egelectron); + default: + assert(false); + } +} + +bool l1ct::OutputBoard::read(std::fstream& from) { + return readVar(from, eta) && readVar(from, phi) && readMany(from, egphoton) && readMany(from, egelectron); +} +bool l1ct::OutputBoard::write(std::fstream& to) const { + return writeVar(eta, to) && writeVar(phi, to) && writeMany(egphoton, to) && writeMany(egelectron, to); +} + +void l1ct::OutputBoard::clear() { + egphoton.clear(); + egelectron.clear(); +} + +bool l1ct::Event::read(std::fstream& from) { + uint32_t version; + if (!readVar(from, version)) + return false; + if (version != VERSION) { + //dbgCout() << "ERROR: version mismatch between this code (" << VERSION << ") and dump file (" << version << ")." + // << std::endl; + //dbgCerr() << "ERROR: version mismatch between this code (" << VERSION << ") and dump file (" << version << ")." + // << std::endl; + abort(); + } + return readVar(from, run) && readVar(from, lumi) && readVar(from, event) && raw.read(from) && decoded.read(from) && + readMany(from, pfinputs) && readMany(from, pvs) && readMany(from, pvs_emu) && readMany(from, out) && + readMany(from, board_out); +} +bool l1ct::Event::write(std::fstream& to) const { + uint32_t version = VERSION; + return writeVar(version, to) && writeVar(run, to) && writeVar(lumi, to) && writeVar(event, to) && raw.write(to) && + decoded.write(to) && writeMany(pfinputs, to) && writeMany(pvs, to) && writeMany(pvs_emu, to) && + writeMany(out, to) && writeMany(board_out, to); +} +void l1ct::Event::init(uint32_t arun, uint32_t alumi, uint64_t anevent) { + clear(); + run = arun; + lumi = alumi; + event = anevent; +} +void l1ct::Event::clear() { + run = 0; + lumi = 0; + event = 0; + raw.clear(); + decoded.clear(); + for (auto& i : pfinputs) + i.clear(); + pvs.clear(); + pvs_emu.clear(); + for (auto& i : out) + i.clear(); + for (auto& i : board_out) + i.clear(); +} diff --git a/DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h b/DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h index 4b37a6b63a46b..a1259812ddbe3 100644 --- a/DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h +++ b/DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h @@ -223,6 +223,7 @@ class TTTrack_TrackWord { double getChi2RZ() const { return chi2RZBins[getChi2RZBits()]; } double getBendChi2() const { return bendChi2Bins[getBendChi2Bits()]; } unsigned int getHitPattern() const { return getHitPatternBits(); } + unsigned int getNStubs() const { return countSetBits(getHitPatternBits()); } unsigned int getMVAQuality() const { return getMVAQualityBits(); } unsigned int getMVAOther() const { return getMVAOtherBits(); } @@ -277,6 +278,16 @@ class TTTrack_TrackWord { private: // ----------private member functions -------------- + unsigned int countSetBits(unsigned int n) const { + // Adapted from: https://www.geeksforgeeks.org/count-set-bits-in-an-integer/ + unsigned int count = 0; + while (n) { + n &= (n - 1); + count++; + } + return count; + } + unsigned int digitizeSignedValue(double value, unsigned int nBits, double lsb) const { // Digitize the incoming value int digitizedValue = std::floor(value / lsb); diff --git a/DataFormats/L1TrackTrigger/src/classes_def.xml b/DataFormats/L1TrackTrigger/src/classes_def.xml index 3d30d9bac86e4..9d5ce0be50192 100644 --- a/DataFormats/L1TrackTrigger/src/classes_def.xml +++ b/DataFormats/L1TrackTrigger/src/classes_def.xml @@ -20,6 +20,10 @@ + + + + diff --git a/DataFormats/L1TrackTrigger/test/TestDataFormatsTTTrackTrackWord.cc b/DataFormats/L1TrackTrigger/test/TestDataFormatsTTTrackTrackWord.cc index 14709bc605514..3eb6c49b54d15 100644 --- a/DataFormats/L1TrackTrigger/test/TestDataFormatsTTTrackTrackWord.cc +++ b/DataFormats/L1TrackTrigger/test/TestDataFormatsTTTrackTrackWord.cc @@ -1,4 +1,4 @@ -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -9,7 +9,7 @@ #include namespace trackwordtest { - class TTTrackTrackWordDummyOneAnalyzer : public edm::EDAnalyzer { + class TTTrackTrackWordDummyOneAnalyzer : public edm::one::EDAnalyzer<> { public: explicit TTTrackTrackWordDummyOneAnalyzer(const edm::ParameterSet&) {} ~TTTrackTrackWordDummyOneAnalyzer() {} @@ -28,4 +28,4 @@ namespace trackwordtest { } // namespace trackwordtest using trackwordtest::TTTrackTrackWordDummyOneAnalyzer; -DEFINE_FWK_MODULE(TTTrackTrackWordDummyOneAnalyzer); \ No newline at end of file +DEFINE_FWK_MODULE(TTTrackTrackWordDummyOneAnalyzer); diff --git a/DataFormats/L1Trigger/BuildFile.xml b/DataFormats/L1Trigger/BuildFile.xml index d5b3b6590cd96..400a1e7b4ec90 100644 --- a/DataFormats/L1Trigger/BuildFile.xml +++ b/DataFormats/L1Trigger/BuildFile.xml @@ -5,6 +5,7 @@ + diff --git a/DataFormats/L1Trigger/interface/MuonShower.h b/DataFormats/L1Trigger/interface/MuonShower.h index 15125d77bc548..716737fe71094 100644 --- a/DataFormats/L1Trigger/interface/MuonShower.h +++ b/DataFormats/L1Trigger/interface/MuonShower.h @@ -54,13 +54,15 @@ namespace l1t { The 2 loose showers case would be mapped onto musOutOfTime0 and musOutOfTime1 later during Run-3 */ - void setMus0(const bool bit) { mus0_ = bit; } - void setMus1(const bool bit) { mus1_ = bit; } + void setOneNominalInTime(const bool bit) { oneNominalInTime_ = bit; } + void setOneTightInTime(const bool bit) { oneTightInTime_ = bit; } + void setMus0(const bool bit) { oneNominalInTime_ = bit; } + void setMus1(const bool bit) { oneTightInTime_ = bit; } void setMusOutOfTime0(const bool bit) { musOutOfTime0_ = bit; } void setMusOutOfTime1(const bool bit) { musOutOfTime1_ = bit; } - bool mus0() const { return mus0_; } - bool mus1() const { return mus1_; } + bool mus0() const { return oneNominalInTime_; } + bool mus1() const { return oneTightInTime_; } bool musOutOfTime0() const { return musOutOfTime0_; } bool musOutOfTime1() const { return musOutOfTime1_; } @@ -69,8 +71,8 @@ namespace l1t { // useful members for trigger performance studies // needed at startup Run-3 - bool isOneNominalInTime() const { return mus0_; } - bool isOneTightInTime() const { return mus1_; } + bool isOneNominalInTime() const { return oneNominalInTime_; } + bool isOneTightInTime() const { return oneTightInTime_; } // to be developed during Run-3 bool isTwoLooseInTime() const { return false; } // these options require more study @@ -84,8 +86,8 @@ namespace l1t { private: // Run-3 definitions as provided in DN-20-033 // in time and out-of-time qualities. only 2 bits each. - bool mus0_; - bool mus1_; + bool oneNominalInTime_; + bool oneTightInTime_; bool musOutOfTime0_; bool musOutOfTime1_; }; diff --git a/DataFormats/L1Trigger/interface/RegionalOutput.h b/DataFormats/L1Trigger/interface/RegionalOutput.h new file mode 100644 index 0000000000000..612a4bd7e7e4d --- /dev/null +++ b/DataFormats/L1Trigger/interface/RegionalOutput.h @@ -0,0 +1,149 @@ +#ifndef DataFormats_L1Trigger_RegionalOutput_h +#define DataFormats_L1Trigger_RegionalOutput_h + +#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" +#include "DataFormats/Common/interface/RefProd.h" +#include "DataFormats/Common/interface/Ref.h" +#include + +namespace l1t { + template + class RegionalOutput { + public: + typedef typename T::value_type value_type; + typedef edm::Ref ref; + typedef edm::RefProd refprod; + + class iterator { + public: + typedef typename T::value_type value_type; + typedef ptrdiff_t difference_type; + iterator(const RegionalOutput& src, unsigned int idx) : src_(&src), idx_(idx) {} + iterator(iterator const& it) : src_(it.src_), idx_(it.idx_) {} + iterator() : src_(nullptr), idx_(0) {} + iterator& operator++() { + ++idx_; + return *this; + } + iterator operator++(int) { + iterator ci = *this; + ++idx_; + return ci; + } + iterator& operator--() { + --idx_; + return *this; + } + iterator operator--(int) { + iterator ci = *this; + --idx_; + return ci; + } + difference_type operator-(iterator const& o) const { return idx_ - o.idx_; } + iterator operator+(difference_type n) const { return iterator(src_, idx_ + n); } + iterator operator-(difference_type n) const { return iterator(src_, idx_ - n); } + bool operator<(iterator const& o) const { return idx_ < o.idx_; } + bool operator==(iterator const& ci) const { return idx_ == ci.idx_; } + bool operator!=(iterator const& ci) const { return idx_ != ci.idx_; } + value_type const& operator*() const { return src_->objAt(idx_); } + value_type const* operator->() const { return &src_->objAt(idx_); } + iterator& operator+=(difference_type d) { + idx_ += d; + return *this; + } + iterator& operator-=(difference_type d) { + idx_ -= d; + return *this; + } + value_type const& operator[](difference_type d) const { return src_->objAt(idx_ + d); } + // interface to get EDM refs & related stuff + edm::Ref ref() const { return src_->refAt(idx_); } + edm::ProductID id() const { return src_->id(); } + unsigned int idx() const { return idx_; } + unsigned int key() const { return idx_; } + + private: + const RegionalOutput* src_; + unsigned int idx_; + }; + typedef iterator const_iterator; + + class Region { + public: + typedef typename T::value_type value_type; + typedef typename RegionalOutput::iterator iterator; + typedef typename RegionalOutput::const_iterator const_iterator; + + const value_type& operator[](unsigned int idx) const { return src_->objAt(ibegin_ + idx); } + const value_type& front() const { return src_->objAt(ibegin_); } + const value_type& back() const { return src_->objAt(iend_ - 1); } + iterator begin() const { return iterator(*src_, ibegin_); } + iterator end() const { return iterator(*src_, iend_); } + unsigned int size() const { return iend_ - ibegin_; } + bool empty() const { return (iend_ == ibegin_); } + // interface to get EDM refs & related stuff + ref refAt(unsigned int idx) const { return src_->refAt(ibegin_ + idx); } + edm::ProductID id() const { return src_->id(); } + + private: + const RegionalOutput* src_; + unsigned int ibegin_, iend_; + friend class RegionalOutput; + Region(const RegionalOutput* src, unsigned int ibegin, unsigned int iend) + : src_(src), ibegin_(ibegin), iend_(iend) {} + }; + + RegionalOutput() : refprod_(), values_(), regions_(), etas_(), phis_() {} + RegionalOutput(const edm::RefProd& prod) : refprod_(prod), values_(), regions_(), etas_(), phis_() {} + + void addRegion(const std::vector& indices, const float eta, const float phi) { + regions_.emplace_back((regions_.empty() ? 0 : regions_.back()) + indices.size()); + values_.insert(values_.end(), indices.begin(), indices.end()); + etas_.push_back(eta); + phis_.push_back(phi); + } + + edm::ProductID id() const { return refprod_.id(); } + unsigned int size() const { return values_.size(); } + unsigned int nRegions() const { return regions_.size(); } + bool empty() const { return values_.empty(); } + void clear() { + values_.clear(); + regions_.clear(); + etas_.clear(); + phis_.clear(); + } + void shrink_to_fit() { + values_.shrink_to_fit(); + regions_.shrink_to_fit(); + etas_.shrink_to_fit(); + phis_.shrink_to_fit(); + } + + const_iterator begin() const { return const_iterator(this, 0); } + const_iterator end() const { return const_iterator(this, values_.size()); } + + Region region(unsigned int ireg) const { + if (ireg >= regions_.size()) + throw cms::Exception("Region index out of bounds"); + return Region(this, ireg == 0 ? 0 : regions_[ireg - 1], regions_[ireg]); + } + + const float eta(unsigned int ireg) const { return etas_[ireg]; } + const float phi(unsigned int ireg) const { return phis_[ireg]; } + + ref refAt(unsigned int idx) const { return ref(refprod_, values_[idx]); } + const value_type& objAt(unsigned int idx) const { return (*refprod_)[values_[idx]]; } + + //Used by ROOT storage + CMS_CLASS_VERSION(3) + + protected: + refprod refprod_; + std::vector values_; // list of indices to objects in each region, flattened. + std::vector regions_; // for each region, store the index of one-past the last object in values + std::vector etas_; // floatEtaCenter of each PFregion + std::vector phis_; // floatPhiCenter of each PFregion + }; +} // namespace l1t +#endif diff --git a/DataFormats/L1Trigger/interface/TkJetWord.h b/DataFormats/L1Trigger/interface/TkJetWord.h new file mode 100644 index 0000000000000..2813b8728f4f9 --- /dev/null +++ b/DataFormats/L1Trigger/interface/TkJetWord.h @@ -0,0 +1,178 @@ +#ifndef FIRMWARE_TkJetWord_h +#define FIRMWARE_TkJetWord_h + +#include +#include +#include +#include +#include +#include + +namespace l1t { + + class TkJetWord { + public: + // ----------constants, enums and typedefs --------- + int INTPHI_PI = 720; + int INTPHI_TWOPI = 2 * INTPHI_PI; + float INTPT_LSB = 1 >> 5; + float ETAPHI_LSB = M_PI / (1 << 12); + float Z0_LSB = 0.05; + + enum TkJetBitWidths { + kPtSize = 16, + kPtMagSize = 11, + kGlbEtaSize = 14, + kGlbPhiSize = 13, + kZ0Size = 10, + kNtSize = 5, + kXtSize = 4, + kUnassignedSize = 8, + kTkJetWordSize = kPtSize + kGlbEtaSize + kGlbPhiSize + kZ0Size + kNtSize + kXtSize + kUnassignedSize, + }; + + enum TkJetBitLocations { + kPtLSB = 0, + kPtMSB = kPtLSB + TkJetBitWidths::kPtSize - 1, + kGlbEtaLSB = kPtMSB + 1, + kGlbEtaMSB = kGlbEtaLSB + TkJetBitWidths::kGlbEtaSize - 1, + kGlbPhiLSB = kGlbEtaMSB + 1, + kGlbPhiMSB = kGlbPhiLSB + TkJetBitWidths::kGlbPhiSize - 1, + kZ0LSB = kGlbPhiMSB + 1, + kZ0MSB = kZ0LSB + TkJetBitWidths::kZ0Size - 1, + kNtLSB = kZ0MSB + 1, + kNtMSB = kNtLSB + TkJetBitWidths::kNtSize - 1, + kXtLSB = kNtMSB + 1, + kXtMSB = kXtLSB + TkJetBitWidths::kXtSize - 1, + kUnassignedLSB = kXtMSB + 1, + kUnassignedMSB = kUnassignedLSB + TkJetBitWidths::kUnassignedSize - 1, + }; + + typedef ap_ufixed pt_t; + typedef ap_int glbeta_t; + typedef ap_int glbphi_t; + typedef ap_int z0_t; // 40cm / 0.1 + typedef ap_uint nt_t; //number of tracks + typedef ap_uint nx_t; //number of tracks with xbit = 1 + typedef ap_uint tkjetunassigned_t; // Unassigned bits + typedef std::bitset tkjetword_bs_t; + typedef ap_uint tkjetword_t; + + public: + // ----------Constructors -------------------------- + TkJetWord() {} + TkJetWord(pt_t pt, glbeta_t eta, glbphi_t phi, z0_t z0, nt_t nt, nx_t nx, tkjetunassigned_t unassigned) { + std::string word = ""; + word.append(TkJetBitWidths::kUnassignedSize - (unassigned.to_string().length() - 2), '0'); + word = word + (unassigned.to_string().substr(2, unassigned.to_string().length() - 2)); + word.append(TkJetBitWidths::kXtSize - (nx.to_string().length() - 2), '0'); + word = word + (nx.to_string().substr(2, nx.to_string().length() - 2)); + word.append(TkJetBitWidths::kNtSize - (nt.to_string().length() - 2), '0'); + word = word + (nt.to_string().substr(2, nt.to_string().length() - 2)); + word.append(TkJetBitWidths::kZ0Size - (z0.to_string().length() - 2), '0'); + word = word + (z0.to_string().substr(2, z0.to_string().length() - 2)); + word.append(TkJetBitWidths::kGlbPhiSize - (phi.to_string().length() - 2), '0'); + word = word + (phi.to_string().substr(2, phi.to_string().length() - 2)); + word.append(TkJetBitWidths::kGlbEtaSize - (eta.to_string().length() - 2), '0'); + word = word + (eta.to_string().substr(2, eta.to_string().length() - 2)); + ap_ufixed pt_2 = pt; + ap_uint pt_temp = pt_2 << 5; + word.append(TkJetBitWidths::kPtSize - (pt_temp.to_string().length() - 2), '0'); + word = word + (pt_temp.to_string().substr(2, pt_temp.to_string().length() - 2)); + + tkjetword_bs_t tmp(word); + tkJetWord_ = tmp; + } + + ~TkJetWord() {} + + // ----------copy constructor ---------------------- + TkJetWord(const TkJetWord& word) { tkJetWord_ = word.tkJetWord_; } + + // ----------operators ----------------------------- + TkJetWord& operator=(const TkJetWord& word) { + tkJetWord_ = word.tkJetWord_; + return *this; + } + + // ----------member functions (getters) ------------ + // These functions return arbitarary precision words (lists of bits) for each quantity + pt_t ptWord() const { + pt_t ret; + ret.V = tkJetWord()(TkJetBitLocations::kPtMSB, TkJetBitLocations::kPtLSB); + return ret; + } + glbeta_t glbEtaWord() const { + glbeta_t ret; + ret.V = tkJetWord()(TkJetBitLocations::kGlbEtaMSB, TkJetBitLocations::kGlbEtaLSB); + return ret; + } + glbphi_t glbPhiWord() const { + glbphi_t ret; + ret.V = tkJetWord()(TkJetBitLocations::kGlbPhiMSB, TkJetBitLocations::kGlbPhiLSB); + return ret; + } + z0_t z0Word() const { + z0_t ret; + ret.V = tkJetWord()(TkJetBitLocations::kZ0MSB, TkJetBitLocations::kZ0LSB); + return ret; + } + nt_t ntWord() const { + nt_t ret; + ret.V = tkJetWord()(TkJetBitLocations::kNtMSB, TkJetBitLocations::kNtLSB); + return ret; + } + nx_t xtWord() const { + nx_t ret; + ret.V = tkJetWord()(TkJetBitLocations::kXtMSB, TkJetBitLocations::kXtLSB); + return ret; + } + tkjetunassigned_t unassignedWord() const { + return tkJetWord()(TkJetBitLocations::kUnassignedMSB, TkJetBitLocations::kUnassignedLSB); + } + tkjetword_t tkJetWord() const { return tkjetword_t(tkJetWord_.to_string().c_str(), 2); } + + // These functions return the packed bits in integer format for each quantity + // Signed quantities have the sign enconded in the left-most bit. + unsigned int ptBits() const { return ptWord().to_uint(); } + unsigned int glbEtaBits() const { return glbEtaWord().to_uint(); } + unsigned int glbPhiBits() const { return glbPhiWord().to_uint(); } + unsigned int z0Bits() const { return z0Word().to_uint(); } + unsigned int ntBits() const { return ntWord().to_uint(); } + unsigned int xtBits() const { return xtWord().to_uint(); } + unsigned int unassignedBits() const { return unassignedWord().to_uint(); } + + // These functions return the unpacked and converted values + // These functions return real numbers converted from the digitized quantities by unpacking the 64-bit vertex word + float pt() const { return ptWord().to_float(); } + float glbeta() const { return glbEtaWord().to_float() * ETAPHI_LSB; } + float glbphi() const { return glbPhiWord().to_float() * ETAPHI_LSB; } + float z0() const { return z0Word().to_float() * Z0_LSB; } + int nt() const { return (ap_ufixed(ntWord())).to_int(); } + int xt() const { return (ap_ufixed(xtWord())).to_int(); } + unsigned int unassigned() const { return unassignedWord().to_uint(); } + + // ----------member functions (setters) ------------ + void setTkJetWord(pt_t pt, glbeta_t eta, glbphi_t phi, z0_t z0, nt_t nt, nx_t nx, tkjetunassigned_t unassigned); + + private: + // ----------private member functions -------------- + double unpackSignedValue(unsigned int bits, unsigned int nBits, double lsb) const { + int isign = 1; + unsigned int digitized_maximum = (1 << nBits) - 1; + if (bits & (1 << (nBits - 1))) { // check the sign + isign = -1; + bits = (1 << (nBits + 1)) - bits; // if negative, flip everything for two's complement encoding + } + return (double(bits & digitized_maximum) + 0.5) * lsb * isign; + } + + // ----------member data --------------------------- + tkjetword_bs_t tkJetWord_; + }; + + typedef std::vector TkJetWordCollection; + +} // namespace l1t + +#endif diff --git a/DataFormats/L1Trigger/interface/Vertex.h b/DataFormats/L1Trigger/interface/Vertex.h index dee272c48c7fd..d26e1a02ac4aa 100644 --- a/DataFormats/L1Trigger/interface/Vertex.h +++ b/DataFormats/L1Trigger/interface/Vertex.h @@ -9,21 +9,18 @@ namespace l1t { - class Vertex; - typedef std::vector VertexCollection; - class Vertex { public: typedef TTTrack Track_t; - Vertex(); - Vertex(float pt, float z0, const std::vector>& tracks); - ~Vertex(); + Vertex() : pt_(0.0), z0_(0.0) {} + Vertex(float pt, float z0, const std::vector>& tracks) : pt_(pt), z0_(z0), tracks_(tracks) {} + ~Vertex() {} - float pt() const; - float z0() const; + float pt() const { return pt_; } + float z0() const { return z0_; } - const std::vector>& tracks() const; + const std::vector>& tracks() const { return tracks_; } private: float pt_; @@ -31,6 +28,8 @@ namespace l1t { std::vector> tracks_; }; + typedef std::vector VertexCollection; + } // namespace l1t #endif diff --git a/DataFormats/L1Trigger/interface/VertexWord.h b/DataFormats/L1Trigger/interface/VertexWord.h new file mode 100644 index 0000000000000..ec8a6ecab4495 --- /dev/null +++ b/DataFormats/L1Trigger/interface/VertexWord.h @@ -0,0 +1,199 @@ +#ifndef DataFormats_L1TVertex_VertexWord_h +#define DataFormats_L1TVertex_VertexWord_h + +//////// +// +// class to store the 96-bit track word produced by the L1 Track Trigger. Intended to be inherited by L1 TTTrack. +// packing scheme given below. +// +// author: Alexx Perloff +// created: March 17, 2021 +// +/////// + +#include "DataFormats/L1Trigger/interface/Vertex.h" + +#include +#include + +#include +#include + +namespace l1t { + + class VertexWord { + public: + // ----------constants, enums and typedefs --------- + enum VertexBitWidths { + // The sizes of the vertex word components and total word size + kValidSize = 1, // Width of the valid bit + kZ0Size = 15, // Width of z-position + kZ0MagSize = 6, // Width of z-position magnitude (signed) + kNTrackInPVSize = 8, // Width of the multiplicity in the PV (unsigned) + kSumPtSize = 10, // Width of pT + kSumPtMagSize = 8, // Width of pT magnitude (unsigned) + kQualitySize = 3, // Width of the quality field + kNTrackOutPVSize = 10, // Width of the multiplicity outside the PV (unsigned) + kUnassignedSize = 17, // Width of the unassigned bits + + kVertexWordSize = kValidSize + kZ0Size + kNTrackInPVSize + kSumPtSize + kQualitySize + kNTrackOutPVSize + + kUnassignedSize, // Width of the vertex word in bits + }; + + enum VertexBitLocations { + // The location of the least significant bit (LSB) and most significant bit (MSB) in the vertex word for different fields + kValidLSB = 0, + kValidMSB = kValidLSB + VertexBitWidths::kValidSize - 1, + kZ0LSB = kValidMSB + 1, + kZ0MSB = kZ0LSB + VertexBitWidths::kZ0Size - 1, + kNTrackInPVLSB = kZ0MSB + 1, + kNTrackInPVMSB = kNTrackInPVLSB + VertexBitWidths::kNTrackInPVSize - 1, + kSumPtLSB = kNTrackInPVMSB + 1, + kSumPtMSB = kSumPtLSB + VertexBitWidths::kSumPtSize - 1, + kQualityLSB = kSumPtMSB + 1, + kQualityMSB = kQualityLSB + VertexBitWidths::kQualitySize - 1, + kNTrackOutPVLSB = kQualityMSB + 1, + kNTrackOutPVMSB = kNTrackOutPVLSB + VertexBitWidths::kNTrackOutPVSize - 1, + kUnassignedLSB = kNTrackOutPVMSB + 1, + kUnassignedMSB = kUnassignedLSB + VertexBitWidths::kUnassignedSize - 1 + }; + + // vertex parameters types + typedef ap_uint vtxvalid_t; // Vertex validity + typedef ap_fixed vtxz0_t; // Vertex z0 + typedef ap_ufixed + vtxmultiplicity_t; // NTracks in vertex + typedef ap_ufixed + vtxsumpt_t; // Vertex Sum pT + typedef ap_uint vtxquality_t; // Vertex quality + typedef ap_ufixed + vtxinversemult_t; // NTracks outside vertex + typedef ap_uint vtxunassigned_t; // Unassigned bits + + // vertex word types + typedef std::bitset vtxword_bs_t; // Entire track word; + typedef ap_uint vtxword_t; // Entire vertex word; + + // reference types + typedef edm::Ref VertexRef; // Reference to a persistent l1t::Vertex + + public: + // ----------Constructors -------------------------- + VertexWord() {} + VertexWord(unsigned int valid, + double z0, + unsigned int multiplicity, + double pt, + unsigned int quality, + unsigned int inverseMultiplicity, + unsigned int unassigned); + VertexWord(unsigned int valid, + unsigned int z0, + unsigned int multiplicity, + unsigned int pt, + unsigned int quality, + unsigned int inverseMultiplicity, + unsigned int unassigned); + VertexWord(vtxvalid_t valid, + vtxz0_t z0, + vtxmultiplicity_t multiplicity, + vtxsumpt_t pt, + vtxquality_t quality, + vtxinversemult_t inverseMultiplicity, + vtxunassigned_t unassigned); + + ~VertexWord() {} + + // ----------copy constructor ---------------------- + VertexWord(const VertexWord& word) { vertexWord_ = word.vertexWord_; } + + // ----------operators ----------------------------- + VertexWord& operator=(const VertexWord& word) { + vertexWord_ = word.vertexWord_; + return *this; + } + + // ----------member functions (getters) ------------ + // These functions return arbitarary precision words (lists of bits) for each quantity + vtxvalid_t validWord() const { return vertexWord()(VertexBitLocations::kValidMSB, VertexBitLocations::kValidLSB); } + vtxz0_t z0Word() const { + vtxz0_t ret; + ret.V = vertexWord()(VertexBitLocations::kZ0MSB, VertexBitLocations::kZ0LSB); + return ret; + } + vtxmultiplicity_t multiplicityWord() const { + return vertexWord()(VertexBitLocations::kNTrackInPVMSB, VertexBitLocations::kNTrackInPVLSB); + } + vtxsumpt_t ptWord() const { + vtxsumpt_t ret; + ret.V = vertexWord()(VertexBitLocations::kSumPtMSB, VertexBitLocations::kSumPtLSB); + return ret; + } + vtxquality_t qualityWord() const { + return vertexWord()(VertexBitLocations::kQualityMSB, VertexBitLocations::kQualityLSB); + } + vtxinversemult_t inverseMultiplicityWord() const { + return vertexWord()(VertexBitLocations::kNTrackOutPVMSB, VertexBitLocations::kNTrackOutPVLSB); + } + vtxunassigned_t unassignedWord() const { + return vertexWord()(VertexBitLocations::kUnassignedMSB, VertexBitLocations::kUnassignedLSB); + } + vtxword_t vertexWord() const { return vtxword_t(vertexWord_.to_string().c_str(), 2); } + + // These functions return the packed bits in integer format for each quantity + // Signed quantities have the sign enconded in the left-most bit. + unsigned int validBits() const { return validWord().to_uint(); } + unsigned int z0Bits() const { return z0Word().to_uint(); } + unsigned int multiplicityBits() const { return multiplicityWord().to_uint(); } + unsigned int ptBits() const { return ptWord().to_uint(); } + unsigned int qualityBits() const { return qualityWord().to_uint(); } + unsigned int inverseMultiplicityBits() const { return inverseMultiplicityWord().to_uint(); } + unsigned int unassignedBits() const { return unassignedWord().to_uint(); } + + // These functions return the unpacked and converted values + // These functions return real numbers converted from the digitized quantities by unpacking the 64-bit vertex word + bool valid() const { return validWord().to_bool(); } + double z0() const { return z0Word().to_double(); } + unsigned int multiplicity() const { return multiplicityWord().to_uint(); } + double pt() const { return ptWord().to_double(); } + unsigned int quality() const { return qualityWord().to_uint(); } + unsigned int inverseMultiplicity() const { return inverseMultiplicityWord().to_uint(); } + unsigned int unassigned() const { return unassignedWord().to_uint(); } + + // return reference to floating point vertex + VertexRef vertexRef() const { return vertexRef_; } + + // ----------member functions (setters) ------------ + void setVertexWord(vtxvalid_t valid, + vtxz0_t z0, + vtxmultiplicity_t multiplicity, + vtxsumpt_t pt, + vtxquality_t quality, + vtxinversemult_t inverseMultiplicity, + vtxunassigned_t unassigned); + + // set reference to floating point vertex + void setVertexRef(const VertexRef& ref) { vertexRef_ = ref; } + + private: + // ----------private member functions -------------- + double unpackSignedValue(unsigned int bits, unsigned int nBits, double lsb) const { + int isign = 1; + unsigned int digitized_maximum = (1 << nBits) - 1; + if (bits & (1 << (nBits - 1))) { // check the sign + isign = -1; + bits = (1 << (nBits + 1)) - bits; // if negative, flip everything for two's complement encoding + } + return (double(bits & digitized_maximum) + 0.5) * lsb * isign; + } + + // ----------member data --------------------------- + vtxword_bs_t vertexWord_; + VertexRef vertexRef_; + }; + + typedef std::vector VertexWordCollection; + typedef edm::Ref VertexWordRef; +} // namespace l1t + +#endif diff --git a/DataFormats/L1Trigger/src/MuonShower.cc b/DataFormats/L1Trigger/src/MuonShower.cc index 123363221b79e..f80cf8763c7f8 100644 --- a/DataFormats/L1Trigger/src/MuonShower.cc +++ b/DataFormats/L1Trigger/src/MuonShower.cc @@ -9,16 +9,18 @@ l1t::MuonShower::MuonShower(bool oneNominalInTime, : L1Candidate(math::PtEtaPhiMLorentzVector{0., 0., 0., 0.}, 0., 0., 0., 0, 0), // in this object it makes more sense to the different shower types to // the 4 bits, so that the object easily interfaces with the uGT emulator - mus0_(oneNominalInTime), - mus1_(oneTightInTime), + oneNominalInTime_(oneNominalInTime), + oneTightInTime_(oneTightInTime), musOutOfTime0_(false), musOutOfTime1_(false) {} l1t::MuonShower::~MuonShower() {} -bool l1t::MuonShower::isValid() const { return mus0_ or mus1_ or musOutOfTime0_ or musOutOfTime1_; } +bool l1t::MuonShower::isValid() const { + return oneNominalInTime_ or oneTightInTime_ or musOutOfTime0_ or musOutOfTime1_; +} bool l1t::MuonShower::operator==(const l1t::MuonShower& rhs) const { - return (mus0_ == rhs.mus0() and mus1_ == rhs.mus1() and musOutOfTime0_ == rhs.musOutOfTime0() and - musOutOfTime1_ == rhs.musOutOfTime1()); + return (oneNominalInTime_ == rhs.isOneNominalInTime() and oneTightInTime_ == rhs.isOneTightInTime() and + musOutOfTime0_ == rhs.musOutOfTime0() and musOutOfTime1_ == rhs.musOutOfTime1()); } diff --git a/DataFormats/L1Trigger/src/Vertex.cc b/DataFormats/L1Trigger/src/Vertex.cc deleted file mode 100644 index 8ec64092a8742..0000000000000 --- a/DataFormats/L1Trigger/src/Vertex.cc +++ /dev/null @@ -1,18 +0,0 @@ -#include "DataFormats/L1Trigger/interface/Vertex.h" - -namespace l1t { - - Vertex::Vertex() : pt_(0.0), z0_(0.0) {} - - Vertex::Vertex(float pt, float z0, const std::vector>& tracks) - : pt_(pt), z0_(z0), tracks_(tracks) {} - - Vertex::~Vertex() {} - - float Vertex::pt() const { return pt_; } - - float Vertex::z0() const { return z0_; } - - const std::vector>& Vertex::tracks() const { return tracks_; } - -} // namespace l1t diff --git a/DataFormats/L1Trigger/src/VertexWord.cc b/DataFormats/L1Trigger/src/VertexWord.cc new file mode 100644 index 0000000000000..ff79288007965 --- /dev/null +++ b/DataFormats/L1Trigger/src/VertexWord.cc @@ -0,0 +1,104 @@ +//////// +// +// class to store the 96-bit track word produced by the L1 Track Trigger. Intended to be inherited by L1 TTTrack. +// packing scheme given below. +// +// author: Alexx Perloff +// created: March 17, 2021 +// +/////// + +#include "DataFormats/L1Trigger/interface/VertexWord.h" + +namespace l1t { + + VertexWord::VertexWord(unsigned int valid, + double z0, + unsigned int multiplicity, + double pt, + unsigned int quality, + unsigned int inverseMultiplicity, + unsigned int unassigned) { + // convert directly to AP types + vtxvalid_t valid_ap = valid; + vtxz0_t z0_ap = z0; + vtxmultiplicity_t mult_ap = multiplicity; + vtxsumpt_t pt_ap = pt; + vtxquality_t quality_ap = quality; + vtxinversemult_t invmult_ap = inverseMultiplicity; + vtxunassigned_t unassigned_ap = unassigned; + + setVertexWord(valid_ap, z0_ap, mult_ap, pt_ap, quality_ap, invmult_ap, unassigned_ap); + } + + VertexWord::VertexWord(unsigned int valid, + unsigned int z0, + unsigned int multiplicity, + unsigned int pt, + unsigned int quality, + unsigned int inverseMultiplicity, + unsigned int unassigned) { + // convert to AP types + vtxvalid_t valid_ap = valid; + vtxz0_t z0_ap = unpackSignedValue( + z0, VertexBitWidths::kZ0Size, 1.0 / (1 << (VertexBitWidths::kZ0Size - VertexBitWidths::kZ0MagSize))); + vtxmultiplicity_t mult_ap = multiplicity; + vtxsumpt_t pt_ap = unpackSignedValue( + z0, VertexBitWidths::kSumPtSize, 1.0 / (1 << (VertexBitWidths::kSumPtSize - VertexBitWidths::kSumPtMagSize))); + vtxquality_t quality_ap = quality; + vtxinversemult_t invmult_ap = inverseMultiplicity; + vtxunassigned_t unassigned_ap = unassigned; + + setVertexWord(valid_ap, z0_ap, mult_ap, pt_ap, quality_ap, invmult_ap, unassigned_ap); + } + + VertexWord::VertexWord(vtxvalid_t valid, + vtxz0_t z0, + vtxmultiplicity_t multiplicity, + vtxsumpt_t pt, + vtxquality_t quality, + vtxinversemult_t inverseMultiplicity, + vtxunassigned_t unassigned) { + setVertexWord(valid, z0, multiplicity, pt, quality, inverseMultiplicity, unassigned); + } + + void VertexWord::setVertexWord(vtxvalid_t valid, + vtxz0_t z0, + vtxmultiplicity_t multiplicity, + vtxsumpt_t pt, + vtxquality_t quality, + vtxinversemult_t inverseMultiplicity, + vtxunassigned_t unassigned) { + // pack the vertex word + unsigned int offset = 0; + for (unsigned int b = offset; b < (offset + VertexBitWidths::kValidSize); b++) { + vertexWord_.set(b, valid[b - offset]); + } + offset += VertexBitWidths::kValidSize; + for (unsigned int b = offset; b < (offset + VertexBitWidths::kZ0Size); b++) { + vertexWord_.set(b, z0[b - offset]); + } + offset += VertexBitWidths::kZ0Size; + + for (unsigned int b = offset; b < (offset + VertexBitWidths::kNTrackInPVSize); b++) { + vertexWord_.set(b, multiplicity[b - offset]); + } + offset += VertexBitWidths::kNTrackInPVSize; + for (unsigned int b = offset; b < (offset + VertexBitWidths::kSumPtSize); b++) { + vertexWord_.set(b, pt[b - offset]); + } + offset += VertexBitWidths::kSumPtSize; + for (unsigned int b = offset; b < (offset + VertexBitWidths::kQualitySize); b++) { + vertexWord_.set(b, quality[b - offset]); + } + offset += VertexBitWidths::kQualitySize; + for (unsigned int b = offset; b < (offset + VertexBitWidths::kNTrackOutPVSize); b++) { + vertexWord_.set(b, inverseMultiplicity[b - offset]); + } + offset += VertexBitWidths::kNTrackOutPVSize; + for (unsigned int b = offset; b < (offset + VertexBitWidths::kUnassignedSize); b++) { + vertexWord_.set(b, unassigned[b - offset]); + } + } + +} // namespace l1t \ No newline at end of file diff --git a/DataFormats/L1Trigger/src/classes.h b/DataFormats/L1Trigger/src/classes.h index 173991dc77bb1..b36258e5029b9 100644 --- a/DataFormats/L1Trigger/src/classes.h +++ b/DataFormats/L1Trigger/src/classes.h @@ -33,3 +33,9 @@ #include "DataFormats/L1Trigger/interface/HOTwinMuxDigiCollection.h" #include "DataFormats/L1Trigger/interface/HOTPDigiTwinMux.h" #include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" +#include "DataFormats/L1Trigger/interface/TkJetWord.h" +#include "DataFormats/Common/interface/RefToBase.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" diff --git a/DataFormats/L1Trigger/src/classes_def.xml b/DataFormats/L1Trigger/src/classes_def.xml index b639135a3e1f6..045c3669354b9 100644 --- a/DataFormats/L1Trigger/src/classes_def.xml +++ b/DataFormats/L1Trigger/src/classes_def.xml @@ -103,7 +103,8 @@ - + + @@ -286,5 +287,21 @@ + + + + + + + + + + + + + + + + diff --git a/DataFormats/TCDS/interface/TCDSRecord.h b/DataFormats/TCDS/interface/TCDSRecord.h index 8536f763849fa..d10a16ec6ddd4 100644 --- a/DataFormats/TCDS/interface/TCDSRecord.h +++ b/DataFormats/TCDS/interface/TCDSRecord.h @@ -99,9 +99,6 @@ class TCDSRecord { // The BST message as received from the LHC const BSTRecord& getBST() const { return bst_; } - // Source FED ID - uint16_t getSourceID() const { return sourceid_; } - // List of active paritions, currently not implemented typedef std::bitset<96> ActivePartitions; ActivePartitions getActivePartitions() const { return activePartitions_; } @@ -149,7 +146,6 @@ class TCDSRecord { uint16_t triggerTypeFlags_; uint16_t inputs_; uint16_t bxid_; - uint16_t sourceid_; ActivePartitions activePartitions_; L1aHistory l1aHistory_; diff --git a/DataFormats/TCDS/src/TCDSRecord.cc b/DataFormats/TCDS/src/TCDSRecord.cc index 5e1b324d719c1..98179b0c15c87 100644 --- a/DataFormats/TCDS/src/TCDSRecord.cc +++ b/DataFormats/TCDS/src/TCDSRecord.cc @@ -42,7 +42,6 @@ TCDSRecord::TCDSRecord(const unsigned char* rawData) { triggerTypeFlags_ = tcdsRaw->header.triggerTypeFlags; inputs_ = tcdsRaw->header.inputs; bxid_ = tcdsRaw->header.bxid; - sourceid_ = fedHeader.sourceID(); activePartitions_ = ActivePartitions(tcdsRaw->header.activePartitions0); activePartitions_ |= ActivePartitions(tcdsRaw->header.activePartitions1) << 32; diff --git a/DataFormats/TCDS/src/classes_def.xml b/DataFormats/TCDS/src/classes_def.xml index 01f0ec37efcf4..b49fe697bb2d0 100644 --- a/DataFormats/TCDS/src/classes_def.xml +++ b/DataFormats/TCDS/src/classes_def.xml @@ -8,8 +8,7 @@ - - + diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.cc index facab356f553e..c033551330b57 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.cc @@ -6,13 +6,14 @@ namespace l1t { namespace stage2 { GTCollections::~GTCollections() { event_.put(std::move(muons_[0]), "Muon"); + event_.put(std::move(muonShowers_[0]), "MuonShower"); event_.put(std::move(egammas_[0]), "EGamma"); event_.put(std::move(etsums_[0]), "EtSum"); event_.put(std::move(jets_[0]), "Jet"); event_.put(std::move(taus_[0]), "Tau"); - for (int i = 1; i < 6; ++i) { event_.put(std::move(muons_[i]), "Muon" + std::to_string(i + 1)); + event_.put(std::move(muonShowers_[i]), "MuonShower" + std::to_string(i + 1)); event_.put(std::move(egammas_[i]), "EGamma" + std::to_string(i + 1)); event_.put(std::move(etsums_[i]), "EtSum" + std::to_string(i + 1)); event_.put(std::move(jets_[i]), "Jet" + std::to_string(i + 1)); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.h index ae71bdb65724f..36dcba98f2507 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.h @@ -20,6 +20,8 @@ namespace l1t { GTCollections(edm::Event& e) : L1TObjectCollections(e), algBlk_(new GlobalAlgBlkBxCollection()), extBlk_(new GlobalExtBlkBxCollection()) { std::generate(muons_.begin(), muons_.end(), [] { return std::make_unique(); }); + std::generate( + muonShowers_.begin(), muonShowers_.end(), [] { return std::make_unique(); }); std::generate(egammas_.begin(), egammas_.end(), [] { return std::make_unique(); }); std::generate(etsums_.begin(), etsums_.end(), [] { return std::make_unique(); }); std::generate(jets_.begin(), jets_.end(), [] { return std::make_unique(); }); @@ -29,6 +31,9 @@ namespace l1t { ~GTCollections() override; inline MuonBxCollection* getMuons(const unsigned int copy) override { return muons_[copy].get(); }; + inline MuonShowerBxCollection* getMuonShowers(const unsigned int copy) override { + return muonShowers_[copy].get(); + }; inline EGammaBxCollection* getEGammas(const unsigned int copy) override { return egammas_[copy].get(); }; inline EtSumBxCollection* getEtSums(const unsigned int copy) override { return etsums_[copy].get(); }; inline JetBxCollection* getJets(const unsigned int copy) override { return jets_[copy].get(); }; @@ -39,6 +44,7 @@ namespace l1t { private: std::array, 6> muons_; + std::array, 6> muonShowers_; std::array, 6> egammas_; std::array, 6> etsums_; std::array, 6> jets_; diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc index 11b6aec6befd5..3e9e09097373a 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc @@ -21,6 +21,7 @@ namespace l1t { desc.addOptional("GtInputTag")->setComment("for stage2"); desc.addOptional("ExtInputTag")->setComment("for stage2"); desc.addOptional("MuonInputTag")->setComment("for stage2"); + desc.addOptional("ShowerInputTag")->setComment("for Run3"); desc.addOptional("EGammaInputTag")->setComment("for stage2"); desc.addOptional("JetInputTag")->setComment("for stage2"); desc.addOptional("TauInputTag")->setComment("for stage2"); @@ -50,6 +51,7 @@ namespace l1t { void GTSetup::registerProducts(edm::ProducesCollector prod) { prod.produces("Muon"); + prod.produces("MuonShower"); prod.produces("EGamma"); prod.produces("EtSum"); prod.produces("Jet"); @@ -58,6 +60,7 @@ namespace l1t { prod.produces(); for (int i = 2; i < 7; ++i) { // Collections from boards 2-6 prod.produces("Muon" + std::to_string(i)); + prod.produces("MuonShower" + std::to_string(i)); prod.produces("EGamma" + std::to_string(i)); prod.produces("EtSum" + std::to_string(i)); prod.produces("Jet" + std::to_string(i)); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTTokens.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTTokens.cc index 5cf3962495ee4..ed0460ee983f4 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTTokens.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTTokens.cc @@ -14,10 +14,12 @@ namespace l1t { auto tautag = cfg.getParameter("TauInputTag"); auto etsumtag = cfg.getParameter("EtSumInputTag"); auto muontag = cfg.getParameter("MuonInputTag"); + auto muonshowertag = cfg.getParameter("ShowerInputLabel"); //cout << "DEBUG: GmtInputTag" << muontag << "\n"; muonToken_ = cc.consumes(muontag); + muonShowerToken_ = cc.consumes(muonshowertag); egammaToken_ = cc.consumes(egammatag); etSumToken_ = cc.consumes(etsumtag); jetToken_ = cc.consumes(jettag); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc index 25c949d9b4c9f..adeb75f2628c0 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc @@ -9,7 +9,7 @@ namespace l1t { GMTOutputObjectMap gmtObjMap; std::pair muonBx = getMuons(gmtObjMap, event, static_cast(toks)->getMuonToken()); std::pair muonShowerBx{0, 0}; - if (fedId_ == 1402 && fwId_ >= 0x7000000) { + if ((fedId_ == 1402 && fwId_ >= 0x7000000) || (fedId_ == 1404 && fwId_ >= 0x00010f01)) { muonShowerBx = getMuonShowers(gmtObjMap, event, static_cast(toks)->getMuonShowerToken()); } diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc index 1c1b12021aa07..7f2c0125debba 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc @@ -8,7 +8,7 @@ namespace l1t { namespace stage2 { - MuonUnpacker::MuonUnpacker() : res_(nullptr), muonCopy_(0) {} + MuonUnpacker::MuonUnpacker() : muonCollection_(nullptr), muonShowerCollection_(nullptr), muonCopy_(0) {} bool MuonUnpacker::unpack(const Block& block, UnpackerCollections* coll) { LogDebug("L1T") << "Block ID = " << block.header().getID() << " size = " << block.header().getSize(); @@ -33,8 +33,12 @@ namespace l1t { getBXRange(nBX, firstBX, lastBX); // Set the muon collection and the BX range - res_ = static_cast(coll)->getMuons(muonCopy_); - res_->setBXRange(firstBX, lastBX); + muonCollection_ = static_cast(coll)->getMuons(muonCopy_); + muonCollection_->setBXRange(firstBX, lastBX); + // Set the muon shower collection and the BX range + muonShowerCollection_ = static_cast(coll)->getMuonShowers(muonCopy_); + muonShowerCollection_->setBXRange(firstBX, lastBX); + LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX; // Get the BX blocks and unpack them @@ -48,15 +52,48 @@ namespace l1t { << " in BX header is outside of the BX range [" << firstBX << "," << lastBX << "] defined in the block header."; } - unpackBx(bx, bxBlock.payload()); + unpackBx(bx, bxBlock.payload(), block.header().getID()); } return true; } - void MuonUnpacker::unpackBx(int bx, const std::vector& payload, unsigned int startIdx) { + void MuonUnpacker::unpackBx(int bx, + const std::vector& payload, + unsigned int blockID, + unsigned int startIdx) { unsigned int i = startIdx + 2; // Only words 2-5 are "standard" muon words. // Check if there are enough words left in the payload if (startIdx + nWords_ <= payload.size()) { + // Unpacking showers. + // The shower from uGMT is transmitted via four links, each link + // carrying on of the bits of the shower. We therefore have to + // determine which link we're looking at and act accordingly. + // Output links are odd and input links are even. + int link_offset{0}; // This is correct for the uGT unpacker + if (fed_ == 1402) { // For uGMT we have to adjust the block/link ID + link_offset = 1; + } + unsigned linkID{(blockID - link_offset) / 2}; + + // Try to get the shower for this BX and if it doesn't exist create an + // empty one and push it in. + // Note: We can't just create it for the first linkID, because in + // prinicple there could be a case where that is removed by the ZS. + MuonShower shower; + if (!muonShowerCollection_->isEmpty(bx)) { + shower = muonShowerCollection_->at(bx, 0); + muonShowerCollection_->erase(bx, 0); + } + if (linkID == 0) { // OneNominal shower + shower.setOneNominalInTime(l1t::MuonRawDigiTranslator::showerFired(payload[i + 1], fed_, getAlgoVersion())); + } else if (linkID == 1) { // OneTight shower + shower.setOneTightInTime(l1t::MuonRawDigiTranslator::showerFired(payload[i + 1], fed_, getAlgoVersion())); + } + + if (shower.isValid()) { + muonShowerCollection_->push_back(bx, shower); + } + for (unsigned nWord = 2; nWord < nWords_; nWord += 2) { // Only words 2-5 are "standard" muon words. uint32_t raw_data_spare = payload[startIdx + 1]; uint32_t raw_data_00_31 = payload[i++]; @@ -78,7 +115,7 @@ namespace l1t { << " iso " << mu.hwIso() << " qual " << mu.hwQual() << " charge " << mu.hwCharge() << " charge valid " << mu.hwChargeValid(); - res_->push_back(bx, mu); + muonCollection_->push_back(bx, mu); } } else { edm::LogWarning("L1T") << "Only " << payload.size() - i << " 32 bit words in this BX but " << nWords_ diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h index bd7ac0bc726cd..f3fe08696b497 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h @@ -24,11 +24,12 @@ namespace l1t { static constexpr unsigned nWords_ = 6; // every link transmits 6 words (3 muons) per bx static constexpr unsigned bxzs_enable_shift_ = 1; - MuonBxCollection* res_; + MuonBxCollection* muonCollection_; + MuonShowerBxCollection* muonShowerCollection_; int fed_; unsigned int muonCopy_; - void unpackBx(int bx, const std::vector& payload, unsigned int startIdx = 0); + void unpackBx(int bx, const std::vector& payload, unsigned int blockID, unsigned int startIdx = 0); }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py b/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py index 95f3bf6802068..e3d126d7ee523 100644 --- a/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py +++ b/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py @@ -7,6 +7,7 @@ GtInputTag = cms.InputTag("simGtStage2Digis"), ExtInputTag = cms.InputTag("simGtExtFakeStage2Digis"), MuonInputTag = cms.InputTag("simGmtStage2Digis"), + ShowerInputLabel = cms.InputTag("simGmtShowerDigis"), EGammaInputTag = cms.InputTag("simCaloStage2Digis"), TauInputTag = cms.InputTag("simCaloStage2Digis"), JetInputTag = cms.InputTag("simCaloStage2Digis"), @@ -31,4 +32,4 @@ ### Era: Run3_2021 from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 -stage2L1Trigger_2021.toModify(gtStage2Raw, FWId = cms.uint32(0x1130)) # FW w/ displaced muon info. +stage2L1Trigger_2021.toModify(gtStage2Raw, FWId = cms.uint32(0x10f01)) # FW w/ displaced muon info and hadronic showers. diff --git a/HLTrigger/Configuration/python/customizeHLTforCMSSW.py b/HLTrigger/Configuration/python/customizeHLTforCMSSW.py index a05857e3221b4..65698281d45c6 100644 --- a/HLTrigger/Configuration/python/customizeHLTforCMSSW.py +++ b/HLTrigger/Configuration/python/customizeHLTforCMSSW.py @@ -200,6 +200,36 @@ def customiseFor36459(process): return process +def customisePixelGainForRun2Input(process): + """Customise the HLT to run on Run 2 data/MC using the old definition of the pixel calibrations + Up to 11.0.x, the pixel calibarations were fully specified in the configuration: + VCaltoElectronGain = 47 + VCaltoElectronGain_L1 = 50 + VCaltoElectronOffset = -60 + VCaltoElectronOffset_L1 = -670 + Starting with 11.1.x, the calibrations for Run 3 were moved to the conditions, leaving in the configuration only: + VCaltoElectronGain = 1 + VCaltoElectronGain_L1 = 1 + VCaltoElectronOffset = 0 + VCaltoElectronOffset_L1 = 0 + Since the conditions for Run 2 have not been updated to the new scheme, the HLT configuration needs to be reverted. + """ + # revert the Pixel parameters to be compatible with the Run 2 conditions + for producer in producers_by_type(process, "SiPixelClusterProducer"): + producer.VCaltoElectronGain = 47 + producer.VCaltoElectronGain_L1 = 50 + producer.VCaltoElectronOffset = -60 + producer.VCaltoElectronOffset_L1 = -670 + + return process + + +def customiseFor2018Input(process): + """Customise the HLT to run on Run 2 data/MC""" + process = customisePixelGainForRun2Input(process) + process = synchronizeHCALHLTofflineRun3on2018data(process) + + # CMSSW version specific customizations def customizeHLTforCMSSW(process, menuType="GRun"): diff --git a/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h b/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h index b7b6dfe79a63d..789dd6c3c14f0 100644 --- a/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h +++ b/L1Trigger/CSCTriggerPrimitives/interface/CSCMotherboard.h @@ -158,6 +158,9 @@ class CSCMotherboard : public CSCBaseboard { */ std::vector preferred_bx_match_; + // Use the new patterns according to the comparator code format + bool use_run3_patterns_; + /** Default values of configuration parameters. */ static const unsigned int def_mpc_block_me1a; static const unsigned int def_alct_trig_enable, def_clct_trig_enable; diff --git a/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py b/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py index 4859ff3b4ef0b..70cc49a0a6ec2 100644 --- a/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py +++ b/L1Trigger/Configuration/python/L1Trigger_EventContent_cff.py @@ -176,46 +176,40 @@ def _appendPhase2Digis(obj): 'keep *_hgcalTowerMapProducer_*_*', 'keep *_hgcalTowerProducer_*_*', 'keep *_L1EGammaClusterEmuProducer_*_*', - 'keep *_l1EGammaEEProducer_*_*', - 'keep *_L1TkPrimaryVertex_*_*', - 'keep *_L1TkElectronsCrystal_*_*', - 'keep *_L1TkElectronsLooseCrystal_*_*', - 'keep *_L1TkElectronsEllipticMatchCrystal_*_*', - 'keep *_L1TkIsoElectronsCrystal_*_*', - 'keep *_L1TkPhotonsCrystal_*_*', - 'keep *_L1TkElectronsHGC_*_*', - 'keep *_L1TkElectronsEllipticMatchHGC_*_*', - 'keep *_L1TkIsoElectronsHGC_*_*', - 'keep *_L1TkPhotonsHGC_*_*', - 'keep *_L1TkMuons_*_*', + 'keep *_L1VertexFinder_*_*', + 'keep *_L1VertexFinderEmulator_*_*', + 'keep *_L1TowerCalibration_*_*', + 'keep *_L1CaloJet_*_*', + 'keep *_L1CaloJetHTT_*_*', 'keep *_pfClustersFromL1EGClusters_*_*', 'keep *_pfClustersFromCombinedCaloHCal_*_*', 'keep *_pfClustersFromCombinedCaloHF_*_*', 'keep *_pfClustersFromHGC3DClusters_*_*', 'keep *_pfTracksFromL1TracksBarrel_*_*', - 'keep *_l1pfProducerBarrel_*_*', 'keep *_pfTracksFromL1TracksHGCal_*_*', - 'keep *_l1pfProducerHGCal_*_*', - 'keep *_l1pfProducerHGCalNoTK_*_*', - 'keep *_l1pfProducerHF_*_*', - 'keep *_l1pfCandidates_*_*', - 'keep *_ak4PFL1Calo_*_*', - 'keep *_ak4PFL1PF_*_*', - 'keep *_ak4PFL1Puppi_*_*', - 'keep *_ak4PFL1CaloCorrected_*_*', - 'keep *_ak4PFL1PFCorrected_*_*', - 'keep *_ak4PFL1PuppiCorrected_*_*', + 'keep *_scPFL1PF_*_*', + 'keep *_scPFL1Puppi_*_*', + 'keep *_scPFL1PuppiCorrectedEmulator_*_*', + 'keep *_scPFL1PuppiCorrectedEmulatorMHT_*_*', 'keep *_Phase1L1TJetProducer_*_*', 'keep *_Phase1L1TJetCalibrator_*_*', - 'keep *_l1PFMetCalo_*_*', - 'keep *_l1PFMetPF_*_*', - 'keep *_l1PFMetPuppi_*_*', + 'keep *_Phase1L1TJetSumsProducer_*_*', + 'keep *_l1ctLayer1Barrel_*_*', + 'keep *_l1ctLayer1HGCal_*_*', + 'keep *_l1ctLayer1HGCalNoTK_*_*', + 'keep *_l1ctLayer1HF_*_*', + 'keep *_l1ctLayer1_*_*', + 'keep *_l1ctLayer1EG_*_*', + 'keep *_L1MetPfProducer_*_*', 'keep *_l1NNTauProducer_*_*', 'keep *_l1NNTauProducerPuppi_*_*', 'keep *_TTStubsFromPhase2TrackerDigis_*_*', 'keep *_TTClustersFromPhase2TrackerDigis_*_*', 'keep *_TTTracksFromExtendedTrackletEmulation_*_*', 'keep *_TTTracksFromTrackletEmulation_*_*', + 'keep *_L1TkStubsGmt_*_*', + 'keep *_L1TkMuonsGmt_*_*', + 'keep *_L1SAMuonsGmt_*_*', ] obj.outputCommands += l1Phase2Digis diff --git a/L1Trigger/Configuration/python/SimL1Emulator_cff.py b/L1Trigger/Configuration/python/SimL1Emulator_cff.py index cb9198b37320e..b117f24b5cb9c 100644 --- a/L1Trigger/Configuration/python/SimL1Emulator_cff.py +++ b/L1Trigger/Configuration/python/SimL1Emulator_cff.py @@ -71,6 +71,10 @@ # ######################################################################## # Phase-2 Trigger Primitives # ######################################################################## +from L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi import * +_phase2_siml1emulator.add(CalibratedDigis) +from L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi import * +_phase2_siml1emulator.add(dtTriggerPhase2PrimitiveDigis) # HGCAL TP # ######################################################################## @@ -87,68 +91,137 @@ from L1Trigger.L1CaloTrigger.L1EGammaCrystalsEmulatorProducer_cfi import * _phase2_siml1emulator.add(L1EGammaClusterEmuProducer) -from L1Trigger.L1CaloTrigger.l1EGammaEEProducer_cfi import * -_phase2_siml1emulator.add(l1EGammaEEProducer) - -# ######################################################################## -# Phase-2 L1T - TrackTrigger dependent modules +# Barrel and EndCap CaloJet/HT # ######################################################################## +# ---- Produce the calibrated tower collection combining Barrel, HGCal, HF +from L1Trigger.L1CaloTrigger.L1TowerCalibrationProducer_cfi import * +L1TowerCalibration = L1TowerCalibrationProducer.clone( + L1HgcalTowersInputTag = cms.InputTag("hgcalTowerProducer","HGCalTowerProcessor",""), + #l1CaloTowers = cms.InputTag("L1EGammaClusterEmuProducer","","") + l1CaloTowers = cms.InputTag("L1EGammaClusterEmuProducer","L1CaloTowerCollection","") +) +# ---- Produce the L1CaloJets +from L1Trigger.L1CaloTrigger.L1CaloJetProducer_cfi import * +L1CaloJet = L1CaloJetProducer.clone ( + l1CaloTowers = cms.InputTag("L1TowerCalibration","L1CaloTowerCalibratedCollection",""), + L1CrystalClustersInputTag = cms.InputTag("L1EGammaClusterEmuProducer", "","") +) +# ---- Produce the CaloJet HTT Sums +from L1Trigger.L1CaloTrigger.L1CaloJetHTTProducer_cfi import * +L1CaloJetHTT = L1CaloJetHTTProducer.clone( + BXVCaloJetsInputTag = cms.InputTag("L1CaloJet", "CaloJets") +) -# Tk + StandaloneObj, including L1TkPrimaryVertex -# ######################################################################## - -from L1Trigger.L1TTrackMatch.L1TkPrimaryVertexProducer_cfi import L1TkPrimaryVertex -from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import L1TkElectronsCrystal, L1TkElectronsLooseCrystal, L1TkElectronsEllipticMatchCrystal, L1TkIsoElectronsCrystal, L1TkElectronsHGC, L1TkElectronsEllipticMatchHGC, L1TkIsoElectronsHGC -from L1Trigger.L1TTrackMatch.L1TkEmParticleProducer_cfi import L1TkPhotonsCrystal, L1TkPhotonsHGC -from L1Trigger.L1TTrackMatch.L1TkMuonProducer_cfi import L1TkMuons - -_phase2_siml1emulator.add(L1TkPrimaryVertex) - -_phase2_siml1emulator.add(L1TkElectronsCrystal) -_phase2_siml1emulator.add(L1TkElectronsLooseCrystal) -_phase2_siml1emulator.add(L1TkElectronsEllipticMatchCrystal) -_phase2_siml1emulator.add(L1TkIsoElectronsCrystal) -_phase2_siml1emulator.add(L1TkPhotonsCrystal) -_phase2_siml1emulator.add(L1TkElectronsHGC) -_phase2_siml1emulator.add(L1TkElectronsEllipticMatchHGC) -_phase2_siml1emulator.add(L1TkIsoElectronsHGC) -_phase2_siml1emulator.add(L1TkPhotonsHGC) +_phase2_siml1emulator.add(L1TowerCalibration) +_phase2_siml1emulator.add(L1CaloJet) +_phase2_siml1emulator.add(L1CaloJetHTT) -_phase2_siml1emulator.add( L1TkMuons ) +# ######################################################################## +# Phase-2 L1T - TrackTrigger dependent modules +# ######################################################################## +from L1Trigger.L1TTrackMatch.L1GTTInputProducer_cfi import * +from L1Trigger.VertexFinder.VertexProducer_cff import * +L1VertexFinder = VertexProducer.clone() +L1VertexFinderEmulator = VertexProducer.clone() +L1VertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" +L1VertexFinderEmulator.l1TracksInputTag = cms.InputTag("L1GTTInputProducer","Level1TTTracksConverted") +_phase2_siml1emulator.add(L1VertexFinder) +_phase2_siml1emulator.add(L1GTTInputProducer) +_phase2_siml1emulator.add(L1GTTInputProducerExtended) +_phase2_siml1emulator.add(L1VertexFinderEmulator) + +# Emulated GMT Muons (Tk + Stub, Tk + MuonTFT, StandaloneMuon) +# ######################################################################## +from L1Trigger.Phase2L1GMT.gmt_cfi import * +L1TkStubsGmt = gmtStubs.clone() +L1TkMuonsGmt = gmtMuons.clone( + srcStubs = cms.InputTag('L1TkStubsGmt') +) +L1SAMuonsGmt = standaloneMuons.clone() +_phase2_siml1emulator.add( L1TkStubsGmt ) +_phase2_siml1emulator.add( L1TkMuonsGmt ) +_phase2_siml1emulator.add( L1SAMuonsGmt ) + +# Tracker Objects +# ######################################################################## +from L1Trigger.L1TTrackMatch.L1TrackJetProducer_cfi import * +from L1Trigger.L1TTrackMatch.L1TrackFastJetProducer_cfi import * +from L1Trigger.L1TTrackMatch.L1TrackerEtMissProducer_cfi import * +from L1Trigger.L1TTrackMatch.L1TkHTMissProducer_cfi import * +# make the input tags consistent with the choice L1VertexFinder above +L1TrackJets.L1PVertexCollection = cms.InputTag("L1VertexFinder", L1VertexFinder.l1VertexCollectionName.value()) +L1TrackJetsExtended.L1PVertexCollection = cms.InputTag("L1VertexFinder", L1VertexFinder.l1VertexCollectionName.value()) +L1TrackerEtMiss.L1VertexInputTag = cms.InputTag("L1VertexFinder", L1VertexFinder.l1VertexCollectionName.value()) +L1TrackerEtMissExtended.L1VertexInputTag = cms.InputTag("L1VertexFinder", L1VertexFinder.l1VertexCollectionName.value()) +_phase2_siml1emulator.add(L1TrackJets) +_phase2_siml1emulator.add(L1TrackJetsExtended) +_phase2_siml1emulator.add(L1TrackFastJets) + +_phase2_siml1emulator.add(L1TrackerEtMiss) +_phase2_siml1emulator.add(L1TrackerHTMiss) +#_phase2_siml1emulator.add(L1TrackerEtMissExtended) +#_phase2_siml1emulator.add(L1TrackerHTMissExtended) + +#Emulated tracker objects +from L1Trigger.L1TTrackMatch.L1TrackJetEmulationProducer_cfi import * +_phase2_siml1emulator.add(L1TrackJetsEmulation) +_phase2_siml1emulator.add(L1TrackJetsExtendedEmulation) + +from L1Trigger.L1TTrackMatch.L1TrackSelectionProducer_cfi import L1TrackSelectionProducer, L1TrackSelectionProducerExtended +_phase2_siml1emulator.add(L1TrackSelectionProducer) +_phase2_siml1emulator.add(L1TrackSelectionProducerExtended) + +from L1Trigger.L1TTrackMatch.L1TrackerEtMissEmulatorProducer_cfi import * +L1TrackerEmuEtMiss.L1VertexInputTag = cms.InputTag("L1VertexFinderEmulator","l1verticesEmulation") +_phase2_siml1emulator.add(L1TrackerEmuEtMiss) + +from L1Trigger.L1TTrackMatch.L1TkHTMissEmulatorProducer_cfi import * +_phase2_siml1emulator.add(L1TrackerEmuHTMiss) +_phase2_siml1emulator.add(L1TrackerEmuHTMissExtended) # PF Candidates # ######################################################################## -from L1Trigger.Phase2L1ParticleFlow.l1ParticleFlow_cff import * -_phase2_siml1emulator.add(l1ParticleFlowTask) +from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_cff import * +from L1Trigger.Phase2L1ParticleFlow.l1ctLayer2EG_cff import * +_phase2_siml1emulator.add(l1ctLayer1TaskInputsTask, l1ctLayer1Task, l1ctLayer2EGTask) # PF Jet # ######################################################################## from L1Trigger.L1CaloTrigger.Phase1L1TJets_cff import * # Describe here l1PFJets_a_la_Phase1 Task # ############################### -l1PFJetsPhase1Task = cms.Task(Phase1L1TJetProducer , Phase1L1TJetCalibrator) +l1PFJetsPhase1Task = cms.Task(Phase1L1TJetProducer , Phase1L1TJetCalibrator, Phase1L1TJetSumsProducer) _phase2_siml1emulator.add(l1PFJetsPhase1Task) +from L1Trigger.Phase2L1Taus.HPSPFTauProducerPF_cfi import * +_phase2_siml1emulator.add(HPSPFTauProducerPF) + +from L1Trigger.Phase2L1Taus.HPSPFTauProducerPuppi_cfi import * +_phase2_siml1emulator.add(HPSPFTauProducerPuppi) + +from L1Trigger.L1CaloTrigger.Phase1L1TJets_9x9_cff import * +l1PFJetsPhase1Task_9x9 = cms.Task( Phase1L1TJetProducer9x9, Phase1L1TJetCalibrator9x9, Phase1L1TJetSumsProducer9x9) +_phase2_siml1emulator.add(l1PFJetsPhase1Task_9x9) + + # PF MET # ######################################################################## from L1Trigger.Phase2L1ParticleFlow.l1pfJetMet_cff import * -# Describe here l1PFMets Task -# ############################### -l1PFMetsTask = cms.Task(l1PFMetCalo , l1PFMetPF , l1PFMetPuppi) -_phase2_siml1emulator.add(l1PFMetsTask) +_phase2_siml1emulator.add(l1PFJetsTask) + +from L1Trigger.Phase2L1ParticleFlow.L1MetPfProducer_cfi import * +_phase2_siml1emulator.add(L1MetPfProducer) + # NNTaus # ######################################################################## from L1Trigger.Phase2L1ParticleFlow.L1NNTauProducer_cff import * -l1NNTauProducer = L1NNTauProducer.clone( - L1PFObjects = cms.InputTag("l1pfCandidates","PF") -) -l1NNTauProducerPuppi = L1NNTauProducerPuppi.clone( - L1PFObjects = cms.InputTag("l1pfCandidates","Puppi") -) -_phase2_siml1emulator.add(l1NNTauProducer) -_phase2_siml1emulator.add(l1NNTauProducerPuppi) + +_phase2_siml1emulator.add(L1NNTauProducerPuppi) +#_phase2_siml1emulator.add(L1NNTauProducerPuppi2Vtx) +_phase2_siml1emulator.add(tau2VtxTaskHW) + # --> add modules from Configuration.Eras.Modifier_phase2_trigger_cff import phase2_trigger diff --git a/L1Trigger/Configuration/python/customisePhase2.py b/L1Trigger/Configuration/python/customisePhase2.py new file mode 100644 index 0000000000000..2477c7c95cfc2 --- /dev/null +++ b/L1Trigger/Configuration/python/customisePhase2.py @@ -0,0 +1,22 @@ +import FWCore.ParameterSet.Config as cms + +def customisePhase2TTNoMC(process): + process.L1TrackTrigger.replace(process.L1PromptExtendedHybridTracksWithAssociators, process.L1PromptExtendedHybridTracks) + process.L1TrackTrigger.remove(process.TrackTriggerAssociatorClustersStubs) + process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') + + return process + +def addHcalTriggerPrimitives(process): + process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') + + return process + +def addMenuNtuples(process): + process.load("L1Trigger.L1TNtuples.l1PhaseIITreeStep1Producer_cfi") + process.TFileService = cms.Service("TFileService", + fileName = cms.string('L1NtuplePhaseII_Step1.root') + ) + + return process + diff --git a/L1Trigger/Configuration/python/customisePhase2FEVTDEBUGHLT.py b/L1Trigger/Configuration/python/customisePhase2FEVTDEBUGHLT.py new file mode 100644 index 0000000000000..077dfd402064d --- /dev/null +++ b/L1Trigger/Configuration/python/customisePhase2FEVTDEBUGHLT.py @@ -0,0 +1,5 @@ +import FWCore.ParameterSet.Config as cms + +def customisePhase2FEVTDEBUGHLT(process): + process.source.inputCommands = cms.untracked.vstring("keep *","drop l1tPFCandidates_*_*_RECO") + return process diff --git a/L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h b/L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h index af9d789c3d56f..0230b1a4eca09 100644 --- a/L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h +++ b/L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h @@ -1,7 +1,6 @@ #ifndef L1Trigger_DTTriggerPhase2_GlobalCoordsObtainer_h #define L1Trigger_DTTriggerPhase2_GlobalCoordsObtainer_h -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Utilities/interface/ESGetToken.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/FrameworkfwdMostUsed.h" @@ -77,4 +76,4 @@ class GlobalCoordsObtainer { std::map luts; }; -#endif \ No newline at end of file +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MPCleanHitsFilter.h b/L1Trigger/DTTriggerPhase2/interface/MPCleanHitsFilter.h new file mode 100644 index 0000000000000..af89cae7dd05e --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MPCleanHitsFilter.h @@ -0,0 +1,51 @@ +#ifndef L1Trigger_DTTriggerPhase2_MPCleanHitsFilter_h +#define L1Trigger_DTTriggerPhase2_MPCleanHitsFilter_h + +#include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" + +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MPCleanHitsFilter : public MPFilter { +public: + // Constructors and destructor + MPCleanHitsFilter(const edm::ParameterSet& pset); + ~MPCleanHitsFilter() override; + + // Main methods + void initialise(const edm::EventSetup& iEventSetup) override{}; + void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + std::vector& inMPath, + std::vector& outMPath) override{}; + + void run(edm::Event& iEvent, + const edm::EventSetup& iEventSetup, + MuonPathPtrs& inMPath, + MuonPathPtrs& outMPath) override; + + void finish() override{}; + + // Other public methods + void removeOutliers(MuonPathPtr& mpath); + + double getMeanTime(MuonPathPtr& mpath); + + void setTimeTolerance(int time) { timeTolerance_ = time; } + int getTimeTolerance() { return timeTolerance_; } + +private: + // Private attributes + bool debug_; + int timeTolerance_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MPFilter.h b/L1Trigger/DTTriggerPhase2/interface/MPFilter.h index 95df42c84c4f5..674a5a3489188 100644 --- a/L1Trigger/DTTriggerPhase2/interface/MPFilter.h +++ b/L1Trigger/DTTriggerPhase2/interface/MPFilter.h @@ -1,7 +1,6 @@ #ifndef Phase2L1Trigger_DTTrigger_MPFilter_h #define Phase2L1Trigger_DTTrigger_MPFilter_h -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/EventSetup.h" diff --git a/L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilterBayes.h b/L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilterBayes.h new file mode 100644 index 0000000000000..9aae0f504f5c4 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilterBayes.h @@ -0,0 +1,58 @@ +#ifndef Phase2L1Trigger_DTTrigger_MPQualityEnhancerFilterBayes_h +#define Phase2L1Trigger_DTTrigger_MPQualityEnhancerFilterBayes_h + +#include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" +#include "DataFormats/MuonDetId/interface/DTChamberId.h" + +#include +#include + +// =============================================================================== +// Previous definitions and declarations +// =============================================================================== + +// =============================================================================== +// Class declarations +// =============================================================================== + +class MPQualityEnhancerFilterBayes : public MPFilter { +public: + // Constructors and destructor + MPQualityEnhancerFilterBayes(const edm::ParameterSet &pset); + ~MPQualityEnhancerFilterBayes() override; + + // Main methods + void initialise(const edm::EventSetup &iEventSetup) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + std::vector &inMPath, + std::vector &outMPath) override; + void run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMPath, + MuonPathPtrs &outMPath) override{}; + + void finish() override; + + // Other public methods + + // Public attributes + int areCousins(cmsdt::metaPrimitive mp1, cmsdt::metaPrimitive mp2); + int shareSL(cmsdt::metaPrimitive mp1, cmsdt::metaPrimitive mp2); + bool areSame(cmsdt::metaPrimitive mp1, cmsdt::metaPrimitive mp2); + int rango(cmsdt::metaPrimitive mp); + int BX(cmsdt::metaPrimitive mp); + void printmP(cmsdt::metaPrimitive mP); + +private: + // Private methods + void filterCousins(std::vector &inMPath, std::vector &outMPath); + /* void refilteringCousins(std::vector &inMPath, std::vector &outMPath); */ + /* void filterTanPhi(std::vector &inMPath, std::vector &outMPath); */ + /* void filterUnique(std::vector &inMPath, std::vector &outMPath); */ + + // Private attributes + bool debug_; +}; + +#endif diff --git a/L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h b/L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h index fbab714a359c5..e68622b43312c 100644 --- a/L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h +++ b/L1Trigger/DTTriggerPhase2/interface/MotherGrouping.h @@ -1,7 +1,6 @@ #ifndef Phase2L1Trigger_DTTrigger_MotherGrouping_h #define Phase2L1Trigger_DTTrigger_MotherGrouping_h -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/EventSetup.h" diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h index 470b276708a8a..7a42509b4b9ae 100644 --- a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzer.h @@ -1,7 +1,6 @@ #ifndef Phase2L1Trigger_DTTrigger_MuonPathAnalyzer_h #define Phase2L1Trigger_DTTrigger_MuonPathAnalyzer_h -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Utilities/interface/ESGetToken.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/FrameworkfwdMostUsed.h" diff --git a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h index e319261725e02..ab008812786c8 100644 --- a/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h +++ b/L1Trigger/DTTriggerPhase2/interface/MuonPathAnalyzerInChamber.h @@ -7,8 +7,7 @@ // Previous definitions and declarations // =============================================================================== namespace { - constexpr int NLayers = 8; - typedef std::array TLateralities; + typedef std::array TLateralities; } // namespace // =============================================================================== // Class declarations @@ -65,7 +64,10 @@ class MuonPathAnalyzerInChamber : public MuonPathAnalyzer { void buildLateralities(MuonPathPtr &mpath); void setLateralitiesInMP(MuonPathPtr &mpath, TLateralities lat); void setWirePosAndTimeInMP(MuonPathPtr &mpath); - void calculateFitParameters(MuonPathPtr &mpath, TLateralities lat, int present_layer[NLayers], int &lat_added); + void calculateFitParameters(MuonPathPtr &mpath, + TLateralities lat, + int present_layer[cmsdt::NUM_LAYERS_2SL], + int &lat_added); void evaluateQuality(MuonPathPtr &mPath); int totalNumValLateralities_; @@ -79,7 +81,7 @@ class MuonPathAnalyzerInChamber : public MuonPathAnalyzer { cmsdt::MP_QUALITY minQuality_; float chiSquareThreshold_; short minHits4Fit_; - int cellLayout_[NLayers]; + int cellLayout_[cmsdt::NUM_LAYERS_2SL]; bool splitPathPerSL_; // global coordinates diff --git a/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h b/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h index e4b6852844425..c2f1d7931a9cf 100644 --- a/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h +++ b/L1Trigger/DTTriggerPhase2/interface/RPCIntegrator.h @@ -1,7 +1,6 @@ #ifndef Phase2L1Trigger_DTTrigger_RPCIntegrator_h #define Phase2L1Trigger_DTTrigger_RPCIntegrator_h -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/EventSetup.h" @@ -93,8 +92,6 @@ class RPCIntegrator { edm::ESGetToken dtGeomH_; edm::ESGetToken rpcGeomH_; - static constexpr double m_dt_phi_granularity_ = (65536. / 0.8); // 65536 different values per 0.8 radian - static constexpr double m_dt_phiB_granularity_ = (2048. / 1.4); // 2048. different values per 1.4 radian // Constant geometry values //R[stat][layer] - radius of rpc station/layer from center of CMS static constexpr double R_[2][2] = {{410.0, 444.8}, {492.7, 527.3}}; diff --git a/L1Trigger/DTTriggerPhase2/plugins/CalibratedDigis.cc b/L1Trigger/DTTriggerPhase2/plugins/CalibratedDigis.cc index 55c633dd9fe15..de20feff242e4 100644 --- a/L1Trigger/DTTriggerPhase2/plugins/CalibratedDigis.cc +++ b/L1Trigger/DTTriggerPhase2/plugins/CalibratedDigis.cc @@ -32,7 +32,6 @@ #include "CalibMuon/DTDigiSync/interface/DTTTrigBaseSync.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "DataFormats/Common/interface/Handle.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "CalibMuon/DTDigiSync/interface/DTTTrigSyncFactory.h" diff --git a/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc b/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc index 7b031f7dc8328..c7a6758baf9ad 100644 --- a/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc +++ b/L1Trigger/DTTriggerPhase2/plugins/DTTrigPhase2Prod.cc @@ -33,6 +33,8 @@ #include "L1Trigger/DTTriggerPhase2/interface/MPFilter.h" #include "L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilter.h" #include "L1Trigger/DTTriggerPhase2/interface/MPRedundantFilter.h" +#include "L1Trigger/DTTriggerPhase2/interface/MPCleanHitsFilter.h" +#include "L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilterBayes.h" #include "L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h" #include "DataFormats/MuonDetId/interface/DTChamberId.h" @@ -104,7 +106,7 @@ class DTTrigPhase2Prod : public edm::stream::EDProducer<> { void setMinimumQuality(MP_QUALITY q); // data-members - DTGeometry const* dtGeo_; + const DTGeometry* dtGeo_; edm::ESGetToken dtGeomH; std::vector> primitives_; @@ -122,7 +124,7 @@ class DTTrigPhase2Prod : public edm::stream::EDProducer<> { bool do_correlation_; int scenario_; int df_extended_; - std::string geometry_tag_; + int max_index_; // ParameterSet edm::EDGetTokenT dtDigisToken_; @@ -133,8 +135,9 @@ class DTTrigPhase2Prod : public edm::stream::EDProducer<> { std::unique_ptr grouping_obj_; std::unique_ptr mpathanalyzer_; std::unique_ptr mpathqualityenhancer_; + std::unique_ptr mpathqualityenhancerbayes_; std::unique_ptr mpathredundantfilter_; - // std::unique_ptr mpathhitsfilter_; + std::unique_ptr mpathhitsfilter_; std::unique_ptr mpathassociator_; std::shared_ptr globalcoordsobtainer_; @@ -166,7 +169,7 @@ namespace { } // namespace DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) - : qmap_({{9, 9}, {8, 8}, {7, 6}, {6, 7}, {5, 3}, {4, 5}, {3, 4}, {2, 2}, {1, 1}}) { + : qmap_({{8, 8}, {7, 7}, {6, 6}, {4, 4}, {3, 3}, {2, 2}, {1, 1}}) { produces(); produces(); produces(); @@ -179,6 +182,7 @@ DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) scenario_ = pset.getParameter("scenario"); df_extended_ = pset.getParameter("df_extended"); + max_index_ = pset.getParameter("max_primitives") - 1; dtDigisToken_ = consumes(pset.getParameter("digiTag")); @@ -188,9 +192,6 @@ DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) // Choosing grouping scheme: algo_ = pset.getParameter("algo"); - // Local to global coordinates approach - geometry_tag_ = pset.getUntrackedParameter("geometry_tag", ""); - edm::ConsumesCollector consumesColl(consumesCollector()); globalcoordsobtainer_ = std::make_shared(pset); globalcoordsobtainer_->generate_luts(); @@ -221,7 +222,9 @@ DTTrigPhase2Prod::DTTrigPhase2Prod(const ParameterSet& pset) superCelltimewidth_ = pset.getParameter("superCelltimewidth"); mpathqualityenhancer_ = std::make_unique(pset); + mpathqualityenhancerbayes_ = std::make_unique(pset); mpathredundantfilter_ = std::make_unique(pset); + mpathhitsfilter_ = std::make_unique(pset); mpathassociator_ = std::make_unique(pset, consumesColl, globalcoordsobtainer_); rpc_integrator_ = std::make_unique(pset, consumesColl); @@ -239,15 +242,17 @@ void DTTrigPhase2Prod::beginRun(edm::Run const& iRun, const edm::EventSetup& iEv if (debug_) LogDebug("DTTrigPhase2Prod") << "beginRun: getting DT geometry"; - grouping_obj_->initialise(iEventSetup); // Grouping object initialisation - mpathanalyzer_->initialise(iEventSetup); // Analyzer object initialisation - mpathqualityenhancer_->initialise(iEventSetup); // Filter object initialisation - mpathredundantfilter_->initialise(iEventSetup); // Filter object initialisation - mpathassociator_->initialise(iEventSetup); // Associator object initialisation + grouping_obj_->initialise(iEventSetup); // Grouping object initialisation + mpathanalyzer_->initialise(iEventSetup); // Analyzer object initialisation + mpathqualityenhancer_->initialise(iEventSetup); // Filter object initialisation + mpathredundantfilter_->initialise(iEventSetup); // Filter object initialisation + mpathqualityenhancerbayes_->initialise(iEventSetup); // Filter object initialisation + mpathhitsfilter_->initialise(iEventSetup); + mpathassociator_->initialise(iEventSetup); // Associator object initialisation - edm::ESHandle geom; - iEventSetup.get().get(geometry_tag_, geom); - dtGeo_ = &(*geom); + if (auto geom = iEventSetup.getHandle(dtGeomH)) { + dtGeo_ = &(*geom); + } } void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { @@ -350,6 +355,8 @@ void DTTrigPhase2Prod::produce(Event& iEvent, const EventSetup& iEventSetup) { MuonPathPtrs filteredmuonpaths; if (algo_ == Standard) { mpathredundantfilter_->run(iEvent, iEventSetup, muonpaths, filteredmuonpaths); + } else { + mpathhitsfilter_->run(iEvent, iEventSetup, muonpaths, filteredmuonpaths); } if (dump_) { @@ -711,7 +718,9 @@ void DTTrigPhase2Prod::endRun(edm::Run const& iRun, const edm::EventSetup& iEven grouping_obj_->finish(); mpathanalyzer_->finish(); mpathqualityenhancer_->finish(); + mpathqualityenhancerbayes_->finish(); mpathredundantfilter_->finish(); + mpathhitsfilter_->finish(); mpathassociator_->finish(); rpc_integrator_->finish(); }; @@ -773,7 +782,8 @@ void DTTrigPhase2Prod::assignIndex(std::vector& inMPaths) { for (auto& prims : primsPerBX) { assignIndexPerBX(prims.second); for (const auto& primitive : prims.second) - inMPaths.push_back(primitive); + if (primitive.index <= max_index_) + inMPaths.push_back(primitive); } } @@ -811,7 +821,7 @@ void DTTrigPhase2Prod::assignIndexPerBX(std::vector& inMPaths) { } int DTTrigPhase2Prod::assignQualityOrder(const metaPrimitive& mP) const { - if (mP.quality > 9 || mP.quality < 1) + if (mP.quality > 8 || mP.quality < 1) return -1; return qmap_.find(mP.quality)->second; diff --git a/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py b/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py index 2ea01dabac697..b95e955194515 100644 --- a/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py +++ b/L1Trigger/DTTriggerPhase2/python/dtTriggerPhase2PrimitiveDigis_cfi.py @@ -27,6 +27,7 @@ scenario = cms.int32(0), #0 for mc, 1 for data, 2 for slice test df_extended = cms.int32(0), # DF: 0 for standard, 1 for extended, 2 for both filter_cousins = cms.untracked.bool(True), + max_primitives = cms.int32(999), ttrig_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/wire_rawId_ttrig.txt'), z_filename = cms.FileInPath('L1Trigger/DTTriggerPhase2/data/wire_rawId_z.txt'), diff --git a/L1Trigger/DTTriggerPhase2/src/MPCleanHitsFilter.cc b/L1Trigger/DTTriggerPhase2/src/MPCleanHitsFilter.cc new file mode 100644 index 0000000000000..e87aedb3fbfc6 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MPCleanHitsFilter.cc @@ -0,0 +1,56 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MPCleanHitsFilter.h" + +using namespace edm; +using namespace std; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MPCleanHitsFilter::MPCleanHitsFilter(const ParameterSet &pset) : MPFilter(pset) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); + + timeTolerance_ = pset.exists("timeTolerance") ? pset.getParameter("timeTolerance") : 999999; + // probably something close to the max time drift (400ns/2) is a reasonable value +} +void MPCleanHitsFilter::run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + MuonPathPtrs &inMPaths, + MuonPathPtrs &outMPaths) { + int counter = 0; + for (const auto &mpath : inMPaths) { + ++counter; + auto mpAux = std::make_shared(*mpath); + removeOutliers(mpAux); // remove hits that are more than 1 bX from the meantime. + + outMPaths.emplace_back(mpAux); + } +} + +void MPCleanHitsFilter::removeOutliers(MuonPathPtr &mpath) { + int MeanTime = getMeanTime(mpath); + for (int i = 0; i < mpath->nprimitives(); i++) { + if (!mpath->primitive(i)->isValidTime()) + continue; + if (std::abs(mpath->primitive(i)->tdcTimeStamp() - MeanTime) > timeTolerance_) { + mpath->primitive(i)->setTDCTimeStamp(-1); //invalidate hit + mpath->primitive(i)->setChannelId(-1); //invalidate hit + } + } +} + +double MPCleanHitsFilter::getMeanTime(MuonPathPtr &mpath) { + float meantime = 0.; + float count = 0.; + for (int i = 0; i < mpath->nprimitives(); i++) { + if (mpath->primitive(i) == nullptr) + continue; + if (!mpath->primitive(i)->isValidTime()) + continue; + meantime += mpath->primitive(i)->tdcTimeStamp(); + count++; + } + return meantime / count; +} + +MPCleanHitsFilter::~MPCleanHitsFilter() {} diff --git a/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilter.cc b/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilter.cc index 4ce76b41c6042..2899d73a88277 100644 --- a/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilter.cc +++ b/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilter.cc @@ -148,7 +148,7 @@ void MPQualityEnhancerFilter::filterCousins(std::vector &inMPaths void MPQualityEnhancerFilter::refilteringCousins(std::vector &inMPaths, std::vector &outMPaths) { if (debug_) - std::cout << "filtering: starting cousins refiltering" << std::endl; + LogDebug("MPQualityEnhancerFilter") << "filtering: starting cousins refiltering\n"; int bestI = -1; double bestChi2 = 9999; bool oneOf4 = false; diff --git a/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilterBayes.cc b/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilterBayes.cc new file mode 100644 index 0000000000000..9c44c86ce167f --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/src/MPQualityEnhancerFilterBayes.cc @@ -0,0 +1,319 @@ +#include "L1Trigger/DTTriggerPhase2/interface/MPQualityEnhancerFilterBayes.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace edm; +using namespace std; +using namespace cmsdt; +; + +// ============================================================================ +// Constructors and destructor +// ============================================================================ +MPQualityEnhancerFilterBayes::MPQualityEnhancerFilterBayes(const ParameterSet &pset) : MPFilter(pset) { + // Obtention of parameters + debug_ = pset.getUntrackedParameter("debug"); +} + +MPQualityEnhancerFilterBayes::~MPQualityEnhancerFilterBayes() {} + +// ============================================================================ +// Main methods (initialise, run, finish) +// ============================================================================ +void MPQualityEnhancerFilterBayes::initialise(const edm::EventSetup &iEventSetup) {} + +void MPQualityEnhancerFilterBayes::run(edm::Event &iEvent, + const edm::EventSetup &iEventSetup, + std::vector &inMPaths, + std::vector &outMPaths) { + // std::vector buff; + // std::vector buff2; + + filterCousins(inMPaths, outMPaths); + if (debug_) { + LogDebug("MPQualityEnhancerFilterBayes") << "Ended Cousins Filter. The final primitives before Refiltering are: "; + for (unsigned int i = 0; i < outMPaths.size(); i++) { + printmP(outMPaths[i]); + } + LogDebug("MPQualityEnhancerFilterBayes") << "Total Primitives = " << outMPaths.size(); + } + // refilteringCousins(buff, buff2); + // if (debug_) { + // LogDebug("MPQualityEnhancerFilterBayes") << "Ended Cousins Refilter. The final primitives before UniqueFilter are: "; + // for (unsigned int i = 0; i < buff2.size(); i++) { + // printmP(buff2[i]); + // } + // LogDebug("MPQualityEnhancerFilterBayes") << "Total Primitives = " << buff2.size(); + // } + // filterUnique(buff2, outMPaths); + + // buff.clear(); + // buff2.clear(); +} + +void MPQualityEnhancerFilterBayes::finish(){}; + +/////////////////////////// +/// OTHER METHODS +int MPQualityEnhancerFilterBayes::areCousins(metaPrimitive mp, metaPrimitive second_mp) { + DTSuperLayerId mpId(mp.rawId); + DTSuperLayerId second_mpId(second_mp.rawId); + + cout << "Comparing mp:" << endl; + cout << "ID: wheel " << mpId.wheel() << ", station " << mpId.station() << ", sector " << mpId.sector() << endl; + cout << "ID: wheel " << second_mpId.wheel() << ", station " << second_mpId.station() << ", sector " + << second_mpId.sector() << endl; + + cout << mp.wi1 << "(" << mp.tdc1 << ")" + << " " << mp.wi2 << "(" << mp.tdc2 << ")" + << " " << mp.wi3 << "(" << mp.tdc3 << ")" + << " " << mp.wi4 << "(" << mp.tdc4 << ")" + << " " << mp.wi5 << "(" << mp.tdc5 << ")" + << " " << mp.wi6 << "(" << mp.tdc6 << ")" + << " " << mp.wi7 << "(" << mp.tdc7 << ")" + << " " << mp.wi8 << "(" << mp.tdc8 << ")" + << " " << endl; + cout << second_mp.wi1 << "(" << second_mp.tdc1 << ")" + << " " << second_mp.wi2 << "(" << second_mp.tdc2 << ")" + << " " << second_mp.wi3 << "(" << second_mp.tdc3 << ")" + << " " << second_mp.wi4 << "(" << second_mp.tdc4 << ")" + << " " << second_mp.wi5 << "(" << second_mp.tdc5 << ")" + << " " << second_mp.wi6 << "(" << second_mp.tdc6 << ")" + << " " << second_mp.wi7 << "(" << second_mp.tdc7 << ")" + << " " << second_mp.wi8 << "(" << second_mp.tdc8 << ")" + << " " << endl; + + int output = 0; + // if (mp.rawId != second_mp.rawId){ + // metaPrimitives must be in the same chamber to be cousins + if (mpId.wheel() != second_mpId.wheel() || mpId.station() != second_mpId.station() || + mpId.sector() != second_mpId.sector()) { + cout << "Not in the same chamber" << endl; + return output; + } + + if (mp.wi1 == second_mp.wi1 and mp.tdc1 == second_mp.tdc1 and mp.wi1 != -1 and mp.tdc1 != -1) + output = 1; + if (mp.wi2 == second_mp.wi2 and mp.tdc2 == second_mp.tdc2 and mp.wi2 != -1 and mp.tdc2 != -1) + output = 2; + if (mp.wi3 == second_mp.wi3 and mp.tdc3 == second_mp.tdc3 and mp.wi3 != -1 and mp.tdc3 != -1) + output = 3; + if (mp.wi4 == second_mp.wi4 and mp.tdc4 == second_mp.tdc4 and mp.wi4 != -1 and mp.tdc4 != -1) + output = 4; + if (mp.wi5 == second_mp.wi5 and mp.tdc5 == second_mp.tdc5 and mp.wi5 != -1 and mp.tdc5 != -1) + output = 5; + if (mp.wi6 == second_mp.wi6 and mp.tdc6 == second_mp.tdc6 and mp.wi6 != -1 and mp.tdc6 != -1) + output = 6; + if (mp.wi7 == second_mp.wi7 and mp.tdc7 == second_mp.tdc7 and mp.wi7 != -1 and mp.tdc7 != -1) + output = 7; + if (mp.wi8 == second_mp.wi8 and mp.tdc8 == second_mp.tdc8 and mp.wi8 != -1 and mp.tdc8 != -1) + output = 8; + + cout << output << endl; + return output; +} + +/////////////////////////// +/// OTHER METHODS +bool MPQualityEnhancerFilterBayes::areSame(metaPrimitive mp, metaPrimitive second_mp) { + if (mp.rawId != second_mp.rawId) + return false; + if (mp.wi1 != second_mp.wi1 or mp.tdc1 != second_mp.tdc1) + return false; + if (mp.wi2 != second_mp.wi2 or mp.tdc2 != second_mp.tdc2) + return false; + if (mp.wi3 != second_mp.wi3 or mp.tdc3 != second_mp.tdc3) + return false; + if (mp.wi4 != second_mp.wi4 or mp.tdc4 != second_mp.tdc4) + return false; + if (mp.wi5 != second_mp.wi5 or mp.tdc5 != second_mp.tdc5) + return false; + if (mp.wi6 != second_mp.wi6 or mp.tdc6 != second_mp.tdc6) + return false; + if (mp.wi7 != second_mp.wi7 or mp.tdc7 != second_mp.tdc7) + return false; + if (mp.wi8 != second_mp.wi8 or mp.tdc8 != second_mp.tdc8) + return false; + return true; +} + +int MPQualityEnhancerFilterBayes::shareSL(metaPrimitive mp, metaPrimitive second_mp) { + DTSuperLayerId mpId(mp.rawId); + DTSuperLayerId second_mpId(second_mp.rawId); + + int output = 0; + if (mpId.wheel() != second_mpId.wheel() || mpId.station() != second_mpId.station() || + mpId.sector() != second_mpId.sector()) { + return output; + } + + int SL1 = 0; + int SL3 = 0; + + int SL1_shared = 0; + int SL3_shared = 0; + + if (mp.wi1 != -1 and mp.tdc1 != -1) { + ++SL1; + if (mp.wi1 == second_mp.wi1 and mp.tdc1 == second_mp.tdc1) { + ++SL1_shared; + } + } + if (mp.wi2 != -1 and mp.tdc2 != -1) { + ++SL1; + if (mp.wi2 == second_mp.wi2 and mp.tdc2 == second_mp.tdc2) { + ++SL1_shared; + } + } + if (mp.wi3 != -1 and mp.tdc3 != -1) { + ++SL1; + if (mp.wi3 == second_mp.wi3 and mp.tdc3 == second_mp.tdc3) { + ++SL1_shared; + } + } + if (mp.wi4 != -1 and mp.tdc4 != -1) { + ++SL1; + if (mp.wi4 == second_mp.wi4 and mp.tdc4 == second_mp.tdc4) { + ++SL1_shared; + } + } + + if (mp.wi5 != -1 and mp.tdc5 != -1) { + ++SL3; + if (mp.wi5 == second_mp.wi5 and mp.tdc5 == second_mp.tdc5) { + ++SL3_shared; + } + } + if (mp.wi6 != -1 and mp.tdc6 != -1) { + ++SL3; + if (mp.wi6 == second_mp.wi6 and mp.tdc6 == second_mp.tdc6) { + ++SL3_shared; + } + } + if (mp.wi7 != -1 and mp.tdc7 != -1) { + ++SL3; + if (mp.wi7 == second_mp.wi7 and mp.tdc7 == second_mp.tdc7) { + ++SL3_shared; + } + } + if (mp.wi8 != -1 and mp.tdc8 != -1) { + ++SL3; + if (mp.wi8 == second_mp.wi8 and mp.tdc8 == second_mp.tdc8) { + ++SL3_shared; + } + } + + // If the two mp share all hits in a SL, we consider that they share that SL + if (SL1_shared == SL1 || SL3_shared == SL3) + output = 1; + + return output; +} + +int MPQualityEnhancerFilterBayes::BX(metaPrimitive mp) { + int bx; + bx = (int)round(mp.t0 / (float)LHC_CLK_FREQ); + return bx; +} + +// Is this really needed? +int MPQualityEnhancerFilterBayes::rango(metaPrimitive mp) { + // Correlated + if (mp.quality > 5) + return 2; + // uncorrelated + else + return 1; +} + +void MPQualityEnhancerFilterBayes::filterCousins(std::vector &inMPaths, + std::vector &outMPaths) { + // int primo_index = 0; + // bool oneof4 = false; // quality >= 6, for the moment. So, correlated primitives + // int bestI = -1; + // double bestChi2 = 9999; + + // At the beginning, we want to keep all mpaths + bool keep_this[inMPaths.size()]; + for (unsigned int k = 0; k < inMPaths.size(); k++) { + keep_this[k] = true; + } + + // If we have just one mpath, save it + if (inMPaths.size() == 1) { + if (debug_) { + printmP(inMPaths[0]); + } + outMPaths.push_back(inMPaths[0]); + } + // More than one mpath + else if (inMPaths.size() > 1) { + for (int i = 0; i < int(inMPaths.size()); i++) { + if (debug_) { + printmP(inMPaths[i]); + } + // If we have already decided to reject the candidate, skip it + if (keep_this[i] == false) + continue; + for (int j = i + 1; j < int(inMPaths.size()); j++) { + // If we have already decided to reject the candidate, skip it + if (keep_this[j] == false) + continue; + // Case they are the same, keep the first one + if (areSame(inMPaths[i], inMPaths[j]) == true) + keep_this[i] = false; + // Case they are cousins, keep the best one + if (areCousins(inMPaths[i], inMPaths[j]) != 0) { + cout << "They are cousins" << endl; + + // In case both are correlated, they have to share a full SL + if (inMPaths[i].quality > 5 && inMPaths[j].quality > 5 && shareSL(inMPaths[i], inMPaths[j]) == 0) { + cout << "But don't share a whole SL" << endl; + continue; + } + + // Compare only if rango is the same (both correlated or both not-correlated) + // if (rango(inMPaths[i]) != rango(inMPaths[j])) continue; + + // If rango is the same, keep higher quality one + // Still, keep lower-quality one if it has lower Chi2 + // and if its BX is different to the higher-quality one + if (inMPaths[i].quality > inMPaths[j].quality) { + if ((inMPaths[i].chi2 < inMPaths[j].chi2) || BX(inMPaths[i]) == BX(inMPaths[j])) + keep_this[j] = false; + } else if (inMPaths[i].quality < inMPaths[j].quality) { + if ((inMPaths[i].chi2 > inMPaths[j].chi2) || BX(inMPaths[i]) == BX(inMPaths[j])) + keep_this[i] = false; + } else { // if they have same quality + // If quality is 8, keep both + // if (inMPaths[i].quality >= 8) continue; + // Otherwise, keep the one with better Chi2 + // and also the one with worse Chi2 if its BX is different + // else{ + if (inMPaths[i].chi2 > inMPaths[j].chi2 && BX(inMPaths[i]) == BX(inMPaths[j])) + keep_this[i] = false; + else if (inMPaths[i].chi2 < inMPaths[j].chi2 && BX(inMPaths[i]) == BX(inMPaths[j])) + keep_this[j] = false; + else + continue; + //} + } + } + } + } + // Finally, fill the output with accepted candidates + for (int i = 0; i < int(inMPaths.size()); i++) + if (keep_this[i] == true) + outMPaths.push_back(inMPaths[i]); + } +} + +void MPQualityEnhancerFilterBayes::printmP(metaPrimitive mP) { + DTSuperLayerId slId(mP.rawId); + LogDebug("MPQualityEnhancerFilterBayes") + << slId << "\t" + << " " << setw(2) << left << mP.wi1 << " " << setw(2) << left << mP.wi2 << " " << setw(2) << left << mP.wi3 << " " + << setw(2) << left << mP.wi4 << " " << setw(5) << left << mP.tdc1 << " " << setw(5) << left << mP.tdc2 << " " + << setw(5) << left << mP.tdc3 << " " << setw(5) << left << mP.tdc4 << " " << setw(10) << right << mP.x << " " + << setw(9) << left << mP.tanPhi << " " << setw(5) << left << mP.t0 << " " << setw(13) << left << mP.chi2 + << " r:" << rango(mP); +} diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyticAnalyzer.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyticAnalyzer.cc index 2fd16bef8ebe9..af37db9009701 100644 --- a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyticAnalyzer.cc +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyticAnalyzer.cc @@ -77,8 +77,7 @@ void MuonPathAnalyticAnalyzer::initialise(const edm::EventSetup &iEventSetup) { if (debug_) LogDebug("MuonPathAnalyticAnalyzer") << "MuonPathAnalyticAnalyzer::initialiase"; - edm::ESHandle geom; - iEventSetup.get().get(geometry_tag_, geom); + auto geom = iEventSetup.getHandle(dtGeomH); dtGeo_ = &(*geom); } diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc index 3e731678853f0..adc8b13211ef4 100644 --- a/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAnalyzerInChamber.cc @@ -56,8 +56,8 @@ void MuonPathAnalyzerInChamber::initialise(const edm::EventSetup &iEventSetup) { if (debug_) LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzerInChamber::initialiase"; - const MuonGeometryRecord &geom = iEventSetup.get(); - dtGeo_ = &geom.get(dtGeomH); + auto geom = iEventSetup.getHandle(dtGeomH); + dtGeo_ = geom.product(); } void MuonPathAnalyzerInChamber::run(edm::Event &iEvent, @@ -346,7 +346,7 @@ void MuonPathAnalyzerInChamber::buildLateralities(MuonPathPtr &mpath) { /* We generate all the possible laterality combinations compatible with the built group in the previous step*/ lateralities_.push_back(TLateralities()); - for (int ilat = 0; ilat < NLayers; ilat++) { + for (int ilat = 0; ilat < cmsdt::NUM_LAYERS_2SL; ilat++) { // Get value from input LATERAL_CASES lr = (mpath->lateralComb())[ilat]; if (debug_) @@ -394,7 +394,7 @@ void MuonPathAnalyzerInChamber::buildLateralities(MuonPathPtr &mpath) { if (debug_) { for (unsigned int iall = 0; iall < lateralities_.size(); iall++) { LogDebug("MuonPathAnalyzerInChamber") << iall << " -> ["; - for (int ilat = 0; ilat < NLayers; ilat++) { + for (int ilat = 0; ilat < cmsdt::NUM_LAYERS_2SL; ilat++) { if (ilat != 0) LogDebug("MuonPathAnalyzerInChamber") << ","; LogDebug("MuonPathAnalyzerInChamber") << lateralities_[iall][ilat]; diff --git a/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc b/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc index 890b892a83dec..e38ce037f8097 100644 --- a/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc +++ b/L1Trigger/DTTriggerPhase2/src/MuonPathAssociator.cc @@ -58,8 +58,7 @@ void MuonPathAssociator::initialise(const edm::EventSetup &iEventSetup) { if (debug_) LogDebug("MuonPathAssociator") << "MuonPathAssociator::initialiase"; - edm::ESHandle geom; - iEventSetup.get().get(geometry_tag_, geom); + auto geom = iEventSetup.getHandle(dtGeomH_); dtGeo_ = &(*geom); } diff --git a/L1Trigger/DTTriggerPhase2/src/RPCIntegrator.cc b/L1Trigger/DTTriggerPhase2/src/RPCIntegrator.cc index be8ea54910111..74b97c9cc3879 100644 --- a/L1Trigger/DTTriggerPhase2/src/RPCIntegrator.cc +++ b/L1Trigger/DTTriggerPhase2/src/RPCIntegrator.cc @@ -35,9 +35,14 @@ void RPCIntegrator::initialise(const edm::EventSetup& iEventSetup, double shift_ if (m_debug_) LogDebug("RPCIntegrator") << "Getting RPC geometry"; - const MuonGeometryRecord& geom = iEventSetup.get(); - dtGeo_ = &geom.get(dtGeomH_); - rpcGeo_ = &geom.get(rpcGeomH_); + if (auto handle = iEventSetup.getHandle(dtGeomH_)) { + dtGeo_ = handle.product(); + } + + if (auto handle = iEventSetup.getHandle(rpcGeomH_)) { + rpcGeo_ = handle.product(); + } + shift_back_ = shift_back_fromDT; } @@ -173,7 +178,7 @@ RPCMetaprimitive* RPCIntegrator::matchDTwithRPC(metaPrimitive* dt_metaprimitive) // just a trick to apply the phi window cut on what could be accessed to fine tune it int delta_phi = (int)round((phi_DT_MP_conv(rpc_mp_it->global_position.phi(), rpc_det_id.sector()) - dt_metaprimitive->phi) * - m_dt_phiB_granularity_); + cmsdt::PHIBRES_CONV); if (std::abs(delta_phi) < min_dPhi && std::abs(delta_phi) < m_phi_window_) { min_dPhi = std::abs(delta_phi); bestMatch_rpcRecHit = &*rpc_mp_it; @@ -195,7 +200,7 @@ L1Phase2MuDTPhDigi RPCIntegrator::createL1Phase2MuDTPhDigi( int rpc_station = rpcDetId.station(); int rpc_layer = rpcDetId.layer(); int rpc_trigger_phi = phiInDTTPFormat(rpc_global_phi, rpcDetId.sector()); - int rpc_trigger_phiB = (phiB == -10000) ? phiB : (int)round(phiB * m_dt_phiB_granularity_); + int rpc_trigger_phiB = (phiB == -10000) ? phiB : (int)round(phiB * cmsdt::PHIBRES_CONV); int rpc_quality = -1; // dummy for rpc int rpc_index = 0; // dummy for rpc return L1Phase2MuDTPhDigi(rpc_bx, @@ -228,7 +233,7 @@ double RPCIntegrator::phiBending(RPCMetaprimitive* rpc_hit_1, RPCMetaprimitive* int RPCIntegrator::phiInDTTPFormat(double rpc_global_phi, int rpcSector) { double rpc_localDT_phi; - rpc_localDT_phi = phi_DT_MP_conv(rpc_global_phi, rpcSector) * m_dt_phi_granularity_; + rpc_localDT_phi = phi_DT_MP_conv(rpc_global_phi, rpcSector) * cmsdt::PHIBRES_CONV; return (int)round(rpc_localDT_phi); } diff --git a/L1Trigger/DTTriggerPhase2/test/test_primitivesPhase2Prod.py b/L1Trigger/DTTriggerPhase2/test/test_primitivesPhase2Prod.py new file mode 100644 index 0000000000000..877c546004e70 --- /dev/null +++ b/L1Trigger/DTTriggerPhase2/test/test_primitivesPhase2Prod.py @@ -0,0 +1,71 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("L1DTTrigPhase2Prod") + +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') + +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") +process.load("Configuration.StandardSequences.MagneticField_cff") + +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') + +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") + +#scenario +process.dtTriggerPhase2PrimitiveDigis.scenario = 0 #0 is mc, 1 is data, 2 is slice test +process.CalibratedDigis.dtDigiTag = "simMuonDTDigis" +process.CalibratedDigis.scenario = 0 + +process.load('RecoLocalMuon.Configuration.RecoLocalMuon_cff') + +# STD +process.dtTriggerPhase2PrimitiveDigis.algo = 0 ## initial grouping +process.dtTriggerPhase2PrimitiveDigis.df_extended = 0 + +process.dtTriggerPhase2PrimitiveDigis.useRPC = True +process.rpcRecHits.rpcDigiLabel = "simMuonRPCDigis" + +# COMPARISON WITH FW +# process.dtTriggerPhase2PrimitiveDigis.useBX_correlation = True +# process.dtTriggerPhase2PrimitiveDigis.dBX_correlate_TP = 1 +# process.dtTriggerPhase2PrimitiveDigis.allow_confirmation = False +# process.dtTriggerPhase2PrimitiveDigis.max_primitives = 4 + + + + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring( + 'file:////eos/cms/store/user/folguera/P2L1TUpgrade/Mu_FlatPt2to100-pythia8-gun_file.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/941C1EA3-141B-6841-AE07-8E5D3ED57461.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/A37FFE18-21EF-5648-AFC8-56BF9CA76B58.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/86F62E38-D278-2841-8BB4-B25FCD44BFF7.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/7CA99B54-AA55-5047-8FCB-8E85DA5B85CE.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/763C6CDF-FF14-A745-AB9E-2A56819BEC78.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/2E88F5EC-8039-4A4D-A48E-A29E2A8C41E7.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/FFB599F9-D497-6943-9287-58E740519498.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/51EFC25B-E0FB-9B4B-B85C-EE4C5CE9C378.root', + # '/store/mc/PhaseIITDRSpring19DR/Mu_FlatPt2to100-pythia8-gun/GEN-SIM-DIGI-RAW/PU200_106X_upgrade2023_realistic_v3-v2/70000/F98EB821-7883-F34C-93AD-2CA3E790BC94.root', + +) + ) +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(100)) + +process.out = cms.OutputModule("PoolOutputModule", + outputCommands = cms.untracked.vstring( + 'drop *', + 'keep *_CalibratedDigis_*_*', + 'keep L1Phase2MuDT??Container_dtTriggerPhase2PrimitiveDigis_*_*', + ), + fileName = cms.untracked.string('DTTriggerPhase2Primitives.root') +) + +process.p = cms.Path(process.rpcRecHits * + process.CalibratedDigis * + process.dtTriggerPhase2PrimitiveDigis +) +process.this_is_the_end = cms.EndPath(process.out) diff --git a/L1Trigger/DemonstratorTools/BuildFile.xml b/L1Trigger/DemonstratorTools/BuildFile.xml new file mode 100644 index 0000000000000..d67b1e937c499 --- /dev/null +++ b/L1Trigger/DemonstratorTools/BuildFile.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/DemonstratorTools/interface/BoardData.h b/L1Trigger/DemonstratorTools/interface/BoardData.h new file mode 100644 index 0000000000000..f68c8c3d83ddb --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/BoardData.h @@ -0,0 +1,55 @@ + +#ifndef L1Trigger_DemonstratorTools_BoardData_h +#define L1Trigger_DemonstratorTools_BoardData_h + +#include +#include + +#include "L1Trigger/DemonstratorTools/interface/Frame.h" + +namespace l1t::demo { + + //! Class representing information that's stored in the input or output buffers on a phase-2 board + class BoardData { + public: + typedef std::vector Channel; + + BoardData(); + + BoardData(const std::string& name); + + BoardData(const std::string& name, const std::vector& channels, size_t length); + + const std::string& name() const; + + std::map::const_iterator begin() const; + + std::map::iterator begin(); + + std::map::const_iterator end() const; + + std::map::iterator end(); + + Channel& add(size_t); + + Channel& add(size_t, const Channel&); + + Channel& at(size_t); + + const Channel& at(size_t) const; + + bool has(size_t) const; + + // Returns number of channels + size_t size(); + + private: + std::string name_; + + // Map of channel indices to data + std::map data_; + }; + +} // namespace l1t::demo + +#endif \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/interface/BoardDataReader.h b/L1Trigger/DemonstratorTools/interface/BoardDataReader.h new file mode 100644 index 0000000000000..da180b9bbe9db --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/BoardDataReader.h @@ -0,0 +1,67 @@ + +#ifndef L1Trigger_DemonstratorTools_BoardDataReader_h +#define L1Trigger_DemonstratorTools_BoardDataReader_h + +#include +#include +#include + +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" +#include "L1Trigger/DemonstratorTools/interface/ChannelSpec.h" +#include "L1Trigger/DemonstratorTools/interface/EventData.h" +#include "L1Trigger/DemonstratorTools/interface/FileFormat.h" + +namespace l1t::demo { + + // Reads I/O buffer files created from hardware/firmware tests, verifying that + // received packets conform to the declared structure, separating out each + // event (accounting for different TM periods of specific links and of the + // data-processor itself), and transparently switching to data from new buffer + // files as needed + class BoardDataReader { + public: + // map of logical channel ID -> [TMUX period, interpacket-gap & offset; channel indices] + typedef std::map>> ChannelMap_t; + + BoardDataReader(FileFormat, + const std::vector&, + const size_t framesPerBX, + const size_t tmux, + const size_t emptyFramesAtStart, + const ChannelMap_t&); + + BoardDataReader(FileFormat, + const std::vector&, + const size_t framesPerBX, + const size_t tmux, + const size_t emptyFramesAtStart, + const std::map>&, + const std::map&); + + EventData getNextEvent(); + + private: + static ChannelMap_t mergeMaps(const std::map>&, + const std::map&); + + FileFormat fileFormat_; + + std::vector fileNames_; + + size_t framesPerBX_; + + size_t boardTMUX_; + + size_t emptyFramesAtStart_; + + // map of logical channel ID -> [TMUX period, interpacket-gap & offset; channel indices] + ChannelMap_t channelMap_; + + std::vector events_; + + std::vector::const_iterator eventIt_; + }; + +} // namespace l1t::demo + +#endif \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/interface/BoardDataWriter.h b/L1Trigger/DemonstratorTools/interface/BoardDataWriter.h new file mode 100644 index 0000000000000..30e7cd3369df7 --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/BoardDataWriter.h @@ -0,0 +1,78 @@ + +#ifndef L1Trigger_DemonstratorTools_BoardDataWriter_h +#define L1Trigger_DemonstratorTools_BoardDataWriter_h + +#include + +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" +#include "L1Trigger/DemonstratorTools/interface/EventData.h" +#include "L1Trigger/DemonstratorTools/interface/ChannelSpec.h" +#include "L1Trigger/DemonstratorTools/interface/FileFormat.h" + +namespace l1t::demo { + + // Writes I/O buffer files created from hardware/firmware tests, ensuring that + // the data conforms to the declared packet structure (by inserting invalid + // frames automatically), concatenating data from each event (accounting for + // different TM periods of specific links, and of the data-processor itself), + // and transparently switching to new output files when the data would overrun + // the length of the board's I/O buffers + class BoardDataWriter { + public: + // map of logical channel ID -> [TMUX period, interpacket-gap & offset; channel indices] + typedef std::map>> ChannelMap_t; + + BoardDataWriter(FileFormat, + const std::string& filePath, + const size_t framesPerBX, + const size_t tmux, + const size_t maxFramesPerFile, + const ChannelMap_t&); + + BoardDataWriter(FileFormat, + const std::string& filePath, + const size_t framesPerBX, + const size_t tmux, + const size_t maxFramesPerFile, + const std::map>&, + const std::map&); + + void addEvent(const EventData& data); + + // If there are events that have not been written to file, forces creation of a board data file containing them + void flush(); + + private: + static ChannelMap_t mergeMaps(const std::map>&, + const std::map&); + + void resetBoardData(); + + FileFormat fileFormat_; + + std::function filePathGen_; + + std::vector fileNames_; + + size_t framesPerBX_; + + size_t boardTMUX_; + + size_t maxFramesPerFile_; + + size_t maxEventsPerFile_; + + size_t eventIndex_; + + // Number of events stored in boardData_ + size_t pendingEvents_; + + BoardData boardData_; + + // map of logical channel ID -> [TMUX period, interpacket-gap & offset; channel indices] + ChannelMap_t channelMap_; + }; + +} // namespace l1t::demo + +#endif \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/interface/ChannelSpec.h b/L1Trigger/DemonstratorTools/interface/ChannelSpec.h new file mode 100644 index 0000000000000..0a737cf8ecd1b --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/ChannelSpec.h @@ -0,0 +1,20 @@ +#ifndef L1Trigger_DemonstratorTools_ChannelSpec_h +#define L1Trigger_DemonstratorTools_ChannelSpec_h + +#include + +namespace l1t::demo { + + struct ChannelSpec { + public: + // Time multiplexing period of data on link + size_t tmux; + // Number of invalid frames between packets (i.e. following each event) + size_t interpacketGap; + // Number of invalid frames before first valid packet + size_t offset{0}; + }; + +} // namespace l1t::demo + +#endif \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/interface/EventData.h b/L1Trigger/DemonstratorTools/interface/EventData.h new file mode 100644 index 0000000000000..4579504fbcd2f --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/EventData.h @@ -0,0 +1,58 @@ + +#ifndef L1Trigger_DemonstratorTools_EventData_h +#define L1Trigger_DemonstratorTools_EventData_h + +#include +#include +#include + +#include "ap_int.h" + +#include "L1Trigger/DemonstratorTools/interface/LinkId.h" + +namespace l1t::demo { + + /*! + * \brief Class representing information phase-2 ATCA I/O data corresponding to a single event, + * with logical channel IDs (essentially string-uint pairs, e.g. tracks-0 to tracks-17). + * + * This class is used to provide an event-index-independent interface to the BoardDataWriter & + * BoardDataReader classes - i.e. to avoid any need to keep track of `eventIndex % tmux` when + * using that class for boards whose TMUX period is less than any of their upstream systems. + * One logical channel ID corresponds to different I/O channel indices from one event to the + * next for the input channels of a board have a higher TMUX period than the board (e.g. for + * tracks sent to the correlator/GMT/GTT, or for the GMT, GTT and correlator links into GT); the + * mapping of logical channel IDs to I/O channel indices is implemented in the BoardDataWriter + * and BoardDataReader classes. + */ + class EventData { + public: + typedef std::map>>::const_iterator const_iterator; + + EventData(); + + EventData(const std::map>>&); + + const_iterator begin() const; + + const_iterator end() const; + + void add(const LinkId&, const std::vector>&); + + void add(const EventData&); + + const std::vector>& at(const LinkId&) const; + + bool has(const LinkId&) const; + + // Returns number of channels + size_t size(); + + private: + // Map of channel IDs to data + std::map>> data_; + }; + +} // namespace l1t::demo + +#endif \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/interface/FileFormat.h b/L1Trigger/DemonstratorTools/interface/FileFormat.h new file mode 100644 index 0000000000000..06d5bc15b7bcb --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/FileFormat.h @@ -0,0 +1,15 @@ + +#ifndef L1Trigger_DemonstratorTools_FileFormat_h +#define L1Trigger_DemonstratorTools_FileFormat_h + +#include + +namespace l1t::demo { + + enum class FileFormat { APx, EMP, X20 }; + + std::ostream& operator<<(std::ostream&, FileFormat); + +} // namespace l1t::demo + +#endif diff --git a/L1Trigger/DemonstratorTools/interface/Frame.h b/L1Trigger/DemonstratorTools/interface/Frame.h new file mode 100644 index 0000000000000..00534443bb57d --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/Frame.h @@ -0,0 +1,27 @@ + +#ifndef L1Trigger_DemonstratorTools_Frame_h +#define L1Trigger_DemonstratorTools_Frame_h + +#include + +#include "ap_int.h" + +namespace l1t::demo { + + struct Frame { + Frame() = default; + + Frame(const uint64_t); + + Frame(const ap_uint<64>&); + + ap_uint<64> data{0}; + bool valid{false}; + bool strobe{true}; + bool start{false}; + bool end{false}; + }; + +} // namespace l1t::demo + +#endif diff --git a/L1Trigger/DemonstratorTools/interface/LinkId.h b/L1Trigger/DemonstratorTools/interface/LinkId.h new file mode 100644 index 0000000000000..cb2592ecfbcc3 --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/LinkId.h @@ -0,0 +1,19 @@ +#ifndef L1Trigger_DemonstratorTools_LinkId_h +#define L1Trigger_DemonstratorTools_LinkId_h + +#include +#include + +namespace l1t::demo { + + //! Logical ID for link within any given time slice (e.g. ["tracks", 0] -> ["tracks", 17] for links from TF) + struct LinkId { + std::string interface; + size_t channel{0}; + }; + + bool operator<(const LinkId&, const LinkId&); + +} // namespace l1t::demo + +#endif \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/interface/codecs/etsums.h b/L1Trigger/DemonstratorTools/interface/codecs/etsums.h new file mode 100644 index 0000000000000..543c18f18f842 --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/codecs/etsums.h @@ -0,0 +1,27 @@ + +#ifndef L1Trigger_DemonstratorTools_codecs_EtSum_h +#define L1Trigger_DemonstratorTools_codecs_EtSum_h + +#include +#include + +#include "ap_int.h" + +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/Math/interface/LorentzVector.h" +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h" + +namespace l1t::demo::codecs { + + ap_uint<64> encodeEtSum(const l1t::EtSum& v); + + // Encodes EtSum collection onto 1 'logical' output link + std::array>, 1> encodeEtSums(const edm::View&); + + std::vector decodeEtSums(const std::vector>&); + +} // namespace l1t::demo::codecs + +#endif diff --git a/L1Trigger/DemonstratorTools/interface/codecs/htsums.h b/L1Trigger/DemonstratorTools/interface/codecs/htsums.h new file mode 100644 index 0000000000000..bd238af66c4b1 --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/codecs/htsums.h @@ -0,0 +1,27 @@ + +#ifndef L1Trigger_DemonstratorTools_codecs_HtSum_h +#define L1Trigger_DemonstratorTools_codecs_HtSum_h + +#include +#include + +#include "ap_int.h" + +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/Math/interface/LorentzVector.h" +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkHTMissEmulatorProducer.h" + +namespace l1t::demo::codecs { + + ap_uint<64> encodeHtSum(const l1t::EtSum& v); + + // Encodes EtSum collection onto 1 'logical' output link + std::array>, 1> encodeHtSums(const edm::View&); + + std::vector decodeHtSums(const std::vector>&); + +} // namespace l1t::demo::codecs + +#endif diff --git a/L1Trigger/DemonstratorTools/interface/codecs/tkjets.h b/L1Trigger/DemonstratorTools/interface/codecs/tkjets.h new file mode 100644 index 0000000000000..c188aded6873d --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/codecs/tkjets.h @@ -0,0 +1,27 @@ + +#ifndef L1Trigger_DemonstratorTools_codecs_tkjets_h +#define L1Trigger_DemonstratorTools_codecs_tkjets_h + +#include +#include + +#include "ap_int.h" + +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/L1TCorrelator/interface/TkJet.h" +#include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" +#include "DataFormats/L1Trigger/interface/TkJetWord.h" +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" + +namespace l1t::demo::codecs { + + ap_uint<64> encodeTkJet(const l1t::TkJetWord& t); + + // Encodes TkJet collection onto 1 'logical' output link + std::array>, 1> encodeTkJets(const edm::View&); + + std::vector decodeTkJets(const std::vector>&); + +} // namespace l1t::demo::codecs + +#endif diff --git a/L1Trigger/DemonstratorTools/interface/codecs/tracks.h b/L1Trigger/DemonstratorTools/interface/codecs/tracks.h new file mode 100644 index 0000000000000..0862a18900a45 --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/codecs/tracks.h @@ -0,0 +1,53 @@ + +#ifndef L1Trigger_DemonstratorTools_codecs_tracks_h +#define L1Trigger_DemonstratorTools_codecs_tracks_h + +#include +#include +#include + +#include "ap_int.h" + +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" + +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" + +namespace l1t::demo::codecs { + + // Return true if a track is contained within a collection + bool trackInCollection(const edm::Ref>>&, + const edm::Handle>>>&); + + // Encodes a single track into a 96-bit track word + ap_uint<96> encodeTrack(const TTTrack_TrackWord& t); + + // Return the 96-bit track words from a given track collection and place them on the appropriate 18 'logical' links + std::array>, 18> getTrackWords(const edm::View>&); + std::array>, 18> getTrackWords( + const edm::Handle>>&, + const edm::Handle>>>&); + + // Encodes track collection onto 18 'logical' output links (2x9 eta-phi sectors; -/+ eta pairs) + std::array>, 18> encodeTracks(const edm::View>&, + int debug = 0); + + // Encodes a track collection based off the ordering of another track collection + // Requirement: The second collection must be a subset of the first + std::array>, 18> encodeTracks( + const edm::Handle>>&, + const edm::Handle>>>&, + int debug = 0); + + // Decodes the tracks for a single link + std::vector decodeTracks(const std::vector>&); + + // Decodes the tracks from 18 'logical' output links (2x9 eta-phi sectors; , -/+ eta pairs) + std::array, 18> decodeTracks(const std::array>, 18>&); + +} // namespace l1t::demo::codecs + +#endif diff --git a/L1Trigger/DemonstratorTools/interface/codecs/vertices.h b/L1Trigger/DemonstratorTools/interface/codecs/vertices.h new file mode 100644 index 0000000000000..4f17131c1cbad --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/codecs/vertices.h @@ -0,0 +1,26 @@ + +#ifndef L1Trigger_DemonstratorTools_codecs_vertices_h +#define L1Trigger_DemonstratorTools_codecs_vertices_h + +#include +#include + +#include "ap_int.h" + +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" + +namespace l1t::demo::codecs { + + ap_uint<64> encodeVertex(const l1t::VertexWord& v); + + // Encodes vertex collection onto 1 'logical' output link + std::array>, 1> encodeVertices(const edm::View&); + + std::vector decodeVertices(const std::vector>&); + +} // namespace l1t::demo::codecs + +#endif diff --git a/L1Trigger/DemonstratorTools/interface/utilities.h b/L1Trigger/DemonstratorTools/interface/utilities.h new file mode 100644 index 0000000000000..3d4d9ef8c38a4 --- /dev/null +++ b/L1Trigger/DemonstratorTools/interface/utilities.h @@ -0,0 +1,25 @@ + +#ifndef L1Trigger_DemonstratorTools_utilities_h +#define L1Trigger_DemonstratorTools_utilities_h + +#include + +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" +#include "L1Trigger/DemonstratorTools/interface/FileFormat.h" + +namespace l1t::demo { + + // Simple function that converts string to file format enum (for e.g. CMSSW configs) + FileFormat parseFileFormat(const std::string&); + + BoardData read(const std::string& filePath, const FileFormat); + + BoardData read(std::istream&, const FileFormat); + + void write(const BoardData&, const std::string& filePath, const FileFormat); + + void write(const BoardData&, std::ostream&, const FileFormat); + +} // namespace l1t::demo + +#endif \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/notes.md b/L1Trigger/DemonstratorTools/notes.md new file mode 100644 index 0000000000000..ac3b5e919cf6e --- /dev/null +++ b/L1Trigger/DemonstratorTools/notes.md @@ -0,0 +1,59 @@ +Common L1T utilities for demonstrators +====================================== + +This package contains a prototype implementation of subsystem-agnostic utility functions and +classes for converting between emulator input/output objects (i.e. C++ objects representing +tracks, calo clusters, muon TPs, vertices etc) and the I/O buffer text files (i.e. the files +that are used to store data that is loaded into or captured from FPGAs, and used to play/capture +data in HDL simulations). The motivation for these tools and their scope was briefly summarised +in the L1T meeting on 16th February (see slides [here](https://indico.cern.ch/event/1008519/contributions/4234188/attachments/2191061/3703176/l1tPhase2_cmsswBufferIO_20210216.pdf)) + +A brief tour of the code: + + * One example EDAnalyzer - `GTTFileWriter` - that creates text files for loading into + input buffers of the GTT board (as well as reference files for outputs of GTT boards) + * Source: `plugins/GTTFileWriter.cc` + * Test cmsRun config: `test/gtt/createFirmwareInputFiles_cfg.py` + * One example EDProducer - `GTTFileReader` - that reads text files that would be + produced by GTT vertex-finding FW + * Source: `plugins/GTTFileReader.cc` + * Test cmsRun config: `test/gtt/verifyFirmwareOutput_cfg.py` + * Main utility classes: + - `BoardData`: Represents the data stored in I/O buffers + - `ChannelSpec`: Simple struct containing parameters that define a link's packet + structure (e.g. TMUX period, gap between packets) + - `EventData`: Represents the data corresponding to a single event, with links + labelled using logical channel IDs (`LinkId` class instances) that are local + to any given time slice (e.g. ["tracks", 0] -> ["tracks", 17] for links from + TF). Used to provide an event-index-independent interface to the + `BoardDataWriter` & `BoardDataReader` classes - i.e. to avoid any need to keep + track of `eventIndex % tmux` when using the reader & writer classes for boards + whose TMUX period is less than any of their upstream systems. + - `BoardDataReader`: This class ... + 1. reads a set of buffer files + 2. verifies data conforms to expected structure + 3. splits out each event; and + 4. returns data for each event in turn via `getNextEvent()` method + - `BoardDataWriter`: Essentially, does the opposite of the reader - + 1. accepts per-event data via `addEvent` method + 2. concatenates events according to specified structure; and + 3. automatically writes out pending data to file whenever the limit on the + number of frames per file is reached. + +(Note: For simplicity this code has been put in its own package during development, +but this might not be its final location.) + +Given the above, the contents of `GTTFileWriter.cc` and `GTTFileReader.cc` +should be mostly self-explanatory, but a couple of additional notes: + + * These `.cc` files each contain some hardcoded constants defining the link TM periods, + TM indices, packet structure etc. that are used to create the `BoardDataReader`/`BoardDataWriter` + instance (so that it can correctly separate/concatenate events). + * At least some (if not all) of these types of constants should eventually be read from + config files, to avoid e.g. needing to recompile code when the latency of an algo changes + * The EDAnalyzer/EDProducer analyze/produce methods use functions from the 'codecs' directory + to convert between EDM collections and vectors of `ap_uint<64>`. + +Finally: Suggestions (and implementations) for improvements most welcome, but please get in +touch with Tom Williams about these before writing large amounts of code, to avoid duplicating +efforts or divergent solutions to the same problem. diff --git a/L1Trigger/DemonstratorTools/plugins/BuildFile.xml b/L1Trigger/DemonstratorTools/plugins/BuildFile.xml new file mode 100644 index 0000000000000..744d43e2b43ea --- /dev/null +++ b/L1Trigger/DemonstratorTools/plugins/BuildFile.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/L1Trigger/DemonstratorTools/plugins/GTTFileReader.cc b/L1Trigger/DemonstratorTools/plugins/GTTFileReader.cc new file mode 100644 index 0000000000000..459f79f82a8f0 --- /dev/null +++ b/L1Trigger/DemonstratorTools/plugins/GTTFileReader.cc @@ -0,0 +1,110 @@ +// -*- C++ -*- +// +// Package: L1Trigger/DemonstratorTools +// Class: GTTFileReader +// +/**\class GTTFileReader GTTFileReader.cc L1Trigger/DemonstratorTools/plugins/GTTFileReader.cc + + Description: Example EDProducer class, illustrating how BoardDataReader can be used to + read I/O buffer files (that have been created in hardware/firmware tests), decode + the contained data, and store this in EDM collections. + + Implementation: + [Notes on implementation] +*/ +// +// Original Author: Thomas Williams +// Created: Fri, 19 Feb 2021 01:10:55 GMT +// +// + +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "DataFormats/L1Trigger/interface/Vertex.h" +#include "L1Trigger/DemonstratorTools/interface/BoardDataReader.h" +#include "L1Trigger/DemonstratorTools/interface/codecs/vertices.h" +#include "L1Trigger/DemonstratorTools/interface/utilities.h" + +// +// class declaration +// + +class GTTFileReader : public edm::stream::EDProducer<> { +public: + explicit GTTFileReader(const edm::ParameterSet&); + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + // ----------constants, enums and typedefs --------- + // NOTE: At least some of the info from these constants will eventually come from config files + static constexpr size_t kFramesPerTMUXPeriod = 9; + static constexpr size_t kGapLength = 44; + static constexpr size_t kVertexTMUX = 6; + static constexpr size_t kVertexChanIndex = 0; + static constexpr size_t kEmptyFrames = 10; + + const l1t::demo::BoardDataReader::ChannelMap_t kChannelSpecs = { + /* logical channel within time slice -> {{link TMUX, inter-packet gap}, vector of channel indices} */ + {{"vertices", 0}, {{kVertexTMUX, kGapLength}, {kVertexChanIndex}}}}; + + // ----------member functions ---------------------- + void produce(edm::Event&, const edm::EventSetup&) override; + + // ----------member data --------------------------- + l1t::demo::BoardDataReader fileReader_; +}; + +// +// class implementation +// + +GTTFileReader::GTTFileReader(const edm::ParameterSet& iConfig) + : fileReader_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), + iConfig.getParameter>("files"), + kFramesPerTMUXPeriod, + kVertexTMUX, + kEmptyFrames, + kChannelSpecs) { + produces(); +} + +// ------------ method called to produce the data ------------ +void GTTFileReader::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + using namespace l1t::demo::codecs; + + l1t::demo::EventData eventData(fileReader_.getNextEvent()); + + l1t::VertexWordCollection vertices(decodeVertices(eventData.at({"vertices", 0}))); + + edm::LogInfo("GTTFileReader") << vertices.size() << " vertices found"; + + iEvent.put(std::make_unique(vertices)); +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void GTTFileReader::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // GTTFileReader + edm::ParameterSetDescription desc; + desc.add>("files", + { + "gttOutput_0.txt", + }); + desc.addUntracked("format", "APx"); + descriptions.add("GTTFileReader", desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(GTTFileReader); diff --git a/L1Trigger/DemonstratorTools/plugins/GTTFileWriter.cc b/L1Trigger/DemonstratorTools/plugins/GTTFileWriter.cc new file mode 100644 index 0000000000000..a332335f8679a --- /dev/null +++ b/L1Trigger/DemonstratorTools/plugins/GTTFileWriter.cc @@ -0,0 +1,316 @@ +// -*- C++ -*- +// +// Package: L1Trigger/DemonstratorTools +// Class: GTTFileWriter +// +/**\class GTTFileWriter GTTFileWriter.cc L1Trigger/DemonstratorTools/plugins/GTTFileWriter.cc + + Description: Example EDAnalyzer class, illustrating how BoardDataWriter can be used to + write I/O buffer files for hardware/firmware tests + + Implementation: + [Notes on implementation] +*/ +// +// Original Author: Thomas Williams +// Created: Mon, 15 Feb 2021 00:39:44 GMT +// +// + +// system include files +#include + +#include "ap_int.h" + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.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/Common/interface/Handle.h" +#include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" + +#include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h" +#include "L1Trigger/DemonstratorTools/interface/codecs/tracks.h" +#include "L1Trigger/DemonstratorTools/interface/codecs/vertices.h" +#include "L1Trigger/DemonstratorTools/interface/codecs/tkjets.h" +#include "L1Trigger/DemonstratorTools/interface/codecs/htsums.h" +#include "L1Trigger/DemonstratorTools/interface/codecs/etsums.h" +#include "L1Trigger/DemonstratorTools/interface/utilities.h" + +// +// class declaration +// + +class GTTFileWriter : public edm::one::EDAnalyzer { +public: + explicit GTTFileWriter(const edm::ParameterSet&); + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + // ----------constants, enums and typedefs --------- + // NOTE: At least some of the info from these constants will eventually come from config files + static constexpr size_t kFramesPerTMUXPeriod = 9; + static constexpr size_t kGapLengthInput = 6; + static constexpr size_t kGapLengthOutputToCorrelator = 44; + static constexpr size_t kGapLengthOutputToGlobalTriggerSums = 3; + static constexpr size_t kGapLengthOutputToGlobalTriggerTaus = 36; + static constexpr size_t kGapLengthOutputToGlobalTriggerMesons = 15; + static constexpr size_t kGapLengthOutputToGlobalTriggerVertices = 6; + static constexpr size_t kTrackTMUX = 18; + static constexpr size_t kGTTBoardTMUX = 6; + static constexpr size_t kMaxLinesPerFile = 1024; + + const std::map> kChannelIdsInput = { + /* logical channel within time slice -> vector of channel indices (one entry per time slice) */ + {{"tracks", 0}, {0, 18, 36}}, + {{"tracks", 1}, {1, 19, 37}}, + {{"tracks", 2}, {2, 20, 38}}, + {{"tracks", 3}, {3, 21, 39}}, + {{"tracks", 4}, {4, 22, 40}}, + {{"tracks", 5}, {5, 23, 41}}, + {{"tracks", 6}, {6, 24, 42}}, + {{"tracks", 7}, {7, 25, 43}}, + {{"tracks", 8}, {8, 26, 44}}, + {{"tracks", 9}, {9, 27, 45}}, + {{"tracks", 10}, {10, 28, 46}}, + {{"tracks", 11}, {11, 29, 47}}, + {{"tracks", 12}, {12, 30, 48}}, + {{"tracks", 13}, {13, 31, 49}}, + {{"tracks", 14}, {14, 32, 50}}, + {{"tracks", 15}, {15, 33, 51}}, + {{"tracks", 16}, {16, 34, 52}}, + {{"tracks", 17}, {17, 35, 53}}}; + + const std::map kChannelSpecsInput = { + /* interface name -> {link TMUX, inter-packet gap} */ + {"tracks", {kTrackTMUX, kGapLengthInput}}}; + + const std::map>> + kChannelSpecsOutputToCorrelator = { + /* logical channel within time slice -> {{link TMUX, inter-packet gap}, vector of channel indices} */ + {{"vertices", 0}, {{kGTTBoardTMUX, kGapLengthOutputToCorrelator}, {0}}}}; + + const std::map> kChannelIdsOutputToGlobalTrigger = { + /* logical channel within time slice -> vector of channel indices (one entry per time slice) */ + {{"sums", 0}, {0}}, + {{"taus", 1}, {1}}, + {{"mesons", 2}, {2}}, + {{"vertices", 3}, {3}}}; + + const std::map kChannelSpecsOutputToGlobalTrigger = { + /* interface name -> {link TMUX, inter-packet gap} */ + {"sums", {kGTTBoardTMUX, kGapLengthOutputToGlobalTriggerSums}}, + {"taus", {kGTTBoardTMUX, kGapLengthOutputToGlobalTriggerTaus}}, + {"mesons", {kGTTBoardTMUX, kGapLengthOutputToGlobalTriggerMesons}}, + {"vertices", {kGTTBoardTMUX, kGapLengthOutputToGlobalTriggerVertices}}}; + + typedef TTTrack Track_t; + typedef std::vector TrackCollection_t; + typedef edm::RefVector TrackRefCollection_t; + + // ----------member functions ---------------------- + void analyze(const edm::Event&, const edm::EventSetup&) override; + void endJob() override; + + // ----------member data --------------------------- + edm::EDGetTokenT> tracksToken_; + edm::EDGetTokenT> convertedTracksToken_; + edm::EDGetTokenT convertedTrackCollectionToken_; + edm::EDGetTokenT selectedTracksToken_; + edm::EDGetTokenT vertexAssociatedTracksToken_; + edm::EDGetTokenT> verticesToken_; + edm::EDGetTokenT> jetsToken_; + edm::EDGetTokenT> htMissToken_; + edm::EDGetTokenT> etMissToken_; + + l1t::demo::BoardDataWriter fileWriterInputTracks_; + l1t::demo::BoardDataWriter fileWriterConvertedTracks_; + l1t::demo::BoardDataWriter fileWriterSelectedTracks_; + l1t::demo::BoardDataWriter fileWriterVertexAssociatedTracks_; + l1t::demo::BoardDataWriter fileWriterOutputToCorrelator_; + l1t::demo::BoardDataWriter fileWriterOutputToGlobalTrigger_; +}; + +// +// class implementation +// + +GTTFileWriter::GTTFileWriter(const edm::ParameterSet& iConfig) + : tracksToken_(consumes>(iConfig.getUntrackedParameter("tracks"))), + convertedTracksToken_( + consumes>(iConfig.getUntrackedParameter("convertedTracks"))), + convertedTrackCollectionToken_( + consumes(iConfig.getUntrackedParameter("convertedTracks"))), + selectedTracksToken_( + consumes(iConfig.getUntrackedParameter("selectedTracks"))), + vertexAssociatedTracksToken_( + consumes(iConfig.getUntrackedParameter("vertexAssociatedTracks"))), + verticesToken_(consumes>(iConfig.getUntrackedParameter("vertices"))), + jetsToken_(consumes>(iConfig.getUntrackedParameter("jets"))), + htMissToken_(consumes>(iConfig.getUntrackedParameter("htmiss"))), + etMissToken_(consumes>(iConfig.getUntrackedParameter("etmiss"))), + fileWriterInputTracks_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), + iConfig.getUntrackedParameter("inputFilename"), + kFramesPerTMUXPeriod, + kGTTBoardTMUX, + kMaxLinesPerFile, + kChannelIdsInput, + kChannelSpecsInput), + fileWriterConvertedTracks_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), + iConfig.getUntrackedParameter("inputConvertedFilename"), + kFramesPerTMUXPeriod, + kGTTBoardTMUX, + kMaxLinesPerFile, + kChannelIdsInput, + kChannelSpecsInput), + fileWriterSelectedTracks_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), + iConfig.getUntrackedParameter("selectedTracksFilename"), + kFramesPerTMUXPeriod, + kGTTBoardTMUX, + kMaxLinesPerFile, + kChannelIdsInput, + kChannelSpecsInput), + fileWriterVertexAssociatedTracks_( + l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), + iConfig.getUntrackedParameter("vertexAssociatedTracksFilename"), + kFramesPerTMUXPeriod, + kGTTBoardTMUX, + kMaxLinesPerFile, + kChannelIdsInput, + kChannelSpecsInput), + fileWriterOutputToCorrelator_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), + iConfig.getUntrackedParameter("outputCorrelatorFilename"), + kFramesPerTMUXPeriod, + kGTTBoardTMUX, + kMaxLinesPerFile, + kChannelSpecsOutputToCorrelator), + fileWriterOutputToGlobalTrigger_(l1t::demo::parseFileFormat(iConfig.getUntrackedParameter("format")), + iConfig.getUntrackedParameter("outputGlobalTriggerFilename"), + kFramesPerTMUXPeriod, + kGTTBoardTMUX, + kMaxLinesPerFile, + kChannelIdsOutputToGlobalTrigger, + kChannelSpecsOutputToGlobalTrigger) {} + +void GTTFileWriter::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + using namespace l1t::demo::codecs; + + // 0) Gather the necessary collections + const auto& tracksCollection = iEvent.get(tracksToken_); + const auto& convertedTracksCollection = iEvent.get(convertedTracksToken_); + const auto& verticesCollection = iEvent.get(verticesToken_); + const auto& jetsCollection = iEvent.get(jetsToken_); + const auto& htMissCollection = iEvent.get(htMissToken_); + const auto& etMissCollection = iEvent.get(etMissToken_); + + edm::Handle convertedTracksHandle; + edm::Handle selectedTracksHandle; + edm::Handle vertexAssociatedTracksHandle; + iEvent.getByToken(convertedTrackCollectionToken_, convertedTracksHandle); + iEvent.getByToken(selectedTracksToken_, selectedTracksHandle); + iEvent.getByToken(vertexAssociatedTracksToken_, vertexAssociatedTracksHandle); + + // 1) Encode 'object' information onto vectors containing link data + const auto trackData(encodeTracks(tracksCollection)); + const auto convertedTrackData(encodeTracks(convertedTracksCollection)); + const auto selectedTrackData(encodeTracks(convertedTracksHandle, selectedTracksHandle)); + const auto vertexAssociatedTrackData(encodeTracks(convertedTracksHandle, vertexAssociatedTracksHandle)); + const auto vertexData(encodeVertices(verticesCollection)); + const auto jetsData(encodeTkJets(jetsCollection)); + const auto htMissData(encodeHtSums(htMissCollection)); + const auto etMissData(encodeEtSums(etMissCollection)); + + // 2) Pack 'object' information into 'event data' object + l1t::demo::EventData eventDataTracks; + l1t::demo::EventData eventDataConvertedTracks; + l1t::demo::EventData eventDataSelectedTracks; + l1t::demo::EventData eventDataVertexAssociatedTracks; + for (size_t i = 0; i < 18; i++) { + eventDataTracks.add({"tracks", i}, trackData.at(i)); + eventDataConvertedTracks.add({"tracks", i}, convertedTrackData.at(i)); + eventDataSelectedTracks.add({"tracks", i}, selectedTrackData.at(i)); + eventDataVertexAssociatedTracks.add({"tracks", i}, vertexAssociatedTrackData.at(i)); + } + + l1t::demo::EventData eventDataVertices; + eventDataVertices.add({"vertices", 0}, vertexData.at(0)); + + // 2b) For the global trigger 'event data' combine different objects into one 'logical' link + std::vector> sumsData; + sumsData.insert(sumsData.end(), jetsData.at(0).begin(), jetsData.at(0).end()); + sumsData.insert(sumsData.end(), 24, 0); + sumsData.insert(sumsData.end(), htMissData.at(0).begin(), htMissData.at(0).end()); + sumsData.insert(sumsData.end(), 1, 0); + sumsData.insert(sumsData.end(), etMissData.at(0).begin(), etMissData.at(0).end()); + + std::vector> tracksVerticesData; + tracksVerticesData.insert(tracksVerticesData.end(), 36, 0); + tracksVerticesData.insert(tracksVerticesData.end(), vertexData.at(0).begin(), vertexData.at(0).end()); + tracksVerticesData.insert(tracksVerticesData.end(), 2, 0); + + l1t::demo::EventData eventDataGlobalTrigger; + eventDataGlobalTrigger.add({"sums", 0}, sumsData); + eventDataGlobalTrigger.add({"taus", 1}, std::vector>(18, 0)); // Placeholder until tau object is written + eventDataGlobalTrigger.add({"mesons", 2}, + std::vector>(39, 0)); // Placeholder until light meson objects are written + eventDataGlobalTrigger.add({"vertices", 3}, tracksVerticesData); + + // 3) Pass the 'event data' object to the file writer + + fileWriterInputTracks_.addEvent(eventDataTracks); + fileWriterConvertedTracks_.addEvent(eventDataConvertedTracks); + fileWriterSelectedTracks_.addEvent(eventDataSelectedTracks); + fileWriterVertexAssociatedTracks_.addEvent(eventDataVertexAssociatedTracks); + fileWriterOutputToCorrelator_.addEvent(eventDataVertices); + fileWriterOutputToGlobalTrigger_.addEvent(eventDataGlobalTrigger); +} + +// ------------ method called once each job just after ending the event loop ------------ +void GTTFileWriter::endJob() { + // Writing pending events to file before exiting + fileWriterInputTracks_.flush(); + fileWriterConvertedTracks_.flush(); + fileWriterOutputToCorrelator_.flush(); + fileWriterOutputToGlobalTrigger_.flush(); +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void GTTFileWriter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // GTTFileWriter + edm::ParameterSetDescription desc; + desc.addUntracked("tracks", edm::InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks")); + desc.addUntracked("convertedTracks", edm::InputTag("L1GTTInputProducer", "Level1TTTracksConverted")); + desc.addUntracked("selectedTracks", + edm::InputTag("L1TrackSelectionProducer", "Level1TTTracksSelectedEmulation")); + desc.addUntracked( + "vertexAssociatedTracks", edm::InputTag("L1TrackSelectionProducer", "Level1TTTracksSelectedAssociatedEmulation")); + desc.addUntracked("vertices", edm::InputTag("VertexProducer", "l1verticesEmulation")); + desc.addUntracked("jets", edm::InputTag("L1TrackJetsEmulation", "L1TrackJets")); + desc.addUntracked("htmiss", edm::InputTag("L1TrackerEmuHTMiss", "L1TrackerEmuHTMiss")); + desc.addUntracked("etmiss", edm::InputTag("L1TrackerEmuEtMiss", "L1TrackerEmuEtMiss")); + desc.addUntracked("inputFilename", "L1GTTInputFile"); + desc.addUntracked("inputConvertedFilename", "L1GTTInputConvertedFile"); + desc.addUntracked("selectedTracksFilename", "L1GTTSelectedTracksFile"); + desc.addUntracked("vertexAssociatedTracksFilename", "L1GTTVertexAssociatedTracksFile"); + desc.addUntracked("outputCorrelatorFilename", "L1GTTOutputToCorrelatorFile"); + desc.addUntracked("outputGlobalTriggerFilename", "L1GTTOutputToGlobalTriggerFile"); + desc.addUntracked("format", "APx"); + descriptions.add("GTTFileWriter", desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(GTTFileWriter); diff --git a/L1Trigger/DemonstratorTools/python/GTTFileReader_cff.py b/L1Trigger/DemonstratorTools/python/GTTFileReader_cff.py new file mode 100644 index 0000000000000..0a5c25c0f714f --- /dev/null +++ b/L1Trigger/DemonstratorTools/python/GTTFileReader_cff.py @@ -0,0 +1,6 @@ +import FWCore.ParameterSet.Config as cms + +GTTFileReader = cms.EDProducer('GTTFileReader', + files = cms.vstring("gttOutput_0.txt"), #, "gttOutput_1.txt"), + format = cms.untracked.string("APx") +) \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/python/GTTFileWriter_cff.py b/L1Trigger/DemonstratorTools/python/GTTFileWriter_cff.py new file mode 100644 index 0000000000000..6909b258db601 --- /dev/null +++ b/L1Trigger/DemonstratorTools/python/GTTFileWriter_cff.py @@ -0,0 +1,19 @@ +import FWCore.ParameterSet.Config as cms + +GTTFileWriter = cms.EDAnalyzer('GTTFileWriter', + tracks = cms.untracked.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), + convertedTracks = cms.untracked.InputTag("L1GTTInputProducer", "Level1TTTracksConverted"), + vertices = cms.untracked.InputTag("VertexProducer", "l1verticesEmulation"), + selectedTracks = cms.untracked.InputTag("L1TrackSelectionProducer", "Level1TTTracksSelectedEmulation"), + vertexAssociatedTracks = cms.untracked.InputTag("L1TrackSelectionProducer", "Level1TTTracksSelectedAssociatedEmulation"), + jets = cms.untracked.InputTag("L1TrackJetsEmulation","L1TrackJets"), + htmiss = cms.untracked.InputTag("L1TrackerEmuHTMiss", "L1TrackerEmuHTMiss"), + etmiss = cms.untracked.InputTag("L1TrackerEmuEtMiss", "L1TrackerEmuEtMiss"), + inputFilename = cms.untracked.string("L1GTTInputFile"), + inputConvertedFilename = cms.untracked.string("L1GTTInputConvertedFile"), + selectedTracksFilename = cms.untracked.string("L1GTTSelectedTracksFile"), + vertexAssociatedTracksFilename = cms.untracked.string("L1GTTVertexAssociatedTracksFile"), + outputCorrelatorFilename = cms.untracked.string("L1GTTOutputToCorrelatorFile"), + outputGlobalTriggerFilename = cms.untracked.string("L1GTTOutputToGlobalTriggerFile"), + format = cms.untracked.string("APx") +) \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/src/BoardData.cc b/L1Trigger/DemonstratorTools/src/BoardData.cc new file mode 100644 index 0000000000000..2a40b5c3d6fec --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/BoardData.cc @@ -0,0 +1,43 @@ + +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" + +namespace l1t::demo { + + BoardData::BoardData() {} + + BoardData::BoardData(const std::string& name) : name_(name) {} + + BoardData::BoardData(const std::string& name, const std::vector& channels, size_t length) : name_(name) { + for (const auto i : channels) + data_[i] = Channel(length); + } + + const std::string& BoardData::name() const { return name_; } + + std::map::const_iterator BoardData::begin() const { return data_.begin(); } + + std::map::iterator BoardData::begin() { return data_.begin(); } + + std::map::const_iterator BoardData::end() const { return data_.end(); } + + std::map::iterator BoardData::end() { return data_.end(); } + + BoardData::Channel& BoardData::add(size_t i) { + data_[i] = Channel(); + return data_.at(i); + } + + BoardData::Channel& BoardData::add(size_t i, const Channel& data) { + data_[i] = data; + return data_.at(i); + } + + BoardData::Channel& BoardData::at(size_t i) { return data_.at(i); } + + const BoardData::Channel& BoardData::at(size_t i) const { return data_.at(i); } + + bool BoardData::has(size_t i) const { return data_.count(i) > 0; } + + size_t BoardData::size() { return data_.size(); } + +} // namespace l1t::demo \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/src/BoardDataReader.cc b/L1Trigger/DemonstratorTools/src/BoardDataReader.cc new file mode 100644 index 0000000000000..161f62d4974fb --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/BoardDataReader.cc @@ -0,0 +1,149 @@ +#include "L1Trigger/DemonstratorTools/interface/BoardDataReader.h" + +#include + +#include "L1Trigger/DemonstratorTools/interface/Frame.h" +#include "L1Trigger/DemonstratorTools/interface/utilities.h" + +namespace l1t::demo { + + BoardDataReader::BoardDataReader(FileFormat format, + const std::vector& fileNames, + const size_t framesPerBX, + const size_t tmux, + const size_t emptyFramesAtStart, + const ChannelMap_t& channelMap) + : fileFormat_(format), + fileNames_(fileNames), + framesPerBX_(framesPerBX), + boardTMUX_(tmux), + emptyFramesAtStart_(emptyFramesAtStart), + channelMap_(channelMap), + events_() { + // TODO (long term): Move much of this to separate function, and only read files on demand + + // Verify that channel map/spec is self-consistent + for (const auto& [id, value] : channelMap_) { + const auto& [spec, indices] = value; + if ((spec.tmux % boardTMUX_) != 0) + throw std::runtime_error("Link [" + id.interface + ", " + std::to_string(id.channel) + + "]: Specified TMUX period, " + std::to_string(spec.tmux) + + ", is not a multiple of the board TMUX, " + std::to_string(boardTMUX_)); + + const size_t tmuxRatio(spec.tmux / boardTMUX_); + if (indices.size() != tmuxRatio) + throw std::runtime_error("Link [" + id.interface + ", " + std::to_string(id.channel) + + "]: Number of channel indices specified, " + std::to_string(indices.size()) + + ", does not match link:board TMUX ratio"); + } + + // Loop over input files + for (const auto& path : fileNames_) { + BoardData boardData(read(path, fileFormat_)); + + // 1) Verify that all expected channels are present + for (const auto& [id, value] : channelMap_) { + const auto& [spec, indices] = value; + for (const auto i : indices) { + if (not boardData.has(i)) + throw std::runtime_error("Channel " + std::to_string(i) + " was declared but is missing from file '" + + path + "'"); + } + } + + // 2) Verify that packet structure is as expected + for (const auto& [id, value] : channelMap) { + const auto& [spec, indices] = value; + for (size_t tmuxIndex = 0; tmuxIndex < indices.size(); tmuxIndex++) { + const auto& chanData = boardData.at(indices.at(tmuxIndex)); + + const size_t framesBeforeFirstPacket(emptyFramesAtStart_ + tmuxIndex * boardTMUX_ * framesPerBX_ + + spec.offset); + const size_t eventLength(spec.tmux * framesPerBX_); + const size_t packetLength(eventLength - spec.interpacketGap); + + for (size_t j = 0; j < framesBeforeFirstPacket; j++) { + if (chanData.at(j).valid) + throw std::runtime_error("Frame " + std::to_string(j) + " on channel " + + std::to_string(indices.at(tmuxIndex)) + " is valid, but first " + + std::to_string(framesBeforeFirstPacket) + "frames should be invalid"); + } + + for (size_t j = framesBeforeFirstPacket; j < chanData.size(); j++) { + if ((j + (framesPerBX_ * spec.tmux)) >= chanData.size()) + continue; + + bool expectValid(((j - framesBeforeFirstPacket) % eventLength) < packetLength); + + if (expectValid) { + if (not chanData.at(j).valid) + throw std::runtime_error("Frame " + std::to_string(j) + " on channel " + + std::to_string(indices.at(tmuxIndex)) + + " is invalid, but expected valid frame"); + } else if (chanData.at(j).valid) + throw std::runtime_error("Frame " + std::to_string(j) + " on channel " + + std::to_string(indices.at(tmuxIndex)) + " is valid, but expected invalid frame"); + } + } + } + + // 3) Extract the data for each event + bool eventIncomplete(false); + for (size_t eventIndex = 0;; eventIndex++) { + EventData eventData; + + for (const auto& [id, value] : channelMap) { + const auto& [spec, indices] = value; + const auto& chanData = boardData.at(indices.at(eventIndex % (spec.tmux / boardTMUX_))); + + // Extract the frames for this event + const size_t framesBeforeEvent(eventIndex * boardTMUX_ * framesPerBX_ + emptyFramesAtStart_ + spec.offset); + const size_t packetLength(spec.tmux * framesPerBX_ - spec.interpacketGap); + + if (chanData.size() < (framesBeforeEvent + spec.tmux * framesPerBX_)) { + eventIncomplete = true; + break; + } + + std::vector> chanEventData(packetLength); + for (size_t j = 0; j < packetLength; j++) + chanEventData.at(j) = chanData.at(framesBeforeEvent + j).data; + eventData.add(id, chanEventData); + } + + if (eventIncomplete) + break; + + events_.push_back(eventData); + } + } + + eventIt_ = events_.begin(); + } + + BoardDataReader::BoardDataReader(FileFormat format, + const std::vector& fileNames, + const size_t framesPerBX, + const size_t tmux, + const size_t emptyFramesAtStart, + const std::map>& channelMap, + const std::map& channelSpecs) + : BoardDataReader(format, fileNames, framesPerBX, tmux, emptyFramesAtStart, mergeMaps(channelMap, channelSpecs)) { + } + + EventData BoardDataReader::getNextEvent() { + if (eventIt_ == events_.end()) + throw std::runtime_error("Board data reader ran out of events"); + + return *(eventIt_++); + } + + BoardDataReader::ChannelMap_t BoardDataReader::mergeMaps(const std::map>& indexMap, + const std::map& specMap) { + ChannelMap_t channelMap; + for (const auto& x : indexMap) + channelMap.at(x.first) = {specMap.at(x.first.interface), x.second}; + return channelMap; + } + +} // namespace l1t::demo diff --git a/L1Trigger/DemonstratorTools/src/BoardDataWriter.cc b/L1Trigger/DemonstratorTools/src/BoardDataWriter.cc new file mode 100644 index 0000000000000..c98a3cb5b9918 --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/BoardDataWriter.cc @@ -0,0 +1,147 @@ +#include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h" + +#include + +#include "L1Trigger/DemonstratorTools/interface/Frame.h" +#include "L1Trigger/DemonstratorTools/interface/utilities.h" + +namespace l1t::demo { + + BoardDataWriter::BoardDataWriter(FileFormat format, + const std::string& path, + const size_t framesPerBX, + const size_t tmux, + const size_t maxFramesPerFile, + const ChannelMap_t& channelSpecs) + : fileFormat_(format), + filePathGen_([=](const size_t i) { return path + "_" + std::to_string(i) + ".txt"; }), + framesPerBX_(framesPerBX), + boardTMUX_(tmux), + maxFramesPerFile_(maxFramesPerFile), + maxEventsPerFile_(maxFramesPerFile_), + eventIndex_(0), + pendingEvents_(0), + channelMap_(channelSpecs) { + if (channelMap_.empty()) + throw std::runtime_error("BoardDataWriter channel map cannnot be empty"); + + for (const auto& [id, value] : channelMap_) { + const auto& [spec, indices] = value; + for (const auto i : indices) + boardData_.add(i); + + if ((spec.tmux % boardTMUX_) != 0) + throw std::runtime_error("BoardDataWriter, link [" + id.interface + ", " + std::to_string(id.channel) + + "]: Specified TMUX period, " + std::to_string(spec.tmux) + + ", is not a multiple of the board TMUX, " + std::to_string(boardTMUX_)); + + const size_t tmuxRatio(spec.tmux / boardTMUX_); + if (indices.size() != tmuxRatio) + throw std::runtime_error("BoardDataWriter, link [" + id.interface + ", " + std::to_string(id.channel) + + "]: Number of channel indices specified, " + std::to_string(indices.size()) + + ", does not match link:board TMUX ratio, " + std::to_string(tmuxRatio)); + + maxEventsPerFile_ = std::min(maxEventsPerFile_, + ((maxFramesPerFile_ - spec.offset) / (framesPerBX_ * boardTMUX_)) - (tmuxRatio - 1)); + } + + resetBoardData(); + } + + BoardDataWriter::BoardDataWriter(FileFormat format, + const std::string& path, + const size_t framesPerBX, + const size_t tmux, + const size_t maxFramesPerFile, + const std::map>& channelMap, + const std::map& channelSpecs) + : BoardDataWriter(format, path, framesPerBX, tmux, maxFramesPerFile, mergeMaps(channelMap, channelSpecs)) {} + + void BoardDataWriter::addEvent(const EventData& eventData) { + // Check that data is supplied for each channel + for (const auto& [id, info] : channelMap_) { + if (not eventData.has(id)) + throw std::runtime_error("Event data for link [" + id.interface + ", " + std::to_string(id.channel) + + "] is missing."); + } + + for (const auto& [id, channelData] : eventData) { + // Check that each channel was declared to constructor + if (channelMap_.count(id) == 0) + throw std::runtime_error("Event data for link [" + id.interface + ", " + std::to_string(id.channel) + + "] was given to BoardDataWriter, but its structure was not defined"); + + const auto& [spec, indices] = channelMap_.at(id); + const size_t chanIndex(indices.at(pendingEvents_ % (spec.tmux / boardTMUX_))); + + // Check that that expected amount of data has been provided + if (channelData.size() > (spec.tmux * framesPerBX_ - spec.interpacketGap)) + throw std::runtime_error("Event data for link [" + id.interface + ", " + std::to_string(id.channel) + + "] (TMUX " + std::to_string(spec.tmux) + ", " + std::to_string(spec.interpacketGap) + + " cycles between packets) is too long (" + std::to_string(channelData.size()) + + " 64-bit words)"); + + if (channelData.empty()) + throw std::runtime_error("Event data for link [" + id.interface + ", " + std::to_string(id.channel) + + "] is empty"); + + // Copy event data for this channel to board data object + boardData_.at(chanIndex).insert(boardData_.at(chanIndex).end(), channelData.begin(), channelData.end()); + + // Override flags for start & end of event + BoardData::Channel::iterator it(boardData_.at(chanIndex).end() - 1); + it->end = true; + it -= (channelData.size() - 1); + it->start = true; + + // Pad link with non-valid frames + boardData_.at(chanIndex).insert( + boardData_.at(chanIndex).end(), spec.tmux * framesPerBX_ - channelData.size(), Frame()); + } + + eventIndex_++; + pendingEvents_++; + + if (pendingEvents_ == maxEventsPerFile_) + flush(); + } + + void BoardDataWriter::flush() { + if (pendingEvents_ == 0) + return; + + // Pad any channels that aren't full with invalid frames + for (auto& x : boardData_) + x.second.resize(maxFramesPerFile_); + + // Write board data object to file + const std::string filePath = filePathGen_(fileNames_.size()); + write(boardData_, filePath, fileFormat_); + fileNames_.push_back(filePath); + + // Clear board data to be ready for next event + resetBoardData(); + } + + BoardDataWriter::ChannelMap_t BoardDataWriter::mergeMaps(const std::map>& indexMap, + const std::map& specMap) { + ChannelMap_t channelMap; + for (const auto& x : indexMap) + channelMap[x.first] = {specMap.at(x.first.interface), x.second}; + return channelMap; + } + + void BoardDataWriter::resetBoardData() { + for (auto& x : boardData_) + x.second.clear(); + + for (const auto& [id, value] : channelMap_) { + const auto& [spec, indices] = value; + for (size_t tmuxIndex = 0; tmuxIndex < indices.size(); tmuxIndex++) + boardData_.at(indices.at(tmuxIndex)).resize(tmuxIndex * boardTMUX_ * framesPerBX_ + spec.offset); + } + + pendingEvents_ = 0; + } + +} // namespace l1t::demo \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/src/EventData.cc b/L1Trigger/DemonstratorTools/src/EventData.cc new file mode 100644 index 0000000000000..dd3caf283718d --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/EventData.cc @@ -0,0 +1,27 @@ + +#include "L1Trigger/DemonstratorTools/interface/EventData.h" + +namespace l1t::demo { + + EventData::EventData() {} + + EventData::EventData(const std::map>>& data) : data_(data) {} + + EventData::const_iterator EventData::begin() const { return data_.begin(); } + + EventData::const_iterator EventData::end() const { return data_.end(); } + + void EventData::add(const LinkId& i, const std::vector>& data) { data_[i] = data; } + + void EventData::add(const EventData& data) { + for (const auto& x : data) + add(x.first, x.second); + } + + const std::vector>& EventData::at(const LinkId& i) const { return data_.at(i); } + + bool EventData::has(const LinkId& i) const { return data_.count(i) > 0; } + + size_t EventData::size() { return data_.size(); } + +} // namespace l1t::demo \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/src/FileFormat.cc b/L1Trigger/DemonstratorTools/src/FileFormat.cc new file mode 100644 index 0000000000000..d51110af1308d --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/FileFormat.cc @@ -0,0 +1,22 @@ + +#include "L1Trigger/DemonstratorTools/interface/FileFormat.h" + +#include + +namespace l1t::demo { + + std::ostream& operator<<(std::ostream& os, FileFormat format) { + switch (format) { + case FileFormat::APx: + os << "APx"; + break; + case FileFormat::EMP: + os << "EMP"; + break; + case FileFormat::X20: + os << "X20"; + } + return os; + } + +} // namespace l1t::demo diff --git a/L1Trigger/DemonstratorTools/src/Frame.cc b/L1Trigger/DemonstratorTools/src/Frame.cc new file mode 100644 index 0000000000000..22e0181cfe63e --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/Frame.cc @@ -0,0 +1,10 @@ + +#include "L1Trigger/DemonstratorTools/interface/Frame.h" + +namespace l1t::demo { + + Frame::Frame(const uint64_t x) : data(x), valid(true) {} + + Frame::Frame(const ap_uint<64>& x) : data(x), valid(true) {} + +} // namespace l1t::demo \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/src/LinkId.cc b/L1Trigger/DemonstratorTools/src/LinkId.cc new file mode 100644 index 0000000000000..4c73421a95332 --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/LinkId.cc @@ -0,0 +1,11 @@ + +#include "L1Trigger/DemonstratorTools/interface/LinkId.h" + +namespace l1t::demo { + + bool operator<(const LinkId& x, const LinkId& y) { + int c = x.interface.compare(y.interface); + return c == 0 ? (x.channel < y.channel) : (c < 0); + } + +} // namespace l1t::demo \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/src/codecs_etsums.cc b/L1Trigger/DemonstratorTools/src/codecs_etsums.cc new file mode 100644 index 0000000000000..34e48c58493f8 --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/codecs_etsums.cc @@ -0,0 +1,54 @@ + +#include "L1Trigger/DemonstratorTools/interface/codecs/etsums.h" + +namespace l1t::demo::codecs { + + ap_uint<64> encodeEtSum(const l1t::EtSum& etSum) { + l1tmetemu::EtMiss etMiss; + etMiss.Et = etSum.hwPt(); + etMiss.Phi = etSum.hwPhi(); + ap_uint<1> valid = (etSum.hwQual() > 0); + ap_uint<64 - (l1tmetemu::kMETSize + l1tmetemu::kMETPhiSize + 1)> unassigned = 0; + ap_uint<64> etSumWord = (unassigned, etMiss.Phi, etMiss.Et, valid); + return etSumWord; + } + + // Encodes etsum collection onto 1 output link + std::array>, 1> encodeEtSums(const edm::View& etSums) { + std::vector> etSumWords; + + for (const auto& etSum : etSums) + etSumWords.push_back(encodeEtSum(etSum)); + + std::array>, 1> linkData; + + for (size_t i = 0; i < linkData.size(); i++) { + // Pad etsum vectors -> full packet length (48 frames, but only 1 etsum max) + etSumWords.resize(1, 0); + linkData.at(i) = etSumWords; + } + + return linkData; + } + + std::vector decodeEtSums(const std::vector>& frames) { + std::vector etSums; + + for (const auto& x : frames) { + if (not x.test(0)) + break; + + math::XYZTLorentzVector v(0, 0, 0, 0); + l1t::EtSum s(v, + l1t::EtSum::EtSumType::kMissingEt, + l1tmetemu::MET_t(x(1 + l1tmetemu::kMETSize, 1)).to_int(), + 0, + l1tmetemu::METphi_t(x(1 + l1tmetemu::kMETSize + l1tmetemu::kMETPhiSize, 17)).to_int(), + 0); + etSums.push_back(s); + } + + return etSums; + } + +} // namespace l1t::demo::codecs \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/src/codecs_htsums.cc b/L1Trigger/DemonstratorTools/src/codecs_htsums.cc new file mode 100644 index 0000000000000..ba14fbaa5cfb9 --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/codecs_htsums.cc @@ -0,0 +1,55 @@ + +#include "L1Trigger/DemonstratorTools/interface/codecs/htsums.h" + +namespace l1t::demo::codecs { + + ap_uint<64> encodeHtSum(const l1t::EtSum& htSum) { + l1tmhtemu::EtMiss htMiss; + htMiss.Et = htSum.p4().energy(); + htMiss.Phi = htSum.hwPhi(); + l1tmhtemu::Et_t HT = htSum.hwPt(); + ap_uint valid = (htSum.hwQual() > 0); + ap_uint unassigned = 0; + ap_uint<64> htSumWord = (unassigned, HT, htMiss.Phi, htMiss.Et, valid); + return htSumWord; + } + + // Encodes htsum collection onto 1 output link + std::array>, 1> encodeHtSums(const edm::View& htSums) { + std::vector> htSumWords; + + for (const auto& htSum : htSums) + htSumWords.push_back(encodeHtSum(htSum)); + + std::array>, 1> linkData; + + for (size_t i = 0; i < linkData.size(); i++) { + // Pad etsum vectors -> full packet length (48 frames, but only 1 htsum max) + htSumWords.resize(1, 0); + linkData.at(i) = htSumWords; + } + + return linkData; + } + + std::vector decodeHtSums(const std::vector>& frames) { + std::vector htSums; + + for (const auto& x : frames) { + if (not x.test(0)) + break; + + math::XYZTLorentzVector v(0, 0, 0, l1tmhtemu::MHT_t(x(l1tmhtemu::kMHTMSB, l1tmhtemu::kMHTLSB)).to_int()); + l1t::EtSum s(v, + l1t::EtSum::EtSumType::kMissingHt, + l1tmhtemu::Et_t(x(l1tmhtemu::kHTMSB, l1tmhtemu::kHTLSB)).to_int(), + 0, + l1tmhtemu::MHTphi_t(x(l1tmhtemu::kMHTPhiMSB, l1tmhtemu::kMHTPhiLSB)).to_int(), + 0); + htSums.push_back(s); + } + + return htSums; + } + +} // namespace l1t::demo::codecs \ No newline at end of file diff --git a/L1Trigger/DemonstratorTools/src/codecs_tkjets.cc b/L1Trigger/DemonstratorTools/src/codecs_tkjets.cc new file mode 100644 index 0000000000000..75de4a5c52e0b --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/codecs_tkjets.cc @@ -0,0 +1,50 @@ + +#include "L1Trigger/DemonstratorTools/interface/codecs/tkjets.h" + +namespace l1t::demo::codecs { + + ap_uint<64> encodeTkJet(const l1t::TkJetWord& j) { return j.tkJetWord(); } + + // Encodes vertex collection onto 1 output link + std::array>, 1> encodeTkJets(const edm::View& tkJets) { + std::vector> tkJetWords; + + for (const auto& tkJet : tkJets) { + tkJetWords.push_back(encodeTkJet(tkJet)); + tkJetWords.push_back(ap_uint<64>(0)); + } + + std::array>, 1> linkData; + + for (size_t i = 0; i < linkData.size(); i++) { + // Pad TkJet vectors -> full packet length (48 frames, but only 12 TkJets max, two words per jet) + tkJetWords.resize(24, 0); + linkData.at(i) = tkJetWords; + } + + return linkData; + } + + std::vector decodeTkJets(const std::vector>& frames) { + std::vector tkJets; + + for (size_t f = 0; f < frames.size(); f += 2) { + // There is no valid bit in the definition right now. + // Uncomment the next two lines when this is available. + //if (not x.test(TkJetWord::kValidLSB)) + // break; + + TkJetWord j(TkJetWord::pt_t(frames[f](TkJetWord::kPtMSB, TkJetWord::kPtLSB)), + TkJetWord::glbeta_t(frames[f](TkJetWord::kGlbEtaMSB, TkJetWord::kGlbEtaLSB)), + TkJetWord::glbphi_t(frames[f](TkJetWord::kGlbPhiMSB, TkJetWord::kGlbPhiLSB)), + TkJetWord::z0_t(frames[f](TkJetWord::kZ0MSB, TkJetWord::kZ0LSB)), + TkJetWord::nt_t(frames[f](TkJetWord::kNtMSB, TkJetWord::kNtLSB)), + TkJetWord::nx_t(frames[f](TkJetWord::kXtMSB, TkJetWord::kXtLSB)), + TkJetWord::tkjetunassigned_t(frames[f](TkJetWord::kUnassignedMSB, TkJetWord::kUnassignedLSB))); + tkJets.push_back(j); + } + + return tkJets; + } + +} // namespace l1t::demo::codecs diff --git a/L1Trigger/DemonstratorTools/src/codecs_tracks.cc b/L1Trigger/DemonstratorTools/src/codecs_tracks.cc new file mode 100644 index 0000000000000..876fb1a6a44b1 --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/codecs_tracks.cc @@ -0,0 +1,171 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "L1Trigger/DemonstratorTools/interface/codecs/tracks.h" + +namespace l1t::demo::codecs { + + // Return true if a track is contained within a collection + bool trackInCollection( + const edm::Ref>>& trackRef, + const edm::Handle>>>& trackRefCollection) { + auto it = std::find_if( + trackRefCollection->begin(), + trackRefCollection->end(), + [&trackRef](edm::Ref>> const& obj) { return obj == trackRef; }); + if (it != trackRefCollection->end()) + return true; + else + return false; + } + + // Encodes a single track into a 96-bit track word + ap_uint<96> encodeTrack(const TTTrack_TrackWord& t) { return t.getTrackWord(); } + + // Return the 96-bit track words from a given track collection and place them on the appropriate 18 'logical' links + std::array>, 18> getTrackWords(const edm::View>& tracks) { + std::array>, 18> trackWords; + for (const auto& track : tracks) { + trackWords.at((track.eta() >= 0 ? 1 : 0) + (2 * track.phiSector())).push_back(encodeTrack(track)); + } + return trackWords; + } + + // Return the 96-bit track words from a given track collection and place them on the appropriate 18 'logical' links + std::array>, 18> getTrackWords( + const edm::Handle>>& referenceTracks, + const edm::Handle>>>& tracks) { + std::array>, 18> trackWords; + for (unsigned int itrack = 0; itrack < referenceTracks->size(); itrack++) { + const auto& referenceTrack = referenceTracks->at(itrack); + edm::Ref>> referenceTrackRef(referenceTracks, itrack); + + if (trackInCollection(referenceTrackRef, tracks)) { + trackWords.at((referenceTrack.eta() >= 0 ? 1 : 0) + (2 * referenceTrack.phiSector())) + .push_back(encodeTrack(referenceTrack)); + } else { + trackWords.at((referenceTrack.eta() >= 0 ? 1 : 0) + (2 * referenceTrack.phiSector())).push_back(ap_uint<96>(0)); + } + } + return trackWords; + } + + // Encodes a set of tracks onto a set of links + size_t encodeLinks(std::array>, 18>& trackWords, + std::array>, 18>& linkData) { + size_t counter = 0; + for (size_t i = 0; i < linkData.size(); i++) { + // Pad track vectors -> full packet length (156 frames = 104 tracks) + trackWords.at(i).resize(104, 0); + linkData.at(i).resize(156, {0}); + + for (size_t j = 0; (j < trackWords.at(i).size()); j += 2) { + linkData.at(i).at(3 * j / 2) = trackWords.at(i).at(j)(63, 0); + linkData.at(i).at(3 * j / 2 + 1) = + (ap_uint<32>(trackWords.at(i).at(j + 1)(31, 0)), ap_uint<32>(trackWords.at(i).at(j)(95, 64))); + linkData.at(i).at(3 * j / 2 + 2) = trackWords.at(i).at(j + 1)(95, 32); + counter += trackWords.at(i).at(j)(95, 95) + trackWords.at(i).at(j + 1)(95, 95); + } + } + return counter; + } + + // Encodes track collection onto 18 output links (2x9 eta-phi sectors; , -/+ eta pairs) + std::array>, 18> encodeTracks(const edm::View>& tracks, + int debug) { + if (debug > 0) { + edm::LogInfo("l1t::demo::codecs") << "encodeTrack::Encoding " << tracks.size() << " tracks"; + } + + std::array>, 18> trackWords = getTrackWords(tracks); + std::array>, 18> linkData; + size_t counter = encodeLinks(trackWords, linkData); + + if (debug > 0) { + edm::LogInfo("l1t::demo::codecs") << "encodeTrack::Encoded " << counter << " tracks"; + } + + return linkData; + } + + // Encodes a track collection based off the ordering of another track collection + // Requirement: The second collection must be a subset of the first + std::array>, 18> encodeTracks( + const edm::Handle>>& referenceTracks, + const edm::Handle>>>& tracks, + int debug) { + if (debug > 0) { + edm::LogInfo("l1t::demo::codecs") << "encodeTrack::Encoding " << tracks->size() << " tracks"; + } + + std::array>, 18> trackWords = getTrackWords(referenceTracks, tracks); + std::array>, 18> linkData; + size_t counter = encodeLinks(trackWords, linkData); + + if (debug > 0) { + edm::LogInfo("l1t::demo::codecs") << "encodeTrack::Encoded " << counter << " tracks"; + } + + return linkData; + } + + std::vector decodeTracks(const std::vector>& frames) { + std::vector tracks; + + if ((frames.size() % 3) != 0) { + std::stringstream message; + message << "The number of track frames (" << frames.size() << ") is not evenly divisible by 3"; + throw std::runtime_error(message.str()); + } + + for (size_t i = 0; i < frames.size(); i += 3) { + TTTrack_TrackWord::tkword_t combination1 = (ap_uint<32>(frames.at(i + 1)(31, 0)), frames.at(i)(63, 0)); + TTTrack_TrackWord::tkword_t combination2 = (frames.at(i + 2)(63, 0), ap_uint<32>(frames.at(i + 1)(63, 32))); + TTTrack_TrackWord track1, track2; + track1.setTrackWord( + TTTrack_TrackWord::valid_t(combination1(TTTrack_TrackWord::kValidMSB, TTTrack_TrackWord::kValidLSB)), + TTTrack_TrackWord::rinv_t(combination1(TTTrack_TrackWord::kRinvMSB, TTTrack_TrackWord::kRinvLSB)), + TTTrack_TrackWord::phi_t(combination1(TTTrack_TrackWord::kPhiMSB, TTTrack_TrackWord::kPhiLSB)), + TTTrack_TrackWord::tanl_t(combination1(TTTrack_TrackWord::kTanlMSB, TTTrack_TrackWord::kTanlLSB)), + TTTrack_TrackWord::z0_t(combination1(TTTrack_TrackWord::kZ0MSB, TTTrack_TrackWord::kZ0LSB)), + TTTrack_TrackWord::d0_t(combination1(TTTrack_TrackWord::kD0MSB, TTTrack_TrackWord::kD0LSB)), + TTTrack_TrackWord::chi2rphi_t(combination1(TTTrack_TrackWord::kChi2RPhiMSB, TTTrack_TrackWord::kChi2RPhiLSB)), + TTTrack_TrackWord::chi2rz_t(combination1(TTTrack_TrackWord::kChi2RZMSB, TTTrack_TrackWord::kChi2RZLSB)), + TTTrack_TrackWord::bendChi2_t(combination1(TTTrack_TrackWord::kBendChi2MSB, TTTrack_TrackWord::kBendChi2LSB)), + TTTrack_TrackWord::hit_t(combination1(TTTrack_TrackWord::kHitPatternMSB, TTTrack_TrackWord::kHitPatternLSB)), + TTTrack_TrackWord::qualityMVA_t( + combination1(TTTrack_TrackWord::kMVAQualityMSB, TTTrack_TrackWord::kMVAQualityLSB)), + TTTrack_TrackWord::otherMVA_t( + combination1(TTTrack_TrackWord::kMVAOtherMSB, TTTrack_TrackWord::kMVAOtherLSB))); + track2.setTrackWord( + TTTrack_TrackWord::valid_t(combination2(TTTrack_TrackWord::kValidMSB, TTTrack_TrackWord::kValidLSB)), + TTTrack_TrackWord::rinv_t(combination2(TTTrack_TrackWord::kRinvMSB, TTTrack_TrackWord::kRinvLSB)), + TTTrack_TrackWord::phi_t(combination2(TTTrack_TrackWord::kPhiMSB, TTTrack_TrackWord::kPhiLSB)), + TTTrack_TrackWord::tanl_t(combination2(TTTrack_TrackWord::kTanlMSB, TTTrack_TrackWord::kTanlLSB)), + TTTrack_TrackWord::z0_t(combination2(TTTrack_TrackWord::kZ0MSB, TTTrack_TrackWord::kZ0LSB)), + TTTrack_TrackWord::d0_t(combination2(TTTrack_TrackWord::kD0MSB, TTTrack_TrackWord::kD0LSB)), + TTTrack_TrackWord::chi2rphi_t(combination2(TTTrack_TrackWord::kChi2RPhiMSB, TTTrack_TrackWord::kChi2RPhiLSB)), + TTTrack_TrackWord::chi2rz_t(combination2(TTTrack_TrackWord::kChi2RZMSB, TTTrack_TrackWord::kChi2RZLSB)), + TTTrack_TrackWord::bendChi2_t(combination2(TTTrack_TrackWord::kBendChi2MSB, TTTrack_TrackWord::kBendChi2LSB)), + TTTrack_TrackWord::hit_t(combination2(TTTrack_TrackWord::kHitPatternMSB, TTTrack_TrackWord::kHitPatternLSB)), + TTTrack_TrackWord::qualityMVA_t( + combination2(TTTrack_TrackWord::kMVAQualityMSB, TTTrack_TrackWord::kMVAQualityLSB)), + TTTrack_TrackWord::otherMVA_t( + combination2(TTTrack_TrackWord::kMVAOtherMSB, TTTrack_TrackWord::kMVAOtherLSB))); + tracks.push_back(track1); + tracks.push_back(track2); + } + + return tracks; + } + + // Decodes the tracks from 18 'logical' output links (2x9 eta-phi sectors; , -/+ eta pairs) + std::array, 18> decodeTracks(const std::array>, 18>& frames) { + std::array, 18> tracks; + + for (size_t i = 0; i < tracks.size(); i++) { + tracks.at(i) = decodeTracks(frames.at(i)); + } + + return tracks; + } + +} // namespace l1t::demo::codecs diff --git a/L1Trigger/DemonstratorTools/src/codecs_vertices.cc b/L1Trigger/DemonstratorTools/src/codecs_vertices.cc new file mode 100644 index 0000000000000..f81e221e5666c --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/codecs_vertices.cc @@ -0,0 +1,46 @@ + +#include "L1Trigger/DemonstratorTools/interface/codecs/vertices.h" + +namespace l1t::demo::codecs { + + ap_uint<64> encodeVertex(const l1t::VertexWord& v) { return v.vertexWord(); } + + // Encodes vertex collection onto 1 output link + std::array>, 1> encodeVertices(const edm::View& vertices) { + std::vector> vertexWords; + + for (const auto& vertex : vertices) + vertexWords.push_back(encodeVertex(vertex)); + + std::array>, 1> linkData; + + for (size_t i = 0; i < linkData.size(); i++) { + // Pad vertex vectors -> full packet length (48 frames, but only 10 vertices max) + vertexWords.resize(10, 0); + linkData.at(i) = vertexWords; + } + + return linkData; + } + + std::vector decodeVertices(const std::vector>& frames) { + std::vector vertices; + + for (const auto& x : frames) { + if (not x.test(VertexWord::kValidLSB)) + break; + + VertexWord v(VertexWord::vtxvalid_t(1), + VertexWord::vtxz0_t(x(VertexWord::kZ0MSB, VertexWord::kZ0LSB)), + VertexWord::vtxmultiplicity_t(x(VertexWord::kNTrackInPVMSB, VertexWord::kNTrackInPVLSB)), + VertexWord::vtxsumpt_t(x(VertexWord::kSumPtMSB, VertexWord::kSumPtLSB)), + VertexWord::vtxquality_t(x(VertexWord::kQualityMSB, VertexWord::kQualityLSB)), + VertexWord::vtxinversemult_t(x(VertexWord::kNTrackOutPVMSB, VertexWord::kNTrackOutPVLSB)), + VertexWord::vtxunassigned_t(x(VertexWord::kUnassignedMSB, VertexWord::kUnassignedLSB))); + vertices.push_back(v); + } + + return vertices; + } + +} // namespace l1t::demo::codecs diff --git a/L1Trigger/DemonstratorTools/src/utilities.cc b/L1Trigger/DemonstratorTools/src/utilities.cc new file mode 100644 index 0000000000000..b35ba60c138d6 --- /dev/null +++ b/L1Trigger/DemonstratorTools/src/utilities.cc @@ -0,0 +1,405 @@ +#include "L1Trigger/DemonstratorTools/interface/utilities.h" + +#include +#include +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#endif +#include "L1Trigger/DemonstratorTools/interface/BoardData.h" + +namespace { + + l1t::demo::BoardData createBoardDataFromRows(const std::string& id, + const std::vector& channels, + const std::vector>& dataRows) { + l1t::demo::BoardData boardData(id); + + for (size_t i = 0; i < channels.size(); i++) { + std::vector channelData(dataRows.size()); + for (size_t j = 0; j < dataRows.size(); j++) + channelData.at(j) = dataRows.at(j).at(i); + boardData.add(channels.at(i), channelData); + } + + return boardData; + } + + std::vector searchAndTokenize(std::istream& file, const std::string& linePrefix) { + std::string line; + + while (getline(file, line)) { + // Strip leading spaces + size_t startIndex = line.find_first_not_of(" \t"); + if (startIndex != std::string::npos) + line = line.substr(startIndex); + + if (line.empty()) + continue; + if (line[0] == '#') + continue; + + if (line.rfind(linePrefix, 0) != std::string::npos) { + std::vector tokens; + + // Split the line into tokens + const std::regex delimiterRegex("\\s+"); + std::sregex_token_iterator it(line.begin() + linePrefix.size(), line.end(), delimiterRegex, -1); + + for (; it != std::sregex_token_iterator(); it++) { + const std::string token(it->str()); + if (token.empty()) + continue; + tokens.push_back(token); + } + + return tokens; + } else + throw std::logic_error("Found unexpected line found when searching for \"" + linePrefix + "\": \"" + line + + "\""); + } + throw std::logic_error("Couldn't find any line starting with \"" + linePrefix + "\""); + } + +} // namespace + +namespace l1t::demo { + + FileFormat parseFileFormat(const std::string& s) { + static const std::unordered_map kFormatStringMap({{"EMP", FileFormat::EMP}, + {"emp", FileFormat::EMP}, + {"APx", FileFormat::APx}, + {"apx", FileFormat::APx}, + {"X20", FileFormat::X20}, + {"x20", FileFormat::X20}}); + + const auto it = kFormatStringMap.find(s); + if (it == kFormatStringMap.end()) + throw std::runtime_error("Could not convert '" + s + "' to FileFormat enum value"); + + return it->second; + } + + BoardData readAPxFile(std::istream&, const FileFormat); + + BoardData readEMPFile(std::istream&, const FileFormat); + + BoardData readX20File(std::istream&, const FileFormat); + + BoardData read(const std::string& filePath, const FileFormat format) { + std::ifstream file(filePath); + + if (not file.is_open()) + throw std::runtime_error("Could not open file '" + filePath + "'"); + + return read(file, format); + } + + BoardData read(std::istream& file, const FileFormat format) { + if (format == FileFormat::APx) + return readAPxFile(file, format); + else if (format == FileFormat::EMP) + return readEMPFile(file, format); + else + return readX20File(file, format); + } + + BoardData readAPxFile(std::istream& file, const FileFormat format) { + std::string line; + + // Complain if file is empty + if (not std::getline(file, line)) + throw std::runtime_error("Specified file is empty!"); + + // If first line is sideband, skip it and move onto 2nd line + if (line.find("#Sideband") == 0) { + if (not std::getline(file, line)) + throw std::runtime_error("APx file has incorrect format: Link labels and data missing!"); + } + + // Parse link labels + if (line.find("#LinkLabel") != 0) + throw std::runtime_error( + "APx file has incorrect format: Link header does not start with '#LinkLabel' (line is '" + line + "')"); + + std::vector indices; + const std::regex delimiterRegex("\\s+"); + std::sregex_token_iterator it(line.begin() + 10, line.end(), delimiterRegex, -1); + for (; it != std::sregex_token_iterator(); it++) { + const std::string token(it->str()); + if (token.empty()) + continue; + + if (token.find("LINK_") != 0) + throw std::runtime_error("Link column name '" + token + "' (does not start with 'LINK_')"); + if (token.size() == 5) + throw std::runtime_error("Link column name '" + token + "' is too short"); + if (not std::all_of(token.begin() + 5, token.end(), ::isdigit)) + throw std::runtime_error("Link column name '" + token + "' does not end with a number"); + + indices.push_back(std::stoul(token.substr(5))); + } + + // Check for '#BeginData' line + if (not std::getline(file, line)) + throw std::runtime_error("APx file has incorrect format: Data missing!"); + if (line != "#BeginData") + throw std::runtime_error("APx file has incorrect format: '#BeginData' line missing (found '" + line + "')"); + + // Parse link data + std::vector> dataRows; + while (std::getline(file, line)) { + it = std::sregex_token_iterator(line.begin(), line.end(), delimiterRegex, -1); + size_t count = 0; + for (; it != std::sregex_token_iterator(); it++, count++) { + const std::string token(it->str()); + + if ((token.find("0x") != 0) or (not std::all_of(token.begin() + 2, token.end(), ::isxdigit))) + throw std::runtime_error("APx file has incorrect format: Data token '" + token + + "' is not hexadecimal number"); + + if (count == 0) { + size_t rowIndex = std::stoul(token, nullptr, 16); + if (rowIndex != dataRows.size()) + throw std::runtime_error("APx file has incorrect format: Expected data row " + + std::to_string(dataRows.size()) + ", but found row " + std::to_string(rowIndex)); + dataRows.push_back(std::vector(indices.size())); + } + // Sideband info + else if ((count % 2) == 1) { + uint16_t sbValue = std::stoul(token, nullptr, 16); + dataRows.back().at((count - 1) / 2).valid = (sbValue & 0x1); + dataRows.back().at((count - 1) / 2).start = ((sbValue >> 1) & 0x1); + dataRows.back().at((count - 1) / 2).end = ((sbValue >> 3) & 0x1); + } + // Data word + else + dataRows.back().at((count - 1) / 2).data = ap_uint<64>(std::stoull(token, nullptr, 16)); + } + + if (count != (2 * indices.size() + 1)) + throw std::runtime_error("APx file has incorrect format: Line has incorrect number of tokens (expected " + + std::to_string(2 * indices.size() + 1) + ", found " + std::to_string(count) + "!"); + } + + return createBoardDataFromRows("", indices, dataRows); + } + + BoardData readEMPFile(std::istream& file, const FileFormat format) { + // 1) Search for ID string + std::string id, line; + while (getline(file, line)) { + if (line.empty()) + continue; + if (line[0] == '#') + continue; + + if (line.rfind("Board ", 0) != std::string::npos) { + id = line.substr(6); + break; + } else + throw std::logic_error("Found unexpected line found when searching for board ID: \"" + line + "\""); + } + + // 2) Search for column labels (i.e. list of channels/links) + searchAndTokenize(file, "Quad/Chan :"); + const auto tokens = searchAndTokenize(file, "Link :"); + std::vector channels; + std::transform(tokens.begin(), tokens.end(), std::back_inserter(channels), [](const std::string& s) { + return std::stoull(s); + }); + + // 3) Read the main data rows + const std::regex delimiterRegex("\\s+"); + static const std::regex frameRegex("([01]s)?([01]v)([0-9a-fA-F]{16})"); + std::vector> dataRows; + while (file.good() and getline(file, line)) { + if (line.empty() or line[0] == '#') + continue; + + std::ostringstream prefixStream; + prefixStream << "Frame "; + prefixStream << std::setw(4) << std::setfill('0') << dataRows.size(); + prefixStream << " :"; + + const std::string prefix(prefixStream.str()); + if (line.rfind(prefix, 0) == std::string::npos) + throw std::logic_error("Found unexpected line found when searching for \"" + prefix + "\": \"" + line + "\""); + + std::vector row; + std::sregex_token_iterator it(line.begin() + prefix.size(), line.end(), delimiterRegex, -1); + for (; it != std::sregex_token_iterator(); it++) { + const std::string token(it->str()); + if (token.empty()) + continue; + + std::smatch what; + if (not std::regex_match(token, what, frameRegex)) + throw std::logic_error("Token '" + token + "' doesn't match the valid format"); + + l1t::demo::Frame value; + // Import strobe if the strobe group is matched + if (what[1].matched) { + value.strobe = (what[1] == "1s"); + } + + value.valid = (what[2] == "1v"); + value.data = ap_uint<64>(std::stoull(what[3].str(), nullptr, 16)); + + row.push_back(value); + } + + dataRows.push_back(row); + } + + return createBoardDataFromRows(id, channels, dataRows); + } + + BoardData readX20File(std::istream& file, const FileFormat format) { + throw std::runtime_error("Reading X20 file format not yet implemented. Will be done ASAP."); + } + + void writeAPxFile(const BoardData&, std::ostream&, const FileFormat); + + void writeEMPFile(const BoardData&, std::ostream&, const FileFormat); + + void writeX20File(const BoardData&, std::ostream&, const FileFormat); + + void write(const BoardData& data, const std::string& filePath, const FileFormat format) { + // Open file +#ifdef CMSSW_GIT_HASH + edm::LogInfo("L1TDemonstratorTools") +#else + std::cout +#endif + << "Writing board data (" << std::distance(data.begin(), data.end()) << " channels, " + << data.begin()->second.size() << " frames) to file '" << filePath << "' (format: " << format << ")" + << std::endl; + std::ofstream file(filePath); + + if (not file.is_open()) + throw std::runtime_error("Could not open file '" + filePath + "'"); + + write(data, file, format); + } + + void write(const BoardData& data, std::ostream& file, const FileFormat format) { + // Check that number of frames is same for every channel + const auto firstChannel = data.begin(); + + for (const auto& channel : data) { + const auto i = channel.first; + const auto channelData = channel.second; + if (channelData.size() != firstChannel->second.size()) + throw std::runtime_error("Cannot write board data to file - channels do not all have the same length (" + + std::to_string(channelData.size()) + " words on channel " + std::to_string(i) + + ", but " + std::to_string(firstChannel->second.size()) + " words on channel " + + std::to_string(firstChannel->first) + ")"); + } + + // Call relevant write function + switch (format) { + case FileFormat::APx: + writeAPxFile(data, file, format); + return; + case FileFormat::EMP: + writeEMPFile(data, file, format); + return; + case FileFormat::X20: + writeX20File(data, file, format); + return; + } + } + + void writeAPxFile(const BoardData& data, std::ostream& file, const FileFormat format) { + // Note: APx sideband encoding + // Short-term, simulation only: + // 0 -> Valid + // 1 -> EOF + // Planned (from ~ May 2021) + // 0 -> Valid + // 1 -> SOF (Start Of Frame) + // 2 -> FFO (First Frame of Orbit) + // 3 -> EOF (End Of Frame) + // 4 -> FERR (Frame Error) + // 5 -> RSV1 + // 6 -> RSV2 + // 7 -> RSV3 + + file << std::setfill('0'); + file << "#Sideband ON" << std::endl; + + // Channel header + file << "#LinkLabel"; + for (const auto& channel : data) { + const auto i = channel.first; + file << " LINK_" << std::setw(2) << i << " "; + } + file << std::endl; + + file << "#BeginData" << std::endl; + + // Frames + file << std::hex; + const auto firstChannel = data.begin(); + for (size_t i = 0; i < firstChannel->second.size(); i++) { + file << "0x" << std::setw(4) << i; + for (const auto& channel : data) { + //const auto j = channel.first; + const auto channelData = channel.second; + uint16_t sideband = channelData.at(i).valid; + sideband |= channelData.at(i).start << 1; + sideband |= channelData.at(i).end << 3; + file << " 0x" << std::setw(2) << sideband; + file << " 0x" << std::setw(16) << uint64_t(channelData.at(i).data); + } + file << std::endl; + } + } + + void writeEMPFile(const BoardData& data, std::ostream& file, const FileFormat format) { + file << std::setfill('0'); + + // Board name/id + file << "Board CMSSW" << std::endl; + + // Quad/chan header + file << " Quad/Chan :"; + for (const auto& channel : data) { + const auto i = channel.first; + file << " q" << std::setw(2) << i / 4 << 'c' << std::setw(1) << i % 4 << " "; + } + file << std::endl; + + // Link header + file << " Link :"; + for (const auto& channel : data) { + const auto i = channel.first; + file << " " << std::setw(3) << i << " "; + } + file << std::endl; + + // Frames + const auto firstChannel = data.begin(); + for (size_t i = 0; i < firstChannel->second.size(); i++) { + file << "Frame " << std::setw(4) << i << " :"; + for (const auto& channel : data) { + //const auto j = channel.first; + const auto channelData = channel.second; + file << " "; + //TODO: Add strobe if zero anywhere on channel + file << " "; + file << std::setw(1) << channelData.at(i).valid << "v" << std::setw(16) << std::hex + << uint64_t(channelData.at(i).data); + } + file << std::endl << std::dec; + } + } + + void writeX20File(const BoardData& data, std::ostream& file, const FileFormat format) { + throw std::runtime_error("Writing X20 file format not yet implemented. Will be done ASAP."); + } + +} // namespace l1t::demo diff --git a/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py b/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py new file mode 100644 index 0000000000000..f067b82d69d63 --- /dev/null +++ b/L1Trigger/DemonstratorTools/test/gtt/createFirmwareInputFiles_cfg.py @@ -0,0 +1,93 @@ +import FWCore.ParameterSet.Config as cms +import FWCore.Utilities.FileUtils as FileUtils +import FWCore.ParameterSet.VarParsing as VarParsing + + +# PART 1 : PARSE ARGUMENTS + +options = VarParsing.VarParsing ('analysis') +options.register('debug', + 0, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Print out additional debugging information") +options.register ('format', + 'EMP', # default value + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "File format (APx, EMP or X20)") +options.register('threads', + 1, # default value + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Number of threads to run") +options.register('streams', + 0, # default value + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Number of streams to run") +options.parseArguments() + +inputFiles = [] +for filePath in options.inputFiles: + if filePath.endswith(".root"): + inputFiles.append(filePath) + elif filePath.endswith("_cff.py"): + filePath = filePath.replace("/python/","/") + filePath = filePath.replace("/", ".") + inputFilesImport = getattr(__import__(filePath.strip(".py"),fromlist=["readFiles"]),"readFiles") + inputFiles.extend( inputFilesImport ) + else: + inputFiles += FileUtils.loadListFromFile(filePath) + +# PART 2: SETUP MAIN CMSSW PROCESS + +process = cms.Process("GTTFileWriter") + +process.load('Configuration.Geometry.GeometryExtended2026D77Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D77_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') +process.load("FWCore.MessageLogger.MessageLogger_cfi") + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(inputFiles), + inputCommands = cms.untracked.vstring("keep *", "drop l1tTkPrimaryVertexs_L1TkPrimaryVertex__*") +) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.maxEvents) ) +process.options = cms.untracked.PSet( + numberOfThreads = cms.untracked.uint32(options.threads), + numberOfStreams = cms.untracked.uint32(options.streams if options.streams>0 else 0) +) + +process.load('L1Trigger.L1TTrackMatch.L1GTTInputProducer_cfi') +process.load('L1Trigger.VertexFinder.VertexProducer_cff') +process.load("L1Trigger.L1TTrackMatch.L1TrackSelectionProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1TrackJetEmulationProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1TkHTMissEmulatorProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1TrackerEtMissEmulatorProducer_cfi") +process.load('L1Trigger.DemonstratorTools.GTTFileWriter_cff') + +process.L1GTTInputProducer.debug = cms.int32(options.debug) +process.VertexProducer.l1TracksInputTag = cms.InputTag("L1GTTInputProducer","Level1TTTracksConverted") +process.VertexProducer.VertexReconstruction.Algorithm = cms.string("fastHistoEmulation") +process.VertexProducer.VertexReconstruction.VxMinTrackPt = cms.double(0.0) +process.VertexProducer.debug = options.debug +process.L1TrackSelectionProducer.processSimulatedTracks = cms.bool(False) +process.L1TrackSelectionProducer.l1VerticesEmulationInputTag = cms.InputTag("VertexProducer", "l1verticesEmulation") +process.L1TrackJetsEmulation.VertexInputTag = cms.InputTag("VertexProducer", "l1verticesEmulation") +process.L1TrackerEmuEtMiss.L1VertexInputTag = cms.InputTag("VertexProducer", "l1verticesEmulation") +process.L1TrackerEmuEtMiss.debug = options.debug + +if options.debug: + process.MessageLogger.cerr.INFO.limit = cms.untracked.int32(1000000000) + +process.GTTFileWriter.format = cms.untracked.string(options.format) +# process.GTTFileWriter.outputFilename = cms.untracked.string("myOutputFile.txt") + +process.MessageLogger.cerr.FwkReport.reportEvery = 1 +process.Timing = cms.Service("Timing", summaryOnly = cms.untracked.bool(True)) + +process.p = cms.Path(process.L1GTTInputProducer * process.VertexProducer * process.L1TrackSelectionProducer * process.L1TrackJetsEmulation * process.L1TrackerEmuHTMiss * process.L1TrackerEmuEtMiss * process.GTTFileWriter) diff --git a/L1Trigger/DemonstratorTools/test/gtt/example_vertex_apx.txt b/L1Trigger/DemonstratorTools/test/gtt/example_vertex_apx.txt new file mode 100644 index 0000000000000..ac930f31e77a1 --- /dev/null +++ b/L1Trigger/DemonstratorTools/test/gtt/example_vertex_apx.txt @@ -0,0 +1,175 @@ +#Sideband ON +#LinkLabel LINK_00 +#BeginData +0x0000 0x00 0x0000000000000000 +0x0001 0x00 0x0000000000000000 +0x0002 0x00 0x0000000000000000 +0x0003 0x00 0x0000000000000000 +0x0004 0x00 0x0000000000000000 +0x0005 0x00 0x0000000000000000 +0x0006 0x00 0x0000000000000000 +0x0007 0x00 0x0000000000000000 +0x0008 0x00 0x0000000000000000 +0x0009 0x00 0x0000000000000000 +0x000a 0x03 0x0000000000000001 +0x000b 0x01 0x0000000000000001 +0x000c 0x01 0x0000000000000001 +0x000d 0x01 0x0000000000000001 +0x000e 0x01 0x0000000000000000 +0x000f 0x01 0x0000000000000000 +0x0010 0x01 0x0000000000000000 +0x0011 0x01 0x0000000000000000 +0x0012 0x01 0x0000000000000000 +0x0013 0x09 0x0000000000000000 +0x0014 0x00 0x0000000000000000 +0x0015 0x00 0x0000000000000000 +0x0016 0x00 0x0000000000000000 +0x0017 0x00 0x0000000000000000 +0x0018 0x00 0x0000000000000000 +0x0019 0x00 0x0000000000000000 +0x001a 0x00 0x0000000000000000 +0x001b 0x00 0x0000000000000000 +0x001c 0x00 0x0000000000000000 +0x001d 0x00 0x0000000000000000 +0x001e 0x00 0x0000000000000000 +0x001f 0x00 0x0000000000000000 +0x0020 0x00 0x0000000000000000 +0x0021 0x00 0x0000000000000000 +0x0022 0x00 0x0000000000000000 +0x0023 0x00 0x0000000000000000 +0x0024 0x00 0x0000000000000000 +0x0025 0x00 0x0000000000000000 +0x0026 0x00 0x0000000000000000 +0x0027 0x00 0x0000000000000000 +0x0028 0x00 0x0000000000000000 +0x0029 0x00 0x0000000000000000 +0x002a 0x00 0x0000000000000000 +0x002b 0x00 0x0000000000000000 +0x002c 0x00 0x0000000000000000 +0x002d 0x00 0x0000000000000000 +0x002e 0x00 0x0000000000000000 +0x002f 0x00 0x0000000000000000 +0x0030 0x00 0x0000000000000000 +0x0031 0x00 0x0000000000000000 +0x0032 0x00 0x0000000000000000 +0x0033 0x00 0x0000000000000000 +0x0034 0x00 0x0000000000000000 +0x0035 0x00 0x0000000000000000 +0x0036 0x00 0x0000000000000000 +0x0037 0x00 0x0000000000000000 +0x0038 0x00 0x0000000000000000 +0x0039 0x00 0x0000000000000000 +0x003a 0x00 0x0000000000000000 +0x003b 0x00 0x0000000000000000 +0x003c 0x00 0x0000000000000000 +0x003d 0x00 0x0000000000000000 +0x003e 0x00 0x0000000000000000 +0x003f 0x00 0x0000000000000000 +0x0040 0x03 0x0000000000000001 +0x0041 0x01 0x0000000000000001 +0x0042 0x01 0x0000000000000000 +0x0043 0x01 0x0000000000000000 +0x0044 0x01 0x0000000000000000 +0x0045 0x01 0x0000000000000000 +0x0046 0x01 0x0000000000000000 +0x0047 0x01 0x0000000000000000 +0x0048 0x01 0x0000000000000000 +0x0049 0x09 0x0000000000000000 +0x004a 0x00 0x0000000000000000 +0x004b 0x00 0x0000000000000000 +0x004c 0x00 0x0000000000000000 +0x004d 0x00 0x0000000000000000 +0x004e 0x00 0x0000000000000000 +0x004f 0x00 0x0000000000000000 +0x0050 0x00 0x0000000000000000 +0x0051 0x00 0x0000000000000000 +0x0052 0x00 0x0000000000000000 +0x0053 0x00 0x0000000000000000 +0x0054 0x00 0x0000000000000000 +0x0055 0x00 0x0000000000000000 +0x0056 0x00 0x0000000000000000 +0x0057 0x00 0x0000000000000000 +0x0058 0x00 0x0000000000000000 +0x0059 0x00 0x0000000000000000 +0x005a 0x00 0x0000000000000000 +0x005b 0x00 0x0000000000000000 +0x005c 0x00 0x0000000000000000 +0x005d 0x00 0x0000000000000000 +0x005e 0x00 0x0000000000000000 +0x005f 0x00 0x0000000000000000 +0x0060 0x00 0x0000000000000000 +0x0061 0x00 0x0000000000000000 +0x0062 0x00 0x0000000000000000 +0x0063 0x00 0x0000000000000000 +0x0064 0x00 0x0000000000000000 +0x0065 0x00 0x0000000000000000 +0x0066 0x00 0x0000000000000000 +0x0067 0x00 0x0000000000000000 +0x0068 0x00 0x0000000000000000 +0x0069 0x00 0x0000000000000000 +0x006a 0x00 0x0000000000000000 +0x006b 0x00 0x0000000000000000 +0x006c 0x00 0x0000000000000000 +0x006d 0x00 0x0000000000000000 +0x006e 0x00 0x0000000000000000 +0x006f 0x00 0x0000000000000000 +0x0070 0x00 0x0000000000000000 +0x0071 0x00 0x0000000000000000 +0x0072 0x00 0x0000000000000000 +0x0073 0x00 0x0000000000000000 +0x0074 0x00 0x0000000000000000 +0x0075 0x00 0x0000000000000000 +0x0076 0x03 0x0000000000000001 +0x0077 0x01 0x0000000000000001 +0x0078 0x01 0x0000000000000001 +0x0079 0x01 0x0000000000000001 +0x007a 0x01 0x0000000000000001 +0x007b 0x01 0x0000000000000001 +0x007c 0x01 0x0000000000000001 +0x007d 0x01 0x0000000000000001 +0x007e 0x01 0x0000000000000000 +0x007f 0x09 0x0000000000000000 +0x0080 0x00 0x0000000000000000 +0x0081 0x00 0x0000000000000000 +0x0082 0x00 0x0000000000000000 +0x0083 0x00 0x0000000000000000 +0x0084 0x00 0x0000000000000000 +0x0085 0x00 0x0000000000000000 +0x0086 0x00 0x0000000000000000 +0x0087 0x00 0x0000000000000000 +0x0088 0x00 0x0000000000000000 +0x0089 0x00 0x0000000000000000 +0x008a 0x00 0x0000000000000000 +0x008b 0x00 0x0000000000000000 +0x008c 0x00 0x0000000000000000 +0x008d 0x00 0x0000000000000000 +0x008e 0x00 0x0000000000000000 +0x008f 0x00 0x0000000000000000 +0x0090 0x00 0x0000000000000000 +0x0091 0x00 0x0000000000000000 +0x0092 0x00 0x0000000000000000 +0x0093 0x00 0x0000000000000000 +0x0094 0x00 0x0000000000000000 +0x0095 0x00 0x0000000000000000 +0x0096 0x00 0x0000000000000000 +0x0097 0x00 0x0000000000000000 +0x0098 0x00 0x0000000000000000 +0x0099 0x00 0x0000000000000000 +0x009a 0x00 0x0000000000000000 +0x009b 0x00 0x0000000000000000 +0x009c 0x00 0x0000000000000000 +0x009d 0x00 0x0000000000000000 +0x009e 0x00 0x0000000000000000 +0x009f 0x00 0x0000000000000000 +0x00a0 0x00 0x0000000000000000 +0x00a1 0x00 0x0000000000000000 +0x00a2 0x00 0x0000000000000000 +0x00a3 0x00 0x0000000000000000 +0x00a4 0x00 0x0000000000000000 +0x00a5 0x00 0x0000000000000000 +0x00a6 0x00 0x0000000000000000 +0x00a7 0x00 0x0000000000000000 +0x00a8 0x00 0x0000000000000000 +0x00a9 0x00 0x0000000000000000 +0x00aa 0x00 0x0000000000000000 +0x00ab 0x00 0x0000000000000000 diff --git a/L1Trigger/DemonstratorTools/test/gtt/example_vertex_emp.txt b/L1Trigger/DemonstratorTools/test/gtt/example_vertex_emp.txt new file mode 100644 index 0000000000000..d675edfbf2fee --- /dev/null +++ b/L1Trigger/DemonstratorTools/test/gtt/example_vertex_emp.txt @@ -0,0 +1,175 @@ +Board CMSSW + Quad/Chan : q00c0 + Link : 000 +Frame 0000 : 0v0000000000000000 +Frame 0001 : 0v0000000000000000 +Frame 0002 : 0v0000000000000000 +Frame 0003 : 0v0000000000000000 +Frame 0004 : 0v0000000000000000 +Frame 0005 : 0v0000000000000000 +Frame 0006 : 0v0000000000000000 +Frame 0007 : 0v0000000000000000 +Frame 0008 : 0v0000000000000000 +Frame 0009 : 0v0000000000000000 +Frame 0010 : 1v0000000000000001 +Frame 0011 : 1v0000000000000001 +Frame 0012 : 1v0000000000000001 +Frame 0013 : 1v0000000000000001 +Frame 0014 : 1v0000000000000000 +Frame 0015 : 1v0000000000000000 +Frame 0016 : 1v0000000000000000 +Frame 0017 : 1v0000000000000000 +Frame 0018 : 1v0000000000000000 +Frame 0019 : 1v0000000000000000 +Frame 0020 : 0v0000000000000000 +Frame 0021 : 0v0000000000000000 +Frame 0022 : 0v0000000000000000 +Frame 0023 : 0v0000000000000000 +Frame 0024 : 0v0000000000000000 +Frame 0025 : 0v0000000000000000 +Frame 0026 : 0v0000000000000000 +Frame 0027 : 0v0000000000000000 +Frame 0028 : 0v0000000000000000 +Frame 0029 : 0v0000000000000000 +Frame 0030 : 0v0000000000000000 +Frame 0031 : 0v0000000000000000 +Frame 0032 : 0v0000000000000000 +Frame 0033 : 0v0000000000000000 +Frame 0034 : 0v0000000000000000 +Frame 0035 : 0v0000000000000000 +Frame 0036 : 0v0000000000000000 +Frame 0037 : 0v0000000000000000 +Frame 0038 : 0v0000000000000000 +Frame 0039 : 0v0000000000000000 +Frame 0040 : 0v0000000000000000 +Frame 0041 : 0v0000000000000000 +Frame 0042 : 0v0000000000000000 +Frame 0043 : 0v0000000000000000 +Frame 0044 : 0v0000000000000000 +Frame 0045 : 0v0000000000000000 +Frame 0046 : 0v0000000000000000 +Frame 0047 : 0v0000000000000000 +Frame 0048 : 0v0000000000000000 +Frame 0049 : 0v0000000000000000 +Frame 0050 : 0v0000000000000000 +Frame 0051 : 0v0000000000000000 +Frame 0052 : 0v0000000000000000 +Frame 0053 : 0v0000000000000000 +Frame 0054 : 0v0000000000000000 +Frame 0055 : 0v0000000000000000 +Frame 0056 : 0v0000000000000000 +Frame 0057 : 0v0000000000000000 +Frame 0058 : 0v0000000000000000 +Frame 0059 : 0v0000000000000000 +Frame 0060 : 0v0000000000000000 +Frame 0061 : 0v0000000000000000 +Frame 0062 : 0v0000000000000000 +Frame 0063 : 0v0000000000000000 +Frame 0064 : 1v0000000000000001 +Frame 0065 : 1v0000000000000001 +Frame 0066 : 1v0000000000000000 +Frame 0067 : 1v0000000000000000 +Frame 0068 : 1v0000000000000000 +Frame 0069 : 1v0000000000000000 +Frame 0070 : 1v0000000000000000 +Frame 0071 : 1v0000000000000000 +Frame 0072 : 1v0000000000000000 +Frame 0073 : 1v0000000000000000 +Frame 0074 : 0v0000000000000000 +Frame 0075 : 0v0000000000000000 +Frame 0076 : 0v0000000000000000 +Frame 0077 : 0v0000000000000000 +Frame 0078 : 0v0000000000000000 +Frame 0079 : 0v0000000000000000 +Frame 0080 : 0v0000000000000000 +Frame 0081 : 0v0000000000000000 +Frame 0082 : 0v0000000000000000 +Frame 0083 : 0v0000000000000000 +Frame 0084 : 0v0000000000000000 +Frame 0085 : 0v0000000000000000 +Frame 0086 : 0v0000000000000000 +Frame 0087 : 0v0000000000000000 +Frame 0088 : 0v0000000000000000 +Frame 0089 : 0v0000000000000000 +Frame 0090 : 0v0000000000000000 +Frame 0091 : 0v0000000000000000 +Frame 0092 : 0v0000000000000000 +Frame 0093 : 0v0000000000000000 +Frame 0094 : 0v0000000000000000 +Frame 0095 : 0v0000000000000000 +Frame 0096 : 0v0000000000000000 +Frame 0097 : 0v0000000000000000 +Frame 0098 : 0v0000000000000000 +Frame 0099 : 0v0000000000000000 +Frame 0100 : 0v0000000000000000 +Frame 0101 : 0v0000000000000000 +Frame 0102 : 0v0000000000000000 +Frame 0103 : 0v0000000000000000 +Frame 0104 : 0v0000000000000000 +Frame 0105 : 0v0000000000000000 +Frame 0106 : 0v0000000000000000 +Frame 0107 : 0v0000000000000000 +Frame 0108 : 0v0000000000000000 +Frame 0109 : 0v0000000000000000 +Frame 0110 : 0v0000000000000000 +Frame 0111 : 0v0000000000000000 +Frame 0112 : 0v0000000000000000 +Frame 0113 : 0v0000000000000000 +Frame 0114 : 0v0000000000000000 +Frame 0115 : 0v0000000000000000 +Frame 0116 : 0v0000000000000000 +Frame 0117 : 0v0000000000000000 +Frame 0118 : 1v0000000000000001 +Frame 0119 : 1v0000000000000001 +Frame 0120 : 1v0000000000000001 +Frame 0121 : 1v0000000000000001 +Frame 0122 : 1v0000000000000001 +Frame 0123 : 1v0000000000000001 +Frame 0124 : 1v0000000000000001 +Frame 0125 : 1v0000000000000001 +Frame 0126 : 1v0000000000000000 +Frame 0127 : 1v0000000000000000 +Frame 0128 : 0v0000000000000000 +Frame 0129 : 0v0000000000000000 +Frame 0130 : 0v0000000000000000 +Frame 0131 : 0v0000000000000000 +Frame 0132 : 0v0000000000000000 +Frame 0133 : 0v0000000000000000 +Frame 0134 : 0v0000000000000000 +Frame 0135 : 0v0000000000000000 +Frame 0136 : 0v0000000000000000 +Frame 0137 : 0v0000000000000000 +Frame 0138 : 0v0000000000000000 +Frame 0139 : 0v0000000000000000 +Frame 0140 : 0v0000000000000000 +Frame 0141 : 0v0000000000000000 +Frame 0142 : 0v0000000000000000 +Frame 0143 : 0v0000000000000000 +Frame 0144 : 0v0000000000000000 +Frame 0145 : 0v0000000000000000 +Frame 0146 : 0v0000000000000000 +Frame 0147 : 0v0000000000000000 +Frame 0148 : 0v0000000000000000 +Frame 0149 : 0v0000000000000000 +Frame 0150 : 0v0000000000000000 +Frame 0151 : 0v0000000000000000 +Frame 0152 : 0v0000000000000000 +Frame 0153 : 0v0000000000000000 +Frame 0154 : 0v0000000000000000 +Frame 0155 : 0v0000000000000000 +Frame 0156 : 0v0000000000000000 +Frame 0157 : 0v0000000000000000 +Frame 0158 : 0v0000000000000000 +Frame 0159 : 0v0000000000000000 +Frame 0160 : 0v0000000000000000 +Frame 0161 : 0v0000000000000000 +Frame 0162 : 0v0000000000000000 +Frame 0163 : 0v0000000000000000 +Frame 0164 : 0v0000000000000000 +Frame 0165 : 0v0000000000000000 +Frame 0166 : 0v0000000000000000 +Frame 0167 : 0v0000000000000000 +Frame 0168 : 0v0000000000000000 +Frame 0169 : 0v0000000000000000 +Frame 0170 : 0v0000000000000000 +Frame 0171 : 0v0000000000000000 diff --git a/L1Trigger/DemonstratorTools/test/gtt/verifyFirmwareOutput_cfg.py b/L1Trigger/DemonstratorTools/test/gtt/verifyFirmwareOutput_cfg.py new file mode 100644 index 0000000000000..ae64cf0329e65 --- /dev/null +++ b/L1Trigger/DemonstratorTools/test/gtt/verifyFirmwareOutput_cfg.py @@ -0,0 +1,48 @@ + +import FWCore.ParameterSet.Config as cms +import FWCore.Utilities.FileUtils as FileUtils +import FWCore.ParameterSet.VarParsing as VarParsing + + +# PART 1 : PARSE ARGUMENTS + +options = VarParsing.VarParsing ('analysis') +options.register ('format', + 'EMP', # default value + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "File format (APx, EMP or X20)") +options.parseArguments() + +inputFiles = [] +for filePath in options.inputFiles: + if filePath.endswith(".root"): + inputFiles.append(filePath) + else: + inputFiles += FileUtils.loadListFromFile(filePath) + + +# PART 2: SETUP MAIN CMSSW PROCESS + +process = cms.Process("GTTValidation") + +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:upgradePLS3', '') +process.load("FWCore.MessageLogger.MessageLogger_cfi") + +process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring(inputFiles) ) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.maxEvents) ) + +process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") +process.load('L1Trigger.DemonstratorTools.GTTFileReader_cff') +process.GTTFileReader.files = cms.vstring("test/gtt/example_vertex_apx.txt") +process.GTTFileReader.format = cms.untracked.string(options.format) + +process.MessageLogger.cerr.FwkReport.reportEvery = 1 +process.Timing = cms.Service("Timing", summaryOnly = cms.untracked.bool(True)) + +process.p = cms.Path(process.L1HybridTracks * process.GTTFileReader) # vertex emulator & FW-emulator comparsion module need to be added here diff --git a/L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h b/L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h deleted file mode 100644 index 51a8efe024e57..0000000000000 --- a/L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef L1Trigger_L1CaloTrigger_L1EGammaEECalibrator_h -#define L1Trigger_L1CaloTrigger_L1EGammaEECalibrator_h - -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include -#include -#include - -class L1EGammaEECalibrator { -public: - explicit L1EGammaEECalibrator(const edm::ParameterSet&); - - float calibrationFactor(const float& pt, const float& eta) const; - -private: - int etaBin(float eta) const { return bin(eta_bins, std::abs(eta)); } - int ptBin(float pt) const { return bin(pt_bins, pt); } - int bin(const std::set& container, float value) const; - - std::set eta_bins; - std::set pt_bins; - std::vector calib_factors; -}; - -#endif diff --git a/L1Trigger/L1CaloTrigger/plugins/L1CaloJetHTTProducer.cc b/L1Trigger/L1CaloTrigger/plugins/L1CaloJetHTTProducer.cc index d29032c46f497..443e2fb0eaf1e 100644 --- a/L1Trigger/L1CaloTrigger/plugins/L1CaloJetHTTProducer.cc +++ b/L1Trigger/L1CaloTrigger/plugins/L1CaloJetHTTProducer.cc @@ -20,8 +20,7 @@ HTT energy sum for CaloJets // #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/ServiceRegistry/interface/Service.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -36,7 +35,7 @@ HTT energy sum for CaloJets #include "DataFormats/JetReco/interface/GenJet.h" #include "DataFormats/JetReco/interface/GenJetCollection.h" -class L1CaloJetHTTProducer : public edm::EDProducer { +class L1CaloJetHTTProducer : public edm::stream::EDProducer<> { public: explicit L1CaloJetHTTProducer(const edm::ParameterSet&); @@ -85,7 +84,7 @@ void L1CaloJetHTTProducer::produce(edm::Event& iEvent, const edm::EventSetup& iS for (const auto& caloJet : *bxvCaloJetsHandle.product()) { if (caloJet.pt() < PtMin) continue; - if (fabs(caloJet.eta()) > EtaMax) + if (std::abs(caloJet.eta()) > EtaMax) continue; *CaloJetHTT += float(caloJet.pt()); } @@ -105,7 +104,7 @@ void L1CaloJetHTTProducer::produce(edm::Event& iEvent, const edm::EventSetup& iS for (const auto& genJet : *genJetsHandle.product()) { if (genJet.pt() < PtMin) continue; - if (fabs(genJet.eta()) > EtaMax) + if (std::abs(genJet.eta()) > EtaMax) continue; *CaloJetHTT += float(genJet.pt()); } diff --git a/L1Trigger/L1CaloTrigger/plugins/L1CaloJetProducer.cc b/L1Trigger/L1CaloTrigger/plugins/L1CaloJetProducer.cc index 5fd985648c4a9..07f8ff64c6470 100644 --- a/L1Trigger/L1CaloTrigger/plugins/L1CaloJetProducer.cc +++ b/L1Trigger/L1CaloTrigger/plugins/L1CaloJetProducer.cc @@ -24,8 +24,7 @@ and clusters them within fixed number of trigger towers #include "DataFormats/Math/interface/deltaPhi.h" #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/ServiceRegistry/interface/Service.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -52,7 +51,7 @@ and clusters them within fixed number of trigger towers #include "DataFormats/L1Trigger/interface/Tau.h" #include "DataFormats/L1Trigger/interface/Jet.h" -class L1CaloJetProducer : public edm::EDProducer { +class L1CaloJetProducer : public edm::stream::EDProducer<> { public: explicit L1CaloJetProducer(const edm::ParameterSet &); @@ -761,7 +760,7 @@ void L1CaloJetProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetu // 7x7 HCAL Trigger Towers // If seeded in barrel and hit is barrel then we can compare iEta/iPhi, else need to use eta/phi // in HGCal / transition region - if ((abs(d_iEta) <= 3 && abs(d_iPhi) <= 3) || (fabs(d_eta) < 0.3 && fabs(d_phi) < 0.3)) { + if ((abs(d_iEta) <= 3 && abs(d_iPhi) <= 3) || (std::abs(d_eta) < 0.3 && std::abs(d_phi) < 0.3)) { l1CaloTower.stale = true; n_stale++; @@ -805,21 +804,21 @@ void L1CaloJetProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetu << caloJetObj.jetCluster.phi() << "\n"; } - if ((abs(d_iEta) == 0 && abs(d_iPhi) == 0) || (fabs(d_eta) < 0.043 && fabs(d_phi) < 0.043)) { + if ((abs(d_iEta) == 0 && abs(d_iPhi) == 0) || (std::abs(d_eta) < 0.043 && std::abs(d_phi) < 0.043)) { caloJetObj.hcal_seed += hcalP4.pt(); caloJetObj.ecal_seed += ecalP4.pt(); caloJetObj.l1eg_seed += l1egP4.pt(); caloJetObj.total_seed += totalP4.pt(); } //if ( (abs( d_iEta ) <= 1 && abs( d_iPhi ) <= 1) || - // ( fabs( d_eta ) < 0.13 && fabs( d_phi ) < 0.13 ) ) + // ( std::abs( d_eta ) < 0.13 && std::abs( d_phi ) < 0.13 ) ) //{ // caloJetObj.hcal_3x3 += hcalP4.pt(); // caloJetObj.ecal_3x3 += ecalP4.pt(); // caloJetObj.l1eg_3x3 += l1egP4.pt(); // caloJetObj.total_3x3 += totalP4.pt(); //} - if ((abs(d_iEta) <= 1 && abs(d_iPhi) <= 2) || (fabs(d_eta) < 0.13 && fabs(d_phi) < 0.22)) { + if ((abs(d_iEta) <= 1 && abs(d_iPhi) <= 2) || (std::abs(d_eta) < 0.13 && std::abs(d_phi) < 0.22)) { caloJetObj.hcal_3x5 += hcalP4.pt(); caloJetObj.ecal_3x5 += ecalP4.pt(); caloJetObj.l1eg_3x5 += l1egP4.pt(); @@ -851,7 +850,7 @@ void L1CaloJetProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetu } } //if ( ( abs( d_iEta ) <= 2 && abs( d_iPhi ) <= 2) || - // ( fabs( d_eta ) < 0.22 && fabs( d_phi ) < 0.22 ) ) + // ( std::abs( d_eta ) < 0.22 && std::abs( d_phi ) < 0.22 ) ) //{ // caloJetObj.hcal_5x5 += hcalP4.pt(); // caloJetObj.ecal_5x5 += ecalP4.pt(); @@ -859,14 +858,14 @@ void L1CaloJetProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetu // caloJetObj.total_5x5 += totalP4.pt(); //} //if ( ( abs( d_iEta ) <= 2 && abs( d_iPhi ) <= 3) || - // ( fabs( d_eta ) < 0.22 && fabs( d_phi ) < 0.3 ) ) + // ( std::abs( d_eta ) < 0.22 && std::abs( d_phi ) < 0.3 ) ) //{ // caloJetObj.hcal_5x7 += hcalP4.pt(); // caloJetObj.ecal_5x7 += ecalP4.pt(); // caloJetObj.l1eg_5x7 += l1egP4.pt(); // caloJetObj.total_5x7 += totalP4.pt(); //} - if ((abs(d_iEta) <= 3 && abs(d_iPhi) <= 3) || (fabs(d_eta) < 0.3 && fabs(d_phi) < 0.3)) { + if ((abs(d_iEta) <= 3 && abs(d_iPhi) <= 3) || (std::abs(d_eta) < 0.3 && std::abs(d_phi) < 0.3)) { caloJetObj.hcal_7x7 += hcalP4.pt(); caloJetObj.ecal_7x7 += ecalP4.pt(); caloJetObj.l1eg_7x7 += l1egP4.pt(); @@ -890,7 +889,7 @@ void L1CaloJetProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetu // caloJetObj.total_2x3_2 += totalP4.pt(); //} //// HGCal / HF - //if ( fabs( d_eta ) < 0.087 && fabs( d_phi ) < 0.13 ) + //if ( std::abs( d_eta ) < 0.087 && std::abs( d_phi ) < 0.13 ) //{ // caloJetObj.hcal_2x3 += hcalP4.pt(); // caloJetObj.ecal_2x3 += ecalP4.pt(); @@ -928,7 +927,7 @@ void L1CaloJetProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetu // caloJetObj.total_2x2_4 += totalP4.pt(); //} //// HGCal / HF - //if ( fabs( d_eta ) < 0.087 && fabs( d_phi ) < 0.087 ) + //if ( std::abs( d_eta ) < 0.087 && std::abs( d_phi ) < 0.087 ) //{ // caloJetObj.hcal_2x2 += hcalP4.pt(); // caloJetObj.ecal_2x2 += ecalP4.pt(); @@ -1144,7 +1143,7 @@ float L1CaloJetProducer::get_hcal_calibration(float &jet_pt, float &ecal_L1EG_jet_pt, float &jet_eta) const { float em_frac = (ecal_L1EG_jet_pt + ecal_pt) / jet_pt; - float abs_eta = fabs(jet_eta); + float abs_eta = std::abs(jet_eta); float tmp_jet_pt = jet_pt; if (tmp_jet_pt > 499) tmp_jet_pt = 499; @@ -1234,7 +1233,7 @@ float L1CaloJetProducer::get_hcal_calibration(float &jet_pt, float L1CaloJetProducer::get_tau_pt_calibration( float &tau_pt, float &ecal_pt, float &l1EG_pt, float &n_L1EGs, float &tau_eta) const { float em_frac = (l1EG_pt + ecal_pt) / tau_pt; - float abs_eta = fabs(tau_eta); + float abs_eta = std::abs(tau_eta); float tmp_tau_pt = tau_pt; if (tmp_tau_pt > 199) tmp_tau_pt = 199; @@ -1336,7 +1335,7 @@ int L1CaloJetProducer::loose_iso_tau_wp(float &tau_pt, float &tau_iso_et, float } // Split by barrel and HGCal // with Barrel first - if (fabs(tau_eta) < 1.5) { + if (std::abs(tau_eta) < 1.5) { if (isoTauBarrel.Eval(tau_pt) >= (tau_iso_et / tau_pt)) { return 1; } else { @@ -1344,7 +1343,7 @@ int L1CaloJetProducer::loose_iso_tau_wp(float &tau_pt, float &tau_iso_et, float } } // HGCal - if (fabs(tau_eta) < 3.0) { + if (std::abs(tau_eta) < 3.0) { if (isoTauHGCal.Eval(tau_pt) >= (tau_iso_et / tau_pt)) { return 1; } else { diff --git a/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc b/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc index 8d8ba03cadec4..5a11cd0802f3f 100644 --- a/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc +++ b/L1Trigger/L1CaloTrigger/plugins/L1EGammaCrystalsEmulatorProducer.cc @@ -28,7 +28,6 @@ Description: Produces crystal clusters using crystal-level information and hardw // user include files #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" diff --git a/L1Trigger/L1CaloTrigger/plugins/L1EGammaEEProducer.cc b/L1Trigger/L1CaloTrigger/plugins/L1EGammaEEProducer.cc deleted file mode 100644 index 48d37445b3707..0000000000000 --- a/L1Trigger/L1CaloTrigger/plugins/L1EGammaEEProducer.cc +++ /dev/null @@ -1,169 +0,0 @@ -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -#include "DataFormats/L1THGCal/interface/HGCalMulticluster.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/L1Trigger/interface/EGamma.h" -#include "L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h" -#include "DataFormats/Math/interface/deltaPhi.h" - -namespace l1tp2 { - // we sort the clusters in pt - bool compare_cluster_pt(const l1t::HGCalMulticluster *cl1, const l1t::HGCalMulticluster *cl2) { - return cl1->pt() > cl2->pt(); - } -}; // namespace l1tp2 - -int etaBin(const l1t::HGCalMulticluster *cl) { - static float constexpr eta_min = 1.; - static float constexpr eta_max = 4.; - static unsigned constexpr n_eta_bins = 150; - int eta_bin = floor((std::abs(cl->eta()) - eta_min) / ((eta_max - eta_min) / n_eta_bins)); - if (cl->eta() < 0) - return -1 * eta_bin; // bin 0 doesn't exist - return eta_bin; -} - -int get_phi_bin(const l1t::HGCalMulticluster *cl) { - static constexpr float phi_min = -M_PI; - static constexpr float phi_max = M_PI; - static constexpr unsigned n_phi_bins = 63; - return floor(std::abs(reco::deltaPhi(cl->phi(), phi_min)) / ((phi_max - phi_min) / n_phi_bins)); -} - -pair get_eta_phi_bin(const l1t::HGCalMulticluster *cl) { return std::make_pair(etaBin(cl), get_phi_bin(cl)); } - -class L1EGammaEEProducer : public edm::stream::EDProducer<> { -public: - explicit L1EGammaEEProducer(const edm::ParameterSet &); - -private: - void produce(edm::Event &, const edm::EventSetup &) override; - - edm::EDGetToken multiclusters_token_; - L1EGammaEECalibrator calibrator_; -}; - -L1EGammaEEProducer::L1EGammaEEProducer(const edm::ParameterSet &iConfig) - : multiclusters_token_( - consumes(iConfig.getParameter("Multiclusters"))), - calibrator_(iConfig.getParameter("calibrationConfig")) { - produces>("L1EGammaCollectionBXVWithCuts"); -} - -void L1EGammaEEProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { - float minEt_ = 0; - - std::unique_ptr> l1EgammaBxCollection(new l1t::EGammaBxCollection); - - // retrieve clusters 3D - edm::Handle multiclusters_h; - iEvent.getByToken(multiclusters_token_, multiclusters_h); - const l1t::HGCalMulticlusterBxCollection &multiclusters = *multiclusters_h; - - std::vector selected_multiclusters; - std::map, std::vector> etaphi_bins; - - // here we loop on the TPGs - for (auto cl3d = multiclusters.begin(0); cl3d != multiclusters.end(0); cl3d++) { - if (cl3d->hwQual()) { - if (cl3d->et() > minEt_) { - int hw_quality = 1; // baseline EG ID passed - if (std::abs(cl3d->eta()) >= 1.52) { - hw_quality = 2; // baseline EG ID passed + cleanup of transition region - } - - float calib_factor = calibrator_.calibrationFactor(cl3d->pt(), cl3d->eta()); - l1t::EGamma eg = - l1t::EGamma(reco::Candidate::PolarLorentzVector(cl3d->pt() / calib_factor, cl3d->eta(), cl3d->phi(), 0.)); - eg.setHwQual(hw_quality); - eg.setHwIso(1); - eg.setIsoEt(-1); // just temporarily as a dummy value - l1EgammaBxCollection->push_back(0, eg); - if (hw_quality == 2) { - // we build the EM interpreted EG object - l1t::EGamma eg_emint = l1t::EGamma(reco::Candidate::PolarLorentzVector( - cl3d->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM), cl3d->eta(), cl3d->phi(), 0.)); - eg_emint.setHwQual(4); - eg_emint.setHwIso(1); - eg_emint.setIsoEt(-1); // just temporarily as a dummy value - l1EgammaBxCollection->push_back(0, eg_emint); - // we also prepare for the brem recovery procedure - selected_multiclusters.push_back(&(*cl3d)); - auto eta_phi_bin = get_eta_phi_bin(&(*cl3d)); - auto bucket = etaphi_bins.find(eta_phi_bin); - if (bucket == etaphi_bins.end()) { - std::vector vec; - vec.push_back(&(*cl3d)); - etaphi_bins[eta_phi_bin] = vec; - } else { - bucket->second.push_back(&(*cl3d)); - } - } - } - } - } - - std::sort(selected_multiclusters.begin(), selected_multiclusters.end(), l1tp2::compare_cluster_pt); - std::set used_clusters; - for (const auto &cl3d : selected_multiclusters) { - if (used_clusters.find(cl3d) == used_clusters.end()) { - float pt = cl3d->pt(); - // we drop the Had component of the energy - if (cl3d->hOverE() != -1) - pt = cl3d->pt() / (1 + cl3d->hOverE()); - reco::Candidate::PolarLorentzVector mom(pt, cl3d->eta(), cl3d->phi(), 0.); - reco::Candidate::PolarLorentzVector mom_eint( - cl3d->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM), cl3d->eta(), cl3d->phi(), 0.); - - // this is not yet used - used_clusters.insert(cl3d); - auto eta_phi_bin = get_eta_phi_bin(cl3d); - - for (int eta_bin : {eta_phi_bin.first - 1, eta_phi_bin.first, eta_phi_bin.first + 1}) { - for (int phi_bin : {eta_phi_bin.second - 1, eta_phi_bin.second, eta_phi_bin.second + 1}) { - auto bucket = etaphi_bins.find(std::make_pair(eta_bin, phi_bin)); - if (bucket != etaphi_bins.end()) { - // this bucket is not empty - for (const auto &other_cl_ptr : bucket->second) { - if (used_clusters.find(other_cl_ptr) == used_clusters.end()) { - if (std::abs(other_cl_ptr->eta() - cl3d->eta()) < 0.02) { - if (std::abs(reco::deltaPhi(other_cl_ptr->phi(), cl3d->phi())) < 0.1) { - float pt_other = other_cl_ptr->pt(); - if (other_cl_ptr->hOverE() != -1) - pt_other = other_cl_ptr->pt() / (1 + other_cl_ptr->hOverE()); - mom += reco::Candidate::PolarLorentzVector(pt_other, other_cl_ptr->eta(), other_cl_ptr->phi(), 0.); - mom_eint += reco::Candidate::PolarLorentzVector( - other_cl_ptr->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM), - other_cl_ptr->eta(), - other_cl_ptr->phi(), - 0.); - used_clusters.insert(other_cl_ptr); - } - } - } - } - } - } - } - float calib_factor = calibrator_.calibrationFactor(mom.pt(), mom.eta()); - l1t::EGamma eg = - l1t::EGamma(reco::Candidate::PolarLorentzVector(mom.pt() / calib_factor, mom.eta(), mom.phi(), 0.)); - eg.setHwQual(3); - eg.setHwIso(1); - l1EgammaBxCollection->push_back(0, eg); - - l1t::EGamma eg_emint_brec = - l1t::EGamma(reco::Candidate::PolarLorentzVector(mom_eint.pt(), mom_eint.eta(), mom_eint.phi(), 0.)); - eg_emint_brec.setHwQual(5); - eg_emint_brec.setHwIso(1); - l1EgammaBxCollection->push_back(0, eg_emint_brec); - } - } - - iEvent.put(std::move(l1EgammaBxCollection), "L1EGammaCollectionBXVWithCuts"); -} - -DEFINE_FWK_MODULE(L1EGammaEEProducer); diff --git a/L1Trigger/L1CaloTrigger/plugins/L1TowerCalibrator.cc b/L1Trigger/L1CaloTrigger/plugins/L1TowerCalibrator.cc index 9054acca9739e..9b09f4d34adbb 100644 --- a/L1Trigger/L1CaloTrigger/plugins/L1TowerCalibrator.cc +++ b/L1Trigger/L1CaloTrigger/plugins/L1TowerCalibrator.cc @@ -38,7 +38,7 @@ This is all ECAL / HCAL specific or EM vs. Hadronic for HGCal. // #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDProducer.h" +#include "FWCore/Framework/interface/one/EDProducer.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -60,7 +60,7 @@ This is all ECAL / HCAL specific or EM vs. Hadronic for HGCal. #include "TFile.h" #include "TF1.h" -class L1TowerCalibrator : public edm::EDProducer { +class L1TowerCalibrator : public edm::one::EDProducer<> { public: explicit L1TowerCalibrator(const edm::ParameterSet&); diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase1L1TJetProducer.cc b/L1Trigger/L1CaloTrigger/plugins/Phase1L1TJetProducer.cc index ba5685517b2a8..beea39ff0a9e7 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase1L1TJetProducer.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase1L1TJetProducer.cc @@ -37,7 +37,6 @@ Description: Produces jets with a phase-1 like sliding window algorithm using a #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Framework/interface/one/EDProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "DataFormats/JetReco/interface/CaloJet.h" #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" #include "DataFormats/L1TParticleFlow/interface/PFCluster.h" diff --git a/L1Trigger/L1CaloTrigger/plugins/Phase1L1TJetSumsProducer.cc b/L1Trigger/L1CaloTrigger/plugins/Phase1L1TJetSumsProducer.cc index 5806141fd2e06..ee62fa65cb4bd 100644 --- a/L1Trigger/L1CaloTrigger/plugins/Phase1L1TJetSumsProducer.cc +++ b/L1Trigger/L1CaloTrigger/plugins/Phase1L1TJetSumsProducer.cc @@ -27,7 +27,6 @@ Description: Computes HT and MHT from phase-1-like jets #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Framework/interface/one/EDProducer.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "DataFormats/JetReco/interface/CaloJet.h" #include "DataFormats/L1Trigger/interface/EtSum.h" #include "DataFormats/Common/interface/View.h" diff --git a/L1Trigger/L1CaloTrigger/python/L1TCaloTriggerNtuples_cff.py b/L1Trigger/L1CaloTrigger/python/L1TCaloTriggerNtuples_cff.py deleted file mode 100644 index 5c3d602ce1baf..0000000000000 --- a/L1Trigger/L1CaloTrigger/python/L1TCaloTriggerNtuples_cff.py +++ /dev/null @@ -1,24 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from L1Trigger.L1THGCalUtilities.hgcalTriggerNtuples_cfi import * - -l1CaloTriggerNtuplizer = hgcalTriggerNtuplizer.clone() - -ntuple_multiclusters_hmvdr = ntuple_multiclusters.clone() -ntuple_multiclusters_hmvdr.Prefix = cms.untracked.string('HMvDR') - -l1CaloTriggerNtuplizer.Ntuples = cms.VPSet(ntuple_event, - ntuple_gen, - ntuple_triggercells, - ntuple_multiclusters_hmvdr) - -from L1Trigger.L1CaloTrigger.ntuple_cfi import * - -l1CaloTriggerNtuplizer.Ntuples.append(ntuple_egammaEE) -l1CaloTriggerNtuplizer.Ntuples.append(ntuple_egammaEB) -l1CaloTriggerNtuplizer.Ntuples.append(ntuple_TTTracks) -l1CaloTriggerNtuplizer.Ntuples.append(ntuple_tkEleEllEE) -l1CaloTriggerNtuplizer.Ntuples.append(ntuple_tkEleEllEB) - -l1CaloTriggerNtuples = cms.Sequence(l1CaloTriggerNtuplizer) - diff --git a/L1Trigger/L1CaloTrigger/python/L1TowerCalibrationProducer_cfi.py b/L1Trigger/L1CaloTrigger/python/L1TowerCalibrationProducer_cfi.py index dcadde6ad3a59..89a131a539afe 100644 --- a/L1Trigger/L1CaloTrigger/python/L1TowerCalibrationProducer_cfi.py +++ b/L1Trigger/L1CaloTrigger/python/L1TowerCalibrationProducer_cfi.py @@ -28,7 +28,7 @@ hfSF = cms.double(1.0), debug = cms.bool(False), skipCalibrations = cms.bool(False), - l1CaloTowers = cms.InputTag("L1EGammaClusterEmuProducer",), + l1CaloTowers = cms.InputTag("L1EGammaClusterEmuProducer","L1CaloTowerCollection",""), L1HgcalTowersInputTag = cms.InputTag("hgcalTowerProducer:HGCalTowerProcessor"), hcalDigis = cms.InputTag("simHcalTriggerPrimitiveDigis"), nHits_to_nvtx_params = cms.VPSet( # Parameters derived on 6 March 2019 on 10_3_X MTD samples diff --git a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_9x9Jets_cfi.py b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_9x9Jets_cfi.py index 61769a9d24c97..58f5933172073 100644 --- a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_9x9Jets_cfi.py +++ b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_9x9Jets_cfi.py @@ -4,773 +4,162 @@ etaMax = cms.double(0.435), etaMin = cms.double(0), l1tCalibrationFactors = cms.vdouble( - 1.26146717329, 1.26146717329, 1.26146717329, 1.26146717329, 1.26146717329, - 1.26146717329, 1.26146717329, 1.24623228894, 1.22774013608, 1.20864472626, - 1.18983620186, 1.17220606581, 1.1583247683, 1.14631058894, 1.13609994066, - 1.12752496855, 1.12089178748, 1.11699447611, 1.11526653347, 1.11555762523, - 1.09853049091, 1.09683531526, 1.09514972072, 1.09326684356, 1.09162970037, - 1.08995375793, 1.08825706983, 1.08670271417, 1.08475374607, 1.08288456528, - 1.0811741799, 1.07928109805, 1.07818965233, 1.07651502479, 1.07449932258, - 1.07285243919, 1.0707178513, 1.06924419003, 1.06772074029, 1.06611812413, - 1.0648425894, 1.06246808088, 1.06156200302, 1.0592770589, 1.05752747574, - 1.0562094913, 1.05403560794, 1.05239347578, 1.0505342996, 1.04819572369, - 1.04813853787, 1.04508846408, 1.04554414394, 1.04558937184, 1.04582193656, - 1.04620801277, 1.04629403559, 1.04678402565, 1.04693513867, 1.04707997811, - 1.04729707852, 1.04761924239, 1.04814409297, 1.04817625354, 1.04827738829, - 1.04862435571, 1.04899633011, 1.04928518739, 1.04948410793, 1.04953664235, - 1.05003438124, 1.05022255911, 1.05079418764, 1.05080587637, 1.0509830576, - 1.05107821919, 1.05138802599, 1.05180619558, 1.05197881611, 1.05212175371, - 1.05264782037, 1.05296283034, 1.05308910042, 1.05374518535, 1.05502979799, - 1.0565958427, 1.057764105, 1.0588840728, 1.06031846417, 1.06116441033, - 1.06276845969, 1.06379817554, 1.06450339465, 1.0661557688, 1.06662936414, - 1.06836012995, 1.06997205086, 1.07041209892, 1.07169696027, 1.07258808631, - 1.07293155402, 1.07354286066, 1.07463205829, 1.07708654714, 1.07781843344, - 1.07822325122, 1.07846301946, 1.07932205225, 1.0808090032, 1.08141472035, - 1.08181938516, 1.08304678146, 1.08314137081, 1.08365386745, 1.08384051114, - 1.08474353214, 1.08568646733 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 13.8924070115, 15.5860038298, 18.0893326776, 20.9564367755, - 23.9770832376, 27.0624635982, 30.5728737338, 34.0912004568, 37.5058618916, - 41.28259481, 45.3408244209, 49.3133175961, 53.093074924, 56.9139697296, - 60.8674434948, 65.0370376256, 69.1457997754, 72.9170868064, 76.9300170371, - 80.9502314594, 84.7098877358, 88.5948271577, 92.6954597315, 96.7404154687, - 100.547576625, 104.423162547, 108.159029626, 112.184798836, 116.572342591, - 120.685724144, 124.826571081, 128.2561768, 131.43475045, 135.675413589, - 139.884195127, 144.229591592, 148.375933576, 151.819999288, 155.412250741, - 158.71961599, 162.913984762, 166.683800103, 170.350694444, 174.986884782, - 178.511914168, 182.524519011, 186.909611243, 190.93306449, 195.756821106, - 198.509859211, 201.441789801, 207.652012822, 211.327924084, 213.366505054, - 217.906400994, 221.370899319, 225.597969342, 230.302703785, 232.47455073, - 235.130646041, 239.088036491, 245.303851371, 249.391477266, 250.369664834, - 253.658062256, 258.934016204, 263.783528944, 267.363086105, 269.208388119, - 273.246568362, 278.280167959, 283.856006586, 288.136679844, 289.522701901, - 291.521289472, 294.493149718, 299.835403885, 304.170916706, 306.486639748, - 311.396126928, 317.568367117, 320.80670045, 326.54801202, 340.789819604, - 361.709366349, 381.775076142, 398.567250891, 417.312413581, 434.046668715, - 452.025958872, 471.353842702, 484.085661524, 501.386857761, 516.988283156, - 533.164985739, 557.695289505, 572.753662147, 585.411908484, 601.380390144, - 610.440455386, 617.447066221, 629.926215437, 655.931555782, 679.314767255, - 687.656469243, 692.386763225, 700.450313755, 717.666313573, 733.02335672, - 740.43804395, 752.41492308, 762.116313664, 766.571413729, 771.702054536, - 779.698558007, 793.245106025, float('inf') + 1.23979294877, 1.23979294877, 1.23979294877, 1.2055534748, 1.16221465185, + 1.1287061285, 1.10174091558, 1.08560073006, 1.06054297933, 1.05390045065, + 1.04755164016, 1.04056108809, 1.03288843815, 1.02558076448, 1.01840595314, + 1.01028026223, 0.994979528345, 0.994359643857, 0.993589993902, 0.992484418292, + 0.991580925563, 0.990450519445, 0.989274770481, 0.989062288938, 0.987526878875, + 0.987143421961, 0.986960123031, 0.985118762072, 0.983812522399, 0.982603964756, + 0.982487894417, 0.9776664197 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 16.8880031307, 23.7353661004, 31.9930260358, 41.2104176206, + 50.6051414267, 60.247220362, 69.8880955069, 79.7508114194, 89.9187170854, + 99.552677671, 109.444721239, 120.318481705, 131.427409379, 142.167155912, + 153.513517796, 170.885803296, 192.373045006, 219.860641852, 262.12573798, + 307.407472656, 353.248854037, 405.226529713, 436.515403398, 475.910561056, + 519.15927673, 531.933201461, 577.566348974, 648.509090909, 705.189285714, + 735.044642857, 846.330357143, float('inf') ) ), cms.PSet( etaMax = cms.double(0.783), etaMin = cms.double(0.435), l1tCalibrationFactors = cms.vdouble( - 1.27440254712, 1.27440254712, 1.27440254712, 1.27440254712, 1.27440254712, - 1.27440254712, 1.27440254712, 1.26237861784, 1.23951156915, 1.21936711031, - 1.20113175263, 1.18314392239, 1.16741650703, 1.1532578472, 1.14251404461, - 1.13200827803, 1.12427897706, 1.11860055115, 1.11471654207, 1.11309371657, - 1.1035823547, 1.10196181856, 1.10027074608, 1.09833277227, 1.09643569091, - 1.09479603469, 1.09254753293, 1.0910773106, 1.08944340405, 1.08705077883, - 1.08537639048, 1.08421015427, 1.08256687333, 1.07995863059, 1.07902607265, - 1.07655905818, 1.07503735031, 1.07301389635, 1.07165575749, 1.06929921168, - 1.06821092927, 1.06616199123, 1.06487780021, 1.06328778675, 1.0601816044, - 1.05917489441, 1.05866746046, 1.05722684059, 1.05413790801, 1.05293443771, - 1.05073793986, 1.05074440903, 1.05156882707, 1.05163408963, 1.05181488861, - 1.05200189767, 1.05217943685, 1.05254100206, 1.05307882377, 1.05386936932, - 1.05395003667, 1.0542087993, 1.05432475605, 1.05494245045, 1.05517112014, - 1.05525094335, 1.0557115483, 1.05594207892, 1.05625830743, 1.05696698354, - 1.05725628851, 1.05743196571, 1.05751284882, 1.05781632022, 1.05799531513, - 1.05839650856, 1.05904363259, 1.05904762922, 1.05949497688, 1.05993791442, - 1.06013251385, 1.06028823516, 1.06060327995, 1.06148490738, 1.0633070629, - 1.06449096664, 1.06670714728, 1.06801525532, 1.06985663341, 1.07108256509, - 1.07206439709, 1.0740254986, 1.07557580148, 1.07619628328, 1.07858299527, - 1.07945640742, 1.08120547417, 1.08132667522, 1.0830354305, 1.08433727452, - 1.08550593118, 1.08573737565, 1.08856278526, 1.08898559663, 1.09085721249, - 1.09115172941, 1.09275835574, 1.09276976832, 1.09444259455, 1.09563540181, - 1.09592154537, 1.09651685067, 1.0973090816, 1.09896312764, 1.09908156772, - 1.0999610622, 1.10120919691 + 1.26088033666, 1.26088033666, 1.26088033666, 1.2249182059, 1.17603697403, + 1.13860928847, 1.11140597558, 1.09630616073, 1.06349385292, 1.05842913938, + 1.05398549405, 1.04895539789, 1.04466168817, 1.03903857045, 1.03439337381, + 1.02704723184, 1.01728260528, 1.00806725137, 1.00707008321, 1.01235956493, + 1.01667298057, 1.02381172068, 1.02613493771, 1.03240539224, 1.03261816221, + 1.03819304914, 1.04119620768, 1.04378137592, 1.04875440814, 1.05051419343, + 1.05716649068, 1.06763963981 ), l1tPtBins = cms.vdouble( - -float('inf'), 13.5166014072, 15.373411826, 17.8203160866, 20.5214351446, - 23.7435311152, 26.9752802487, 30.159287011, 33.795645223, 37.5316299794, - 41.1721803568, 44.9660370105, 48.902377368, 52.876112172, 56.6808679777, - 60.5654106611, 64.6237707464, 68.5221021533, 72.5227681626, 76.5042056448, - 80.2180681472, 83.8258362025, 87.532675527, 91.5948377827, 95.8875954562, - 99.8464322114, 104.198630369, 108.361173199, 111.835770689, 116.342857134, - 120.895256769, 124.074901486, 127.219726204, 131.978656674, 135.94204146, - 139.747342798, 144.212107373, 148.180373794, 151.965549722, 156.12357104, - 159.979529336, 163.491167779, 167.222095949, 170.439328244, 175.696001155, - 180.29975505, 181.994607597, 184.175155894, 189.245297056, 194.049985541, - 198.340003157, 201.321048531, 206.218215217, 211.461904271, 212.912166551, - 215.079990584, 217.228601695, 220.406029412, 225.706926541, 233.536191247, - 238.671033554, 240.671600092, 242.880158901, 247.204225898, 252.192611789, - 254.010838342, 257.196068218, 261.26955259, 264.492096592, 270.532782577, - 276.414783911, 279.155342625, 280.667483589, 282.932830907, 285.776439406, - 289.196011843, 295.374690785, 299.212331303, 301.872509758, 307.119762288, - 310.877341827, 312.94209744, 315.716746046, 322.769813223, 338.705641346, - 356.423056004, 376.462815601, 397.234622991, 415.797381365, 433.875800387, - 446.888140191, 464.233497952, 484.92936658, 497.723755857, 515.447857308, - 534.662705108, 550.119335237, 561.142507879, 571.928088666, 589.672261866, - 604.233147494, 612.485204409, 630.501998671, 649.646690452, 663.169816605, - 675.936788044, 687.141937495, 696.678498096, 706.605234297, 723.494993391, - 732.211782606, 737.406954657, 745.584955357, 760.003068783, 770.449925926, - 776.331653061, 788.871688149, float('inf') + -float('inf'), 16.693599742, 23.4533780602, 31.574804867, 40.607871487, + 50.0226273473, 59.5432535328, 68.9906256857, 78.7889753636, 89.2161833142, + 99.0522298664, 108.852466017, 118.497599303, 128.756191525, 139.378383999, + 151.782981506, 169.483440448, 189.1175302, 214.728316677, 255.782543996, + 301.126430305, 355.202323162, 399.880704365, 440.459131006, 471.072245322, + 498.400961538, 538.905603448, 565.293103448, 600.982142857, 632.773809524, + 672.494791667, 753.359375, float('inf') ) ), cms.PSet( etaMax = cms.double(1.131), etaMin = cms.double(0.783), l1tCalibrationFactors = cms.vdouble( - 1.28877882208, 1.28877882208, 1.28877882208, 1.28877882208, 1.28877882208, - 1.28877882208, 1.28877882208, 1.27694835829, 1.25297836741, 1.23044531865, - 1.20855235448, 1.1893282309, 1.1725504389, 1.159203929, 1.14569587541, - 1.13380083086, 1.12771359895, 1.12132733429, 1.11801327984, 1.1164039178, - 1.09801792847, 1.09588518489, 1.09370961881, 1.09201093419, 1.09011871384, - 1.08808881147, 1.08571111049, 1.0844474359, 1.0816414337, 1.07974691293, - 1.07795760075, 1.07551422323, 1.07375791565, 1.07236983191, 1.07058218311, - 1.06770191716, 1.06603119504, 1.06362972852, 1.06219040348, 1.05951643702, - 1.05780511343, 1.05549894379, 1.05456596784, 1.05183218447, 1.04998506398, - 1.04777908115, 1.04555637855, 1.04371561533, 1.04114340237, 1.0397345442, - 1.03703721093, 1.0370020161, 1.03697403511, 1.03684016386, 1.03681653914, - 1.03674288479, 1.03673045853, 1.03669821954, 1.03660261509, 1.03654890521, - 1.03647824831, 1.03641370002, 1.03638368584, 1.0363474327, 1.03626689773, - 1.0362274515, 1.03612736074, 1.03606484142, 1.03601160822, 1.0359745858, - 1.03591575182, 1.03585836866, 1.03576558282, 1.03572050093, 1.03570445277, - 1.03564801105, 1.03564340833, 1.03559278773, 1.03548525195, 1.03540543085, - 1.03537311338, 1.035353379, 1.03531268737, 1.03509757281, 1.03481844747, - 1.03460188756, 1.03436873742, 1.03404872284, 1.03382849525, 1.03352709651, - 1.03339139385, 1.03316615269, 1.03281524483, 1.03254783724, 1.0322983399, - 1.03220214395, 1.03198001329, 1.03179532519, 1.03149961876, 1.03119032511, - 1.03108787294, 1.03084032788, 1.03073682524, 1.03031711785, 1.03026374639, - 1.03000361434, 1.02980821858, 1.02966151075, 1.02953728147, 1.0295357024, - 1.02913791337, 1.02909523261, 1.0288898051, 1.02885866633, 1.02866419809, - 1.02857281869, 1.02854490374 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 13.5223180803, 15.3157792118, 17.7207146184, 20.4619302345, - 23.3867043945, 26.6674195508, 30.0148453856, 33.5181156442, 37.2034564252, - 41.0654706777, 45.0242304428, 48.9215289734, 52.6171619736, 56.4669723943, - 60.8532828285, 64.6431610877, 68.2511806135, 72.1165788509, 75.9507576219, - 80.178753144, 84.4601989805, 88.7755810919, 92.6561916984, 96.2529914483, - 100.18155266, 104.59639146, 108.243744657, 112.320102165, 117.028341441, - 120.718221713, 124.957859738, 129.164438975, 132.313992074, 135.494937852, - 140.170515382, 144.728974276, 148.807847754, 152.654944304, 156.774988123, - 161.167476996, 165.191565276, 168.436028198, 172.108806818, 176.697230616, - 180.756987451, 185.192942943, 189.263079284, 193.683299739, 197.670906127, - 200.669569599, 203.481912923, 205.680557963, 211.313340235, 216.794515892, - 220.180022472, 223.175800166, 224.730240575, 229.17944849, 234.375886398, - 238.704099822, 243.409511328, 246.700474731, 249.00671039, 253.071170975, - 257.246757399, 262.102924202, 267.762080987, 271.790500732, 274.931577111, - 278.267572043, 282.312161533, 287.538343865, 292.336417173, 294.463865342, - 296.986658469, 299.111127436, 301.033009752, 306.537168829, 313.057563733, - 316.96021075, 318.771719474, 320.874665805, 329.777234102, 346.977773204, - 364.228613586, 379.879425057, 399.130666101, 417.932176338, 436.085818382, - 451.29782338, 463.859392071, 483.910533029, 505.429149973, 523.418477617, - 535.449297178, 546.527701523, 560.68580979, 577.404502376, 598.459717959, - 612.789297808, 624.969903015, 637.187066993, 655.395825055, 671.859917095, - 682.770467826, 698.623748975, 710.529639449, 719.958794038, 724.337177101, - 738.235987456, 753.565219085, 762.199884396, 770.432864923, 778.284440936, - 788.232511997, 792.384194735, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(1.305), - etaMin = cms.double(1.131), - l1tCalibrationFactors = cms.vdouble( - 1.30464904899, 1.30464904899, 1.30464904899, 1.30464904899, 1.30464904899, - 1.30464904899, 1.30464904899, 1.28753966966, 1.26184241946, 1.23615743701, - 1.21112716928, 1.18830854051, 1.16922129671, 1.15162104151, 1.13926988997, - 1.12013893675, 1.11315074529, 1.10421726948, 1.09857786941, 1.08796490485, - 1.08552778022, 1.08306838599, 1.08021288693, 1.07781388228, 1.07524586684, - 1.07202146179, 1.07155192888, 1.06803593019, 1.0650691697, 1.0625137133, - 1.05970398098, 1.05913981338, 1.05484331908, 1.05247891606, 1.04987962874, - 1.04909722507, 1.04389372917, 1.04368102591, 1.0422637752, 1.0370645451, - 1.03592014765, 1.03435988683, 1.03031862795, 1.02680188551, 1.02408943242, - 1.02282610293, 1.02225324386, 1.01840036238, 0.989241976704, 0.98936641432, - 0.989446855212, 0.98951480633, 0.989647898182, 0.989701958582, 0.989706514106, - 0.989820263437, 0.989821771034, 0.989943716755, 0.990074385744, 0.990085628723, - 0.990095337335, 0.990197326453, 0.990412605548, 0.990427287837, 0.990488988094, - 0.99062322091, 0.990637873057, 0.990783650663, 0.99080168294, 0.990822418393, - 0.990869793135, 0.991049950613, 0.991105067801, 0.991109415833, 0.991144130522, - 0.991182618547, 0.991221896221, 0.991348588885, 0.991390279742, 0.991508569063, - 0.991561035644, 0.991706459406, 0.991709328176, 0.991771803291, 0.992203832104, - 0.992607250874, 0.992961331312, 0.993424404998, 0.993474148563, 0.993704249848, - 0.994181954878, 0.994342287962, 0.994860595811, 0.994943125569, 0.99513621193, - 0.995791648606, 0.995861005306, 0.996071614139, 0.996576493061, 0.996769080865, - 0.99717703025, 0.997283342352, 0.997320725972, 0.997392435524, 0.997393456879, - 0.997724128794, 0.9983288294, 0.998396228241, 0.998558386961, 0.99871575569, - 0.998740910223, 0.998767733861, 0.998828447311, 0.998932961763, 0.999586369087, - 0.99979063868, 0.999822861843 + 1.27397054477, 1.27397054477, 1.27397054477, 1.22056106783, 1.15938219586, + 1.1160040995, 1.09031092233, 1.08156433802, 1.05625132693, 1.04972333604, + 1.04407369194, 1.03742876202, 1.03092173843, 1.02452207329, 1.0174828527, + 1.0081675749, 0.995620430116, 0.997797998703, 0.994732173644, 0.990755096265, + 0.985892068632, 0.981548089599, 0.976271265679, 0.973826119963, 0.968463015729, + 0.967588482776, 0.961575991775, 0.957590009436, 0.946036734844, 0.943173725323, + 0.939992812643, 0.933960176944 ), l1tPtBins = cms.vdouble( - -float('inf'), 13.7762473951, 15.5332882685, 17.7177050482, 20.5318058753, - 23.6984819534, 26.8528548618, 30.4115268065, 34.1183239417, 37.9102526851, - 41.9771903896, 46.1951438026, 50.2953206763, 54.3412175936, 58.0533034892, - 62.7880145798, 67.2857005426, 70.9603292709, 75.2703501199, 79.2421638597, - 83.2352443262, 87.3871418906, 91.8937910264, 96.3492341157, 100.560911672, - 105.4724697, 108.604664727, 111.984110281, 117.481026109, 122.163470824, - 126.712766881, 129.573592546, 133.695085969, 139.343050191, 143.551904358, - 146.4193363, 151.494950739, 156.0875, 157.469584309, 163.079886507, - 168.458828671, 170.752185315, 175.501873127, 181.910517332, 187.192429336, - 190.563608433, 192.12056492, 195.873276157, 200.366441748, 205.180843606, - 211.088590075, 215.367527804, 221.164675131, 226.561278527, 228.251490056, - 231.662853692, 234.986329234, 238.546150662, 245.830387931, 249.922471264, - 250.526618005, 253.747462754, 262.89600735, 269.527027681, 271.729546239, - 277.379347826, 281.6725, 286.29855042, 291.022068119, 292.139949738, - 294.103932039, 300.664906542, 307.449137311, 309.163838612, 310.2902264, - 312.401053339, 314.643455616, 319.429270833, 324.284671053, 328.897757787, - 333.821566464, 339.527806653, 343.803875892, 345.688090636, 359.947291667, - 384.037727273, 405.880493053, 429.443430116, 444.230702504, 452.300130761, - 472.709983897, 491.10804551, 510.676904206, 528.002275641, 535.9497669, - 560.417237991, 581.316919192, 589.389827419, 610.021177686, 630.132884972, - 647.449593726, 662.278511184, 666.422029703, 669.567771084, 671.664993307, - 681.229489664, 708.201297293, 727.581529851, 734.200905797, 743.414596273, - 748.677721088, 750.176530612, 752.700694444, 757.465101224, 779.320051941, - 804.051478495, 810.870833333, float('inf') + -float('inf'), 16.880217392, 23.9022653333, 32.2717617865, 41.5428951519, + 51.1274314482, 60.6194200011, 70.1354681051, 79.7123453897, 89.5991512838, + 99.1387572012, 108.769969768, 119.072828547, 129.183554009, 139.711187156, + 152.522826668, 169.649214185, 190.606597094, 218.71218636, 257.712877156, + 306.665735047, 357.65034307, 410.926384374, 453.687469423, 496.926339286, + 531.46780303, 569.60530303, 624.972727273, 711.022727273, 790.854166667, + 824.322916667, 875.34375, float('inf') ) ), cms.PSet( etaMax = cms.double(1.479), - etaMin = cms.double(1.305), - l1tCalibrationFactors = cms.vdouble( - 1.49402222179, 1.49402222179, 1.49402222179, 1.49402222179, 1.49402222179, - 1.49402222179, 1.49402222179, 1.49402222179, 1.47291221879, 1.44067526904, - 1.411205428, 1.3790606936, 1.35626109444, 1.32763245033, 1.30702937763, - 1.29039880276, 1.2769964355, 1.26383930097, 1.25651331227, 1.24922145017, - 1.24848514467, 1.25017146805, 1.26970714471, 1.26829421131, 1.2655539554, - 1.26351627994, 1.26218918978, 1.26008701808, 1.25872051661, 1.25553057705, - 1.25531916062, 1.25231191618, 1.25098985677, 1.25092649727, 1.24631095309, - 1.24491550742, 1.24463699336, 1.24089920022, 1.23818713652, 1.23797504425, - 1.23762209646, 1.2357981512, 1.22994667174, 1.22918782752, 1.2288766297, - 1.22661112186, 1.22335120944, 1.2222374654, 1.21863915082, 1.21627578407, - 1.21531079011, 1.21316997355, 1.21159701937, 1.20973271047, 1.20822352112, - 1.20808119953, 1.20712941377, 1.21601638464, 1.21449875865, 1.2128657327, - 1.2125648381, 1.2109969654, 1.21095095908, 1.20763240272, 1.20752194607, - 1.20715412726, 1.20339192426, 1.20316452215, 1.19908630242, 1.19856391893, - 1.19711998156, 1.19710976017, 1.19697659596, 1.19693795887, 1.19237829632, - 1.19185381308, 1.19110119575, 1.19056500802, 1.18847825696, 1.1856511587, - 1.18562060063, 1.17851535013, 1.17823027895, 1.17742187998, 1.17067824059, - 1.16493911336, 1.16357145785, 1.1500930073, 1.14923508822, 1.13766740107, - 1.13594359689, 1.12975025424, 1.12340048965, 1.11872349781, 1.11766570258, - 1.1029557049, 1.09804762317, 1.09571573203, 1.08638808459, 1.08507723903, - 1.08354390779, 1.08218176765, 1.07784354968, 1.07131903088, 1.05973674136, - 1.05896743969, 1.0508941418, 1.04895873762, 1.04534850219, 1.03661916912, - 1.0363330056, 1.03616346044, 1.03608676144, 1.03173422477, 1.02442109082, - 1.01944146354, 1.01859650582 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 12.6732940885, 14.0822469238, 16.0351992264, 18.533035159, - 21.4040329809, 24.2413122912, 27.0941591248, 30.3228808559, 33.4579112263, - 36.5410985835, 39.9175328544, 43.2085508359, 46.7155207753, 50.4991283112, - 53.856301359, 57.0602265701, 60.6020503279, 64.0753510179, 68.3166558302, - 72.2444890811, 75.2333861985, 78.6940353936, 81.7003273087, 85.6517013971, - 90.1974595599, 93.3987216924, 96.661346018, 99.961466543, 104.296497204, - 107.53257168, 110.594828706, 114.713759425, 116.03185691, 120.483399419, - 126.202298261, 127.794915554, 131.616059028, 137.752499071, 140.534562021, - 141.072145181, 143.143256833, 150.445710948, 156.734820295, 157.752865961, - 160.204362204, 165.461286653, 169.622414766, 174.105501125, 179.777487488, - 182.944113735, 185.899004129, 189.432312233, 192.70254897, 195.912119398, - 197.483378752, 198.524320323, 202.308928058, 207.324072464, 211.758643892, - 214.480654762, 217.110961838, 219.382511317, 224.118164062, 228.94453125, - 229.617708333, 235.430751812, 241.046157513, 247.106359649, 253.581750769, - 256.34936537, 258.396107129, 258.597923681, 258.839735591, 265.311884405, - 272.467866122, 274.265396862, 276.079401776, 279.771212121, 286.6875, - 290.709677419, 300.753393266, 311.155338654, 312.694407895, 323.323970985, - 340.893579208, 350.896440929, 371.792471042, 391.971042471, 409.460196929, - 428.168092588, 439.311549189, 456.966087393, 472.486347955, 480.558113227, - 502.751426025, 530.364052288, 540.554380342, 556.965287579, 571.939063803, - 575.942268669, 580.017671131, 588.040977328, 603.330378727, 628.815877093, - 646.200854701, 658.646894491, 672.734234234, 680.539772727, 697.907828283, - 710.597222222, 711.238636364, 711.585227273, 717.819416996, 734.238955119, - 751.541129032, 759.739285714, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(1.653), - etaMin = cms.double(1.479), + etaMin = cms.double(1.131), l1tCalibrationFactors = cms.vdouble( - 1.42596303316, 1.42596303316, 1.42596303316, 1.42596303316, 1.42596303316, - 1.42596303316, 1.42596303316, 1.42596303316, 1.4177466629, 1.3995618494, - 1.38276766283, 1.36931683062, 1.35471035569, 1.34046255312, 1.32941184468, - 1.3200455296, 1.30948382237, 1.30681144426, 1.29825728374, 1.29404806931, - 1.29165391765, 1.29030779607, 1.29083243576, 1.27396085005, 1.2718551659, - 1.26738255058, 1.26670434297, 1.26318102804, 1.26166765764, 1.25786412703, - 1.25518057962, 1.2530501746, 1.25083737691, 1.24869400501, 1.24550511467, - 1.24178608904, 1.24042240626, 1.23648242831, 1.23493825442, 1.2342084223, - 1.23053562244, 1.22893151286, 1.22377063054, 1.22034488227, 1.2189599762, - 1.21777849227, 1.21430917685, 1.21153741107, 1.20889147869, 1.20688285726, - 1.20338743284, 1.20096161619, 1.19672737216, 1.19202941837, 1.19004800954, - 1.18746316629, 1.18655348217, 1.18312435414, 1.2078909264, 1.20650658231, - 1.20582228539, 1.20537671722, 1.2049862715, 1.20476513856, 1.20105971422, - 1.19989656052, 1.19785505378, 1.19710626467, 1.19676963305, 1.19462529476, - 1.19282384753, 1.19154278626, 1.1900948274, 1.18954891892, 1.18914968595, - 1.18716610868, 1.18495727793, 1.18196604297, 1.18192678954, 1.17969476053, - 1.17965050907, 1.17895360889, 1.17527559787, 1.1706607414, 1.16483173896, - 1.15823552842, 1.14819433249, 1.14213524047, 1.13251935285, 1.12815142061, - 1.12191024514, 1.11085417981, 1.10484148389, 1.09826582928, 1.0895403454, - 1.0769799347, 1.07350817324, 1.06670957019, 1.06226444487, 1.05723223376, - 1.0482595789, 1.04499468512, 1.03683454016, 1.025456056, 1.02167918917, - 1.01487166026, 1.01290550623, 1.01098880941, 0.986266161192, 0.982622683842, - 0.982314921628, 0.97851685144, 0.969837554507, 0.968857319337, 0.963060466121, - 0.961712306729, 0.936251542713 + 1.34802320734, 1.34802320734, 1.34802320734, 1.30212233785, 1.24209460275, + 1.19015306181, 1.15264110831, 1.12372171912, 1.10729927389, 1.10106230836, + 1.09548001551, 1.08898845858, 1.08276378762, 1.07376271165, 1.07053777522, + 1.06006587987, 1.04671444238, 1.03585271305, 1.04610056164, 1.03768418, + 1.03119548102, 1.02676678101, 1.01915019189, 1.01242076126, 1.00893312811, + 1.00508141223, 1.00136013543, 0.995951447598, 0.984231225019, 0.980800927737, + 0.973451186577, 0.926524468915 ), l1tPtBins = cms.vdouble( - -float('inf'), 12.685246952, 14.2020094702, 16.2454279268, 18.4570790339, - 21.1373272484, 24.0711882608, 27.0820591121, 30.0028435266, 32.9840363303, - 36.1993781266, 39.2042073033, 42.2602760673, 45.7316358924, 49.1357169678, - 52.2647120658, 55.8647436347, 58.5356962906, 61.5291305064, 65.6115998363, - 68.7852077001, 72.1760839599, 75.8652500891, 79.0593559025, 81.8557422467, - 86.158418801, 89.527423993, 92.275519088, 95.5698701527, 99.0475022401, - 103.290513469, 106.439181353, 109.279945377, 112.129190662, 115.616870088, - 120.135139319, 123.45959276, 126.928564758, 130.515590803, 132.002952756, - 134.882587759, 138.33406251, 142.758849213, 148.375117414, 151.521628111, - 153.200230026, 156.242184166, 160.324295949, 163.867856555, 166.912266376, - 170.512304528, 174.385218076, 178.741372283, 184.583666075, 188.952445129, - 191.939099333, 194.224769217, 197.062661499, 202.978632479, 208.439765991, - 211.111679147, 212.571043719, 213.650862069, 214.440793754, 219.512442241, - 225.800830439, 229.940057283, 233.544079516, 234.946038538, 238.150526944, - 243.247011145, 247.228463203, 250.753340051, 253.328673501, 254.549443975, - 257.627146678, 263.04217524, 269.75872195, 273.67298341, 276.606633772, - 279.546739719, 280.504031385, 286.154786036, 296.866079896, 310.35565294, - 326.40439696, 347.893724986, 368.689296081, 388.935527359, 406.997410523, - 420.700423425, 443.042011475, 465.088489103, 481.347946019, 501.111313869, - 528.604755931, 549.312346814, 562.577829768, 577.100536021, 589.341722273, - 607.430789179, 623.237140805, 637.994032486, 663.23065883, 682.805723566, - 696.47681781, 707.809146027, 712.824342105, 747.232446809, 783.870908347, - 788.974437148, 794.277642276, 810.39375, 822.870265152, 831.623737374, - 840.852430556, 875.479567308, float('inf') + -float('inf'), 16.9252841647, 23.7590878196, 31.7131252613, 40.1274040838, + 49.1249022327, 58.1527487225, 67.4760337457, 77.3005352247, 86.9408929333, + 95.9552442624, 105.163768208, 114.862223233, 126.474646588, 135.799222426, + 146.245567688, 164.415226489, 182.882205173, 207.962905257, 252.719711752, + 302.236065785, 338.504892994, 378.520698052, 426.179788961, 460.12202381, + 484.504166667, 509.6625, 539.993269231, 596.897435897, 647.229166667, + 683.041666667, 863.354166667, float('inf') ) ), cms.PSet( etaMax = cms.double(1.83), - etaMin = cms.double(1.653), - l1tCalibrationFactors = cms.vdouble( - 1.28436707004, 1.28436707004, 1.28436707004, 1.28436707004, 1.28436707004, - 1.28436707004, 1.28436707004, 1.27860218313, 1.26114748386, 1.24471548932, - 1.23270424679, 1.2176463909, 1.20808675984, 1.19869392953, 1.1936775499, - 1.18744907855, 1.18433575975, 1.18260381979, 1.18295019864, 1.18491560081, - 1.18809316262, 1.18172024138, 1.18097131001, 1.17918745502, 1.17764940709, - 1.17688881581, 1.17504482963, 1.17248725691, 1.17129302591, 1.17004602745, - 1.1693666084, 1.16756409321, 1.16526063859, 1.16417855306, 1.16338089054, - 1.16187070953, 1.16019586336, 1.15840088317, 1.15626975454, 1.15472336309, - 1.15277251156, 1.15246623852, 1.15140593602, 1.1487970247, 1.14747602274, - 1.14638703449, 1.14512379243, 1.14247008702, 1.14113527821, 1.14044553287, - 1.1383875885, 1.1362425234, 1.13472903282, 1.13376714195, 1.13369814816, - 1.13350729029, 1.16282574417, 1.15866607792, 1.1571074204, 1.15511734699, - 1.15296938865, 1.14945591442, 1.14546738724, 1.14533339505, 1.14012295605, - 1.13927325429, 1.13750627088, 1.13378322433, 1.13171236291, 1.1286109126, - 1.12546123624, 1.12353248187, 1.12272791593, 1.12206079073, 1.11242790976, - 1.11158955611, 1.10975128919, 1.10808940983, 1.10614764171, 1.10457082693, - 1.10456528268, 1.0898943432, 1.08474469459, 1.08098903788, 1.07264937986, - 1.05568600919, 1.04193743035, 1.02564328415, 1.02145534312, 0.999803345141, - 0.98600256732, 0.975181807318, 0.953065655597, 0.948568657631, 0.92718714575, - 0.917282051972, 0.912089302025, 0.91014768072, 0.881521878237, 0.859430480658, - 0.847000750016, 0.835921402493, 0.828394647755, 0.805581771714, 0.80323037479, - 0.777498864082, 0.772467852877, 0.763114519703, 0.753840438847, 0.744731491356, - 0.737491553318, 0.717291473065, 0.715629958029, 0.701675695843, 0.695798790437, - 0.681716394464, 0.677915256402 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 13.7634866136, 15.6328013015, 17.7753080392, 20.3849274482, - 23.5230630809, 26.6159799854, 29.5849918302, 32.8058836317, 36.3551255626, - 39.6586540788, 43.2891715395, 47.0457162843, 50.5748804671, 53.7537486235, - 57.0903993284, 60.7800647992, 64.3406024724, 68.0650146493, 71.4916076649, - 74.644158805, 78.7362044271, 82.2255472682, 85.2770231354, 89.2792188034, - 92.0485965047, 95.1865655713, 100.489520051, 105.009655946, 107.950824978, - 110.271753676, 113.261963412, 118.208795089, 122.287660256, 124.55236204, - 127.332829028, 131.170118167, 135.350530522, 140.080667464, 144.511307162, - 148.724750804, 151.444112084, 153.090548725, 157.511181119, 162.245901639, - 165.149433932, 167.98337766, 172.702477093, 177.507799446, 179.946962191, - 183.257351475, 188.321095571, 192.72888715, 195.711202161, 196.953201763, - 197.266268454, 202.700189394, 210.834895833, 214.863790761, 217.364080113, - 220.279566498, 224.268378227, 229.553978798, 232.458535806, 236.224001452, - 240.493726516, 242.337334893, 246.205383427, 250.287531857, 253.93172923, - 258.336015088, 261.914067782, 263.839852462, 264.876745306, 272.133704557, - 279.511304302, 281.397140688, 283.863199301, 286.40218059, 288.881228885, - 289.99609375, 300.336538462, 314.301306801, 320.575617396, 329.097476964, - 346.924946684, 368.563318777, 389.730182927, 404.16101626, 422.366770833, - 447.345333473, 464.692652854, 487.898641496, 506.649168399, 524.882098391, - 546.92534949, 557.562667068, 562.589250605, 584.12579584, 619.859041826, - 644.181204029, 660.744730248, 673.853821998, 695.22987368, 712.959581843, - 732.745639535, 754.419642857, 764.554258242, 777.678365385, 790.630288462, - 802.149038462, 821.482142857, 836.884920635, 847.887152778, 861.859375, - 875.921875, 888.521875, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(1.93), - etaMin = cms.double(1.83), - l1tCalibrationFactors = cms.vdouble( - 1.2075501775, 1.2075501775, 1.2075501775, 1.2075501775, 1.2075501775, - 1.2075501775, 1.2075501775, 1.20133355605, 1.19530708945, 1.1903774073, - 1.18470031348, 1.17981636403, 1.17466612498, 1.17013138415, 1.16570649395, - 1.16262296754, 1.15961379695, 1.1567798582, 1.15461512052, 1.15166019705, - 1.15059363693, 1.14781934175, 1.1468890285, 1.14439368656, 1.1401875604, - 1.13984882528, 1.13572729329, 1.13486154989, 1.13303702319, 1.12825443539, - 1.12724956215, 1.12465904179, 1.12162552813, 1.12147167362, 1.12055227448, - 1.11576929423, 1.11397531519, 1.11305961492, 1.10776036523, 1.10688504821, - 1.1049969562, 1.10395365658, 1.1004820424, 1.10020941695, 1.09364390424, - 1.09317323804, 1.09263618254, 1.08730605402, 1.08462991715, 1.08438007388, - 1.08214472159, 1.08209582567, 1.07713798478, 1.06280435801, 1.06125183068, - 1.06112183264, 1.06039791195, 1.06008868406, 1.05691560019, 1.0565842396, - 1.05634385411, 1.05575454385, 1.0537213763, 1.05344424321, 1.05312642297, - 1.05270479117, 1.05177723394, 1.05040270302, 1.04838541277, 1.04816948872, - 1.04767671633, 1.04649582963, 1.04631815897, 1.04547121251, 1.04486369542, - 1.04344015331, 1.04328394209, 1.04310709983, 1.04295802389, 1.03991666934, - 1.03829941334, 1.03817848315, 1.0372602046, 1.03498791406, 1.02967074065, - 1.02645904098, 1.02456252935, 1.02028571289, 1.01532132205, 1.00708648081, - 1.00557866056, 1.00227921875, 0.998369858075, 0.990255818748, 0.989183194449, - 0.98548744733, 0.978667289452, 0.977142200594, 0.967587781957, 0.966301554612, - 0.96164692143, 0.961353555121, 0.959804877641, 0.958874784431, 0.956874521799, - 0.948352201413, 0.947703706372, 0.947132960055, 0.945451349391, 0.944535445859, - 0.94373366214, 0.934967051729, 0.93335906675, 0.927113925719, 0.924216523587, - 0.919275945565 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 14.1553016676, 16.2664390716, 18.850560812, 21.4525843899, - 24.2848068147, 27.54630177, 31.3476954248, 35.0449062766, 38.2354125974, - 41.5290770126, 45.0155066897, 48.5944191332, 52.3320360328, 56.1346401629, - 59.6217196328, 62.7708486989, 66.1328716295, 69.3619089373, 73.3173162311, - 76.8510115304, 81.249183365, 85.3190875777, 88.0806578066, 93.4830038621, - 97.1468149946, 100.742431072, 104.762891529, 106.931635726, 112.25791923, - 116.923444288, 119.821848062, 124.355627455, 126.925104108, 127.79030074, - 132.387237762, 137.68921183, 139.873602642, 144.883745186, 149.86133302, - 152.089037698, 154.452160494, 158.091829657, 161.110224719, 166.622746479, - 172.294917532, 173.107285995, 177.837079228, 184.291279354, 186.650039706, - 188.653464364, 190.494896589, 194.531045752, 199.945492662, 205.024103774, - 208.991538462, 211.005099068, 213.441287879, 221.652661483, 229.916224533, - 231.264415323, 233.220857558, 239.404722354, 244.852465986, 246.255380037, - 247.999025468, 251.180445151, 256.608823529, 264.606818182, 269.872790404, - 271.543913399, 275.490441176, 278.693951613, 281.110023041, 284.53968254, - 289.328968254, 293.054064039, 293.839412025, 294.607934858, 302.131045519, - 313.116159539, 317.21484375, 319.665322581, 327.188760081, 345.084895833, - 365.196180556, 377.241463795, 391.79831766, 413.58930336, 444.713405239, - 467.686831812, 479.022469636, 496.020996641, 524.372458629, 546.03482906, - 557.278761808, 582.075514874, 601.753804348, 627.879545455, 653.442045455, - 667.450735294, 679.118235294, 683.461818182, 689.306818182, 696.216666667, - 721.029166667, 742.654166667, 745.529166667, 750.840277778, 756.965277778, - 761.015625, 783.578125, 808.041666667, 826.55952381, 848.117857143, - 866.6, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(2.043), - etaMin = cms.double(1.93), + etaMin = cms.double(1.479), l1tCalibrationFactors = cms.vdouble( - 1.2042309243, 1.2042309243, 1.2042309243, 1.2042309243, 1.2042309243, - 1.2042309243, 1.2036640024, 1.19524481612, 1.18325954566, 1.17368692683, - 1.16506130726, 1.15388106163, 1.14598632447, 1.13983893861, 1.13173200239, - 1.12546585042, 1.11919443175, 1.11241946353, 1.10679191353, 1.10277852463, - 1.11490627601, 1.11335120331, 1.11096141728, 1.1100935654, 1.10764450009, - 1.10624839945, 1.10429555791, 1.10156835063, 1.09955747398, 1.09789752189, - 1.09641249383, 1.09381679019, 1.09212245543, 1.09111912485, 1.08977982989, - 1.08630997483, 1.08401046173, 1.08083468198, 1.08080770014, 1.07993240947, - 1.07653702393, 1.07631811434, 1.07301303878, 1.07283358668, 1.07001112188, - 1.06715409534, 1.0655999551, 1.06480464407, 1.06127745288, 1.06095399959, - 1.0595969905, 0.984257510274, 0.984200634859, 0.98372269169, 0.98276381661, - 0.98266206775, 0.982472890781, 0.98197300242, 0.981690492126, 0.981228789794, - 0.980704442874, 0.980684026587, 0.979800102722, 0.979593434658, 0.979151401752, - 0.978667991619, 0.978456340039, 0.97838130467, 0.977422760752, 0.977354967521, - 0.977290768842, 0.977152281231, 0.976393403414, 0.976162511198, 0.975933603237, - 0.975769076539, 0.975703772172, 0.975379887997, 0.974640979874, 0.974534324589, - 0.973636260808, 0.972439925244, 0.972186024592, 0.97169810365, 0.969210446816, - 0.967673923531, 0.964817552461, 0.963418429289, 0.961590054487, 0.960059426291, - 0.957463919289, 0.957075193291, 0.95355179413, 0.952130925316, 0.949695436177, - 0.948922486673, 0.94612010092, 0.945132832372, 0.943722360083, 0.942093889524, - 0.940692364001, 0.939819564434, 0.936657595081, 0.935648076104, 0.933290760148, - 0.932922673767, 0.932487858551, 0.929229710674, 0.928871233299, 0.927770557843, - 0.924947493401, 0.924880802499, 0.924463019827, 0.921416182608, 0.918224719831, - 0.917399847078 + 1.64615015562, 1.64615015562, 1.64615015562, 1.64615015562, 1.62354748453, + 1.58955281827, 1.5596420256, 1.52857227236, 1.4981491184, 1.47483671945, + 1.44848305769, 1.42279372844, 1.41374089612, 1.4008972173, 1.39160024497, + 1.37606952993, 1.3577735774, 1.32702431242, 1.28941444869, 1.28016614572, + 1.24765615972, 1.22053713127, 1.17427545004, 1.15813500374, 1.14591122897, + 1.10386182373, 1.08986646446, 1.08400487869, 1.05705595373, 0.986136154545, + 0.970000328559, 0.926367737882, 0.92097540828 ), l1tPtBins = cms.vdouble( - -float('inf'), 14.774327423, 16.7467039494, 19.3220519597, 21.9668153648, - 24.8434771127, 28.3182127012, 31.5913687934, 35.0924952038, 38.9535281293, - 42.3917608897, 46.3696188172, 50.4144256002, 53.5857932878, 57.0301456325, - 60.7164859952, 64.1946035834, 68.1349803463, 72.2419874509, 75.7665473847, - 79.6012507013, 83.4598320886, 87.4613764276, 90.7658249374, 94.1304045289, - 98.0308235506, 101.427888328, 106.175187062, 110.981354838, 114.704931512, - 117.895103426, 122.034473158, 126.386157219, 129.122586641, 131.498874511, - 136.377129554, 142.229400591, 147.783370605, 151.032154249, 151.947391963, - 156.279435613, 159.945666315, 163.520289331, 167.054887874, 170.099940784, - 175.861043525, 180.335596527, 182.718808205, 187.103422578, 191.009398855, - 192.714008621, 197.379894037, 200.976387994, 203.864313553, 211.622877431, - 217.350058724, 218.921006636, 222.641837284, 226.866651348, 230.885267621, - 236.209758809, 239.151383574, 244.034660107, 249.923663227, 253.426533491, - 258.423761872, 262.176971925, 263.725030637, 269.306175595, 274.848214286, - 275.560947205, 276.655417251, 281.501031508, 286.845614257, 289.328453717, - 291.452931141, 292.693978162, 294.795527307, 300.534417344, 305.100309876, - 310.525614754, 321.835, 329.666018519, 333.671723647, 349.739316239, - 371.469175627, 395.190026541, 418.168941192, 435.596858199, 453.734879032, - 476.015277778, 492.129607046, 513.254389509, 539.952560241, 560.776209677, - 578.101209677, 597.407386364, 617.870847902, 630.818223443, 647.22797619, - 663.589417989, 675.87037037, 697.657407407, 720.182705026, 738.363016917, - 753.079706478, 757.415232794, 777.356578947, 796.885714286, 804.764880952, - 825.952380952, 841.556547619, 844.172619048, 862.880952381, 896.566666667, - 918.254166667, float('inf') + -float('inf'), 14.2534283688, 19.3658902191, 24.8886644469, 31.0322354574, + 37.7896859331, 44.4976332373, 51.4162446385, 59.0148938612, 66.284690538, + 73.8402824355, 82.7989717528, 90.9876146413, 99.3412409944, 107.78800796, + 117.259892418, 130.164931944, 148.875922888, 174.955265646, 212.930051719, + 261.237428866, 306.506597467, 362.21578114, 409.590242347, 431.123798077, + 472.326923077, 514.875, 529.95, 554.859090909, 629.159090909, + 695.25, 740.625, 777.84375, float('inf') ) ), cms.PSet( etaMax = cms.double(2.172), - etaMin = cms.double(2.043), - l1tCalibrationFactors = cms.vdouble( - 1.2157935489, 1.2157935489, 1.2157935489, 1.2157935489, 1.2157935489, - 1.2157935489, 1.2131670386, 1.19252693905, 1.16613128795, 1.14891680382, - 1.13585884458, 1.11956017752, 1.10976982201, 1.10285725152, 1.09763906728, - 1.09602675736, 1.09773310507, 1.10102752345, 1.10591456862, 1.12056604454, - 1.09024831793, 1.0866258585, 1.08397193938, 1.08121891991, 1.07860560959, - 1.07354275531, 1.06972453158, 1.06917647609, 1.06336781577, 1.06252684817, - 1.05814049533, 1.05375938581, 1.04843010939, 1.04614697071, 1.04491970624, - 1.0411245951, 1.03745844809, 1.03489726734, 1.03360755376, 1.02882103269, - 1.02188125281, 1.02178616775, 1.01439480032, 1.01409606035, 1.01341880324, - 1.00827791468, 1.00542136086, 0.998511182345, 0.994448442251, 1.04477728911, - 1.04421248637, 1.04392479755, 1.04274630788, 1.04272994051, 1.04168658376, - 1.04135777469, 1.03965139823, 1.03957385755, 1.03896194302, 1.03828897643, - 1.03719007928, 1.03617088577, 1.03571879048, 1.03499873182, 1.0346382378, - 1.03177687804, 1.03176555727, 1.03159294818, 1.03108256137, 1.03015878893, - 1.02995488679, 1.02899017097, 1.02649853162, 1.02628818447, 1.02560062889, - 1.02505812439, 1.02504298404, 1.02401015146, 1.0238655626, 1.0238353063, - 1.02376716185, 1.02349302901, 1.01992907169, 1.01735550261, 1.01183126604, - 1.00598039495, 1.00503085618, 1.00325705789, 0.997956898494, 0.994701643546, - 0.994616268066, 0.988149085989, 0.986924650126, 0.984155654984, 0.978759764732, - 0.97776008685, 0.972914253171, 0.9716143493, 0.961266323588, 0.959651973391, - 0.957930376835, 0.957798054327, 0.953759936411, 0.952946229034, 0.949084679396, - 0.947113174765, 0.943899628142, 0.939131455009, 0.934865194838, 0.930798559139, - 0.928294697889, 0.902970907566, 0.902468994604 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 14.5720423979, 16.5824805021, 19.0934145429, 22.0784007761, - 25.1490151046, 28.497403927, 31.9362849912, 35.7593269258, 39.7393275631, - 42.9558645787, 46.7338248946, 50.7967533731, 54.2877761449, 58.0901293351, - 62.2284810254, 66.2495543993, 69.6790156787, 72.5465787405, 76.7862415377, - 81.6681494869, 85.8291480655, 89.4707953394, 92.6079807459, 95.7216043282, - 100.175428087, 105.328360356, 107.861739865, 111.55, 115.408212058, - 118.441180371, 123.528191168, 129.162300109, 133.579135466, 135.615923077, - 138.529979381, 142.85911125, 146.472298535, 148.706644144, 152.232164977, - 159.0359375, 163.117669753, 167.461419753, 171.923333333, 172.489621212, - 175.865395022, 180.505628882, 186.17243083, 192.539079823, 197.591920732, - 201.834787736, 204.170204403, 208.186827957, 211.46016129, 214.363295455, - 218.122369529, 223.697798564, 228.584873138, 230.473648649, 233.993604651, - 238.847658705, 244.6502079, 248.680831266, 251.891969086, 254.852163462, - 263.678492485, 271.548254836, 272.052134146, 273.923214286, 277.852120536, - 280.94140625, 284.142857143, 293.611607143, 301.01375, 303.473571429, - 306.843344156, 308.371022727, 311.241964286, 314.467532468, 314.946524064, - 315.216094771, 316.153769841, 326.668290043, 343.482159091, 365.66625, - 396.828571429, 415.458422175, 422.919055292, 442.298295455, 465.736013986, - 474.887733888, 492.838588589, 513.909920635, 524.85, 547.217857143, - 564.738636364, 580.752525253, 597.588888889, 629.498611111, 662.269764957, - 671.408653846, 676.4875, 687.9125, 701.204166667, 714.012121212, - 729.991883117, 744.196428571, 766.0625, 790.8125, 813.640625, - 831.640625, 907.875, 978.625, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(2.322), - etaMin = cms.double(2.172), + etaMin = cms.double(1.83), l1tCalibrationFactors = cms.vdouble( - 1.27175839461, 1.27175839461, 1.27175839461, 1.27175839461, 1.27175839461, - 1.27175839461, 1.27175839461, 1.25215773409, 1.22958887764, 1.20467102121, - 1.18331005838, 1.16118964804, 1.14659600623, 1.13536255747, 1.12227110191, - 1.11136706147, 1.10575962446, 1.10196633526, 1.10080589724, 1.10257943107, - 1.0895166152, 1.08712811776, 1.08506891006, 1.08334188412, 1.07944257634, - 1.07931511022, 1.07630099342, 1.07361351611, 1.07140563288, 1.06922569703, - 1.06658310837, 1.06465192235, 1.06420654338, 1.06188411668, 1.05901973065, - 1.05528665699, 1.05300137798, 1.051994328, 1.05135284213, 1.04907816509, - 1.04583953913, 1.04219906506, 1.04019715537, 1.03946927527, 1.03680516372, - 1.03482472473, 1.03422230477, 1.0290706971, 1.02587253395, 1.04189050346, - 1.04062098834, 1.03935940395, 1.03844770162, 1.03554348618, 1.03344374769, - 1.03259309389, 1.03096624127, 1.03091664154, 1.0307058552, 1.02970686067, - 1.02797665766, 1.02297895874, 1.0225585419, 1.02255209792, 1.02200274202, - 1.01925034359, 1.01836955561, 1.01481130761, 1.01304746603, 1.0125551422, - 1.01159949029, 1.0101101956, 1.009911649, 1.00887160684, 1.00769969245, - 1.00576601578, 1.00232319829, 1.00190642009, 1.00161081362, 1.00153977401, - 0.999733338201, 0.991799358109, 0.990838727914, 0.988553070499, 0.979019416267, - 0.972596120228, 0.965820586276, 0.961922937946, 0.95947715169, 0.938855080551, - 0.935398002383, 0.930922826071, 0.917969221694, 0.913373875384, 0.905540501267, - 0.903909529794, 0.891888232267, 0.890539229272, 0.886803191571, 0.874256627624, - 0.868131613929, 0.865423598775, 0.854669607728, 0.85255321933, 0.849689435029, - 0.842563274095, 0.832262530564, 0.825380568291, 0.819209002123, 0.812060641311, - 0.807167788133, 0.799199511816, 0.777177232542, 0.768504480086 + 1.46868261989, 1.46868261989, 1.46868261989, 1.46868261989, 1.43911078656, + 1.40910755658, 1.38320919564, 1.35606709317, 1.32433798702, 1.30822665905, + 1.27541632146, 1.2610425712, 1.25048382907, 1.23727857048, 1.22557226003, + 1.20350464618, 1.17346110455, 1.15438568707, 1.17264007703, 1.14234287567, + 1.09578935279, 1.05521480704, 1.05300376705, 0.948841272141, 0.90157065563, + 0.900460510028, 0.886102626899, 0.870622263217, 0.794268915654 ), l1tPtBins = cms.vdouble( - -float('inf'), 13.8611374939, 16.0113120701, 18.5774916373, 21.1920554612, - 24.1752187507, 27.0444032168, 30.4197485207, 34.1362264284, 37.630227696, - 41.3788405138, 45.3845868193, 49.2170575261, 52.3470983693, 55.8753769944, - 60.2185652965, 64.1891998797, 67.746979597, 71.9226859348, 76.0177144871, - 79.2426623888, 82.8780435994, 86.9768023638, 90.4659856164, 95.6509032122, - 99.3617550597, 102.256863911, 107.511137313, 112.022430505, 116.066001586, - 120.510173128, 124.725110598, 126.915221292, 129.465877728, 134.245757114, - 140.325610632, 145.871791188, 148.905819269, 150.425018615, 153.112392871, - 158.193147611, 164.532545265, 169.732253692, 172.247876799, 175.373748474, - 179.653909058, 182.034128838, 187.336722065, 195.031408476, 200.278290307, - 204.364974552, 207.927915687, 210.987176147, 216.358711473, 223.402604167, - 227.555769231, 231.043269231, 233.403153153, 233.769689611, 235.47265625, - 239.314453125, 248.785087719, 256.411981659, 257.012858852, 257.795239106, - 262.443004352, 267.557315064, 273.805992313, 281.29771353, 284.473639456, - 286.511904762, 289.953571429, 292.329487179, 294.073005698, 297.186700337, - 301.558333333, 309.126638002, 314.559657218, 315.562456446, 316.078571429, - 318.721428571, 332.432674772, 344.953309693, 349.522996357, 366.160632113, - 388.622678491, 407.202214452, 422.226483586, 431.155916807, 463.627740925, - 497.523125651, 508.689085624, 533.222976718, 557.926026958, 575.421506352, - 588.744137931, 607.961964286, 626.782873377, 633.940909091, 656.861363636, - 683.14469697, 695.578645833, 714.528645833, 732.645833333, 739.65625, - 753.71875, 778.25, 802.4375, 820.8125, 839.5625, - 856.5125, 874.616666667, 916.833333333, 960.041666667, float('inf') + -float('inf'), 15.0001433736, 20.3973850042, 26.6770760436, 33.5779131491, + 40.9929083245, 48.3312410359, 55.7380156093, 64.5733527179, 72.1987214889, + 78.6859384392, 87.4179205144, 95.9828439006, 104.146361706, 112.70409741, + 124.306269775, 142.207731347, 159.081299984, 186.111094647, 227.056412071, + 278.975766649, 337.838362069, 366.74375, 438.608333333, 540.914583333, + 573.6, 584.05, 604.208333333, 666.25, float('inf') ) ), cms.PSet( etaMax = cms.double(2.5), - etaMin = cms.double(2.322), - l1tCalibrationFactors = cms.vdouble( - 1.52098890483, 1.52098890483, 1.52098890483, 1.52098890483, 1.52098890483, - 1.52098890483, 1.52098890483, 1.52098890483, 1.51895546826, 1.46136782786, - 1.41340180478, 1.35573588879, 1.31548728533, 1.2660316752, 1.24305402297, - 1.20796926099, 1.18988784161, 1.17884713219, 1.17592060458, 1.17998100319, - 1.20630819302, 1.20702059628, 1.16461440063, 1.1627843218, 1.15462180385, - 1.14998530406, 1.14403998714, 1.14283512108, 1.13526703393, 1.13059271226, - 1.12854192667, 1.11889321097, 1.11775202034, 1.1054171342, 1.10277511289, - 1.09594837096, 1.0913309999, 1.08820170399, 1.07970532444, 1.07452255879, - 1.06815095029, 1.0610340945, 1.05826841645, 1.05159167139, 1.04828178929, - 1.04695109923, 1.040946783, 1.03753240119, 1.03143269275, 1.01975938867, - 1.01717478622, 1.01699522985, 1.01689154612, 1.01658655876, 1.01575891227, - 1.01298629449, 1.01236640909, 1.01165960029, 1.00992588245, 1.00974364973, - 1.0092096141, 1.0091517754, 1.00820583884, 1.00643626079, 1.00571818371, - 1.00528017329, 1.0050951432, 1.00493058446, 1.00347528251, 1.00215164281, - 1.00202838906, 0.999594624288, 0.998682402719, 0.99802438797, 0.997853420087, - 0.997793406637, 0.997477519847, 0.9948799271, 0.993917034924, 0.992918147191, - 0.992749818395, 0.99256051789, 0.992049160684, 0.990263478702, 0.984112026821, - 0.978946943439, 0.977244896076, 0.970657922256, 0.966699455759, 0.963014448433, - 0.957912516057, 0.956213356451, 0.947912641797, 0.944214889997, 0.939896603289, - 0.932799639357, 0.930035262422, 0.920920793695, 0.917125860352, 0.915876952158, - 0.915867590189, 0.915004674903, 0.901780409368, 0.896212297563, 0.891688206722, - 0.889600164796, 0.887412692301, 0.860715584811 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 12.3465412359, 13.9372836782, 15.8932447157, 17.9567741799, - 20.2201934345, 22.1859464929, 24.7687444772, 28.3358498854, 31.553573754, - 34.3379949843, 37.4578756454, 40.6769264758, 44.1823241936, 47.422092709, - 50.849889017, 54.8346440435, 58.3587018402, 61.9463616926, 65.3145012856, - 70.0209069248, 73.199696694, 77.0267305735, 81.5382115009, 85.589096942, - 90.7776736182, 95.0674221357, 97.9660252463, 101.522481012, 106.485414746, - 109.211696977, 113.95454215, 118.328647842, 123.791696575, 129.863165046, - 133.701694304, 138.34100796, 141.481418919, 146.194335938, 151.739706308, - 156.423718585, 161.891789075, 165.898056245, 169.725907519, 173.774372943, - 175.655608281, 178.629136668, 182.447370065, 186.304274383, 193.50925215, - 202.982657241, 208.175298886, 208.887454356, 209.914983165, 212.762784091, - 221.814990942, 230.344820487, 233.680550699, 239.816809117, 244.634116809, - 246.435042735, 247.923202614, 250.447012138, 257.274677579, 263.529431997, - 266.43620283, 268.002724359, 268.881701632, 272.954545455, 279.941686603, - 283.579635863, 290.008791832, 298.421663279, 302.369735663, 304.45406106, - 305.034821429, 305.979953917, 313.305366005, 322.257554945, 327.190092166, - 330.124844913, 331.024038462, 332.785714286, 338.561199723, 358.517672937, - 386.971033654, 404.237179487, 425.078409091, 451.592992424, 470.811111111, - 492.904265873, 510.004369301, 535.147226444, 565.315178571, 585.470043103, - 614.171605603, 638.966145833, 668.833333333, 701.291666667, 713.973484848, - 717.137175325, 719.330357143, 754.75, 802.0, 827.375, - 844.0, 854.75, 927.375, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(2.964), - etaMin = cms.double(2.5), - l1tCalibrationFactors = cms.vdouble( - 1.3918486761, 1.3918486761, 1.3918486761, 1.3918486761, 1.3918486761, - 1.3918486761, 1.3918486761, 1.3918486761, 1.36703547997, 1.31736470956, - 1.26434084266, 1.21404966543, 1.17272244317, 1.12964733287, 1.09922572696, - 1.07489413214, 1.04575625838, 1.03614621508, 1.0189580814, 0.986964784102, - 0.982458030641, 0.978031042361, 0.974273380329, 0.971371999377, 0.96837697535, - 0.964571949947, 0.959066324787, 0.954816960611, 0.951051733139, 0.947034095561, - 0.943943667589, 0.938609460085, 0.937019169869, 0.932068478426, 0.928858927549, - 0.926316705707, 0.920620507742, 0.917363382195, 0.913676796538, 0.913073182723, - 0.90574749251, 0.900207435866, 0.894934151475, 0.910472072588, 0.910358697956, - 0.909635081259, 0.908573398308, 0.90826193476, 0.907612137329, 0.905710315215, - 0.90469219147, 0.90441181284, 0.904047558298, 0.903685516587, 0.902896006391, - 0.900438172704, 0.900210427796, 0.899854579435, 0.899045004048, 0.898129764354, - 0.897823164358, 0.89675805585, 0.895325000445, 0.893395983258, 0.893215118042, - 0.893140210389, 0.891265616092, 0.890965233319, 0.890412121542, 0.890372676695, - 0.888807907347, 0.887953767739, 0.887495255962, 0.886434140358, 0.885443967903, - 0.883245786048, 0.882202319982, 0.881358584844, 0.881034970476, 0.880334968579, - 0.878047857587, 0.877560128555, 0.875956745243, 0.875620944741, 0.870531125372, - 0.866385311313, 0.861266229338, 0.859959502058, 0.853992060055, 0.848393476744, - 0.84511718603, 0.843056740086, 0.839164575537, 0.837340755606, 0.835467151152, - 0.83475709971, 0.816664565995, 0.811494584033, 0.810888989616, 0.808659504987, - 0.802552720798, 0.797094894576, 0.794851952293, 0.792773492445 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 14.9280984166, 15.5184273833, 16.4023808425, 18.0557795913, - 20.1991457662, 22.7308290002, 25.8917360906, 29.6875539525, 33.7956696286, - 38.015162488, 42.6730248745, 47.2635724398, 52.0970691846, 56.9054288356, - 61.1308154962, 66.3128316967, 70.8061386875, 75.9997818499, 81.2539330218, - 85.4687663551, 91.0077784091, 96.0823460483, 100.211021404, 103.866853328, - 108.082954136, 113.855653548, 119.903847585, 124.872977098, 129.69843373, - 134.105507709, 139.328868627, 143.622128658, 147.677604774, 152.737039207, - 156.303197637, 161.411102918, 166.962255873, 171.267428462, 173.927396399, - 178.843646708, 186.820542503, 193.524925513, 199.719612493, 202.960729245, - 205.293021006, 210.267791371, 214.09408939, 216.772660819, 223.882795699, - 232.019278639, 235.637579431, 237.433861643, 239.457699535, 242.666520144, - 251.715303709, 259.198717949, 260.824911348, 264.072386095, 268.878615098, - 272.283293909, 276.105584931, 283.066764706, 292.435241935, 298.314468126, - 299.027183937, 304.459507042, 310.520120724, 312.898399015, 314.549568966, - 319.019741379, 325.760075758, 329.41780303, 333.652272727, 339.3682247, - 348.252632734, 357.285544397, 362.544265328, 365.797106237, 368.649431818, - 376.973076923, 384.70521978, 390.532142857, 395.935714286, 411.054304029, - 436.789566755, 462.60637027, 480.512006162, 500.781612903, 533.010555556, - 557.740555556, 572.611470588, 589.198529412, 605.12622549, 615.429166667, - 622.628571429, 675.022321429, 739.84375, 755.9375, 763.8375, - 787.066666667, 819.291666667, 840.75, 852.791666667, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(3.489), - etaMin = cms.double(2.964), - l1tCalibrationFactors = cms.vdouble( - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 26.2286936937, 25.0883854167, 21.5503612231, 19.2925423089, - 21.3457232423, 22.8334014207, 23.9319267237, 26.6239039363, 30.3986741142, - 33.7250755974, 37.8195972328, 42.1978424806, 52.2604512363, 80.2692022114, - 122.67241995, 166.87206295, 199.54597288, 226.44949301, 245.655374, - 257.034237337, 257.866298241, 287.3217783, 347.484176974, 307.774717514, - 272.791666667, 304.614583333, 366.880208333, 406.911458333, 296.145833333, - 209.0, 217.875, 211.25, 178.5, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(4.191), - etaMin = cms.double(3.489), + etaMin = cms.double(2.172), l1tCalibrationFactors = cms.vdouble( - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0 + 1.33772238866, 1.33772238866, 1.33772238866, 1.33473934195, 1.30242829723, + 1.27631075498, 1.25143840782, 1.2365993847, 1.22283208594, 1.21383948973, + 1.20270942905, 1.19242313522, 1.18157505638, 1.17163939573, 1.16212445691, + 1.15064512868, 1.12111242416, 1.10180561512, 1.06494795446, 1.02791008468, + 0.979565936906, 0.935460737671, 0.922476716325, 0.870214599247, 0.862692426562, + 0.780257657402, 0.726159840141, 0.698509844652 ), l1tPtBins = cms.vdouble( - -float('inf'), 22.5440519958, 20.5700369268, 18.940228544, 19.656022303, - 21.0931801845, 23.113990869, 26.3227763633, 30.3817638115, 35.043540285, - 39.4982579153, 43.4506655731, 48.6407605324, 59.5995676838, 82.7690755527, - 114.280107948, 142.242281862, 162.02662341, 183.956841939, 210.824209207, - 229.926842684, 227.643518519, 238.016534392, 247.125, 298.946428571, - 271.65625, 243.03125, 326.625, float('inf') + -float('inf'), 15.2987042682, 20.6666592562, 27.150657531, 34.834542074, + 42.9223748303, 51.5696382427, 59.9311353298, 68.6376432274, 76.9323193226, + 85.3108305134, 95.1635083363, 104.886459308, 114.448100114, 123.396424629, + 133.054919468, 151.922665869, 174.391475487, 200.175498357, 244.035295655, + 306.180445151, 373.469537815, 415.021825397, 462.511111111, 506.025, + 571.5, 670.875, 730.375, float('inf') ) ), cms.PSet( etaMax = cms.double(5.191), - etaMin = cms.double(4.191), + etaMin = cms.double(3), l1tCalibrationFactors = cms.vdouble( 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0 + 1.0, 1.0 ), l1tPtBins = cms.vdouble( - -float('inf'), 20.1275528907, 18.8347289263, 19.1060971818, 20.3123157733, - 21.92154214, 24.441478902, 27.4055129042, 30.8574386517, 34.6682463198, - 39.247933023, 43.9824249801, 47.9520354357, 57.1837291686, 77.2409768212, - 102.910275424, 131.248104371, 147.631578947, 175.0, 199.875, - float('inf') + -float('inf'), 50.6609817658, 87.2333638822, 128.156144343, 165.535850739, + 220.379807692, 214.8125, float('inf') ) ) ) @@ -780,4 +169,4 @@ absEtaBinning = cms.vdouble([p.etaMin.value() for p in calibration] + [calibration[-1].etaMax.value()]), calibration = calibration, outputCollectionName = cms.string("Phase1L1TJetFromPfCandidates") -) \ No newline at end of file +) diff --git a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_9x9trimmedJets_cfi.py b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_9x9trimmedJets_cfi.py new file mode 100644 index 0000000000000..19522191c7afa --- /dev/null +++ b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_9x9trimmedJets_cfi.py @@ -0,0 +1,172 @@ +import FWCore.ParameterSet.Config as cms +calibration = cms.VPSet( + cms.PSet( + etaMax = cms.double(0.435), + etaMin = cms.double(0), + l1tCalibrationFactors = cms.vdouble( + 1.26806262588, 1.26806262588, 1.26806262588, 1.21946518166, 1.16379314256, + 1.12254571737, 1.09470447579, 1.0841543755, 1.0506829785, 1.04497069514, + 1.03934326232, 1.03345095744, 1.02750216269, 1.02112447625, 1.01574388754, + 1.00810805817, 0.99605714473, 0.998607125466, 0.993219133111, 0.985092796485, + 0.978878065815, 0.970789716092, 0.961656436256, 0.959516385399, 0.948147862573, + 0.947200388265, 0.946753222399, 0.932749319061, 0.926825446704, 0.923647034369, + 0.913806018949, 0.881718922491 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 16.6077877711, 23.758945127, 32.4028984708, 42.0487682803, + 52.0149801449, 62.3890828336, 72.8126081905, 83.1366634984, 93.6055295245, + 103.912979585, 114.384063612, 125.147255659, 136.35164449, 147.039551665, + 158.871071713, 176.765709913, 197.959631424, 225.348244676, 268.360888373, + 314.00482813, 359.527865313, 414.339896094, 450.220016892, 493.214342949, + 532.413003663, 536.851785714, 582.845833333, 646.270833333, 675.241071429, + 716.678571429, 850.125, float('inf') + ) + ), + cms.PSet( + etaMax = cms.double(0.783), + etaMin = cms.double(0.435), + l1tCalibrationFactors = cms.vdouble( + 1.27022476075, 1.27022476075, 1.27022476075, 1.23193977019, 1.17930700881, + 1.13682836123, 1.10620197739, 1.08803729104, 1.06551671995, 1.05815998513, + 1.05091777833, 1.04351195843, 1.03840402395, 1.02970511677, 1.02322448674, + 1.01173641061, 0.998762625873, 1.01162336339, 1.01141830879, 1.01110184225, + 1.01084507077, 1.01048193189, 1.01025026917, 1.00998987557, 1.00977460446, + 1.00958480149, 1.00938402751, 1.00923173234, 1.00896205922, 1.00877952325, + 1.00848454553, 1.00809094748 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 16.455812263, 23.4058211563, 31.8076589224, 41.2694704832, + 51.4874752049, 61.8853021467, 72.1485970296, 82.3017709389, 92.821899346, + 103.57630449, 114.366868474, 123.585206897, 133.756106455, 144.938211106, + 158.174975175, 176.194963818, 195.029478711, 220.750032768, 262.570643701, + 308.538413528, 358.248823119, 405.945769577, 445.403605016, 483.547003284, + 516.029761905, 547.35, 575.6625, 609.5, 645.7625, + 684.054166667, 739.270833333, float('inf') + ) + ), + cms.PSet( + etaMax = cms.double(1.131), + etaMin = cms.double(0.783), + l1tCalibrationFactors = cms.vdouble( + 1.26940863552, 1.26940863552, 1.26940863552, 1.21850042272, 1.16014066757, + 1.11360382831, 1.08451810312, 1.06753212736, 1.05501857105, 1.04712872618, + 1.03953145463, 1.03129558228, 1.02392940863, 1.01647040511, 1.00765667693, + 0.997452910609, 0.981686885508, 0.989286565044, 0.992427119505, 0.996927682694, + 1.00148185029, 1.00626281233, 1.01118610536, 1.01492397525, 1.0197730491, + 1.02294548929, 1.02309909545, 1.03179752273, 1.04335891364, 1.04679419517, + 1.04697871887, 1.05665639769 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 16.658158537, 23.8634314296, 32.6191125159, 42.4492040271, + 52.9120745879, 63.2335833679, 73.7409226942, 84.0418964903, 94.148332101, + 104.682994045, 115.453031153, 126.065870612, 136.150267568, 147.219321527, + 160.155420808, 177.820618512, 198.152518248, 224.425247256, 264.972493816, + 313.021014808, 362.557459677, 414.052651985, 460.012722795, 505.578952902, + 548.144755747, 565.794270833, 612.7671875, 720.275, 799.854166667, + 819.0625, 871.395833333, float('inf') + ) + ), + cms.PSet( + etaMax = cms.double(1.479), + etaMin = cms.double(1.131), + l1tCalibrationFactors = cms.vdouble( + 1.35067406191, 1.35067406191, 1.35067406191, 1.29728973727, 1.23323857604, + 1.1805316629, 1.14192838643, 1.12335733217, 1.1065907126, 1.1005436618, + 1.09369739262, 1.08689105877, 1.08047792193, 1.07301990489, 1.06799861036, + 1.0578434328, 1.04620517219, 1.03279280198, 1.03276766643, 1.05490363283, + 1.0613631336, 1.07151789312, 1.0923432672, 1.10236162162, 1.12458041647, + 1.13080591424, 1.15738278091, 1.18032588359, 1.20641120054, 1.24407887972, + 1.35400575741 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 16.5873975086, 23.8386796597, 32.2204904018, 41.0711979739, + 50.5775158961, 60.7008778657, 70.3592246275, 80.5033152458, 90.7596180755, + 100.458044915, 110.727608677, 120.671367886, 131.105326809, 140.492334228, + 151.908160762, 168.301305891, 187.144529404, 214.024926059, 257.981265415, + 293.073033708, 313.461711712, 351.47989353, 389.330681818, 428.891447368, + 463.797697368, 504.052083333, 564.821969697, 624.988636364, 703.225, + 884.35, float('inf') + ) + ), + cms.PSet( + etaMax = cms.double(1.83), + etaMin = cms.double(1.479), + l1tCalibrationFactors = cms.vdouble( + 1.63343989323, 1.63343989323, 1.63343989323, 1.63343989323, 1.61237327031, + 1.58129290649, 1.54880181313, 1.51437276367, 1.47566044577, 1.4333612461, + 1.43007616674, 1.41838888661, 1.41120688977, 1.40292719871, 1.39289499293, + 1.38154733635, 1.36518171857, 1.34179569075, 1.31131037345, 1.21512470624, + 1.19652546359, 1.18052243169, 1.14219697689, 1.12090132667, 1.10494445955, + 1.08116744865, 1.04972485653, 1.02388122645, 1.02106332779, 0.93821710715, + 0.932912827317, 0.900954541324 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 14.0304333699, 19.2702852281, 25.0387598316, 31.5205165869, + 38.5596312994, 45.8035002303, 53.2357524128, 61.14689424, 69.6758091231, + 77.1332356297, 85.7578326385, 94.7364478681, 102.093621468, 110.807017112, + 120.98025046, 134.167127072, 153.082251962, 178.715988762, 222.463142692, + 269.236689617, 301.854005866, 353.065940767, 409.266883117, 444.382411067, + 481.836956522, 533.888888889, 587.888888889, 614.90625, 695.65625, + 778.75, 813.875, float('inf') + ) + ), + cms.PSet( + etaMax = cms.double(2.172), + etaMin = cms.double(1.83), + l1tCalibrationFactors = cms.vdouble( + 1.4878363144, 1.4878363144, 1.4878363144, 1.48518474866, 1.44553707599, + 1.40800746363, 1.37269392814, 1.34268728519, 1.31155107185, 1.29724964634, + 1.26824717982, 1.25895653021, 1.25080118853, 1.24412237598, 1.23242162986, + 1.21983464552, 1.19947769179, 1.17915682723, 1.19591426516, 1.16520900199, + 1.11521954951, 1.08960480689, 1.06320579474, 0.984904677633, 0.936138290441, + 0.933930169885, 0.906741381816, 0.83587888946 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 14.6323212201, 20.2961463384, 26.9638979746, 34.2907286866, + 42.0772600421, 50.2694398412, 58.5750993499, 67.719467579, 75.5350197454, + 83.5378418246, 93.3456200252, 101.928069729, 109.225642018, 118.267354545, + 130.215556381, 146.422127101, 166.433333333, 193.380670156, 231.798066137, + 288.213675743, 341.070380435, 377.434442935, 450.6328125, 539.46875, + 575.10625, 595.658333333, 664.208333333, float('inf') + ) + ), + cms.PSet( + etaMax = cms.double(2.5), + etaMin = cms.double(2.172), + l1tCalibrationFactors = cms.vdouble( + 1.34807839515, 1.34807839515, 1.34807839515, 1.33809647408, 1.28296668109, + 1.24225927144, 1.21974923257, 1.21649951103, 1.23064762664, 1.1629973435, + 1.15852840915, 1.15372227709, 1.15041260925, 1.14530829511, 1.13990768956, + 1.13512676324, 1.125588949, 1.11458405118, 1.09607958404, 1.05737289774, + 1.01895994641, 0.992663655394, 0.955621083551, 0.93513823446, 0.901760000269, + 0.843868420876, 0.795304246419, 0.770482557252 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 15.2387099279, 20.6150961319, 27.4619155051, 35.7501165961, + 44.8270237134, 54.3715537124, 63.4511614119, 72.3586695675, 81.6352356283, + 91.1311643255, 101.316594704, 110.228974539, 119.468803554, 131.004799458, + 142.185666464, 157.90981642, 180.468831547, 207.538452813, 253.905743927, + 316.433023873, 368.898168103, 420.252232143, 466.892857143, 510.5625, + 584.5625, 670.875, 730.375, float('inf') + ) + ), + cms.PSet( + etaMax = cms.double(5.191), + etaMin = cms.double(3), + l1tCalibrationFactors = cms.vdouble( + 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 50.6626115353, 87.3285137419, 126.832659901, 178.631354515, + 238.634615385, 218.625, float('inf') + ) + ) +) + +Phase1L1TJetCalibrator = cms.EDProducer('Phase1L1TJetCalibrator', + inputCollectionTag = cms.InputTag("Phase1L1TJetProducer", "UncalibratedPhase1L1TJetFromPfCandidates", ""), + absEtaBinning = cms.vdouble([p.etaMin.value() for p in calibration] + [calibration[-1].etaMax.value()]), + calibration = calibration, + outputCollectionName = cms.string("Phase1L1TJetFromPfCandidates") +) \ No newline at end of file diff --git a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_cfi.py b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_cfi.py index 19e3300cdb56e..a10d9b94d3aee 100644 --- a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_cfi.py +++ b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetCalibrator_cfi.py @@ -4,773 +4,162 @@ etaMax = cms.double(0.435), etaMin = cms.double(0), l1tCalibrationFactors = cms.vdouble( - 1.30593500928, 1.30593500928, 1.30593500928, 1.30593500928, 1.30593500928, - 1.30593500928, 1.30593500928, 1.29877240738, 1.27505646861, 1.25219959782, - 1.22883381968, 1.20684371656, 1.18979961771, 1.17522355783, 1.16246546468, - 1.15226940379, 1.14413882066, 1.13938941727, 1.13739491227, 1.13793199102, - 1.14092700033, 1.11795659621, 1.11609313161, 1.11417037162, 1.11243226077, - 1.11070072771, 1.10875740287, 1.10726570195, 1.1051616362, 1.10338001137, - 1.10153571845, 1.09948230743, 1.09818855487, 1.09646594549, 1.09446138827, - 1.09234579871, 1.09022671097, 1.08886241836, 1.08736953376, 1.08544940592, - 1.08442568658, 1.08180803071, 1.08067218285, 1.07858187394, 1.07669746524, - 1.07527455825, 1.07316897527, 1.07098953035, 1.06911445001, 1.06716469346, - 1.06667492923, 1.06447002386, 1.06523124572, 1.06527893525, 1.065576197, - 1.06591666099, 1.06601764401, 1.06644873563, 1.06661880084, 1.06673071851, - 1.06691420012, 1.06726762157, 1.06775571347, 1.06786374719, 1.06789576306, - 1.06827875616, 1.06865711015, 1.06884800094, 1.06906043831, 1.06920596303, - 1.06966578613, 1.06985365053, 1.07034848137, 1.07041388057, 1.07058592324, - 1.0706252938, 1.07110117409, 1.0712930591, 1.07152975484, 1.07176404737, - 1.07220228702, 1.07233826378, 1.07264834127, 1.07320100205, 1.07453197014, - 1.07607530754, 1.07712180013, 1.07823841009, 1.07970500773, 1.08048043515, - 1.08219189804, 1.08304518283, 1.08380317179, 1.08526467262, 1.08603074759, - 1.08759821577, 1.08924251106, 1.08973269374, 1.09074314469, 1.09191666444, - 1.09208743615, 1.09278371011, 1.09402309387, 1.09596401083, 1.09711717282, - 1.09741736219, 1.09749810025, 1.09884588375, 1.10015897034, 1.1004754894, - 1.10083709022, 1.10221338454, 1.10264282921, 1.10297906711, 1.10325547222, - 1.10415448675, 1.10483978956 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 13.7361486471, 15.0444025401, 17.183249284, 19.7418995533, - 22.6195179309, 25.672465563, 29.1248468266, 32.5574913862, 35.8853691114, - 39.5168955091, 43.4997516772, 47.3845759529, 51.0331468753, 54.7604938703, - 58.5852237487, 62.5900316096, 66.6097071387, 70.2674525642, 74.1920185409, - 78.1851696373, 81.8396255454, 85.6631528954, 89.6542996572, 93.5133081382, - 97.1707398937, 101.044492453, 104.665432414, 108.45581308, 112.551809241, - 116.373972856, 120.482632575, 124.010954993, 127.190571759, 131.119464129, - 135.462605973, 139.92647709, 143.598388747, 146.610205213, 150.207940433, - 153.311117714, 157.149575393, 161.106230342, 164.506996681, 168.696838277, - 172.183156108, 175.902618853, 180.419565698, 184.693534394, 188.725383271, - 191.296938447, 194.137451888, 199.906004752, 203.7012173, 206.239381413, - 210.93179056, 214.179973659, 218.094998222, 222.51833203, 224.593172332, - 226.766731017, 230.717283226, 236.909168989, 241.295482948, 242.325972922, - 245.379623995, 250.981643592, 255.170167389, 258.13787065, 260.771768771, - 265.225940013, 269.991648129, 275.014944527, 279.137137587, 280.884243502, - 282.439829719, 286.231064235, 291.144505567, 294.298018293, 297.763567073, - 302.712083333, 306.937188552, 310.219271886, 316.567331487, 330.427141221, - 351.576385453, 370.632448645, 386.548635886, 405.555971293, 422.052873198, - 440.351502533, 459.223009166, 471.078819965, 487.409906566, 503.8004903, - 520.970785619, 544.603058025, 560.308624487, 571.35034125, 587.420077061, - 597.311422476, 603.691176027, 617.933815952, 641.33458427, 664.100929644, - 674.7947418, 677.597619695, 688.108733243, 707.687512066, 719.678209698, - 724.667840428, 737.455336011, 750.742029179, 756.375949367, 760.883798883, - 769.53257937, 781.190043929, float('inf') + 1.27449917748, 1.27449917748, 1.27449917748, 1.23493179134, 1.18016297798, + 1.13799575237, 1.10812834725, 1.09304437053, 1.06535849935, 1.05911433179, + 1.05311693057, 1.04683141823, 1.04024977527, 1.03376492646, 1.02792720165, + 1.01956986102, 1.00718649496, 0.988626784325, 0.998476722478, 1.01288124549, + 1.02471525137, 1.03646775333, 1.05180913101, 1.05924395389, 1.07924401671, + 1.08165375247, 1.08337316605, 1.10962671513, 1.12102129235, 1.13021919622, + 1.13576642802 + ), + l1tPtBins = cms.vdouble( + -float('inf'), 15.9186731488, 22.8302714976, 31.3470623972, 40.9124979701, + 50.8182301193, 60.9776479471, 71.0672224351, 81.1996034394, 91.6144971179, + 101.789274468, 111.998416189, 122.693159862, 133.553585263, 143.795691085, + 155.594148691, 172.833121605, 193.219678024, 219.365786562, 258.892647496, + 301.652891703, 340.091206576, 384.245393528, 421.36317182, 466.073087432, + 502.59375, 509.322916667, 554.909722222, 616.263888889, 649.822916667, + 673.852678571, float('inf') ) ), cms.PSet( etaMax = cms.double(0.783), etaMin = cms.double(0.435), l1tCalibrationFactors = cms.vdouble( - 1.31765124058, 1.31765124058, 1.31765124058, 1.31765124058, 1.31765124058, - 1.31765124058, 1.31765124058, 1.31465282163, 1.28575901774, 1.26113393397, - 1.2380602966, 1.21582096587, 1.19744916693, 1.18054629443, 1.16787485502, - 1.15583168823, 1.14758337599, 1.14208327323, 1.13886556331, 1.13870497984, - 1.14096533043, 1.12408964993, 1.12219388973, 1.120013898, 1.11803240949, - 1.11630261403, 1.11402073463, 1.1123966406, 1.11086129444, 1.10826887919, - 1.10620765113, 1.1049896097, 1.10324756085, 1.10088556073, 1.09942980465, - 1.09699690808, 1.09548617564, 1.09368130331, 1.09205222583, 1.08919862016, - 1.08839582595, 1.08641065057, 1.08493842877, 1.08316334005, 1.0795450924, - 1.07895335999, 1.07798891069, 1.07686082074, 1.07314681503, 1.07194406998, - 1.06878984551, 1.0686060925, 1.06678939448, 1.06679179464, 1.06708846087, - 1.06742528856, 1.06769130631, 1.06815041574, 1.06884086475, 1.06987814673, - 1.06988802987, 1.0704377678, 1.07056710173, 1.07130122174, 1.07152113679, - 1.07194159982, 1.07208591853, 1.0727232614, 1.07319937955, 1.07386963115, - 1.07432131127, 1.07470513305, 1.07491724281, 1.07537253505, 1.07556595045, - 1.07591108387, 1.07677896733, 1.07719731979, 1.0777851552, 1.07805517241, - 1.07807740993, 1.07838901022, 1.0790622486, 1.08013699918, 1.0827927702, - 1.0843121895, 1.08709452076, 1.08901828006, 1.09165640327, 1.09308535273, - 1.09472958635, 1.09710399868, 1.09964360135, 1.10048996502, 1.10377615478, - 1.1046473137, 1.1072696257, 1.10727248074, 1.1096455364, 1.11147790878, - 1.11292801571, 1.11347619372, 1.11699484494, 1.11815689474, 1.12003828784, - 1.12052763208, 1.1229679511, 1.12352199927, 1.12575850043, 1.12683694743, - 1.12811442818, 1.12934567928, 1.12942295213, 1.13132368863, 1.13163278182, - 1.1325017048, 1.13471717386 + 1.29025683658, 1.29025683658, 1.29025683658, 1.25298150518, 1.19487866706, + 1.15080116375, 1.12093007164, 1.10806840148, 1.07542032572, 1.06982434752, + 1.06427959217, 1.05839569094, 1.05415876237, 1.04791679928, 1.04281508228, + 1.03415621861, 1.02449421978, 1.01478042466, 1.01158365084, 1.02291458246, + 1.03300938298, 1.04555663218, 1.05063718336, 1.06450205914, 1.0726614699, + 1.0729443896, 1.07622132959, 1.07800287535, 1.09647412495, 1.10102369381, + 1.11498981219, 1.1308491155 ), l1tPtBins = cms.vdouble( - -float('inf'), 13.4617640698, 14.8563033537, 17.0029373627, 19.4993459131, - 22.5094875271, 25.5722154792, 28.6759341595, 32.2508141657, 35.8830447487, - 39.4471435422, 43.2156130286, 47.0159530895, 50.8305690624, 54.5607207729, - 58.3946605126, 62.3675105446, 66.1130769642, 70.0678977472, 73.9986011825, - 77.6384420382, 81.0379731643, 84.5542929113, 88.7089448536, 92.950984667, - 96.7341131314, 100.823447565, 104.805034359, 108.025636234, 112.233304465, - 116.977034833, 120.319785711, 123.33717858, 127.52067535, 131.412337172, - 135.376267885, 139.396239217, 142.776028763, 146.276454316, 150.84591501, - 154.573096915, 157.415037111, 160.939363945, 164.249537178, 169.747279876, - 174.038758381, 175.625065269, 177.758112715, 182.693943557, 187.705874717, - 192.147188166, 195.549783519, 199.928504019, 204.130123494, 205.402214778, - 208.096807494, 210.661035632, 213.745394243, 218.63508887, 225.984064443, - 230.438224799, 232.818596253, 235.707056628, 239.379793877, 243.437821641, - 246.161696405, 248.564018995, 251.888849024, 256.625001773, 261.501133119, - 266.273316288, 269.827158363, 272.361977929, 275.200800082, 277.960105005, - 280.250844775, 285.410462468, 290.881520408, 295.161382353, 298.810294118, - 300.053411765, 301.473404762, 305.662456971, 313.097600657, 328.965529309, - 346.72487487, 365.02254967, 385.040101444, 404.444258283, 421.743720885, - 434.815632795, 451.909110374, 472.811077415, 487.213425946, 504.7914137, - 522.474869077, 537.334492822, 548.50074994, 558.606784829, 576.494747776, - 590.456909938, 598.956697952, 616.255125105, 636.164681419, 649.110092294, - 659.194122119, 671.655566518, 684.392231766, 696.261949339, 710.362219101, - 720.383255686, 731.054250871, 736.620111876, 745.03365685, 754.433259259, - 759.444, 772.563589744, float('inf') + -float('inf'), 15.6919158647, 22.5226170435, 30.8891780787, 40.2493434193, + 50.214229057, 60.4912167204, 70.5763790324, 80.500905786, 90.8133968691, + 101.207902198, 111.871044901, 121.313961636, 131.090956543, 141.674814644, + 154.513684583, 171.607379717, 189.685344913, 214.218520282, 253.593388284, + 298.795202861, 346.563079677, 383.752406958, 423.721527778, 470.186111111, + 487.996875, 495.507102273, 506.178977273, 548.90625, 597.473214286, + 636.535714286, 699.458333333, float('inf') ) ), cms.PSet( etaMax = cms.double(1.131), etaMin = cms.double(0.783), l1tCalibrationFactors = cms.vdouble( - 1.33475296985, 1.33475296985, 1.33475296985, 1.33475296985, 1.33475296985, - 1.33475296985, 1.33475296985, 1.33226561273, 1.30259690233, 1.27443021782, - 1.24695451996, 1.22360268987, 1.20311338673, 1.18615855335, 1.17043324164, - 1.15641477527, 1.14977495838, 1.14283657905, 1.13989123124, 1.13946579446, - 1.14231716233, 1.11223390498, 1.11032941862, 1.10876770575, 1.10706257355, - 1.10533758256, 1.10327773464, 1.10205106864, 1.09952657792, 1.09796497528, - 1.09636198479, 1.09407699909, 1.09292917433, 1.09146444937, 1.0897827088, - 1.08753713213, 1.08571574463, 1.08360712003, 1.08241273249, 1.08006263471, - 1.07876430683, 1.07665001315, 1.07520977699, 1.07309317212, 1.07148954915, - 1.06998446196, 1.06763882723, 1.06593012152, 1.06416994604, 1.06248789644, - 1.06108879272, 1.05992286402, 1.05317676325, 1.05325315207, 1.05328145202, - 1.05331946129, 1.05333451749, 1.05335739056, 1.05338867229, 1.05345362721, - 1.05350461987, 1.05353242681, 1.05354620215, 1.05357596304, 1.05361901933, - 1.05367016652, 1.05372471613, 1.05375800268, 1.0537740869, 1.053808856, - 1.05383905531, 1.05387820854, 1.05393304933, 1.05395697478, 1.0539790604, - 1.05401082594, 1.05402814078, 1.05405575203, 1.05412382321, 1.05419138364, - 1.05420892544, 1.05421588207, 1.05422623442, 1.05435819942, 1.05453691148, - 1.05468229568, 1.054828368, 1.0550371744, 1.05519442279, 1.05537683494, - 1.05543587199, 1.05559643203, 1.05583354939, 1.05600523012, 1.05614564645, - 1.0562065587, 1.05637629134, 1.05648705268, 1.0566601044, 1.05685709467, - 1.05691564828, 1.05705161557, 1.05716562079, 1.05743417336, 1.05746847205, - 1.0576223392, 1.05776311116, 1.05791278011, 1.05794893649, 1.05797135724, - 1.05819866602, 1.05822994354, 1.05831735118, 1.0583732007, 1.05849860943, - 1.05855452656, 1.05861094491 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 13.343711949, 14.6817682075, 16.8611920462, 19.3625988325, - 22.1116860384, 25.328469293, 28.6465449042, 32.0291942377, 35.5920256883, - 39.3690921576, 43.2083995055, 46.9599214361, 50.6306173694, 54.4137625385, - 58.6651596584, 62.3400410819, 65.8670625897, 69.6785286182, 73.4717140921, - 77.5436215676, 81.596122565, 85.7580030814, 89.5501134195, 93.1241252244, - 96.8767674566, 101.017477729, 104.613007766, 108.716868869, 113.187159185, - 116.649304764, 120.902849856, 124.658432024, 127.516628035, 130.95894155, - 135.255526753, 139.704889265, 144.00442271, 147.618002205, 151.495759517, - 155.487230222, 159.220725229, 163.109471504, 167.000746281, 171.070770402, - 174.471778589, 178.684566552, 183.120118366, 186.915162838, 190.681044847, - 194.051905148, 196.85811602, 199.101017508, 204.172301866, 209.796636713, - 213.359056052, 216.209963072, 218.247687695, 221.157118607, 226.327368908, - 232.55657599, 236.790032777, 239.024013533, 241.362968684, 245.275023653, - 250.336043531, 256.014534028, 260.733473605, 263.385885886, 266.117946708, - 269.608331324, 273.334250786, 278.384017686, 282.61568155, 285.087595672, - 287.980713846, 290.617524613, 293.031149132, 298.171624579, 305.458343268, - 310.03040446, 311.3465663, 312.276479787, 319.922385204, 336.61330505, - 354.025162613, 369.683471169, 388.749095858, 408.415147831, 426.663185853, - 439.634884418, 451.432593373, 472.797548772, 494.759955929, 511.527164727, - 522.343409581, 534.734653862, 549.804007526, 565.051676294, 584.931937661, - 598.660863769, 609.111370713, 622.540978556, 643.093642739, 659.364126808, - 669.473212056, 685.302503628, 700.90625, 710.889593046, 714.036610575, - 727.453164507, 741.345542654, 747.721824336, 755.418220561, 765.156199987, - 774.897811932, 780.932961538, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(1.305), - etaMin = cms.double(1.131), - l1tCalibrationFactors = cms.vdouble( - 1.33248922515, 1.33248922515, 1.33248922515, 1.33248922515, 1.33248922515, - 1.33248922515, 1.33248922515, 1.32688879235, 1.29906234477, 1.27366038559, - 1.24728154779, 1.22259039808, 1.20156077285, 1.1820242409, 1.16894642274, - 1.14538049183, 1.13599218236, 1.12345426818, 1.11389465861, 1.10832948259, - 1.1094883059, 1.10730870156, 1.1046443432, 1.10218927312, 1.0998241559, - 1.09712132956, 1.09650471763, 1.09299340082, 1.09036610962, 1.0881608947, - 1.08538164179, 1.08458884034, 1.08011669298, 1.07797201118, 1.07595937564, - 1.07453993476, 1.07028104604, 1.06936193745, 1.06900352118, 1.06383911152, - 1.0631856285, 1.06120230014, 1.05712829896, 1.05394170957, 1.05266659306, - 1.05057123897, 1.05043680863, 1.04730040896, 1.04499172248, 1.01238369998, - 1.01242033768, 1.01245156427, 1.01249373928, 1.0125349522, 1.01253765187, - 1.01259478391, 1.01259573287, 1.0126640653, 1.01268954277, 1.01269789252, - 1.01271219022, 1.01276687267, 1.01284855331, 1.01284872483, 1.01286809281, - 1.01294642869, 1.01296438096, 1.01301199095, 1.01302906886, 1.0130369754, - 1.01306242998, 1.01313354135, 1.01317323157, 1.01318089545, 1.0131844335, - 1.01320611448, 1.01325479001, 1.01327294514, 1.0132943449, 1.01333923946, - 1.01333939937, 1.01336603457, 1.01343494486, 1.0134583253, 1.01365298014, - 1.01383738731, 1.01398139619, 1.01419208892, 1.01423075495, 1.01430101943, - 1.01454848742, 1.01459766887, 1.0148864832, 1.01489807764, 1.01496904818, - 1.0152443383, 1.01527866955, 1.01539244372, 1.01559278518, 1.01568902894, - 1.01587835395, 1.01596342556, 1.01598386393, 1.01600383536, 1.01601236775, - 1.01617537883, 1.01635496837, 1.0164341118, 1.01648866286, 1.01651364121, - 1.01654465787, 1.01662331127, 1.01672120961, 1.01680219651, 1.01692763695, - 1.0171096791, 1.01711329036 + 1.30032664809, 1.30032664809, 1.30032664809, 1.25084727971, 1.18473554378, + 1.13301872436, 1.10276185733, 1.08703419718, 1.06357257192, 1.05675721169, + 1.04991871811, 1.04261488423, 1.03584577743, 1.02906929088, 1.02063131716, + 1.01179767645, 0.998329381732, 1.01828991088, 1.01201460292, 1.00416117779, + 0.994510368907, 0.985813238053, 0.978643190728, 0.970975488844, 0.96254161562, + 0.961175449848, 0.951861024521, 0.939008392591, 0.92267285167, 0.918064561515, + 0.905942754804, 0.877221856129 ), l1tPtBins = cms.vdouble( - -float('inf'), 13.1991270188, 14.6706495023, 16.786504567, 19.5079933515, - 22.4885277317, 25.4702587937, 28.9241163451, 32.6179726599, 36.3450911266, - 40.2439203837, 44.4019591261, 48.4611625118, 52.4297312604, 55.9179085836, - 60.4622819187, 64.9611669799, 68.6264634248, 72.9747163646, 76.6433659092, - 80.5435379752, 84.7906966315, 89.0107872025, 93.4708652448, 97.6702425453, - 102.085466641, 104.977381997, 108.573659306, 113.921652962, 118.131762489, - 122.474262009, 125.586258094, 130.173114391, 135.937737294, 139.559618136, - 142.549664558, 147.496660786, 152.007764393, 153.120752036, 157.932272499, - 163.00085695, 165.298063498, 170.575246841, 176.900718716, 180.787784775, - 183.724159816, 185.666761947, 188.516329496, 193.260122567, 198.584541847, - 204.223510123, 208.531776071, 213.191570664, 218.485332513, 221.273059543, - 225.071388889, 228.758576779, 233.156805946, 239.112191752, 241.259663468, - 242.697403782, 247.076508835, 255.733322196, 260.929587689, 262.17002442, - 268.372612412, 274.485326087, 278.647451456, 282.754069103, 284.340170279, - 286.458052632, 292.588401869, 299.622480301, 302.628687127, 303.33982519, - 304.940818645, 309.407300067, 313.649947917, 316.161032609, 320.369631094, - 323.229848485, 324.930897436, 330.996464446, 336.855407305, 350.697060925, - 374.761263184, 395.610280177, 418.127998187, 433.958178188, 440.873473699, - 461.044258718, 479.876618531, 501.333790888, 520.404806472, 525.646324329, - 547.628180439, 567.284044338, 576.686302211, 596.627477785, 615.455760614, - 633.584680135, 651.004351852, 657.7025, 660.267857143, 662.077380952, - 672.967569787, 694.717073755, 711.142361111, 719.629761905, 724.678571429, - 728.233333333, 735.195578231, 746.403709789, 757.759979929, 770.864720395, - 790.384807181, 802.170744681, float('inf') + -float('inf'), 15.9376851628, 22.9667030429, 31.5826642359, 41.2563645846, + 51.6134274019, 61.737786741, 71.945868755, 82.3189929537, 92.2883651517, + 102.331025225, 112.732966631, 123.083872784, 133.046905301, 144.237420066, + 156.941009466, 173.344492287, 192.503331696, 218.721044328, 256.917525105, + 304.239541454, 353.842483457, 396.738782991, 436.852061311, 480.382043828, + 506.876068376, 535.750631313, 595.678409091, 674.5875, 731.208333333, + 776.4375, 886.854166667, float('inf') ) ), cms.PSet( etaMax = cms.double(1.479), - etaMin = cms.double(1.305), - l1tCalibrationFactors = cms.vdouble( - 1.55053611073, 1.55053611073, 1.55053611073, 1.55053611073, 1.55053611073, - 1.55053611073, 1.55053611073, 1.55053611073, 1.54638583833, 1.512307745, - 1.48258717408, 1.4463976765, 1.42288112248, 1.39363661304, 1.3687636092, - 1.35211274766, 1.33750572334, 1.32267214736, 1.3128565255, 1.3027849667, - 1.30104315905, 1.30082885055, 1.30332360096, 1.30747374592, 1.30668643591, - 1.30438047865, 1.3032934116, 1.30035733244, 1.29908560369, 1.29602715108, - 1.29505644045, 1.29163628253, 1.28996767813, 1.28989480377, 1.28461540765, - 1.28347088112, 1.282705006, 1.27899988113, 1.27615055594, 1.27540726403, - 1.27531929265, 1.27404732742, 1.266819441, 1.26559675044, 1.26479751037, - 1.26278228062, 1.25961571784, 1.25858988601, 1.25342931611, 1.25047902368, - 1.24977308008, 1.24717203691, 1.24566712314, 1.24344847356, 1.241598276, - 1.24031216833, 1.23988105588, 1.22467736101, 1.22402129431, 1.22335887347, - 1.22303925667, 1.22282408914, 1.2223486938, 1.22108111085, 1.22097181547, - 1.2207651341, 1.21897516287, 1.21870058998, 1.2168966347, 1.21650530889, - 1.21630498404, 1.21607424838, 1.21600542498, 1.21598026192, 1.2137962299, - 1.21372590019, 1.21281741654, 1.21258175459, 1.2119929356, 1.21059324293, - 1.21058736979, 1.20740482198, 1.20720931922, 1.20683105268, 1.20373224058, - 1.20106297279, 1.20054984017, 1.19366853865, 1.19354228722, 1.18838816243, - 1.1878042203, 1.18418445048, 1.18142497805, 1.17931401318, 1.17870445128, - 1.17066478299, 1.16966607112, 1.16861608134, 1.16349131531, 1.16342522664, - 1.16182333043, 1.16071419568, 1.15986629269, 1.15580770443, 1.15173210832, - 1.15052198307, 1.1469395989, 1.14460243603, 1.14301237975, 1.14121497695, - 1.14021597405, 1.13882073104, 1.13869512526, 1.13846588111, 1.1347546327, - 1.13372289319, 1.1283538163 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 11.9509981885, 13.1128783605, 15.0627791319, 17.3682558202, - 20.1606178343, 22.9355703348, 25.6212323447, 28.7746797464, 31.8781217164, - 34.8313717661, 38.1736730812, 41.4573850098, 44.7367937098, 48.5192920857, - 51.8510666355, 54.7947345647, 58.1397157415, 61.6111267192, 65.942009059, - 69.7267242278, 72.4678768053, 75.6724493842, 78.5070873127, 82.678372027, - 87.4166066242, 90.168807585, 93.4321225081, 96.8452230149, 100.357584913, - 103.625780468, 107.187367882, 111.315041385, 112.727615853, 117.069030069, - 122.279698925, 123.829292675, 127.455877505, 132.772421724, 135.686519401, - 136.360786194, 137.463878446, 144.358406096, 151.212965333, 152.85302415, - 155.13593928, 159.339072854, 162.739671099, 167.75767841, 174.336683174, - 177.302384393, 179.984797297, 183.315282909, 186.335595674, 189.635980229, - 192.179947347, 193.572844787, 197.081267606, 202.171094891, 206.051987748, - 208.942559524, 210.516666667, 212.549299065, 217.679656208, 221.732418999, - 222.662478522, 228.539511494, 234.61637931, 240.734408377, 247.196092966, - 248.937582934, 250.206384946, 251.088119922, 251.364763731, 257.867403399, - 264.502988506, 267.384069767, 270.75179704, 273.178609626, 279.031680225, - 283.168882979, 292.553818091, 302.496917195, 304.185774374, 314.420356937, - 331.39837094, 340.765584936, 362.530679884, 383.157012092, 398.699498162, - 415.589170692, 427.962556936, 446.739492481, 461.075346728, 469.083062039, - 494.54157754, 521.145533769, 527.175770163, 545.350811499, 560.629796091, - 565.539414414, 573.519179336, 579.279608243, 593.721585269, 617.664092789, - 633.222311967, 647.328789954, 664.752638889, 676.312184343, 686.282976827, - 694.514037433, 701.561363636, 706.037895257, 707.082375776, 718.680990783, - 732.641705069, 751.482142857, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(1.653), - etaMin = cms.double(1.479), + etaMin = cms.double(1.131), l1tCalibrationFactors = cms.vdouble( - 1.47510233492, 1.47510233492, 1.47510233492, 1.47510233492, 1.47510233492, - 1.47510233492, 1.47510233492, 1.47510233492, 1.47510233492, 1.4610643606, - 1.44666801713, 1.43428469166, 1.42010685754, 1.40617546755, 1.39445133437, - 1.38279251817, 1.37051441405, 1.36518321339, 1.35292577477, 1.34325721725, - 1.33655416596, 1.32866101799, 1.3220675042, 1.31700973337, 1.32394181408, - 1.31922131925, 1.31758491373, 1.31353767077, 1.31168591849, 1.30731143759, - 1.30423718122, 1.30149639051, 1.29910753795, 1.29613194393, 1.2927432706, - 1.28816631146, 1.28729627477, 1.28216478956, 1.2805202569, 1.27893402302, - 1.2744708607, 1.27238944788, 1.26682870797, 1.26265655511, 1.26160288568, - 1.25949842198, 1.25649396459, 1.25187762696, 1.24938619475, 1.24629312412, - 1.24240410057, 1.23941775171, 1.23332097252, 1.22931737485, 1.22740630336, - 1.22448901312, 1.22336345681, 1.21794711245, 1.24837929725, 1.24724969226, - 1.24643035218, 1.24587397529, 1.24553440169, 1.2443805474, 1.24056481789, - 1.23964490051, 1.2359960211, 1.234864924, 1.23473710254, 1.23246130069, - 1.23096671336, 1.22875003041, 1.2275003914, 1.22712168234, 1.22588206032, - 1.22426235306, 1.22396540417, 1.21853310822, 1.21755510256, 1.21437460675, - 1.21412832391, 1.21226853491, 1.20945758693, 1.20463090002, 1.1985416616, - 1.18959323554, 1.17883388187, 1.17062181435, 1.15988282459, 1.15380357774, - 1.1471725546, 1.13240499119, 1.12557546067, 1.11793584977, 1.10806682041, - 1.09229438152, 1.09004753375, 1.08112380778, 1.07481457592, 1.06792352051, - 1.05866880708, 1.0542749938, 1.0450927737, 1.03277032939, 1.02765454892, - 1.02258374097, 1.019559042, 1.01832348416, 0.984947954336, 0.976379953438, - 0.974273595928, 0.965285475352, 0.961772951972, 0.96047444904, 0.952738008558, - 0.946904700595, 0.940821826013 + 1.40630295592, 1.40630295592, 1.40630295592, 1.3451455964, 1.26173230426, + 1.19825744521, 1.16239000556, 1.15460411542, 1.11317911814, 1.10876504365, + 1.10362794273, 1.09894571801, 1.09461826627, 1.08895294806, 1.08521989237, + 1.07836011776, 1.06893763358, 1.06054325313, 1.08532676037, 1.09042100065, + 1.09208466173, 1.09391071074, 1.09680712368, 1.09909581139, 1.10478318931, + 1.10569948748, 1.11027935157, 1.11505396558, 1.11542681834, 1.12458187837, + 1.12799428451, 1.13085478987 ), l1tPtBins = cms.vdouble( - -float('inf'), 11.9520026903, 13.3017694508, 15.1455230338, 17.2620108043, - 19.8515755233, 22.6298799464, 25.4341803806, 28.3835571385, 31.3933508904, - 34.3708730432, 37.2671754532, 40.2882500762, 43.6546314404, 46.9043803573, - 50.0569376737, 53.5081905296, 56.1830571229, 59.1027962522, 62.9871953228, - 66.1652442343, 69.3120024326, 72.7583064266, 75.871356138, 78.7010134986, - 82.6003185278, 85.9846784178, 89.0106047154, 92.1511798088, 95.4659736083, - 99.4316182254, 102.527500023, 105.25847864, 108.114464552, 111.502746572, - 115.743581819, 118.643516255, 121.838675669, 125.446170173, 127.166202908, - 130.386850195, 133.871126556, 137.939743927, 143.121453578, 145.903637092, - 147.585000415, 150.304946722, 154.362193428, 158.146309873, 161.119451872, - 164.836659664, 168.497049689, 173.332830113, 178.710185185, 181.859104938, - 184.429683819, 186.582061069, 190.064913561, 196.659681373, 201.580577957, - 203.667790601, 205.141107571, 206.100621118, 207.7, 213.022150072, - 218.093766614, 222.986695906, 228.105787037, 229.45401936, 232.028167311, - 236.066046099, 240.040611814, 243.752851398, 245.496722342, 247.229865642, - 250.29204955, 252.34468254, 258.480387668, 265.345467033, 269.798992674, - 273.468883547, 275.724370292, 280.7264719, 288.905957496, 300.596311278, - 316.700820289, 337.806765081, 358.124110489, 378.419647273, 396.431050803, - 410.043048728, 432.959754335, 456.089050388, 471.584702562, 490.335490303, - 517.796088129, 537.09375, 549.056818182, 565.370475589, 579.507254968, - 596.798482618, 611.415301724, 625.954484463, 648.984793603, 667.660170251, - 678.569444444, 687.239285714, 691.801785714, 728.868351064, 773.787558381, - 785.219207317, 797.10078125, 810.48828125, 815.640625, 825.316550926, - 839.849002849, 852.610576923, float('inf') + -float('inf'), 15.7808242842, 22.8598536893, 31.1328897878, 39.9581424851, + 49.410406772, 59.3070027653, 68.7280465817, 78.7196211917, 88.7819701311, + 98.5388212366, 108.569596929, 117.773288398, 127.981243371, 137.582002524, + 148.402939584, 165.035821694, 183.236355957, 206.750527794, 251.111311387, + 290.141534392, 310.296336207, 337.570889778, 367.517410714, 413.583134921, + 451.722630719, 483.465686275, 537.492424242, 567.221590909, 622.25, + 694.833333333, 731.0625, float('inf') ) ), cms.PSet( etaMax = cms.double(1.83), - etaMin = cms.double(1.653), - l1tCalibrationFactors = cms.vdouble( - 1.33049881625, 1.33049881625, 1.33049881625, 1.33049881625, 1.33049881625, - 1.33049881625, 1.33049881625, 1.33049881625, 1.31669422606, 1.29984566417, - 1.28831750594, 1.27206618286, 1.26175402093, 1.25022535161, 1.24448120045, - 1.23544818898, 1.23014212283, 1.22521081056, 1.22185223127, 1.22023847148, - 1.22004739542, 1.22200944331, 1.21023056241, 1.20867763267, 1.20712846626, - 1.2059863879, 1.20431406313, 1.20202212, 1.20064986431, 1.19941356649, - 1.19858518712, 1.19742660667, 1.1949860383, 1.19348175521, 1.19265655738, - 1.1911473882, 1.18962343872, 1.18774638031, 1.18626995789, 1.18420073928, - 1.18206241557, 1.18196490317, 1.18097507924, 1.17792986136, 1.17673435841, - 1.17653207534, 1.17496333267, 1.17096343417, 1.16977652272, 1.16947704111, - 1.16784294341, 1.16587442933, 1.16405773995, 1.16400239434, 1.16254269381, - 1.16252492005, 1.16166579308, 1.16003646939, 1.15876432336, 1.15741507548, - 1.15723775457, 1.15543741864, 1.15342598582, 1.15323916802, 1.15093617585, - 1.14995636309, 1.14991128176, 1.14804616599, 1.14676976413, 1.14528704825, - 1.14283644118, 1.14171061787, 1.14131838019, 1.14044577632, 1.13600962614, - 1.13592662429, 1.13498628758, 1.13452687172, 1.13372080526, 1.13293905158, - 1.13250566094, 1.12464538359, 1.12280554603, 1.12017353199, 1.11708777477, - 1.10827310225, 1.10270091176, 1.0945794585, 1.08974341302, 1.07924111342, - 1.07165107426, 1.06705262412, 1.05658393901, 1.05350745525, 1.0410369918, - 1.03824422355, 1.03674561618, 1.03470551006, 1.02062969788, 1.00923138262, - 1.00111680727, 0.99545047553, 0.993301194787, 0.980082984491, 0.978647303549, - 0.965813606339, 0.963258808111, 0.957559232861, 0.955293441368, 0.947836750142, - 0.946217207546, 0.943019649087, 0.935849869836, 0.935610273169, 0.929797537225, - 0.916832136078, 0.916266661888 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 12.7788766789, 14.4351898824, 16.5278531327, 19.0137931992, - 22.0681370062, 25.0720296167, 27.8529044087, 31.0167926884, 34.5850953632, - 37.7735513379, 41.2714077045, 44.9397579323, 48.4339717156, 51.5134219936, - 54.7022573757, 58.2903782147, 61.6456991131, 65.3655250891, 69.0603949477, - 72.0952646025, 75.8921881776, 79.3974791654, 82.1470948449, 85.7802504422, - 88.9322194751, 92.228430802, 96.8713565527, 101.162843269, 104.217964812, - 106.636101814, 108.963216713, 113.178517282, 117.798702614, 120.526976089, - 123.260972126, 126.813341723, 130.796580869, 134.724156627, 138.876789216, - 143.804636438, 146.423233696, 147.696715198, 152.422530911, 157.389236606, - 159.026314844, 161.100529101, 167.622486772, 173.697246127, 175.438100374, - 177.702696352, 181.922052728, 186.355259324, 188.547774983, 190.32218754, - 192.05259618, 197.343524531, 204.861505682, 208.864470109, 212.481032609, - 214.58713785, 217.315579208, 222.574422541, 225.607202447, 229.042227362, - 233.571294559, 234.985272639, 237.62064429, 241.954786825, 245.761357725, - 251.187901303, 256.122063968, 258.216431557, 259.961449169, 267.285583368, - 273.520356288, 274.932188309, 276.863333644, 278.609235283, 280.799844927, - 282.476298564, 293.918519631, 307.301121795, 313.470637464, 321.359065461, - 337.777295379, 357.625891595, 376.518099388, 394.39469697, 415.555989583, - 440.516783767, 457.332430269, 478.119552752, 496.806919643, 518.256006722, - 539.313670412, 545.234195402, 550.116322595, 572.350381161, 607.495337302, - 634.415972222, 653.428571429, 664.211251167, 685.412754525, 705.629751789, - 725.31626197, 746.546743697, 757.934752747, 768.924038462, 782.3375, - 794.859375, 801.505208333, 815.808333333, 826.030555556, 834.380555556, - 860.2875, 878.955147059, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(1.93), - etaMin = cms.double(1.83), - l1tCalibrationFactors = cms.vdouble( - 1.26344020365, 1.26344020365, 1.26344020365, 1.26344020365, 1.26344020365, - 1.26344020365, 1.26344020365, 1.2594177509, 1.25024812783, 1.24257955651, - 1.23460877998, 1.22689840022, 1.21927757925, 1.21265488275, 1.20557178744, - 1.20174679788, 1.19654003623, 1.19235906229, 1.18833919988, 1.18423598421, - 1.18248510015, 1.18498117639, 1.18352790424, 1.18144657707, 1.17661686818, - 1.1765750739, 1.17151719886, 1.17090460227, 1.16808185289, 1.16334134477, - 1.16221061551, 1.15972417328, 1.15524883242, 1.15467922536, 1.15437781148, - 1.14938817625, 1.14838488731, 1.14532947934, 1.1392096584, 1.13892990227, - 1.13689064678, 1.13591199573, 1.13361506216, 1.13235799184, 1.12453112537, - 1.12353768589, 1.12340029796, 1.11834798253, 1.11415617971, 1.11202444858, - 1.11098817404, 1.11061422522, 1.10500019468, 1.10106129638, 1.0570645963, - 1.05674843271, 1.05655028722, 1.05652919587, 1.05550650582, 1.05546035549, - 1.05542095684, 1.05524242507, 1.05460820421, 1.05450067037, 1.05416171584, - 1.05369091407, 1.05366974164, 1.05304299788, 1.05252325406, 1.05242940461, - 1.05226646078, 1.05205766435, 1.05195399297, 1.05156885848, 1.0513176496, - 1.05086320472, 1.05074695298, 1.05073829611, 1.05042190785, 1.04926402517, - 1.04905737894, 1.04891256396, 1.04885123511, 1.04783944462, 1.04603957355, - 1.04498728955, 1.0441774476, 1.04290300185, 1.04080891766, 1.03794610759, - 1.03738392589, 1.03617570363, 1.03473564365, 1.03230390795, 1.03224663935, - 1.03072766404, 1.0279685602, 1.02730218418, 1.0239743365, 1.02360043749, - 1.0235627012, 1.02316035177, 1.02183147754, 1.02103587202, 1.02087206722, - 1.02012591455, 1.01776880707, 1.01688594279, 1.01667002772, 1.01607314711, - 1.01546355034, 1.01250081665, 1.01177249255, 1.01009529511, 1.00867950913, - 1.00535732355 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 13.4970175928, 15.1917668493, 17.5598120604, 20.0549383771, - 22.761185412, 25.9356197296, 29.5710629017, 33.1286806262, 36.3295437527, - 39.4893787898, 42.8608536262, 46.4031905244, 49.9559825377, 53.7094286808, - 56.936193824, 59.9200888492, 63.3132010844, 66.6765207646, 70.5592973062, - 73.7585546318, 78.1130632902, 82.4061178903, 84.8649824691, 89.6726849112, - 93.0615744275, 96.6091890563, 100.553885637, 102.943704044, 108.205128122, - 112.289488565, 114.805794958, 119.648799866, 123.158347238, 123.764278017, - 127.445027112, 131.614039681, 134.437495801, 140.820297168, 145.272200183, - 146.885434107, 148.984858352, 151.263537847, 153.735901327, 160.055194805, - 166.191091954, 166.977758621, 170.588005952, 177.01873059, 181.41773377, - 183.621575342, 184.602605426, 188.768178105, 195.413728632, 199.786828737, - 203.53490566, 206.975568182, 208.442234848, 215.425, 222.575406504, - 223.147718332, 224.605645161, 230.042857143, 235.005102041, 237.99205259, - 243.409219457, 246.700464396, 251.03494152, 258.70479798, 262.809659091, - 264.527573529, 267.014468691, 269.10483871, 272.374887993, 276.631944444, - 281.352678571, 285.170566502, 286.006189213, 288.180699931, 298.043385491, - 307.171910755, 309.523141655, 310.902217742, 318.08125, 336.890909091, - 355.971464646, 368.42885101, 382.372471279, 404.907509158, 438.068502825, - 460.981263242, 472.825041118, 490.541713326, 516.443535188, 533.09465812, - 543.639529915, 572.259336678, 595.175362319, 621.896212121, 646.660427807, - 649.414215686, 652.358333333, 663.94, 678.1525, 684.570833333, - 690.658333333, 711.41875, 733.09375, 740.444444444, 745.881944444, - 753.953125, 777.8515625, 802.544270833, 818.636904762, 839.328571429, - 871.025, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(2.043), - etaMin = cms.double(1.93), + etaMin = cms.double(1.479), l1tCalibrationFactors = cms.vdouble( - 1.21629221754, 1.21629221754, 1.21629221754, 1.21629221754, 1.21629221754, - 1.21629221754, 1.21629221754, 1.2143105786, 1.20705887946, 1.20172327443, - 1.19635501501, 1.18935438692, 1.18357975306, 1.17883483547, 1.17253244835, - 1.16676369422, 1.16146408844, 1.15476931936, 1.14861458752, 1.14383587886, - 1.13613912201, 1.15219667932, 1.14906219403, 1.14808161605, 1.14459785262, - 1.14269095066, 1.13997101838, 1.13619937599, 1.13345316689, 1.13104833952, - 1.12931087162, 1.12605458004, 1.12332075961, 1.12214084987, 1.11977644024, - 1.11623567986, 1.1122458245, 1.1083505494, 1.10797285096, 1.1062306348, - 1.10265809398, 1.10229188147, 1.09738697231, 1.0973031017, 1.09328160834, - 1.09069771195, 1.0879352071, 1.08518609065, 1.08159568534, 1.0804492949, - 1.07870449836, 1.07588358785, 1.07557418398, 1.07132896072, 1.06936132658, - 1.06924237699, 1.06898155499, 1.06721691315, 1.06713176616, 1.06488611764, - 1.06431281061, 1.06412410989, 1.06233512154, 1.06192478599, 1.06145249365, - 1.05929718716, 1.05870708468, 1.05842616938, 1.0572390605, 1.05617065365, - 1.05611813058, 1.0552591158, 1.0534771748, 1.05302603505, 1.05253372113, - 1.05190835065, 1.05121994984, 1.0510965109, 1.04964431982, 1.04827293909, - 1.04609786683, 1.04420242601, 1.04403524786, 1.04199171851, 1.03570032676, - 1.03170060202, 1.02471475781, 1.0220533428, 1.01625398917, 1.01232260497, - 1.00789998134, 1.005889945, 0.996025162737, 0.993256242866, 0.987535132918, - 0.984948957557, 0.977747868812, 0.974817880234, 0.971037822426, 0.968447238948, - 0.967125997203, 0.964218737777, 0.953609602752, 0.951350786713, 0.947089571165, - 0.946104023103, 0.944511162439, 0.934743979786, 0.933976798255, 0.933636687551, - 0.933361313828, 0.924631483686, 0.92374807926, 0.915007896723, 0.908342886395, - 0.905162078334 + 1.7217035487, 1.7217035487, 1.7217035487, 1.7217035487, 1.68988534586, + 1.63791921552, 1.59185473537, 1.54971405338, 1.51154883337, 1.47823543692, + 1.46172800374, 1.43645114385, 1.43046780928, 1.42226174585, 1.41623186647, + 1.40561299065, 1.39363735903, 1.37464296082, 1.35286001653, 1.26158343404, + 1.22056556893, 1.18715984647, 1.13819685131, 1.10934113225, 1.07919505312, + 1.02868299603, 0.979047219899, 0.898684534732, 0.891076670235, 0.797123236841, + 0.780947291941, 0.735669418772 ), l1tPtBins = cms.vdouble( - -float('inf'), 13.7095810759, 15.4916612561, 17.9731744352, 20.5838742792, - 23.4100000067, 26.6783243919, 29.7833794964, 33.3573519293, 37.1343601956, - 40.3573168403, 44.0942976559, 47.9659992073, 51.1645381429, 54.5349591352, - 58.2287070452, 61.6267983551, 65.3223567751, 69.2944890498, 72.6855845329, - 76.5706641213, 80.4371088472, 84.1729552063, 87.1526553819, 90.3852664018, - 94.288624754, 97.6388961585, 102.339418339, 107.058967456, 110.78881151, - 113.788230258, 117.404190704, 121.741605862, 124.575521573, 127.141948466, - 131.417857475, 136.870744963, 142.580335091, 145.674377436, 147.209398766, - 151.05779216, 153.909827044, 157.726624294, 161.338978945, 164.311655893, - 169.094591097, 172.965897963, 176.956839992, 181.547261296, 184.977155366, - 187.070651816, 190.376661279, 192.643308886, 195.941295421, 204.738489298, - 210.718209119, 211.537057681, 215.904283217, 219.892725202, 224.918294881, - 230.996416056, 232.639427218, 236.903642654, 241.645738408, 243.548825992, - 249.21435132, 255.133894231, 257.011948529, 260.177244582, 265.040498975, - 267.457404009, 269.422826087, 275.117151163, 279.932032115, 281.966269841, - 284.376177024, 287.208879045, 288.959336007, 292.356647537, 298.444722111, - 306.091444672, 314.868125, 319.315462963, 324.082103588, 342.05353289, - 364.242833824, 387.929485862, 408.730527062, 426.973303897, 447.95433838, - 465.966921736, 479.836770348, 505.44078754, 532.681079581, 550.986948217, - 568.898790323, 590.001704545, 611.845935315, 626.313873626, 640.05, - 648.48452381, 657.601851852, 686.74537037, 714.490740741, 728.548976608, - 739.861842105, 745.421305668, 769.915384615, 792.629166667, 795.016666667, - 796.34375, 815.760416667, 836.488095238, 857.238095238, 890.454166667, - 911.683333333, float('inf') + -float('inf'), 13.333575988, 18.4571028394, 24.1116921172, 30.5374906258, + 37.5605591469, 44.6732556617, 51.969510234, 59.7448700477, 68.2252386063, + 75.5169980339, 83.6148776707, 92.2747240616, 100.355850244, 108.463484563, + 117.945260433, 130.813252843, 148.451261093, 171.674716389, 212.783964929, + 264.625978134, 306.609011628, 353.073966408, 396.972222222, 430.255681818, + 475.755681818, 532.25, 605.583333333, 655.208333333, 712.5, + 774.625, 809.291666667, float('inf') ) ), cms.PSet( etaMax = cms.double(2.172), - etaMin = cms.double(2.043), - l1tCalibrationFactors = cms.vdouble( - 1.24463108809, 1.24463108809, 1.24463108809, 1.24463108809, 1.24463108809, - 1.24463108809, 1.24463108809, 1.22870705887, 1.19836644148, 1.18057435385, - 1.16475611868, 1.14656045785, 1.13630392181, 1.12907309301, 1.12458941546, - 1.12396919862, 1.1266691842, 1.1312951597, 1.13754265674, 1.15717137943, - 1.10016929711, 1.09836792879, 1.09706087373, 1.09576962823, 1.09437951599, - 1.09168003074, 1.08991624307, 1.08969627714, 1.08696432458, 1.08673589039, - 1.08406597119, 1.08255042879, 1.07947490575, 1.0788668256, 1.07782375909, - 1.07550979348, 1.0749747491, 1.07333347682, 1.07178181655, 1.06993614183, - 1.06669791954, 1.06650550898, 1.06287391246, 1.06281120026, 1.06127587052, - 1.05980687707, 1.05949187174, 1.05578275324, 1.05274463618, 1.05182571746, - 1.04931367066, 1.04874893864, 1.05641180597, 1.05606383878, 1.05578640694, - 1.05328201855, 1.05119788827, 1.04979736321, 1.04954378139, 1.04765914049, - 1.04733102858, 1.04453346835, 1.04293143151, 1.04200055639, 1.04163370047, - 1.03601225755, 1.03572772664, 1.03536402867, 1.03450353855, 1.03300397956, - 1.03271844062, 1.03133148602, 1.02824720508, 1.0255034533, 1.02501438762, - 1.02406097142, 1.02318864953, 1.02308413253, 1.0229264435, 1.02153080396, - 1.02093884026, 1.01829648613, 1.01377147911, 1.00893009266, 1.00026908515, - 0.990933236615, 0.985829663806, 0.985726981538, 0.971780898171, 0.968360565127, - 0.966542691472, 0.953970559056, 0.95293612294, 0.946253207331, 0.936055411119, - 0.935335159677, 0.928640241117, 0.922416983962, 0.900616319824, 0.900259767754, - 0.89668374879, 0.89500810959, 0.894758911965, 0.886314836132, 0.882442768547, - 0.876919799248, 0.876060497094, 0.8621398022, 0.852372401049, 0.849862522675, - 0.844180387181, 0.799367779851, 0.791762955788 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 13.7820945333, 15.5998481907, 18.0388646745, 20.8537251841, - 23.7351968264, 27.1010552292, 30.5665269509, 34.3658060316, 38.1699828726, - 41.3104960011, 45.1926203129, 49.2128167802, 52.6824711873, 56.3735085314, - 60.2779866824, 63.9695042596, 67.1696331331, 69.9876168562, 74.2520342153, - 79.0837779271, 83.0918300233, 86.6840545663, 89.6867597631, 92.7854493351, - 97.5115598722, 102.669505424, 104.962014358, 108.373375284, 111.794522495, - 115.143981347, 119.98087647, 125.286504425, 129.543430905, 131.451565295, - 135.331092539, 138.62352808, 141.138570972, 144.82845787, 148.754560811, - 154.62972561, 158.594308943, 163.013492063, 167.282790309, 169.129554656, - 172.601476648, 174.663140528, 179.313586957, 187.11097561, 191.683892276, - 195.648860063, 199.204514825, 203.202156334, 207.05334681, 207.963095238, - 212.009722222, 218.684496997, 223.753516271, 226.159693878, 229.270099668, - 232.488922062, 237.035739687, 243.435696095, 247.120244003, 249.008012821, - 257.719004065, 266.310239697, 267.253197998, 269.033986175, 272.467075893, - 275.063802083, 277.49672619, 284.000892857, 292.47875, 297.181428571, - 299.279761905, 301.935606061, 303.356583072, 303.738005997, 305.997584541, - 308.888888889, 313.59375, 324.019886364, 337.644886364, 357.286397059, - 383.465861345, 404.470436508, 412.043813131, 432.480113636, 457.742497086, - 465.362352737, 486.295045045, 506.088095238, 517.314285714, 541.87012987, - 557.752272727, 568.538888889, 587.330555556, 628.096078431, 660.327488688, - 666.048076923, 673.6875, 676.4875, 689.133333333, 707.049242424, - 720.715909091, 730.0, 751.5, 785.958333333, 803.817708333, - 815.734375, 889.1875, 965.4375, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(2.322), - etaMin = cms.double(2.172), + etaMin = cms.double(1.83), l1tCalibrationFactors = cms.vdouble( - 1.28801427048, 1.28801427048, 1.28801427048, 1.28801427048, 1.28801427048, - 1.28801427048, 1.28801427048, 1.27907573544, 1.25762676468, 1.23203051181, - 1.2127674306, 1.19077164733, 1.17543776249, 1.16511470979, 1.15158170141, - 1.14016563295, 1.13350074649, 1.12895447486, 1.12701259705, 1.12771778387, - 1.13005719625, 1.11063374411, 1.10758429943, 1.10533186553, 1.10085120985, - 1.10059366031, 1.09686271227, 1.09335974897, 1.09053459072, 1.08737330282, - 1.0841616756, 1.08169734143, 1.08108045671, 1.07763696162, 1.07538006669, - 1.06882658148, 1.06625547439, 1.06548471888, 1.06531775586, 1.06230384419, - 1.05825281932, 1.05453507243, 1.04970622179, 1.04918779307, 1.04646655271, - 1.04313607714, 1.04281858988, 1.03580641861, 1.03161769069, 1.03031476389, - 1.02733028469, 1.04451881331, 1.04358016577, 1.04068114378, 1.03785227024, - 1.03643816672, 1.0357736928, 1.03492993529, 1.03456417436, 1.03136179253, - 1.03055081273, 1.024529249, 1.02422733697, 1.02334146768, 1.02241728615, - 1.02059348669, 1.01985018062, 1.01666009697, 1.0130438797, 1.01165916838, - 1.01140500027, 1.01114694986, 1.00899659255, 1.00897349765, 1.00875653846, - 1.00517644592, 1.00109640283, 1.00037768928, 1.00025619424, 0.99956287175, - 0.996551957183, 0.988475727802, 0.986121623075, 0.985031919886, 0.974596613229, - 0.965439918879, 0.957320195213, 0.953186488337, 0.949892454978, 0.926661255415, - 0.920528165625, 0.915875457067, 0.899356341318, 0.896217293885, 0.888738729006, - 0.886243597827, 0.8711147297, 0.86995326756, 0.862406839919, 0.854984830236, - 0.846246861389, 0.844351880193, 0.840477696416, 0.831379447193, 0.822164808693, - 0.820032954848, 0.813084690464, 0.808452514208, 0.79271364261, 0.781396393802, - 0.772921616788, 0.767436698994, 0.759709386784, 0.732126882713 + 1.4936926105, 1.4936926105, 1.4936926105, 1.4936926105, 1.46485100129, + 1.43305929866, 1.40381441593, 1.3729601552, 1.34123460884, 1.32284737093, + 1.27511162571, 1.26798560095, 1.26164735469, 1.25626695799, 1.24848902406, + 1.23877770715, 1.22404536549, 1.20885962123, 1.27286033084, 1.12054466533, + 0.913202215731, 0.772663996883, 0.727095419562, 0.301220472331, 0.165219962792, + 0.0626367213111, 1, 1 ), l1tPtBins = cms.vdouble( - -float('inf'), 13.2086215379, 15.1534633583, 17.649581287, 20.148553298, - 22.9153920468, 25.7015069204, 29.060016827, 32.6923997679, 36.1610750872, - 39.7706769991, 43.5376631987, 47.3688383738, 50.3852546185, 53.7172554454, - 57.9534260164, 61.9605131723, 65.6678061224, 69.6307046732, 73.3961583546, - 76.6034311572, 80.0068013724, 84.0792280583, 87.8363678805, 92.6077255375, - 95.9654221045, 98.7918435032, 103.918105058, 108.402484908, 112.644738829, - 117.160861331, 121.183092365, 123.366576954, 126.243937206, 130.283479421, - 136.526894756, 142.992974381, 145.361162346, 146.025670141, 148.279775128, - 153.286293854, 158.791580579, 164.848068182, 168.637380952, 170.933150183, - 175.221657081, 177.806760866, 183.000873016, 190.938313253, 194.82993663, - 197.868177431, 201.573971636, 204.279335391, 208.835980308, 215.636979167, - 220.674864719, 223.142857143, 224.933651026, 226.369768963, 230.606392106, - 235.371644491, 243.484243697, 250.992402882, 252.402711324, 254.551869501, - 257.814676139, 260.862720875, 265.533018868, 273.614458991, 279.552295918, - 281.498214286, 282.106395349, 284.966010733, 287.546652422, 287.831679894, - 292.340097403, 301.435335498, 307.133124196, 308.130743243, 309.098214286, - 313.496428571, 326.660714286, 339.045138889, 343.134133454, 356.818317873, - 380.080819035, 400.593919969, 415.142992424, 423.962296577, 455.456948983, - 490.32254617, 503.129030127, 528.267329545, 551.608388158, 564.215176951, - 576.057413793, 596.983214286, 616.325487013, 626.664772727, 644.4375, - 663.625, 676.25, 683.1, 698.502777778, 720.246527778, - 733.71875, 744.5, 758.25, 782.4375, 814.5625, - 838.0625, 854.6375, 870.325, 912.25, float('inf') + -float('inf'), 13.9285565669, 19.4784943976, 26.0657472216, 33.348104504, + 41.2050778872, 49.214573875, 57.4805182505, 66.5342548469, 74.11237099, + 81.9515569476, 91.5619071823, 100.322330841, 107.946975123, 116.508341035, + 127.887586641, 143.791663771, 163.257634657, 190.003392571, 230.031554019, + 284.725347222, 337.628125, 365.9296875, 437.622869318, 523.068181818, + 559.35, 594.808333333, 633.5, float('inf') ) ), cms.PSet( etaMax = cms.double(2.5), - etaMin = cms.double(2.322), - l1tCalibrationFactors = cms.vdouble( - 1.49099272974, 1.49099272974, 1.49099272974, 1.49099272974, 1.49099272974, - 1.49099272974, 1.49099272974, 1.49099272974, 1.49099272974, 1.47147038177, - 1.44110402098, 1.40753020227, 1.37956170944, 1.34154928405, 1.32662591014, - 1.29145531966, 1.27013765447, 1.25161491993, 1.2366175646, 1.22505436234, - 1.20823932564, 1.20809834449, 1.2002598421, 1.20028932445, 1.17154819236, - 1.16715932959, 1.16186770819, 1.16148283057, 1.15335519391, 1.1488697101, - 1.14767746297, 1.13827946341, 1.1358739365, 1.12500903936, 1.12381049159, - 1.11606740787, 1.11328525068, 1.10859721749, 1.09922102489, 1.09821077013, - 1.09052169667, 1.08488302349, 1.08153352107, 1.07328228308, 1.07188989833, - 1.06894515671, 1.06465122204, 1.06062459224, 1.05449740609, 1.04338878875, - 1.01675416711, 1.01672417914, 1.01634370681, 1.01585049968, 1.01513546771, - 1.01298973033, 1.01217730218, 1.01216542747, 1.01018592681, 1.0100395536, - 1.01002803705, 1.00914742382, 1.00887714281, 1.00721832199, 1.00671129005, - 1.00655810927, 1.00627959876, 1.00588744428, 1.00460201118, 1.00384341089, - 1.00299029948, 1.00209052381, 1.00091136827, 1.00001173513, 0.999756820516, - 0.999278584114, 0.99922058166, 0.996788735278, 0.996659815284, 0.996096791635, - 0.995773572724, 0.995354250529, 0.995118203853, 0.993301997984, 0.989036584866, - 0.988381013983, 0.983025372315, 0.981083152224, 0.976011511955, 0.972971480757, - 0.970258549606, 0.967103117391, 0.964576096961, 0.956678867029, 0.954580550515, - 0.950868086735, 0.94471770796, 0.943730423923, 0.934853199103, 0.932163311311, - 0.930502635614, 0.928838528386, 0.927952803766, 0.916409614493, 0.911182186537, - 0.908097147087, 0.906061878006, 0.904069456695, 0.880588878663 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 11.7109508065, 13.1353167235, 14.9562968923, 16.9790007769, - 19.2055898521, 21.2130593084, 23.6785649226, 27.0011527762, 30.1557544543, - 33.0301927004, 35.9993524621, 39.0504868894, 42.6484814856, 45.7286654343, - 49.0779288075, 53.2083314286, 56.6240315145, 59.9624119134, 63.0960035212, - 67.687040583, 70.8089905193, 74.6588425168, 78.9967962298, 82.8893453066, - 88.1025978687, 92.1714100297, 94.5573039396, 98.1352057253, 103.436636624, - 105.823048321, 110.274243502, 115.235393294, 120.813095997, 125.883492316, - 129.641756703, 134.065629252, 137.205431034, 143.116777188, 147.482313307, - 151.13873501, 156.740531015, 160.518358396, 165.394275013, 169.447593917, - 171.270535021, 174.313028925, 177.810252132, 182.078010753, 189.322405303, - 197.010106452, 200.116219668, 201.313657407, 203.862446581, 207.387248168, - 215.732983954, 224.362854084, 226.767596676, 232.577045329, 238.778867102, - 239.239479638, 241.842094017, 245.199603175, 250.827380952, 257.145833333, - 259.071875, 260.33125, 262.287784091, 267.181818182, 273.144886364, - 277.846740431, 282.960446085, 289.025321816, 295.089781746, 298.457949309, - 300.596774194, 302.161146313, 309.424793956, 316.89532967, 318.913940092, - 321.499379653, 323.665598291, 325.577508961, 331.564554901, 349.306490385, - 363.6625, 381.199038462, 402.489124668, 422.950692268, 446.614909339, - 463.398053279, 480.517857143, 497.095302795, 527.506017081, 556.666071429, - 573.617887931, 602.390804598, 623.213541667, 651.991319444, 685.736111111, - 698.428030303, 708.127435065, 715.566071429, 751.825, 800.75, - 825.0, 839.9375, 851.6875, 926.0, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(2.964), - etaMin = cms.double(2.5), - l1tCalibrationFactors = cms.vdouble( - 1.440149383, 1.440149383, 1.440149383, 1.440149383, 1.440149383, - 1.440149383, 1.440149383, 1.440149383, 1.41823798726, 1.35779202704, - 1.29604078279, 1.2331235664, 1.18467513743, 1.13662522351, 1.10424412126, - 1.07837858706, 1.05044035802, 1.04305528311, 1.0340586478, 1.00199436988, - 0.996831578408, 0.992117421642, 0.988148133039, 0.984926887957, 0.981877067499, - 0.978707515289, 0.972062429005, 0.966286792195, 0.962735311068, 0.95862885791, - 0.954502608232, 0.950423801308, 0.947238356455, 0.942280737153, 0.938495013502, - 0.935311137492, 0.930922164099, 0.926299938098, 0.922249224325, 0.921813179341, - 0.913624959749, 0.906364289469, 0.900282833844, 0.894782452879, 0.894475540131, - 0.921298447858, 0.920060749826, 0.919642016454, 0.918764943707, 0.915754164947, - 0.914027770112, 0.913999384828, 0.913560277424, 0.913085606477, 0.91203015986, - 0.908571622169, 0.908257851694, 0.907433350595, 0.907344653677, 0.90484903435, - 0.904759606357, 0.902656738308, 0.900464218778, 0.898745527548, 0.898405801686, - 0.897649208068, 0.896626034151, 0.895132171113, 0.895039360638, 0.894668072035, - 0.891575466112, 0.89133534261, 0.890764181016, 0.889023303745, 0.888628513297, - 0.88591462355, 0.883324458751, 0.882629359352, 0.881185912773, 0.880459117431, - 0.876243057514, 0.875178000699, 0.87464703624, 0.873006971519, 0.866733439423, - 0.859896825026, 0.855088048182, 0.851019815143, 0.844211345078, 0.835743265866, - 0.833130191023, 0.830973313737, 0.821796437249, 0.819127304091, 0.816851492601, - 0.815531687779, 0.789740765722, 0.788751364403, 0.782537924121, 0.779444659838, - 0.778195111933, 0.762997907676, 0.762449119745, 0.758713140365 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 14.4814106025, 15.0665800452, 15.9944547311, 17.6513154301, - 19.7313910596, 22.2415956293, 25.2338482897, 28.9983965864, 33.1945877234, - 37.2192967935, 41.7965852462, 46.4087212029, 51.1009737924, 55.6907222438, - 59.7792537073, 64.8784785583, 69.1828569435, 74.2756704848, 79.3854559008, - 83.4870901039, 88.9448473521, 93.7431044401, 97.7164154653, 101.18165114, - 104.618322613, 110.041649037, 116.905033337, 122.058967962, 126.290552995, - 130.83974091, 135.3736522, 139.38769802, 143.887353817, 148.718708827, - 152.569937177, 156.754506409, 161.733872263, 166.526324219, 169.005596108, - 173.771151354, 182.307825701, 189.6803544, 196.080190772, 199.289157609, - 200.278288043, 203.541100543, 206.810974482, 209.36895705, 217.043759812, - 226.395164547, 229.859183499, 230.782036177, 232.585877863, 235.606402305, - 244.517220831, 251.963935574, 254.2109375, 256.013633578, 261.115196078, - 266.218201754, 270.545897833, 279.025196078, 286.746111111, 290.80952381, - 292.973710317, 296.48705561, 301.45580561, 304.587974173, 305.504127703, - 312.342019331, 318.920984848, 320.5225, 325.086574074, 329.302483165, - 335.439164905, 345.90961945, 352.394886364, 356.616477273, 360.900637472, - 370.658067542, 381.083241758, 384.23386324, 388.519577526, 404.141391941, - 430.021441202, 453.009994316, 470.533631691, 492.004758065, 522.161388889, - 544.036111111, 553.452222222, 575.825588235, 599.210171569, 608.97172619, - 616.069642857, 669.5875, 722.453125, 736.671875, 755.04375, - 763.616666667, 796.083333333, 827.166666667, 835.625, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(3.489), - etaMin = cms.double(2.964), - l1tCalibrationFactors = cms.vdouble( - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0 - ), - l1tPtBins = cms.vdouble( - -float('inf'), 25.5826843658, 24.2629824561, 21.1982915959, 19.24759157, - 21.2638970135, 22.779435911, 23.9039434399, 26.5016611824, 30.2078332673, - 33.6160387858, 37.7073720397, 42.0957302547, 52.2161530155, 80.4293131351, - 123.112789661, 167.484620234, 200.362734522, 227.533021978, 247.865403082, - 260.104100561, 259.756684492, 287.576571793, 345.295419755, 305.06330819, - 271.547743056, 295.071859903, 357.906929348, 405.463541667, 290.769345238, - 202.021428571, 212.075, 193.625, 163.625, float('inf') - ) - ), - cms.PSet( - etaMax = cms.double(4.191), - etaMin = cms.double(3.489), + etaMin = cms.double(2.172), l1tCalibrationFactors = cms.vdouble( - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0 + 1.36288541376, 1.36288541376, 1.36288541376, 1.35728228981, 1.30022440066, + 1.25938136072, 1.23301769934, 1.22642366857, 1.23558221804, 1.16540136021, + 1.16082535056, 1.15619052246, 1.15215783917, 1.146792252, 1.1411562498, + 1.13744491457, 1.12697797447, 1.11559143334, 1.06859652983, 1.03815298361, + 1.00472588913, 0.978567329549, 0.951793014325, 0.935812848708, 0.920110074644, + 0.860000530916, 0.820110419384, 0.799722140156 ), l1tPtBins = cms.vdouble( - -float('inf'), 22.6446171016, 20.5125237851, 18.9096163143, 19.6264810998, - 21.0068368313, 23.0523217726, 26.2785604184, 30.3103046044, 34.9313275194, - 39.3931844106, 43.3488875356, 48.4803086268, 59.4328197875, 82.5972291029, - 114.115285978, 141.656915733, 161.147025234, 182.762630662, 209.627475248, - 229.03719747, 227.122685185, 237.558201058, 249.011904762, 301.291666667, - 271.65625, 243.03125, 326.625, float('inf') + -float('inf'), 14.6351342446, 20.0485971642, 26.9278098497, 35.1665914695, + 43.9984688651, 53.3287953196, 62.5042389456, 71.1936448694, 80.3838909754, + 89.9515275488, 99.6235248178, 108.724992978, 118.593807156, 130.146213706, + 139.961544796, 154.849684614, 177.797305292, 204.724624754, 249.745733173, + 312.791595442, 371.607804233, 423.857142857, 466.05952381, 497.333333333, + 572.166666667, 670.875, 730.375, float('inf') ) ), cms.PSet( etaMax = cms.double(5.191), - etaMin = cms.double(4.191), + etaMin = cms.double(3), l1tCalibrationFactors = cms.vdouble( 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0 + 1.0, 1.0 ), l1tPtBins = cms.vdouble( - -float('inf'), 19.9973790323, 18.7233958626, 19.0354844999, 20.2562619616, - 21.8848170727, 24.4047538346, 27.3838689353, 30.8225281734, 34.60470791, - 39.1976611227, 43.9557705684, 47.9253810239, 57.1837291686, 77.2146849218, - 102.883983524, 131.248104371, 147.631578947, 175.0, 199.875, - float('inf') + -float('inf'), 50.3968059551, 87.5328766659, 125.735369213, 167.221300362, + 224.93359375, 214.8125, float('inf') ) ) ) diff --git a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetProducer_cfi.py b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetProducer_cfi.py index 5634d7ca0bb08..c9c91248f9343 100644 --- a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetProducer_cfi.py +++ b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetProducer_cfi.py @@ -2,7 +2,7 @@ import FWCore.ParameterSet.Config as cms from math import pi -from .Phase1L1TJets_sincosLUT_cff import sinPhi, cosPhi +from L1Trigger.L1CaloTrigger.Phase1L1TJets_sincosLUT_cff import sinPhi, cosPhi caloEtaSegmentation = cms.vdouble( -5.0, -4.917, -4.833, -4.75, -4.667, -4.583, -4.5, -4.417, -4.333, -4.25, @@ -18,7 +18,7 @@ 4.0, 4.083, 4.167, 4.25, 4.333, 4.417, 4.5, 4.583, 4.667, 4.75, 4.833, 4.917, 5.0) Phase1L1TJetProducer = cms.EDProducer('Phase1L1TJetProducer', - inputCollectionTag = cms.InputTag("l1pfCandidates", "Puppi"), + inputCollectionTag = cms.InputTag("l1ctLayer1", "Puppi"), etaBinning = caloEtaSegmentation, nBinsPhi = cms.uint32(72), phiLow = cms.double(-pi), diff --git a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetSumsProducer_cfi.py b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetSumsProducer_cfi.py index 90a9b43a51428..719fc53d4047c 100644 --- a/L1Trigger/L1CaloTrigger/python/Phase1L1TJetSumsProducer_cfi.py +++ b/L1Trigger/L1CaloTrigger/python/Phase1L1TJetSumsProducer_cfi.py @@ -1,8 +1,7 @@ -from __future__ import absolute_import import FWCore.ParameterSet.Config as cms from math import pi -from .Phase1L1TJets_sincosLUT_cff import sinPhi, cosPhi +from L1Trigger.L1CaloTrigger.Phase1L1TJets_sincosLUT_cff import sinPhi, cosPhi Phase1L1TJetSumsProducer = cms.EDProducer('Phase1L1TJetSumsProducer', inputJetCollectionTag = cms.InputTag("Phase1L1TJetCalibrator", "Phase1L1TJetFromPfCandidates"), diff --git a/L1Trigger/L1CaloTrigger/python/Phase1L1TJets_9x9trimmed_cff.py b/L1Trigger/L1CaloTrigger/python/Phase1L1TJets_9x9trimmed_cff.py index 6348fdc643d0c..caed466ccb8c1 100644 --- a/L1Trigger/L1CaloTrigger/python/Phase1L1TJets_9x9trimmed_cff.py +++ b/L1Trigger/L1CaloTrigger/python/Phase1L1TJets_9x9trimmed_cff.py @@ -2,7 +2,7 @@ from math import pi from L1Trigger.L1CaloTrigger.Phase1L1TJetProducer_cfi import Phase1L1TJetProducer -from L1Trigger.L1CaloTrigger.Phase1L1TJetCalibrator_9x9Jets_cfi import Phase1L1TJetCalibrator as Phase1L1TJetCalibrator9x9 +from L1Trigger.L1CaloTrigger.Phase1L1TJetCalibrator_9x9trimmedJets_cfi import Phase1L1TJetCalibrator as Phase1L1TJetCalibrator9x9trimmed from L1Trigger.L1CaloTrigger.Phase1L1TJetSumsProducer_cfi import Phase1L1TJetSumsProducer Phase1L1TJetProducer9x9trimmed = Phase1L1TJetProducer.clone( @@ -12,10 +12,9 @@ outputCollectionName = cms.string("UncalibratedPhase1L1TJetFromPfCandidates") ) -Phase1L1TJetCalibrator9x9trimmed = Phase1L1TJetCalibrator9x9.clone( - inputCollectionTag = cms.InputTag("Phase1L1TJetProducer9x9trimmed", "UncalibratedPhase1L1TJetFromPfCandidates", ""), - outputCollectionName = cms.string("Phase1L1TJetFromPfCandidates") - ) +Phase1L1TJetCalibrator9x9trimmed.inputCollectionTag = cms.InputTag("Phase1L1TJetProducer9x9trimmed", "UncalibratedPhase1L1TJetFromPfCandidates", "") +Phase1L1TJetCalibrator9x9trimmed.outputCollectionName = cms.string("Phase1L1TJetFromPfCandidates") + Phase1L1TJetSumsProducer9x9trimmed = Phase1L1TJetSumsProducer.clone( inputJetCollectionTag = cms.InputTag("Phase1L1TJetCalibrator9x9trimmed", "Phase1L1TJetFromPfCandidates"), @@ -25,4 +24,4 @@ Phase1L1TJetProducer9x9trimmed + Phase1L1TJetCalibrator9x9trimmed + Phase1L1TJetSumsProducer9x9trimmed -) \ No newline at end of file +) diff --git a/L1Trigger/L1CaloTrigger/python/l1EGammaEEProducer_cfi.py b/L1Trigger/L1CaloTrigger/python/l1EGammaEEProducer_cfi.py deleted file mode 100644 index 161e8e8faa27e..0000000000000 --- a/L1Trigger/L1CaloTrigger/python/l1EGammaEEProducer_cfi.py +++ /dev/null @@ -1,5 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -l1EGammaEEProducer = cms.EDProducer("L1EGammaEEProducer", - calibrationConfig = cms.PSet(calibrationFile = cms.FileInPath('L1Trigger/L1TCalorimeter/data/calib_ee_v1.json')), - Multiclusters=cms.InputTag('hgcalBackEndLayer2Producer:HGCalBackendLayer2Processor3DClustering')) diff --git a/L1Trigger/L1CaloTrigger/python/l1EgammaStaProducers_cff.py b/L1Trigger/L1CaloTrigger/python/l1EgammaStaProducers_cff.py index 6bf59009af963..46dec1ae4ed00 100644 --- a/L1Trigger/L1CaloTrigger/python/l1EgammaStaProducers_cff.py +++ b/L1Trigger/L1CaloTrigger/python/l1EgammaStaProducers_cff.py @@ -1,9 +1,7 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.L1CaloTrigger.l1EGammaEEProducer_cfi import * from L1Trigger.L1CaloTrigger.L1EGammaCrystalsEmulatorProducer_cfi import * -l1EgammaStaProducers = cms.Sequence(l1EGammaEEProducer+L1EGammaClusterEmuProducer) +l1EgammaStaProducers = cms.Sequence(L1EGammaClusterEmuProducer) -l1EgammaStaProducersEE = cms.Sequence(l1EGammaEEProducer) l1EgammaStaProducersEB = cms.Sequence(L1EGammaClusterEmuProducer) diff --git a/L1Trigger/L1CaloTrigger/python/ntuple_cfi.py b/L1Trigger/L1CaloTrigger/python/ntuple_cfi.py deleted file mode 100644 index 644ccd9d7a1be..0000000000000 --- a/L1Trigger/L1CaloTrigger/python/ntuple_cfi.py +++ /dev/null @@ -1,55 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -ntuple_egammaEE = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleEgamma'), - Egamma = cms.InputTag('l1EGammaEEProducer:L1EGammaCollectionBXVWithCuts'), - BranchNamePrefix = cms.untracked.string("egammaEE") -) - -ntuple_egammaEB = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleEgamma'), - Egamma = cms.InputTag("L1EGammaClusterEmuProducer"), - BranchNamePrefix = cms.untracked.string("egammaEB") -) - -ntuple_TTTracks = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleTrackTrigger'), - TTTracks = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), - BranchNamePrefix = cms.untracked.string("l1Trk") -) - -ntuple_tkEleEE = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleTkElectrons'), - TkElectrons = cms.InputTag("L1TkElectronsHGC","EG"), - BranchNamePrefix = cms.untracked.string("tkEleEE") -) - -ntuple_tkEleEB = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleTkElectrons'), - TkElectrons = cms.InputTag("L1TkElectronsCrystal","EG"), - BranchNamePrefix = cms.untracked.string("tkEleEB") -) - -ntuple_tkEleEllEE = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleTkElectrons'), - TkElectrons = cms.InputTag("L1TkElectronsEllipticMatchHGC","EG"), - BranchNamePrefix = cms.untracked.string("tkEleEE") -) - -ntuple_tkEleEllEB = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleTkElectrons'), - TkElectrons = cms.InputTag("L1TkElectronsEllipticMatchCrystal","EG"), - BranchNamePrefix = cms.untracked.string("tkEleEB") -) - -ntuple_tkIsoEleEE = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleTkElectrons'), - TkElectrons = cms.InputTag("L1TkIsoElectronsHGC","EG"), - BranchNamePrefix = cms.untracked.string("tkIsoEleEE") -) - -ntuple_tkIsoEleEB = cms.PSet( - NtupleName = cms.string('L1TriggerNtupleTkElectrons'), - TkElectrons = cms.InputTag("L1TkIsoElectronsCrystal","EG"), - BranchNamePrefix = cms.untracked.string("tkIsoEleEB") -) diff --git a/L1Trigger/L1CaloTrigger/src/L1EGammaEECalibrator.cc b/L1Trigger/L1CaloTrigger/src/L1EGammaEECalibrator.cc deleted file mode 100644 index ddd9ee590a12c..0000000000000 --- a/L1Trigger/L1CaloTrigger/src/L1EGammaEECalibrator.cc +++ /dev/null @@ -1,61 +0,0 @@ -#include "L1Trigger/L1CaloTrigger/interface/L1EGammaEECalibrator.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ParameterSet/interface/FileInPath.h" -#include "boost/property_tree/ptree.hpp" -#include "boost/property_tree/json_parser.hpp" -#include - -namespace l1tp2 { - std::vector as_vector(boost::property_tree::ptree const& pt, - boost::property_tree::ptree::key_type const& key) { - std::vector ret; - for (const auto& item : pt.get_child(key)) - ret.push_back(item.second.get_value()); - return ret; - } -}; // namespace l1tp2 - -L1EGammaEECalibrator::L1EGammaEECalibrator(const edm::ParameterSet& pset) { - //read the JSON file and populate the eta - pt bins and the value container - boost::property_tree::ptree calibration_map; - read_json(pset.getParameter("calibrationFile").fullPath(), calibration_map); - - auto eta_l = l1tp2::as_vector(calibration_map, "eta_l"); - std::copy(eta_l.begin(), eta_l.end(), std::inserter(eta_bins, eta_bins.end())); - auto eta_h = l1tp2::as_vector(calibration_map, "eta_h"); - eta_bins.insert(eta_h.back()); - - auto pt_l = l1tp2::as_vector(calibration_map, "pt_l"); - std::copy(pt_l.begin(), pt_l.end(), std::inserter(pt_bins, pt_bins.end())); - auto pt_h = l1tp2::as_vector(calibration_map, "pt_h"); - pt_bins.insert(pt_h.back()); - - auto calib_data = l1tp2::as_vector(calibration_map, "calib"); - auto n_bins_eta = eta_bins.size(); - auto n_bins_pt = pt_bins.size(); - calib_factors.reserve(n_bins_eta * n_bins_pt); - for (auto calib_f = calib_data.begin(); calib_f != calib_data.end(); ++calib_f) { - auto index = calib_f - calib_data.begin(); - int eta_bin = etaBin(eta_l[index]); - int pt_bin = ptBin(pt_l[index]); - calib_factors[(eta_bin * n_bins_pt) + pt_bin] = *calib_f; - } -} - -int L1EGammaEECalibrator::bin(const std::set& container, float value) const { - auto bin_l = container.upper_bound(value); - if (bin_l == container.end()) { - // value not mapped to any bin - return -1; - } - return std::distance(container.begin(), bin_l) - 1; -} - -float L1EGammaEECalibrator::calibrationFactor(const float& pt, const float& eta) const { - int bin_eta = etaBin(eta); - int bin_pt = ptBin(pt); - if (bin_eta == -1 || bin_pt == -1) - return 1.; - auto n_bins_pt = pt_bins.size(); - return calib_factors[(bin_eta * n_bins_pt) + bin_pt]; -} diff --git a/L1Trigger/L1CaloTrigger/test/BuildFile.xml b/L1Trigger/L1CaloTrigger/test/BuildFile.xml deleted file mode 100644 index e55b6f2e11d1f..0000000000000 --- a/L1Trigger/L1CaloTrigger/test/BuildFile.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/L1Trigger/L1CaloTrigger/test/ntuples/L1TCaloTriggerNtupleBase.h b/L1Trigger/L1CaloTrigger/test/ntuples/L1TCaloTriggerNtupleBase.h deleted file mode 100644 index d12ccc710fbf2..0000000000000 --- a/L1Trigger/L1CaloTrigger/test/ntuples/L1TCaloTriggerNtupleBase.h +++ /dev/null @@ -1,14 +0,0 @@ -#include "L1Trigger/L1THGCalUtilities/interface/HGCalTriggerNtupleBase.h" - -class L1TCaloTriggerNtupleBase : public HGCalTriggerNtupleBase { -public: - L1TCaloTriggerNtupleBase(const edm::ParameterSet& conf) - : HGCalTriggerNtupleBase(conf), - branch_name_prefix_(conf.getUntrackedParameter("BranchNamePrefix", "")) {} - ~L1TCaloTriggerNtupleBase() override{}; - - std::string branch_name_w_prefix(const std::string name) const { return branch_name_prefix_ + "_" + name; } - -private: - std::string branch_name_prefix_; -}; diff --git a/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleEgamma.cc b/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleEgamma.cc deleted file mode 100644 index e474c516bb2f9..0000000000000 --- a/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleEgamma.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include "DataFormats/L1Trigger/interface/EGamma.h" -#include "L1TCaloTriggerNtupleBase.h" - -class L1TriggerNtupleEgamma : public L1TCaloTriggerNtupleBase { -public: - L1TriggerNtupleEgamma(const edm::ParameterSet& conf); - ~L1TriggerNtupleEgamma() override{}; - void initialize(TTree&, const edm::ParameterSet&, edm::ConsumesCollector&&) final; - void fill(const edm::Event& e, const edm::EventSetup& es) final; - -private: - void clear() final; - - edm::EDGetToken egamma_token_; - - int egamma_n_; - std::vector egamma_pt_; - std::vector egamma_energy_; - std::vector egamma_eta_; - std::vector egamma_phi_; - std::vector egamma_hwQual_; -}; - -DEFINE_EDM_PLUGIN(HGCalTriggerNtupleFactory, L1TriggerNtupleEgamma, "L1TriggerNtupleEgamma"); - -L1TriggerNtupleEgamma::L1TriggerNtupleEgamma(const edm::ParameterSet& conf) : L1TCaloTriggerNtupleBase(conf) {} - -void L1TriggerNtupleEgamma::initialize(TTree& tree, const edm::ParameterSet& conf, edm::ConsumesCollector&& collector) { - egamma_token_ = collector.consumes(conf.getParameter("Egamma")); - - tree.Branch(branch_name_w_prefix("n").c_str(), &egamma_n_, branch_name_w_prefix("n/I").c_str()); - tree.Branch(branch_name_w_prefix("pt").c_str(), &egamma_pt_); - tree.Branch(branch_name_w_prefix("energy").c_str(), &egamma_energy_); - tree.Branch(branch_name_w_prefix("eta").c_str(), &egamma_eta_); - tree.Branch(branch_name_w_prefix("phi").c_str(), &egamma_phi_); - tree.Branch(branch_name_w_prefix("hwQual").c_str(), &egamma_hwQual_); -} - -void L1TriggerNtupleEgamma::fill(const edm::Event& e, const edm::EventSetup& es) { - // retrieve towers - edm::Handle egamma_h; - e.getByToken(egamma_token_, egamma_h); - const l1t::EGammaBxCollection& egamma_collection = *egamma_h; - - clear(); - for (auto egee_itr = egamma_collection.begin(0); egee_itr != egamma_collection.end(0); egee_itr++) { - egamma_n_++; - // physical values - egamma_pt_.emplace_back(egee_itr->pt()); - egamma_energy_.emplace_back(egee_itr->energy()); - egamma_eta_.emplace_back(egee_itr->eta()); - egamma_phi_.emplace_back(egee_itr->phi()); - egamma_hwQual_.emplace_back(egee_itr->hwQual()); - } -} - -void L1TriggerNtupleEgamma::clear() { - egamma_n_ = 0; - egamma_pt_.clear(); - egamma_energy_.clear(); - egamma_eta_.clear(); - egamma_phi_.clear(); - egamma_hwQual_.clear(); -} diff --git a/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleTkElectrons.cc b/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleTkElectrons.cc deleted file mode 100644 index 03df9545ba321..0000000000000 --- a/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleTkElectrons.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include "L1TCaloTriggerNtupleBase.h" - -#include "DataFormats/L1TCorrelator/interface/TkElectron.h" -#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" - -class L1TriggerNtupleTkElectrons : public L1TCaloTriggerNtupleBase { -public: - L1TriggerNtupleTkElectrons(const edm::ParameterSet& conf); - ~L1TriggerNtupleTkElectrons() override{}; - void initialize(TTree&, const edm::ParameterSet&, edm::ConsumesCollector&&) final; - void fill(const edm::Event& e, const edm::EventSetup& es) final; - -private: - void clear() final; - - edm::EDGetToken tkEle_token_; - - int tkEle_n_; - std::vector tkEle_pt_; - std::vector tkEle_energy_; - std::vector tkEle_eta_; - std::vector tkEle_phi_; - std::vector tkEle_hwQual_; - std::vector tkEle_tkIso_; -}; - -DEFINE_EDM_PLUGIN(HGCalTriggerNtupleFactory, L1TriggerNtupleTkElectrons, "L1TriggerNtupleTkElectrons"); - -L1TriggerNtupleTkElectrons::L1TriggerNtupleTkElectrons(const edm::ParameterSet& conf) - : L1TCaloTriggerNtupleBase(conf) {} - -void L1TriggerNtupleTkElectrons::initialize(TTree& tree, - const edm::ParameterSet& conf, - edm::ConsumesCollector&& collector) { - tkEle_token_ = collector.consumes(conf.getParameter("TkElectrons")); - - tree.Branch(branch_name_w_prefix("n").c_str(), &tkEle_n_, branch_name_w_prefix("n/I").c_str()); - tree.Branch(branch_name_w_prefix("pt").c_str(), &tkEle_pt_); - tree.Branch(branch_name_w_prefix("energy").c_str(), &tkEle_energy_); - tree.Branch(branch_name_w_prefix("eta").c_str(), &tkEle_eta_); - tree.Branch(branch_name_w_prefix("phi").c_str(), &tkEle_phi_); - tree.Branch(branch_name_w_prefix("hwQual").c_str(), &tkEle_hwQual_); - tree.Branch(branch_name_w_prefix("tkIso").c_str(), &tkEle_tkIso_); -} - -void L1TriggerNtupleTkElectrons::fill(const edm::Event& e, const edm::EventSetup& es) { - // retrieve towers - edm::Handle tkEle_h; - e.getByToken(tkEle_token_, tkEle_h); - const l1t::TkElectronCollection& tkEle_collection = *tkEle_h; - - clear(); - for (auto tkele_itr : tkEle_collection) { - tkEle_n_++; - tkEle_pt_.emplace_back(tkele_itr.pt()); - tkEle_energy_.emplace_back(tkele_itr.energy()); - tkEle_eta_.emplace_back(tkele_itr.eta()); - tkEle_phi_.emplace_back(tkele_itr.phi()); - tkEle_hwQual_.emplace_back(tkele_itr.EGRef()->hwQual()); - tkEle_tkIso_.emplace_back(tkele_itr.trkIsol()); - } -} - -void L1TriggerNtupleTkElectrons::clear() { - tkEle_n_ = 0; - tkEle_pt_.clear(); - tkEle_energy_.clear(); - tkEle_eta_.clear(); - tkEle_phi_.clear(); - tkEle_hwQual_.clear(); - tkEle_tkIso_.clear(); -} diff --git a/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleTrackTrigger.cc b/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleTrackTrigger.cc deleted file mode 100644 index 9ff76aa6c461b..0000000000000 --- a/L1Trigger/L1CaloTrigger/test/ntuples/L1TriggerNtupleTrackTrigger.cc +++ /dev/null @@ -1,157 +0,0 @@ -#include "L1Trigger/L1THGCal/interface/HGCalTriggerTools.h" - -#include "L1Trigger/L1TTrackMatch/interface/pTFrom2Stubs.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/Math/interface/LorentzVector.h" -#include "DataFormats/Candidate/interface/Candidate.h" -#include "DataFormats/ParticleFlowReco/interface/PFCluster.h" - -#include "MagneticField/Engine/interface/MagneticField.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" - -#include "CommonTools/BaseParticlePropagator/interface/BaseParticlePropagator.h" -#include "FWCore/Framework/interface/ESWatcher.h" - -#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" -#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" - -#include "L1TCaloTriggerNtupleBase.h" - -class L1TriggerNtupleTrackTrigger : public L1TCaloTriggerNtupleBase { -public: - L1TriggerNtupleTrackTrigger(const edm::ParameterSet& conf); - ~L1TriggerNtupleTrackTrigger() override{}; - void initialize(TTree&, const edm::ParameterSet&, edm::ConsumesCollector&&) final; - void fill(const edm::Event& e, const edm::EventSetup& es) final; - typedef TTTrack L1TTTrackType; - -private: - void clear() final; - std::pair propagateToCalo(const math::XYZTLorentzVector& iMom, - const math::XYZTLorentzVector& iVtx, - double iCharge, - double iBField); - - edm::EDGetToken track_token_; - - int l1track_n_; - std::vector l1track_pt_; - std::vector l1track_pt2stubs_; - std::vector l1track_eta_; - std::vector l1track_phi_; - std::vector l1track_curv_; - std::vector l1track_chi2_; - std::vector l1track_chi2Red_; - std::vector l1track_nStubs_; - std::vector l1track_z0_; - std::vector l1track_charge_; - std::vector l1track_caloeta_; - std::vector l1track_calophi_; - - edm::ESWatcher magfield_watcher_; - HGCalTriggerTools triggerTools_; -}; - -DEFINE_EDM_PLUGIN(HGCalTriggerNtupleFactory, L1TriggerNtupleTrackTrigger, "L1TriggerNtupleTrackTrigger"); - -L1TriggerNtupleTrackTrigger::L1TriggerNtupleTrackTrigger(const edm::ParameterSet& conf) - : L1TCaloTriggerNtupleBase(conf) {} - -void L1TriggerNtupleTrackTrigger::initialize(TTree& tree, - const edm::ParameterSet& conf, - edm::ConsumesCollector&& collector) { - track_token_ = - collector.consumes>>(conf.getParameter("TTTracks")); - - tree.Branch(branch_name_w_prefix("n").c_str(), &l1track_n_, branch_name_w_prefix("n/I").c_str()); - tree.Branch(branch_name_w_prefix("pt").c_str(), &l1track_pt_); - tree.Branch(branch_name_w_prefix("pt2stubs").c_str(), &l1track_pt2stubs_); - tree.Branch(branch_name_w_prefix("eta").c_str(), &l1track_eta_); - tree.Branch(branch_name_w_prefix("phi").c_str(), &l1track_phi_); - tree.Branch(branch_name_w_prefix("curv").c_str(), &l1track_curv_); - tree.Branch(branch_name_w_prefix("chi2").c_str(), &l1track_chi2_); - tree.Branch(branch_name_w_prefix("chi2Red").c_str(), &l1track_chi2Red_); - tree.Branch(branch_name_w_prefix("nStubs").c_str(), &l1track_nStubs_); - tree.Branch(branch_name_w_prefix("z0").c_str(), &l1track_z0_); - tree.Branch(branch_name_w_prefix("charge").c_str(), &l1track_charge_); - tree.Branch(branch_name_w_prefix("caloeta").c_str(), &l1track_caloeta_); - tree.Branch(branch_name_w_prefix("calophi").c_str(), &l1track_calophi_); -} - -void L1TriggerNtupleTrackTrigger::fill(const edm::Event& ev, const edm::EventSetup& es) { - // the L1Tracks - edm::Handle> l1TTTrackHandle; - ev.getByToken(track_token_, l1TTTrackHandle); - - float fBz = 0; - if (magfield_watcher_.check(es)) { - edm::ESHandle magfield; - es.get().get(magfield); - fBz = magfield->inTesla(GlobalPoint(0, 0, 0)).z(); - } - - // geometry needed to call pTFrom2Stubs - edm::ESHandle geomHandle; - es.get().get("idealForDigi", geomHandle); - const TrackerGeometry* tGeom = geomHandle.product(); - - triggerTools_.eventSetup(es); - - clear(); - for (auto trackIter = l1TTTrackHandle->begin(); trackIter != l1TTTrackHandle->end(); ++trackIter) { - l1track_n_++; - l1track_pt_.emplace_back(trackIter->momentum().perp()); - l1track_pt2stubs_.emplace_back(pTFrom2Stubs::pTFrom2(trackIter, tGeom)); - l1track_eta_.emplace_back(trackIter->momentum().eta()); - l1track_phi_.emplace_back(trackIter->momentum().phi()); - l1track_curv_.emplace_back(trackIter->rInv()); - l1track_chi2_.emplace_back(trackIter->chi2()); - l1track_chi2Red_.emplace_back(trackIter->chi2Red()); - l1track_nStubs_.emplace_back(trackIter->getStubRefs().size()); - float z0 = trackIter->POCA().z(); //cm - int charge = trackIter->rInv() > 0 ? +1 : -1; - - reco::Candidate::PolarLorentzVector p4p( - trackIter->momentum().perp(), trackIter->momentum().eta(), trackIter->momentum().phi(), 0); // no mass ? - reco::Particle::LorentzVector p4(p4p.X(), p4p.Y(), p4p.Z(), p4p.E()); - reco::Particle::Point vtx(0., 0., z0); - - auto caloetaphi = propagateToCalo(p4, math::XYZTLorentzVector(0., 0., z0, 0.), charge, fBz); - - l1track_z0_.emplace_back(z0); - l1track_charge_.emplace_back(charge); - l1track_caloeta_.emplace_back(caloetaphi.first); - l1track_calophi_.emplace_back(caloetaphi.second); - } -} - -void L1TriggerNtupleTrackTrigger::clear() { - l1track_n_ = 0; - l1track_pt_.clear(); - l1track_pt2stubs_.clear(); - l1track_eta_.clear(); - l1track_phi_.clear(); - l1track_curv_.clear(); - l1track_chi2_.clear(); - l1track_chi2Red_.clear(); - l1track_nStubs_.clear(); - l1track_z0_.clear(); - l1track_charge_.clear(); - l1track_caloeta_.clear(); - l1track_calophi_.clear(); -} - -std::pair L1TriggerNtupleTrackTrigger::propagateToCalo(const math::XYZTLorentzVector& iMom, - const math::XYZTLorentzVector& iVtx, - double iCharge, - double iBField) { - BaseParticlePropagator prop = BaseParticlePropagator(RawParticle(iMom, iVtx, iCharge), 0., 0., iBField); - prop.setPropagationConditions(129.0, triggerTools_.getLayerZ(1), false); - prop.propagate(); - double ecalShowerDepth = reco::PFCluster::getDepthCorrection(prop.particle().momentum().E(), false, false); - math::XYZVector point = math::XYZVector(prop.particle().vertex()) + - math::XYZTLorentzVector(prop.particle().momentum()).Vect().Unit() * ecalShowerDepth; - return std::make_pair(point.eta(), point.phi()); -} diff --git a/L1Trigger/L1CaloTrigger/test/runL1TP2EgammaNtuples_D49geom.py b/L1Trigger/L1CaloTrigger/test/runL1TP2EgammaNtuples_D49geom.py deleted file mode 100644 index ecc07070f0a54..0000000000000 --- a/L1Trigger/L1CaloTrigger/test/runL1TP2EgammaNtuples_D49geom.py +++ /dev/null @@ -1,139 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from Configuration.StandardSequences.Eras import eras -process = cms.Process('DIGI',eras.Phase2C9) - - -# import of standard configurations -process.load('Configuration.StandardSequences.Services_cff') -process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') -process.load('FWCore.MessageService.MessageLogger_cfi') -process.load('Configuration.EventContent.EventContent_cff') -process.load('SimGeneral.MixingModule.mixNoPU_cfi') -process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') -process.load('Configuration.Geometry.GeometryExtended2026D49_cff') -process.load('Configuration.StandardSequences.MagneticField_cff') -process.load('Configuration.StandardSequences.Generator_cff') -process.load('IOMC.EventVertexGenerators.VtxSmearedHLLHC14TeV_cfi') -process.load('GeneratorInterface.Core.genFilterSummary_cff') -process.load('Configuration.StandardSequences.SimIdeal_cff') -process.load('Configuration.StandardSequences.Digi_cff') -process.load('Configuration.StandardSequences.SimL1Emulator_cff') -process.load('Configuration.StandardSequences.DigiToRaw_cff') -process.load('Configuration.StandardSequences.EndOfProcess_cff') -process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') - - -############################################################ -# L1 tracking -############################################################ - -# remake stubs ? -process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') -from L1Trigger.TrackTrigger.TTStubAlgorithmRegister_cfi import * -process.load("SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff") -process.load("L1Trigger.TrackFindingTracklet.Tracklet_cfi") -process.load("RecoVertex.BeamSpotProducer.BeamSpot_cfi") - -# process.TTClusterStub = cms.Path(process.TrackTriggerClustersStubs) -# process.TTClusterStubTruth = cms.Path(process.TrackTriggerAssociatorClustersStubs) - - -process.TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag( - cms.InputTag('TTTracksFromTrackletEmulation', 'Level1TTTracks')) - -# emulation -process.TTTracksEmulationWithTruth = cms.Path( - process.offlineBeamSpot * - process.TTTracksFromTrackletEmulation * - process.TrackTriggerAssociatorTracks) -# L1TRK_PROC.asciiFileName = cms.untracked.string("evlist.txt") - - - - - -process.maxEvents = cms.untracked.PSet( - input = cms.untracked.int32(200) -) - -# Input source -process.source = cms.Source("PoolSource", - fileNames = cms.untracked.vstring('file:/data/cerminar/Phase2HLTTDRWinter20DIGI/SingleElectron_PT2to200/GEN-SIM-DIGI-RAW/PU200_110X_mcRun4_realistic_v3_ext2-v2/F32C5A21-F0E9-9149-B04A-883CC704E820.root'), - # fileNames = cms.untracked.vstring('/store/mc/PhaseIIMTDTDRAutumn18DR/SinglePion_FlatPt-2to100/FEVT/PU200_103X_upgrade2023_realistic_v2-v1/70000/FFA969EE-22E0-E447-86AA-46A6CBF6407D.root'), - inputCommands=cms.untracked.vstring( - 'keep *', - 'drop l1tEMTFHit2016Extras_simEmtfDigis_CSC_HLT', - 'drop l1tEMTFHit2016Extras_simEmtfDigis_RPC_HLT', - 'drop l1tEMTFHit2016s_simEmtfDigis__HLT', - 'drop l1tEMTFTrack2016Extras_simEmtfDigis__HLT', - 'drop l1tEMTFTrack2016s_simEmtfDigis__HLT', - 'drop FTLClusteredmNewDetSetVector_mtdClusters_FTLBarrel_RECO', - 'drop FTLClusteredmNewDetSetVector_mtdClusters_FTLEndcap_RECO', - 'drop MTDTrackingRecHitedmNewDetSetVector_mtdTrackingRecHits__RECO', - 'drop BTLDetIdBTLSampleFTLDataFrameTsSorted_mix_FTLBarrel_HLT', - 'drop ETLDetIdETLSampleFTLDataFrameTsSorted_mix_FTLEndcap_HLT', - ) - ) - -process.options = cms.untracked.PSet( - -) - -# Production Info -process.configurationMetadata = cms.untracked.PSet( - version = cms.untracked.string('$Revision: 1.20 $'), - annotation = cms.untracked.string('SingleElectronPt10_cfi nevts:10'), - name = cms.untracked.string('Applications') -) - -# Output definition -process.TFileService = cms.Service( - "TFileService", - fileName = cms.string("ntuple.root") - ) - -# Other statements -from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') - -# load HGCAL TPG simulation -process.load('L1Trigger.L1THGCal.hgcalTriggerPrimitives_cff') - -# To add truth-matched calo cells and downstream objects -# process.load('L1Trigger.L1THGCalUtilities.caloTruthCells_cff') -# process.hgcalTriggerPrimitives += process.caloTruthCells -# process.load('L1Trigger.L1THGCalUtilities.caloTruthCellsNtuples_cff') - -process.hgcl1tpg_step = cms.Path(process.hgcalTriggerPrimitives) - -# load Standalone EG producers -process.load('L1Trigger.L1CaloTrigger.l1EgammaStaProducers_cff') -process.l1EgammaStaProducers_step = cms.Path(process.l1EgammaStaProducers) - -# load track matching modules -process.load('L1Trigger.L1TTrackMatch.L1TkEgammaObjects_cff') -process.l1EgammaTrackMatchProducers_step = cms.Path(process.l1TkElectronTrackEllipticProducers) - -# load ntuplizer -process.load('L1Trigger.L1CaloTrigger.L1TCaloTriggerNtuples_cff') -process.ntuple_step = cms.Path(process.l1CaloTriggerNtuples) - -# customization from Giovanni -# process.hgcalBackEndLayer2Producer.ProcessorParameters.C3d_parameters.histoMax_C3d_seeding_parameters.threshold_histo_multicluster = 0.5 -# process.hgcalBackEndLayer2Producer.ProcessorParameters.C3d_parameters.histoMax_C3d_seeding_parameters.binSumsHisto = cms.vuint32( -# 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 -# ) - -# Schedule definition -process.schedule = cms.Schedule( - process.TTTracksEmulationWithTruth, - process.hgcl1tpg_step, - process.l1EgammaTrackMatchProducers_step, - process.l1EgammaStaProducers_step, - process.ntuple_step) - -# Add early deletion of temporary data products to reduce peak memory need -from Configuration.StandardSequences.earlyDeleteSettings_cff import customiseEarlyDelete -process = customiseEarlyDelete(process) -# End adding early deletion diff --git a/L1Trigger/L1THGCal/interface/backend/HGCalTriggerClusterIdentificationBase.h b/L1Trigger/L1THGCal/interface/backend/HGCalTriggerClusterIdentificationBase.h index ac630527dceea..64948f7821de7 100644 --- a/L1Trigger/L1THGCal/interface/backend/HGCalTriggerClusterIdentificationBase.h +++ b/L1Trigger/L1THGCal/interface/backend/HGCalTriggerClusterIdentificationBase.h @@ -10,7 +10,8 @@ class HGCalTriggerClusterIdentificationBase { virtual ~HGCalTriggerClusterIdentificationBase(){}; virtual void initialize(const edm::ParameterSet& conf) = 0; virtual float value(const l1t::HGCalMulticluster& cluster) const = 0; - virtual bool decision(const l1t::HGCalMulticluster& cluster) const = 0; + virtual bool decision(const l1t::HGCalMulticluster& cluster, unsigned wp = 0) const = 0; + virtual const std::vector& working_points() const = 0; }; #include "FWCore/PluginManager/interface/PluginFactory.h" diff --git a/L1Trigger/L1THGCal/plugins/backend/HGCalTriggerClusterIdentificationBDT.cc b/L1Trigger/L1THGCal/plugins/backend/HGCalTriggerClusterIdentificationBDT.cc index b423341fbdea7..1ad007471d134 100644 --- a/L1Trigger/L1THGCal/plugins/backend/HGCalTriggerClusterIdentificationBDT.cc +++ b/L1Trigger/L1THGCal/plugins/backend/HGCalTriggerClusterIdentificationBDT.cc @@ -33,12 +33,26 @@ class HGCalTriggerClusterIdentificationBDT : public HGCalTriggerClusterIdentific float eta_max_ = 3.; }; + class WorkingPoint { + public: + WorkingPoint(const std::string& name, double wp) : name_(name), wp_(wp) {} + ~WorkingPoint() = default; + + const std::string& name() const { return name_; } + double working_point() const { return wp_; } + + private: + std::string name_; + double wp_; + }; + public: HGCalTriggerClusterIdentificationBDT(); ~HGCalTriggerClusterIdentificationBDT() override{}; void initialize(const edm::ParameterSet& conf) final; float value(const l1t::HGCalMulticluster& cluster) const final; - bool decision(const l1t::HGCalMulticluster& cluster) const final; + bool decision(const l1t::HGCalMulticluster& cluster, unsigned wp = 0) const final; + const std::vector& working_points() const final { return working_points_names_; } private: enum class ClusterVariable { @@ -57,9 +71,10 @@ class HGCalTriggerClusterIdentificationBDT : public HGCalTriggerClusterIdentific }; std::vector categories_; std::vector> bdts_; - std::vector working_points_; + std::vector> working_points_; std::vector input_variables_; std::vector input_variables_id_; + std::vector working_points_names_; float clusterVariable(ClusterVariable, const l1t::HGCalMulticluster&) const; int category(float pt, float eta) const; @@ -81,17 +96,32 @@ void HGCalTriggerClusterIdentificationBDT::initialize(const edm::ParameterSet& c std::vector categories_etamax = conf.getParameter>("CategoriesEtaMax"); std::vector categories_ptmin = conf.getParameter>("CategoriesPtMin"); std::vector categories_ptmax = conf.getParameter>("CategoriesPtMax"); - working_points_ = conf.getParameter>("WorkingPoints"); if (bdt_files.size() != categories_etamin.size() || categories_etamin.size() != categories_etamax.size() || - categories_etamax.size() != categories_ptmin.size() || categories_ptmin.size() != categories_ptmax.size() || - categories_ptmax.size() != working_points_.size()) { + categories_etamax.size() != categories_ptmin.size() || categories_ptmin.size() != categories_ptmax.size()) { throw cms::Exception("HGCalTriggerClusterIdentificationBDT|BadInitialization") << "Inconsistent numbers of categories, BDT weight files and working points"; } - categories_.reserve(working_points_.size()); - bdts_.reserve(working_points_.size()); - for (unsigned cat = 0; cat < categories_etamin.size(); cat++) { + size_t categories_size = categories_etamin.size(); + + const auto wps_conf = conf.getParameter>("WorkingPoints"); + working_points_.resize(categories_size); + for (const auto& wp_conf : wps_conf) { + std::string wp_name = wp_conf.getParameter("Name"); + std::vector wps = wp_conf.getParameter>("WorkingPoint"); + working_points_names_.emplace_back(wp_name); + if (wps.size() != categories_size) { + throw cms::Exception("HGCalTriggerClusterIdentificationBDT|BadInitialization") + << "Inconsistent number of categories in working point '" << wp_name << "'"; + } + for (size_t cat = 0; cat < categories_size; cat++) { + working_points_[cat].emplace_back(wp_name, wps[cat]); + } + } + + categories_.reserve(categories_size); + bdts_.reserve(categories_size); + for (size_t cat = 0; cat < categories_size; cat++) { categories_.emplace_back( categories_ptmin[cat], categories_ptmax[cat], categories_etamin[cat], categories_etamax[cat]); } @@ -148,12 +178,12 @@ float HGCalTriggerClusterIdentificationBDT::value(const l1t::HGCalMulticluster& return (cat != -1 ? bdts_.at(cat)->evaluate(inputs) : -999.); } -bool HGCalTriggerClusterIdentificationBDT::decision(const l1t::HGCalMulticluster& cluster) const { +bool HGCalTriggerClusterIdentificationBDT::decision(const l1t::HGCalMulticluster& cluster, unsigned wp) const { float bdt_output = value(cluster); float pt = cluster.pt(); float eta = cluster.eta(); int cat = category(pt, eta); - return (cat != -1 ? bdt_output > working_points_.at(cat) : true); + return (cat != -1 ? bdt_output > working_points_.at(cat).at(wp).working_point() : true); } int HGCalTriggerClusterIdentificationBDT::category(float pt, float eta) const { diff --git a/L1Trigger/L1THGCal/python/egammaIdentification.py b/L1Trigger/L1THGCal/python/egammaIdentification.py index 32afa8459a02f..c7e18b8bddfad 100644 --- a/L1Trigger/L1THGCal/python/egammaIdentification.py +++ b/L1Trigger/L1THGCal/python/egammaIdentification.py @@ -205,23 +205,44 @@ def __init__(self, eta_min, eta_max, pt_min, pt_max): CategoriesPtMin=cms.vdouble([cat.pt_min for cat in categories]), CategoriesPtMax=cms.vdouble([cat.pt_max for cat in categories]), Weights=cms.vstring(bdt_weights_histomax['v10_3151']), - WorkingPoints=cms.vdouble( - [wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],tight_wp)] - ) + WorkingPoints=cms.VPSet([ + cms.PSet( + Name=cms.string('tight'), + WorkingPoint=cms.vdouble([wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],tight_wp)]) + ), + cms.PSet( + Name=cms.string('loose'), + WorkingPoint=cms.vdouble([wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],loose_wp)]) + ), + ]) ) phase2_hgcalV10.toModify(egamma_identification_histomax, Inputs=cms.vstring(input_features_histomax['v10_3151']), Weights=cms.vstring(bdt_weights_histomax['v10_3151']), - WorkingPoints=cms.vdouble( - [wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],tight_wp)] - ) + WorkingPoints=cms.VPSet([ + cms.PSet( + Name=cms.string('tight'), + WorkingPoint=cms.vdouble([wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],tight_wp)]) + ), + cms.PSet( + Name=cms.string('loose'), + WorkingPoint=cms.vdouble([wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],loose_wp)]) + ), + ]) ) phase2_hgcalV11.toModify(egamma_identification_histomax, Inputs=cms.vstring(input_features_histomax['v10_3151']), Weights=cms.vstring(bdt_weights_histomax['v10_3151']), - WorkingPoints=cms.vdouble( - [wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],tight_wp)] - ) + WorkingPoints=cms.VPSet([ + cms.PSet( + Name=cms.string('tight'), + WorkingPoint=cms.vdouble([wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],tight_wp)]) + ), + cms.PSet( + Name=cms.string('loose'), + WorkingPoint=cms.vdouble([wps[eff] for wps,eff in zip(working_points_histomax['v10_3151'],loose_wp)]) + ), + ]) ) diff --git a/L1Trigger/L1THGCal/src/backend/HGCalHistoClusteringImpl.cc b/L1Trigger/L1THGCal/src/backend/HGCalHistoClusteringImpl.cc index dddf5fafa5a97..f78d08a89ed20 100644 --- a/L1Trigger/L1THGCal/src/backend/HGCalHistoClusteringImpl.cc +++ b/L1Trigger/L1THGCal/src/backend/HGCalHistoClusteringImpl.cc @@ -141,7 +141,11 @@ void HGCalHistoClusteringImpl::finalizeClusters(std::vectordecision(multicluster)); + unsigned hwQual = 0; + for (unsigned wp = 0; wp < id_->working_points().size(); wp++) { + hwQual |= (id_->decision(multicluster, wp) << wp); + } + multicluster.setHwQual(hwQual); // fill H/E multicluster.saveHOverE(); diff --git a/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h b/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h index ab7a387019000..f0f32df597f9e 100644 --- a/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h +++ b/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h @@ -18,6 +18,7 @@ namespace l1t { int muInBx); static void fillMuon(Muon& mu, uint32_t raw_data_spare, uint64_t dataword, int fed, unsigned int fw, int muInBx); static void fillIntermediateMuon(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63, unsigned int fw); + static bool showerFired(uint32_t shower_word, int fedId, unsigned int fwId); static void generatePackedMuonDataWords(const Muon& mu, uint32_t& raw_data_spare, uint32_t& raw_data_00_31, diff --git a/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h b/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h index 7e0212b77e4c9..248851332a7a3 100644 --- a/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h +++ b/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h @@ -51,9 +51,9 @@ namespace l1t { static constexpr unsigned emtfPtUnconstrainedShift_ = 20; static constexpr unsigned trackAddressMask_ = 0x1FFFFFFF; static constexpr unsigned trackAddressShift_ = 2; - static constexpr unsigned emtfShowerMask_ = 0x3; - static constexpr unsigned emtfShowerInTimeFrame_ = 0; - static constexpr unsigned emtfShowerOOTFrame_ = 2; + static constexpr unsigned emtfShowerMask_ = 0x1; + static constexpr unsigned emtfShowerInTimeFrame_ = 1; + static constexpr unsigned emtfShowerOOTFrame_ = 3; static constexpr unsigned emtfShowerOneNominalShift_ = 18; static constexpr unsigned emtfShowerOneTightShift_ = 19; diff --git a/L1Trigger/L1TMuon/plugins/L1TMuonShowerProducer.cc b/L1Trigger/L1TMuon/plugins/L1TMuonShowerProducer.cc index 8c115c63dcd7d..4ca795dfd3043 100644 --- a/L1Trigger/L1TMuon/plugins/L1TMuonShowerProducer.cc +++ b/L1Trigger/L1TMuon/plugins/L1TMuonShowerProducer.cc @@ -4,7 +4,6 @@ // user include files #include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/stream/EDProducer.h" diff --git a/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc b/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc index b5ed16c019fc1..64e75fea6f4e5 100644 --- a/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc +++ b/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc @@ -263,17 +263,20 @@ void l1t::MuonRawDigiTranslator::generate64bitDataWord( dataword = (((uint64_t)msw) << 32) + lsw; } +bool l1t::MuonRawDigiTranslator::showerFired(uint32_t shower_word, int fedId, unsigned int fwId) { + if ((fedId == 1402 && fwId >= 0x7000000) || (fedId == 1404 && fwId >= 0x00010f01)) { + return ((shower_word >> showerShift_) & 1) == 1; + } + return false; +} + std::array l1t::MuonRawDigiTranslator::getPackedShowerDataWords(const MuonShower& shower, const int fedId, const unsigned int fwId) { std::array res{}; - if (fedId == 1402 && fwId < 0x7000000) { - return res; - } else { + if ((fedId == 1402 && fwId >= 0x7000000) || (fedId == 1404 && fwId >= 0x00010f01)) { res.at(0) = shower.isOneNominalInTime() ? (1 << showerShift_) : 0; - res.at(1) = shower.isOneNominalOutOfTime() ? (1 << showerShift_) : 0; - res.at(2) = shower.isTwoLooseInTime() ? (1 << showerShift_) : 0; - res.at(3) = shower.isTwoLooseOutOfTime() ? (1 << showerShift_) : 0; + res.at(1) = shower.isOneTightInTime() ? (1 << showerShift_) : 0; } return res; } diff --git a/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc b/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc index 725317a7b1ba3..ce363b405a853 100644 --- a/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc +++ b/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc @@ -76,12 +76,15 @@ void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand(RegionalMuonCand& mu.setTrackSubAddress(RegionalMuonCand::kME3Ch, (rawTrackAddress >> emtfTrAddrMe3ChShift_) & emtfTrAddrMe3ChMask_); mu.setTrackSubAddress(RegionalMuonCand::kME4Seg, (rawTrackAddress >> emtfTrAddrMe4SegShift_) & 0x1); mu.setTrackSubAddress(RegionalMuonCand::kME4Ch, (rawTrackAddress >> emtfTrAddrMe4ChShift_) & emtfTrAddrMe4ChMask_); - mu.setTrackSubAddress(RegionalMuonCand::kTrkNum, - (rawTrackAddress >> emtfTrAddrTrkNumShift_) & emtfTrAddrTrkNumMask_); - mu.setTrackSubAddress(RegionalMuonCand::kBX, (rawTrackAddress >> emtfTrAddrBxShift_) & emtfTrAddrBxMask_); if (useEmtfDisplacementInfo) { // In Run-3 we receive displaced muon information from EMTF mu.setHwPtUnconstrained((raw_data_32_63 >> emtfPtUnconstrainedShift_) & ptUnconstrainedMask_); mu.setHwDXY((raw_data_32_63 >> emtfDxyShift_) & dxyMask_); + mu.setTrackSubAddress(RegionalMuonCand::kTrkNum, 0); + mu.setTrackSubAddress(RegionalMuonCand::kBX, 0); + } else { + mu.setTrackSubAddress(RegionalMuonCand::kTrkNum, + (rawTrackAddress >> emtfTrAddrTrkNumShift_) & emtfTrAddrTrkNumMask_); + mu.setTrackSubAddress(RegionalMuonCand::kBX, (rawTrackAddress >> emtfTrAddrBxShift_) & emtfTrAddrBxMask_); } } else if (tf == omtf_neg || tf == omtf_pos) { mu.setTrackSubAddress(RegionalMuonCand::kLayers, @@ -124,7 +127,7 @@ bool l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonShower( muShower.setOneTightInTime(((bxPayload[emtfShowerInTimeFrame_] >> emtfShowerOneTightShift_) & 1) == 1); muShower.setOneTightOutOfTime(((bxPayload[emtfShowerOOTFrame_] >> emtfShowerOneTightShift_) & 1) == 1); - return true; + return muShower.isValid(); } else { return false; } @@ -133,14 +136,17 @@ bool l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonShower( void l1t::RegionalMuonRawDigiTranslator::generatePackedShowerPayload(const RegionalMuonShower& shower, std::array& payload, const bool useEmtfShowers) { - if (!useEmtfShowers) { + if (!useEmtfShowers || !shower.isValid()) { return; } // First we check whether we're going to overwrite something in the payload. - if (((payload.at(emtfShowerInTimeFrame_) & emtfShowerMask_) != 0) || - ((payload.at(emtfShowerOOTFrame_) & emtfShowerMask_) != 0)) { + if ((((payload.at(emtfShowerInTimeFrame_) >> emtfShowerOneNominalShift_) & emtfShowerMask_) != 0) || + (((payload.at(emtfShowerInTimeFrame_) >> emtfShowerOneTightShift_) & emtfShowerMask_) != 0) || + (((payload.at(emtfShowerOOTFrame_) >> emtfShowerOneNominalShift_) & emtfShowerMask_) != 0) || + (((payload.at(emtfShowerOOTFrame_) >> emtfShowerOneTightShift_) & emtfShowerMask_) != 0)) { edm::LogError("L1T") << "Check constants for RegionalMuonShower fields! It looks like we're in danger of " - "overwriting muon data in the packer!"; + "overwriting muon data in the packer! InTimeFrame is " + << payload.at(emtfShowerInTimeFrame_) << ", OOTFrame is " << payload.at(emtfShowerOOTFrame_); return; } payload.at(emtfShowerInTimeFrame_) |= (shower.isOneNominalInTime() & 1) << emtfShowerOneNominalShift_ | @@ -232,9 +238,7 @@ int l1t::RegionalMuonRawDigiTranslator::generateRawTrkAddress(const RegionalMuon (mu.trackSubAddress(RegionalMuonCand::kME3Seg) & 0x1) << emtfTrAddrMe3SegShift_ | (mu.trackSubAddress(RegionalMuonCand::kME3Ch) & emtfTrAddrMe3ChMask_) << emtfTrAddrMe3ChShift_ | (mu.trackSubAddress(RegionalMuonCand::kME4Seg) & 0x1) << emtfTrAddrMe4SegShift_ | - (mu.trackSubAddress(RegionalMuonCand::kME4Ch) & emtfTrAddrMe4ChMask_) << emtfTrAddrMe4ChShift_ | - (mu.trackSubAddress(RegionalMuonCand::kTrkNum) & emtfTrAddrTrkNumMask_) << emtfTrAddrTrkNumShift_ | - (mu.trackSubAddress(RegionalMuonCand::kBX) & emtfTrAddrBxMask_) << emtfTrAddrBxShift_; + (mu.trackSubAddress(RegionalMuonCand::kME4Ch) & emtfTrAddrMe4ChMask_) << emtfTrAddrMe4ChShift_; } else { edm::LogWarning("L1T") << "EMTF muon track address map contains " << mu.trackAddress().size() diff --git a/L1Trigger/L1TNtuples/BuildFile.xml b/L1Trigger/L1TNtuples/BuildFile.xml index 0cb4edde586d8..da9e155aeb2dc 100644 --- a/L1Trigger/L1TNtuples/BuildFile.xml +++ b/L1Trigger/L1TNtuples/BuildFile.xml @@ -4,6 +4,7 @@ + @@ -22,6 +23,8 @@ + + diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisGeneratorDataFormat.h b/L1Trigger/L1TNtuples/interface/L1AnalysisGeneratorDataFormat.h index e2b0fbaae587d..fd619fa7838f2 100644 --- a/L1Trigger/L1TNtuples/interface/L1AnalysisGeneratorDataFormat.h +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisGeneratorDataFormat.h @@ -31,12 +31,21 @@ namespace L1Analysis { partPhi.resize(0); partE.resize(0); partCh.resize(0); + partP.resize(0); + partDxy.resize(0); + partLxy.resize(0); + partVx.resize(0); + partVy.resize(0); + partVz.resize(0); nJet = 0; jetPt.resize(0); jetEta.resize(0); jetPhi.resize(0); jetM.resize(0); + + genMetTrue = 0; + genMetCalo = 0; } // ---- L1AnalysisGeneratorDataFormat information. @@ -55,12 +64,21 @@ namespace L1Analysis { std::vector partPhi; std::vector partE; std::vector partCh; + std::vector partP; + std::vector partDxy; + std::vector partLxy; + std::vector partVx; + std::vector partVy; + std::vector partVz; int nJet; std::vector jetPt; std::vector jetEta; std::vector jetPhi; std::vector jetM; + + float genMetTrue; + float genMetCalo; }; } // namespace L1Analysis #endif diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisL1Menu.h b/L1Trigger/L1TNtuples/interface/L1AnalysisL1Menu.h index b35ea73611618..6336caac11f0a 100644 --- a/L1Trigger/L1TNtuples/interface/L1AnalysisL1Menu.h +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisL1Menu.h @@ -3,7 +3,6 @@ #include "DataFormats/L1GlobalTrigger/interface/L1GtTriggerMenuLite.h" #include "CondFormats/L1TObjects/interface/L1GtTriggerMenuFwd.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h" #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GtUtils.h" #include "FWCore/Framework/interface/Event.h" diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseII.h b/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseII.h new file mode 100644 index 0000000000000..c392f39e1905a --- /dev/null +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseII.h @@ -0,0 +1,178 @@ +#ifndef __L1Analysis_L1AnalysisPhaseII_H__ +#define __L1Analysis_L1AnalysisPhaseII_H__ + +//------------------------------------------------------------------------------- +// Created 02/03/2010 - A.C. Le Bihan +// +// +// Original code : UserCode/L1TriggerDPG/L1ExtraTreeProducer - Jim Brooke +//------------------------------------------------------------------------------- + +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1Trigger/interface/Tau.h" +#include "DataFormats/L1Trigger/interface/Jet.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" + +#include "DataFormats/L1Trigger/interface/L1EmParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1EmParticle.h" +#include "DataFormats/L1Trigger/interface/L1JetParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1JetParticle.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticle.h" +#include "DataFormats/L1Trigger/interface/L1EtMissParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1EtMissParticle.h" +#include "DataFormats/L1Trigger/interface/L1HFRingsFwd.h" +#include "DataFormats/L1Trigger/interface/L1HFRings.h" +#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h" + +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" + +#include "DataFormats/L1TCorrelator/interface/TkMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkGlbMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkGlbMuonFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkEm.h" +#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkElectron.h" +#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkJet.h" +#include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMissFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkTau.h" +#include "DataFormats/L1TCorrelator/interface/TkTauFwd.h" +#include "DataFormats/L1TCorrelator/interface/L1TrkTau.h" +#include "DataFormats/L1TCorrelator/interface/TkEGTau.h" +#include "DataFormats/L1TCorrelator/interface/L1CaloTkTau.h" + +//#include "DataFormats/JetReco/interface/PFJet.h" +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" + +#include "DataFormats/METReco/interface/PFMET.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "DataFormats/L1TParticleFlow/interface/PFTau.h" +#include "DataFormats/L1TParticleFlow/interface/PFTau.h" + +//#include "DataFormats/Phase2L1Taus/interface/L1HPSPFTau.h" +//#include "DataFormats/Phase2L1Taus/interface/L1HPSPFTauFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkBsCandidate.h" +#include "DataFormats/L1TCorrelator/interface/TkBsCandidateFwd.h" + +//#include "DataFormats/L1TMuon/interface/BayesMuCorrelatorTrack.h" + +#include "DataFormats/JetReco/interface/CaloJet.h" + +#include "L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIDataFormat.h" + +namespace L1Analysis { + class L1AnalysisPhaseII { + public: + L1AnalysisPhaseII(); + ~L1AnalysisPhaseII(); + void Reset() { l1extra_.Reset(); } + + // Fill DZ of Vertex, different algorithms + void SetVertices(float z0Puppi, const edm::Handle> TkPrimaryVertex); + + // Old style objects (Phase I) + // void SetJet (const edm::Handle jet, unsigned maxL1Extra); + // void SetSum (const edm::Handle sums, unsigned maxL1Extra); + void SetMuon(const edm::Handle muon, unsigned maxL1Extra); + + // Add new standalone objects + void SetEG(const edm::Handle EG, + const edm::Handle EGHGC, + unsigned maxL1Extra); + void SetMuonKF(const edm::Handle muonKF, + unsigned maxL1Extra, + unsigned int muonDetector); + void SetCaloJet(const edm::Handle calojet, unsigned maxL1Extra, float caloJetHTT); + void SetCaloTau(const edm::Handle calotau, unsigned maxL1Extra); + + // Add L1TrackTriggerObjects + void SetTkEG(const edm::Handle tkEG, + const edm::Handle tkEGHGC, + unsigned maxL1Extra); + void SetTkEGV2(const edm::Handle tkEGV2, + const edm::Handle tkEGV2HGc, + unsigned maxL1Extra); + void SetTkEM(const edm::Handle tkEM, + const edm::Handle tkEMHGC, + unsigned maxL1Extra); + void SetTkGlbMuon(const edm::Handle TkGlbMuon, unsigned maxL1Extra); + void SetTkMuon(const edm::Handle TkMuon, unsigned maxL1Extra); + void SetTkMuonStubs(const edm::Handle TkMuon, + unsigned maxL1Extra, + unsigned int muonDetector); + //void SetTkMuonStubsOMTF (const edm::Handle TkMuonOMTF, unsigned maxL1Extra,unsigned int muonDetector); + + //void SetHSCP (const edm::Handle TkMuonHSCP, unsigned maxL1Extra); + + void SetTrkTau(const edm::Handle tkTau, unsigned maxL1Extra); + void SetCaloTkTau(const edm::Handle L1CaloTkTau, unsigned maxL1Extra); + void SetTkEGTau(const edm::Handle TkEGTau, unsigned maxL1Extra); + + void SetTkJet(const edm::Handle tkTrackerJet, unsigned maxL1Extra); + void SetTkCaloJet(const edm::Handle tkCaloJet, unsigned maxL1Extra); + void SetTkMET(const edm::Handle trackerMETts); + void SetTkMHT(const edm::Handle trackerMHTs); + + // Add new PFJet collections + void SetPFJet(const edm::Handle PFJet, unsigned maxL1Extra); + void SetL1METPF(const edm::Handle> l1MetPF); + void SetPFObjects(const edm::Handle> l1pfCandidates, unsigned maxL1Extra); + // void SetPFJetForMET (const edm::Handle PFJet, unsigned maxL1Extra); // this needs to be done better + + // reco::caloJet collection for "Phase1L1Jets" ... + void SetL1PfPhase1L1TJet(const edm::Handle> l1L1PFPhase1L1Jet, unsigned maxL1Extra); + + // Add new PFTau + void SetPFTaus(const edm::Handle> l1pfTaus, unsigned maxL1Extra); + void SetNNTaus(const edm::Handle> l1nnTaus, unsigned maxL1Extra); + //void SetHPSPFTaus (const edm::Handle HPSPFTau, unsigned maxL1Extra); + void SetNNTauPFs(const edm::Handle> l1nnTauPFs, unsigned maxL1Extra); + + void SetBsCands(const edm::Handle> l1TkBs, unsigned maxL1Extra, int kind); + + L1AnalysisPhaseIIDataFormat* getData() { return &l1extra_; } + + // DiObjects + void SetDiMuonTk(const edm::Handle muon, unsigned maxL1Extra); + + static int transverseCoord(double cxa, + double cya, + double ra, + double cxb, + double cyb, + double rb, + double& xg1, + double& yg1, + double& xg2, + double& yg2) dso_internal; + + // Computes z-coordinate on helix at given transverse coordinates + static double zCoord(const GlobalVector& mom, + const GlobalPoint& pos, + double r, + double xc, + double yc, + double xg, + double yg) dso_internal; + + private: + L1AnalysisPhaseIIDataFormat l1extra_; + int tk_nFitParams_ = 4; // Harcoding this, choosing 4, + // to not have to store the chosen fitParams for all objects in this tree producer as a configuration. + // (it would be cleaner if all objects save the Z directly as well as the pointer to the track, or if + // it is clear that the default is 4 unless specifically stated) + }; +} // namespace L1Analysis +#endif diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIDataFormat.h b/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIDataFormat.h new file mode 100644 index 0000000000000..e252e4beb2766 --- /dev/null +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIDataFormat.h @@ -0,0 +1,724 @@ +#ifndef __L1Analysis_L1AnalysisPhaseIIDataFormat_H__ +#define __L1Analysis_L1AnalysisPhaseIIDataFormat_H__ + +//------------------------------------------------------------------------------- +// Created 20/04/2010 - E. Conte, A.C. Le Bihan +// +// +// Original code : UserCode/L1TriggerDPG/L1ExtraTreeProducer - Jim Brooke +//------------------------------------------------------------------------------- + +#include + +namespace L1Analysis { + struct L1AnalysisPhaseIIDataFormat { + L1AnalysisPhaseIIDataFormat() { Reset(); }; + ~L1AnalysisPhaseIIDataFormat(){}; + + void Reset() { + z0Puppi = 0; + z0VertexTDR = 0; + z0Vertices.clear(); + z0L1TkPV.clear(); + sumL1TkPV.clear(); + nL1TkPVs = 0; + nVertices = 0; + + nCaloTaus = 0; + caloTauEt.clear(); + caloTauEta.clear(); + caloTauPhi.clear(); + caloTauIEt.clear(); + caloTauIEta.clear(); + caloTauIPhi.clear(); + caloTauIso.clear(); + caloTauBx.clear(); + caloTauTowerIPhi.clear(); + caloTauTowerIEta.clear(); + caloTauRawEt.clear(); + caloTauIsoEt.clear(); + caloTauNTT.clear(); + caloTauHasEM.clear(); + caloTauIsMerged.clear(); + caloTauHwQual.clear(); + + nCaloJets = 0; + caloJetEt.clear(); + caloJetEta.clear(); + caloJetPhi.clear(); + caloJetBx.clear(); + + nPfPhase1L1Jets = 0; + pfPhase1L1JetEt.clear(); + pfPhase1L1JetEta.clear(); + pfPhase1L1JetPhi.clear(); + + pfPhase1L1HT.clear(); + pfPhase1L1MHTEt.clear(); + pfPhase1L1MHTPhi.clear(); + nPfPhase1L1MHT = 0; + + caloJetHTDefault = 0; + caloJetHT.clear(); + caloJetMHTEt.clear(); + caloJetMHTPhi.clear(); + nCaloJetMHT = 0; + + nGlobalMuons = 0; + globalMuonPt.clear(); + globalMuonEta.clear(); + globalMuonPhi.clear(); + globalMuonEtaAtVtx.clear(); + globalMuonPhiAtVtx.clear(); + globalMuonIEt.clear(); + globalMuonIEta.clear(); + globalMuonIPhi.clear(); + globalMuonIEtaAtVtx.clear(); + globalMuonIPhiAtVtx.clear(); + globalMuonIDEta.clear(); + globalMuonIDPhi.clear(); + globalMuonChg.clear(); + globalMuonIso.clear(); + globalMuonQual.clear(); + globalMuonTfMuonIdx.clear(); + globalMuonBx.clear(); + + nStandaloneMuons = 0; + standaloneMuonPt.clear(); + standaloneMuonPt2.clear(); + standaloneMuonEta.clear(); + standaloneMuonPhi.clear(); + standaloneMuonChg.clear(); + standaloneMuonQual.clear(); + standaloneMuonBx.clear(); + standaloneMuonRegion.clear(); + standaloneMuonDXY.clear(); + + nEG = 0; + EGEt.clear(); + EGEta.clear(); + EGPhi.clear(); + EGBx.clear(); + EGIso.clear(); + EGzVtx.clear(); + EGHwQual.clear(); + EGHGC.clear(); + EGPassesLooseTrackID.clear(); + EGPassesPhotonID.clear(); + + nTkElectrons = 0; + tkElectronEt.clear(); + tkElectronEta.clear(); + tkElectronPhi.clear(); + tkElectronChg.clear(); + tkElectronBx.clear(); + tkElectronTrkIso.clear(); + tkElectronzVtx.clear(); + tkElectronHwQual.clear(); + tkElectronEGRefPt.clear(); + tkElectronEGRefEta.clear(); + tkElectronEGRefPhi.clear(); + tkElectronHGC.clear(); + tkElectronPassesLooseTrackID.clear(); + tkElectronPassesPhotonID.clear(); + + nTkElectronsV2 = 0; + tkElectronV2Et.clear(); + tkElectronV2Eta.clear(); + tkElectronV2Phi.clear(); + tkElectronV2Chg.clear(); + tkElectronV2Bx.clear(); + tkElectronV2TrkIso.clear(); + tkElectronV2zVtx.clear(); + tkElectronV2HwQual.clear(); + tkElectronV2EGRefPt.clear(); + tkElectronV2EGRefEta.clear(); + tkElectronV2EGRefPhi.clear(); + tkElectronV2HGC.clear(); + tkElectronV2PassesLooseTrackID.clear(); + tkElectronV2PassesPhotonID.clear(); + + nTkPhotons = 0; + tkPhotonEt.clear(); + tkPhotonEta.clear(); + tkPhotonPhi.clear(); + tkPhotonBx.clear(); + tkPhotonTrkIso.clear(); + tkPhotonTrkIsoPV.clear(); + tkPhotonzVtx.clear(); + tkPhotonHwQual.clear(); + tkPhotonEGRefPt.clear(); + tkPhotonEGRefEta.clear(); + tkPhotonEGRefPhi.clear(); + tkPhotonHGC.clear(); + tkPhotonPassesLooseTrackID.clear(); + tkPhotonPassesPhotonID.clear(); + + // TkTaus + nTkTau = 0; + tkTauEt.clear(); + tkTauEta.clear(); + tkTauPhi.clear(); + tkTauBx.clear(); + tkTauTrkIso.clear(); + tkTauzVtx.clear(); + + nCaloTkTau = 0; + caloTkTauEt.clear(); + caloTkTauEta.clear(); + caloTkTauPhi.clear(); + caloTkTauBx.clear(); + caloTkTauTrkIso.clear(); + caloTkTauzVtx.clear(); + + nTkEGTau = 0; + tkEGTauEt.clear(); + tkEGTauEta.clear(); + tkEGTauPhi.clear(); + tkEGTauBx.clear(); + tkEGTauTrkIso.clear(); + tkEGTauzVtx.clear(); + + // TkJets + nTrackerJets = 0; + trackerJetEt.clear(); + trackerJetEta.clear(); + trackerJetPhi.clear(); + trackerJetBx.clear(); + trackerJetzVtx.clear(); + + // TkCaloJets + nTkCaloJets = 0; + tkCaloJetEt.clear(); + tkCaloJetEta.clear(); + tkCaloJetPhi.clear(); + tkCaloJetBx.clear(); + + // tkTkGlbMuons + nTkGlbMuons = 0; + tkGlbMuonPt.clear(); + tkGlbMuonEta.clear(); + tkGlbMuonPhi.clear(); + tkGlbMuonChg.clear(); + tkGlbMuonTrkIso.clear(); + tkGlbMuonBx.clear(); + tkGlbMuonQual.clear(); + tkGlbMuonzVtx.clear(); + tkGlbMuonMuRefPt.clear(); + tkGlbMuonTrkRefPt.clear(); + tkGlbMuonMuRefPhi.clear(); + tkGlbMuonMuRefEta.clear(); + tkGlbMuonDRMuTrack.clear(); + tkGlbMuonNMatchedTracks.clear(); + + nTkMuons = 0; + tkMuonPt.clear(); + tkMuonEta.clear(); + tkMuonPhi.clear(); + tkMuonChg.clear(); + tkMuonTrkIso.clear(); + tkMuonBx.clear(); + tkMuonQual.clear(); + tkMuonzVtx.clear(); + tkMuonMuRefPt.clear(); + tkMuonTrkRefPt.clear(); + tkMuonMuRefPhi.clear(); + tkMuonMuRefEta.clear(); + tkMuonDRMuTrack.clear(); + tkMuonNMatchedTracks.clear(); + tkMuonMuRefChg.clear(); + tkMuonRegion.clear(); + + nTkMuonStubs = 0; + tkMuonStubsPt.clear(); + tkMuonStubsEta.clear(); + tkMuonStubsPhi.clear(); + tkMuonStubsChg.clear(); + tkMuonStubsTrkIso.clear(); + tkMuonStubsBx.clear(); + tkMuonStubsQual.clear(); + tkMuonStubszVtx.clear(); + tkMuonStubsBarrelStubs.clear(); + tkMuonStubsRegion.clear(); + + nTkHSCPs = 0; + tkHSCPsPt.clear(); + tkHSCPsEta.clear(); + tkHSCPsPhi.clear(); + tkHSCPsChg.clear(); + tkHSCPsBx.clear(); + tkHSCPszVtx.clear(); + + // TrackerMet + nTrackerMet = 0; + trackerMetSumEt.clear(); + trackerMetEt.clear(); + trackerMetPhi.clear(); + trackerMetBx.clear(); + + //trackerMHT + nTrackerMHT = 0; + trackerHT.clear(); + trackerMHT.clear(); + trackerMHTPhi.clear(); + + // New Jet Collections + nPuppiJets = 0; + puppiJetEt.clear(); + puppiJetEta.clear(); + puppiJetPhi.clear(); + puppiJetBx.clear(); + puppiJetzVtx.clear(); + puppiJetEtUnCorr.clear(); + + /* nPuppiJetForMETs = 0; + puppiJetForMETEt.clear(); + puppiJetForMETEta.clear(); + puppiJetForMETPhi.clear(); + puppiJetForMETBx.clear(); + puppiJetForMETzVtx.clear(); + puppiJetForMETEtUnCorr.clear(); +*/ + + puppiMETEt = 0; + puppiMETPhi = 0; + puppiHT.clear(); + puppiMHTEt.clear(); + puppiMHTPhi.clear(); + nPuppiMHT = 0; + + nPFMuons = 0; + pfMuonPt.clear(); + pfMuonEta.clear(); + pfMuonPhi.clear(); + pfMuonzVtx.clear(); + pfMuonChg.clear(); + + nPFCands = 0; + pfCandId.clear(); + pfCandEt.clear(); + pfCandEta.clear(); + pfCandPhi.clear(); + pfCandzVtx.clear(); + pfCandChg.clear(); + + nPFTaus = 0; + pfTauEt.clear(); + pfTauEta.clear(); + pfTauPhi.clear(); + pfTauChargedIso.clear(); + pfTauType.clear(); + pfTauIsoFlag.clear(); + pfTauRelIsoFlag.clear(); + pfTauPassesMediumIso.clear(); + pfTauChg.clear(); + pfTauZ0.clear(); + + nNNTaus = 0; + nnTauEt.clear(); + nnTauEta.clear(); + nnTauPhi.clear(); + nnTauChg.clear(); + nnTauChargedIso.clear(); + nnTauFullIso.clear(); + nnTauID.clear(); + nnTauPassLooseNN.clear(); + nnTauPassLoosePF.clear(); + nnTauPassTightPF.clear(); + nnTauPassTightNN.clear(); + + nNNTauPFs = 0; + nnTauPFEt.clear(); + nnTauPFEta.clear(); + nnTauPFPhi.clear(); + nnTauPFChg.clear(); + nnTauPFChargedIso.clear(); + nnTauPFFullIso.clear(); + nnTauPFID.clear(); + nnTauPFPassLooseNN.clear(); + nnTauPFPassLoosePF.clear(); + nnTauPFPassTightPF.clear(); + nnTauPFPassTightNN.clear(); + + nHPSTaus = 0; + hpsTauEt.clear(); + hpsTauEta.clear(); + hpsTauPhi.clear(); + hpsTauChg.clear(); + hpsTauPassTightRelIso.clear(); + hpsTauType.clear(); + hpsTauZ0.clear(); + + nTkBsCands = 0; + tkBsCandPt.clear(); + tkBsCandEta.clear(); + tkBsCandPhi.clear(); + tkBsCandMass.clear(); + tkBsCandPhi1Pt.clear(); + tkBsCandPhi2Pt.clear(); + tkBsCandPhi1Eta.clear(); + tkBsCandPhi2Eta.clear(); + tkBsCandPhi1Phi.clear(); + tkBsCandPhi2Phi.clear(); + tkBsCandPhi1Mass.clear(); + tkBsCandPhi2Mass.clear(); + tkBsCandDRPhiPair.clear(); + tkBsCandDxyPhiPair.clear(); + tkBsCandDzPhiPair.clear(); + tkBsCandKind.clear(); + } + + double z0Puppi; + double z0VertexTDR; + unsigned short int nVertices; + std::vector z0Vertices; + unsigned short int nL1TkPVs; + std::vector z0L1TkPV; + std::vector sumL1TkPV; + + unsigned short int nCaloTaus; + std::vector caloTauEt; + std::vector caloTauEta; + std::vector caloTauPhi; + std::vector caloTauIEt; + std::vector caloTauIEta; + std::vector caloTauIPhi; + std::vector caloTauIso; + std::vector caloTauBx; + std::vector caloTauTowerIPhi; + std::vector caloTauTowerIEta; + std::vector caloTauRawEt; + std::vector caloTauIsoEt; + std::vector caloTauNTT; + std::vector caloTauHasEM; + std::vector caloTauIsMerged; + std::vector caloTauHwQual; + + unsigned short int nCaloJets; + std::vector caloJetEt; + std::vector caloJetEta; + std::vector caloJetPhi; + std::vector caloJetBx; + + unsigned short int nPfPhase1L1Jets; + std::vector pfPhase1L1JetEt; + std::vector pfPhase1L1JetEta; + std::vector pfPhase1L1JetPhi; + + std::vector pfPhase1L1HT; + std::vector pfPhase1L1MHTEt; + std::vector pfPhase1L1MHTPhi; + unsigned int nPfPhase1L1MHT; + + float caloJetHTDefault; + std::vector caloJetHT; + std::vector caloJetMHTEt; + std::vector caloJetMHTPhi; + unsigned int nCaloJetMHT; + + unsigned short int nGlobalMuons; + std::vector globalMuonPt; + std::vector globalMuonEta; + std::vector globalMuonPhi; + std::vector globalMuonEtaAtVtx; + std::vector globalMuonPhiAtVtx; + std::vector globalMuonIEt; + std::vector globalMuonIEta; + std::vector globalMuonIPhi; + std::vector globalMuonIEtaAtVtx; + std::vector globalMuonIPhiAtVtx; + std::vector globalMuonIDEta; + std::vector globalMuonIDPhi; + std::vector globalMuonChg; + std::vector globalMuonIso; + std::vector globalMuonQual; + std::vector globalMuonTfMuonIdx; + std::vector globalMuonBx; + + unsigned short int nStandaloneMuons; + std::vector standaloneMuonPt; + std::vector standaloneMuonPt2; + std::vector standaloneMuonEta; + std::vector standaloneMuonPhi; + std::vector standaloneMuonChg; + std::vector standaloneMuonQual; + std::vector standaloneMuonDXY; + std::vector standaloneMuonBx; + std::vector standaloneMuonRegion; + + unsigned int nEG; + std::vector EGEt; + std::vector EGEta; + std::vector EGPhi; + std::vector EGBx; + std::vector EGIso; + std::vector EGzVtx; + std::vector EGHwQual; + std::vector EGHGC; + std::vector EGPassesLooseTrackID; + std::vector EGPassesPhotonID; + + unsigned int nTkElectrons; + std::vector tkElectronEt; + std::vector tkElectronEta; + std::vector tkElectronPhi; + std::vector tkElectronChg; + std::vector tkElectronBx; + std::vector tkElectronTrkIso; + std::vector tkElectronzVtx; + std::vector tkElectronHwQual; + std::vector tkElectronEGRefPt; + std::vector tkElectronEGRefEta; + std::vector tkElectronEGRefPhi; + std::vector tkElectronHGC; + std::vector tkElectronPassesLooseTrackID; + std::vector tkElectronPassesPhotonID; + + unsigned int nTkElectronsV2; + std::vector tkElectronV2Et; + std::vector tkElectronV2Eta; + std::vector tkElectronV2Phi; + std::vector tkElectronV2Chg; + std::vector tkElectronV2Bx; + std::vector tkElectronV2TrkIso; + std::vector tkElectronV2zVtx; + std::vector tkElectronV2HwQual; + std::vector tkElectronV2EGRefPt; + std::vector tkElectronV2EGRefEta; + std::vector tkElectronV2EGRefPhi; + std::vector tkElectronV2HGC; + std::vector tkElectronV2PassesLooseTrackID; + std::vector tkElectronV2PassesPhotonID; + + unsigned int nTkPhotons; + std::vector tkPhotonEt; + std::vector tkPhotonEta; + std::vector tkPhotonPhi; + std::vector tkPhotonBx; + std::vector tkPhotonTrkIso; + std::vector tkPhotonTrkIsoPV; + std::vector tkPhotonzVtx; + std::vector tkPhotonHwQual; + std::vector tkPhotonEGRefPt; + std::vector tkPhotonEGRefEta; + std::vector tkPhotonEGRefPhi; + std::vector tkPhotonHGC; + std::vector tkPhotonPassesLooseTrackID; + std::vector tkPhotonPassesPhotonID; + + unsigned int nTkTau; + std::vector tkTauEt; + std::vector tkTauEta; + std::vector tkTauPhi; + std::vector tkTauBx; + std::vector tkTauTrkIso; + std::vector tkTauzVtx; + + unsigned int nCaloTkTau; + std::vector caloTkTauEt; + std::vector caloTkTauEta; + std::vector caloTkTauPhi; + std::vector caloTkTauBx; + std::vector caloTkTauTrkIso; + std::vector caloTkTauzVtx; + + unsigned int nTkEGTau; + std::vector tkEGTauEt; + std::vector tkEGTauEta; + std::vector tkEGTauPhi; + std::vector tkEGTauBx; + std::vector tkEGTauTrkIso; + std::vector tkEGTauzVtx; + + unsigned int nTrackerJets; + std::vector trackerJetEt; + std::vector trackerJetEta; + std::vector trackerJetPhi; + std::vector trackerJetBx; + std::vector trackerJetzVtx; + + unsigned int nTkCaloJets; + std::vector tkCaloJetEt; + std::vector tkCaloJetEta; + std::vector tkCaloJetPhi; + std::vector tkCaloJetBx; + std::vector tkCaloJetzVtx; + + unsigned int nTkGlbMuons; + std::vector tkGlbMuonPt; + std::vector tkGlbMuonEta; + std::vector tkGlbMuonPhi; + std::vector tkGlbMuonChg; + std::vector tkGlbMuonIso; + std::vector tkGlbMuonTrkIso; + std::vector tkGlbMuonBx; + std::vector tkGlbMuonQual; + std::vector tkGlbMuonzVtx; + std::vector tkGlbMuonMuRefPt; + std::vector tkGlbMuonTrkRefPt; + std::vector tkGlbMuonMuRefPhi; + std::vector tkGlbMuonMuRefEta; + std::vector tkGlbMuonDRMuTrack; + std::vector tkGlbMuonNMatchedTracks; + + unsigned int nTkMuons; + std::vector tkMuonPt; + std::vector tkMuonEta; + std::vector tkMuonPhi; + std::vector tkMuonChg; + std::vector tkMuonIso; + std::vector tkMuonTrkIso; + std::vector tkMuonFwd; + std::vector tkMuonMip; + std::vector tkMuonRPC; + std::vector tkMuonBx; + std::vector tkMuonQual; + std::vector tkMuonzVtx; + std::vector tkMuonMuRefPt; + std::vector tkMuonTrkRefPt; + std::vector tkMuonMuRefPhi; + std::vector tkMuonMuRefEta; + std::vector tkMuonDRMuTrack; + std::vector tkMuonNMatchedTracks; + std::vector tkMuonMuRefChg; + std::vector tkMuonRegion; + + unsigned int nTkMuonStubs; + std::vector tkMuonStubsPt; + std::vector tkMuonStubsEta; + std::vector tkMuonStubsPhi; + std::vector tkMuonStubsChg; + std::vector tkMuonStubsBx; + std::vector tkMuonStubsTrkIso; + std::vector tkMuonStubsQual; + std::vector tkMuonStubszVtx; + std::vector tkMuonStubsBarrelStubs; + std::vector tkMuonStubsRegion; + + unsigned int nTkHSCPs; + std::vector tkHSCPsPt; + std::vector tkHSCPsEta; + std::vector tkHSCPsPhi; + std::vector tkHSCPsChg; + std::vector tkHSCPsBx; + std::vector tkHSCPszVtx; + + unsigned int nTrackerMet; + std::vector trackerMetSumEt; + std::vector trackerMetEt; + std::vector trackerMetPhi; + std::vector trackerMetBx; + + unsigned int nTrackerMHT; + std::vector trackerHT; + std::vector trackerMHT; + std::vector trackerMHTPhi; + + unsigned int nPuppiJets; + std::vector puppiJetEt; + std::vector puppiJetEta; + std::vector puppiJetPhi; + std::vector puppiJetBx; + std::vector puppiJetzVtx; + std::vector puppiJetEtUnCorr; + + /* + unsigned int nPuppiJetForMETs; + std::vector puppiJetForMETEt; + std::vector puppiJetForMETEta; + std::vector puppiJetForMETPhi; + std::vector puppiJetForMETBx; + std::vector puppiJetForMETzVtx; + std::vector puppiJetForMETEtUnCorr; +*/ + + double puppiMETEt; + double puppiMETPhi; + + std::vector puppiHT; + std::vector puppiMHTEt; + std::vector puppiMHTPhi; + unsigned int nPuppiMHT; + + unsigned int nPFMuons; + std::vector pfMuonPt; + std::vector pfMuonEta; + std::vector pfMuonPhi; + std::vector pfMuonzVtx; + std::vector pfMuonChg; + + unsigned int nPFCands; + std::vector pfCandId; + std::vector pfCandEt; + std::vector pfCandEta; + std::vector pfCandPhi; + std::vector pfCandzVtx; + std::vector pfCandChg; + + unsigned int nPFTaus; + std::vector pfTauEt; + std::vector pfTauEta; + std::vector pfTauPhi; + std::vector pfTauType; + std::vector pfTauChargedIso; + std::vector pfTauIsoFlag; + std::vector pfTauRelIsoFlag; + std::vector pfTauPassesMediumIso; + std::vector pfTauChg; + std::vector pfTauZ0; + + unsigned int nNNTaus; + std::vector nnTauEt; + std::vector nnTauEta; + std::vector nnTauPhi; + std::vector nnTauChg; + std::vector nnTauChargedIso; + std::vector nnTauFullIso; + std::vector nnTauID; + std::vector nnTauPassLooseNN; + std::vector nnTauPassLoosePF; + std::vector nnTauPassTightPF; + std::vector nnTauPassTightNN; + + unsigned int nNNTauPFs; + std::vector nnTauPFEt; + std::vector nnTauPFEta; + std::vector nnTauPFPhi; + std::vector nnTauPFChg; + std::vector nnTauPFChargedIso; + std::vector nnTauPFFullIso; + std::vector nnTauPFID; + std::vector nnTauPFPassLooseNN; + std::vector nnTauPFPassLoosePF; + std::vector nnTauPFPassTightPF; + std::vector nnTauPFPassTightNN; + + unsigned int nHPSTaus; + std::vector hpsTauEt; + std::vector hpsTauEta; + std::vector hpsTauPhi; + std::vector hpsTauChg; + std::vector hpsTauPassTightRelIso; + std::vector hpsTauType; + std::vector hpsTauZ0; + + unsigned int nTkBsCands; + std::vector tkBsCandPt; + std::vector tkBsCandEta; + std::vector tkBsCandPhi; + std::vector tkBsCandMass; + std::vector tkBsCandPhi1Pt; + std::vector tkBsCandPhi2Pt; + std::vector tkBsCandPhi1Eta; + std::vector tkBsCandPhi2Eta; + std::vector tkBsCandPhi1Phi; + std::vector tkBsCandPhi2Phi; + std::vector tkBsCandPhi1Mass; + std::vector tkBsCandPhi2Mass; + std::vector tkBsCandDRPhiPair; + std::vector tkBsCandDxyPhiPair; + std::vector tkBsCandDzPhiPair; + std::vector tkBsCandKind; + }; +} // namespace L1Analysis +#endif diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1.h b/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1.h new file mode 100644 index 0000000000000..ec759698f21c4 --- /dev/null +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1.h @@ -0,0 +1,192 @@ +#ifndef __L1Analysis_L1AnalysisPhaseIIStep1_H__ +#define __L1Analysis_L1AnalysisPhaseIIStep1_H__ + +//------------------------------------------------------------------------------- +// Created 02/03/2010 - A.C. Le Bihan +// +// +// Original code : UserCode/L1TriggerDPG/L1ExtraTreeProducer - Jim Brooke +//------------------------------------------------------------------------------- + +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1Trigger/interface/Tau.h" +#include "DataFormats/L1Trigger/interface/Jet.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" + +#include "DataFormats/L1Trigger/interface/L1EmParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1EmParticle.h" +#include "DataFormats/L1Trigger/interface/L1JetParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1JetParticle.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticle.h" +#include "DataFormats/L1Trigger/interface/L1EtMissParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1EtMissParticle.h" +#include "DataFormats/L1Trigger/interface/L1HFRingsFwd.h" +#include "DataFormats/L1Trigger/interface/L1HFRings.h" +#include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h" + +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" + +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" + +#include "DataFormats/L1TCorrelator/interface/TkMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkGlbMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkGlbMuonFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkEm.h" +#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkElectron.h" +#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkJet.h" +#include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMissFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkTau.h" +#include "DataFormats/L1TCorrelator/interface/TkTauFwd.h" +#include "DataFormats/L1TCorrelator/interface/L1TrkTau.h" +#include "DataFormats/L1TCorrelator/interface/TkEGTau.h" +#include "DataFormats/L1TCorrelator/interface/L1CaloTkTau.h" + +//#include "DataFormats/JetReco/interface/PFJet.h" +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" + +#include "DataFormats/L1Trigger/interface/TkJetWord.h" + +#include "DataFormats/METReco/interface/PFMET.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "DataFormats/L1TParticleFlow/interface/PFTau.h" +#include "DataFormats/L1TParticleFlow/interface/PFTau.h" + +#include "DataFormats/L1TParticleFlow/interface/HPSPFTau.h" +#include "DataFormats/L1TParticleFlow/interface/HPSPFTauFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkBsCandidate.h" +#include "DataFormats/L1TCorrelator/interface/TkBsCandidateFwd.h" + +//#include "DataFormats/L1TMuon/interface/BayesMuCorrelatorTrack.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkHTMissEmulatorProducer.h" + +#include "DataFormats/JetReco/interface/CaloJet.h" + +#include "L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1DataFormat.h" + +namespace L1Analysis { + class L1AnalysisPhaseIIStep1 { + public: + L1AnalysisPhaseIIStep1(); + ~L1AnalysisPhaseIIStep1(); + void Reset() { l1extra_.Reset(); } + + // Fill DZ of Vertex, different algorithms + void SetVertices(float z0Puppi, const edm::Handle> TkPrimaryVertex); + + // Add new standalone objects + void SetEG(const edm::Handle EG, + const edm::Handle EGHGC, + unsigned maxL1Extra); + void SetCaloTau(const edm::Handle calotau, unsigned maxL1Extra); + void SetHPSPFTaus(const edm::Handle HPSPFTau, unsigned maxL1Extra); + void SetCaloJet(const edm::Handle calojet, unsigned maxL1Extra, float caloJetHTT); + + // Add L1TrackTriggerObjects + void SetTkEG(const edm::Handle tkEG, + const edm::Handle tkEGHGC, + unsigned maxL1Extra); + void SetTkEM(const edm::Handle tkEM, + const edm::Handle tkEMHGC, + unsigned maxL1Extra); + +/* + void SetMuonKF(const edm::Handle muonKF, + unsigned maxL1Extra, + unsigned int muonDetector); + void SetMuonEMTF(const edm::Handle muonKF, + unsigned maxL1Extra, + unsigned int muonDetector); + + void SetTkMuon(const edm::Handle TkMuon, unsigned maxL1Extra); + + void SetMuon(const edm::Handle muon, unsigned maxL1Extra); + void SetTkGlbMuon(const edm::Handle TkGlbMuon, unsigned maxL1Extra); +*/ + + void SetGmtMuon(const edm::Handle> gmtMuon, unsigned maxL1Extra); + void SetGmtTkMuon(const edm::Handle> gmtTkMuon, unsigned maxL1Extra); + + // Add new PFJet collections + void SetL1METPF(const edm::Handle> l1MetPF); + + // reco::caloJet collection for "Phase1L1Jets" ... + void SetL1PfPhase1L1TJet(const edm::Handle> l1L1PFPhase1L1Jet, unsigned maxL1Extra); + void SetL1PfPhase1L1TJetMET(const edm::Handle> l1L1PFPhase1L1TJetMET, unsigned maxL1Extra); + void SetL1PfPhase1L1TJetSums(const edm::Handle> l1L1PFPhase1L1TJetSums, + unsigned maxL1Extra); + + void SetPFJet(const edm::Handle PFJet, unsigned maxL1Extra); + void SetL1seededConeMHT(const edm::Handle> l1SeededConeMHT); + + // Add nntaus + void SetNNTaus(const edm::Handle> l1nnTaus, unsigned maxL1Extra); + void SetNNTau2vtxs(const edm::Handle> l1nnTau2vtxs, unsigned maxL1Extra); + + //tkjets, tkmet, tkht + void SetTkJet(const edm::Handle tkTrackerJet, unsigned maxL1Extra); + void SetTkJetDisplaced(const edm::Handle tkTrackerJet, unsigned maxL1Extra); + + void SetTkMET(const edm::Handle> trackerMet); + void SetTkMHT(const edm::Handle> trackerMHT); + void SetTkMHTDisplaced(const edm::Handle> trackerMHT); + + L1AnalysisPhaseIIStep1DataFormat* getData() { return &l1extra_; } + + static int transverseCoord(double cxa, + double cya, + double ra, + double cxb, + double cyb, + double rb, + double& xg1, + double& yg1, + double& xg2, + double& yg2) dso_internal; + + // Computes z-coordinate on helix at given transverse coordinates + static double zCoord(const GlobalVector& mom, + const GlobalPoint& pos, + double r, + double xc, + double yc, + double xg, + double yg) dso_internal; + + private: + L1AnalysisPhaseIIStep1DataFormat l1extra_; + int tk_nFitParams_ = 4; // Harcoding this, choosing 4, + // to not have to store the chosen fitParams for all objects in this tree producer as a configuration. + // (it would be cleaner if all objects save the Z directly as well as the pointer to the track, or if + // it is clear that the default is 4 unless specifically stated) + + const float lsb_pt = Phase2L1GMT::LSBpt; + const float lsb_phi = Phase2L1GMT::LSBphi; + const float lsb_eta = Phase2L1GMT::LSBeta; + const float lsb_z0 = Phase2L1GMT::LSBGTz0; + const float lsb_d0 = Phase2L1GMT::LSBGTd0; + const float lsb_SA_z0 = Phase2L1GMT::LSBSAz0; + const float lsb_SA_d0 = Phase2L1GMT::LSBSAd0; + + }; +} // namespace L1Analysis +#endif diff --git a/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1DataFormat.h b/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1DataFormat.h new file mode 100644 index 0000000000000..7226ef8a84857 --- /dev/null +++ b/L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1DataFormat.h @@ -0,0 +1,630 @@ +#ifndef __L1Analysis_L1AnalysisPhaseIIStep1DataFormat_H__ +#define __L1Analysis_L1AnalysisPhaseIIStep1DataFormat_H__ + +//------------------------------------------------------------------------------- +// Created 20/04/2010 - E. Conte, A.C. Le Bihan +// +// +// Original code : UserCode/L1TriggerDPG/L1ExtraTreeProducer - Jim Brooke +//------------------------------------------------------------------------------- + +#include + +namespace L1Analysis { + struct L1AnalysisPhaseIIStep1DataFormat { + L1AnalysisPhaseIIStep1DataFormat() { Reset(); }; + ~L1AnalysisPhaseIIStep1DataFormat(){}; + + void Reset() { + + z0L1TkPV = 0; + z0L1TkAll.clear(); + nL1TkPVs = 0; + + nCaloTaus = 0; + caloTauPt.clear(); + caloTauEt.clear(); + caloTauEta.clear(); + caloTauPhi.clear(); + caloTauIEt.clear(); + caloTauIEta.clear(); + caloTauIPhi.clear(); + caloTauIso.clear(); + caloTauBx.clear(); + caloTauTowerIPhi.clear(); + caloTauTowerIEta.clear(); + caloTauRawEt.clear(); + caloTauIsoEt.clear(); + caloTauNTT.clear(); + caloTauHasEM.clear(); + caloTauIsMerged.clear(); + caloTauHwQual.clear(); + + nHPSTaus = 0; + hpsTauPt.clear(); + hpsTauEt.clear(); + hpsTauEta.clear(); + hpsTauPhi.clear(); + hpsTauChg.clear(); + hpsTauPassTightRelIso.clear(); + hpsTauPassTightRelIsoMenu.clear(); + hpsTauType.clear(); + hpsTauZ0.clear(); + + nCaloJets = 0; + caloJetPt.clear(); + caloJetEt.clear(); + caloJetEta.clear(); + caloJetPhi.clear(); + caloJetBx.clear(); + + caloJetHT = 0; + caloJetHTMenu.clear(); + caloJetMHTMenuEt.clear(); + caloJetMHTMenuPhi.clear(); + nCaloJetMHTMenu = 0; + + nPhase1PuppiJets = 0; + phase1PuppiJetPt.clear(); + phase1PuppiJetEt.clear(); + phase1PuppiJetEta.clear(); + phase1PuppiJetPhi.clear(); + + phase1PuppiHTMenu.clear(); + phase1PuppiMHTMenuEt.clear(); + phase1PuppiMHTMenuPhi.clear(); + nPhase1PuppiMHTMenu = 0; + + phase1PuppiHT = 0; + phase1PuppiMHTEt = 0; + phase1PuppiMHTPhi = 0; + + phase1PuppiMETEt = 0; + phase1PuppiMETPhi = 0; + + puppiMETEt = 0; + puppiMETPhi = 0; + + nEG = 0; + EGPt.clear(); + EGEt.clear(); + EGEta.clear(); + EGPhi.clear(); + EGBx.clear(); + EGIso.clear(); + EGzVtx.clear(); + EGHwQual.clear(); + EGHGC.clear(); + EGPassesLooseTrackID.clear(); + EGPassesPhotonID.clear(); + + nTkElectrons = 0; + tkElectronPt.clear(); + tkElectronEt.clear(); + tkElectronEta.clear(); + tkElectronPhi.clear(); + tkElectronChg.clear(); + tkElectronBx.clear(); + tkElectronTrkIso.clear(); + tkElectronPfIso.clear(); + tkElectronPuppiIso.clear(); + tkElectronzVtx.clear(); + tkElectronHwQual.clear(); + tkElectronEGRefPt.clear(); + tkElectronEGRefEta.clear(); + tkElectronEGRefPhi.clear(); + tkElectronHGC.clear(); + tkElectronPassesLooseTrackID.clear(); + tkElectronPassesPhotonID.clear(); + + nTkPhotons = 0; + tkPhotonPt.clear(); + tkPhotonEt.clear(); + tkPhotonEta.clear(); + tkPhotonPhi.clear(); + tkPhotonBx.clear(); + tkPhotonTrkIso.clear(); + tkPhotonTrkIsoPV.clear(); + tkPhotonPfIso.clear(); + tkPhotonPfIsoPV.clear(); + tkPhotonPuppiIso.clear(); + tkPhotonPuppiIsoPV.clear(); + tkPhotonzVtx.clear(); + tkPhotonHwQual.clear(); + tkPhotonEGRefPt.clear(); + tkPhotonEGRefEta.clear(); + tkPhotonEGRefPhi.clear(); + tkPhotonHGC.clear(); + tkPhotonPassesLooseTrackID.clear(); + tkPhotonPassesPhotonID.clear(); + +/* + nStandaloneMuons = 0; + standaloneMuonPt.clear(); + standaloneMuonPt2.clear(); + standaloneMuonEta.clear(); + standaloneMuonPhi.clear(); + standaloneMuonChg.clear(); + standaloneMuonQual.clear(); + standaloneMuonBx.clear(); + standaloneMuonRegion.clear(); + standaloneMuonDXY.clear(); + + nTkMuons = 0; + tkMuonPt.clear(); + tkMuonEta.clear(); + tkMuonPhi.clear(); + tkMuonChg.clear(); + tkMuonTrkIso.clear(); + tkMuonBx.clear(); + tkMuonQual.clear(); + tkMuonzVtx.clear(); + tkMuonMuRefPt.clear(); + tkMuonMuRefPhi.clear(); + tkMuonMuRefEta.clear(); + tkMuonDRMuTrack.clear(); + tkMuonNMatchedTracks.clear(); + tkMuonMuRefChg.clear(); + tkMuonRegion.clear(); + + //global + nGlobalMuons = 0; + globalMuonPt.clear(); + globalMuonEta.clear(); + globalMuonPhi.clear(); + globalMuonEtaAtVtx.clear(); + globalMuonPhiAtVtx.clear(); + globalMuonIEt.clear(); + globalMuonIEta.clear(); + globalMuonIPhi.clear(); + globalMuonIEtaAtVtx.clear(); + globalMuonIPhiAtVtx.clear(); + globalMuonIDEta.clear(); + globalMuonIDPhi.clear(); + globalMuonChg.clear(); + globalMuonIso.clear(); + globalMuonQual.clear(); + globalMuonTfMuonIdx.clear(); + globalMuonBx.clear(); + + nTkGlbMuons = 0; + tkGlbMuonPt.clear(); + tkGlbMuonEta.clear(); + tkGlbMuonPhi.clear(); + tkGlbMuonChg.clear(); + tkGlbMuonTrkIso.clear(); + tkGlbMuonBx.clear(); + tkGlbMuonQual.clear(); + tkGlbMuonzVtx.clear(); + tkGlbMuonMuRefPt.clear(); + //tkGlbMuonTrkRefPt.clear(); + tkGlbMuonMuRefPhi.clear(); + tkGlbMuonMuRefEta.clear(); + tkGlbMuonDRMuTrack.clear(); + tkGlbMuonNMatchedTracks.clear(); +*/ + + nGmtMuons = 0; + gmtMuonPt.clear(); + gmtMuonEta.clear(); + gmtMuonPhi.clear(); + gmtMuonZ0.clear(); + gmtMuonD0.clear(); + gmtMuonIPt.clear(); + gmtMuonIEta.clear(); + gmtMuonIPhi.clear(); + gmtMuonIZ0.clear(); + gmtMuonID0.clear(); + gmtMuonChg.clear(); + gmtMuonIso.clear(); + gmtMuonQual.clear(); + gmtMuonBeta.clear(); + gmtMuonBx.clear(); + + nGmtTkMuons = 0; + gmtTkMuonPt.clear(); + gmtTkMuonEta.clear(); + gmtTkMuonPhi.clear(); + gmtTkMuonZ0.clear(); + gmtTkMuonD0.clear(); + + gmtTkMuonIPt.clear(); + gmtTkMuonIEta.clear(); + gmtTkMuonIPhi.clear(); + gmtTkMuonIZ0.clear(); + gmtTkMuonID0.clear(); + gmtTkMuonChg.clear(); + gmtTkMuonIso.clear(); + gmtTkMuonQual.clear(); + gmtTkMuonBeta.clear(); + gmtTkMuonNStubs.clear(); + gmtTkMuonBx.clear(); + + nSeededConePuppiJets = 0; + seededConePuppiJetPt.clear(); + seededConePuppiJetEt.clear(); + seededConePuppiJetEta.clear(); + seededConePuppiJetPhi.clear(); + seededConePuppiJetBx.clear(); + seededConePuppiJetzVtx.clear(); + seededConePuppiJetEtUnCorr.clear(); + + seededConePuppiHT = 0; + seededConePuppiMHTEt = 0; + seededConePuppiMHTPhi = 0; + + nNNTaus = 0; + nnTauPt.clear(); + nnTauEt.clear(); + nnTauEta.clear(); + nnTauPhi.clear(); + nnTauChg.clear(); + nnTauChargedIso.clear(); + nnTauFullIso.clear(); + nnTauID.clear(); + nnTauPassLooseNN.clear(); + nnTauPassLoosePF.clear(); + nnTauPassTightPF.clear(); + nnTauPassTightNN.clear(); + nnTauPassLooseNNMass.clear(); + nnTauPassTightNNMass.clear(); + nnTauPassMass.clear(); + nnTauDXY.clear(); + nnTauZ0.clear(); + + nNNTau2vtxs = 0; + nnTau2vtxPt.clear(); + nnTau2vtxEt.clear(); + nnTau2vtxEta.clear(); + nnTau2vtxPhi.clear(); + nnTau2vtxChg.clear(); + nnTau2vtxChargedIso.clear(); + nnTau2vtxFullIso.clear(); + nnTau2vtxID.clear(); + nnTau2vtxPassLooseNN.clear(); + nnTau2vtxPassLoosePF.clear(); + nnTau2vtxPassTightPF.clear(); + nnTau2vtxPassTightNN.clear(); + nnTau2vtxPassLooseNNMass.clear(); + nnTau2vtxPassTightNNMass.clear(); + nnTau2vtxPassMass.clear(); + nnTau2vtxDXY.clear(); + nnTau2vtxZ0.clear(); + + // TkJets + nTrackerJets = 0; + trackerJetPt.clear(); + trackerJetEt.clear(); + trackerJetEta.clear(); + trackerJetPhi.clear(); + trackerJetBx.clear(); + trackerJetZ0.clear(); + + nTrackerJetsDisplaced = 0; + trackerJetDisplacedPt.clear(); + trackerJetDisplacedEt.clear(); + trackerJetDisplacedEta.clear(); + trackerJetDisplacedPhi.clear(); + trackerJetDisplacedBx.clear(); + trackerJetDisplacedZ0.clear(); + + // TrackerMet + trackerMET = 0; + trackerMETPhi = 0; + + // TrackerMHT (including displaced) + trackerHT = 0; + trackerMHT = 0; + trackerMHTPhi = 0; + + trackerHTDisplaced = 0; + trackerMHTDisplaced = 0; + trackerMHTPhiDisplaced = 0; + + } + + //double z0Puppi; + unsigned short int nL1TkPVs; + std::vector z0L1TkAll; + double z0L1TkPV; + //std::vector sumL1TkPV; + + unsigned short int nCaloTaus; + std::vector caloTauPt; + std::vector caloTauEt; + std::vector caloTauEta; + std::vector caloTauPhi; + std::vector caloTauIEt; + std::vector caloTauIEta; + std::vector caloTauIPhi; + std::vector caloTauIso; + std::vector caloTauBx; + std::vector caloTauTowerIPhi; + std::vector caloTauTowerIEta; + std::vector caloTauRawEt; + std::vector caloTauIsoEt; + std::vector caloTauNTT; + std::vector caloTauHasEM; + std::vector caloTauIsMerged; + std::vector caloTauHwQual; + + unsigned int nHPSTaus; + std::vector hpsTauPt; + std::vector hpsTauEt; + std::vector hpsTauEta; + std::vector hpsTauPhi; + std::vector hpsTauChg; + std::vector hpsTauPassTightRelIso; + std::vector hpsTauPassTightRelIsoMenu; + std::vector hpsTauType; + std::vector hpsTauZ0; + + unsigned short int nCaloJets; + std::vector caloJetPt; + std::vector caloJetEt; + std::vector caloJetEta; + std::vector caloJetPhi; + std::vector caloJetBx; + + float caloJetHT; + std::vector caloJetHTMenu; + std::vector caloJetMHTMenuEt; + std::vector caloJetMHTMenuPhi; + unsigned int nCaloJetMHTMenu; + + unsigned short int nPhase1PuppiJets; + std::vector phase1PuppiJetPt; + std::vector phase1PuppiJetEt; + std::vector phase1PuppiJetEta; + std::vector phase1PuppiJetPhi; + + std::vector phase1PuppiHTMenu; + std::vector phase1PuppiMHTMenuEt; + std::vector phase1PuppiMHTMenuPhi; + unsigned int nPhase1PuppiMHTMenu; + + double phase1PuppiHT; + double phase1PuppiMHTEt; + double phase1PuppiMHTPhi; + + double phase1PuppiMETEt; + double phase1PuppiMETPhi; + + double puppiMETEt; + double puppiMETPhi; + + unsigned int nEG; + std::vector EGPt; + std::vector EGEt; + std::vector EGEta; + std::vector EGPhi; + std::vector EGBx; + std::vector EGIso; + std::vector EGzVtx; + std::vector EGHwQual; + std::vector EGHGC; + std::vector EGPassesLooseTrackID; + std::vector EGPassesPhotonID; + + unsigned int nTkElectrons; + std::vector tkElectronPt; + std::vector tkElectronEt; + std::vector tkElectronEta; + std::vector tkElectronPhi; + std::vector tkElectronChg; + std::vector tkElectronBx; + std::vector tkElectronTrkIso; + std::vector tkElectronPfIso; + std::vector tkElectronPuppiIso; + std::vector tkElectronzVtx; + std::vector tkElectronHwQual; + std::vector tkElectronEGRefPt; + std::vector tkElectronEGRefEta; + std::vector tkElectronEGRefPhi; + std::vector tkElectronHGC; + std::vector tkElectronPassesLooseTrackID; + std::vector tkElectronPassesPhotonID; + + unsigned int nTkPhotons; + std::vector tkPhotonPt; + std::vector tkPhotonEt; + std::vector tkPhotonEta; + std::vector tkPhotonPhi; + std::vector tkPhotonBx; + std::vector tkPhotonTrkIso; + std::vector tkPhotonTrkIsoPV; + std::vector tkPhotonPfIso; + std::vector tkPhotonPfIsoPV; + std::vector tkPhotonPuppiIso; + std::vector tkPhotonPuppiIsoPV; + std::vector tkPhotonzVtx; + std::vector tkPhotonHwQual; + std::vector tkPhotonEGRefPt; + std::vector tkPhotonEGRefEta; + std::vector tkPhotonEGRefPhi; + std::vector tkPhotonHGC; + std::vector tkPhotonPassesLooseTrackID; + std::vector tkPhotonPassesPhotonID; + +/* + unsigned short int nStandaloneMuons; + std::vector standaloneMuonPt; + std::vector standaloneMuonPt2; + std::vector standaloneMuonEta; + std::vector standaloneMuonPhi; + std::vector standaloneMuonChg; + std::vector standaloneMuonQual; + std::vector standaloneMuonDXY; + std::vector standaloneMuonBx; + std::vector standaloneMuonRegion; + + unsigned int nTkMuons; + std::vector tkMuonPt; + std::vector tkMuonEta; + std::vector tkMuonPhi; + std::vector tkMuonChg; + std::vector tkMuonTrkIso; + std::vector tkMuonBx; + std::vector tkMuonQual; + std::vector tkMuonzVtx; + std::vector tkMuonMuRefPt; + std::vector tkMuonMuRefPhi; + std::vector tkMuonMuRefEta; + std::vector tkMuonDRMuTrack; + std::vector tkMuonNMatchedTracks; + std::vector tkMuonMuRefChg; + std::vector tkMuonRegion; + + unsigned short int nGlobalMuons; + std::vector globalMuonPt; + std::vector globalMuonEta; + std::vector globalMuonPhi; + std::vector globalMuonEtaAtVtx; + std::vector globalMuonPhiAtVtx; + std::vector globalMuonIEt; + std::vector globalMuonIEta; + std::vector globalMuonIPhi; + std::vector globalMuonIEtaAtVtx; + std::vector globalMuonIPhiAtVtx; + std::vector globalMuonIDEta; + std::vector globalMuonIDPhi; + std::vector globalMuonChg; + std::vector globalMuonIso; + std::vector globalMuonQual; + std::vector globalMuonTfMuonIdx; + std::vector globalMuonBx; + + unsigned int nTkGlbMuons; + std::vector tkGlbMuonPt; + std::vector tkGlbMuonEta; + std::vector tkGlbMuonPhi; + std::vector tkGlbMuonChg; + //std::vector tkGlbMuonIso; + std::vector tkGlbMuonTrkIso; + std::vector tkGlbMuonBx; + std::vector tkGlbMuonQual; + std::vector tkGlbMuonzVtx; + std::vector tkGlbMuonMuRefPt; + //std::vector tkGlbMuonTrkRefPt; + std::vector tkGlbMuonMuRefPhi; + std::vector tkGlbMuonMuRefEta; + std::vector tkGlbMuonDRMuTrack; + std::vector tkGlbMuonNMatchedTracks; +*/ + + unsigned int nGmtMuons; + std::vector gmtMuonPt; + std::vector gmtMuonEta; + std::vector gmtMuonPhi; + std::vector gmtMuonZ0; + std::vector gmtMuonD0; + std::vector gmtMuonIPt; + std::vector gmtMuonIEta; + std::vector gmtMuonIPhi; + std::vector gmtMuonIZ0; + std::vector gmtMuonID0; + std::vector gmtMuonChg; + std::vector gmtMuonIso; + std::vector gmtMuonQual; + std::vector gmtMuonBeta; + std::vector gmtMuonBx; + + unsigned int nGmtTkMuons; + std::vector gmtTkMuonPt; + std::vector gmtTkMuonEta; + std::vector gmtTkMuonPhi; + std::vector gmtTkMuonZ0; + std::vector gmtTkMuonD0; + std::vector gmtTkMuonIPt; + std::vector gmtTkMuonIEta; + std::vector gmtTkMuonIPhi; + std::vector gmtTkMuonIZ0; + std::vector gmtTkMuonID0; + std::vector gmtTkMuonChg; + std::vector gmtTkMuonIso; + std::vector gmtTkMuonQual; + std::vector gmtTkMuonBeta; + std::vector gmtTkMuonNStubs; + std::vector gmtTkMuonBx; + + unsigned int nSeededConePuppiJets; + std::vector seededConePuppiJetPt; + std::vector seededConePuppiJetEt; + std::vector seededConePuppiJetEta; + std::vector seededConePuppiJetPhi; + std::vector seededConePuppiJetBx; + std::vector seededConePuppiJetzVtx; + std::vector seededConePuppiJetEtUnCorr; + + double seededConePuppiHT; + double seededConePuppiMHTEt; + double seededConePuppiMHTPhi; + + unsigned int nNNTaus; + std::vector nnTauPt; + std::vector nnTauEt; + std::vector nnTauEta; + std::vector nnTauPhi; + std::vector nnTauChg; + std::vector nnTauChargedIso; + std::vector nnTauFullIso; + std::vector nnTauID; + std::vector nnTauPassLooseNN; + std::vector nnTauPassLoosePF; + std::vector nnTauPassTightPF; + std::vector nnTauPassTightNN; + std::vector nnTauPassLooseNNMass; + std::vector nnTauPassTightNNMass; + std::vector nnTauPassMass; + std::vector nnTauDXY; + std::vector nnTauZ0; + + unsigned int nNNTau2vtxs; + std::vector nnTau2vtxPt; + std::vector nnTau2vtxEt; + std::vector nnTau2vtxEta; + std::vector nnTau2vtxPhi; + std::vector nnTau2vtxChg; + std::vector nnTau2vtxChargedIso; + std::vector nnTau2vtxFullIso; + std::vector nnTau2vtxID; + std::vector nnTau2vtxPassLooseNN; + std::vector nnTau2vtxPassLoosePF; + std::vector nnTau2vtxPassTightPF; + std::vector nnTau2vtxPassTightNN; + std::vector nnTau2vtxPassLooseNNMass; + std::vector nnTau2vtxPassTightNNMass; + std::vector nnTau2vtxPassMass; + std::vector nnTau2vtxDXY; + std::vector nnTau2vtxZ0; + + unsigned int nTrackerJets; + std::vector trackerJetPt; + std::vector trackerJetEt; + std::vector trackerJetEta; + std::vector trackerJetPhi; + std::vector trackerJetBx; + std::vector trackerJetZ0; + + unsigned int nTrackerJetsDisplaced; + std::vector trackerJetDisplacedPt; + std::vector trackerJetDisplacedEt; + std::vector trackerJetDisplacedEta; + std::vector trackerJetDisplacedPhi; + std::vector trackerJetDisplacedBx; + std::vector trackerJetDisplacedZ0; + + double trackerMET; + double trackerMETPhi; + + double trackerHT; + double trackerMHT; + double trackerMHTPhi; + + double trackerHTDisplaced; + double trackerMHTDisplaced; + double trackerMHTPhiDisplaced; + + }; +} // namespace L1Analysis +#endif diff --git a/L1Trigger/L1TNtuples/interface/MuonID.h b/L1Trigger/L1TNtuples/interface/MuonID.h index 0cdeafb802f04..a857242669da8 100644 --- a/L1Trigger/L1TNtuples/interface/MuonID.h +++ b/L1Trigger/L1TNtuples/interface/MuonID.h @@ -37,8 +37,9 @@ inline bool isTightMuonCustom(const reco::Muon& recoMu, const reco::Vertex recoV //bp bool isTight = recoMu.isGlobalMuon() && recoMu.isPFMuon() && recoMu.globalTrack()->normalizedChi2() < 10. && recoMu.globalTrack()->hitPattern().numberOfValidMuonHits() > 0 && - recoMu.numberOfMatchedStations() > 1 && fabs(recoMu.muonBestTrack()->dxy(recoVtx.position())) < 0.2 && - fabs(recoMu.muonBestTrack()->dz(recoVtx.position())) < 0.5 && + recoMu.numberOfMatchedStations() > 1 && + std::abs(recoMu.muonBestTrack()->dxy(recoVtx.position())) < 0.2 && + std::abs(recoMu.muonBestTrack()->dz(recoVtx.position())) < 0.5 && recoMu.innerTrack()->hitPattern().numberOfValidPixelHits() > 0 && recoMu.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 && recoMu.globalTrack()->normalizedChi2() < 1; diff --git a/L1Trigger/L1TNtuples/plugins/BuildFile.xml b/L1Trigger/L1TNtuples/plugins/BuildFile.xml index 2b20c036acabc..de0146652d6af 100644 --- a/L1Trigger/L1TNtuples/plugins/BuildFile.xml +++ b/L1Trigger/L1TNtuples/plugins/BuildFile.xml @@ -28,6 +28,11 @@ + + + + + diff --git a/L1Trigger/L1TNtuples/plugins/L1ElectronRecoTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1ElectronRecoTreeProducer.cc index bb505c962ad20..8d1a521609d25 100644 --- a/L1Trigger/L1TNtuples/plugins/L1ElectronRecoTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1ElectronRecoTreeProducer.cc @@ -15,7 +15,7 @@ // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -40,7 +40,7 @@ // class declaration // -class L1ElectronRecoTreeProducer : public edm::EDAnalyzer { +class L1ElectronRecoTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1ElectronRecoTreeProducer(const edm::ParameterSet&); ~L1ElectronRecoTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/plugins/L1EventTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1EventTreeProducer.cc index 99c59b7486d93..72e9f21dde799 100644 --- a/L1Trigger/L1TNtuples/plugins/L1EventTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1EventTreeProducer.cc @@ -22,7 +22,7 @@ Description: Produce L1 Extra tree // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -46,7 +46,7 @@ Description: Produce L1 Extra tree // class declaration // -class L1EventTreeProducer : public edm::EDAnalyzer { +class L1EventTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1EventTreeProducer(const edm::ParameterSet&); ~L1EventTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/plugins/L1ExtraTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1ExtraTreeProducer.cc index c43183e12de1a..28e0cd705ad3a 100644 --- a/L1Trigger/L1TNtuples/plugins/L1ExtraTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1ExtraTreeProducer.cc @@ -22,7 +22,7 @@ Description: Produce L1 Extra tree // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -52,7 +52,7 @@ Description: Produce L1 Extra tree // class declaration // -class L1ExtraTreeProducer : public edm::EDAnalyzer { +class L1ExtraTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1ExtraTreeProducer(const edm::ParameterSet&); ~L1ExtraTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/plugins/L1GenTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1GenTreeProducer.cc index 7b5d34c06704a..d526f9b264ff0 100644 --- a/L1Trigger/L1TNtuples/plugins/L1GenTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1GenTreeProducer.cc @@ -22,7 +22,7 @@ Description: Produce L1 Extra tree // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -38,6 +38,9 @@ Description: Produce L1 Extra tree #include "HepMC/GenVertex.h" #include "DataFormats/HepMCCandidate/interface/GenParticle.h" +#include "DataFormats/METReco/interface/GenMET.h" +#include "DataFormats/METReco/interface/GenMETFwd.h" + #include "SimDataFormats/PileupSummaryInfo/interface/PileupSummaryInfo.h" // ROOT output stuff @@ -51,7 +54,7 @@ Description: Produce L1 Extra tree // class declaration // -class L1GenTreeProducer : public edm::EDAnalyzer { +class L1GenTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1GenTreeProducer(const edm::ParameterSet&); ~L1GenTreeProducer() override; @@ -75,13 +78,22 @@ class L1GenTreeProducer : public edm::EDAnalyzer { // EDM input tags edm::EDGetTokenT genJetToken_; + edm::EDGetTokenT genMETTrueToken_; + edm::EDGetTokenT genMETCaloToken_; edm::EDGetTokenT genParticleToken_; edm::EDGetTokenT> pileupInfoToken_; edm::EDGetTokenT genInfoToken_; + edm::EDGetTokenT hepMCProductTag_; }; L1GenTreeProducer::L1GenTreeProducer(const edm::ParameterSet& iConfig) { + hepMCProductTag_ = consumes( + iConfig.getUntrackedParameter("hepMCProductTag", edm::InputTag("generatorSmeared"))); genJetToken_ = consumes(iConfig.getUntrackedParameter("genJetToken")); + genMETTrueToken_ = consumes( + iConfig.getUntrackedParameter("genMETTrueToken", edm::InputTag("genMetTrue"))); + genMETCaloToken_ = consumes( + iConfig.getUntrackedParameter("genMETCaloToken", edm::InputTag("genMetCalo"))); genParticleToken_ = consumes(iConfig.getUntrackedParameter("genParticleToken")); pileupInfoToken_ = @@ -114,6 +126,7 @@ void L1GenTreeProducer::analyze(const edm::Event& iEvent, const edm::EventSetup& if (genInfo.isValid()) { l1GenData_->weight = genInfo->weight(); l1GenData_->pthat = genInfo->hasBinningValues() ? (genInfo->binningValues())[0] : 0.0; + // std::cout<signalProcessID()< genJets; @@ -126,6 +139,7 @@ void L1GenTreeProducer::analyze(const edm::Event& iEvent, const edm::EventSetup& l1GenData_->jetPt.push_back(jetItr->pt()); l1GenData_->jetEta.push_back(jetItr->eta()); l1GenData_->jetPhi.push_back(jetItr->phi()); + l1GenData_->jetM.push_back(jetItr->mass()); l1GenData_->nJet++; } @@ -133,6 +147,28 @@ void L1GenTreeProducer::analyze(const edm::Event& iEvent, const edm::EventSetup& edm::LogWarning("MissingProduct") << "Gen jets not found. Branch will not be filled" << std::endl; } + edm::Handle genMetsTrue; + iEvent.getByToken(genMETTrueToken_, genMetsTrue); + + if (genMetsTrue.isValid()) { + l1GenData_->genMetTrue = genMetsTrue->at(0).pt(); + + } else { + edm::LogWarning("MissingProduct") << "Gen Met True not found. Branch will not be filled" << std::endl; + } + + edm::Handle genMetsCalo; + iEvent.getByToken(genMETCaloToken_, genMetsCalo); + + //std::cout<< genMetsCalo->at(0).pt()<genMetCalo = genMetsCalo->at(0).pt(); + + } else { + edm::LogWarning("MissingProduct") << "Gen Met Calo not found. Branch will not be filled" << std::endl; + } + edm::Handle genParticles; iEvent.getByToken(genParticleToken_, genParticles); @@ -143,6 +179,11 @@ void L1GenTreeProducer::analyze(const edm::Event& iEvent, const edm::EventSetup& const reco::GenParticle& p = (*genParticles)[i]; int id = p.pdgId(); + double LXY = sqrt(p.vertex().x() * p.vertex().x() + p.vertex().y() * p.vertex().y()); // or rho + double DXY = -p.vertex().x() * sin(p.phi()) + p.vertex().y() * cos(p.phi()); + + //if(abs(id)==13) std::cout<<"p?" <"<"<(p.mother(0))->pdgId(); // // If the parent of this particle is interesting, store all of the info - if ((parentID != p.pdgId()) && - ((parentID > -9999) || (abs(id) == 11) || (abs(id) == 13) || (abs(id) == 23) || (abs(id) == 24) || - (abs(id) == 25) || (abs(id) == 4) || (abs(id) == 5) || (abs(id) == 6))) { + // Maria: also save all the status 1 particles + if (p.status() == 1 || ((parentID != p.pdgId()) && ((parentID > -9999) || (abs(id) == 11) || (abs(id) == 13) || + (abs(id) == 23) || (abs(id) == 24) || (abs(id) == 25) || + (abs(id) == 4) || (abs(id) == 5) || (abs(id) == 6)))) { l1GenData_->partId.push_back(p.pdgId()); l1GenData_->partStat.push_back(p.status()); l1GenData_->partPt.push_back(p.pt()); @@ -171,6 +213,13 @@ void L1GenTreeProducer::analyze(const edm::Event& iEvent, const edm::EventSetup& l1GenData_->partE.push_back(p.energy()); l1GenData_->partParent.push_back(parentID); l1GenData_->partCh.push_back(p.charge()); + l1GenData_->partP.push_back(p.p()); + l1GenData_->partDxy.push_back(DXY); + l1GenData_->partLxy.push_back(LXY); + l1GenData_->partVx.push_back(p.vertex().x()); + l1GenData_->partVy.push_back(p.vertex().y()); + l1GenData_->partVz.push_back(p.vertex().z()); + ++nPart; } } diff --git a/L1Trigger/L1TNtuples/plugins/L1HOTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1HOTreeProducer.cc index 57ddfdfbce7d3..6247736751831 100644 --- a/L1Trigger/L1TNtuples/plugins/L1HOTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1HOTreeProducer.cc @@ -9,7 +9,7 @@ // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -30,7 +30,7 @@ // class declaration // -class L1HOTreeProducer : public edm::EDAnalyzer { +class L1HOTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1HOTreeProducer(const edm::ParameterSet&); ~L1HOTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/plugins/L1JetRecoTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1JetRecoTreeProducer.cc index dd389532c1773..727d8df56783d 100644 --- a/L1Trigger/L1TNtuples/plugins/L1JetRecoTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1JetRecoTreeProducer.cc @@ -15,13 +15,12 @@ // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Framework/interface/ESHandle.h" // cond formats #include "JetMETCorrections/JetCorrector/interface/JetCorrector.h" @@ -55,7 +54,7 @@ // class declaration // -class L1JetRecoTreeProducer : public edm::EDAnalyzer { +class L1JetRecoTreeProducer : public edm::one::EDAnalyzer { public: explicit L1JetRecoTreeProducer(const edm::ParameterSet&); ~L1JetRecoTreeProducer() override; @@ -83,9 +82,6 @@ class L1JetRecoTreeProducer : public edm::EDAnalyzer { L1Analysis::L1AnalysisRecoMetDataFormat* met_data; private: - // output file - edm::Service fs_; - // tree TTree* tree_; @@ -151,6 +147,8 @@ L1JetRecoTreeProducer::L1JetRecoTreeProducer(const edm::ParameterSet& iConfig) muonToken_ = consumes(iConfig.getUntrackedParameter("muonToken", edm::InputTag("muons"))); + usesResource(TFileService::kSharedResource); + jetptThreshold_ = iConfig.getParameter("jetptThreshold"); jetetaMax_ = iConfig.getParameter("jetetaMax"); maxJet_ = iConfig.getParameter("maxJet"); @@ -159,6 +157,7 @@ L1JetRecoTreeProducer::L1JetRecoTreeProducer(const edm::ParameterSet& iConfig) met_data = new L1Analysis::L1AnalysisRecoMetDataFormat(); // set up output + edm::Service fs_; tree_ = fs_->make("JetRecoTree", "JetRecoTree"); tree_->Branch("Jet", "L1Analysis::L1AnalysisRecoJetDataFormat", &jet_data, 32000, 3); tree_->Branch("Sums", "L1Analysis::L1AnalysisRecoMetDataFormat", &met_data, 32000, 3); @@ -389,7 +388,7 @@ void L1JetRecoTreeProducer::doPFJetCorr(edm::Handle pfJet nJets++; - if (it->pt() * corrFactor > jetptThreshold_ && fabs(it->eta()) < jetetaMax_) { + if (it->pt() * corrFactor > jetptThreshold_ && std::abs(it->eta()) < jetetaMax_) { mHx += -1. * it->px() * corrFactor; mHy += -1. * it->py() * corrFactor; met_data->Ht += it->pt() * corrFactor; @@ -420,7 +419,7 @@ void L1JetRecoTreeProducer::doCaloJetCorr(edm::Handle c nCaloJets++; - if (it->pt() * caloCorrFactor > jetptThreshold_ && fabs(it->eta()) < jetetaMax_) { + if (it->pt() * caloCorrFactor > jetptThreshold_ && std::abs(it->eta()) < jetetaMax_) { met_data->caloHt += it->pt() * caloCorrFactor; } } @@ -488,7 +487,7 @@ void L1JetRecoTreeProducer::doCaloMetBE(edm::Handle cal bool L1JetRecoTreeProducer::pfJetID(const reco::PFJet& jet) { bool tmp = true; - if (fabs(jet.eta()) < 2.7) { + if (std::abs(jet.eta()) < 2.7) { tmp &= jet.neutralHadronEnergyFraction() < 0.9; tmp &= jet.neutralEmEnergyFraction() < 0.9; tmp &= (jet.chargedMultiplicity() + jet.neutralMultiplicity()) > 1; @@ -497,12 +496,12 @@ bool L1JetRecoTreeProducer::pfJetID(const reco::PFJet& jet) { tmp &= jet.chargedMultiplicity() > 0; tmp &= jet.chargedEmEnergyFraction() < 0.9; } - if (fabs(jet.eta()) > 2.7 && fabs(jet.eta()) < 3.0) { + if (std::abs(jet.eta()) > 2.7 && std::abs(jet.eta()) < 3.0) { tmp &= jet.neutralEmEnergyFraction() > 0.01; tmp &= jet.neutralHadronEnergyFraction() < 0.98; tmp &= jet.neutralMultiplicity() > 2; } - if (fabs(jet.eta()) > 3.0) { + if (std::abs(jet.eta()) > 3.0) { tmp &= jet.neutralEmEnergyFraction() < 0.9; tmp &= jet.neutralMultiplicity() > 10; } diff --git a/L1Trigger/L1TNtuples/plugins/L1MenuTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1MenuTreeProducer.cc index 071733c74dc00..f6a7322edbcb9 100644 --- a/L1Trigger/L1TNtuples/plugins/L1MenuTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1MenuTreeProducer.cc @@ -22,7 +22,7 @@ Description: Produce L1 Extra tree // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -42,16 +42,16 @@ Description: Produce L1 Extra tree // class declaration // -class L1MenuTreeProducer : public edm::EDAnalyzer { +class L1MenuTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1MenuTreeProducer(const edm::ParameterSet&); ~L1MenuTreeProducer() override; private: void beginJob(void) override; - void beginRun(const edm::Run&, const edm::EventSetup&) override; + void beginRun(const edm::Run&, const edm::EventSetup&); void analyze(const edm::Event&, const edm::EventSetup&) override; - void endRun(const edm::Run&, const edm::EventSetup&) override {} + void endRun(const edm::Run&, const edm::EventSetup&) {} void endJob() override; public: diff --git a/L1Trigger/L1TNtuples/plugins/L1MetFilterRecoTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1MetFilterRecoTreeProducer.cc index 1e1af5cb53398..fc9f25708e207 100644 --- a/L1Trigger/L1TNtuples/plugins/L1MetFilterRecoTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1MetFilterRecoTreeProducer.cc @@ -15,13 +15,12 @@ // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Common/interface/TriggerNames.h" // cond formats @@ -45,7 +44,7 @@ // class declaration // -class L1MetFilterRecoTreeProducer : public edm::EDAnalyzer { +class L1MetFilterRecoTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1MetFilterRecoTreeProducer(const edm::ParameterSet&); ~L1MetFilterRecoTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/plugins/L1MuonRecoTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1MuonRecoTreeProducer.cc index bc0054afa9c20..0a32b63dd3e85 100644 --- a/L1Trigger/L1TNtuples/plugins/L1MuonRecoTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1MuonRecoTreeProducer.cc @@ -17,13 +17,12 @@ UserCode/L1Trigger/src/L1MuonRecoTreeProducer.cc #include // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/MakerMacros.h" #include @@ -99,12 +98,20 @@ UserCode/L1Trigger/src/L1MuonRecoTreeProducer.cc // class declaration // -class L1MuonRecoTreeProducer : public edm::EDAnalyzer { +class L1MuonRecoTreeProducer : public edm::one::EDAnalyzer { public: explicit L1MuonRecoTreeProducer(const edm::ParameterSet &); ~L1MuonRecoTreeProducer() override; - TrajectoryStateOnSurface cylExtrapTrkSam(reco::TrackRef track, double rho); - TrajectoryStateOnSurface surfExtrapTrkSam(reco::TrackRef track, double z); + TrajectoryStateOnSurface cylExtrapTrkSam(reco::TrackRef track, + double rho, + const MagneticField *theMagneticField, + const Propagator &propagatorAlong, + const Propagator &propagatorOpposite); + TrajectoryStateOnSurface surfExtrapTrkSam(reco::TrackRef track, + double z, + const MagneticField *theMagneticField, + const Propagator &propagatorAlong, + const Propagator &propagatorOpposite); void empty_global(); void empty_tracker(); void empty_standalone(); @@ -119,8 +126,8 @@ class L1MuonRecoTreeProducer : public edm::EDAnalyzer { void beginJob(void) override; void analyze(const edm::Event &, const edm::EventSetup &) override; void endJob() override; - void beginRun(const edm::Run &, const edm::EventSetup &) override; - void endRun(const edm::Run &, const edm::EventSetup &) override; + void beginRun(const edm::Run &, const edm::EventSetup &); + void endRun(const edm::Run &, const edm::EventSetup &); public: L1Analysis::L1AnalysisRecoMuon *muon; @@ -150,30 +157,20 @@ class L1MuonRecoTreeProducer : public edm::EDAnalyzer { enum { GL_MUON = 0, SA_MUON = 1, TR_MUON = 2, TRSA_MUON = 3 }; - // GP start - edm::ESHandle cscGeom; - // GP end - - // DT Geometry - edm::ESHandle dtGeom; - - // RPC Geometry - edm::ESHandle rpcGeom; + edm::ESGetToken cscGeomToken_; + edm::ESGetToken rpcGeomToken_; // The Magnetic field - edm::ESHandle theBField; + edm::ESGetToken theBFieldToken_; // The GlobalTrackingGeometry - edm::ESHandle theTrackingGeometry; + edm::ESGetToken theTrackingGeometryToken_; // Extrapolator to cylinder - edm::ESHandle propagatorAlong; - edm::ESHandle propagatorOpposite; - - FreeTrajectoryState freeTrajStateMuon(reco::TrackRef track); + edm::ESGetToken propagatorAlongToken_; + edm::ESGetToken propagatorOppositeToken_; - // output file - edm::Service fs_; + FreeTrajectoryState freeTrajStateMuon(reco::TrackRef track, const MagneticField *theMagneticField); // tree TTree *tree_; @@ -185,7 +182,16 @@ class L1MuonRecoTreeProducer : public edm::EDAnalyzer { edm::InputTag rpcHitTag_; }; -L1MuonRecoTreeProducer::L1MuonRecoTreeProducer(const edm::ParameterSet &iConfig) { +L1MuonRecoTreeProducer::L1MuonRecoTreeProducer(const edm::ParameterSet &iConfig) + : cscGeomToken_(esConsumes(edm::ESInputTag("", ""))), + rpcGeomToken_(esConsumes(edm::ESInputTag("", ""))), + theBFieldToken_(esConsumes(edm::ESInputTag("", ""))), + theTrackingGeometryToken_( + esConsumes(edm::ESInputTag("", ""))), + propagatorAlongToken_( + esConsumes(edm::ESInputTag("SmartPropagatorAny", ""))), + propagatorOppositeToken_( + esConsumes(edm::ESInputTag("SmartPropagatorAnyOpposite", ""))) { maxMuon_ = iConfig.getParameter("maxMuon"); maxRpcHit_ = iConfig.getParameter("maxMuon"); @@ -200,8 +206,11 @@ L1MuonRecoTreeProducer::L1MuonRecoTreeProducer(const edm::ParameterSet &iConfig) rpcHit = new L1Analysis::L1AnalysisRecoRpcHit(); rpcHitData = rpcHit->getData(); + usesResource(TFileService::kSharedResource); + // set up output - tree_ = fs_->make("MuonRecoTree", "MuonRecoTree"); + edm::Service fs; + tree_ = fs->make("MuonRecoTree", "MuonRecoTree"); tree_->Branch("Muon", "L1Analysis::L1AnalysisRecoMuonDataFormat", &muonData, 32000, 3); tree_->Branch("RpcHit", "L1Analysis::L1AnalysisRecoRpcHitDataFormat", &rpcHitData, 32000, 3); @@ -401,22 +410,16 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muon->Reset(); rpcHit->Reset(); - //GP start - // Get the CSC Geometry - iSetup.get().get(cscGeom); - //GP end - - // Get the DT Geometry from the setup - iSetup.get().get(dtGeom); - - // Get the RPC Geometry from the setup - iSetup.get().get(rpcGeom); + const CSCGeometry &cscGeom = iSetup.getData(cscGeomToken_); + const RPCGeometry &rpcGeom = iSetup.getData(rpcGeomToken_); //Get the Magnetic field from the setup - iSetup.get().get(theBField); + const MagneticField &theBField = iSetup.getData(theBFieldToken_); + const MagneticField *theMagneticField = &theBField; // Get the GlobalTrackingGeometry from the setup - iSetup.get().get(theTrackingGeometry); + const GlobalTrackingGeometry &TrackingGeometry = iSetup.getData(theTrackingGeometryToken_); + const GlobalTrackingGeometry *theTrackingGeometry = &TrackingGeometry; edm::Handle rpcRecHits; @@ -447,7 +450,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS int ring = rpcId.ring(); LocalPoint recHitPosLoc = recHitIt->localPosition(); - const BoundPlane &RPCSurface = rpcGeom->roll(rpcId)->surface(); + const BoundPlane &RPCSurface = rpcGeom.roll(rpcId)->surface(); GlobalPoint recHitPosGlob = RPCSurface.toGlobal(recHitPosLoc); float xLoc = recHitPosLoc.x(); @@ -490,8 +493,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS iEvent.getByLabel(edm::InputTag("offlinePrimaryVertices"), vertex); // Get the propagators - iSetup.get().get("SmartPropagatorAny", propagatorAlong); - iSetup.get().get("SmartPropagatorAnyOpposite", propagatorOpposite); + const Propagator &propagatorAlong = iSetup.getData(propagatorAlongToken_); + const Propagator &propagatorOpposite = iSetup.getData(propagatorOppositeToken_); for (reco::MuonCollection::const_iterator imu = mucand->begin(); // for(pat::MuonCollection::const_iterator imu = mucand->begin(); @@ -661,7 +664,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS GlobalPoint gp = GlobalPoint(0.0, 0.0, 0.0); - const CSCChamber *cscchamber = cscGeom->chamber(id); + const CSCChamber *cscchamber = cscGeom.chamber(id); if (!cscchamber) continue; @@ -784,7 +787,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS // Use the track now, and make a transient track out of it (for extrapolations) reco::TrackRef glb_mu = imu->globalTrack(); - reco::TransientTrack ttrack(*glb_mu, &*theBField, theTrackingGeometry); + reco::TransientTrack ttrack(*glb_mu, theMagneticField, theTrackingGeometry); // Track quantities muonData->ch.push_back(glb_mu->charge()); @@ -815,7 +818,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS if (!runOnPostLS1_) { //Extrapolation to HB TrajectoryStateOnSurface tsos; - tsos = cylExtrapTrkSam(glb_mu, 235); + tsos = cylExtrapTrkSam(glb_mu, 235, theMagneticField, propagatorAlong, propagatorOpposite); if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -833,7 +836,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS } //Extrapolation to HE+ - tsos = surfExtrapTrkSam(glb_mu, 479); + tsos = surfExtrapTrkSam(glb_mu, 479, theMagneticField, propagatorAlong, propagatorOpposite); if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -850,7 +853,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS } //Extrapolation to HE- - tsos = surfExtrapTrkSam(glb_mu, -479); + tsos = surfExtrapTrkSam(glb_mu, -479, theMagneticField, propagatorAlong, propagatorOpposite); if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -879,7 +882,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS if (isTR || isGL || isTRSA) { // Take the tracker track and build a transient track out of it reco::TrackRef tr_mu = imu->innerTrack(); - reco::TransientTrack ttrack(*tr_mu, &*theBField, theTrackingGeometry); + reco::TransientTrack ttrack(*tr_mu, theMagneticField, theTrackingGeometry); // Fill track quantities muonData->tr_ch.push_back(tr_mu->charge()); muonData->tr_pt.push_back(tr_mu->pt()); @@ -912,7 +915,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS if (!runOnPostLS1_) { TrajectoryStateOnSurface tsos; - tsos = cylExtrapTrkSam(tr_mu, 410); // track at MB1 radius - extrapolation + tsos = cylExtrapTrkSam( + tr_mu, 410, theMagneticField, propagatorAlong, propagatorOpposite); // track at MB1 radius - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -929,7 +933,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muonData->tr_phi_mb1.push_back(-999999); } - tsos = cylExtrapTrkSam(tr_mu, 500); // track at MB2 radius - extrapolation + tsos = cylExtrapTrkSam( + tr_mu, 500, theMagneticField, propagatorAlong, propagatorOpposite); // track at MB2 radius - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -946,7 +951,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muonData->tr_phi_mb2.push_back(-999999); } - tsos = surfExtrapTrkSam(tr_mu, 630); // track at ME1+ plane - extrapolation + tsos = surfExtrapTrkSam( + tr_mu, 630, theMagneticField, propagatorAlong, propagatorOpposite); // track at ME1+ plane - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -962,7 +968,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muonData->tr_phi_me1_p.push_back(-999999); } - tsos = surfExtrapTrkSam(tr_mu, 790); // track at ME2+ plane - extrapolation + tsos = surfExtrapTrkSam( + tr_mu, 790, theMagneticField, propagatorAlong, propagatorOpposite); // track at ME2+ plane - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -978,7 +985,11 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muonData->tr_phi_me2_p.push_back(-999999); } - tsos = surfExtrapTrkSam(tr_mu, -630); // track at ME1- plane - extrapolation + tsos = surfExtrapTrkSam(tr_mu, + -630, + theMagneticField, + propagatorAlong, + propagatorOpposite); // track at ME1- plane - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -994,7 +1005,11 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muonData->tr_phi_me1_n.push_back(-999999); } - tsos = surfExtrapTrkSam(tr_mu, -790); // track at ME2- plane - extrapolation + tsos = surfExtrapTrkSam(tr_mu, + -790, + theMagneticField, + propagatorAlong, + propagatorOpposite); // track at ME2- plane - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1033,7 +1048,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS // Take the SA track and build a transient track out of it reco::TrackRef sa_mu = imu->outerTrack(); - reco::TransientTrack ttrack(*sa_mu, &*theBField, theTrackingGeometry); + reco::TransientTrack ttrack(*sa_mu, theMagneticField, theTrackingGeometry); // Extrapolation to IP if (ttrack.impactPointTSCP().isValid()) { @@ -1053,7 +1068,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS // Extrapolation to MB2 TrajectoryStateOnSurface tsos; - tsos = cylExtrapTrkSam(sa_mu, 410); // track at MB1 radius - extrapolation + tsos = cylExtrapTrkSam( + sa_mu, 410, theMagneticField, propagatorAlong, propagatorOpposite); // track at MB1 radius - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1070,7 +1086,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muonData->sa_phi_mb1.push_back(-999999); } - tsos = cylExtrapTrkSam(sa_mu, 500); // track at MB2 radius - extrapolation + tsos = cylExtrapTrkSam( + sa_mu, 500, theMagneticField, propagatorAlong, propagatorOpposite); // track at MB2 radius - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1093,7 +1110,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muonData->sa_pseta.push_back(-999999); } - tsos = surfExtrapTrkSam(sa_mu, 630); // track at ME1+ plane - extrapolation + tsos = surfExtrapTrkSam( + sa_mu, 630, theMagneticField, propagatorAlong, propagatorOpposite); // track at ME1+ plane - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1110,7 +1128,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS } // Extrapolation to ME2+ - tsos = surfExtrapTrkSam(sa_mu, 790); + tsos = surfExtrapTrkSam(sa_mu, 790, theMagneticField, propagatorAlong, propagatorOpposite); if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1126,7 +1144,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS muonData->sa_phi_me2_p.push_back(-999999); } - tsos = surfExtrapTrkSam(sa_mu, -630); // track at ME1- plane - extrapolation + tsos = surfExtrapTrkSam( + sa_mu, -630, theMagneticField, propagatorAlong, propagatorOpposite); // track at ME1- plane - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1143,7 +1162,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS } // Extrapolation to ME2- - tsos = surfExtrapTrkSam(sa_mu, -790); // track at ME2- disk - extrapolation + tsos = surfExtrapTrkSam( + sa_mu, -790, theMagneticField, propagatorAlong, propagatorOpposite); // track at ME2- disk - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1160,7 +1180,8 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS } // Extrapolation to HB - tsos = cylExtrapTrkSam(sa_mu, 235); // track at HB radius - extrapolation + tsos = cylExtrapTrkSam( + sa_mu, 235, theMagneticField, propagatorAlong, propagatorOpposite); // track at HB radius - extrapolation if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1178,7 +1199,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS } // Extrapolation to HE+ - tsos = surfExtrapTrkSam(sa_mu, 479); + tsos = surfExtrapTrkSam(sa_mu, 479, theMagneticField, propagatorAlong, propagatorOpposite); if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1195,7 +1216,7 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS } // Extrapolation to HE- - tsos = surfExtrapTrkSam(sa_mu, -479); + tsos = surfExtrapTrkSam(sa_mu, -479, theMagneticField, propagatorAlong, propagatorOpposite); if (tsos.isValid()) { double xx = tsos.globalPosition().x(); double yy = tsos.globalPosition().y(); @@ -1241,40 +1262,49 @@ void L1MuonRecoTreeProducer::analyze(const edm::Event &iEvent, const edm::EventS } // to get the track position info at a particular rho -TrajectoryStateOnSurface L1MuonRecoTreeProducer::cylExtrapTrkSam(reco::TrackRef track, double rho) { +TrajectoryStateOnSurface L1MuonRecoTreeProducer::cylExtrapTrkSam(reco::TrackRef track, + double rho, + const MagneticField *theMagneticField, + const Propagator &propagatorAlong, + const Propagator &propagatorOpposite) { Cylinder::PositionType pos(0, 0, 0); Cylinder::RotationType rot; Cylinder::CylinderPointer myCylinder = Cylinder::build(pos, rot, rho); - FreeTrajectoryState recoStart = freeTrajStateMuon(track); + FreeTrajectoryState recoStart = freeTrajStateMuon(track, theMagneticField); TrajectoryStateOnSurface recoProp; - recoProp = propagatorAlong->propagate(recoStart, *myCylinder); + recoProp = propagatorAlong.propagate(recoStart, *myCylinder); if (!recoProp.isValid()) { - recoProp = propagatorOpposite->propagate(recoStart, *myCylinder); + recoProp = propagatorOpposite.propagate(recoStart, *myCylinder); } return recoProp; } // to get track position at a particular (xy) plane given its z -TrajectoryStateOnSurface L1MuonRecoTreeProducer::surfExtrapTrkSam(reco::TrackRef track, double z) { +TrajectoryStateOnSurface L1MuonRecoTreeProducer::surfExtrapTrkSam(reco::TrackRef track, + double z, + const MagneticField *theMagneticField, + const Propagator &propagatorAlong, + const Propagator &propagatorOpposite) { Plane::PositionType pos(0, 0, z); Plane::RotationType rot; Plane::PlanePointer myPlane = Plane::build(pos, rot); - FreeTrajectoryState recoStart = freeTrajStateMuon(track); + FreeTrajectoryState recoStart = freeTrajStateMuon(track, theMagneticField); TrajectoryStateOnSurface recoProp; - recoProp = propagatorAlong->propagate(recoStart, *myPlane); + recoProp = propagatorAlong.propagate(recoStart, *myPlane); if (!recoProp.isValid()) { - recoProp = propagatorOpposite->propagate(recoStart, *myPlane); + recoProp = propagatorOpposite.propagate(recoStart, *myPlane); } return recoProp; } -FreeTrajectoryState L1MuonRecoTreeProducer::freeTrajStateMuon(reco::TrackRef track) { +FreeTrajectoryState L1MuonRecoTreeProducer::freeTrajStateMuon(reco::TrackRef track, + const MagneticField *theMagneticField) { GlobalPoint innerPoint(track->innerPosition().x(), track->innerPosition().y(), track->innerPosition().z()); GlobalVector innerVec(track->innerMomentum().x(), track->innerMomentum().y(), track->innerMomentum().z()); - FreeTrajectoryState recoStart(innerPoint, innerVec, track->charge(), &*theBField); + FreeTrajectoryState recoStart(innerPoint, innerVec, track->charge(), theMagneticField); return recoStart; } diff --git a/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeProducer.cc new file mode 100644 index 0000000000000..ebb1703315fc5 --- /dev/null +++ b/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeProducer.cc @@ -0,0 +1,651 @@ +// -*- C++ -*- +// +// Package: UserCode/L1TriggerDPG +// Class: L1PhaseIITreeProducer +// +/**\class L1PhaseIITreeProducer L1PhaseIITreeProducer.cc UserCode/L1TriggerDPG/src/L1PhaseIITreeProducer.cc + +Description: Produce L1 Extra tree + +Implementation: + +*/ +// +// Original Author: Alex Tapper +// Created: +// $Id: L1PhaseIITreeProducer.cc,v 1.5 2013/01/06 21:55:55 jbrooke Exp $ +// +// + +// system include files +#include + +// framework +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +// data formats +#include "DataFormats/L1Trigger/interface/L1EmParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1EmParticle.h" +#include "DataFormats/L1Trigger/interface/L1JetParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1JetParticle.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticle.h" +#include "DataFormats/L1Trigger/interface/L1EtMissParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1EtMissParticle.h" +#include "DataFormats/L1TCorrelator/interface/TkMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkGlbMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkGlbMuonFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkEm.h" +#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkElectron.h" +#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkJet.h" +#include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMissFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkTau.h" +#include "DataFormats/L1TCorrelator/interface/TkTauFwd.h" + +#include "DataFormats/L1TCorrelator/interface/L1TrkTau.h" +#include "DataFormats/L1TCorrelator/interface/TkEGTau.h" +#include "DataFormats/L1TCorrelator/interface/L1CaloTkTau.h" + +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1Trigger/interface/Tau.h" +#include "DataFormats/L1Trigger/interface/Jet.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +//#include "DataFormats/L1TVertex/interface/Vertex.h" + +//#include "DataFormats/JetReco/interface/PFJet.h" +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" + +//#include "DataFormats/L1Trigger/interface/PFTau.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "DataFormats/L1TParticleFlow/interface/PFTau.h" + +//#include "DataFormats/Phase2L1Taus/interface/L1HPSPFTau.h" +//#include "DataFormats/Phase2L1Taus/interface/L1HPSPFTauFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkBsCandidate.h" +#include "DataFormats/L1TCorrelator/interface/TkBsCandidateFwd.h" + +#include "DataFormats/JetReco/interface/CaloJet.h" + +//#include "DataFormats/L1TMuon/interface/BayesMuCorrelatorTrack.h" + +// ROOT output stuff +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "TTree.h" + +#include "L1Trigger/L1TNtuples/interface/L1AnalysisPhaseII.h" + +// +// class declaration +// + +class L1PhaseIITreeProducer : public edm::one::EDAnalyzer<> { +public: + explicit L1PhaseIITreeProducer(const edm::ParameterSet&); + ~L1PhaseIITreeProducer() override; + +private: + void beginJob(void) override; + void analyze(const edm::Event&, const edm::EventSetup&) override; + void endJob() override; + +public: + L1Analysis::L1AnalysisPhaseII* l1Extra; + L1Analysis::L1AnalysisPhaseIIDataFormat* l1ExtraData; + +private: + unsigned maxL1Extra_; + + // output file + edm::Service fs_; + + // tree + TTree* tree_; + + edm::EDGetTokenT muonToken_; + + edm::EDGetTokenT caloJetToken_; + + edm::EDGetTokenT egToken_; + edm::EDGetTokenT tkEGToken_; + edm::EDGetTokenT tkEGV2Token_; + edm::EDGetTokenT tkEMToken_; + + edm::EDGetTokenT egTokenHGC_; + edm::EDGetTokenT tkEGTokenHGC_; + edm::EDGetTokenT tkEGV2TokenHGC_; + edm::EDGetTokenT tkEMTokenHGC_; + + edm::EDGetTokenT TkMuonToken_; + edm::EDGetTokenT TkGlbMuonToken_; + + // edm::EDGetTokenT TkMuonStubsTokenBMTF_; + // edm::EDGetTokenT TkMuonStubsTokenEMTF_; + // edm::EDGetTokenT TkMuonStubsTokenOMTF_; // and yet another class... why not? + // edm::EDGetTokenT TkMuonStubsTokenME0_; + // edm::EDGetTokenT TkMuonStubsTokenHSCP_; // and yet another class... why not? + + edm::EDGetTokenT tkTrackerJetToken_; + edm::EDGetTokenT tkMetToken_; + + edm::EDGetTokenT tkTauToken_; + edm::EDGetTokenT tkEGTauToken_; + edm::EDGetTokenT caloTkTauToken_; + + std::vector> tkMhtToken_; + + edm::EDGetTokenT tkCaloJetToken_; + edm::EDGetTokenT caloTauToken_; + edm::EDGetTokenT caloJetHTTToken_; + + edm::EDGetTokenT> ak4L1PF_; + // edm::EDGetTokenT> ak4L1PFForMET_; + + edm::EDGetTokenT muonKalman_; + edm::EDGetTokenT muonOverlap_; + edm::EDGetTokenT muonEndcap_; + + edm::EDGetTokenT> l1PFMet_; + + edm::EDGetTokenT> l1pfPhase1L1TJetToken_; // why are these caloJets??? + + edm::EDGetTokenT z0PuppiToken_; + //edm::EDGetTokenT l1vertextdrToken_; + //edm::EDGetTokenT l1verticesToken_; + edm::EDGetTokenT l1TkPrimaryVertexToken_; + + //edm::EDGetTokenT PFTauToken_; + edm::EDGetTokenT> l1PFCandidates_; + + edm::EDGetTokenT L1NNTauToken_; + edm::EDGetTokenT L1NNTauPFToken_; + + //edm::EDGetTokenT L1HPSPFTauToken_; + + edm::EDGetTokenT L1TkBsCandToken_; + edm::EDGetTokenT L1TkBsCandLooseToken_; + edm::EDGetTokenT L1TkBsCandTightToken_; +}; + +L1PhaseIITreeProducer::L1PhaseIITreeProducer(const edm::ParameterSet& iConfig) { + muonToken_ = consumes(iConfig.getUntrackedParameter("muonToken")); + + caloJetToken_ = consumes(iConfig.getParameter("caloJetToken")); + caloTauToken_ = consumes(iConfig.getParameter("caloTauToken")); + caloJetHTTToken_ = consumes(iConfig.getParameter("caloJetHTTToken")); + + egToken_ = consumes(iConfig.getParameter("egTokenBarrel")); + egTokenHGC_ = consumes(iConfig.getParameter("egTokenHGC")); + + tkEGToken_ = consumes(iConfig.getParameter("tkEGTokenBarrel")); + tkEGV2Token_ = consumes(iConfig.getParameter("tkEGV2TokenBarrel")); + tkEMToken_ = consumes(iConfig.getParameter("tkEMTokenBarrel")); + + tkEGTokenHGC_ = consumes(iConfig.getParameter("tkEGTokenHGC")); + tkEGV2TokenHGC_ = consumes(iConfig.getParameter("tkEGV2TokenHGC")); + tkEMTokenHGC_ = consumes(iConfig.getParameter("tkEMTokenHGC")); + + TkMuonToken_ = consumes(iConfig.getParameter("TkMuonToken")); + + TkGlbMuonToken_ = consumes(iConfig.getParameter("TkGlbMuonToken")); + + //TkMuonStubsTokenBMTF_ = consumes(iConfig.getParameter("TkMuonStubsTokenBMTF")); + //TkMuonStubsTokenEMTF_ = consumes(iConfig.getParameter("TkMuonStubsTokenEMTF")); + //TkMuonStubsTokenOMTF_ = consumes(iConfig.getParameter("TkMuonStubsTokenOMTF")); + //TkMuonStubsTokenME0_ = consumes(iConfig.getParameter("TkMuonStubsTokenME0")); + + //TkMuonStubsTokenHSCP_ = consumes(iConfig.getParameter("TkMuonStubsTokenHSCP")); + + tkTauToken_ = consumes(iConfig.getParameter("tkTauToken")); + caloTkTauToken_ = consumes(iConfig.getParameter("caloTkTauToken")); + tkEGTauToken_ = consumes(iConfig.getParameter("tkEGTauToken")); + + tkTrackerJetToken_ = consumes(iConfig.getParameter("tkTrackerJetToken")); + tkMetToken_ = consumes(iConfig.getParameter("tkMetToken")); + //tkMhtToken_ = consumes(iConfig.getParameter("tkMhtToken")); + + const auto& mhttokens = iConfig.getParameter>("tkMhtTokens"); + for (const auto& mhttoken : mhttokens) { + tkMhtToken_.push_back(consumes(mhttoken)); + } + + tkCaloJetToken_ = consumes(iConfig.getParameter("tkCaloJetToken")); + + ak4L1PF_ = consumes>(iConfig.getParameter("ak4L1PF")); + + l1pfPhase1L1TJetToken_ = + consumes>(iConfig.getParameter("l1pfPhase1L1TJetToken")); + + muonKalman_ = consumes(iConfig.getParameter("muonKalman")); + muonOverlap_ = consumes(iConfig.getParameter("muonOverlap")); + muonEndcap_ = consumes(iConfig.getParameter("muonEndcap")); + + l1PFMet_ = consumes>(iConfig.getParameter("l1PFMet")); + + z0PuppiToken_ = consumes(iConfig.getParameter("zoPuppi")); + //l1vertextdrToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("l1vertextdr")); + //l1verticesToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("l1vertices")); + l1TkPrimaryVertexToken_ = + consumes(iConfig.getParameter("l1TkPrimaryVertex")); + + l1PFCandidates_ = consumes>(iConfig.getParameter("l1PFCandidates")); + //PFTauToken_ = consumes(iConfig.getParameter("PFTauToken")); + + L1NNTauToken_ = consumes(iConfig.getParameter("L1NNTauToken")); + L1NNTauPFToken_ = consumes(iConfig.getParameter("L1NNTauPFToken")); + + //L1HPSPFTauToken_ = consumes(iConfig.getParameter("L1HPSPFTauToken")); + + L1TkBsCandToken_ = consumes(iConfig.getParameter("L1TkBsCandsToken")); + L1TkBsCandLooseToken_ = + consumes(iConfig.getParameter("L1TkBsCandsLooseToken")); + L1TkBsCandTightToken_ = + consumes(iConfig.getParameter("L1TkBsCandsTightToken")); + + maxL1Extra_ = iConfig.getParameter("maxL1Extra"); + + l1Extra = new L1Analysis::L1AnalysisPhaseII(); + l1ExtraData = l1Extra->getData(); + + // set up output + tree_ = fs_->make("L1PhaseIITree", "L1PhaseIITree"); + tree_->Branch("L1PhaseII", "L1Analysis::L1AnalysisPhaseIIDataFormat", &l1ExtraData, 32000, 3); +} + +L1PhaseIITreeProducer::~L1PhaseIITreeProducer() { + // do anything here that needs to be done at desctruction time + // (e.g. close files, deallocate resources etc.) +} + +// +// member functions +// + +// ------------ method called to for each event ------------ +void L1PhaseIITreeProducer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + l1Extra->Reset(); + + edm::Handle muon; + edm::Handle TkGlbMuon; + edm::Handle TkMuon; + edm::Handle TkMuonStubsBMTF; + edm::Handle TkMuonStubsEMTF; + edm::Handle TkMuonStubsME0; + + //edm::Handle TkMuonStubsOMTF; + + iEvent.getByToken(muonToken_, muon); + iEvent.getByToken(TkGlbMuonToken_, TkGlbMuon); + iEvent.getByToken(TkMuonToken_, TkMuon); + // iEvent.getByToken(TkMuonStubsTokenBMTF_,TkMuonStubsBMTF); + // iEvent.getByToken(TkMuonStubsTokenEMTF_,TkMuonStubsEMTF); + // iEvent.getByToken(TkMuonStubsTokenME0_,TkMuonStubsME0); + + // iEvent.getByToken(TkMuonStubsTokenOMTF_,TkMuonStubsOMTF); + + // edm::Handle TkMuonStubsHSCP; + // iEvent.getByToken(TkMuonStubsTokenHSCP_,TkMuonStubsHSCP); + + edm::Handle muonsKalman; + iEvent.getByToken(muonKalman_, muonsKalman); + + edm::Handle muonsOverlap; + iEvent.getByToken(muonOverlap_, muonsOverlap); + + edm::Handle muonsEndcap; + iEvent.getByToken(muonEndcap_, muonsEndcap); + + edm::Handle tkTau; + iEvent.getByToken(tkTauToken_, tkTau); + edm::Handle caloTkTau; + iEvent.getByToken(caloTkTauToken_, caloTkTau); + edm::Handle tkEGTau; + iEvent.getByToken(tkEGTauToken_, tkEGTau); + + //edm::Handle PFTau; + //iEvent.getByToken(PFTauToken_,PFTau); + + edm::Handle l1NNTau; + iEvent.getByToken(L1NNTauToken_, l1NNTau); + + edm::Handle l1NNTauPF; + iEvent.getByToken(L1NNTauPFToken_, l1NNTauPF); + + //edm::Handle l1HPSPFTau; + //iEvent.getByToken(L1HPSPFTauToken_,l1HPSPFTau); + + edm::Handle> l1PFCandidates; + iEvent.getByToken(l1PFCandidates_, l1PFCandidates); + + edm::Handle caloJet; + iEvent.getByToken(caloJetToken_, caloJet); + + edm::Handle caloTau; + iEvent.getByToken(caloTauToken_, caloTau); + + edm::Handle tkTrackerJet; + edm::Handle tkCaloJet; + edm::Handle tkMets; + //edm::Handle tkMhts; + + iEvent.getByToken(tkTrackerJetToken_, tkTrackerJet); + iEvent.getByToken(tkCaloJetToken_, tkCaloJet); + iEvent.getByToken(tkMetToken_, tkMets); + //iEvent.getByToken(tkMhtToken_, tkMhts); + + edm::Handle> ak4L1PFs; + iEvent.getByToken(ak4L1PF_, ak4L1PFs); + // edm::Handle> ak4L1PFForMETs; + // iEvent.getByToken(ak4L1PFForMET_,ak4L1PFForMETs); + + edm::Handle> l1PFMet; + iEvent.getByToken(l1PFMet_, l1PFMet); + + edm::Handle> l1pfPhase1L1TJet; + iEvent.getByToken(l1pfPhase1L1TJetToken_, l1pfPhase1L1TJet); + + // now also fill vertices + + edm::Handle z0Puppi; + iEvent.getByToken(z0PuppiToken_, z0Puppi); + //float Z0=*z0Puppi; + + // edm::Handle > l1vertextdr; + // edm::Handle > l1vertices; + // iEvent.getByToken(l1vertextdrToken_,l1vertextdr); + // iEvent.getByToken(l1verticesToken_,l1vertices); + + edm::Handle> l1TkPrimaryVertex; + iEvent.getByToken(l1TkPrimaryVertexToken_, l1TkPrimaryVertex); + + // Why just a value? no HTMiss? No angles? + edm::Handle caloJetHTTs; + iEvent.getByToken(caloJetHTTToken_, caloJetHTTs); + float caloJetHTT = *caloJetHTTs; + + edm::Handle> tkBsCands; + iEvent.getByToken(L1TkBsCandToken_, tkBsCands); + edm::Handle> tkBsCandsLoose; + iEvent.getByToken(L1TkBsCandLooseToken_, tkBsCandsLoose); + edm::Handle> tkBsCandsTight; + iEvent.getByToken(L1TkBsCandTightToken_, tkBsCandsTight); + + // float vertexTDRZ0=-999; + // if(l1vertextdr->size()>0) vertexTDRZ0=l1vertextdr->at(0).z0(); + + // if(l1vertices.isValid() && l1TkPrimaryVertex.isValid() && l1vertices->size()>0 && l1TkPrimaryVertex->size()>0){ + // l1Extra->SetVertices(Z0,vertexTDRZ0,l1vertices,l1TkPrimaryVertex); + // } + // else { + // edm::LogWarning("MissingProduct") << "One of the L1TVertex collections is not valid " << std::endl; + // std::cout<<"Getting the vertices!"<size() <<" "<< l1vertices->size() <<" "<< l1TkPrimaryVertex->size()<SetCaloJet(caloJet, maxL1Extra_, caloJetHTT); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade caloJets not found. Branch will not be filled" << std::endl; + } + + if (caloTau.isValid()) { + l1Extra->SetCaloTau(caloTau, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade caloTaus not found. Branch will not be filled" << std::endl; + } + + if (muon.isValid()) { + l1Extra->SetMuon(muon, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade Muons not found. Branch will not be filled" << std::endl; + } + + if (muonsKalman.isValid()) { + l1Extra->SetMuonKF(muonsKalman, maxL1Extra_, 1); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade KBMTF Muons not found. Branch will not be filled" << std::endl; + } + + if (muonsOverlap.isValid()) { + l1Extra->SetMuonKF(muonsOverlap, maxL1Extra_, 2); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade KBMTF Muons not found. Branch will not be filled" << std::endl; + } + + if (muonsEndcap.isValid()) { + l1Extra->SetMuonKF(muonsEndcap, maxL1Extra_, 3); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade KBMTF Muons not found. Branch will not be filled" << std::endl; + } + + edm::Handle tkEG; + iEvent.getByToken(tkEGToken_, tkEG); + edm::Handle tkEGHGC; + iEvent.getByToken(tkEGTokenHGC_, tkEGHGC); + + edm::Handle tkEGV2; + iEvent.getByToken(tkEGV2Token_, tkEGV2); + edm::Handle tkEGV2HGC; + iEvent.getByToken(tkEGV2TokenHGC_, tkEGV2HGC); + + if (tkEG.isValid() && tkEGHGC.isValid()) { + l1Extra->SetTkEG(tkEG, tkEGHGC, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkEG not found. Branch will not be filled" << std::endl; + } + + if (tkEGV2.isValid() && tkEGV2HGC.isValid()) { + l1Extra->SetTkEGV2(tkEGV2, tkEGV2HGC, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII tkEGV2 not found. Branch will not be filled" << std::endl; + } + + edm::Handle eg; + iEvent.getByToken(egToken_, eg); + edm::Handle egHGC; + iEvent.getByToken(egTokenHGC_, egHGC); + + if (eg.isValid() && egHGC.isValid()) { + l1Extra->SetEG(eg, egHGC, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII Barrel EG not found. Branch will not be filled" << std::endl; + } + + edm::Handle tkEM; + iEvent.getByToken(tkEMToken_, tkEM); + + edm::Handle tkEMHGC; + iEvent.getByToken(tkEMTokenHGC_, tkEMHGC); + + if (tkEM.isValid() && tkEMHGC.isValid()) { + l1Extra->SetTkEM(tkEM, tkEMHGC, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkEM not found. Branch will not be filled" << std::endl; + } + + if (tkTau.isValid()) { + l1Extra->SetTrkTau(tkTau, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TrkTau not found. Branch will not be filled" << std::endl; + } + if (caloTkTau.isValid()) { + l1Extra->SetCaloTkTau(caloTkTau, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII caloTkTau not found. Branch will not be filled" << std::endl; + } + if (tkEGTau.isValid()) { + l1Extra->SetTkEGTau(tkEGTau, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkEGTau not found. Branch will not be filled" << std::endl; + } + + if (tkTrackerJet.isValid()) { + l1Extra->SetTkJet(tkTrackerJet, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII tkTrackerJets not found. Branch will not be filled" << std::endl; + } + + if (tkCaloJet.isValid()) { + l1Extra->SetTkCaloJet(tkCaloJet, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkCaloJets not found. Branch will not be filled" << std::endl; + } + + if (l1pfPhase1L1TJet.isValid()) { + l1Extra->SetL1PfPhase1L1TJet(l1pfPhase1L1TJet, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII l1pfPhase1L1TJets not found. Branch will not be filled" + << std::endl; + } + + if (TkGlbMuon.isValid()) { + l1Extra->SetTkGlbMuon(TkGlbMuon, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkGlbMuons not found. Branch will not be filled" << std::endl; + } + if (TkMuon.isValid()) { + l1Extra->SetTkMuon(TkMuon, maxL1Extra_); + // l1Extra->SetDiMuonTk(TkMuon,maxL1Extra_); + + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkMuons not found. Branch will not be filled" << std::endl; + } + //if (TkMuonStubsBMTF.isValid()){ + // l1Extra->SetTkMuonStubs(TkMuonStubsBMTF, maxL1Extra_,1); + //} else { + // edm::LogWarning("MissingProduct") << "L1PhaseII TkMuonStubsBMTF not found. Branch will not be filled" << std::endl; + //} + //if (TkMuonStubsOMTF.isValid()){ + // l1Extra->SetTkMuonStubsOMTF(TkMuonStubsOMTF, maxL1Extra_,2); + //} else { + // edm::LogWarning("MissingProduct") << "L1PhaseII TkMuonStubsOMTF not found. Branch will not be filled" << std::endl; + //} + //if (TkMuonStubsEMTF.isValid()){ + // l1Extra->SetTkMuonStubs(TkMuonStubsEMTF, maxL1Extra_,3); + //} else { + // edm::LogWarning("MissingProduct") << "L1PhaseII TkMuonStubsEMTF not found. Branch will not be filled" << std::endl; + //} + + //if (TkMuonStubsME0.isValid()){ + // l1Extra->SetTkMuonStubs(TkMuonStubsME0, maxL1Extra_,4); + //} else { + // edm::LogWarning("MissingProduct") << "L1PhaseII TkMuonStubsME0 not found. Branch will not be filled" << std::endl; + //} + + //if (TkMuonStubsHSCP.isValid()){ + // l1Extra->SetHSCP(TkMuonStubsHSCP, maxL1Extra_); + //} else { + // edm::LogWarning("MissingProduct") << "L1PhaseII TkMuonStubsHSCP not found. Branch will not be filled" << std::endl; + //} + + if (tkMets.isValid()) { + l1Extra->SetTkMET(tkMets); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkMET not found. Branch will not be filled" << std::endl; + } + + for (auto& tkmhttoken : tkMhtToken_) { + edm::Handle tkMhts; + iEvent.getByToken(tkmhttoken, tkMhts); + + if (tkMhts.isValid()) { + l1Extra->SetTkMHT(tkMhts); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkMHT not found. Branch will not be filled" << std::endl; + } + } + + if (ak4L1PFs.isValid()) { + l1Extra->SetPFJet(ak4L1PFs, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII PFJets not found. Branch will not be filled" << std::endl; + } + + /* if (ak4L1PFForMETs.isValid()){ + l1Extra->SetPFJetForMET(ak4L1PFForMETs, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII PFJetForMETs not found. Branch will not be filled" << std::endl; + } +*/ + + if (l1PFMet.isValid()) { + l1Extra->SetL1METPF(l1PFMet); + } else { + edm::LogWarning("MissingProduct") << "L1PFMet missing" << std::endl; + } + + if (l1PFCandidates.isValid()) { + l1Extra->SetPFObjects(l1PFCandidates, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PFCandidates missing, no L1PFMuons will be found" << std::endl; + } + + //if(PFTau.isValid()){ + // l1Extra->SetPFTaus(PFTau,maxL1Extra_); + //} else{ + // edm::LogWarning("MissingProduct") << "PFTaus missing"<SetNNTaus(l1NNTau, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1NNTaus missing" << std::endl; + } + + if (l1NNTauPF.isValid()) { + l1Extra->SetNNTauPFs(l1NNTauPF, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1NNTauPFs missing" << std::endl; + } + + //if(l1HPSPFTau.isValid()){ + // l1Extra->SetHPSPFTaus(l1HPSPFTau,maxL1Extra_); + //} else{ + // edm::LogWarning("MissingProduct") << "L1HPSPFTaus missing"<SetBsCands(tkBsCands, maxL1Extra_, 0); + } else { + edm::LogWarning("MissingProduct") << "L1TkBsCands missing " << std::endl; + } + if (tkBsCandsLoose.isValid()) { + l1Extra->SetBsCands(tkBsCandsLoose, maxL1Extra_, 1); + } else { + edm::LogWarning("MissingProduct") << "L1TkBsCandsLoose missing " << std::endl; + } + if (tkBsCandsTight.isValid()) { + l1Extra->SetBsCands(tkBsCandsTight, maxL1Extra_, 2); + } else { + edm::LogWarning("MissingProduct") << "L1TkBsCandsTight missing " << std::endl; + } + + tree_->Fill(); +} + +// ------------ method called once each job just before starting event loop ------------ +void L1PhaseIITreeProducer::beginJob(void) {} + +// ------------ method called once each job just after ending the event loop ------------ +void L1PhaseIITreeProducer::endJob() {} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1PhaseIITreeProducer); diff --git a/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeStep1Producer.cc b/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeStep1Producer.cc new file mode 100644 index 0000000000000..f4a17cf74c613 --- /dev/null +++ b/L1Trigger/L1TNtuples/plugins/L1PhaseIITreeStep1Producer.cc @@ -0,0 +1,603 @@ +// -*- C++ -*- +// +// Package: UserCode/L1TriggerDPG +// Class: L1PhaseIITreeStep1Producer +// +/**\class L1PhaseIITreeStep1Producer L1PhaseIITreeStep1Producer.cc UserCode/L1TriggerDPG/src/L1PhaseIITreeStep1Producer.cc + +//This is a tree producer for L1 TDR Step 1 Menu - for the extended version, go for L1PhaseIITreeProducer.cc + +Description: Produce L1 Extra tree + +Implementation: + +*/ +// +// Original Author: Alex Tapper +// Created: +// $Id: L1PhaseIITreeProducer.cc,v 1.5 2013/01/06 21:55:55 jbrooke Exp $ +// +// + +// system include files +#include + +// framework +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +// data formats +#include "DataFormats/L1Trigger/interface/L1EmParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1EmParticle.h" +#include "DataFormats/L1Trigger/interface/L1JetParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1JetParticle.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticle.h" +#include "DataFormats/L1Trigger/interface/L1EtMissParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1EtMissParticle.h" +#include "DataFormats/L1TCorrelator/interface/TkMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkGlbMuon.h" +#include "DataFormats/L1TCorrelator/interface/TkGlbMuonFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkEm.h" +#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkElectron.h" +#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkJet.h" +#include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMissFwd.h" + +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" + +#include "DataFormats/L1TCorrelator/interface/TkTau.h" +#include "DataFormats/L1TCorrelator/interface/TkTauFwd.h" + +#include "DataFormats/L1TCorrelator/interface/L1TrkTau.h" +#include "DataFormats/L1TCorrelator/interface/TkEGTau.h" +#include "DataFormats/L1TCorrelator/interface/L1CaloTkTau.h" + +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1Trigger/interface/Tau.h" +#include "DataFormats/L1Trigger/interface/Jet.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" + +#include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" + +//#include "DataFormats/JetReco/interface/PFJet.h" +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" + +//#include "DataFormats/L1Trigger/interface/PFTau.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "DataFormats/L1TParticleFlow/interface/PFTau.h" + +#include "DataFormats/L1Trigger/interface/TkJetWord.h" + +#include "DataFormats/L1TParticleFlow/interface/HPSPFTau.h" +#include "DataFormats/L1TParticleFlow/interface/HPSPFTauFwd.h" + +#include "DataFormats/L1TCorrelator/interface/TkBsCandidate.h" +#include "DataFormats/L1TCorrelator/interface/TkBsCandidateFwd.h" + +#include "DataFormats/JetReco/interface/CaloJet.h" + +//#include "DataFormats/L1TMuon/interface/BayesMuCorrelatorTrack.h" + +// ROOT output stuff +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "TTree.h" + +#include "L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1.h" +#include "L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1DataFormat.h" + +// +// class declaration +// + +class L1PhaseIITreeStep1Producer : public edm::one::EDAnalyzer<> { +public: + explicit L1PhaseIITreeStep1Producer(const edm::ParameterSet&); + ~L1PhaseIITreeStep1Producer() override; + +private: + void beginJob(void) override; + void analyze(const edm::Event&, const edm::EventSetup&) override; + void endJob() override; + +public: + L1Analysis::L1AnalysisPhaseIIStep1* l1Extra; + L1Analysis::L1AnalysisPhaseIIStep1DataFormat* l1ExtraData; + +private: + unsigned maxL1Extra_; + + // output file + edm::Service fs_; + + // tree + TTree* tree_; + + //Include only the step1 menu objects + edm::EDGetTokenT egToken_; + edm::EDGetTokenT tkEGToken_; + edm::EDGetTokenT tkEMToken_; + + edm::EDGetTokenT egTokenHGC_; + edm::EDGetTokenT tkEGTokenHGC_; + edm::EDGetTokenT tkEMTokenHGC_; + + edm::EDGetTokenT muonKalman_; + edm::EDGetTokenT muonOverlap_; + edm::EDGetTokenT muonEndcap_; + edm::EDGetTokenT TkMuonToken_; + + edm::EDGetTokenT muonToken_; + edm::EDGetTokenT TkGlbMuonToken_; + + edm::EDGetTokenT> gmtMuonToken_; + edm::EDGetTokenT> gmtTkMuonToken_; + + edm::EDGetTokenT caloTauToken_; + edm::EDGetTokenT L1HPSPFTauToken_; + edm::EDGetTokenT caloJetToken_; + edm::EDGetTokenT caloJetHTTToken_; + + edm::EDGetTokenT> l1PFMet_; + + edm::EDGetTokenT> l1pfPhase1L1TJetToken_; // why are these caloJets??? + edm::EDGetTokenT> l1pfPhase1L1TJetMET_; + edm::EDGetTokenT> l1pfPhase1L1TJetSums_; + + edm::EDGetTokenT> scPFL1Puppi_; + edm::EDGetTokenT> scPFL1PuppiMHT_; + + + //edm::EDGetTokenT z0PuppiToken_; + //edm::EDGetTokenT l1vertextdrToken_; + //edm::EDGetTokenT l1verticesToken_; + edm::EDGetTokenT l1TkPrimaryVertexToken_; + + edm::EDGetTokenT L1NNTauToken_; + edm::EDGetTokenT L1NNTau2vtxToken_; + + //adding tkjets, tkmet, tkht + edm::EDGetTokenT tkTrackerJetToken_; + edm::EDGetTokenT tkTrackerJetDisplacedToken_; + + edm::EDGetTokenT> tkMetToken_; //was TkEtMissCollection like displaced + edm::EDGetTokenT> tkMhtToken_; + + edm::EDGetTokenT> tkMhtDisplacedToken_; +}; + +L1PhaseIITreeStep1Producer::L1PhaseIITreeStep1Producer(const edm::ParameterSet& iConfig) { + caloTauToken_ = consumes(iConfig.getParameter("caloTauToken")); + L1HPSPFTauToken_ = consumes(iConfig.getParameter("L1HPSPFTauToken")); + caloJetToken_ = consumes(iConfig.getParameter("caloJetToken")); + caloJetHTTToken_ = consumes(iConfig.getParameter("caloJetHTTToken")); + + egToken_ = consumes(iConfig.getParameter("egTokenBarrel")); + egTokenHGC_ = consumes(iConfig.getParameter("egTokenHGC")); + + tkEGToken_ = consumes(iConfig.getParameter("tkEGTokenBarrel")); + tkEMToken_ = consumes(iConfig.getParameter("tkEMTokenBarrel")); + + tkEGTokenHGC_ = consumes(iConfig.getParameter("tkEGTokenHGC")); + tkEMTokenHGC_ = consumes(iConfig.getParameter("tkEMTokenHGC")); + +/* muonKalman_ = consumes(iConfig.getParameter("muonKalman")); + muonOverlap_ = consumes(iConfig.getParameter("muonOverlap")); + muonEndcap_ = consumes(iConfig.getParameter("muonEndcap")); + TkMuonToken_ = consumes(iConfig.getParameter("TkMuonToken")); +*/ + + //global muons +// muonToken_ = consumes(iConfig.getUntrackedParameter("muonToken")); +// TkGlbMuonToken_ = consumes(iConfig.getParameter("TkGlbMuonToken")); + + gmtMuonToken_ = consumes>(iConfig.getParameter("gmtMuonToken")); + gmtTkMuonToken_ = consumes>(iConfig.getParameter("gmtTkMuonToken")); + + l1PFMet_ = consumes>(iConfig.getParameter("l1PFMet")); + + scPFL1Puppi_ = consumes>(iConfig.getParameter("scPFL1Puppi")); + scPFL1PuppiMHT_ = consumes>(iConfig.getParameter("scPFL1PuppiMHT")); + + l1pfPhase1L1TJetToken_ = + consumes>(iConfig.getParameter("l1pfPhase1L1TJetToken")); + l1pfPhase1L1TJetMET_ = consumes>(iConfig.getParameter("l1pfPhase1L1TJetMET")); + l1pfPhase1L1TJetSums_ = + consumes>(iConfig.getParameter("l1pfPhase1L1TJetSums")); + + //z0PuppiToken_ = consumes(iConfig.getParameter("zoPuppi")); + // -> Gone after cleaning the simulated info + + //l1vertextdrToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("l1vertextdr")); + //l1verticesToken_ = consumes< l1t::VertexCollection> (iConfig.getParameter("l1vertices")); + l1TkPrimaryVertexToken_ = + consumes(iConfig.getParameter("l1TkPrimaryVertex")); + + L1NNTauToken_ = consumes(iConfig.getParameter("L1NNTauToken")); + L1NNTau2vtxToken_ = consumes(iConfig.getParameter("L1NNTau2vtxToken")); + + tkTrackerJetToken_ = consumes(iConfig.getParameter("tkTrackerJetToken")); + tkTrackerJetDisplacedToken_ = + consumes(iConfig.getParameter("tkTrackerJetDisplacedToken")); + + tkMetToken_ = consumes>(iConfig.getParameter("tkMetToken")); + + tkMhtToken_ = consumes>(iConfig.getParameter("tkMhtToken")); + tkMhtDisplacedToken_ = consumes>(iConfig.getParameter("tkMhtDisplacedToken")); + + /*const auto& mhttokens = iConfig.getParameter>("tkMhtTokens"); + for (const auto& mhttoken : mhttokens) { + tkMhtToken_.push_back(consumes(mhttoken)); + } + + const auto& mhtdisplacedtokens = iConfig.getParameter>("tkMhtDisplacedTokens"); + for (const auto& mhtdisplacedtoken : mhtdisplacedtokens) { + tkMhtDisplacedToken_.push_back(consumes(mhtdisplacedtoken)); + }*/ + + maxL1Extra_ = iConfig.getParameter("maxL1Extra"); + + l1Extra = new L1Analysis::L1AnalysisPhaseIIStep1(); + l1ExtraData = l1Extra->getData(); + + // set up output + tree_ = fs_->make("L1PhaseIITree", "L1PhaseIITree"); + tree_->Branch("L1PhaseII", "L1Analysis::L1AnalysisPhaseIIStep1DataFormat", &l1ExtraData, 32000, 3); +} + +L1PhaseIITreeStep1Producer::~L1PhaseIITreeStep1Producer() { + // do anything here that needs to be done at desctruction time + // (e.g. close files, deallocate resources etc.) +} + +// +// member functions +// + +// ------------ method called to for each event ------------ +void L1PhaseIITreeStep1Producer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + l1Extra->Reset(); + +/* edm::Handle muonsKalman; + iEvent.getByToken(muonKalman_, muonsKalman); + + edm::Handle muonsOverlap; + iEvent.getByToken(muonOverlap_, muonsOverlap); + + edm::Handle muonsEndcap; + iEvent.getByToken(muonEndcap_, muonsEndcap); + + edm::Handle TkMuon; + iEvent.getByToken(TkMuonToken_, TkMuon); + + edm::Handle muon; + edm::Handle TkGlbMuon; + + iEvent.getByToken(muonToken_, muon); + iEvent.getByToken(TkGlbMuonToken_, TkGlbMuon); +*/ + + edm::Handle> gmtMuon; + edm::Handle> gmtTkMuon; + + iEvent.getByToken(gmtMuonToken_, gmtMuon); + iEvent.getByToken(gmtTkMuonToken_, gmtTkMuon); + + edm::Handle l1NNTau; + iEvent.getByToken(L1NNTauToken_, l1NNTau); + + edm::Handle l1NNTau2vtx; + iEvent.getByToken(L1NNTau2vtxToken_, l1NNTau2vtx); + + edm::Handle caloTau; + iEvent.getByToken(caloTauToken_, caloTau); + + edm::Handle l1HPSPFTau; + iEvent.getByToken(L1HPSPFTauToken_, l1HPSPFTau); + + edm::Handle> l1PFMet; + iEvent.getByToken(l1PFMet_, l1PFMet); + + edm::Handle caloJet; + iEvent.getByToken(caloJetToken_, caloJet); + + edm::Handle caloJetHTTs; + iEvent.getByToken(caloJetHTTToken_, caloJetHTTs); + float caloJetHTT = *caloJetHTTs; + + edm::Handle> l1pfPhase1L1TJet; + iEvent.getByToken(l1pfPhase1L1TJetToken_, l1pfPhase1L1TJet); + + edm::Handle> l1pfPhase1L1TJetMET; + iEvent.getByToken(l1pfPhase1L1TJetMET_, l1pfPhase1L1TJetMET); + + edm::Handle> l1pfPhase1L1TJetSums; + iEvent.getByToken(l1pfPhase1L1TJetSums_, l1pfPhase1L1TJetSums); + + edm::Handle> scPFL1Puppis; + iEvent.getByToken(scPFL1Puppi_, scPFL1Puppis); + + edm::Handle> scPFL1PuppiMHTs; + iEvent.getByToken(scPFL1PuppiMHT_, scPFL1PuppiMHTs); + + + // now also fill vertices + +/* edm::Handle z0Puppi; + iEvent.getByToken(z0PuppiToken_, z0Puppi); + float Z0 = *z0Puppi; +*/ + + // edm::Handle > l1vertextdr; + // edm::Handle > l1vertices; + // iEvent.getByToken(l1vertextdrToken_,l1vertextdr); + // iEvent.getByToken(l1verticesToken_,l1vertices); + + //edm::Handle l1TkPrimaryVertex; + //iEvent.getByToken(l1TkPrimaryVertexToken_, l1TkPrimaryVertex); + + edm::Handle> l1TkPrimaryVertex; + iEvent.getByToken(l1TkPrimaryVertexToken_, l1TkPrimaryVertex); + + //tkjet, tkmet, tkht + edm::Handle tkTrackerJet; + edm::Handle tkTrackerJetDisplaced; + + edm::Handle> tkMets; //was TkEtMissCollection + + edm::Handle> tkMhts; + edm::Handle> tkMhtsDisplaced; + + iEvent.getByToken(tkTrackerJetToken_, tkTrackerJet); + iEvent.getByToken(tkTrackerJetDisplacedToken_, tkTrackerJetDisplaced); + + iEvent.getByToken(tkMetToken_, tkMets); + + iEvent.getByToken(tkMhtToken_, tkMhts); + iEvent.getByToken(tkMhtDisplacedToken_, tkMhtsDisplaced); + + if (tkTrackerJet.isValid()) { + l1Extra->SetTkJet(tkTrackerJet, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII tkTrackerJets not found. Branch will not be filled" << std::endl; + } + + if (tkTrackerJetDisplaced.isValid()) { + l1Extra->SetTkJetDisplaced(tkTrackerJetDisplaced, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII tkTrackerJetDisplaced not found. Branch will not be filled" + << std::endl; + } + + if (tkMets.isValid()) { + l1Extra->SetTkMET(tkMets); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkMET not found. Branch will not be filled" << std::endl; + } + + + /*for (auto& tkmhttoken : tkMhtToken_) { + edm::Handle tkMhts; + iEvent.getByToken(tkmhttoken, tkMhts);*/ + + if (tkMhts.isValid()) { + l1Extra->SetTkMHT(tkMhts); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkMHT not found. Branch will not be filled" << std::endl; + } + + /*for (auto& tkmhtdisplacedtoken : tkMhtDisplacedToken_) { + edm::Handle tkMhtsDisplaced; + iEvent.getByToken(tkmhtdisplacedtoken, tkMhtsDisplaced);*/ + + if (tkMhtsDisplaced.isValid()) { + l1Extra->SetTkMHTDisplaced(tkMhtsDisplaced); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkMHT Displaced not found. Branch will not be filled" << std::endl; + } + + // float vertexTDRZ0=-999; + // if(l1vertextdr->size()>0) vertexTDRZ0=l1vertextdr->at(0).z0(); + /* + if(l1vertices.isValid() && l1TkPrimaryVertex.isValid() && l1vertices->size()>0 && l1TkPrimaryVertex->size()>0){ + l1Extra->SetVertices(Z0,vertexTDRZ0,l1vertices,l1TkPrimaryVertex); + } + else { + edm::LogWarning("MissingProduct") << "One of the L1TVertex collections is not valid " << std::endl; + std::cout<<"Getting the vertices!"<size() <<" "<< l1vertices->size() <<" "<< l1TkPrimaryVertex->size()<empty()) { + l1Extra->SetVertices(0, l1TkPrimaryVertex); // We should change this function + } else { + edm::LogWarning("MissingProduct") << "One of the L1TVertex collections is not valid " << std::endl; + std::cout << "Getting the vertices!" << std::endl; + std::cout << 0 << " " << l1TkPrimaryVertex->size() << std::endl; + } + + if (caloTau.isValid()) { + l1Extra->SetCaloTau(caloTau, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade caloTaus not found. Branch will not be filled" << std::endl; + } + + if (l1HPSPFTau.isValid()) { + l1Extra->SetHPSPFTaus(l1HPSPFTau, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1HPSPFTaus missing" << std::endl; + } + + if (caloJet.isValid()) { + l1Extra->SetCaloJet(caloJet, maxL1Extra_, caloJetHTT); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade caloJets not found. Branch will not be filled" << std::endl; + } + + edm::Handle tkEG; + iEvent.getByToken(tkEGToken_, tkEG); + edm::Handle tkEGHGC; + iEvent.getByToken(tkEGTokenHGC_, tkEGHGC); + + if (tkEG.isValid() && tkEGHGC.isValid()) { + l1Extra->SetTkEG(tkEG, tkEGHGC, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkEG not found. Branch will not be filled" << std::endl; + } + + edm::Handle eg; + iEvent.getByToken(egToken_, eg); + edm::Handle egHGC; + iEvent.getByToken(egTokenHGC_, egHGC); + + if (eg.isValid() && egHGC.isValid()) { + l1Extra->SetEG(eg, egHGC, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII Barrel EG not found. Branch will not be filled" << std::endl; + } + + edm::Handle tkEM; + iEvent.getByToken(tkEMToken_, tkEM); + + edm::Handle tkEMHGC; + iEvent.getByToken(tkEMTokenHGC_, tkEMHGC); + + if (tkEM.isValid() && tkEMHGC.isValid()) { + l1Extra->SetTkEM(tkEM, tkEMHGC, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkEM not found. Branch will not be filled" << std::endl; + } + + if (l1pfPhase1L1TJet.isValid()) { + l1Extra->SetL1PfPhase1L1TJet(l1pfPhase1L1TJet, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII l1pfPhase1L1TJets not found. Branch will not be filled" + << std::endl; + } + + if (l1pfPhase1L1TJetMET.isValid()) { + l1Extra->SetL1PfPhase1L1TJetMET(l1pfPhase1L1TJetMET, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII l1pfPhase1L1TJetMET not found. Branch will not be filled" + << std::endl; + } + + if (l1pfPhase1L1TJetSums.isValid()) { + l1Extra->SetL1PfPhase1L1TJetSums(l1pfPhase1L1TJetSums, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII l1pfPhase1L1TJetSums not found. Branch will not be filled" + << std::endl; + } + + if (scPFL1Puppis.isValid()) { + l1Extra->SetPFJet(scPFL1Puppis, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII scJets not found. Branch will not be filled" << std::endl; + } + + if (scPFL1PuppiMHTs.isValid()) { + l1Extra->SetL1seededConeMHT(scPFL1PuppiMHTs); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII seededCone PuppiMHT not found. Branch will not be filled" << std::endl; + } + +/* + if (muonsKalman.isValid()) { + l1Extra->SetMuonKF(muonsKalman, maxL1Extra_, 1); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade KBMTF Muons not found. Branch will not be filled" << std::endl; + } + + if (muonsOverlap.isValid()) { + l1Extra->SetMuonKF(muonsOverlap, maxL1Extra_, 2); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade KBMTF Muons not found. Branch will not be filled" << std::endl; + } + + if (muonsEndcap.isValid()) { + l1Extra->SetMuonEMTF(muonsEndcap, maxL1Extra_, 3); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade EMTF track Muons not found. Branch will not be filled" << std::endl; + } + + if (TkMuon.isValid()) { + l1Extra->SetTkMuon(TkMuon, maxL1Extra_); + // l1Extra->SetDiMuonTk(TkMuon,maxL1Extra_); + + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkMuons not found. Branch will not be filled" << std::endl; + } + + if (muon.isValid()) { + l1Extra->SetMuon(muon, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1Upgrade Muons not found. Branch will not be filled" << std::endl; + } + + if (TkGlbMuon.isValid()) { + l1Extra->SetTkGlbMuon(TkGlbMuon, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII TkGlbMuons not found. Branch will not be filled" << std::endl; + } +*/ + + if (gmtMuon.isValid()) { + l1Extra->SetGmtMuon(gmtMuon, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII gmtMuons not found. Branch will not be filled" << std::endl; + } + + if (gmtTkMuon.isValid()) { + l1Extra->SetGmtTkMuon(gmtTkMuon, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1PhaseII gmtTkMuons not found. Branch will not be filled" << std::endl; + } + + if (l1PFMet.isValid()) { + l1Extra->SetL1METPF(l1PFMet); + } else { + edm::LogWarning("MissingProduct") << "L1PFMet missing" << std::endl; + } + + if (l1NNTau.isValid()) { + l1Extra->SetNNTaus(l1NNTau, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1NNTau missing" << std::endl; + } + + if (l1NNTau2vtx.isValid()) { + l1Extra->SetNNTau2vtxs(l1NNTau2vtx, maxL1Extra_); + } else { + edm::LogWarning("MissingProduct") << "L1NNTau2vtxs missing" << std::endl; + } + + tree_->Fill(); +} + +// ------------ method called once each job just before starting event loop ------------ +void L1PhaseIITreeStep1Producer::beginJob(void) {} + +// ------------ method called once each job just after ending the event loop ------------ +void L1PhaseIITreeStep1Producer::endJob() {} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1PhaseIITreeStep1Producer); diff --git a/L1Trigger/L1TNtuples/plugins/L1RecoTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1RecoTreeProducer.cc index 7c121e87217fc..bcc8a415df094 100644 --- a/L1Trigger/L1TNtuples/plugins/L1RecoTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1RecoTreeProducer.cc @@ -12,13 +12,12 @@ // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Framework/interface/ESHandle.h" // ROOT output stuff #include "FWCore/ServiceRegistry/interface/Service.h" @@ -38,7 +37,7 @@ // class declaration // -class L1RecoTreeProducer : public edm::EDAnalyzer { +class L1RecoTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1RecoTreeProducer(const edm::ParameterSet&); ~L1RecoTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/plugins/L1TauRecoTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1TauRecoTreeProducer.cc index 0e3bf59998c27..bcd090c58cefe 100644 --- a/L1Trigger/L1TNtuples/plugins/L1TauRecoTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1TauRecoTreeProducer.cc @@ -15,13 +15,12 @@ // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Framework/interface/ESHandle.h" // cond formats #include "JetMETCorrections/JetCorrector/interface/JetCorrector.h" @@ -59,7 +58,7 @@ // class declaration // -class L1TauRecoTreeProducer : public edm::EDAnalyzer { +class L1TauRecoTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1TauRecoTreeProducer(const edm::ParameterSet&); ~L1TauRecoTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/plugins/L1UpgradeTfMuonTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1UpgradeTfMuonTreeProducer.cc index 128b9e571bfe7..a2c889845a72d 100644 --- a/L1Trigger/L1TNtuples/plugins/L1UpgradeTfMuonTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1UpgradeTfMuonTreeProducer.cc @@ -20,7 +20,7 @@ // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -47,7 +47,7 @@ // class declaration // -class L1UpgradeTfMuonTreeProducer : public edm::EDAnalyzer { +class L1UpgradeTfMuonTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1UpgradeTfMuonTreeProducer(const edm::ParameterSet&); ~L1UpgradeTfMuonTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/plugins/L1UpgradeTreeProducer.cc b/L1Trigger/L1TNtuples/plugins/L1UpgradeTreeProducer.cc index 596a7c7103bcb..46ae70e597266 100644 --- a/L1Trigger/L1TNtuples/plugins/L1UpgradeTreeProducer.cc +++ b/L1Trigger/L1TNtuples/plugins/L1UpgradeTreeProducer.cc @@ -22,7 +22,7 @@ Description: Produce L1 Extra tree // framework #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -47,7 +47,7 @@ Description: Produce L1 Extra tree // class declaration // -class L1UpgradeTreeProducer : public edm::EDAnalyzer { +class L1UpgradeTreeProducer : public edm::one::EDAnalyzer<> { public: explicit L1UpgradeTreeProducer(const edm::ParameterSet&); ~L1UpgradeTreeProducer() override; diff --git a/L1Trigger/L1TNtuples/python/l1GeneratorTree_cfi.py b/L1Trigger/L1TNtuples/python/l1GeneratorTree_cfi.py index 32f3093ad4f2c..09e0744aa3de8 100644 --- a/L1Trigger/L1TNtuples/python/l1GeneratorTree_cfi.py +++ b/L1Trigger/L1TNtuples/python/l1GeneratorTree_cfi.py @@ -2,7 +2,7 @@ l1GeneratorTree = cms.EDAnalyzer( "L1GenTreeProducer", - genJetToken = cms.untracked.InputTag("ak4GenJets"), + genJetToken = cms.untracked.InputTag("ak4GenJetsNoNu"), genParticleToken = cms.untracked.InputTag("genParticles"), pileupInfoToken = cms.untracked.InputTag("addPileupInfo"), genInfoToken = cms.InputTag("generator") diff --git a/L1Trigger/L1TNtuples/python/l1PhaseIITreeProducer_cfi.py b/L1Trigger/L1TNtuples/python/l1PhaseIITreeProducer_cfi.py new file mode 100644 index 0000000000000..2ed086458e703 --- /dev/null +++ b/L1Trigger/L1TNtuples/python/l1PhaseIITreeProducer_cfi.py @@ -0,0 +1,83 @@ +import FWCore.ParameterSet.Config as cms + +l1PhaseIITree = cms.EDAnalyzer("L1PhaseIITreeProducer", + + muonToken = cms.untracked.InputTag("simGmtStage2Digis"), + + egTokenBarrel = cms.InputTag("L1EGammaClusterEmuProducer","L1EGammaCollectionBXVEmulator"), + tkEGTokenBarrel = cms.InputTag("L1TkElectronsCrystal","EG"), + tkEGV2TokenBarrel = cms.InputTag("L1TkElectronsEllipticMatchCrystal","EG"), + tkEMTokenBarrel = cms.InputTag("L1TkPhotonsCrystal","EG"), + + egTokenHGC = cms.InputTag("l1EGammaEEProducer","L1EGammaCollectionBXVWithCuts"), + tkEGTokenHGC = cms.InputTag("L1TkElectronsHGC","EG"), + tkEGV2TokenHGC = cms.InputTag("L1TkElectronsEllipticMatchHGC","EG"), + tkEMTokenHGC = cms.InputTag("L1TkPhotonsHGC","EG"), + + tkTauToken = cms.InputTag("L1TrackerTaus","TkTau"), # ? + caloTkTauToken = cms.InputTag("L1TkCaloTaus","CaloTk"), # ? + tkEGTauToken = cms.InputTag("L1TkEGTaus","TkEG"), # ? + + TkGlbMuonToken = cms.InputTag("L1TkGlbMuons",""), + TkMuonToken = cms.InputTag("L1TkMuons",""), + #TkMuonStubsTokenBMTF = cms.InputTag("l1TPSMuons",""), #Changed to this by Mike, then to + # TkMuonStubsTokenBMTF = cms.InputTag("l1StubMatchedMuons",""), # by Vlad... + # TkMuonStubsTokenEMTF = cms.InputTag("l1TkMuonStubEndCapS12",""), + # TkMuonStubsTokenOMTF = cms.InputTag("l1TkMuonStubOverlap","MuonTracks"), + # TkMuonStubsTokenME0 = cms.InputTag("l1TkMuonStubEndCap","ME0Ext"), + + # TkMuonStubsTokenHSCP = cms.InputTag("l1TkMuonStubOverlap","HscpTracks"), + + tkTrackerJetToken = cms.InputTag("TwoLayerJets", "L1TwoLayerJets"), + tkCaloJetToken = cms.InputTag("L1TkCaloJets","L1TkCaloJets"), + tkMetToken = cms.InputTag("L1TrackerEtMiss","trkMET"), + tkMhtTokens = cms.VInputTag( cms.InputTag("L1TrackerHTMiss","L1TrackerHTMiss") ), + + ak4L1PF = cms.InputTag("ak4PFL1PuppiCorrected"), +# ak4L1PFForMET = cms.InputTag("ak4PFL1PuppiForMETCorrected"), + +# l1pfPhase1L1TJetToken = cms.InputTag("Phase1L1TJetProducer" , "UncalibratedPhase1L1TJetFromPfCandidates"), +# l1pfPhase1L1TJetToken = cms.InputTag("Phase1L1TJetCalibrator" , "Phase1L1TJetFromPfCandidates"), + + l1PFCandidates = cms.InputTag("l1pfCandidates","Puppi"), +# l1PFCandidates = cms.InputTag("l1pfCandidates","PF"), + + + caloTauToken = cms.InputTag("L1CaloJetProducer","L1CaloTauCollectionBXV"), + caloJetToken = cms.InputTag("L1CaloJetProducer","L1CaloJetCollectionBXV"), + caloJetHTTToken = cms.InputTag("L1CaloJetHTTProducer","CaloJetHTT"), + + muonKalman = cms.InputTag("simKBmtfDigis","BMTF"), + muonOverlap = cms.InputTag("simOmtfDigis","OMTF"), + muonEndcap = cms.InputTag("simEmtfDigis","EMTF"), + + l1PFMet = cms.InputTag("l1PFMetPuppi"), + + zoPuppi = cms.InputTag("l1pfProducerBarrel","z0"), + l1vertextdr = cms.InputTag("VertexProducer","l1vertextdr"), + l1vertices = cms.InputTag("VertexProducer","l1vertices"), + l1TkPrimaryVertex= cms.InputTag("L1TkPrimaryVertex",""), + + # L1PFTauToken = cms.InputTag("l1pfTauProducer","L1PFTaus"), + L1NNTauToken = cms.InputTag("L1NNTauProducerPuppi"), + L1NNTauPFToken = cms.InputTag("L1NNTauProducerPF"), + + # L1HPSPFTauToken = cms.InputTag("L1HPSPFTauProducerPF",""), + + L1TkBsCandsToken = cms.InputTag("l1TkBsCandidates"), + L1TkBsCandsLooseToken = cms.InputTag("l1TkBsCandidatesLooseWP"), + L1TkBsCandsTightToken = cms.InputTag("l1TkBsCandidatesTightWP"), + + maxL1Extra = cms.uint32(50) +) + +#### Gen level tree + +from L1Trigger.L1TNtuples.l1GeneratorTree_cfi import l1GeneratorTree +genTree=l1GeneratorTree.clone() + +runmenutree=cms.Path(l1PhaseIITree*genTree) + + + + diff --git a/L1Trigger/L1TNtuples/python/l1PhaseIITreeStep1Producer_cfi.py b/L1Trigger/L1TNtuples/python/l1PhaseIITreeStep1Producer_cfi.py new file mode 100644 index 0000000000000..26687c5943ecc --- /dev/null +++ b/L1Trigger/L1TNtuples/python/l1PhaseIITreeStep1Producer_cfi.py @@ -0,0 +1,71 @@ +import FWCore.ParameterSet.Config as cms + + +l1PhaseIITree = cms.EDAnalyzer("L1PhaseIITreeStep1Producer", + + egTokenBarrel = cms.InputTag("L1EGammaClusterEmuProducer",""), #keep as is, not produced by GCT + tkEGTokenBarrel = cms.InputTag("l1ctLayer1EG","L1TkEleEB"), + tkEMTokenBarrel = cms.InputTag("l1ctLayer1EG","L1TkEmEB"), + + egTokenHGC = cms.InputTag("l1ctLayer1EG","L1EgEE"), + tkEGTokenHGC = cms.InputTag("l1ctLayer1EG","L1TkEleEE"), + tkEMTokenHGC = cms.InputTag("l1ctLayer1EG","L1TkEmEE"), + +# muonKalman = cms.InputTag("simKBmtfDigis","BMTF"), # we should remove all of these +# muonOverlap = cms.InputTag("simOmtfDigis","OMTF"), +# muonEndcap = cms.InputTag("simEmtfDigis",""), +# TkMuonToken = cms.InputTag(""),#"L1TkMuons",""), # removing this from the run + + #Global muons +# muonToken = cms.untracked.InputTag("simGmtStage2Digis", ""), +# TkGlbMuonToken = cms.InputTag(""),#L1TkGlbMuons",""), # removing this from the run + + #GMT muons + gmtMuonToken = cms.InputTag("L1SAMuonsGmt", "promptSAMuons"), #we use the prompt + gmtTkMuonToken = cms.InputTag("L1TkMuonsGmt",""), + + + scPFL1Puppi = cms.InputTag("scPFL1PuppiCorrectedEmulator", ""), #Emulator and corrected JEC; seededcone jets + scPFL1PuppiMHT = cms.InputTag("scPFL1PuppiCorrectedEmulatorMHT", ""), #Emulator for seededcone puppiMHT + + l1pfPhase1L1TJetToken = cms.InputTag("Phase1L1TJetCalibrator9x9" , "Phase1L1TJetFromPfCandidates"), #use the 9x9 case + l1pfPhase1L1TJetMET = cms.InputTag("Phase1L1TJetProducer9x9" , "UncalibratedPhase1L1TJetFromPfCandidatesMET"), #use the 9x9 case + l1pfPhase1L1TJetSums = cms.InputTag("Phase1L1TJetSumsProducer9x9" , "Sums"), #use the 9x9 case + + caloJetToken = cms.InputTag("L1CaloJet","L1CaloJetCollectionBXV"), + caloJetHTTToken = cms.InputTag("L1CaloJetHTT","CaloJetHTT"), + caloTauToken = cms.InputTag("L1CaloJet","L1CaloTauCollectionBXV"), + L1HPSPFTauToken = cms.InputTag("HPSPFTauProducerPF",""), + + l1PFMet = cms.InputTag("L1MetPfProducer",""), #emulator + + + #zoPuppi = cms.InputTag(""), # does not exist anymore! + #l1vertextdr = cms.InputTag("VertexProducer","l1vertextdr"), #not used anymore - but kept in the loop just to be sure, not filled to ntuples + #l1vertices = cms.InputTag("VertexProducer","l1vertices"), #not used anymore - but kept in the loop just to be sure, not filled to ntuples + l1TkPrimaryVertex= cms.InputTag("L1VertexFinderEmulator","l1verticesEmulation"), #we need to rename this, but these are now emulated vertices! + + L1NNTauToken = cms.InputTag("L1NNTauProducerPuppi","L1PFTausNN"), # default collection, emulated + L1NNTau2vtxToken = cms.InputTag("L1NNTauProducerPuppi2Vtx","L1PFTausNN"), # 2 vtx version + + tkTrackerJetToken = cms.InputTag("L1TrackJetsEmulation", "L1TrackJets"), #these are emulated + tkTrackerJetDisplacedToken = cms.InputTag("L1TrackJetsExtendedEmulation", "L1TrackJetsExtended"), #emulated + + tkMetToken = cms.InputTag("L1TrackerEmuEtMiss","L1TrackerEmuEtMiss"), #emulated + + tkMhtToken = cms.InputTag("L1TrackerEmuHTMiss","L1TrackerEmuHTMiss"), #emulated + tkMhtDisplacedToken = cms.InputTag("L1TrackerEmuHTMissExtended","L1TrackerEmuHTMissExtended"), #emulated + + maxL1Extra = cms.uint32(50) +) + +#### Gen level tree + +from L1Trigger.L1TNtuples.l1GeneratorTree_cfi import l1GeneratorTree +genTree=l1GeneratorTree.clone() + +runmenutree=cms.Path(l1PhaseIITree*genTree) + + + + diff --git a/L1Trigger/L1TNtuples/src/L1AnalysisPhaseII.cc b/L1Trigger/L1TNtuples/src/L1AnalysisPhaseII.cc new file mode 100644 index 0000000000000..7508469a3f5ff --- /dev/null +++ b/L1Trigger/L1TNtuples/src/L1AnalysisPhaseII.cc @@ -0,0 +1,808 @@ +#include "L1Trigger/L1TNtuples/interface/L1AnalysisPhaseII.h" +#include "L1Trigger/L1TMuon/interface/MicroGMTConfiguration.h" + +L1Analysis::L1AnalysisPhaseII::L1AnalysisPhaseII() {} + +L1Analysis::L1AnalysisPhaseII::~L1AnalysisPhaseII() {} + +void L1Analysis::L1AnalysisPhaseII::SetVertices(float z0Puppi, + const edm::Handle> TkPrimaryVertex) { + l1extra_.z0Puppi = z0Puppi; + + for (unsigned int i = 0; i < TkPrimaryVertex->size(); i++) { + l1extra_.z0L1TkPV.push_back(TkPrimaryVertex->at(i).zvertex()); + l1extra_.sumL1TkPV.push_back(TkPrimaryVertex->at(i).sum()); + l1extra_.nL1TkPVs++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetCaloTau(const edm::Handle calotau, unsigned maxL1Extra) { + for (int ibx = calotau->getFirstBX(); ibx <= calotau->getLastBX(); ++ibx) { + for (l1t::TauBxCollection::const_iterator it = calotau->begin(ibx); + it != calotau->end(ibx) && l1extra_.nCaloTaus < maxL1Extra; + it++) { + if (it->pt() > 0) { + l1extra_.caloTauEt.push_back(it->et()); + l1extra_.caloTauEta.push_back(it->eta()); + l1extra_.caloTauPhi.push_back(it->phi()); + l1extra_.caloTauIEt.push_back(it->hwPt()); + l1extra_.caloTauIEta.push_back(it->hwEta()); + l1extra_.caloTauIPhi.push_back(it->hwPhi()); + l1extra_.caloTauIso.push_back(it->hwIso()); + l1extra_.caloTauBx.push_back(ibx); + l1extra_.caloTauTowerIPhi.push_back(it->towerIPhi()); + l1extra_.caloTauTowerIEta.push_back(it->towerIEta()); + l1extra_.caloTauRawEt.push_back(it->rawEt()); + l1extra_.caloTauIsoEt.push_back(it->isoEt()); + l1extra_.caloTauNTT.push_back(it->nTT()); + l1extra_.caloTauHasEM.push_back(it->hasEM()); + l1extra_.caloTauIsMerged.push_back(it->isMerged()); + l1extra_.caloTauHwQual.push_back(it->hwQual()); + l1extra_.nCaloTaus++; + } + } + } +} + +void L1Analysis::L1AnalysisPhaseII::SetCaloJet(const edm::Handle jet, + unsigned maxL1Extra, + float caloJetHTT) { + double mHT30_px = 0, mHT30_py = 0, HT30 = 0; + double mHT30_3p5_px = 0, mHT30_3p5_py = 0, HT30_3p5 = 0; + + for (int ibx = jet->getFirstBX(); ibx <= jet->getLastBX(); ++ibx) { + for (l1t::JetBxCollection::const_iterator it = jet->begin(ibx); + it != jet->end(ibx) && l1extra_.nCaloJets < maxL1Extra; + it++) { + if (it->pt() > 0) { + l1extra_.caloJetEt.push_back(it->et()); + l1extra_.caloJetEta.push_back(it->eta()); + l1extra_.caloJetPhi.push_back(it->phi()); + l1extra_.caloJetBx.push_back(ibx); + l1extra_.nCaloJets++; + + if (it->et() > 30 && fabs(it->eta()) < 2.4) { + HT30 += it->et(); + mHT30_px += it->px(); + mHT30_py += it->py(); + } + if (it->et() > 30 && fabs(it->eta()) < 3.5) { + HT30_3p5 += it->et(); + mHT30_3p5_px += it->px(); + mHT30_3p5_py += it->py(); + } + } + } + } + + l1extra_.caloJetHTDefault = caloJetHTT; + + l1extra_.caloJetMHTEt.push_back(sqrt(mHT30_px * mHT30_px + mHT30_py * mHT30_py)); + l1extra_.caloJetMHTPhi.push_back(atan(mHT30_py / mHT30_px)); + l1extra_.caloJetHT.push_back(HT30); + + l1extra_.caloJetMHTEt.push_back(sqrt(mHT30_3p5_px * mHT30_3p5_px + mHT30_3p5_py * mHT30_3p5_py)); + l1extra_.caloJetMHTPhi.push_back(atan(mHT30_3p5_py / mHT30_3p5_px)); + l1extra_.caloJetHT.push_back(HT30_3p5); + + l1extra_.nCaloJetMHT = 2; +} + +void L1Analysis::L1AnalysisPhaseII::SetMuon(const edm::Handle muon, unsigned maxL1Extra) { + for (int ibx = muon->getFirstBX(); ibx <= muon->getLastBX(); ++ibx) { + for (l1t::MuonBxCollection::const_iterator it = muon->begin(ibx); + it != muon->end(ibx) && l1extra_.nGlobalMuons < maxL1Extra; + it++) { + if (it->pt() > 0) { + l1extra_.globalMuonPt.push_back(it->et()); + l1extra_.globalMuonEta.push_back(it->eta()); + l1extra_.globalMuonPhi.push_back(it->phi()); + l1extra_.globalMuonEtaAtVtx.push_back(it->etaAtVtx()); + l1extra_.globalMuonPhiAtVtx.push_back(it->phiAtVtx()); + l1extra_.globalMuonIEt.push_back(it->hwPt()); + l1extra_.globalMuonIEta.push_back(it->hwEta()); + l1extra_.globalMuonIPhi.push_back(it->hwPhi()); + l1extra_.globalMuonIEtaAtVtx.push_back(it->hwEtaAtVtx()); + l1extra_.globalMuonIPhiAtVtx.push_back(it->hwPhiAtVtx()); + l1extra_.globalMuonIDEta.push_back(it->hwDEtaExtra()); + l1extra_.globalMuonIDPhi.push_back(it->hwDPhiExtra()); + l1extra_.globalMuonChg.push_back(it->charge()); + l1extra_.globalMuonIso.push_back(it->hwIso()); + l1extra_.globalMuonQual.push_back(it->hwQual()); + l1extra_.globalMuonTfMuonIdx.push_back(it->tfMuonIndex()); + l1extra_.globalMuonBx.push_back(ibx); + l1extra_.nGlobalMuons++; + } + } + } +} + +void L1Analysis::L1AnalysisPhaseII::SetMuonKF(const edm::Handle standaloneMuon, + unsigned maxL1Extra, + unsigned int muonDetector) { + for (int ibx = standaloneMuon->getFirstBX(); ibx <= standaloneMuon->getLastBX(); ++ibx) { + for (l1t::RegionalMuonCandBxCollection::const_iterator it = standaloneMuon->begin(ibx); + it != standaloneMuon->end(ibx) && l1extra_.nStandaloneMuons < maxL1Extra; + it++) { + if (it->hwPt() > 0) { + // std::cout<<"hwPt vs hwPt2?"<hwPt()*0.5<<" "<hwPt2()<<" "<hwSign()<<" "<hwPt() * 0.5); + l1extra_.standaloneMuonPt2.push_back(it->hwPtUnconstrained()); + l1extra_.standaloneMuonDXY.push_back(it->hwDXY()); + l1extra_.standaloneMuonEta.push_back(it->hwEta() * 0.010875); + l1extra_.standaloneMuonPhi.push_back( + l1t::MicroGMTConfiguration::calcGlobalPhi(it->hwPhi(), it->trackFinderType(), it->processor()) * 2 * M_PI / + 576); + l1extra_.standaloneMuonChg.push_back(pow(-1, it->hwSign())); + l1extra_.standaloneMuonQual.push_back(it->hwQual()); + l1extra_.standaloneMuonRegion.push_back(muonDetector); + l1extra_.standaloneMuonBx.push_back(ibx); + l1extra_.nStandaloneMuons++; + } + } + } +} +// RegionalMuons are a bit ugly... why not global muons?? +/// Get compressed pT (returned int * 0.5 = pT (GeV)) +// const int hwPt() const { return m_hwPt; }; +// /// Get compressed local phi (returned int * 2*pi/576 = local phi in rad) +// const int hwPhi() const { return m_hwPhi; }; +// /// Get compressed eta (returned int * 0.010875 = eta) +// const int hwEta() const { return m_hwEta; }; +// /// Get charge sign bit (charge = (-1)^(sign)) +// const int hwSign() const { return m_hwSign; }; + +//EG (seeded by Phase 2 Objects ) +void L1Analysis::L1AnalysisPhaseII::SetEG(const edm::Handle EG, + const edm::Handle EGHGC, + unsigned maxL1Extra) { + for (l1t::EGammaBxCollection::const_iterator it = EG->begin(); it != EG->end() && l1extra_.nEG < maxL1Extra; it++) { + if (it->et() > 5) { + l1extra_.EGEt.push_back(it->et()); + l1extra_.EGEta.push_back(it->eta()); + l1extra_.EGPhi.push_back(it->phi()); + l1extra_.EGIso.push_back(it->isoEt()); + l1extra_.EGHwQual.push_back(it->hwQual()); + l1extra_.EGBx.push_back(0); //it->bx()); + l1extra_.EGHGC.push_back(0); + bool quality = ((it->hwQual() >> 1) & 1) > 0; + l1extra_.EGPassesLooseTrackID.push_back(quality); + quality = ((it->hwQual() >> 2) & 1) > 0; + l1extra_.EGPassesPhotonID.push_back(quality); + l1extra_.nEG++; + } + } + + for (l1t::EGammaBxCollection::const_iterator it = EGHGC->begin(); it != EGHGC->end() && l1extra_.nEG < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.EGEt.push_back(it->et()); + l1extra_.EGEta.push_back(it->eta()); + l1extra_.EGPhi.push_back(it->phi()); + l1extra_.EGIso.push_back(it->isoEt()); + l1extra_.EGHwQual.push_back(it->hwQual()); + l1extra_.EGBx.push_back(0); //it->bx()); + l1extra_.EGHGC.push_back(1); + bool quality = (it->hwQual() == 5); + l1extra_.EGPassesLooseTrackID.push_back(quality); + l1extra_.EGPassesPhotonID.push_back(quality); + l1extra_.nEG++; + } + } +} + +// TrkEG (seeded by Phase 2 Objects) +void L1Analysis::L1AnalysisPhaseII::SetTkEG(const edm::Handle tkElectron, + const edm::Handle tkElectronHGC, + unsigned maxL1Extra) { + for (l1t::TkElectronCollection::const_iterator it = tkElectron->begin(); + it != tkElectron->end() && l1extra_.nTkElectrons < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkElectronEt.push_back(it->et()); + l1extra_.tkElectronEta.push_back(it->eta()); + l1extra_.tkElectronPhi.push_back(it->phi()); + int chargeFromCurvature = (it->trackCurvature() > 0) ? 1 : -1; // ThisIsACheck + l1extra_.tkElectronChg.push_back(chargeFromCurvature); + l1extra_.tkElectronzVtx.push_back(it->trkzVtx()); + l1extra_.tkElectronTrkIso.push_back(it->trkIsol()); + l1extra_.tkElectronHwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkElectronEGRefPt.push_back(it->EGRef()->et()); + l1extra_.tkElectronEGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkElectronEGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkElectronBx.push_back(0); //it->bx()); + l1extra_.tkElectronHGC.push_back(0); + bool quality = ((it->EGRef()->hwQual() >> 1) & 1) > 0; // LooseTrackID should be the second bit + l1extra_.tkElectronPassesLooseTrackID.push_back(quality); + quality = ((it->EGRef()->hwQual() >> 2) & 1) > 0; // LooseTrackID should be the second bit + l1extra_.tkElectronPassesPhotonID.push_back(quality); + l1extra_.nTkElectrons++; + } + } + + for (l1t::TkElectronCollection::const_iterator it = tkElectronHGC->begin(); + it != tkElectronHGC->end() && l1extra_.nTkElectrons < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkElectronEt.push_back(it->et()); + l1extra_.tkElectronEta.push_back(it->eta()); + l1extra_.tkElectronPhi.push_back(it->phi()); + int chargeFromCurvature = (it->trackCurvature() > 0) ? 1 : -1; // ThisIsACheck + l1extra_.tkElectronChg.push_back(chargeFromCurvature); + l1extra_.tkElectronzVtx.push_back(it->trkzVtx()); + l1extra_.tkElectronTrkIso.push_back(it->trkIsol()); + l1extra_.tkElectronHwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkElectronEGRefPt.push_back(it->EGRef()->et()); + l1extra_.tkElectronEGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkElectronEGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkElectronBx.push_back(0); //it->bx()); + l1extra_.tkElectronHGC.push_back(1); + bool quality = (it->EGRef()->hwQual() == 5); + l1extra_.tkElectronPassesLooseTrackID.push_back(quality); + l1extra_.tkElectronPassesPhotonID.push_back(quality); + l1extra_.nTkElectrons++; + } + } +} + +void L1Analysis::L1AnalysisPhaseII::SetTkEGV2(const edm::Handle tkElectronV2, + const edm::Handle tkElectronV2HGC, + unsigned maxL1Extra) { + for (l1t::TkElectronCollection::const_iterator it = tkElectronV2->begin(); + it != tkElectronV2->end() && l1extra_.nTkElectronsV2 < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkElectronV2Et.push_back(it->et()); + l1extra_.tkElectronV2Eta.push_back(it->eta()); + l1extra_.tkElectronV2Phi.push_back(it->phi()); + int chargeFromCurvature = (it->trackCurvature() > 0) ? 1 : -1; // ThisIsACheck + l1extra_.tkElectronV2Chg.push_back(chargeFromCurvature); + l1extra_.tkElectronV2zVtx.push_back(it->trkzVtx()); + l1extra_.tkElectronV2TrkIso.push_back(it->trkIsol()); + l1extra_.tkElectronV2HwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkElectronV2EGRefPt.push_back(it->EGRef()->et()); + l1extra_.tkElectronV2EGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkElectronV2EGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkElectronV2Bx.push_back(0); //it->bx()); + l1extra_.tkElectronV2HGC.push_back(0); + bool quality = ((it->EGRef()->hwQual() >> 1) & 1) > 0; + l1extra_.tkElectronV2PassesLooseTrackID.push_back(quality); + quality = ((it->EGRef()->hwQual() >> 2) & 1) > 0; + l1extra_.tkElectronV2PassesPhotonID.push_back(quality); + l1extra_.nTkElectronsV2++; + } + } + + for (l1t::TkElectronCollection::const_iterator it = tkElectronV2HGC->begin(); + it != tkElectronV2HGC->end() && l1extra_.nTkElectronsV2 < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkElectronV2Et.push_back(it->et()); + l1extra_.tkElectronV2Eta.push_back(it->eta()); + l1extra_.tkElectronV2Phi.push_back(it->phi()); + int chargeFromCurvature = (it->trackCurvature() > 0) ? 1 : -1; // ThisIsACheck + l1extra_.tkElectronV2Chg.push_back(chargeFromCurvature); + l1extra_.tkElectronV2zVtx.push_back(it->trkzVtx()); + l1extra_.tkElectronV2TrkIso.push_back(it->trkIsol()); + l1extra_.tkElectronV2HwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkElectronV2EGRefPt.push_back(it->EGRef()->et()); + l1extra_.tkElectronV2EGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkElectronV2EGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkElectronV2Bx.push_back(0); //it->bx()); + l1extra_.tkElectronV2HGC.push_back(1); + bool quality = (it->EGRef()->hwQual() == 5); + l1extra_.tkElectronV2PassesLooseTrackID.push_back(quality); + l1extra_.tkElectronV2PassesPhotonID.push_back(quality); + l1extra_.nTkElectronsV2++; + } + } +} + +void L1Analysis::L1AnalysisPhaseII::SetTkEM(const edm::Handle tkPhoton, + const edm::Handle tkPhotonHGC, + unsigned maxL1Extra) { + for (l1t::TkEmCollection::const_iterator it = tkPhoton->begin(); + it != tkPhoton->end() && l1extra_.nTkPhotons < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkPhotonEt.push_back(it->et()); + l1extra_.tkPhotonEta.push_back(it->eta()); + l1extra_.tkPhotonPhi.push_back(it->phi()); + l1extra_.tkPhotonTrkIso.push_back(it->trkIsol()); + l1extra_.tkPhotonTrkIsoPV.push_back(it->trkIsolPV()); + l1extra_.tkPhotonBx.push_back(0); //it->bx()); + l1extra_.tkPhotonHwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkPhotonEGRefPt.push_back(it->EGRef()->et()); + l1extra_.tkPhotonEGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkPhotonEGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkPhotonHGC.push_back(0); + bool quality = ((it->EGRef()->hwQual() >> 1) & 1) > 0; + l1extra_.tkPhotonPassesLooseTrackID.push_back(quality); + quality = ((it->EGRef()->hwQual() >> 2) & 1) > 0; // Photon Id should be the third bit + l1extra_.tkPhotonPassesPhotonID.push_back(quality); + l1extra_.nTkPhotons++; + } + } + for (l1t::TkEmCollection::const_iterator it = tkPhotonHGC->begin(); + it != tkPhotonHGC->end() && l1extra_.nTkPhotons < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkPhotonEt.push_back(it->et()); + l1extra_.tkPhotonEta.push_back(it->eta()); + l1extra_.tkPhotonPhi.push_back(it->phi()); + l1extra_.tkPhotonTrkIso.push_back(it->trkIsol()); + l1extra_.tkPhotonTrkIsoPV.push_back(it->trkIsolPV()); + l1extra_.tkPhotonBx.push_back(0); //it->bx()); + l1extra_.tkPhotonHwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkPhotonEGRefPt.push_back(it->EGRef()->et()); + l1extra_.tkPhotonEGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkPhotonEGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkPhotonHGC.push_back(1); + bool quality = (it->EGRef()->hwQual() == 5); + l1extra_.tkPhotonPassesLooseTrackID.push_back(quality); + l1extra_.tkPhotonPassesPhotonID.push_back(quality); + l1extra_.nTkPhotons++; + } + } +} + +void L1Analysis::L1AnalysisPhaseII::SetTrkTau(const edm::Handle tkTau, unsigned maxL1Extra) { + for (l1t::L1TrkTauCollection::const_iterator it = tkTau->begin(); it != tkTau->end() && l1extra_.nTkTau < maxL1Extra; + it++) { + l1extra_.tkTauEt.push_back(it->et()); + l1extra_.tkTauEta.push_back(it->eta()); + l1extra_.tkTauPhi.push_back(it->phi()); + l1extra_.tkTauTrkIso.push_back(it->iso()); + l1extra_.tkTauBx.push_back(0); //it->bx()); + l1extra_.tkTauzVtx.push_back(it->seedTrk()->POCA().z()); + l1extra_.nTkTau++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetCaloTkTau(const edm::Handle caloTkTau, + unsigned maxL1Extra) { + for (l1t::L1CaloTkTauCollection::const_iterator it = caloTkTau->begin(); + it != caloTkTau->end() && l1extra_.nCaloTkTau < maxL1Extra; + it++) { + l1extra_.caloTkTauEt.push_back(it->et()); + l1extra_.caloTkTauEta.push_back(it->eta()); + l1extra_.caloTkTauPhi.push_back(it->phi()); + l1extra_.caloTkTauTrkIso.push_back(it->vtxIso()); + l1extra_.caloTkTauBx.push_back(0); //it->bx()); + l1extra_.caloTkTauzVtx.push_back(it->seedTrk()->POCA().z()); + l1extra_.nCaloTkTau++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetTkEGTau(const edm::Handle tkEGTau, unsigned maxL1Extra) { + for (l1t::TkEGTauCollection::const_iterator it = tkEGTau->begin(); + it != tkEGTau->end() && l1extra_.nTkEGTau < maxL1Extra; + it++) { + l1extra_.tkEGTauEt.push_back(it->et()); + l1extra_.tkEGTauEta.push_back(it->eta()); + l1extra_.tkEGTauPhi.push_back(it->phi()); + l1extra_.tkEGTauTrkIso.push_back(it->iso()); + l1extra_.tkEGTauBx.push_back(0); //it->bx()); + l1extra_.tkEGTauzVtx.push_back(it->seedTrk()->POCA().z()); + //std::cout<seedTrk()->POCA().z() < trackerJet, unsigned maxL1Extra) { + for (l1t::TkJetCollection::const_iterator it = trackerJet->begin(); + it != trackerJet->end() && l1extra_.nTrackerJets < maxL1Extra; + it++) { + l1extra_.trackerJetEt.push_back(it->et()); + l1extra_.trackerJetEta.push_back(it->eta()); + l1extra_.trackerJetPhi.push_back(it->phi()); + l1extra_.trackerJetzVtx.push_back(it->jetVtx()); + l1extra_.trackerJetBx.push_back(0); //it->bx()); + l1extra_.nTrackerJets++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetTkCaloJet(const edm::Handle tkCaloJet, + unsigned maxL1Extra) { + for (l1t::TkJetCollection::const_iterator it = tkCaloJet->begin(); + it != tkCaloJet->end() && l1extra_.nTkCaloJets < maxL1Extra; + it++) { + l1extra_.tkCaloJetEt.push_back(it->et()); + l1extra_.tkCaloJetEta.push_back(it->eta()); + l1extra_.tkCaloJetPhi.push_back(it->phi()); + l1extra_.tkCaloJetzVtx.push_back(it->jetVtx()); + l1extra_.tkCaloJetBx.push_back(0); //it->bx()); + l1extra_.nTkCaloJets++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetTkMuon(const edm::Handle muon, unsigned maxL1Extra) { + for (l1t::TkMuonCollection::const_iterator it = muon->begin(); it != muon->end() && l1extra_.nTkMuons < maxL1Extra; + it++) { + l1extra_.tkMuonPt.push_back(it->pt()); + l1extra_.tkMuonEta.push_back(it->eta()); + l1extra_.tkMuonPhi.push_back(it->phi()); + int chargeFromCurvature = (it->trackCurvature() > 0) ? 1 : -1; // ThisIsACheck + l1extra_.tkMuonChg.push_back(chargeFromCurvature); + l1extra_.tkMuonTrkIso.push_back(it->trkIsol()); + if (it->muonDetector() != 3) { + l1extra_.tkMuonMuRefPt.push_back(it->muRef()->hwPt() * 0.5); + l1extra_.tkMuonMuRefEta.push_back(it->muRef()->hwEta() * 0.010875); + l1extra_.tkMuonMuRefPhi.push_back(l1t::MicroGMTConfiguration::calcGlobalPhi(it->muRef()->hwPhi(), + it->muRef()->trackFinderType(), + it->muRef()->processor()) * + 2 * M_PI / 576); + l1extra_.tkMuonDRMuTrack.push_back(it->dR()); + l1extra_.tkMuonNMatchedTracks.push_back(it->nTracksMatched()); + l1extra_.tkMuonQual.push_back(it->muRef()->hwQual()); + l1extra_.tkMuonMuRefChg.push_back(pow(-1, it->muRef()->hwSign())); + } else { + l1extra_.tkMuonMuRefPt.push_back(-777); + l1extra_.tkMuonMuRefEta.push_back(-777); + l1extra_.tkMuonMuRefPhi.push_back(-777); + l1extra_.tkMuonDRMuTrack.push_back(-777); + l1extra_.tkMuonNMatchedTracks.push_back(0); + l1extra_.tkMuonQual.push_back(999); + l1extra_.tkMuonMuRefChg.push_back(0); + } + l1extra_.tkMuonRegion.push_back(it->muonDetector()); + l1extra_.tkMuonzVtx.push_back(it->trkzVtx()); + l1extra_.tkMuonBx.push_back(0); //it->bx()); + l1extra_.nTkMuons++; + } +} + +/* +void L1Analysis::L1AnalysisPhaseII::SetTkMuonStubs(const edm::Handle muon, unsigned maxL1Extra, unsigned int muonDetector) +{ + + for(l1t::TkMuonCollection::const_iterator it=muon->begin(); it!=muon->end() && l1extra_.nTkMuonStubseta())>=0.9) continue; + if (muonDetector==3 && fabs(it->eta())<1.2) continue; + + l1extra_.tkMuonStubsPt .push_back( it->pt()); + l1extra_.tkMuonStubsEta.push_back(it->eta()); + l1extra_.tkMuonStubsPhi.push_back(it->phi()); + l1extra_.tkMuonStubsChg.push_back(it->charge()); + l1extra_.tkMuonStubsTrkIso.push_back(it->trkIsol()); + l1extra_.tkMuonStubszVtx.push_back(it->trkzVtx()); + l1extra_.tkMuonStubsBx .push_back(0); //it->bx()); + l1extra_.tkMuonStubsQual .push_back(1); + l1extra_.tkMuonStubsBarrelStubs.push_back(it->matchedStubs().size()); + l1extra_.tkMuonStubsRegion.push_back(muonDetector); + l1extra_.nTkMuonStubs++; + } +} +*/ +/* +void L1Analysis::L1AnalysisPhaseII::SetTkMuonStubsOMTF(const edm::Handle muon, unsigned maxL1Extra, unsigned int muonDetector) +{ + + for (int ibx = muon->getFirstBX(); ibx <= muon->getLastBX(); ++ibx) { + for(l1t::BayesMuCorrTrackBxCollection::const_iterator it=muon->begin(ibx); it!=muon->end(ibx) && l1extra_.nTkMuonStubseta())<0.9 || fabs(it->eta())>=1.2) continue; + + l1extra_.tkMuonStubsPt .push_back( it->pt()); + l1extra_.tkMuonStubsEta.push_back(it->eta()); + l1extra_.tkMuonStubsPhi.push_back(it->phi()); + l1extra_.tkMuonStubsChg.push_back( pow(-1,it->hwSign() ) ); + l1extra_.tkMuonStubsTrkIso.push_back(0); + l1extra_.tkMuonStubszVtx.push_back(it->getTtTrackPtr()->POCA().z()); + l1extra_.tkMuonStubsBx .push_back(ibx); + l1extra_.tkMuonStubsQual .push_back(1); + l1extra_.tkMuonStubsBarrelStubs.push_back(0); + l1extra_.tkMuonStubsRegion.push_back(muonDetector); + l1extra_.nTkMuonStubs++; + } + } + +} + +void L1Analysis::L1AnalysisPhaseII::SetHSCP(const edm::Handle muon, unsigned maxL1Extra) +{ + + for (int ibx = muon->getFirstBX(); ibx <= muon->getLastBX(); ++ibx) { + for(l1t::BayesMuCorrTrackBxCollection::const_iterator it=muon->begin(ibx); it!=muon->end(ibx) && l1extra_.nTkHSCPspt()); + l1extra_.tkHSCPsEta.push_back(it->eta()); + l1extra_.tkHSCPsPhi.push_back(it->phi()); + l1extra_.tkHSCPsChg.push_back(it->hwSign()); + l1extra_.tkHSCPszVtx.push_back(it->getTtTrackPtr()->POCA().z()); + l1extra_.tkHSCPsBx .push_back(ibx); + l1extra_.nTkHSCPs++; + } + } + +} +*/ + +void L1Analysis::L1AnalysisPhaseII::SetTkGlbMuon(const edm::Handle muon, + unsigned maxL1Extra) { + for (l1t::TkGlbMuonCollection::const_iterator it = muon->begin(); + it != muon->end() && l1extra_.nTkGlbMuons < maxL1Extra; + it++) { + l1extra_.tkGlbMuonPt.push_back(it->pt()); + l1extra_.tkGlbMuonEta.push_back(it->eta()); + l1extra_.tkGlbMuonPhi.push_back(it->phi()); + l1extra_.tkGlbMuonChg.push_back(it->charge()); + l1extra_.tkGlbMuonTrkIso.push_back(it->trkIsol()); + l1extra_.tkGlbMuonMuRefPt.push_back(it->muRef()->pt()); + l1extra_.tkGlbMuonMuRefEta.push_back(it->muRef()->eta()); + l1extra_.tkGlbMuonMuRefPhi.push_back(it->muRef()->phi()); + l1extra_.tkGlbMuonDRMuTrack.push_back(it->dR()); + l1extra_.tkGlbMuonNMatchedTracks.push_back(it->nTracksMatched()); + l1extra_.tkGlbMuonzVtx.push_back(it->trkzVtx()); + l1extra_.tkGlbMuonBx.push_back(0); //it->bx()); + l1extra_.tkGlbMuonQual.push_back(it->muRef()->hwQual()); + l1extra_.nTkGlbMuons++; + } +} + +// trackerMet +void L1Analysis::L1AnalysisPhaseII::SetTkMET(const edm::Handle trackerMets) { + for (l1t::TkEtMissCollection::const_iterator it = trackerMets->begin(); it != trackerMets->end(); it++) { + l1extra_.trackerMetSumEt.push_back(it->etTotal()); + l1extra_.trackerMetEt.push_back(it->etMiss()); + l1extra_.trackerMetPhi.push_back(it->phi()); + l1extra_.trackerMetBx.push_back(it->bx()); + l1extra_.nTrackerMet++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetTkMHT(const edm::Handle trackerMHTs) { + // Hardcoding it like this, but this needs to be changed to a vector + + for (l1t::TkHTMissCollection::const_iterator it = trackerMHTs->begin(); it != trackerMHTs->end(); it++) { + l1extra_.trackerHT.push_back(it->etTotal()); + l1extra_.trackerMHT.push_back(it->EtMiss()); + l1extra_.trackerMHTPhi.push_back(it->phi()); + l1extra_.nTrackerMHT++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetL1PfPhase1L1TJet(const edm::Handle> l1L1PFPhase1L1Jet, + unsigned maxL1Extra) { + double mHT30_px = 0, mHT30_py = 0, HT30 = 0; + double mHT30_3p5_px = 0, mHT30_3p5_py = 0, HT30_3p5 = 0; + + for (reco::CaloJetCollection::const_iterator it = l1L1PFPhase1L1Jet->begin(); + it != l1L1PFPhase1L1Jet->end() && l1extra_.nPfPhase1L1Jets < maxL1Extra; + it++) { + if (it->pt() > 0) { + l1extra_.pfPhase1L1JetEt.push_back(it->et()); + l1extra_.pfPhase1L1JetEta.push_back(it->eta()); + l1extra_.pfPhase1L1JetPhi.push_back(it->phi()); + // l1extra_.pfPhase1L1JetBx .push_back(0); + l1extra_.nPfPhase1L1Jets++; + + if (it->et() > 30 && fabs(it->eta()) < 2.4) { + HT30 += it->et(); + mHT30_px += it->px(); + mHT30_py += it->py(); + } + if (it->et() > 30 && fabs(it->eta()) < 3.5) { + HT30_3p5 += it->et(); + mHT30_3p5_px += it->px(); + mHT30_3p5_py += it->py(); + } + } + } + + l1extra_.nPfPhase1L1MHT = 2; + + l1extra_.pfPhase1L1MHTEt.push_back(sqrt(mHT30_px * mHT30_px + mHT30_py * mHT30_py)); + l1extra_.pfPhase1L1MHTPhi.push_back(atan(mHT30_py / mHT30_px)); + l1extra_.pfPhase1L1HT.push_back(HT30); + + l1extra_.pfPhase1L1MHTEt.push_back(sqrt(mHT30_3p5_px * mHT30_3p5_px + mHT30_3p5_py * mHT30_3p5_py)); + l1extra_.pfPhase1L1MHTPhi.push_back(atan(mHT30_3p5_py / mHT30_3p5_px)); + l1extra_.pfPhase1L1HT.push_back(HT30_3p5); +} + +/* +void L1Analysis::L1AnalysisPhaseII::SetPFJetForMET(const edm::Handle PFJet, unsigned maxL1Extra) +{ + + for(l1t::PFJetCollection::const_iterator it=PFJet->begin(); it!=PFJet->end() && l1extra_.nPuppiJetForMETspt()); + l1extra_.puppiJetForMETEtUnCorr .push_back(it->rawPt()); + l1extra_.puppiJetForMETEta.push_back(it->eta()); + l1extra_.puppiJetForMETPhi.push_back(it->phi()); +// l1extra_.puppiJetForMETzVtx.push_back(it->getJetVtx()); + l1extra_.puppiJetForMETBx .push_back(0);//it->bx()); + l1extra_.nPuppiJetForMETs++; + } +} +*/ + +void L1Analysis::L1AnalysisPhaseII::SetPFJet(const edm::Handle PFJet, unsigned maxL1Extra) { + double mHT30_px = 0, mHT30_py = 0, HT30 = 0; + double mHT30_3p5_px = 0, mHT30_3p5_py = 0, HT30_3p5 = 0; + + for (l1t::PFJetCollection::const_iterator it = PFJet->begin(); it != PFJet->end() && l1extra_.nPuppiJets < maxL1Extra; + it++) { + l1extra_.puppiJetEt.push_back(it->pt()); + l1extra_.puppiJetEtUnCorr.push_back(it->rawPt()); + l1extra_.puppiJetEta.push_back(it->eta()); + l1extra_.puppiJetPhi.push_back(it->phi()); + // l1extra_.puppiJetzVtx.push_back(it->getJetVtx()); + l1extra_.puppiJetBx.push_back(0); //it->bx()); + l1extra_.nPuppiJets++; + + if (it->pt() > 30 && fabs(it->eta()) < 2.4) { + HT30 += it->pt(); + mHT30_px += it->px(); + mHT30_py += it->py(); + } + if (it->pt() > 30 && fabs(it->eta()) < 3.5) { + HT30_3p5 += it->pt(); + mHT30_3p5_px += it->px(); + mHT30_3p5_py += it->py(); + } + } + l1extra_.puppiMHTEt.push_back(sqrt(mHT30_px * mHT30_px + mHT30_py * mHT30_py)); + l1extra_.puppiMHTPhi.push_back(atan(mHT30_py / mHT30_px)); + l1extra_.puppiHT.push_back(HT30); + + l1extra_.puppiMHTEt.push_back(sqrt(mHT30_3p5_px * mHT30_3p5_px + mHT30_3p5_py * mHT30_3p5_py)); + l1extra_.puppiMHTPhi.push_back(atan(mHT30_3p5_py / mHT30_3p5_px)); + l1extra_.puppiHT.push_back(HT30_3p5); + + l1extra_.nPuppiMHT = 2; +} + +void L1Analysis::L1AnalysisPhaseII::SetL1METPF(const edm::Handle> l1MetPF) { + reco::PFMET met = l1MetPF->at(0); + l1extra_.puppiMETEt = met.et(); + l1extra_.puppiMETPhi = met.phi(); +} + +void L1Analysis::L1AnalysisPhaseII::SetPFObjects(const edm::Handle> l1pfCandidates, + unsigned maxL1Extra) { + for (unsigned int i = 0; i < l1pfCandidates->size() && l1extra_.nPFMuons < maxL1Extra; i++) { + //enum Kind { ChargedHadron=0, Electron=1, NeutralHadron=2, Photon=3, Muon=4 }; + if (abs(l1pfCandidates->at(i).id()) == 4) { + l1extra_.pfMuonPt.push_back(l1pfCandidates->at(i).pt()); + l1extra_.pfMuonChg.push_back(l1pfCandidates->at(i).charge()); + l1extra_.pfMuonEta.push_back(l1pfCandidates->at(i).eta()); + l1extra_.pfMuonPhi.push_back(l1pfCandidates->at(i).phi()); + l1extra_.pfMuonzVtx.push_back( + l1pfCandidates->at(i) + .pfTrack() + ->track() + ->POCA() + .z()); // check with Giovanni, there has to be a cleaner way to do this. nParam_=4 should not be hardcoded + l1extra_.nPFMuons++; + } + } + + for (unsigned int i = 0; i < l1pfCandidates->size(); i++) { + //enum Kind { ChargedHadron=0, Electron=1, NeutralHadron=2, Photon=3, Muon=4 }; + if (abs(l1pfCandidates->at(i).id()) != 4) { + // std::cout<<"pf cand id: "<at(i).id()<at(i).id()); + l1extra_.pfCandEt.push_back(l1pfCandidates->at(i).pt()); + l1extra_.pfCandChg.push_back(l1pfCandidates->at(i).charge()); + l1extra_.pfCandEta.push_back(l1pfCandidates->at(i).eta()); + l1extra_.pfCandPhi.push_back(l1pfCandidates->at(i).phi()); + if (l1pfCandidates->at(i).id() == 0) { + l1extra_.pfCandzVtx.push_back(l1pfCandidates->at(i).pfTrack()->track()->POCA().z()); + } else { + l1extra_.pfCandzVtx.push_back(9999.0); + }; + + l1extra_.nPFCands++; + } + } +} +/* +void L1Analysis::L1AnalysisPhaseII::SetPFTaus(const edm::Handle< vector > l1pfTaus, unsigned maxL1Extra) +{ + + for (unsigned int i=0; isize() && l1extra_.nPFTausat(i).pt()<1) continue; + l1extra_.pfTauEt.push_back(l1pfTaus->at(i).pt()); + l1extra_.pfTauEta.push_back(l1pfTaus->at(i).eta()); + l1extra_.pfTauPhi.push_back(l1pfTaus->at(i).phi()); + l1extra_.pfTauChg.push_back(l1pfTaus->at(i).charge()); + l1extra_.pfTauType.push_back(l1pfTaus->at(i).tauType()); + l1extra_.pfTauChargedIso.push_back(l1pfTaus->at(i).chargedIso()); + unsigned int isoflag=l1pfTaus->at(i).tauIsoQuality(); + l1extra_.pfTauIsoFlag.push_back(isoflag); + //std::cout<at(i).pt()<<" "<at(i).chargedIso()<<" "<at(i).passTightIso()<<" "<at(i).tauRelIsoQuality(); + l1extra_.pfTauRelIsoFlag.push_back(isoflag); + l1extra_.pfTauPassesMediumIso.push_back(l1pfTaus->at(i).passMediumIso()); + + l1extra_.pfTauZ0.push_back(l1pfTaus->at(i).z0()); + l1extra_.nPFTaus++; + } + +} +*/ +/* +void L1Analysis::L1AnalysisPhaseII::SetHPSPFTaus(const edm::Handle l1HPSPFTaus, unsigned maxL1Extra) +{ + + for (unsigned int i=0; isize() && l1extra_.nHPSTausat(i).pt()<1) continue; + l1extra_.hpsTauEt.push_back(l1HPSPFTaus->at(i).pt()); + l1extra_.hpsTauEta.push_back(l1HPSPFTaus->at(i).eta()); + l1extra_.hpsTauPhi.push_back(l1HPSPFTaus->at(i).phi()); + l1extra_.hpsTauChg.push_back(l1HPSPFTaus->at(i).charge()); + l1extra_.hpsTauType.push_back(l1HPSPFTaus->at(i).tauType()); + l1extra_.hpsTauPassTightRelIso.push_back(l1HPSPFTaus->at(i).passTightRelIso()); + l1extra_.hpsTauZ0.push_back(l1HPSPFTaus->at(i).primaryVertex()->z0()); + l1extra_.nHPSTaus++; + } + +} +*/ + +void L1Analysis::L1AnalysisPhaseII::SetNNTaus(const edm::Handle> l1nnTaus, unsigned maxL1Extra) { + for (unsigned int i = 0; i < l1nnTaus->size() && l1extra_.nNNTaus < maxL1Extra; i++) { + if (l1nnTaus->at(i).pt() < 1) + continue; + l1extra_.nnTauEt.push_back(l1nnTaus->at(i).pt()); + l1extra_.nnTauEta.push_back(l1nnTaus->at(i).eta()); + l1extra_.nnTauPhi.push_back(l1nnTaus->at(i).phi()); + l1extra_.nnTauChg.push_back(l1nnTaus->at(i).charge()); + l1extra_.nnTauChargedIso.push_back(l1nnTaus->at(i).chargedIso()); + l1extra_.nnTauFullIso.push_back(l1nnTaus->at(i).fullIso()); + l1extra_.nnTauID.push_back(l1nnTaus->at(i).id()); + l1extra_.nnTauPassLooseNN.push_back(l1nnTaus->at(i).passLooseNN()); + l1extra_.nnTauPassLoosePF.push_back(l1nnTaus->at(i).passLoosePF()); + l1extra_.nnTauPassTightPF.push_back(l1nnTaus->at(i).passTightPF()); + l1extra_.nnTauPassTightNN.push_back(l1nnTaus->at(i).passTightNN()); + l1extra_.nNNTaus++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetNNTauPFs(const edm::Handle> l1nnTauPFs, unsigned maxL1Extra) { + for (unsigned int i = 0; i < l1nnTauPFs->size() && l1extra_.nNNTauPFs < maxL1Extra; i++) { + if (l1nnTauPFs->at(i).pt() < 1) + continue; + l1extra_.nnTauPFEt.push_back(l1nnTauPFs->at(i).pt()); + l1extra_.nnTauPFEta.push_back(l1nnTauPFs->at(i).eta()); + l1extra_.nnTauPFPhi.push_back(l1nnTauPFs->at(i).phi()); + l1extra_.nnTauPFChg.push_back(l1nnTauPFs->at(i).charge()); + l1extra_.nnTauPFChargedIso.push_back(l1nnTauPFs->at(i).chargedIso()); + l1extra_.nnTauPFFullIso.push_back(l1nnTauPFs->at(i).fullIso()); + l1extra_.nnTauPFID.push_back(l1nnTauPFs->at(i).id()); + l1extra_.nnTauPFPassLooseNN.push_back(l1nnTauPFs->at(i).passLooseNN()); + l1extra_.nnTauPFPassLoosePF.push_back(l1nnTauPFs->at(i).passLoosePF()); + l1extra_.nnTauPFPassTightPF.push_back(l1nnTauPFs->at(i).passTightPF()); + l1extra_.nnTauPFPassTightNN.push_back(l1nnTauPFs->at(i).passTightNN()); + l1extra_.nNNTauPFs++; + } +} + +void L1Analysis::L1AnalysisPhaseII::SetBsCands(const edm::Handle> l1TkBs, + unsigned maxL1Extra, + int kind) { + for (unsigned int i = 0; i < l1TkBs->size() && l1extra_.nTkBsCands < maxL1Extra; i++) { + l1extra_.tkBsCandPt.push_back(l1TkBs->at(i).pt()); + l1extra_.tkBsCandMass.push_back(l1TkBs->at(i).p4().M()); + l1extra_.tkBsCandEta.push_back(l1TkBs->at(i).eta()); + l1extra_.tkBsCandPhi.push_back(l1TkBs->at(i).phi()); + l1extra_.tkBsCandPhi1Pt.push_back(l1TkBs->at(i).phiCandidate(0).pt()); + l1extra_.tkBsCandPhi2Pt.push_back(l1TkBs->at(i).phiCandidate(1).pt()); + l1extra_.tkBsCandPhi1Mass.push_back(l1TkBs->at(i).phiCandidate(0).p4().M()); + l1extra_.tkBsCandPhi2Mass.push_back(l1TkBs->at(i).phiCandidate(1).p4().M()); + l1extra_.tkBsCandPhi1Phi.push_back(l1TkBs->at(i).phiCandidate(0).phi()); + l1extra_.tkBsCandPhi2Phi.push_back(l1TkBs->at(i).phiCandidate(1).phi()); + l1extra_.tkBsCandPhi1Eta.push_back(l1TkBs->at(i).phiCandidate(0).eta()); + l1extra_.tkBsCandPhi2Eta.push_back(l1TkBs->at(i).phiCandidate(1).eta()); + // l1extra_.tkBsCandDRPhiPair.push_back(l1TkBs->at(i).dRPhiPair()); + // l1extra_.tkBsCandDxyPhiPair.push_back(l1TkBs->at(i).dxyPhiPair()); + // l1extra_.tkBsCandDzPhiPair.push_back(l1TkBs->at(i).dRPhiPair()); + l1extra_.tkBsCandKind.push_back(kind); + l1extra_.nTkBsCands++; + } +} diff --git a/L1Trigger/L1TNtuples/src/L1AnalysisPhaseIIStep1.cc b/L1Trigger/L1TNtuples/src/L1AnalysisPhaseIIStep1.cc new file mode 100644 index 0000000000000..9c61d9a80917a --- /dev/null +++ b/L1Trigger/L1TNtuples/src/L1AnalysisPhaseIIStep1.cc @@ -0,0 +1,681 @@ +//This code is for filling the step1 menu objects, for full tree go for L1AnalysisPhaseII.c +#include "L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1.h" +#include "L1Trigger/L1TMuon/interface/MicroGMTConfiguration.h" +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkHTMissEmulatorProducer.h" + +L1Analysis::L1AnalysisPhaseIIStep1::L1AnalysisPhaseIIStep1() {} + +L1Analysis::L1AnalysisPhaseIIStep1::~L1AnalysisPhaseIIStep1() {} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetVertices(float z0Puppi, + const edm::Handle > TkPrimaryVertex) { + //l1extra_.z0Puppi = z0Puppi; + l1extra_.z0L1TkPV = TkPrimaryVertex->at(0).z0(); + for (unsigned int i = 0; i < TkPrimaryVertex->size(); i++) { + l1extra_.z0L1TkAll.push_back(TkPrimaryVertex->at(i).z0()); + //l1extra_.sumL1TkPV.push_back(TkPrimaryVertex->at(i).sum()); + l1extra_.nL1TkPVs++; + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetCaloTau(const edm::Handle calotau, + unsigned maxL1Extra) { + for (int ibx = calotau->getFirstBX(); ibx <= calotau->getLastBX(); ++ibx) { + for (l1t::TauBxCollection::const_iterator it = calotau->begin(ibx); + it != calotau->end(ibx) && l1extra_.nCaloTaus < maxL1Extra; + it++) { + if (it->pt() > 0) { + l1extra_.caloTauPt.push_back(it->pt()); + l1extra_.caloTauEt.push_back(it->et()); + l1extra_.caloTauEta.push_back(it->eta()); + l1extra_.caloTauPhi.push_back(it->phi()); + l1extra_.caloTauIEt.push_back(it->hwPt()); + l1extra_.caloTauIEta.push_back(it->hwEta()); + l1extra_.caloTauIPhi.push_back(it->hwPhi()); + l1extra_.caloTauIso.push_back(it->hwIso()); + l1extra_.caloTauBx.push_back(ibx); + l1extra_.caloTauTowerIPhi.push_back(it->towerIPhi()); + l1extra_.caloTauTowerIEta.push_back(it->towerIEta()); + l1extra_.caloTauRawEt.push_back(it->rawEt()); + l1extra_.caloTauIsoEt.push_back(it->isoEt()); + l1extra_.caloTauNTT.push_back(it->nTT()); + l1extra_.caloTauHasEM.push_back(it->hasEM()); + l1extra_.caloTauIsMerged.push_back(it->isMerged()); + l1extra_.caloTauHwQual.push_back(it->hwQual()); + l1extra_.nCaloTaus++; + } + } + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetHPSPFTaus(const edm::Handle l1HPSPFTaus, + unsigned maxL1Extra) { + for (unsigned int i = 0; i < l1HPSPFTaus->size() && l1extra_.nHPSTaus < maxL1Extra; i++) { + if (l1HPSPFTaus->at(i).pt() < 1) + continue; + l1extra_.hpsTauPt.push_back(l1HPSPFTaus->at(i).pt()); + l1extra_.hpsTauEt.push_back(l1HPSPFTaus->at(i).et()); + l1extra_.hpsTauEta.push_back(l1HPSPFTaus->at(i).eta()); + l1extra_.hpsTauPhi.push_back(l1HPSPFTaus->at(i).phi()); + l1extra_.hpsTauChg.push_back(l1HPSPFTaus->at(i).charge()); + l1extra_.hpsTauType.push_back(l1HPSPFTaus->at(i).tauType()); + l1extra_.hpsTauPassTightRelIso.push_back(l1HPSPFTaus->at(i).passTightRelIso()); + bool hpsTauPassTightRelIsoMenuVar = (l1HPSPFTaus->at(i).sumChargedIso() / l1HPSPFTaus->at(i).pt()) < 0.05; + l1extra_.hpsTauPassTightRelIsoMenu.push_back(hpsTauPassTightRelIsoMenuVar); + l1extra_.hpsTauZ0.push_back(l1HPSPFTaus->at(i).z()); + //if (!l1HPSPFTaus->at(i).leadChargedPFCand().isNull()){ + // l1extra_.hpsTauZ0.push_back(l1HPSPFTaus->at(i).leadChargedPFCand()->pfTrack()->vertex().z()); + //}else{ + // l1extra_.hpsTauZ0.push_back(-9999); + //} + l1extra_.nHPSTaus++; + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetCaloJet(const edm::Handle jet, + unsigned maxL1Extra, + float caloJetHTT) { + double mHT30_px = 0, mHT30_py = 0, HT30 = 0; + double mHT30_3p5_px = 0, mHT30_3p5_py = 0, HT30_3p5 = 0; + + for (int ibx = jet->getFirstBX(); ibx <= jet->getLastBX(); ++ibx) { + for (l1t::JetBxCollection::const_iterator it = jet->begin(ibx); + it != jet->end(ibx) && l1extra_.nCaloJets < maxL1Extra; + it++) { + if (it->pt() > 0) { + l1extra_.caloJetEt.push_back(it->et()); + l1extra_.caloJetPt.push_back(it->pt()); + l1extra_.caloJetEta.push_back(it->eta()); + l1extra_.caloJetPhi.push_back(it->phi()); + l1extra_.caloJetBx.push_back(ibx); + l1extra_.nCaloJets++; + + if (it->pt() > 30 && fabs(it->eta()) < 2.4) { + HT30 += it->pt(); + mHT30_px += it->px(); + mHT30_py += it->py(); + } + if (it->pt() > 30 && fabs(it->eta()) < 3.5) { + HT30_3p5 += it->pt(); + mHT30_3p5_px += it->px(); + mHT30_3p5_py += it->py(); + } + } + } + } + + l1extra_.caloJetHT = caloJetHTT; + + l1extra_.caloJetMHTMenuEt.push_back(sqrt(mHT30_px * mHT30_px + mHT30_py * mHT30_py)); + l1extra_.caloJetMHTMenuPhi.push_back(atan(mHT30_py / mHT30_px)); + l1extra_.caloJetHTMenu.push_back(HT30); + + l1extra_.caloJetMHTMenuEt.push_back(sqrt(mHT30_3p5_px * mHT30_3p5_px + mHT30_3p5_py * mHT30_3p5_py)); + l1extra_.caloJetMHTMenuPhi.push_back(atan(mHT30_3p5_py / mHT30_3p5_px)); + l1extra_.caloJetHTMenu.push_back(HT30_3p5); + + l1extra_.nCaloJetMHTMenu = 2; +} + +//EG (seeded by Phase 2 Objects ) +void L1Analysis::L1AnalysisPhaseIIStep1::SetEG(const edm::Handle EG, + const edm::Handle EGHGC, + unsigned maxL1Extra) { + for (l1t::EGammaBxCollection::const_iterator it = EG->begin(); it != EG->end() && l1extra_.nEG < maxL1Extra; it++) { + if (it->et() > 5) { + l1extra_.EGPt.push_back(it->pt()); + l1extra_.EGEt.push_back(it->et()); + l1extra_.EGEta.push_back(it->eta()); + l1extra_.EGPhi.push_back(it->phi()); + l1extra_.EGIso.push_back(it->isoEt()); + l1extra_.EGHwQual.push_back(it->hwQual()); + l1extra_.EGBx.push_back(0); //it->bx()); + l1extra_.EGHGC.push_back(0); + bool quality = ((it->hwQual() >> 1) & 1) > 0; + l1extra_.EGPassesLooseTrackID.push_back(quality); + quality = ((it->hwQual() >> 2) & 1) > 0; + l1extra_.EGPassesPhotonID.push_back(quality); + l1extra_.nEG++; + } + } + + for (l1t::EGammaBxCollection::const_iterator it = EGHGC->begin(); it != EGHGC->end() && l1extra_.nEG < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.EGPt.push_back(it->pt()); + l1extra_.EGEt.push_back(it->et()); + l1extra_.EGEta.push_back(it->eta()); + l1extra_.EGPhi.push_back(it->phi()); + l1extra_.EGIso.push_back(it->isoEt()); + l1extra_.EGHwQual.push_back(it->hwQual()); + l1extra_.EGBx.push_back(0); //it->bx()); + l1extra_.EGHGC.push_back(1); + bool quality = (it->hwQual() == 3); + l1extra_.EGPassesLooseTrackID.push_back(quality); + l1extra_.EGPassesPhotonID.push_back(quality); + l1extra_.nEG++; + } + } +} + +// TrkEG (seeded by Phase 2 Objects) +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkEG(const edm::Handle tkElectron, + const edm::Handle tkElectronHGC, + unsigned maxL1Extra) { + for (l1t::TkElectronCollection::const_iterator it = tkElectron->begin(); + it != tkElectron->end() && l1extra_.nTkElectrons < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkElectronPt.push_back(it->pt()); + l1extra_.tkElectronEt.push_back(it->et()); + l1extra_.tkElectronEta.push_back(it->eta()); + l1extra_.tkElectronPhi.push_back(it->phi()); + int chargeFromCurvature = (it->trackCurvature() > 0) ? 1 : -1; // ThisIsACheck + l1extra_.tkElectronChg.push_back(chargeFromCurvature); + l1extra_.tkElectronzVtx.push_back(it->trkzVtx()); + l1extra_.tkElectronTrkIso.push_back(it->trkIsol()); + l1extra_.tkElectronPfIso.push_back(it->pfIsol()); + l1extra_.tkElectronPuppiIso.push_back(it->puppiIsol()); + l1extra_.tkElectronHwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkElectronEGRefPt.push_back(it->EGRef()->et()); //Rename this? + l1extra_.tkElectronEGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkElectronEGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkElectronBx.push_back(0); //it->bx()); + l1extra_.tkElectronHGC.push_back(0); + bool quality = ((it->EGRef()->hwQual() >> 1) & 1) > 0; // LooseTrackID should be the second bit + l1extra_.tkElectronPassesLooseTrackID.push_back(quality); + quality = ((it->EGRef()->hwQual() >> 2) & 1) > 0; // LooseTrackID should be the second bit + l1extra_.tkElectronPassesPhotonID.push_back(quality); + l1extra_.nTkElectrons++; + } + } + + for (l1t::TkElectronCollection::const_iterator it = tkElectronHGC->begin(); + it != tkElectronHGC->end() && l1extra_.nTkElectrons < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkElectronPt.push_back(it->pt()); + l1extra_.tkElectronEt.push_back(it->et()); + l1extra_.tkElectronEta.push_back(it->eta()); + l1extra_.tkElectronPhi.push_back(it->phi()); + int chargeFromCurvature = (it->trackCurvature() > 0) ? 1 : -1; // ThisIsACheck + l1extra_.tkElectronChg.push_back(chargeFromCurvature); + l1extra_.tkElectronzVtx.push_back(it->trkzVtx()); + l1extra_.tkElectronTrkIso.push_back(it->trkIsol()); + l1extra_.tkElectronPfIso.push_back(it->pfIsol()); + l1extra_.tkElectronPuppiIso.push_back(it->puppiIsol()); + l1extra_.tkElectronHwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkElectronEGRefPt.push_back(it->EGRef()->et()); //Rename this? + l1extra_.tkElectronEGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkElectronEGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkElectronBx.push_back(0); //it->bx()); + l1extra_.tkElectronHGC.push_back(1); + bool quality = (it->EGRef()->hwQual() == 3); + l1extra_.tkElectronPassesLooseTrackID.push_back(quality); + l1extra_.tkElectronPassesPhotonID.push_back(quality); + l1extra_.nTkElectrons++; + } + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkEM(const edm::Handle tkPhoton, + const edm::Handle tkPhotonHGC, + unsigned maxL1Extra) { + for (l1t::TkEmCollection::const_iterator it = tkPhoton->begin(); + it != tkPhoton->end() && l1extra_.nTkPhotons < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkPhotonPt.push_back(it->pt()); + l1extra_.tkPhotonEt.push_back(it->et()); + l1extra_.tkPhotonEta.push_back(it->eta()); + l1extra_.tkPhotonPhi.push_back(it->phi()); + l1extra_.tkPhotonTrkIso.push_back(it->trkIsol()); + l1extra_.tkPhotonTrkIsoPV.push_back(it->trkIsolPV()); + l1extra_.tkPhotonPfIso.push_back(it->pfIsol()); + l1extra_.tkPhotonPfIsoPV.push_back(it->pfIsolPV()); + l1extra_.tkPhotonPuppiIso.push_back(it->puppiIsol()); + l1extra_.tkPhotonPuppiIsoPV.push_back(it->puppiIsolPV()); + l1extra_.tkPhotonBx.push_back(0); //it->bx()); + l1extra_.tkPhotonHwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkPhotonEGRefPt.push_back(it->EGRef()->et()); //REname this? + l1extra_.tkPhotonEGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkPhotonEGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkPhotonHGC.push_back(0); + bool quality = ((it->EGRef()->hwQual() >> 1) & 1) > 0; + l1extra_.tkPhotonPassesLooseTrackID.push_back(quality); + quality = ((it->EGRef()->hwQual() >> 2) & 1) > 0; // Photon Id should be the third bit + l1extra_.tkPhotonPassesPhotonID.push_back(quality); + l1extra_.nTkPhotons++; + } + } + for (l1t::TkEmCollection::const_iterator it = tkPhotonHGC->begin(); + it != tkPhotonHGC->end() && l1extra_.nTkPhotons < maxL1Extra; + it++) { + if (it->et() > 5) { + l1extra_.tkPhotonPt.push_back(it->pt()); + l1extra_.tkPhotonEt.push_back(it->et()); + l1extra_.tkPhotonEta.push_back(it->eta()); + l1extra_.tkPhotonPhi.push_back(it->phi()); + l1extra_.tkPhotonTrkIso.push_back(it->trkIsol()); + l1extra_.tkPhotonTrkIsoPV.push_back(it->trkIsolPV()); + l1extra_.tkPhotonPfIso.push_back(it->pfIsol()); + l1extra_.tkPhotonPfIsoPV.push_back(it->pfIsolPV()); + l1extra_.tkPhotonPuppiIso.push_back(it->puppiIsol()); + l1extra_.tkPhotonPuppiIsoPV.push_back(it->puppiIsolPV()); + l1extra_.tkPhotonBx.push_back(0); //it->bx()); + l1extra_.tkPhotonHwQual.push_back(it->EGRef()->hwQual()); + l1extra_.tkPhotonEGRefPt.push_back(it->EGRef()->et()); //rename this? + l1extra_.tkPhotonEGRefEta.push_back(it->EGRef()->eta()); + l1extra_.tkPhotonEGRefPhi.push_back(it->EGRef()->phi()); + l1extra_.tkPhotonHGC.push_back(1); + bool quality = (it->EGRef()->hwQual() == 3); + l1extra_.tkPhotonPassesLooseTrackID.push_back(quality); + l1extra_.tkPhotonPassesPhotonID.push_back(quality); + l1extra_.nTkPhotons++; + } + } +} + +/* +void L1Analysis::L1AnalysisPhaseIIStep1::SetMuonKF(const edm::Handle standaloneMuon, + unsigned maxL1Extra, + unsigned int muonDetector) { + for (int ibx = standaloneMuon->getFirstBX(); ibx <= standaloneMuon->getLastBX(); ++ibx) { + for (l1t::RegionalMuonCandBxCollection::const_iterator it = standaloneMuon->begin(ibx); + it != standaloneMuon->end(ibx) && l1extra_.nStandaloneMuons < maxL1Extra; + it++) { + if (it->hwPt() > 0) { + // std::cout<<"hwPt vs hwPt2?"<hwPt()*0.5<<" "<hwPt2()<<" "<hwSign()<<" "<hwPt() * 0.5); + l1extra_.standaloneMuonPt2.push_back(it->hwPtUnconstrained()); + l1extra_.standaloneMuonDXY.push_back(it->hwDXY()); + l1extra_.standaloneMuonEta.push_back(it->hwEta() * 0.010875); + l1extra_.standaloneMuonPhi.push_back( + l1t::MicroGMTConfiguration::calcGlobalPhi(it->hwPhi(), it->trackFinderType(), it->processor()) * 2 * M_PI / + 576); + l1extra_.standaloneMuonChg.push_back(pow(-1, it->hwSign())); + l1extra_.standaloneMuonQual.push_back(it->hwQual()); + l1extra_.standaloneMuonRegion.push_back(muonDetector); + l1extra_.standaloneMuonBx.push_back(ibx); + l1extra_.nStandaloneMuons++; + } + } + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetMuonEMTF(const edm::Handle standaloneEMTFMuon, + unsigned maxL1Extra, + unsigned int muonDetector) { + for (l1t::EMTFTrackCollection::const_iterator it = standaloneEMTFMuon->begin(); + it != standaloneEMTFMuon->end() && l1extra_.nStandaloneMuons < maxL1Extra; + it++) { + if (it->Pt() > 0) { + l1extra_.standaloneMuonPt.push_back(it->Pt()); + l1extra_.standaloneMuonPt2.push_back(-999); + l1extra_.standaloneMuonDXY.push_back(-999); + l1extra_.standaloneMuonEta.push_back(it->Eta()); // * 0.010875); + l1extra_.standaloneMuonPhi.push_back(angle_units::operators::convertDegToRad(it->Phi_glob())); + l1extra_.standaloneMuonChg.push_back(it->Charge()); + l1extra_.standaloneMuonQual.push_back(it->Mode()); + l1extra_.standaloneMuonRegion.push_back(muonDetector); + l1extra_.standaloneMuonBx.push_back(it->BX()); + l1extra_.nStandaloneMuons++; + } + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkMuon(const edm::Handle muon, unsigned maxL1Extra) { + for (l1t::TkMuonCollection::const_iterator it = muon->begin(); it != muon->end() && l1extra_.nTkMuons < maxL1Extra; + it++) { + l1extra_.tkMuonPt.push_back(it->pt()); + l1extra_.tkMuonEta.push_back(it->eta()); + l1extra_.tkMuonPhi.push_back(it->phi()); + int chargeFromCurvature = (it->trackCurvature() > 0) ? 1 : -1; // ThisIsACheck + l1extra_.tkMuonChg.push_back(chargeFromCurvature); + l1extra_.tkMuonTrkIso.push_back(it->trkIsol()); + if (it->muonDetector() != 3) { + l1extra_.tkMuonMuRefPt.push_back(it->muRef()->hwPt() * 0.5); + l1extra_.tkMuonMuRefEta.push_back(it->muRef()->hwEta() * 0.010875); + l1extra_.tkMuonMuRefPhi.push_back(l1t::MicroGMTConfiguration::calcGlobalPhi(it->muRef()->hwPhi(), + it->muRef()->trackFinderType(), + it->muRef()->processor()) * + 2 * M_PI / 576); + l1extra_.tkMuonDRMuTrack.push_back(it->dR()); + l1extra_.tkMuonNMatchedTracks.push_back(it->nTracksMatched()); + l1extra_.tkMuonQual.push_back(it->quality()); + l1extra_.tkMuonMuRefChg.push_back(pow(-1, it->muRef()->hwSign())); + } else { + l1extra_.tkMuonMuRefPt.push_back(it->emtfTrk()->Pt()); + l1extra_.tkMuonMuRefEta.push_back(it->emtfTrk()->Eta()); + l1extra_.tkMuonMuRefPhi.push_back(angle_units::operators::convertDegToRad(it->emtfTrk()->Phi_glob())); + l1extra_.tkMuonDRMuTrack.push_back(it->dR()); + l1extra_.tkMuonNMatchedTracks.push_back(it->nTracksMatched()); + l1extra_.tkMuonQual.push_back(it->quality()); + l1extra_.tkMuonMuRefChg.push_back(it->emtfTrk()->Charge()); + } + l1extra_.tkMuonRegion.push_back(it->muonDetector()); + l1extra_.tkMuonzVtx.push_back(it->trkzVtx()); + l1extra_.tkMuonBx.push_back(0); //it->bx()); + l1extra_.nTkMuons++; + } +} + +//global muons + +//sta glb +void L1Analysis::L1AnalysisPhaseIIStep1::SetMuon(const edm::Handle muon, unsigned maxL1Extra) { + for (int ibx = muon->getFirstBX(); ibx <= muon->getLastBX(); ++ibx) { + for (l1t::MuonBxCollection::const_iterator it = muon->begin(ibx); + it != muon->end(ibx) && l1extra_.nGlobalMuons < maxL1Extra; + it++) { + if (it->pt() > 0) { + l1extra_.globalMuonPt.push_back(it->pt()); //use pT + l1extra_.globalMuonEta.push_back(it->eta()); + l1extra_.globalMuonPhi.push_back(it->phi()); + l1extra_.globalMuonEtaAtVtx.push_back(it->etaAtVtx()); + l1extra_.globalMuonPhiAtVtx.push_back(it->phiAtVtx()); + l1extra_.globalMuonIEt.push_back(it->hwPt()); //rename? + l1extra_.globalMuonIEta.push_back(it->hwEta()); + l1extra_.globalMuonIPhi.push_back(it->hwPhi()); + l1extra_.globalMuonIEtaAtVtx.push_back(it->hwEtaAtVtx()); + l1extra_.globalMuonIPhiAtVtx.push_back(it->hwPhiAtVtx()); + l1extra_.globalMuonIDEta.push_back(it->hwDEtaExtra()); + l1extra_.globalMuonIDPhi.push_back(it->hwDPhiExtra()); + l1extra_.globalMuonChg.push_back(it->charge()); + l1extra_.globalMuonIso.push_back(it->hwIso()); + l1extra_.globalMuonQual.push_back(it->hwQual()); + l1extra_.globalMuonTfMuonIdx.push_back(it->tfMuonIndex()); + l1extra_.globalMuonBx.push_back(ibx); + l1extra_.nGlobalMuons++; + } + } + } +} + +//tkmuon global +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkGlbMuon(const edm::Handle muon, + unsigned maxL1Extra) { + for (l1t::TkGlbMuonCollection::const_iterator it = muon->begin(); + it != muon->end() && l1extra_.nTkGlbMuons < maxL1Extra; + it++) { + l1extra_.tkGlbMuonPt.push_back(it->pt()); + l1extra_.tkGlbMuonEta.push_back(it->eta()); + l1extra_.tkGlbMuonPhi.push_back(it->phi()); + l1extra_.tkGlbMuonChg.push_back(it->charge()); + l1extra_.tkGlbMuonTrkIso.push_back(it->trkIsol()); + l1extra_.tkGlbMuonDRMuTrack.push_back(it->dR()); + l1extra_.tkGlbMuonNMatchedTracks.push_back(it->nTracksMatched()); + l1extra_.tkGlbMuonMuRefPt.push_back(it->muRef()->pt()); + l1extra_.tkGlbMuonMuRefEta.push_back(it->muRef()->eta()); + l1extra_.tkGlbMuonMuRefPhi.push_back(it->muRef()->phi()); + l1extra_.tkGlbMuonQual.push_back(it->muRef()->hwQual()); //What to do with this? + l1extra_.tkGlbMuonzVtx.push_back(it->trkzVtx()); + l1extra_.tkGlbMuonBx.push_back(0); //it->bx()); + l1extra_.nTkGlbMuons++; + } +} +*/ + + + +void L1Analysis::L1AnalysisPhaseIIStep1::SetL1PfPhase1L1TJet( + const edm::Handle > l1L1PFPhase1L1Jet, unsigned maxL1Extra) { + double mHT30_px = 0, mHT30_py = 0, HT30 = 0; + double mHT30_3p5_px = 0, mHT30_3p5_py = 0, HT30_3p5 = 0; + + for (reco::CaloJetCollection::const_iterator it = l1L1PFPhase1L1Jet->begin(); + it != l1L1PFPhase1L1Jet->end() && l1extra_.nPhase1PuppiJets < maxL1Extra; + it++) { + if (it->pt() > 0) { + l1extra_.phase1PuppiJetPt.push_back(it->pt()); + l1extra_.phase1PuppiJetEt.push_back(it->et()); + l1extra_.phase1PuppiJetEta.push_back(it->eta()); + l1extra_.phase1PuppiJetPhi.push_back(it->phi()); + // l1extra_.phase1PuppiJetBx .push_back(0); + l1extra_.nPhase1PuppiJets++; + + if (it->pt() > 30 && fabs(it->eta()) < 2.4) { //use pT + HT30 += it->pt(); + mHT30_px += it->px(); + mHT30_py += it->py(); + } + if (it->pt() > 30 && fabs(it->eta()) < 3.5) { + HT30_3p5 += it->pt(); + mHT30_3p5_px += it->px(); + mHT30_3p5_py += it->py(); + } + } + } + + l1extra_.nPhase1PuppiMHTMenu = 2; + + l1extra_.phase1PuppiMHTMenuEt.push_back(sqrt(mHT30_px * mHT30_px + mHT30_py * mHT30_py)); + l1extra_.phase1PuppiMHTMenuPhi.push_back(atan(mHT30_py / mHT30_px)); + l1extra_.phase1PuppiHTMenu.push_back(HT30); + + l1extra_.phase1PuppiMHTMenuEt.push_back(sqrt(mHT30_3p5_px * mHT30_3p5_px + mHT30_3p5_py * mHT30_3p5_py)); + l1extra_.phase1PuppiMHTMenuPhi.push_back(atan(mHT30_3p5_py / mHT30_3p5_px)); + l1extra_.phase1PuppiHTMenu.push_back(HT30_3p5); +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetL1PfPhase1L1TJetMET( + const edm::Handle > l1L1PFPhase1L1JetMET, unsigned maxL1Extra) { + l1t::EtSum met = l1L1PFPhase1L1JetMET->at(0); + //cout< > l1L1PFPhase1L1JetSums, unsigned maxL1Extra) { + //cout<<"testing the size of this sums vector:"<at(0); + l1t::EtSum MHT = l1L1PFPhase1L1JetSums->at(1); + //cout< PFJet, unsigned maxL1Extra) { + for (l1t::PFJetCollection::const_iterator it = PFJet->begin(); + it != PFJet->end() && l1extra_.nSeededConePuppiJets < maxL1Extra; + it++) { + l1extra_.seededConePuppiJetPt.push_back(it->pt()); + l1extra_.seededConePuppiJetEt.push_back(it->et()); + l1extra_.seededConePuppiJetEtUnCorr.push_back(it->rawPt()); //rename? + l1extra_.seededConePuppiJetEta.push_back(it->eta()); + l1extra_.seededConePuppiJetPhi.push_back(it->phi()); + // l1extra_.seededConePuppiJetzVtx.push_back(it->getJetVtx()); + l1extra_.seededConePuppiJetBx.push_back(0); //it->bx()); + l1extra_.nSeededConePuppiJets++; + } + +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetL1seededConeMHT(const edm::Handle > l1SeededConeMHT) { + l1t::EtSum HT = l1SeededConeMHT->at(0); + l1t::EtSum MHT = l1SeededConeMHT->at(1); + l1extra_.seededConePuppiHT = HT.pt(); + l1extra_.seededConePuppiMHTEt = MHT.pt(); + l1extra_.seededConePuppiMHTPhi = MHT.phi(); +} + + +void L1Analysis::L1AnalysisPhaseIIStep1::SetL1METPF(const edm::Handle > l1MetPF) { + l1t::EtSum met = l1MetPF->at(0); + l1extra_.puppiMETEt = met.et(); + l1extra_.puppiMETPhi = met.phi(); +} + +//void L1Analysis::L1AnalysisPhaseIIStep1::SetL1METPF(const edm::Handle > l1MetPF) { +// reco::PFMET met = l1MetPF->at(0); +// l1extra_.puppiMETRecoEt = met.et(); +// l1extra_.puppiMETRecoPhi = met.phi(); +//} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetNNTaus(const edm::Handle > l1nnTaus, + unsigned maxL1Extra) { + for (unsigned int i = 0; i < l1nnTaus->size() && l1extra_.nNNTaus < maxL1Extra; i++) { + if (l1nnTaus->at(i).pt() < 1) + continue; + l1extra_.nnTauPt.push_back(l1nnTaus->at(i).pt()); + l1extra_.nnTauEt.push_back(l1nnTaus->at(i).et()); + l1extra_.nnTauEta.push_back(l1nnTaus->at(i).eta()); + l1extra_.nnTauPhi.push_back(l1nnTaus->at(i).phi()); + l1extra_.nnTauChg.push_back(l1nnTaus->at(i).charge()); + l1extra_.nnTauChargedIso.push_back(l1nnTaus->at(i).chargedIso()); + l1extra_.nnTauFullIso.push_back(l1nnTaus->at(i).fullIso()); + l1extra_.nnTauID.push_back(l1nnTaus->at(i).id()); + l1extra_.nnTauPassLooseNN.push_back(l1nnTaus->at(i).passLooseNN()); + l1extra_.nnTauPassLoosePF.push_back(l1nnTaus->at(i).passLoosePF()); + l1extra_.nnTauPassTightPF.push_back(l1nnTaus->at(i).passTightPF()); + l1extra_.nnTauPassTightNN.push_back(l1nnTaus->at(i).passTightNN()); + l1extra_.nnTauPassLooseNNMass.push_back(l1nnTaus->at(i).passLooseNNMass()); + l1extra_.nnTauPassTightNNMass.push_back(l1nnTaus->at(i).passTightNNMass()); + l1extra_.nnTauPassMass.push_back(l1nnTaus->at(i).passMass()); + l1extra_.nnTauDXY.push_back(l1nnTaus->at(i).dxy()); + l1extra_.nnTauZ0.push_back(l1nnTaus->at(i).z0()); + l1extra_.nNNTaus++; + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetNNTau2vtxs(const edm::Handle > l1nnTau2vtxs, + unsigned maxL1Extra) { + for (unsigned int i = 0; i < l1nnTau2vtxs->size() && l1extra_.nNNTau2vtxs < maxL1Extra; i++) { + if (l1nnTau2vtxs->at(i).pt() < 1) + continue; + l1extra_.nnTau2vtxPt.push_back(l1nnTau2vtxs->at(i).pt()); + l1extra_.nnTau2vtxEt.push_back(l1nnTau2vtxs->at(i).et()); + l1extra_.nnTau2vtxEta.push_back(l1nnTau2vtxs->at(i).eta()); + l1extra_.nnTau2vtxPhi.push_back(l1nnTau2vtxs->at(i).phi()); + l1extra_.nnTau2vtxChg.push_back(l1nnTau2vtxs->at(i).charge()); + l1extra_.nnTau2vtxChargedIso.push_back(l1nnTau2vtxs->at(i).chargedIso()); + l1extra_.nnTau2vtxFullIso.push_back(l1nnTau2vtxs->at(i).fullIso()); + l1extra_.nnTau2vtxID.push_back(l1nnTau2vtxs->at(i).id()); + l1extra_.nnTau2vtxPassLooseNN.push_back(l1nnTau2vtxs->at(i).passLooseNN()); + l1extra_.nnTau2vtxPassLoosePF.push_back(l1nnTau2vtxs->at(i).passLoosePF()); + l1extra_.nnTau2vtxPassTightPF.push_back(l1nnTau2vtxs->at(i).passTightPF()); + l1extra_.nnTau2vtxPassTightNN.push_back(l1nnTau2vtxs->at(i).passTightNN()); + l1extra_.nnTau2vtxPassLooseNNMass.push_back(l1nnTau2vtxs->at(i).passLooseNNMass()); + l1extra_.nnTau2vtxPassTightNNMass.push_back(l1nnTau2vtxs->at(i).passTightNNMass()); + l1extra_.nnTau2vtxPassMass.push_back(l1nnTau2vtxs->at(i).passMass()); + l1extra_.nnTau2vtxDXY.push_back(l1nnTau2vtxs->at(i).dxy()); + l1extra_.nnTau2vtxZ0.push_back(l1nnTau2vtxs->at(i).z0()); + l1extra_.nNNTau2vtxs++; + } +} + +// TkJet +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkJet(const edm::Handle trackerJet, + unsigned maxL1Extra) { + for (l1t::TkJetWordCollection::const_iterator it = trackerJet->begin(); + it != trackerJet->end() && l1extra_.nTrackerJets < maxL1Extra; + it++) { + l1extra_.trackerJetPt.push_back(it->pt()); + //l1extra_.trackerJetEt.push_back(it->et()); + l1extra_.trackerJetEta.push_back(it->glbeta()); + l1extra_.trackerJetPhi.push_back(it->glbphi()); + //l1extra_.trackerJetzVtx.push_back(it->jetVtx()); + l1extra_.trackerJetBx.push_back(0); //it->bx()); + l1extra_.nTrackerJets++; + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkJetDisplaced(const edm::Handle trackerJet, + unsigned maxL1Extra) { + for (l1t::TkJetWordCollection::const_iterator it = trackerJet->begin(); + it != trackerJet->end() && l1extra_.nTrackerJets < maxL1Extra; + it++) { + l1extra_.trackerJetDisplacedPt.push_back(it->pt()); + //l1extra_.trackerJetDisplacedEt.push_back(it->et()); + l1extra_.trackerJetDisplacedEta.push_back(it->glbeta()); + l1extra_.trackerJetDisplacedPhi.push_back(it->glbphi()); + l1extra_.trackerJetDisplacedZ0.push_back(it->z0()); + l1extra_.trackerJetDisplacedBx.push_back(0); //it->bx()); + l1extra_.nTrackerJetsDisplaced++; + } +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkMET(const edm::Handle > trackerMET) { + l1extra_.trackerMET = trackerMET->begin()->hwPt() * l1tmetemu::kStepMET; + l1extra_.trackerMETPhi = trackerMET->begin()->hwPhi() * l1tmetemu::kStepMETPhi - M_PI; +} + +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkMHT(const edm::Handle > trackerMHT) { + l1extra_.trackerMHT = trackerMHT->begin()->p4().energy() * l1tmhtemu::kStepMHT; + l1extra_.trackerHT = trackerMHT->begin()->hwPt() * l1tmhtemu::kStepPt; + l1extra_.trackerMHTPhi = trackerMHT->begin()->hwPhi() * l1tmhtemu::kStepMHTPhi - M_PI; +} + + +void L1Analysis::L1AnalysisPhaseIIStep1::SetTkMHTDisplaced(const edm::Handle > trackerMHT) { + l1extra_.trackerHTDisplaced = trackerMHT->begin()->hwPt() * l1tmhtemu::kStepPt; + l1extra_.trackerMHTDisplaced = trackerMHT->begin()->p4().energy() * l1tmhtemu::kStepMHT; + l1extra_.trackerMHTPhiDisplaced = trackerMHT->begin()->hwPhi() * l1tmhtemu::kStepMHTPhi - M_PI; +} + +//gmt muons +void L1Analysis::L1AnalysisPhaseIIStep1::SetGmtMuon(const edm::Handle > gmtMuon, + unsigned maxL1Extra) { + + for (unsigned int i = 0; i < gmtMuon->size() && l1extra_.nGmtMuons < maxL1Extra; i++) { + if (lsb_pt * gmtMuon->at(i).hwPt() > 0) { + + l1extra_.gmtMuonPt.push_back(gmtMuon->at(i).phPt()); + l1extra_.gmtMuonEta.push_back(gmtMuon->at(i).phEta()); + l1extra_.gmtMuonPhi.push_back(gmtMuon->at(i).phPhi()); + l1extra_.gmtMuonZ0.push_back(gmtMuon->at(i).phZ0()); + l1extra_.gmtMuonD0.push_back(gmtMuon->at(i).phD0()); + + l1extra_.gmtMuonIPt.push_back(gmtMuon->at(i).hwPt()); //rename? + l1extra_.gmtMuonIEta.push_back(gmtMuon->at(i).hwEta()); + l1extra_.gmtMuonIPhi.push_back(gmtMuon->at(i).hwPhi()); + l1extra_.gmtMuonIZ0.push_back(gmtMuon->at(i).hwZ0()); + l1extra_.gmtMuonID0.push_back(gmtMuon->at(i).hwD0()); + + l1extra_.gmtMuonChg.push_back(gmtMuon->at(i).hwCharge()); + l1extra_.gmtMuonIso.push_back(gmtMuon->at(i).hwIso()); + l1extra_.gmtMuonQual.push_back(gmtMuon->at(i).hwQual()); + l1extra_.gmtMuonBeta.push_back(gmtMuon->at(i).hwBeta()); + + l1extra_.gmtMuonBx.push_back(0); //is this just 0 always? + + l1extra_.nGmtMuons++; + } + } +} + +//tkmuon gmt +void L1Analysis::L1AnalysisPhaseIIStep1::SetGmtTkMuon(const edm::Handle > gmtTkMuon, + + unsigned maxL1Extra) { + + for (unsigned int i = 0; i < gmtTkMuon->size() && l1extra_.nGmtTkMuons < maxL1Extra; i++) { + if (lsb_pt * gmtTkMuon->at(i).hwPt() > 0) { + + l1extra_.gmtTkMuonPt.push_back(gmtTkMuon->at(i).phPt()); + l1extra_.gmtTkMuonEta.push_back(gmtTkMuon->at(i).phEta()); + l1extra_.gmtTkMuonPhi.push_back(gmtTkMuon->at(i).phPhi()); + l1extra_.gmtTkMuonZ0.push_back(gmtTkMuon->at(i).phZ0()); + l1extra_.gmtTkMuonD0.push_back(gmtTkMuon->at(i).phD0()); + + l1extra_.gmtTkMuonIPt.push_back(gmtTkMuon->at(i).hwPt()); //rename? + l1extra_.gmtTkMuonIEta.push_back(gmtTkMuon->at(i).hwEta()); + l1extra_.gmtTkMuonIPhi.push_back(gmtTkMuon->at(i).hwPhi()); + l1extra_.gmtTkMuonIZ0.push_back(gmtTkMuon->at(i).hwZ0()); + l1extra_.gmtTkMuonID0.push_back(gmtTkMuon->at(i).hwD0()); + + l1extra_.gmtTkMuonChg.push_back(gmtTkMuon->at(i).hwCharge()); + l1extra_.gmtTkMuonIso.push_back(gmtTkMuon->at(i).hwIso()); + l1extra_.gmtTkMuonQual.push_back(gmtTkMuon->at(i).hwQual()); + l1extra_.gmtTkMuonBeta.push_back(gmtTkMuon->at(i).hwBeta()); + + l1extra_.gmtTkMuonNStubs.push_back(gmtTkMuon->at(i).stubs().size()); + l1extra_.gmtTkMuonBx.push_back(0); //is this just 0 always? + + l1extra_.nGmtTkMuons++; + } + } +} diff --git a/L1Trigger/L1TNtuples/src/classes.h b/L1Trigger/L1TNtuples/src/classes.h index 220da7a47b3f9..dd7969922dc9d 100644 --- a/L1Trigger/L1TNtuples/src/classes.h +++ b/L1Trigger/L1TNtuples/src/classes.h @@ -29,3 +29,5 @@ #include "L1Trigger/L1TNtuples/interface/L1AnalysisRecoTauDataFormat.h" #include "L1Trigger/L1TNtuples/interface/L1AnalysisRecoMuon2DataFormat.h" #include "L1Trigger/L1TNtuples/interface/L1AnalysisRecoElectronDataFormat.h" + +#include "L1Trigger/L1TNtuples/interface/L1AnalysisPhaseIIStep1DataFormat.h" diff --git a/L1Trigger/L1TNtuples/src/classes_def.xml b/L1Trigger/L1TNtuples/src/classes_def.xml index 2fd7d7bafa97f..69ae4f64bbc72 100644 --- a/L1Trigger/L1TNtuples/src/classes_def.xml +++ b/L1Trigger/L1TNtuples/src/classes_def.xml @@ -30,4 +30,7 @@ + + + diff --git a/L1Trigger/L1TTrackMatch/BuildFile.xml b/L1Trigger/L1TTrackMatch/BuildFile.xml index 4fd94f3fd8b79..1e3c8b04396a2 100644 --- a/L1Trigger/L1TTrackMatch/BuildFile.xml +++ b/L1Trigger/L1TTrackMatch/BuildFile.xml @@ -13,6 +13,7 @@ + diff --git a/L1Trigger/L1TTrackMatch/interface/Cordic.h b/L1Trigger/L1TTrackMatch/interface/Cordic.h new file mode 100644 index 0000000000000..9269fef225ccd --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/Cordic.h @@ -0,0 +1,40 @@ +#ifndef L1Trigger_L1TTrackMatch_Cordic_HH +#define L1Trigger_L1TTrackMatch_Cordic_HH + +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h" + +/* +** class : Cordic +** author : Christopher Brown +** date : 19/02/2021 +** brief : Integer sqrt and atan calculation for TrackMET emulation + +** : +*/ + +class Cordic { +public: + Cordic(); + Cordic(int aPhiScale, int aMagnitudeBits, const int aSteps, bool debug); + + l1tmetemu::EtMiss toPolar(l1tmetemu::Et_t x, l1tmetemu::Et_t y) const; + +private: + // Scale for Phi calculation to maintain precision + const int mPhiScale; + // Scale for Magnitude calculation + const int mMagnitudeScale; + // Bit width for internal magnitude + const int mMagnitudeBits; + // Number of cordic iterations + const int cordicSteps; + + const bool debug; + + // To calculate atan + std::vector atanLUT; + // To normalise final magnitude + std::vector magNormalisationLUT; +}; + +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h b/L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h deleted file mode 100644 index 1fd86fc14656b..0000000000000 --- a/L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef L1Trigger_L1TTrackMatch_L1TkElectronTrackMatchAlgo_HH -#define L1Trigger_L1TTrackMatch_L1TkElectronTrackMatchAlgo_HH - -#include "DataFormats/L1Trigger/interface/EGamma.h" -#include "DataFormats/GeometryVector/interface/GlobalPoint.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" - -namespace L1TkElectronTrackMatchAlgo { - typedef TTTrack L1TTTrackType; - typedef std::vector L1TTTrackCollection; - void doMatch(BXVector::const_iterator egIter, - const edm::Ptr& pTrk, - double& dph, - double& dr, - double& deta); - void doMatchClusterET(BXVector::const_iterator egIter, - const edm::Ptr& pTrk, - double& dph, - double& dr, - double& deta); - void doMatch(const GlobalPoint& epos, const edm::Ptr& pTrk, double& dph, double& dr, double& deta); - - double deltaR(const GlobalPoint& epos, const edm::Ptr& pTrk); - double deltaPhi(const GlobalPoint& epos, const edm::Ptr& pTrk); - double deltaPhiClusterET(BXVector::const_iterator egIter, const edm::Ptr& pTrk); - double deltaEta(const GlobalPoint& epos, const edm::Ptr& pTrk); - GlobalPoint calorimeterPosition(double phi, double eta, double e); - -} // namespace L1TkElectronTrackMatchAlgo -#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h b/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h new file mode 100644 index 0000000000000..65a9264fe7d7e --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h @@ -0,0 +1,122 @@ +#ifndef L1Trigger_L1TTrackMatch_L1TkEtMissEmuAlgo_HH +#define L1Trigger_L1TTrackMatch_L1TkEtMissEmuAlgo_HH + +#include + +#include +#include +#include +#include +#include +#include + +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +// Namespace that defines constants and types used by the EtMiss Emulation +// Includes functions for writing LUTs and converting to integer representations +namespace l1tmetemu { + + const unsigned int kInternalVTXWidth{12}; //default 8 max 12 + const unsigned int kInternalEtaWidth{8}; //default 8 max 16 + const unsigned int kInternalPtWidth{15}; // default 15 max 15 + const unsigned int kInternalPhiWidth{8}; //default 8 max 12 + + // Extra bits needed by global phi to span full range + const unsigned int kGlobalPhiExtra{3}; // default 3 + // Extra room for Et sums + const unsigned int kEtExtra{10}; // default 8 + + typedef ap_uint<3> nstub_t; + + typedef ap_uint global_phi_t; + + typedef ap_uint pt_t; + typedef ap_uint eta_t; + typedef ap_uint z_t; + // For internal Et representation, sums become larger than initial pt + // representation + typedef ap_int Et_t; + + //Output format + const float kMaxMET{4096}; // 4 TeV + const float kMaxMETPhi{2 * M_PI}; + const unsigned int kMETSize{15}; // For output Magnitude default 15 + const unsigned int kMETPhiSize{14}; // For Output Phi default 14 + + typedef ap_uint MET_t; + // Cordic means this is evaluated between 0 and 2Pi rather than -pi to pi so + // unsigned + typedef ap_uint METphi_t; + + const unsigned int kGlobalPhiBins = 1 << kInternalPhiWidth; + const unsigned int kMETBins = 1 << kMETSize; + const unsigned int kMETPhiBins = 1 << kMETPhiSize; + + const unsigned int kNEtaRegion{6}; + const unsigned int kNSector{9}; + const unsigned int kNQuadrants{4}; + + const float kMaxTrackZ0{-TTTrack_TrackWord::minZ0}; + const float kMaxTrackPt{512}; + const float kMaxTrackEta{4}; + + // Steps used to convert from track word floats to track MET integer representations + + const double kStepPt = (std::abs(kMaxTrackPt)) / (1 << kInternalPtWidth); + const double kStepEta = (2 * std::abs(kMaxTrackEta)) / (1 << kInternalEtaWidth); + const double kStepZ0 = (2 * std::abs(kMaxTrackZ0)) / (1 << kInternalVTXWidth); + + const double kStepPhi = (2 * -TTTrack_TrackWord::minPhi0) / (kGlobalPhiBins - 1); + + const double kStepMET = (l1tmetemu::kMaxMET / l1tmetemu::kMETBins); + const double kStepMETPhi = (l1tmetemu::kMaxMETPhi / l1tmetemu::kMETPhiBins); + + // Enough symmetry in cos and sin between 0 and pi/2 to get all possible values + // of cos and sin phi + const float kMaxCosLUTPhi{M_PI / 2}; + + // Simple struct used for ouput of cordic + struct EtMiss { + MET_t Et; + METphi_t Phi; + }; + + std::vector generateCosLUT(unsigned int size); + std::vector generateEtaRegionLUT(std::vector EtaRegions); + std::vector generateDeltaZLUT(std::vector DeltaZBins); + + template + T digitizeSignedValue(double value, unsigned int nBits, double lsb) { + // Digitize the incoming value + int digitizedValue = std::floor(value / lsb); + + // Calculate the maxmum possible positive value given an output of nBits in size + int digitizedMaximum = (1 << (nBits - 1)) - 1; // The remove 1 bit from nBits to account for the sign + int digitizedMinimum = -1. * (digitizedMaximum + 1); + + // Saturate the digitized value + digitizedValue = std::clamp(digitizedValue, digitizedMinimum, digitizedMaximum); + + // Do the two's compliment encoding + T twosValue = digitizedValue; + if (digitizedValue < 0) { + twosValue += (1 << nBits); + } + + return twosValue; + } + + template + unsigned int getBin(double value, const T& bins) { + auto up = std::upper_bound(bins.begin(), bins.end(), value); + return (up - bins.begin() - 1); + } + + int unpackSignedValue(unsigned int bits, unsigned int nBits); + + unsigned int transformSignedValue(unsigned int bits, unsigned int oldnBits, unsigned int newnBits); + +} // namespace l1tmetemu +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuTrackTransform.h b/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuTrackTransform.h new file mode 100644 index 0000000000000..77b291df4bb16 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuTrackTransform.h @@ -0,0 +1,133 @@ +#ifndef L1Trigger_L1TTrackMatch_L1TkEtMissEmuTrackTransform_HH +#define L1Trigger_L1TTrackMatch_L1TkEtMissEmuTrackTransform_HH + +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h" + +/* +** class : L1TkEtMissEmuTrackTransform +** author : Christopher Brown +** date : 19/02/2021 +** modified :16/06/2021 +** brief : Converts TTrack_trackword to internal Et word including vertex + +** : +*/ + +// Internal Word used by EtMiss Emulation, producer expects this wordtype +struct InternalEtWord { + l1tmetemu::z_t pV; + l1tmetemu::z_t z0; + + l1tmetemu::pt_t pt; + l1tmetemu::eta_t eta; + l1tmetemu::global_phi_t globalPhi; + l1tmetemu::nstub_t nstubs; + + TTTrack_TrackWord::hit_t Hitpattern; + TTTrack_TrackWord::bendChi2_t bendChi2; + TTTrack_TrackWord::chi2rphi_t chi2rphidof; + TTTrack_TrackWord::chi2rz_t chi2rzdof; + + unsigned int Sector; //Phi sector + bool EtaSector; //Positve or negative eta + + float phi; // Used to debug cos phi LUT +}; + +class L1TkEtMissEmuTrackTransform { +public: + L1TkEtMissEmuTrackTransform() = default; + ~L1TkEtMissEmuTrackTransform() = default; + + void generateLUTs(); // Generate internal LUTs needed for track transfrom + + // Transform track and vertex, allow for vertex word or vertex collections + template + InternalEtWord transformTrack(track& track_ref, vertex& PV); + + // Converts local int phi to global int phi + l1tmetemu::global_phi_t localToGlobalPhi(TTTrack_TrackWord::phi_t local_phi, l1tmetemu::global_phi_t sector_shift); + + // Function to count stubs in hitpattern + l1tmetemu::nstub_t countNStub(TTTrack_TrackWord::hit_t Hitpattern); + + std::vector generatePhiSliceLUT(unsigned int N); + + std::vector getPhiQuad() const { return phiQuadrants; } + std::vector getPhiShift() const { return phiShift; } + + void setGTTinput(bool input) { GTTinput_ = input; } + +private: + std::vector phiQuadrants; + std::vector phiShift; + + bool GTTinput_ = false; +}; + +// Template to allow vertex word or vertex from vertex finder depending on simulation vs emulation +template +InternalEtWord L1TkEtMissEmuTrackTransform::transformTrack(track& track_ref, vertex& PV) { + InternalEtWord Outword; + + unsigned int temp_pt; + unsigned int temp_eta; + + if (GTTinput_) { + if ((track_ref.getRinvWord() & (1 << (TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1))) != 0) { + // Only Want Magnitude of Pt for sums so perform absolute value + temp_pt = abs((1 << (TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1)) - track_ref.getRinvWord()); + } else { + temp_pt = track_ref.getRinvWord(); + } + Outword.pt = l1tmetemu::transformSignedValue( + temp_pt * 2, TTTrack_TrackWord::TrackBitWidths::kRinvSize, l1tmetemu::kInternalPtWidth); + + if ((track_ref.getTanlWord() & (1 << (TTTrack_TrackWord::TrackBitWidths::kTanlSize - 1))) != 0) { + // Only Want Magnitude of Eta for cuts and track to vertex association so + // perform absolute value + temp_eta = abs((1 << (TTTrack_TrackWord::TrackBitWidths::kTanlSize)) - track_ref.getTanlWord()); + } else { + temp_eta = track_ref.getTanlWord(); + } + Outword.eta = l1tmetemu::transformSignedValue( + temp_eta, TTTrack_TrackWord::TrackBitWidths::kTanlSize, l1tmetemu::kInternalEtaWidth); + + } else { + track_ref.setTrackWordBits(); + // Change track word digitization to digitization expected by track MET + Outword.pt = l1tmetemu::digitizeSignedValue( + track_ref.momentum().perp(), l1tmetemu::kInternalPtWidth, l1tmetemu::kStepPt); + + Outword.eta = l1tmetemu::digitizeSignedValue( + abs(track_ref.momentum().eta()), l1tmetemu::kInternalEtaWidth, l1tmetemu::kStepEta); + } + + Outword.chi2rphidof = track_ref.getChi2RPhiWord(); + Outword.chi2rzdof = track_ref.getChi2RZWord(); + Outword.bendChi2 = track_ref.getBendChi2Word(); + Outword.nstubs = countNStub(track_ref.getHitPatternWord()); + Outword.Hitpattern = track_ref.getHitPatternWord(); + Outword.Sector = track_ref.phiSector(); + Outword.EtaSector = (track_ref.getTanlWord() & (1 << (TTTrack_TrackWord::TrackBitWidths::kTanlSize - 1))); + Outword.phi = track_ref.phi(); + Outword.globalPhi = localToGlobalPhi(track_ref.getPhiWord(), phiShift[track_ref.phiSector()]); + + unsigned int temp_pv = l1tmetemu::digitizeSignedValue( + PV.z0(), + TTTrack_TrackWord::TrackBitWidths::kZ0Size, + TTTrack_TrackWord::stepZ0); // Convert vertex to integer representation + //Rescale to internal representations + Outword.z0 = l1tmetemu::transformSignedValue( + track_ref.getZ0Word(), TTTrack_TrackWord::TrackBitWidths::kZ0Size, l1tmetemu::kInternalVTXWidth); + Outword.pV = l1tmetemu::transformSignedValue( + temp_pv, TTTrack_TrackWord::TrackBitWidths::kZ0Size, l1tmetemu::kInternalVTXWidth); + + return Outword; +} + +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkHTMissEmulatorProducer.h b/L1Trigger/L1TTrackMatch/interface/L1TkHTMissEmulatorProducer.h new file mode 100644 index 0000000000000..cfdfed57820e3 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/L1TkHTMissEmulatorProducer.h @@ -0,0 +1,187 @@ +#ifndef L1Trigger_L1TTrackMatch_L1TkHTMissEmulatorProducer_HH +#define L1Trigger_L1TTrackMatch_L1TkHTMissEmulatorProducer_HH + +// Original Author: Hardik Routray +// Created: Mon, 11 Oct 2021 + +#include + +#include +#include +#include +#include +#include +#include + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "DataFormats/L1Trigger/interface/TkJetWord.h" + +// Namespace that defines constants and types used by the HTMiss Emulation + +namespace l1tmhtemu { + + const unsigned int kInternalPtWidth{l1t::TkJetWord::TkJetBitWidths::kPtSize}; + const unsigned int kInternalEtaWidth{l1t::TkJetWord::TkJetBitWidths::kGlbEtaSize}; + const unsigned int kInternalPhiWidth{l1t::TkJetWord::TkJetBitWidths::kGlbPhiSize}; + + // extra room for sumPx, sumPy + const unsigned int kEtExtra{10}; + + const unsigned int kValidSize{1}; + const unsigned int kMHTSize{15}; // For output Magnitude default 15 + const unsigned int kMHTPhiSize{14}; // For output Phi default 14 + const unsigned int kHTSize{kInternalPtWidth + kEtExtra}; + const unsigned int kUnassignedSize{64 - (kHTSize + kMHTSize + kMHTPhiSize + kValidSize)}; + + enum BitLocations { + // The location of the least significant bit (LSB) and most significant bit (MSB) in the sum word for different fields + kValidLSB = 0, + kValidMSB = kValidLSB + kValidSize - 1, + kMHTLSB = kValidMSB + 1, + kMHTMSB = kMHTLSB + kMHTSize - 1, + kMHTPhiLSB = kMHTMSB + 1, + kMHTPhiMSB = kMHTPhiLSB + kMHTPhiSize - 1, + kHTLSB = kMHTPhiMSB + 1, + kHTMSB = kHTLSB + kHTSize - 1, + kUnassignedLSB = kHTMSB + 1, + kUnassignedMSB = kUnassignedLSB + kUnassignedSize - 1 + }; + + const float kMaxMHT{4096}; // 4 TeV + const float kMaxMHTPhi{2 * M_PI}; + + typedef ap_uint<5> ntracks_t; + typedef ap_uint pt_t; + typedef ap_int eta_t; + typedef ap_int phi_t; + + typedef ap_int Et_t; + typedef ap_uint MHT_t; + typedef ap_uint MHTphi_t; + + const unsigned int kMHTBins = 1 << kMHTSize; + const unsigned int kMHTPhiBins = 1 << kMHTPhiSize; + + const double kStepPt{0.25}; + const double kStepEta{M_PI / (720)}; + const double kStepPhi{M_PI / (720)}; + + const double kStepMHT = (l1tmhtemu::kMaxMHT / l1tmhtemu::kMHTBins); + const double kStepMHTPhi = (l1tmhtemu::kMaxMHTPhi / l1tmhtemu::kMHTPhiBins); + + const unsigned int kPhiBins = 1 << kInternalPhiWidth; + + const float kMaxCosLUTPhi{M_PI}; + + template + T digitizeSignedValue(double value, unsigned int nBits, double lsb) { + T digitized_value = std::floor(std::abs(value) / lsb); + T digitized_maximum = (1 << (nBits - 1)) - 1; // The remove 1 bit from nBits to account for the sign + if (digitized_value > digitized_maximum) + digitized_value = digitized_maximum; + if (value < 0) + digitized_value = (1 << nBits) - digitized_value; // two's complement encoding + return digitized_value; + } + + inline std::vector generateCosLUT(unsigned int size) { // Fill cosine LUT with integer values + float phi = 0; + std::vector cosLUT; + for (unsigned int LUT_idx = 0; LUT_idx < size; LUT_idx++) { + cosLUT.push_back(digitizeSignedValue(cos(phi), l1tmhtemu::kInternalPhiWidth, l1tmhtemu::kStepPhi)); + phi += l1tmhtemu::kStepPhi; + } + cosLUT.push_back((phi_t)(0)); //Prevent overflow in last bin + return cosLUT; + } + + inline std::vector generateaTanLUT(int cordicSteps) { // Fill atan LUT with integer values + std::vector atanLUT; + atanLUT.reserve(cordicSteps); + for (int cordicStep = 0; cordicStep < cordicSteps; cordicStep++) { + atanLUT.push_back(MHTphi_t(round((kMHTPhiBins * atan(pow(2, -1 * cordicStep))) / (2 * M_PI)))); + } + return atanLUT; + } + + inline std::vector generatemagNormalisationLUT(int cordicSteps) { + float val = 1.0; + std::vector magNormalisationLUT; + for (int cordicStep = 0; cordicStep < cordicSteps; cordicStep++) { + val = val / (pow(1 + pow(4, -1 * cordicStep), 0.5)); + magNormalisationLUT.push_back(Et_t(round(kMHTBins * val))); + } + return magNormalisationLUT; + } + + struct EtMiss { + MHT_t Et; + MHTphi_t Phi; + }; + + inline EtMiss cordicSqrt(Et_t x, + Et_t y, + int cordicSteps, + std::vector atanLUT, + std::vector magNormalisationLUT) { + Et_t new_x = 0; + Et_t new_y = 0; + + MHTphi_t phi = 0; + MHTphi_t new_phi = 0; + bool sign = false; + + EtMiss ret_etmiss; + + if (x >= 0 && y >= 0) { + phi = 0; + sign = true; + //x = x; + //y = y; + } else if (x < 0 && y >= 0) { + phi = kMHTPhiBins >> 1; + sign = false; + x = -x; + //y = y; + } else if (x < 0 && y < 0) { + phi = kMHTPhiBins >> 1; + sign = true; + x = -x; + y = -y; + } else { + phi = kMHTPhiBins; + sign = false; + //x = x; + y = -y; + } + + for (int step = 0; step < cordicSteps; step++) { + if (y < 0) { + new_x = x - (y >> step); + new_y = y + (x >> step); + } else { + new_x = x + (y >> step); + new_y = y - (x >> step); + } + + if ((y < 0) == sign) { + new_phi = phi - atanLUT[step]; + } else { + new_phi = phi + atanLUT[step]; + } + + x = new_x; + y = new_y; + phi = new_phi; + } + + float sqrtval = (float(x * magNormalisationLUT[cordicSteps - 1]) / float(kMHTBins)) * float(kStepPt * kStepPhi); + + ret_etmiss.Et = std::floor(sqrtval / l1tmhtemu::kStepMHT); + ret_etmiss.Phi = phi; + + return ret_etmiss; + } + +} // namespace l1tmhtemu +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h b/L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h deleted file mode 100644 index 71809f52d6c13..0000000000000 --- a/L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef L1Trigger_L1TTrackMatch_L1TKMUCORRDYNAMICWINDOWS_H -#define L1Trigger_L1TTrackMatch_L1TKMUCORRDYNAMICWINDOWS_H - -#include "TFile.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "DataFormats/L1TCorrelator/interface/TkMuon.h" -#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" -#include "DataFormats/L1Trigger/interface/Muon.h" -#include "DataFormats/L1TMuon/interface/EMTFTrack.h" -#include "DataFormats/Math/interface/angle_units.h" - -#include "L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h" -#include "L1Trigger/L1TMuonEndCap/interface/Common.h" - -class L1TkMuCorrDynamicWindows { -public: - typedef TTTrack L1TTTrackType; - typedef std::vector L1TTTrackCollectionType; - - L1TkMuCorrDynamicWindows(const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi); - L1TkMuCorrDynamicWindows( - const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi, TFile* fIn_theta_S1, TFile* fIn_phi_S1); - ~L1TkMuCorrDynamicWindows() {} - std::vector find_match( - const EMTFTrackCollection& l1mus, - const L1TTTrackCollectionType& l1trks); // gives a vector with the idxs of muons for each L1TTT - std::vector find_match_stub( - const EMTFHitCollection& l1mus, - const L1TTTrackCollectionType& l1trks, - const int& station, - bool requireBX0 = true); // gives a vector with the idxs of muon stubs from station "station" for each L1TTT - - // ------------------------------ - static std::vector prepare_corr_bounds(const string& fname, const string& hname); - - void set_safety_factor(float sf_l, float sf_h) { - safety_factor_l_ = sf_l; - safety_factor_h_ = sf_h; - } - void set_sf_initialrelax(float sf_l, float sf_h) { - initial_sf_l_ = sf_l; - initial_sf_h_ = sf_h; - } - void set_relaxation_pattern(float pt_start, float pt_end) { - pt_start_ = pt_start; - pt_end_ = pt_end; - } - void set_safety_factor(float sf) { set_safety_factor(sf, sf); } - void set_sf_initialrelax(float sf) { set_sf_initialrelax(sf, sf); } - void set_do_relax_factor(bool val) { do_relax_factor_ = val; } - - void set_do_trk_qual_presel(bool val) { track_qual_presel_ = val; } - - // setters for trk - void set_n_trk_par(int val) { nTrkPars_ = val; } - void set_min_trk_p(float val) { min_trk_p_ = val; } - void set_max_trk_aeta(float val) { max_trk_aeta_ = val; } - void set_max_trk_chi2(float val) { max_trk_chi2_ = val; } - void set_min_trk_nstubs(int val) { min_trk_nstubs_ = val; } - - // getters for trk - const int n_trk_par() { return nTrkPars_; } - const float min_trk_p() { return min_trk_p_; } - const float max_trk_aeta() { return max_trk_aeta_; } - const float max_trk_chi2() { return max_trk_chi2_; } - const int min_trk_nstubs() { return min_trk_nstubs_; } - -private: - int findBin(double val); - - // resolves ambiguities to give max 1 tkmu per EMTF - // if a pointer to narbitrated is passed, this vector is filled with the number of tracks arbitrated that were matched to the same EMTF - std::vector make_unique_coll(const unsigned int& l1musSize, - const L1TTTrackCollectionType& l1trks, - const std::vector& matches); - - // converters - double eta_to_theta(double x) { - // give theta in rad - return (2. * atan(exp(-1. * x))); - } - - double to_mpio2_pio2(double x) { - // put the angle in radians between -pi/2 and pi/2 - while (x >= 0.5 * M_PI) - x -= M_PI; - while (x < -0.5 * M_PI) - x += M_PI; - return x; - } - - double sf_progressive(double x, double xstart, double xstop, double ystart, double ystop) { - if (x < xstart) - return ystart; - if (x >= xstart && x < xstop) - return ystart + (x - xstart) * (ystop - ystart) / (xstop - xstart); - return ystop; - } - - int nbins_; // counts the number of MatchWindow = bounds_.size() - 1 - std::vector bounds_; // counts the boundaries of the MatchWindow (in eta/theta) - std::vector wdws_theta_; - std::vector wdws_phi_; - std::vector wdws_theta_S1_; - std::vector wdws_phi_S1_; - float safety_factor_l_; // increase the lower theta/phi threshold by this fractions - float safety_factor_h_; // increase the upper theta/phi threshold by this fractions - float initial_sf_l_; // the start of the relaxation - float initial_sf_h_; // the start of the relaxation - float pt_start_; // the relaxation of the threshold - float pt_end_; // the relaxation of the threshold - bool do_relax_factor_; // true if applying the linear relaxation - bool track_qual_presel_; // if true, apply the track preselection - - // trk configurable params - int nTrkPars_; // 4 - float min_trk_p_; // 3.5 - float max_trk_aeta_; // 2.5 - float max_trk_chi2_; // 100 - int min_trk_nstubs_; // 4 -}; - -#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h b/L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h deleted file mode 100644 index 0a621d1b036d1..0000000000000 --- a/L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef L1Trigger_L1TTrackMatch_L1TKMUMANTRA_H -#define L1Trigger_L1TTrackMatch_L1TKMUMANTRA_H - -/* -** class : GenericDataFormat -** author : L.Cadamuro (UF) -** date : 4/11/2019 -** brief : very generic structs to be used as inputs to the correlator -** : to make sure that Mantra can handle muons and tracks from all the detectors -*/ - -namespace L1TkMuMantraDF { - - struct track_df { - double pt; // GeV - double eta; // rad, -inf / +inf - double theta; // rad, 0 -> +90-90 - double phi; // rad, -pi / + pi - int nstubs; // - double chi2; // - int charge; // -1. +1 - }; - - struct muon_df { - double pt; // GeV - double eta; // rad, -inf / +inf - double theta; // rad, 0 -> +90-90 - double phi; // rad, -pi / + pi - int charge; // -1. +1 - }; -} // namespace L1TkMuMantraDF - -/* -** class : L1TkMuMantra -** author : L.Cadamuro (UF) -** date : 4/11/2019 -** brief : correlates muons and tracks using pre-encoded windows -*/ - -#include -#include -#include -#include -#include "L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h" -#include - -#include "TFile.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "DataFormats/Math/interface/angle_units.h" - -class L1TkMuMantra { -public: - L1TkMuMantra(const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi, std::string name); - ~L1TkMuMantra(){}; - - // returns a vector with the same size of muons, each with an index to the matched L1 track, or -1 if no match is found - std::vector find_match(const std::vector& tracks, - const std::vector& muons); - - void test(double eta, double pt); - - void relax_windows(double& low, double cent, double& high); // will modify low and high - - void set_safety_factor(float sf_l, float sf_h) { - safety_factor_l_ = sf_l; - safety_factor_h_ = sf_h; - if (verbosity_ > 0) - LogTrace("L1TkMuMantra") << name_ << " safety factor LOW is " << safety_factor_l_ << std::endl; - if (verbosity_ > 0) - LogTrace("L1TkMuMantra") << name_ << " safety factor HIGH is " << safety_factor_h_ << std::endl; - } - - int sign(double x) { - if (x == 0) - return 1; - return (0 < x) - (x < 0); - } - - void setArbitrationType(std::string type); // MaxPt, MinDeltaPt - - // static functions, meant to be used from outside to interface with MAnTra - static std::vector prepare_corr_bounds(std::string fname, std::string hname); - - // converters - static double eta_to_theta(double x) { - // give theta in rad - return (2. * atan(exp(-1. * x))); - } - - static double to_mpio2_pio2(double x) { - // put the angle in radians between -pi/2 and pi/2 - while (x >= 0.5 * M_PI) - x -= M_PI; - while (x < -0.5 * M_PI) - x += M_PI; - return x; - } - -private: - int findBin(double val); - - std::string name_; - - int nbins_; // counts the number of MuMatchWindow = bounds_.size() - 1 - std::vector bounds_; // counts the boundaries of the MuMatchWindow (in eta/theta) - std::vector wdws_theta_; - std::vector wdws_phi_; - - int min_nstubs = 4; // >= min_nstubs - double max_chi2 = 100; // < max_chi2 - - float safety_factor_l_; // increase the lower theta/phi threshold by this fractions w.r.t. the center - float safety_factor_h_; // increase the upper theta/phi threshold by this fractions w.r.t. the center - - enum sortParType { - kMaxPt, // pick the highest pt track matched - kMinDeltaPt // pick the track with the smallest pt difference w.r.t the muon - }; - - sortParType sort_type_; - - int verbosity_ = 0; -}; - -#endif // L1TKMUMANTRA_H diff --git a/L1Trigger/L1TTrackMatch/interface/L1TrackJetEmulationProducer.h b/L1Trigger/L1TTrackMatch/interface/L1TrackJetEmulationProducer.h new file mode 100644 index 0000000000000..dd46370d13af4 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/interface/L1TrackJetEmulationProducer.h @@ -0,0 +1,79 @@ +#ifndef L1Trigger_L1TTrackMatch_L1TrackJetEmulationProducer_HH +#define L1Trigger_L1TTrackMatch_L1TrackJetEmulationProducer_HH +#include +#include +#include +#include +#include +#include +#include "DataFormats/L1Trigger/interface/TkJetWord.h" + +//For precision studies +const int PT_EXTRABITS = 0; +const int ETA_EXTRABITS = 0; +const int PHI_EXTRABITS = 0; +const int Z0_EXTRABITS = 0; + +typedef ap_ufixed<16 + PT_EXTRABITS, 11, AP_TRN, AP_SAT> pt_intern; +typedef ap_int<14 + ETA_EXTRABITS> glbeta_intern; +typedef ap_int<14 + PHI_EXTRABITS> glbphi_intern; +typedef ap_int<10 + Z0_EXTRABITS> z0_intern; // 40cm / 0.1 + +namespace convert { + const int INTPHI_PI = 720; + const int INTPHI_TWOPI = 2 * INTPHI_PI; + static const float INTPT_LSB_POW = pow(2.0, -5 - PT_EXTRABITS); + static const float INTPT_LSB = INTPT_LSB_POW; + static const float ETA_LSB_POW = pow(2.0, -1 * ETA_EXTRABITS); + static const float ETA_LSB = M_PI / pow(2.0, 12) * ETA_LSB_POW; + static const float PHI_LSB_POW = pow(2.0, -1 * PHI_EXTRABITS); + static const float PHI_LSB = M_PI / pow(2.0, 12) * PHI_LSB_POW; + static const float Z0_LSB_POW = pow(2.0, -1 * Z0_EXTRABITS); + static const float Z0_LSB = 0.05 * Z0_LSB_POW; + inline float floatPt(pt_intern pt) { return pt.to_float(); } + inline int intPt(pt_intern pt) { return (ap_ufixed<18 + PT_EXTRABITS, 13 + PT_EXTRABITS>(pt)).to_int(); } + inline float floatEta(glbeta_intern eta) { return eta.to_float() * ETA_LSB; } + inline float floatPhi(glbphi_intern phi) { return phi.to_float() * PHI_LSB; } + inline float floatZ0(z0_intern z0) { return z0.to_float() * Z0_LSB; } + + inline pt_intern makePt(int pt) { return ap_ufixed<18 + PT_EXTRABITS, 13 + PT_EXTRABITS>(pt); } + inline pt_intern makePtFromFloat(float pt) { return pt_intern(INTPT_LSB_POW * round(pt / INTPT_LSB_POW)); } + inline z0_intern makeZ0(float z0) { return z0_intern(round(z0 / Z0_LSB)); } + + inline ap_uint ptToInt(pt_intern pt) { + // note: this can be synthethized, e.g. when pT is used as intex in a LUT + ap_uint ret = 0; + ret(pt_intern::width - 1, 0) = pt(pt_intern::width - 1, 0); + return ret; + } + + inline glbeta_intern makeGlbEta(float eta) { return round(eta / ETA_LSB); } + inline glbeta_intern makeGlbEtaRoundEven(float eta) { + glbeta_intern ghweta = round(eta / ETA_LSB); + return (ghweta % 2) ? glbeta_intern(ghweta + 1) : ghweta; + } + + inline glbphi_intern makeGlbPhi(float phi) { return round(phi / PHI_LSB); } + +}; // namespace convert + +//Each individual box in the eta and phi dimension. +// Also used to store final cluster data for each zbin. +struct TrackJetEmulationEtaPhiBin { + pt_intern pTtot; + l1t::TkJetWord::nt_t ntracks; + l1t::TkJetWord::nx_t nxtracks; + bool used; + glbphi_intern phi; //average phi value (halfway b/t min and max) + glbeta_intern eta; //average eta value +}; + +//store important information for plots +struct TrackJetEmulationMaxZBin { + int znum; //Numbered from 0 to nzbins (16, 32, or 64) in order + int nclust; //number of clusters in this bin + z0_intern zbincenter; + TrackJetEmulationEtaPhiBin *clusters; //list of all the clusters in this bin + pt_intern ht; //sum of all cluster pTs--only the zbin with the maximum ht is stored +}; +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/L1TrackJetProducer.h b/L1Trigger/L1TTrackMatch/interface/L1TrackJetProducer.h index 7d7340d585389..57ac3a39953ae 100644 --- a/L1Trigger/L1TTrackMatch/interface/L1TrackJetProducer.h +++ b/L1Trigger/L1TTrackMatch/interface/L1TrackJetProducer.h @@ -1,9 +1,11 @@ -#pragma once +#ifndef L1Trigger_L1TTrackMatch_L1TrackJetProducer_HH +#define L1Trigger_L1TTrackMatch_L1TrackJetProducer_HH #include #include #include #include #include +#include //Each individual box in the eta and phi dimension. // Also used to store final cluster data for each zbin. @@ -16,6 +18,7 @@ struct EtaPhiBin { bool used; float phi; //average phi value (halfway b/t min and max) float eta; //average eta value + std::vector trackidx; }; //store important information for plots @@ -26,3 +29,4 @@ struct MaxZBin { EtaPhiBin *clusters; //list of all the clusters in this bin float ht; //sum of all cluster pTs--only the zbin with the maximum ht is stored }; +#endif diff --git a/L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h b/L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h deleted file mode 100644 index aa8a6da239bf7..0000000000000 --- a/L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef L1Trigger_L1TTrackMatch_MUMATCHWINDOW_H -#define L1Trigger_L1TTrackMatch_MUMATCHWINDOW_H - -#include "TF1.h" -#include -#include -#include - -/* -** class : MuMatchWindow -** author : L.Cadamuro (UF) -** date : 25/12/2018 -** brief : encodes the lower, central, and upper bounds to match a track to a muon -** to be flexible, limits are given as strings to create a TF1 function -*/ - -class MuMatchWindow { -public: - MuMatchWindow(); - MuMatchWindow(std::string name); - ~MuMatchWindow(); - void SetName(std::string name) { name_ = name; } - - void SetLower(std::string formula); - void SetCentral(std::string formula); - void SetUpper(std::string formula); - - void SetLower(TF1* formula); - void SetCentral(TF1* formula); - void SetUpper(TF1* formula); - - // bool matches (double pt); - const double bound_low(double pt) { return fLow_->Eval(pt); } - const double bound_cent(double pt) { return fCent_->Eval(pt); } - const double bound_high(double pt) { return fHigh_->Eval(pt); } - -private: - std::string name_; - std::shared_ptr fLow_; - std::shared_ptr fCent_; - std::shared_ptr fHigh_; -}; - -#endif diff --git a/L1Trigger/L1TTrackMatch/plugins/BuildFile.xml b/L1Trigger/L1TTrackMatch/plugins/BuildFile.xml index 577495943b1e0..fdafd47595970 100644 --- a/L1Trigger/L1TTrackMatch/plugins/BuildFile.xml +++ b/L1Trigger/L1TTrackMatch/plugins/BuildFile.xml @@ -1,13 +1,23 @@ + + + + + + - + + + + + diff --git a/L1Trigger/L1TTrackMatch/plugins/L1FastTrackingJetProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1FastTrackingJetProducer.cc index 8af9cf53cfb3e..35d46da11db45 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1FastTrackingJetProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1FastTrackingJetProducer.cc @@ -14,7 +14,6 @@ #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/EventSetup.h" #include "DataFormats/Common/interface/Handle.h" #include "FWCore/Utilities/interface/InputTag.h" @@ -70,19 +69,19 @@ class L1FastTrackingJetProducer : public edm::stream::EDProducer<> { virtual void endJob(); // track selection criteria - float trkZMax_; // in [cm] - float trkChi2dofMax_; // maximum track chi2dof - double trkBendChi2Max_; // maximum track bendchi2 - float trkPtMin_; // in [GeV] - float trkEtaMax_; // in [rad] - int trkNStubMin_; // minimum number of stubs - int trkNPSStubMin_; // minimum number of PS stubs - double deltaZ0Cut_; // save with |L1z-z0| < maxZ0 - double coneSize_; // Use anti-kt with this cone size - bool doTightChi2_; - float trkPtTightChi2_; - float trkChi2dofTightChi2_; - bool displaced_; //use prompt/displaced tracks + const float trkZMax_; // in [cm] + const float trkChi2dofMax_; // maximum track chi2dof + const double trkBendChi2Max_; // maximum track bendchi2 + const float trkPtMin_; // in [GeV] + const float trkEtaMax_; // in [rad] + const int trkNStubMin_; // minimum number of stubs + const int trkNPSStubMin_; // minimum number of PS stubs + const double deltaZ0Cut_; // save with |L1z-z0| < maxZ0 + const double coneSize_; // Use anti-kt with this cone size + const bool doTightChi2_; + const float trkPtTightChi2_; + const float trkChi2dofTightChi2_; + const bool displaced_; //use prompt/displaced tracks bool selectTrkMatchGenTight_; bool selectTrkMatchGenLoose_; bool selectTrkMatchGenOrPU_; @@ -91,32 +90,34 @@ class L1FastTrackingJetProducer : public edm::stream::EDProducer<> { edm::EDGetTokenT> pvToken_; const edm::EDGetTokenT> genToken_; edm::ESGetToken tTopoToken_; + edm::ESGetToken tGeomToken_; }; // constructor L1FastTrackingJetProducer::L1FastTrackingJetProducer(const edm::ParameterSet& iConfig) - : trackToken_(consumes>>( + : trkZMax_((float)iConfig.getParameter("trk_zMax")), + trkChi2dofMax_((float)iConfig.getParameter("trk_chi2dofMax")), + trkBendChi2Max_(iConfig.getParameter("trk_bendChi2Max")), + trkPtMin_((float)iConfig.getParameter("trk_ptMin")), + trkEtaMax_((float)iConfig.getParameter("trk_etaMax")), + trkNStubMin_((int)iConfig.getParameter("trk_nStubMin")), + trkNPSStubMin_((int)iConfig.getParameter("trk_nPSStubMin")), + deltaZ0Cut_((float)iConfig.getParameter("deltaZ0Cut")), + coneSize_((float)iConfig.getParameter("coneSize")), + doTightChi2_(iConfig.getParameter("doTightChi2")), + trkPtTightChi2_((float)iConfig.getParameter("trk_ptTightChi2")), + trkChi2dofTightChi2_((float)iConfig.getParameter("trk_chi2dofTightChi2")), + displaced_(iConfig.getParameter("displaced")), + selectTrkMatchGenTight_(iConfig.getParameter("selectTrkMatchGenTight")), + selectTrkMatchGenLoose_(iConfig.getParameter("selectTrkMatchGenLoose")), + selectTrkMatchGenOrPU_(iConfig.getParameter("selectTrkMatchGenOrPU")), + trackToken_(consumes>>( iConfig.getParameter("L1TrackInputTag"))), pvToken_(consumes>(iConfig.getParameter("L1PrimaryVertexTag"))), genToken_( consumes>(iConfig.getParameter("GenInfo"))), - tTopoToken_(esConsumes(edm::ESInputTag("", ""))) { - trkZMax_ = (float)iConfig.getParameter("trk_zMax"); - trkChi2dofMax_ = (float)iConfig.getParameter("trk_chi2dofMax"); - trkBendChi2Max_ = iConfig.getParameter("trk_bendChi2Max"); - trkPtMin_ = (float)iConfig.getParameter("trk_ptMin"); - trkEtaMax_ = (float)iConfig.getParameter("trk_etaMax"); - trkNStubMin_ = (int)iConfig.getParameter("trk_nStubMin"); - trkNPSStubMin_ = (int)iConfig.getParameter("trk_nPSStubMin"); - deltaZ0Cut_ = (float)iConfig.getParameter("deltaZ0Cut"); - coneSize_ = (float)iConfig.getParameter("coneSize"); - doTightChi2_ = iConfig.getParameter("doTightChi2"); - trkPtTightChi2_ = (float)iConfig.getParameter("trk_ptTightChi2"); - trkChi2dofTightChi2_ = (float)iConfig.getParameter("trk_chi2dofTightChi2"); - displaced_ = iConfig.getParameter("displaced"); - selectTrkMatchGenTight_ = iConfig.getParameter("selectTrkMatchGenTight"); - selectTrkMatchGenLoose_ = iConfig.getParameter("selectTrkMatchGenLoose"); - selectTrkMatchGenOrPU_ = iConfig.getParameter("selectTrkMatchGenOrPU"); + tTopoToken_(esConsumes(edm::ESInputTag("", ""))), + tGeomToken_(esConsumes(edm::ESInputTag("", ""))) { if (displaced_) produces("L1FastTrackingJetsExtended"); else @@ -142,6 +143,7 @@ void L1FastTrackingJetProducer::produce(edm::Event& iEvent, const edm::EventSetu // Tracker Topology const TrackerTopology& tTopo = iSetup.getData(tTopoToken_); + //const TrackerGeometry& tGeom = iSetup.getData(tGeomToken_); edm::Handle> L1VertexHandle; iEvent.getByToken(pvToken_, L1VertexHandle); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1GTTInputProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1GTTInputProducer.cc new file mode 100644 index 0000000000000..5074ec2c2cec1 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1GTTInputProducer.cc @@ -0,0 +1,538 @@ +// -*- C++ -*- +// +// Package: L1Trigger/L1TTrackMatch +// Class: L1GTTInputProducer +// +/**\class L1GTTInputProducer L1GTTInputProducer.cc L1Trigger/L1TTrackMatch/plugins/L1GTTInputProducer.cc + + Description: Takes in L1TTracks and outputs the same tracks, but with modifications to the underlying track word. + The modifications convert from Rinv --> pt and tanL --> eta. + + Implementation: + [Notes on implementation] +*/ +// +// Original Author: Alexx Perloff +// Created: Sat, 20 Feb 2021 17:02:00 GMT +// +// + +// user include files +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/EDMException.h" +#include "FWCore/Utilities/interface/StreamID.h" + +// Vivado HLS includes +#include +#include + +// system include files +#define _USE_MATH_DEFINES +#include +#include +#include +#include + +// +// class declaration +// + +class L1GTTInputProducer : public edm::global::EDProducer<> { +public: + explicit L1GTTInputProducer(const edm::ParameterSet&); + ~L1GTTInputProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + // ----------constants, enums and typedefs --------- + static constexpr unsigned int Npars4 = 4; + static constexpr unsigned int Npars5 = 5; + enum ConversionBitWidths { + kEtaMagSize = 3, // eta output magnitude size; MAG + FRAC should be <= kEtaInputSize + kEtaFracSize = 5, // eta output fraction size; MAG + FRAC should be <= kEtaInputSize + kEtaInputSize = 16, // size of tan(lambda) + + kPTMagSize = 7, // magnitude output size; MAG + FRAC should be <= kPTInputSize + kPTFracSize = 3, // fraction output size; MAG + FRAC should be <= kPTInputSize + kPTInputSize = 15, // size of 1/R + + kEtaOutputSize = kEtaMagSize + kEtaFracSize, // total bit width for eta + kPTOutputSize = kPTMagSize + kPTFracSize, // total bit width for pT + }; + + static constexpr double kEtaErrThresh = 0.0485; // error corresponding to 0.25 of a degree error in lambda + + static constexpr double kPTErrThresh = 5; // error threshold in percent + static constexpr double kSynchrotron = (1.0 / (0.3 * 3.8)); // 1/(0.3*B) for 1/R to 1/pT conversion + static constexpr unsigned int kPtLutSize = (1 << ConversionBitWidths::kPTOutputSize); + static constexpr unsigned int kEtaLutSize = (1 << (ConversionBitWidths::kEtaOutputSize - 1)); + + typedef TTTrack L1Track; + typedef std::vector TTTrackCollection; + typedef edm::View TTTrackCollectionView; + typedef ap_fixed out_eta_t; + typedef TTTrack_TrackWord::tanl_t in_eta_t; + typedef ap_ufixed out_pt_t; + typedef TTTrack_TrackWord::rinv_t in_pt_t; + typedef ap_uint<1> out_charge_t; + + // ----------member functions ---------------------- + void generate_eta_lut(); + void generate_pt_lut(); + bool getEtaBits( + const L1Track& track, out_eta_t& etaBits, double& expected, double& maxErrPerc, double& maxErrEpsilon) const; + bool getPtBits(const L1Track& track, + out_pt_t& ptBits, + out_charge_t& chargeBit, + double& expected, + double& maxErrPerc, + double& maxErrEpsilon, + double& minErrPerc, + double& minExpected) const; + double indexTanLambda2Eta(unsigned int indexTanLambda) const; + double inverseRT2InversePT(unsigned int indexRT) const; + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + template + int sgn(T val) const { + return (T(0) < val) - (val < T(0)); + } // From https://stackoverflow.com/questions/1903954/is-there-a-standard-sign-function-signum-sgn-in-c-c + double unpackSignedValue(unsigned int bits, unsigned int nBits, double lsb) const; + + // ----------member data --------------------------- + const edm::EDGetTokenT l1TracksToken_; + const std::string outputCollectionName_; + int debug_; + std::vector pt_lut_; + std::vector eta_lut_; +}; + +// +// constructors and destructor +// +L1GTTInputProducer::L1GTTInputProducer(const edm::ParameterSet& iConfig) + : l1TracksToken_(consumes(iConfig.getParameter("l1TracksInputTag"))), + outputCollectionName_(iConfig.getParameter("outputCollectionName")), + debug_(iConfig.getParameter("debug")) { + // Generate the required luts + generate_eta_lut(); + generate_pt_lut(); + + // Define EDM output to be written to file (if required) + produces(outputCollectionName_); + produces>("L1GTTInputTrackPtExpected"); + produces>("L1GTTInputTrackEtaExpected"); +} + +L1GTTInputProducer::~L1GTTInputProducer() {} + +// +// member functions +// + +/** + generate_lut: calculate the lut and write it to a file + - argument:None + - return (void): None + - method: + 1) iterates through all possibilities of the input value + 2) finds values of eta from input values + 3) stores the values of eta in an array (lut) + 4) writes out the array into a file (eta_lut.h) +*/ +void L1GTTInputProducer::generate_eta_lut() { + // initialize lut array + eta_lut_.reserve(kEtaLutSize); + + // iterate through all values in the lut + for (unsigned int i = 0; i < kEtaLutSize; i++) { + // -1 to ignore sign bit for input + unsigned int index = ((i + 0.5) * pow(2, (int)(kEtaInputSize - kEtaOutputSize))); + double newValue = indexTanLambda2Eta(index); // map out the index to the represented eta + out_eta_t out_eta = newValue; // cast it to fxp + eta_lut_[i] = out_eta; // add value for the lut + } + + if (debug_ >= 3) { + edm::LogInfo log("L1GTTInputProducer"); + log << "generate_eta_lut::The eta_lut_[" << kEtaLutSize << "] values are ... \n"; + for (unsigned int i = 0; i < kEtaLutSize; i++) { + log << "\t" << i << "\t" << eta_lut_[i] << "\n"; + } + } +} + +void L1GTTInputProducer::generate_pt_lut() { + // initialize lut array + pt_lut_.reserve(kPtLutSize); // generate lut + + // iterate through all values in the lut + for (unsigned int i = 0; i < kPtLutSize; i++) { + unsigned int index = (i + 0.5) * pow(2, (int)(kPTInputSize - 1 - kPTOutputSize)); + double newValue = inverseRT2InversePT(index); //map out the index to the represented 1/pT + out_pt_t out_pt = 1.0 / newValue; // take the reciprocal and cast as an AP fixed-point (1/pt ==> pt) + pt_lut_[i] = out_pt; // setting the i-th value for the lut + } + + if (debug_ >= 3) { + edm::LogInfo log("L1GTTInputProducer"); + log << "generate_pt_lut::The pt_lut_[" << kPtLutSize << "] values are ... \n"; + for (unsigned int i = 0; i < kPtLutSize; i++) { + log << "\t" << i << "\t" << pt_lut_[i] << "\n"; + } + } +} + +double L1GTTInputProducer::unpackSignedValue(unsigned int bits, unsigned int nBits, double lsb) const { + // Check that none of the bits above the nBits-1 bit, in a range of [0, nBits-1], are set. + // This makes sure that it isn't possible for the value represented by 'bits' to be + // any bigger than ((1 << nBits) - 1). + assert((bits >> nBits) == 0); + + // Convert from twos compliment to C++ signed integer (normal digitized value) + int digitizedValue = bits; + if (bits & (1 << (nBits - 1))) { // check if the 'bits' is negative + digitizedValue -= (1 << nBits); + } + + // Convert to floating point value + return (double(digitizedValue) + 0.5) * lsb; +} + +/** + indexTanLambda2Eta: calculates eta from tan(lambda) + - argument: + indexTanLambda (int): the index representation for tan(lambda) + - formula: + f(x) = -1*ln(tan((pi/2-atan(x))/2)), where x = tan(lambda) + - return (double): eta +*/ +double L1GTTInputProducer::indexTanLambda2Eta(unsigned int indexTanLambda) const { + double tanl = unpackSignedValue(indexTanLambda, kEtaInputSize, TTTrack_TrackWord::stepTanL); + double theta = (M_PI / 2.0) - atan(tanl); + double eta = -1.0 * log(tan(theta / 2.0)); + if (debug_ >= 3) { + edm::LogInfo("L1GTTInputProducer") << "indexTanLambda2Eta::tanl index = " << indexTanLambda << "\n" + << "indexTanLambda2Eta::tanl value = " << tanl << "\n" + << "indexTanLambda2Eta::theta = " << theta << "\n" + << "indexTanLambda2Eta::eta = " << eta; + } + return eta; +} + +/** + inverseRT2InversePT: calculates 1/pT from 1/rT + - argument: + indexRT (int): the index representation for 1/rT + - formula: + f(x) = 100.*(1/(0.3*3.8))*x , where x = 1/R + - return (double): 1/pT +*/ +double L1GTTInputProducer::inverseRT2InversePT(unsigned int indexRT) const { + double inverseRT = unpackSignedValue(indexRT, kPTInputSize, TTTrack_TrackWord::stepRinv); + return 100.0 * kSynchrotron * inverseRT; // multiply by 100 to convert from cm to m +} + +bool L1GTTInputProducer::getEtaBits( + const L1Track& track, out_eta_t& etaBits, double& expected, double& maxErrPerc, double& maxErrEpsilon) const { + // Conver the input to an ap_uint + in_eta_t value = track.getTanlWord(); + + // Get the expected outcome (floating point) + out_eta_t maxValuePossible = pow(2, 15); // saturate at max value possible for fxp + expected = indexTanLambda2Eta(value); // expected value for eta + if (expected > maxValuePossible) { + expected = maxValuePossible; + } + + // Converted value (emulation) + // Masking and shifting converts the efficient bit representation into an index + // Start by setting up the masks + in_eta_t indexTanLambda = value; + in_eta_t mask = ~0; // mask (all 1's) + bool sign = indexTanLambda.range(kEtaInputSize - 1, kEtaInputSize - 1); // sign bit of indexTanLambda + mask *= sign; // all 0's for positive numbers, all 1's for negative numbers + + // Take the absolute value of indexTanLambda (2's complement) + indexTanLambda ^= mask; + indexTanLambda += sign; + + // Find the value for eta, not |eta| + indexTanLambda = + indexTanLambda >> + (kEtaInputSize - + kEtaOutputSize); // Don't subtract 1 because we now want to take into account the sign bit of the output + indexTanLambda = + (indexTanLambda < (1 << (kEtaOutputSize - 1))) ? indexTanLambda : in_eta_t((1 << (kEtaOutputSize - 1)) - 1); + etaBits = eta_lut_[indexTanLambda]; + + // Reinacting the sign + out_eta_t maskOut; + maskOut.V = ~0; + maskOut *= sign; + etaBits ^= maskOut; + etaBits.V += sign; + + // Compare the floating point calculation to the emulation + double delta = std::abs(expected - etaBits.to_double()); + double perc_diff = (delta / std::abs(expected)) * 100.; // calc percentage error + if (delta > maxErrEpsilon) { + maxErrPerc = perc_diff; + maxErrEpsilon = delta; + } + + if (delta >= kEtaErrThresh) { + edm::LogError("L1GTTInputProducer") << "getEtaBits::MISMATCH!!!\n" + << "\tTTTrack tanL = " << track.tanL() << "\n" + << "\tTTTrack eta = " << track.momentum().eta() << "\n" + << "\tTTTrack_TrackWord = " << track.getTrackWord().to_string(2) << "\n" + << "\tTTTrack_TrackWord tanlWord = " << track.getTanlWord() << " (" + << track.getTanlWord().to_string(2) << ")\n" + << "\tin_eta_t value = " << value << " (" << value.to_string(2) << ")\n" + << "\tExpected value = " << expected << "\n" + << "\tCalculated eta = " << etaBits.to_double() << " (" << etaBits.to_string(2) + << ") @ index " << indexTanLambda << "\n" + << "\tDelta = " << delta << "\tpercentage error = " << perc_diff; + return true; + } else { + if (debug_ >= 2) { + edm::LogInfo("L1GTTInputProducer") + << "getEtaBits::SUCCESS (TTTrack, floating eta calculation, bitwise calculation, initial index, lut index) = " + << "(" << track.momentum().eta() << ", " << expected << ", " << etaBits << ", " << value << ", " + << indexTanLambda << ")"; + } + } + + return false; +} + +bool L1GTTInputProducer::getPtBits(const L1Track& track, + out_pt_t& ptBits, + out_charge_t& chargeBit, + double& expected, + double& maxErrPerc, + double& maxErrEpsilon, + double& minErrPerc, + double& minExpected) const { + // Convert the input to an ap_uint + in_pt_t value = track.getRinvWord(); + in_pt_t value_initial = value; + + // Get the expected outcome (floating point) + out_pt_t maxValuePossible = pow(2, 16); // saturate at max value possible for fxp + expected = 1.0 / inverseRT2InversePT(value); // expected value for inverse + bool saturation = true; + if (std::abs(expected) > maxValuePossible) { + expected = maxValuePossible; + } else { + saturation = false; + } + + // Converted value (emulation) + // Masking and shifting converts the efficient bit representation into an index + // Start by setting up the masks + in_pt_t mask = ~0; // mask (all 1's) + bool sign = value.range(kPTInputSize - 1, kPTInputSize - 1); // sign bit of value + mask *= sign; // all 0's for positive numbers, all 1's for negative numbers + + // Take the absolute value of value (2's complement) + value ^= mask; + value += sign; + + // Shift the value so that the index changes when the LSB of the output changes + value = value >> (kPTInputSize - 1 - (kPTOutputSize)); + + // Get the pt from the LUT + ptBits = pt_lut_[value]; + + // Set the charge bit + chargeBit = sign; + double charge = 1. - (2 * chargeBit.to_uint()); + + // Compare the floating point calculation to the emulation + double delta = std::abs(expected - (charge * ptBits.to_double())); + double perc_diff = (delta / std::abs(expected)) * 100.; + + if (delta > maxErrEpsilon) { + maxErrPerc = perc_diff; + maxErrEpsilon = delta; + } else if (delta < minExpected && !saturation && minErrPerc > 100.0) { + minErrPerc = perc_diff; + minExpected = expected; + } + + if (std::abs(perc_diff) >= kPTErrThresh && !saturation) { + edm::LogError("L1GTTInputProducer") << "getPtBits::MISMATCH!!!\n" + << "\tTTTrack Rinv = " << track.rInv() << "\n" + << "\tTTTrack pt = " << track.momentum().transverse() << "\n" + << "\tTTTrack_TrackWord = " << track.getTrackWord().to_string(2) << "\n" + << "\tTTTrack_TrackWord RinvWord = " << track.getRinvWord() << " (" + << track.getRinvWord().to_string(2) << ")\n" + << "\tin_pt_t value = " << value_initial << " (" << value_initial.to_string(2) + << ")\n" + << "\tExpected value = " << expected << "\n" + << "\tCalculated pt = " << ptBits.to_double() << " (" << ptBits.to_string(2) + << ") @ index " << value << "\n" + << "\tcharge = " << charge << " (bit = " << chargeBit << ")\n" + << "\tDelta = " << delta << "\tpercentage error = " << perc_diff; + return true; + } else { + if (debug_ >= 2) { + edm::LogInfo("L1GTTInputProducer") << "getPtBits::SUCCESS (TTTrack, floating pt calculation, charge, bitwise " + "calculation, initial index, lut index) = " + << "(" << sgn(track.rInv()) * track.momentum().transverse() << ", " << expected + << ", " << charge << ", " << ptBits << ", " << value_initial << ", " << value + << ")"; + } + } + + return false; +} + +// ------------ method called to produce the data ------------ +void L1GTTInputProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + auto vTTTrackOutput = std::make_unique(); + auto vPtOutput = std::make_unique>(); + auto vEtaOutput = std::make_unique>(); + + edm::Handle l1TracksHandle; + iEvent.getByToken(l1TracksToken_, l1TracksHandle); + + out_charge_t chargeBit = 0; + out_pt_t ptBits = 0; + out_eta_t etaBits = 0; + in_pt_t ptBitsShifted = 0; + in_eta_t etaBitsShifted = 0; + unsigned int error_pt_c = 0; // error counter + unsigned int error_eta_c = 0; // error counter + double expectedPt = 0.0; // expected value of the pt + double expectedEta = 0.0; // expected value of the eta + double maxErrPercPt = 0.0; // stores the maximum error percentage + double maxErrPercEta = 0.0; // stores the maximum error percentage + double maxErrEpsilonPt = 0.0; // keeps track of epsilon for max error + double maxErrEpsilonEta = 0.0; // keeps track of epsilon for max error + double minErrPercPt = 10000000.0; // stores the maximum error percentage + double minExpectedPt = 10000000.0; // keeps track of epsilon for max error + + unsigned int nOutput = l1TracksHandle->size(); + vTTTrackOutput->reserve(nOutput); + vPtOutput->reserve(nOutput); + vEtaOutput->reserve(nOutput); + for (const auto& track : *l1TracksHandle) { + if (!(track.nFitPars() == Npars4 || track.nFitPars() == Npars5)) { + throw cms::Exception("nFitPars unknown") + << "L1GTTInputProducer::produce method is called with numFitPars_ = " << track.nFitPars() + << ". The only possible values are 4/5."; + } + + // Fill the vector of tracks + vTTTrackOutput->push_back(track); + auto& currentTrackRef = vTTTrackOutput->back(); + if (debug_ >= 2) { + edm::LogInfo("L1GTTInputProducer") << "produce::word before anything " + << currentTrackRef.getTrackWord().to_string(2); + } + + // Do an initial setting of the bits based on the floating point values + currentTrackRef.setTrackWordBits(); + if (debug_ >= 2) { + edm::LogInfo("L1GTTInputProducer") << "produce::word after initial setting of the track word " + << currentTrackRef.getTrackWord().to_string(2); + } + + // Do the conversions + error_pt_c += getPtBits( + currentTrackRef, ptBits, chargeBit, expectedPt, maxErrPercPt, maxErrEpsilonPt, minErrPercPt, minExpectedPt); + error_eta_c += getEtaBits(currentTrackRef, etaBits, expectedEta, maxErrPercEta, maxErrEpsilonEta); + + // Assign the exat same bits to an ap_uint + ptBitsShifted = ptBits.range(); + etaBitsShifted = etaBits.range(); + + // Shift the bits so that the decimal is in the right spot for the GTT software + ptBitsShifted = ptBitsShifted << 2; + etaBitsShifted = etaBitsShifted << 8; + + // Set the MSB for the pt to the sign of the incoming word + ptBitsShifted.set(kPTInputSize - 1, chargeBit); + + // Set the correct bits based on the converted quanteties and the existing track word components + currentTrackRef.setTrackWord(currentTrackRef.getValidWord(), + ptBitsShifted, + currentTrackRef.getPhiWord(), + etaBitsShifted, + currentTrackRef.getZ0Word(), + currentTrackRef.getD0Word(), + currentTrackRef.getChi2RPhiWord(), + currentTrackRef.getChi2RZWord(), + currentTrackRef.getBendChi2Word(), + currentTrackRef.getHitPatternWord(), + currentTrackRef.getMVAQualityWord(), + currentTrackRef.getMVAOtherWord()); + if (debug_ >= 2) { + edm::LogInfo("L1GTTInputProducer") << "produce::charge after all conversions " << chargeBit << "\n" + << "produce::ptBits after all conversions " << ptBits.to_string(2) << " (" + << ptBitsShifted.to_string(2) << " = " << ptBitsShifted.to_uint() << ")\n" + << "produce::etaBits after all conversions " << etaBits.to_string(2) << " (" + << etaBitsShifted.to_string(2) << " = " << etaBitsShifted.to_uint() << ")\n" + << "produce::word after all conversions " + << vTTTrackOutput->back().getTrackWord().to_string(2); + } + + // Fill the remaining outputs + vPtOutput->push_back(expectedPt); + vEtaOutput->push_back(expectedEta); + } + + if (debug_ >= 1) { + edm::LogInfo("L1GTTInputProducer") << "\nNumber of converted tracks: " << nOutput << "\n\n" + << "q/r ==> pt conversion:\n" + << "\tError Threshold: " << kPTErrThresh << "%\n" + << "\tMax error: " << maxErrEpsilonPt + << " GeV difference with percentage: " << maxErrPercPt << "% @ " + << 100.0 * maxErrEpsilonPt / maxErrPercPt << " GeV" + << "\n" + << "\tError @ max range: " << minExpectedPt + << " GeV with precentage: " << minErrPercPt << "%" + << "\n" + << "\tTotal number of errors: " << error_pt_c << "\n\n" + << "tan(lambda) ==> eta conversion:\n" + << "\tError Threshold: " << kEtaErrThresh << "\n" + << "\tMax error: " << maxErrEpsilonEta << " with percentage: " << maxErrPercEta + << "% @ " << 100.0 * maxErrEpsilonEta / maxErrPercEta << "\n" + << "\tTotal number of errors: " << error_eta_c; + } + + if (error_pt_c + error_eta_c) { + edm::LogError("L1GTTInputProducer") << "produce::" << error_pt_c << "/" << error_eta_c + << " pt/eta mismatches detected!!!"; + } + + // Put the outputs into the event + iEvent.put(std::move(vTTTrackOutput), outputCollectionName_); + iEvent.put(std::move(vPtOutput), "L1GTTInputTrackPtExpected"); + iEvent.put(std::move(vEtaOutput), "L1GTTInputTrackEtaExpected"); +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1GTTInputProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // L1GTTInputProducer + edm::ParameterSetDescription desc; + desc.add("debug", 0)->setComment("Verbosity levels: 0, 1, 2, 3"); + desc.add("l1TracksInputTag", edm::InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks")); + desc.add("outputCollectionName", "Level1TTTracksConverted"); + descriptions.addWithDefaultLabel(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1GTTInputProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkElectronTrackProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkElectronTrackProducer.cc deleted file mode 100644 index 345238919a42c..0000000000000 --- a/L1Trigger/L1TTrackMatch/plugins/L1TkElectronTrackProducer.cc +++ /dev/null @@ -1,350 +0,0 @@ -// -*- C++ -*- -// -/**\class L1TkElectronTrackMatchAlgo - - Description: Producer of a TkElectron, for the algorithm matching a L1Track to the L1EG object - - Implementation: - [Notes on implementation] -*/ -// -// system include files -#include - -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/Framework/interface/EventSetup.h" - -#include "DataFormats/Common/interface/Handle.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "DataFormats/L1TCorrelator/interface/TkElectron.h" -#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" - -#include "DataFormats/Math/interface/LorentzVector.h" - -#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" -#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" - -// Matching Algorithm -#include "L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h" -#include "L1Trigger/L1TTrackMatch/interface/L1TkElectronEtComparator.h" -#include "L1Trigger/L1TTrackMatch/interface/pTFrom2Stubs.h" - -#include "DataFormats/Math/interface/deltaPhi.h" -#include "DataFormats/L1Trigger/interface/EGamma.h" - -#include - -static constexpr float EB_MaxEta = 0.9; - -using namespace l1t; - -// -// class declaration -// - -class L1TkElectronTrackProducer : public edm::stream::EDProducer<> { -public: - typedef TTTrack L1TTTrackType; - typedef std::vector L1TTTrackCollectionType; - - explicit L1TkElectronTrackProducer(const edm::ParameterSet&); - ~L1TkElectronTrackProducer() override; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - -private: - //void beginJob() override; - void produce(edm::Event&, const edm::EventSetup&) override; - //void endJob() override; - - float isolation(const edm::Handle& trkHandle, int match_index); - double getPtScaledCut(double pt, std::vector& parameters); - bool selectMatchedTrack(double& d_r, double& d_phi, double& d_eta, double& tk_pt, float& eg_eta); - - // ----------member data --------------------------- - std::string label; - - float etMin_; // min ET in GeV of L1EG objects - - float dRMin_; - float dRMax_; - float pTMinTra_; - float maxChi2IsoTracks_; - unsigned int minNStubsIsoTracks_; - - bool primaryVtxConstrain_; // use the primary vertex (default = false) - float deltaZ_; // | z_track - z_ref_track | < deltaZ_ in cm. - // Used only when primaryVtxConstrain_ = True. - float isoCut_; - bool relativeIsolation_; - - float trkQualityChi2_; - bool useTwoStubsPT_; - bool useClusterET_; // use cluster et to extrapolate tracks - float trkQualityPtMin_; - std::vector dPhiCutoff_; - std::vector dRCutoff_; - std::vector dEtaCutoff_; - std::string matchType_; - - const edm::EDGetTokenT egToken_; - const edm::EDGetTokenT > > trackToken_; - const edm::ESGetToken geomToken_; -}; - -// -// constructors and destructor -// -L1TkElectronTrackProducer::L1TkElectronTrackProducer(const edm::ParameterSet& iConfig) - : egToken_(consumes(iConfig.getParameter("L1EGammaInputTag"))), - trackToken_(consumes > >( - iConfig.getParameter("L1TrackInputTag"))), - geomToken_(esConsumes()) { - // label of the collection produced - // e.g. EG or IsoEG if all objects are kept - // EGIsoTrk or IsoEGIsoTrk if only the EG or IsoEG - // objects that pass a cut RelIso < isoCut_ are written - // in the new collection. - label = iConfig.getParameter("label"); - - etMin_ = (float)iConfig.getParameter("ETmin"); - - // parameters for the calculation of the isolation : - pTMinTra_ = (float)iConfig.getParameter("PTMINTRA"); - dRMin_ = (float)iConfig.getParameter("DRmin"); - dRMax_ = (float)iConfig.getParameter("DRmax"); - deltaZ_ = (float)iConfig.getParameter("DeltaZ"); - maxChi2IsoTracks_ = iConfig.getParameter("maxChi2IsoTracks"); - minNStubsIsoTracks_ = iConfig.getParameter("minNStubsIsoTracks"); - // cut applied on the isolation (if this number is <= 0, no cut is applied) - isoCut_ = (float)iConfig.getParameter("IsoCut"); - relativeIsolation_ = iConfig.getParameter("RelativeIsolation"); - - // parameters to select tracks to match with L1EG - trkQualityChi2_ = (float)iConfig.getParameter("TrackChi2"); - trkQualityPtMin_ = (float)iConfig.getParameter("TrackMinPt"); - useTwoStubsPT_ = iConfig.getParameter("useTwoStubsPT"); - useClusterET_ = iConfig.getParameter("useClusterET"); - dPhiCutoff_ = iConfig.getParameter >("TrackEGammaDeltaPhi"); - dRCutoff_ = iConfig.getParameter >("TrackEGammaDeltaR"); - dEtaCutoff_ = iConfig.getParameter >("TrackEGammaDeltaEta"); - matchType_ = iConfig.getParameter("TrackEGammaMatchType"); - - produces(label); -} - -L1TkElectronTrackProducer::~L1TkElectronTrackProducer() {} - -// ------------ method called to produce the data ------------ -void L1TkElectronTrackProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - std::unique_ptr result(new TkElectronCollection); - - // geometry needed to call pTFrom2Stubs - edm::ESHandle geomHandle = iSetup.getHandle(geomToken_); - const TrackerGeometry* tGeom = geomHandle.product(); - - // the L1EGamma objects - edm::Handle eGammaHandle; - iEvent.getByToken(egToken_, eGammaHandle); - EGammaBxCollection eGammaCollection = (*eGammaHandle.product()); - EGammaBxCollection::const_iterator egIter; - - // the L1Tracks - edm::Handle L1TTTrackHandle; - iEvent.getByToken(trackToken_, L1TTTrackHandle); - L1TTTrackCollectionType::const_iterator trackIter; - - if (!eGammaHandle.isValid()) { - throw cms::Exception("L1TkElectronTrackProducer") - << "\nWarning: L1EmCollection not found in the event. Exit" << std::endl; - return; - } - if (!L1TTTrackHandle.isValid()) { - throw cms::Exception("TkEmProducer") << "\nWarning: L1TTTrackCollectionType not found in the event. Exit." - << std::endl; - return; - } - - int ieg = 0; - for (egIter = eGammaCollection.begin(0); egIter != eGammaCollection.end(0); ++egIter) { // considering BX = only - edm::Ref EGammaRef(eGammaHandle, ieg); - ieg++; - - float e_ele = egIter->energy(); - float eta_ele = egIter->eta(); - float et_ele = 0; - float cosh_eta_ele = cosh(eta_ele); - if (cosh_eta_ele > 0.0) - et_ele = e_ele / cosh_eta_ele; - else - et_ele = -1.0; - if (etMin_ > 0.0 && et_ele <= etMin_) - continue; - // match the L1EG object with a L1Track - float drmin = 999; - int itr = 0; - int itrack = -1; - for (trackIter = L1TTTrackHandle->begin(); trackIter != L1TTTrackHandle->end(); ++trackIter) { - edm::Ptr L1TrackPtr(L1TTTrackHandle, itr); - double trkPt_fit = trackIter->momentum().perp(); - double trkPt_stubs = pTFrom2Stubs::pTFrom2(trackIter, tGeom); - double trkPt = trkPt_fit; - if (useTwoStubsPT_) - trkPt = trkPt_stubs; - - if (trkPt > trkQualityPtMin_ && trackIter->chi2() < trkQualityChi2_) { - double dPhi = 99.; - double dR = 99.; - double dEta = 99.; - if (useClusterET_) - L1TkElectronTrackMatchAlgo::doMatchClusterET(egIter, L1TrackPtr, dPhi, dR, dEta); - else - L1TkElectronTrackMatchAlgo::doMatch(egIter, L1TrackPtr, dPhi, dR, dEta); - if (dR < drmin && selectMatchedTrack(dR, dPhi, dEta, trkPt, eta_ele)) { - drmin = dR; - itrack = itr; - } - } - itr++; - } - if (itrack >= 0) { - edm::Ptr matchedL1TrackPtr(L1TTTrackHandle, itrack); - - const math::XYZTLorentzVector P4 = egIter->p4(); - float trkisol = isolation(L1TTTrackHandle, itrack); - if (relativeIsolation_ && et_ele > 0.0) { // relative isolation - trkisol = trkisol / et_ele; - } - - TkElectron trkEm(P4, EGammaRef, matchedL1TrackPtr, trkisol); - - trkEm.setTrackCurvature(matchedL1TrackPtr->rInv()); // should this have npars? 4? 5? - - //std::cout<rInv()<<" "<rInv(4)<<" "<rInv()<push_back(trkEm); - } else { - // the object is written to the collection only - // if it passes the isolation cut - if (trkisol <= isoCut_) - result->push_back(trkEm); - } - } - - } // end loop over EGamma objects - - iEvent.put(std::move(result), label); -} - -// ------------ method called once each job just before starting event loop ------------ -//void L1TkElectronTrackProducer::beginJob() {} - -// ------------ method called once each job just after ending the event loop ------------ -//void L1TkElectronTrackProducer::endJob() {} - -// ------------ method called when starting to processes a run ------------ -/* -void -L1TkElectronTrackProducer::beginRun(edm::Run& iRun, edm::EventSetup const& iSetup) -{ -} -*/ - -// ------------ method called when ending the processing of a run ------------ -/* -void -L1TkElectronTrackProducer::endRun(edm::Run&, edm::EventSetup const&) -{ -} -*/ - -// ------------ method called when starting to processes a luminosity block ------------ -/* -void -L1TkElectronTrackProducer::beginLuminosityBlock(edm::LuminosityBlock&, edm::EventSetup const&) -{ -} -*/ - -// ------------ method called when ending the processing of a luminosity block ------------ -/* -void -L1TkElectronTrackProducer::endLuminosityBlock(edm::LuminosityBlock&, edm::EventSetup const&) -{ -} -*/ - -// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ -void L1TkElectronTrackProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - //The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters - edm::ParameterSetDescription desc; - desc.setUnknown(); - descriptions.addDefault(desc); -} -// method to calculate isolation -float L1TkElectronTrackProducer::isolation(const edm::Handle& trkHandle, int match_index) { - edm::Ptr matchedTrkPtr(trkHandle, match_index); - L1TTTrackCollectionType::const_iterator trackIter; - - float sumPt = 0.0; - int itr = 0; - - float dRMin2 = dRMin_ * dRMin_; - float dRMax2 = dRMax_ * dRMax_; - - for (trackIter = trkHandle->begin(); trackIter != trkHandle->end(); ++trackIter) { - if (itr++ != match_index) { - if (trackIter->chi2() > maxChi2IsoTracks_ || trackIter->momentum().perp() <= pTMinTra_ || - trackIter->getStubRefs().size() < minNStubsIsoTracks_) { - continue; - } - - float dZ = std::abs(trackIter->POCA().z() - matchedTrkPtr->POCA().z()); - - float phi1 = trackIter->momentum().phi(); - float phi2 = matchedTrkPtr->momentum().phi(); - float dPhi = reco::deltaPhi(phi1, phi2); - float dEta = (trackIter->momentum().eta() - matchedTrkPtr->momentum().eta()); - float dR2 = (dPhi * dPhi + dEta * dEta); - - if (dR2 > dRMin2 && dR2 < dRMax2 && dZ < deltaZ_ && trackIter->momentum().perp() > pTMinTra_) { - sumPt += trackIter->momentum().perp(); - } - } - } - - return sumPt; -} -double L1TkElectronTrackProducer::getPtScaledCut(double pt, std::vector& parameters) { - return (parameters[0] + parameters[1] * exp(parameters[2] * pt)); -} -bool L1TkElectronTrackProducer::selectMatchedTrack( - double& d_r, double& d_phi, double& d_eta, double& tk_pt, float& eg_eta) { - if (matchType_ == "PtDependentCut") { - if (std::abs(d_phi) < getPtScaledCut(tk_pt, dPhiCutoff_) && d_r < getPtScaledCut(tk_pt, dRCutoff_)) - return true; - } else { - double deta_max = dEtaCutoff_[0]; - if (std::abs(eg_eta) < EB_MaxEta) - deta_max = dEtaCutoff_[1]; - double dphi_max = dPhiCutoff_[0]; - if ((d_eta / deta_max) * (d_eta / deta_max) + (d_phi / dphi_max) * (d_phi / dphi_max) < 1) - return true; - } - return false; -} -//define this as a plug-in -DEFINE_FWK_MODULE(L1TkElectronTrackProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkEmParticleProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkEmParticleProducer.cc deleted file mode 100644 index e4ab08db8e3be..0000000000000 --- a/L1Trigger/L1TTrackMatch/plugins/L1TkEmParticleProducer.cc +++ /dev/null @@ -1,293 +0,0 @@ -// -*- C++ -*- -// -// -// dummy producer for a TkEm -// - -// system include files -#include - -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/global/EDProducer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/InputTag.h" - -#include "DataFormats/Common/interface/Handle.h" - -#include "DataFormats/L1TCorrelator/interface/TkEm.h" -#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" - -#include "DataFormats/Math/interface/LorentzVector.h" -#include "DataFormats/Math/interface/deltaR.h" - -// for L1Tracks: -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" - -#include -#include - -static constexpr float EtaECal = 1.479; -static constexpr float REcal = 129.; -static constexpr float ZEcal = 315.4; -using namespace l1t; -// -// class declaration -// - -class L1TkEmParticleProducer : public edm::global::EDProducer<> { -public: - typedef TTTrack L1TTTrackType; - typedef std::vector L1TTTrackCollectionType; - - explicit L1TkEmParticleProducer(const edm::ParameterSet&); - ~L1TkEmParticleProducer() override; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - - float CorrectedEta(float eta, float zv) const; - -private: - void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; - - // ----------member data --------------------------- - - const edm::EDGetTokenT egToken_; - const edm::EDGetTokenT trackToken_; - const edm::EDGetTokenT vertexToken_; - - const std::string label_; - - const float etMin_; // min ET in GeV of L1EG objects - const float zMax_; // |z_track| < zMax_ in cm - const float chi2Max_; - const float pTMinTra_; - const float dR2Min_; - const float dR2Max_; - const bool primaryVtxConstrain_; // use the primary vertex (default = false) - const float deltaZMax_; // | z_track - z_primaryvtx | < deltaZMax_ in cm. - // Used only when primaryVtxConstrain_ = True. - const float isoCut_; - const bool relativeIsolation_; -}; - -// -// constructors and destructor -// -L1TkEmParticleProducer::L1TkEmParticleProducer(const edm::ParameterSet& iConfig) - : egToken_(consumes(iConfig.getParameter("L1EGammaInputTag"))), - trackToken_(consumes(iConfig.getParameter("L1TrackInputTag"))), - vertexToken_(consumes(iConfig.getParameter("L1VertexInputTag"))), - label_(iConfig.getParameter("label")), - etMin_((float)iConfig.getParameter("ETmin")), - zMax_((float)iConfig.getParameter("ZMAX")), - chi2Max_((float)iConfig.getParameter("CHI2MAX")), - pTMinTra_((float)iConfig.getParameter("PTMINTRA")), - dR2Min_((float)iConfig.getParameter("DRmin") * (float)iConfig.getParameter("DRmin")), - dR2Max_((float)iConfig.getParameter("DRmax") * (float)iConfig.getParameter("DRmax")), - primaryVtxConstrain_(iConfig.getParameter("PrimaryVtxConstrain")), - deltaZMax_((float)iConfig.getParameter("DeltaZMax")), - isoCut_((float)iConfig.getParameter("IsoCut")), - relativeIsolation_(iConfig.getParameter("RelativeIsolation")) { - produces(label_); -} - -L1TkEmParticleProducer::~L1TkEmParticleProducer() {} - -// ------------ method called to produce the data ------------ -void L1TkEmParticleProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { - using namespace edm; - - auto result = std::make_unique(); - - // the L1Tracks - edm::Handle L1TTTrackHandle; - iEvent.getByToken(trackToken_, L1TTTrackHandle); - if (!L1TTTrackHandle.isValid()) { - LogError("L1TkEmParticleProducer") << "\nWarning: L1TTTrackCollectionType not found in the event. Exit." - << std::endl; - return; - } - - // the primary vertex (used only if primaryVtxConstrain_ = true) - float zvtxL1tk = -999; - bool primaryVtxConstrain = primaryVtxConstrain_; - edm::Handle L1VertexHandle; - iEvent.getByToken(vertexToken_, L1VertexHandle); - if (!L1VertexHandle.isValid()) { - LogWarning("L1TkEmParticleProducer") - << "Warning: TkPrimaryVertexCollection not found in the event. Won't use any PrimaryVertex constraint." - << std::endl; - primaryVtxConstrain = false; - } else { - std::vector::const_iterator vtxIter = L1VertexHandle->begin(); - // by convention, the first vertex in the collection is the one that should - // be used by default - zvtxL1tk = vtxIter->zvertex(); - } - - // Now loop over the L1EGamma objects - - edm::Handle eGammaHandle; - iEvent.getByToken(egToken_, eGammaHandle); - if (!eGammaHandle.isValid()) { - LogError("L1TkEmParticleProducer") << "\nWarning: L1EmCollection not found in the event. Exit." << std::endl; - return; - } - EGammaBxCollection eGammaCollection = (*eGammaHandle.product()); - EGammaBxCollection::const_iterator egIter; - - int ieg = 0; - for (egIter = eGammaCollection.begin(0); egIter != eGammaCollection.end(0); ++egIter) // considering BX = only - { - edm::Ref EGammaRef(eGammaHandle, ieg); - ieg++; - - float et = egIter->et(); - if (et < etMin_) - continue; - - float eta = egIter->eta(); - // The eta of the L1EG object is seen from (0,0,0). - // if primaryVtxConstrain_ = true, and for the PV constrained iso, use the zvtxL1tk to correct the eta(L1EG) - // that is used in the calculation of DeltaR. - float etaPV = CorrectedEta(eta, zvtxL1tk); - - float phi = egIter->phi(); - - // calculate the isolation of the L1EG object with - // respect to L1Tracks. - - float sumPt = 0; - float sumPtPV = 0; - - for (const auto& track : *L1TTTrackHandle) { - float Pt = track.momentum().perp(); - float Eta = track.momentum().eta(); - float Phi = track.momentum().phi(); - float z = track.POCA().z(); - if (fabs(z) > zMax_) - continue; - if (Pt < pTMinTra_) - continue; - float chi2 = track.chi2(); - if (chi2 > chi2Max_) - continue; - - float dr2 = reco::deltaR2(Eta, Phi, eta, phi); - if (dr2 < dR2Max_ && dr2 >= dR2Min_) { - sumPt += Pt; - } - - if (zvtxL1tk > -999 && std::abs(z - zvtxL1tk) >= deltaZMax_) - continue; // Now, PV constrained trackSum: - - dr2 = reco::deltaR2(Eta, Phi, etaPV, phi); // recompute using the corrected eta - if (dr2 < dR2Max_ && dr2 >= dR2Min_) { - sumPtPV += Pt; - } - } // end loop over tracks - - float trkisol = -999; - float trkisolPV = -999; - if (relativeIsolation_) { - if (et > 0) { - trkisol = sumPt / et; - trkisolPV = sumPtPV / et; - } // relative isolation - } else { // absolute isolation - trkisol = sumPt; - trkisolPV = sumPtPV; - } - - float isolation = primaryVtxConstrain ? trkisolPV : trkisol; - - const math::XYZTLorentzVector P4 = egIter->p4(); - TkEm trkEm(P4, EGammaRef, trkisol, trkisolPV); - - if (isoCut_ <= 0) { - // write the L1TkEm particle to the collection, - // irrespective of its relative isolation - result->push_back(trkEm); - } else { - // the object is written to the collection only - // if it passes the isolation cut - if (isolation <= isoCut_) - result->push_back(trkEm); - } - - } // end loop over EGamma objects - - iEvent.put(std::move(result), label_); -} - -// -------------------------------------------------------------------------------------- - -float L1TkEmParticleProducer::CorrectedEta(float eta, float zv) const { - // Correct the eta of the L1EG object once we know the zvertex - - if (zv == 0.) - return eta; - - if (eta == 0) { - float thetaprime = atan(-REcal / zv); - if (thetaprime < 0) - thetaprime = thetaprime + M_PI; - float etaprime = -log(tan(0.5 * thetaprime)); - return etaprime; - } - - bool IsBarrel = (std::abs(eta) < EtaECal); - - float tanhalftheta = exp(-eta); - float tantheta = 2. * tanhalftheta / (1. - tanhalftheta * tanhalftheta); - - float delta; - if (IsBarrel) - delta = REcal / tantheta; - else - delta = eta > 0 ? ZEcal : -ZEcal; - - float etaprime; - if (delta == zv) { - etaprime = 0.; - } else { - float tanthetaprime = delta * tantheta / (delta - zv); - float thetaprime = atan(tanthetaprime); - if (thetaprime < 0) - thetaprime = thetaprime + M_PI; - etaprime = -log(tan(0.5 * thetaprime)); - } - - return etaprime; -} - -// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ -void L1TkEmParticleProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - //The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters - edm::ParameterSetDescription desc; - desc.add("label", "EG"); - desc.add("L1EGammaInputTag", edm::InputTag("simCaloStage2Digis")); - desc.add("L1TrackInputTag", edm::InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks")); - desc.add("L1VertexInputTag", edm::InputTag("L1TkPrimaryVertex")); - desc.add("ETmin", -1.); - desc.add("RelativeIsolation", true); - desc.add("IsoCut", 0.23); - desc.add("ZMAX", 25.); - desc.add("CHI2MAX", 100.); - desc.add("PTMINTRA", 2.); - desc.add("DRmin", 0.07); - desc.add("DRmax", 0.30); - desc.add("PrimaryVtxConstrain", false); - desc.add("DeltaZMax", 0.6); - descriptions.add("l1TkEmParticleProducer", desc); -} - -//define this as a plug-in -DEFINE_FWK_MODULE(L1TkEmParticleProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkFastVertexProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkFastVertexProducer.cc deleted file mode 100644 index 2e0615b6cd6f4..0000000000000 --- a/L1Trigger/L1TTrackMatch/plugins/L1TkFastVertexProducer.cc +++ /dev/null @@ -1,357 +0,0 @@ -// -*- C++ -*- -// -// -// Original Author: Emmanuelle Perez,40 1-A28,+41227671915, -// Created: Tue Nov 12 17:03:19 CET 2013 -// $Id$ -// -// -// system include files -#include -#include - -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/global/EDProducer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Utilities/interface/ESGetToken.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" - -//////////////////////////// -// DETECTOR GEOMETRY HEADERS -#include "MagneticField/Engine/interface/MagneticField.h" - -#include "Geometry/Records/interface/TrackerTopologyRcd.h" -#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" - -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" - -//////////////////////////// -// HepMC products -#include "DataFormats/HepMCCandidate/interface/GenParticle.h" -#include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h" -#include "DataFormats/Candidate/interface/Candidate.h" - -#include "TH1F.h" - -using namespace l1t; - -// -// class declaration -// - -class L1TkFastVertexProducer : public edm::global::EDProducer<> { -public: - typedef TTTrack L1TTTrackType; - typedef std::vector L1TTTrackCollectionType; - - explicit L1TkFastVertexProducer(const edm::ParameterSet&); - ~L1TkFastVertexProducer() override; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - -private: - void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; - - // ----------member data --------------------------- - - float zMax_; // in cm - float DeltaZ; // in cm - float chi2Max_; - float pTMinTra_; // in GeV - - float pTMax_; // in GeV, saturation / truncation value - int highPtTracks_; // saturate or truncate - - int nVtx_; // the number of vertices to return - int nStubsmin_; // minimum number of stubs - int nStubsPSmin_; // minimum number of stubs in PS modules - - int nBinning_; // number of bins used in the temp histogram - - bool monteCarloVertex_; // - //const StackedTrackerGeometry* theStackedGeometry; - - bool doPtComp_; - bool doTightChi2_; - float trkPtTightChi2_; - float trkChi2dofTightChi2_; - - int weight_; // weight (power) of pT 0 , 1, 2 - - constexpr static float xmin_ = -30; - constexpr static float xmax_ = +30; - - const edm::EDGetTokenT hepmcToken_; - const edm::EDGetTokenT > genparticleToken_; - const edm::EDGetTokenT > > trackToken_; - const edm::ESGetToken topoToken_; -}; - -// -// constants, enums and typedefs -// - -// -// static data member definitions -// - -// -// constructors and destructor -// -L1TkFastVertexProducer::L1TkFastVertexProducer(const edm::ParameterSet& iConfig) - : hepmcToken_(consumes(iConfig.getParameter("HepMCInputTag"))), - genparticleToken_( - consumes >(iConfig.getParameter("GenParticleInputTag"))), - trackToken_(consumes > >( - iConfig.getParameter("L1TrackInputTag"))), - topoToken_(esConsumes(edm::ESInputTag("", ""))) { - zMax_ = (float)iConfig.getParameter("ZMAX"); - chi2Max_ = (float)iConfig.getParameter("CHI2MAX"); - pTMinTra_ = (float)iConfig.getParameter("PTMINTRA"); - - pTMax_ = (float)iConfig.getParameter("PTMAX"); - highPtTracks_ = iConfig.getParameter("HighPtTracks"); - - nVtx_ = iConfig.getParameter("nVtx"); - nStubsmin_ = iConfig.getParameter("nStubsmin"); - nStubsPSmin_ = iConfig.getParameter("nStubsPSmin"); - nBinning_ = iConfig.getParameter("nBinning"); - - monteCarloVertex_ = iConfig.getParameter("MonteCarloVertex"); - doPtComp_ = iConfig.getParameter("doPtComp"); - doTightChi2_ = iConfig.getParameter("doTightChi2"); - trkPtTightChi2_ = (float)iConfig.getParameter("trk_ptTightChi2"); - trkChi2dofTightChi2_ = (float)iConfig.getParameter("trk_chi2dofTightChi2"); - - weight_ = iConfig.getParameter("WEIGHT"); - - produces(); -} - -L1TkFastVertexProducer::~L1TkFastVertexProducer() { - // do anything here that needs to be done at desctruction time - // (e.g. close files, deallocate resources etc.) -} - -// -// member functions -// - -// ------------ method called to produce the data ------------ -void L1TkFastVertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { - using namespace edm; - - auto result = std::make_unique(); - - // Tracker Topology - const TrackerTopology& tTopo = iSetup.getData(topoToken_); - - TH1F htmp("htmp", ";z (cm); Tracks", nBinning_, xmin_, xmax_); - TH1F htmp_weight("htmp_weight", ";z (cm); Tracks", nBinning_, xmin_, xmax_); - - // ---------------------------------------------------------------------- - - if (monteCarloVertex_) { - // MC info ... retrieve the zvertex - edm::Handle HepMCEvt; - iEvent.getByToken(hepmcToken_, HepMCEvt); - - edm::Handle > GenParticleHandle; - iEvent.getByToken(genparticleToken_, GenParticleHandle); - - const double mm = 0.1; - float zvtx_gen = -999; - - if (HepMCEvt.isValid()) { - // using HepMCEvt - - const HepMC::GenEvent* MCEvt = HepMCEvt->GetEvent(); - for (HepMC::GenEvent::vertex_const_iterator ivertex = MCEvt->vertices_begin(); ivertex != MCEvt->vertices_end(); - ++ivertex) { - bool hasParentVertex = false; - - // Loop over the parents looking to see if they are coming from a production vertex - for (HepMC::GenVertex::particle_iterator iparent = (*ivertex)->particles_begin(HepMC::parents); - iparent != (*ivertex)->particles_end(HepMC::parents); - ++iparent) - if ((*iparent)->production_vertex()) { - hasParentVertex = true; - break; - } - - // Reject those vertices with parent vertices - if (hasParentVertex) - continue; - // Get the position of the vertex - HepMC::FourVector pos = (*ivertex)->position(); - zvtx_gen = pos.z() * mm; - break; // there should be one single primary vertex - } // end loop over gen vertices - - } else if (GenParticleHandle.isValid()) { - for (const auto& genpart : *GenParticleHandle) { - int status = genpart.status(); - if (status != 3) - continue; - if (genpart.numberOfMothers() == 0) - continue; // the incoming hadrons - float part_zvertex = genpart.vz(); - zvtx_gen = part_zvertex; - break; // - } - } else { - throw cms::Exception("L1TkFastVertexProducer") - << "\nerror: try to retrieve the MC vertex (monteCarloVertex_ = True) " - << "\nbut the input file contains neither edm::HepMCProduct> nor vector. Exit" - << std::endl; - } - - TkPrimaryVertex genvtx(zvtx_gen, -999.); - - result->push_back(genvtx); - iEvent.put(std::move(result)); - return; - } - - edm::Handle L1TTTrackHandle; - iEvent.getByToken(trackToken_, L1TTTrackHandle); - - if (!L1TTTrackHandle.isValid()) { - throw cms::Exception("L1TkFastVertexProducer") - << "\nWarning: L1TkTrackCollection with not found in the event. Exit" << std::endl; - return; - } - - for (const auto& track : *L1TTTrackHandle) { - float z = track.POCA().z(); - float chi2 = track.chi2(); - float pt = track.momentum().perp(); - float eta = track.momentum().eta(); - - //.............................................................. - float wt = pow(pt, weight_); // calculating the weight for tks in as pt^0,pt^1 or pt^2 based on weight_ - - if (std::abs(z) > zMax_) - continue; - if (chi2 > chi2Max_) - continue; - if (pt < pTMinTra_) - continue; - - // saturation or truncation : - if (pTMax_ > 0 && pt > pTMax_) { - if (highPtTracks_ == 0) - continue; // ignore this track - if (highPtTracks_ == 1) - pt = pTMax_; // saturate - } - - // get the number of stubs and the number of stubs in PS layers - float nPS = 0.; // number of stubs in PS modules - float nstubs = 0; - - // get pointers to stubs associated to the L1 track - const std::vector >, TTStub > >& - theStubs = track.getStubRefs(); - - int tmp_trk_nstub = (int)theStubs.size(); - if (tmp_trk_nstub < 0) { - LogTrace("L1TkFastVertexProducer") - << " ... could not retrieve the vector of stubs in L1TkFastVertexProducer::SumPtVertex " << std::endl; - continue; - } - - // loop over the stubs - for (const auto& stub : theStubs) { - nstubs++; - bool isPS = false; - DetId detId(stub->getDetId()); - if (detId.det() == DetId::Detector::Tracker) { - if (detId.subdetId() == StripSubdetector::TOB && tTopo.tobLayer(detId) <= 3) - isPS = true; - else if (detId.subdetId() == StripSubdetector::TID && tTopo.tidRing(detId) <= 9) - isPS = true; - } - if (isPS) - nPS++; - } // end loop over stubs - if (nstubs < nStubsmin_) - continue; - if (nPS < nStubsPSmin_) - continue; - - // quality cuts from Louise S, based on the pt-stub compatibility (June 20, 2014) - int trk_nstub = (int)track.getStubRefs().size(); - float chi2dof = chi2 / (2 * trk_nstub - 4); - - if (doPtComp_) { - float trk_consistency = track.stubPtConsistency(); - if (trk_nstub == 4) { - if (std::abs(eta) < 2.2 && trk_consistency > 10) - continue; - else if (std::abs(eta) > 2.2 && chi2dof > 5.0) - continue; - } - } - if (doTightChi2_) { - if (pt > trkPtTightChi2_ && chi2dof > trkChi2dofTightChi2_) - continue; - } - - htmp.Fill(z); - htmp_weight.Fill(z, wt); // changed from "pt" to "wt" which is some power of pt (0,1 or 2) - - } // end loop over tracks - - // sliding windows... maximize bin i + i-1 + i+1 - - float zvtx_sliding; - float sigma_max; - int imax; - int nb = htmp.GetNbinsX(); - std::vector found; - found.reserve(nVtx_); - for (int ivtx = 0; ivtx < nVtx_; ivtx++) { - zvtx_sliding = -999; - sigma_max = -999; - imax = -999; - for (int i = 2; i <= nb - 1; i++) { - float a0 = htmp_weight.GetBinContent(i - 1); - float a1 = htmp_weight.GetBinContent(i); - float a2 = htmp_weight.GetBinContent(i + 1); - float sigma = a0 + a1 + a2; - if ((sigma > sigma_max) && (find(found.begin(), found.end(), i) == found.end())) { - sigma_max = sigma; - imax = i; - float z0 = htmp_weight.GetBinCenter(i - 1); - float z1 = htmp_weight.GetBinCenter(i); - float z2 = htmp_weight.GetBinCenter(i + 1); - zvtx_sliding = (a0 * z0 + a1 * z1 + a2 * z2) / sigma; - } - } - found.push_back(imax); - TkPrimaryVertex vtx4(zvtx_sliding, sigma_max); - result->push_back(vtx4); - } - - iEvent.put(std::move(result)); -} - -// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ -void L1TkFastVertexProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - //The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters - edm::ParameterSetDescription desc; - desc.setUnknown(); - descriptions.addDefault(desc); -} - -//define this as a plug-in -DEFINE_FWK_MODULE(L1TkFastVertexProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkHTMissEmulatorProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkHTMissEmulatorProducer.cc new file mode 100644 index 0000000000000..5851938d3de04 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TkHTMissEmulatorProducer.cc @@ -0,0 +1,269 @@ + +/**\class L1TrackerHTMissEmulatorProducer L1TrackerHTMissEmulatorProducer.cc + L1Trigger/L1TTrackMatch/plugins/L1TrackerHTMissEmulatorProducer.cc + Description: Takes L1TTkJets and performs a integer emulation of Track-based missing HT, outputting a collection of EtSum +*/ + +// Original Author: Hardik Routray +// Created: Mon, 11 Oct 2021 + +// system include files +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/Math/interface/LorentzVector.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkHTMissFwd.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/L1Trigger/interface/TkJetWord.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkHTMissEmulatorProducer.h" + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +using namespace l1t; + +class L1TkHTMissEmulatorProducer : public edm::stream::EDProducer<> { +public: + explicit L1TkHTMissEmulatorProducer(const edm::ParameterSet&); + ~L1TkHTMissEmulatorProducer() override = default; + +private: + virtual void beginJob(); + void produce(edm::Event&, const edm::EventSetup&) override; + virtual void endJob(); + + // ----------member data --------------------------- + + bool debug_ = false; + bool displaced_; + + int cosLUTbins; + int aSteps = 8; + + l1tmhtemu::pt_t jetMinPt_; + l1tmhtemu::eta_t jetMaxEta_; + l1tmhtemu::ntracks_t minNtracksHighPt_; + l1tmhtemu::ntracks_t minNtracksLowPt_; + + std::vector cosLUT_; + std::vector atanLUT_; + std::vector magNormalisationLUT_; + + std::string L1MHTCollectionName_; + + const edm::EDGetTokenT jetToken_; +}; + +L1TkHTMissEmulatorProducer::L1TkHTMissEmulatorProducer(const edm::ParameterSet& iConfig) + : jetToken_(consumes(iConfig.getParameter("L1TkJetEmulationInputTag"))) { + debug_ = iConfig.getParameter("debug"); + displaced_ = iConfig.getParameter("displaced"); + + jetMinPt_ = l1tmhtemu::digitizeSignedValue( + (float)iConfig.getParameter("jet_minPt"), l1tmhtemu::kInternalPtWidth, l1tmhtemu::kStepPt); + jetMaxEta_ = l1tmhtemu::digitizeSignedValue( + (float)iConfig.getParameter("jet_maxEta"), l1tmhtemu::kInternalEtaWidth, l1tmhtemu::kStepEta); + minNtracksHighPt_ = (l1tmhtemu::ntracks_t)iConfig.getParameter("jet_minNtracksHighPt"); + minNtracksLowPt_ = (l1tmhtemu::ntracks_t)iConfig.getParameter("jet_minNtracksLowPt"); + + cosLUTbins = floor(l1tmhtemu::kMaxCosLUTPhi / l1tmhtemu::kStepPhi); + cosLUT_ = l1tmhtemu::generateCosLUT(cosLUTbins); + + atanLUT_ = l1tmhtemu::generateaTanLUT(aSteps); + magNormalisationLUT_ = l1tmhtemu::generatemagNormalisationLUT(aSteps); + + // Name of output ED Product + L1MHTCollectionName_ = (std::string)iConfig.getParameter("L1MHTCollectionName"); + + produces>(L1MHTCollectionName_); + + if (debug_) { + edm::LogVerbatim("L1TrackerHTMissEmulatorProducer") + << "-------------------------------------------------------------------------\n" + << "====BITWIDTHS====\n" + << "pt: " << l1t::TkJetWord::TkJetBitWidths::kPtSize << " eta: " << l1t::TkJetWord::TkJetBitWidths::kGlbEtaSize + << " phi:" << l1t::TkJetWord::TkJetBitWidths::kGlbPhiSize << "\n" + << "====CUT AP_INTS====\n" + << "minpt: " << jetMinPt_ << " maxeta: " << jetMaxEta_ << " minNtracksHighPt: " << minNtracksHighPt_ + << " minNtracksLowPt: " << minNtracksLowPt_ << "\n" + << "====CUT AP_INTS TO FLOATS====\n" + << "minpt: " << (float)jetMinPt_ * l1tmhtemu::kStepPt << " maxeta: " << (float)jetMaxEta_ * l1tmhtemu::kStepEta + << " minNtracksHighPt: " << (int)minNtracksHighPt_ << " minNtracksLowPt: " << (int)minNtracksLowPt_ << "\n" + << "-------------------------------------------------------------------------\n"; + } +} + +void L1TkHTMissEmulatorProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + std::unique_ptr> MHTCollection(new std::vector(0)); + + // L1 track-trigger jets + edm::Handle L1TkJetsHandle; + iEvent.getByToken(jetToken_, L1TkJetsHandle); + std::vector::const_iterator jetIter; + + if (!L1TkJetsHandle.isValid() && !displaced_) { + LogError("TkHTMissEmulatorProducer") << "\nWarning: TkJetCollection not found in the event. Exit\n"; + return; + } + + if (!L1TkJetsHandle.isValid() && displaced_) { + LogError("TkHTMissEmulatorProducer") << "\nWarning: TkJetExtendedCollection not found in the event. Exit\n"; + return; + } + + // floats used for debugging + float sumPx_ = 0; + float sumPy_ = 0; + float HT_ = 0; + + l1tmhtemu::Et_t sumPx = 0; + l1tmhtemu::Et_t sumPy = 0; + l1tmhtemu::Et_t HT = 0; + + // loop over jets + int jetn = 0; + int jetnpasscuts = 0; + + for (jetIter = L1TkJetsHandle->begin(); jetIter != L1TkJetsHandle->end(); ++jetIter) { + // floats used for debugging + float tmp_jet_px_ = jetIter->pt() * cos(jetIter->glbphi()); + float tmp_jet_py_ = jetIter->pt() * sin(jetIter->glbphi()); + //float tmp_jet_et_ = jetIter->pt(); // FIXME Get Et from the emulated jets + float tmp_jet_pt_ = jetIter->pt(); + + l1tmhtemu::pt_t tmp_jet_pt = + l1tmhtemu::digitizeSignedValue(jetIter->pt(), l1tmhtemu::kInternalPtWidth, l1tmhtemu::kStepPt); + l1tmhtemu::eta_t tmp_jet_eta = l1tmhtemu::digitizeSignedValue( + jetIter->glbeta(), l1tmhtemu::kInternalEtaWidth, l1tmhtemu::kStepEta); + l1tmhtemu::phi_t tmp_jet_phi = l1tmhtemu::digitizeSignedValue( + jetIter->glbphi(), l1tmhtemu::kInternalPhiWidth, l1tmhtemu::kStepPhi); + l1tmhtemu::ntracks_t tmp_jet_nt = l1tmhtemu::ntracks_t(jetIter->nt()); + + l1tmhtemu::phi_t tmp_jet_cos_phi = l1tmhtemu::phi_t(-999); + l1tmhtemu::phi_t tmp_jet_sin_phi = l1tmhtemu::phi_t(-999); + + if (tmp_jet_phi >= 0) { + tmp_jet_cos_phi = cosLUT_[tmp_jet_phi]; + + if (cosLUTbins / 2 + 1 - tmp_jet_phi >= 0) + tmp_jet_sin_phi = cosLUT_[cosLUTbins / 2 + 1 - tmp_jet_phi]; + else + tmp_jet_sin_phi = cosLUT_[-1 * (cosLUTbins / 2 + 1 - tmp_jet_phi)]; + + } else { + tmp_jet_cos_phi = cosLUT_[-1 * tmp_jet_phi]; + + if (cosLUTbins / 2 + 1 - (-1 * tmp_jet_phi) >= 0) + tmp_jet_sin_phi = -1 * cosLUT_[cosLUTbins / 2 + 1 - (-1 * tmp_jet_phi)]; + else + tmp_jet_sin_phi = -1 * cosLUT_[-1 * (cosLUTbins / 2 + 1 - (-1 * tmp_jet_phi))]; + } + + l1tmhtemu::Et_t tmp_jet_px = tmp_jet_pt * tmp_jet_cos_phi; + l1tmhtemu::Et_t tmp_jet_py = tmp_jet_pt * tmp_jet_sin_phi; + + jetn++; + + if (debug_) { + edm::LogVerbatim("L1TrackerHTMissEmulatorProducer") + << "****JET EMULATION" << jetn << "****\n" + << "FLOATS ORIGINAL\n" + << "PT: " << jetIter->pt() << "| ETA: " << jetIter->glbeta() << "| PHI: " << jetIter->glbphi() + << "| NTRACKS: " << jetIter->nt() << "| COS(PHI): " << cos(jetIter->glbphi()) + << "| SIN(PHI): " << sin(jetIter->glbphi()) << "| Px: " << jetIter->pt() * cos(jetIter->glbphi()) + << "| Py: " << jetIter->pt() * sin(jetIter->glbphi()) << "\n" + << "AP_INTS RAW\n" + << "PT: " << jetIter->ptWord() << "| ETA: " << jetIter->glbEtaWord() << "| PHI: " << jetIter->glbPhiWord() + << "| NTRACKS: " << jetIter->ntWord() << "\n" + << "AP_INTS NEW\n" + << "PT: " << tmp_jet_pt << "| ETA: " << tmp_jet_eta << "| PHI: " << tmp_jet_phi << "| NTRACKS: " << tmp_jet_nt + << "| COS(PHI): " << tmp_jet_cos_phi << "| SIN(PHI): " << tmp_jet_sin_phi << "| Px: " << tmp_jet_px + << "| Py: " << tmp_jet_py << "\n" + << "AP_INTS NEW TO FLOATS\n" + << "PT: " << (float)tmp_jet_pt * l1tmhtemu::kStepPt << "| ETA: " << (float)tmp_jet_eta * l1tmhtemu::kStepEta + << "| PHI: " << (float)tmp_jet_phi * l1tmhtemu::kStepPhi << "| NTRACKS: " << (int)tmp_jet_nt + << "| COS(PHI): " << (float)tmp_jet_cos_phi * l1tmhtemu::kStepPhi + << "| SIN(PHI): " << (float)tmp_jet_sin_phi * l1tmhtemu::kStepPhi + << "| Px: " << (float)tmp_jet_px * l1tmhtemu::kStepPt * l1tmhtemu::kStepPhi + << "| Py: " << (float)tmp_jet_py * l1tmhtemu::kStepPt * l1tmhtemu::kStepPhi << "\n" + << "-------------------------------------------------------------------------\n"; + } + + if (tmp_jet_pt < jetMinPt_) + continue; + if (tmp_jet_eta > jetMaxEta_ or tmp_jet_eta < -1 * jetMaxEta_) + continue; + if (tmp_jet_nt < minNtracksLowPt_ && tmp_jet_pt > 200) + continue; + if (tmp_jet_nt < minNtracksHighPt_ && tmp_jet_pt > 400) + continue; + + jetnpasscuts++; + + if (debug_) { + sumPx_ += tmp_jet_px_; + sumPy_ += tmp_jet_py_; + HT_ += tmp_jet_pt_; + } + + sumPx += tmp_jet_pt * tmp_jet_cos_phi; + sumPy += tmp_jet_pt * tmp_jet_sin_phi; + HT += tmp_jet_pt; + + } // end jet loop + + // define missing HT + + // Perform cordic sqrt, take x,y and converts to polar coordinate r,phi where + // r=sqrt(x**2+y**2) and phi = atan(y/x) + l1tmhtemu::EtMiss EtMiss = l1tmhtemu::cordicSqrt(sumPx, sumPy, aSteps, atanLUT_, magNormalisationLUT_); + math::XYZTLorentzVector missingEt(-sumPx, -sumPy, 0, EtMiss.Et); + + l1tmhtemu::MHTphi_t phi = 0; + + if ((sumPx < 0) && (sumPy < 0)) + phi = EtMiss.Phi - l1tmhtemu::kMHTPhiBins / 2; + else if ((sumPx >= 0) && (sumPy >= 0)) + phi = (EtMiss.Phi) + l1tmhtemu::kMHTPhiBins / 2; + else if ((sumPx >= 0) && (sumPy < 0)) + phi = EtMiss.Phi - l1tmhtemu::kMHTPhiBins / 2; + else if ((sumPx < 0) && (sumPy >= 0)) + phi = EtMiss.Phi - 3 * l1tmhtemu::kMHTPhiBins / 2; + + if (debug_) { + edm::LogVerbatim("L1TrackerHTMissEmulatorProducer") + << "-------------------------------------------------------------------------\n" + << "====MHT FLOATS====\n" + << "sumPx: " << sumPx_ << "| sumPy: " << sumPy_ << "| ET: " << sqrt(sumPx_ * sumPx_ + sumPy_ * sumPy_) + << "| HT: " << HT_ << "| PHI: " << atan2(sumPy_, sumPx_) << "\n" + << "====MHT AP_INTS====\n" + << "sumPx: " << sumPx << "| sumPy: " << sumPy << "| ET: " << EtMiss.Et << "| HT: " << HT << "| PHI: " << phi + << "\n" + << "====MHT AP_INTS TO FLOATS====\n" + << "sumPx: " << (float)sumPx * l1tmhtemu::kStepPt * l1tmhtemu::kStepPhi + << "| sumPy: " << (float)sumPy * l1tmhtemu::kStepPt * l1tmhtemu::kStepPhi + << "| ET: " << (float)EtMiss.Et * l1tmhtemu::kStepMHT << "| HT: " << (float)HT * l1tmhtemu::kStepPt + << "| PHI: " << (float)phi * l1tmhtemu::kStepMHTPhi - M_PI << "\n" + << "-------------------------------------------------------------------------\n"; + } + + EtSum L1HTSum(missingEt, EtSum::EtSumType::kMissingHt, (int)HT, 0, (int)phi, (int)jetn); + + MHTCollection->push_back(L1HTSum); + iEvent.put(std::move(MHTCollection), L1MHTCollectionName_); + +} //end producer + +void L1TkHTMissEmulatorProducer::beginJob() {} + +void L1TkHTMissEmulatorProducer::endJob() {} + +DEFINE_FWK_MODULE(L1TkHTMissEmulatorProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkHTMissProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkHTMissProducer.cc index fc5626b256ecb..b47f7601008b2 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TkHTMissProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TkHTMissProducer.cc @@ -6,15 +6,13 @@ // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDProducer.h" #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DataFormats/Math/interface/LorentzVector.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" #include "DataFormats/L1TCorrelator/interface/TkHTMiss.h" #include "DataFormats/L1TCorrelator/interface/TkHTMissFwd.h" @@ -26,41 +24,40 @@ class L1TkHTMissProducer : public edm::stream::EDProducer<> { ~L1TkHTMissProducer() override; private: - //void beginJob() override; + virtual void beginJob(); void produce(edm::Event&, const edm::EventSetup&) override; - //void endJob() override; + virtual void endJob(); // ----------member data --------------------------- - float jetMinPt_; // [GeV] - float jetMaxEta_; // [rad] - bool doVtxConstrain_; // require vertex constraint - bool primaryVtxConstrain_; // use event primary vertex instead of leading jet (if doVtxConstrain) - bool useCaloJets_; // Determines whether or not calo jets are used - float deltaZ_; // for jets [cm] (if DoTvxConstrain) - float minJetEtLowPt_; // for track jets, minimum et required, depending on number of low pT tracks - float minJetEtHighPt_; - bool displaced_; // Use prompt/displaced tracks - unsigned int minNtracksHighPt_; - unsigned int minNtracksLowPt_; - const edm::EDGetTokenT pvToken_; + const float jetMinPt_; // [GeV] + const float jetMaxEta_; // [rad] + const bool doVtxConstrain_; // require vertex constraint + const bool useCaloJets_; // Determines whether or not calo jets are used + const bool primaryVtxConstrain_; // use event primary vertex instead of leading jet (if doVtxConstrain) + const float deltaZ_; // for jets [cm] (if DoTvxConstrain) + const unsigned int minNtracksHighPt_; + const unsigned int minNtracksLowPt_; + const float minJetEtLowPt_; // for track jets, minimum et required, depending on number of low pT tracks + const float minJetEtHighPt_; + const bool displaced_; // Use prompt/displaced tracks + const edm::EDGetTokenT pvToken_; const edm::EDGetTokenT jetToken_; }; L1TkHTMissProducer::L1TkHTMissProducer(const edm::ParameterSet& iConfig) - : pvToken_(consumes(iConfig.getParameter("L1VertexInputTag"))), + : jetMinPt_((float)iConfig.getParameter("jet_minPt")), + jetMaxEta_((float)iConfig.getParameter("jet_maxEta")), + doVtxConstrain_(iConfig.getParameter("doVtxConstrain")), + useCaloJets_(iConfig.getParameter("useCaloJets")), + primaryVtxConstrain_(iConfig.getParameter("primaryVtxConstrain")), + deltaZ_((float)iConfig.getParameter("deltaZ")), + minNtracksHighPt_(iConfig.getParameter("jet_minNtracksHighPt")), + minNtracksLowPt_(iConfig.getParameter("jet_minNtracksLowPt")), + minJetEtLowPt_(iConfig.getParameter("jet_minJetEtLowPt")), + minJetEtHighPt_(iConfig.getParameter("jet_minJetEtHighPt")), + displaced_(iConfig.getParameter("displaced")), + pvToken_(consumes(iConfig.getParameter("L1VertexInputTag"))), jetToken_(consumes(iConfig.getParameter("L1TkJetInputTag"))) { - jetMinPt_ = (float)iConfig.getParameter("jet_minPt"); - jetMaxEta_ = (float)iConfig.getParameter("jet_maxEta"); - doVtxConstrain_ = iConfig.getParameter("doVtxConstrain"); - useCaloJets_ = iConfig.getParameter("useCaloJets"); - primaryVtxConstrain_ = iConfig.getParameter("primaryVtxConstrain"); - deltaZ_ = (float)iConfig.getParameter("deltaZ"); - minNtracksHighPt_ = iConfig.getParameter("jet_minNtracksHighPt"); - minNtracksLowPt_ = iConfig.getParameter("jet_minNtracksLowPt"); - minJetEtLowPt_ = iConfig.getParameter("jet_minJetEtLowPt"); - minJetEtHighPt_ = iConfig.getParameter("jet_minJetEtHighPt"); - displaced_ = iConfig.getParameter("displaced"); - if (useCaloJets_) produces("TkCaloHTMiss"); else if (displaced_) @@ -76,7 +73,7 @@ void L1TkHTMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSet std::unique_ptr MHTCollection(new TkHTMissCollection); // L1 primary vertex - edm::Handle L1VertexHandle; + edm::Handle L1VertexHandle; iEvent.getByToken(pvToken_, L1VertexHandle); // L1 track-trigger jets @@ -99,21 +96,21 @@ void L1TkHTMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSet // ---------------------------------------------------------------------------------------------- float evtZVtx = 999; bool foundVtx = false; - edm::Ref L1VtxRef; // null reference + edm::Ref L1VtxRef; // null reference if (useCaloJets_) { if (doVtxConstrain_ && primaryVtxConstrain_) { if (!L1VertexHandle.isValid()) { - LogError("L1TkHTMissProducer") << "\nWarning: TkPrimaryVertexCollection not found in the event. Exit\n"; + LogError("L1TkHTMissProducer") << "\nWarning: VertexCollection not found in the event. Exit\n"; return; } else { - std::vector::const_iterator vtxIter = L1VertexHandle->begin(); + std::vector::const_iterator vtxIter = L1VertexHandle->begin(); // by convention, the first vertex in the collection is the one that should // be used by default - evtZVtx = vtxIter->zvertex(); + evtZVtx = vtxIter->z0(); foundVtx = true; int ivtx = 0; - edm::Ref vtxRef(L1VertexHandle, ivtx); + edm::Ref vtxRef(L1VertexHandle, ivtx); L1VtxRef = vtxRef; } } //endif primaryVtxConstrain_ @@ -135,9 +132,9 @@ void L1TkHTMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSet float tmp_jet_eta = jetIter->eta(); if (tmp_jet_pt < jetMinPt_) continue; - if (fabs(tmp_jet_eta) > jetMaxEta_) + if (std::abs(tmp_jet_eta) > jetMaxEta_) continue; - if (fabs(tmp_jet_vtx) > jetVtxMax) + if (std::abs(tmp_jet_vtx) > jetVtxMax) continue; // find vertex position of leading jet @@ -168,13 +165,13 @@ void L1TkHTMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSet float tmp_jet_vtx = jetIter->jetVtx(); if (jetIter->pt() < jetMinPt_) continue; - if (fabs(jetIter->eta()) > jetMaxEta_) + if (std::abs(jetIter->eta()) > jetMaxEta_) continue; // vertex consistency requirement bool VtxRequirement = false; if (foundVtx) - VtxRequirement = fabs(tmp_jet_vtx - evtZVtx) < deltaZ_; + VtxRequirement = std::abs(tmp_jet_vtx - evtZVtx) < deltaZ_; if (!doVtxConstrain_ || VtxRequirement) { sumPx_calo += tmp_jet_px; @@ -210,7 +207,7 @@ void L1TkHTMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSet float tmp_jet_pt = jetIter->pt(); if (tmp_jet_pt < jetMinPt_) continue; - if (fabs(jetIter->eta()) > jetMaxEta_) + if (std::abs(jetIter->eta()) > jetMaxEta_) continue; if (jetIter->ntracks() < minNtracksLowPt_ && tmp_jet_et > minJetEtLowPt_) continue; @@ -235,8 +232,8 @@ void L1TkHTMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSet } } //end producer -//void L1TkHTMissProducer::beginJob() {} +void L1TkHTMissProducer::beginJob() {} -//void L1TkHTMissProducer::endJob() {} +void L1TkHTMissProducer::endJob() {} DEFINE_FWK_MODULE(L1TkHTMissProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc deleted file mode 100644 index 8199d7ac45315..0000000000000 --- a/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc +++ /dev/null @@ -1,782 +0,0 @@ -// input: L1TkTracks and RegionalMuonCand (standalone with component details) -// match the two and produce a collection of TkMuon -// eventually, this should be made modular and allow to swap out different algorithms - -// user include files -#include "FWCore/Utilities/interface/InputTag.h" -#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/Framework/interface/EventSetup.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Common/interface/Handle.h" -#include "DataFormats/L1Trigger/interface/Muon.h" -#include "DataFormats/Math/interface/LorentzVector.h" -#include "DataFormats/Math/interface/angle_units.h" -#include "DataFormats/Math/interface/deltaR.h" -#include "DataFormats/Math/interface/deltaPhi.h" -#include "DataFormats/L1TCorrelator/interface/TkMuon.h" -#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" -#include "L1Trigger/L1TMuon/interface/MicroGMTConfiguration.h" -#include "L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h" -#include "L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h" -#include "L1Trigger/L1TMuonEndCap/interface/Common.h" - -// system include files -#include -#include - -static constexpr float mu_mass = 0.105658369; -static constexpr int barrel_MTF_region = 1; -static constexpr int overlap_MTF_region = 2; -static constexpr int endcap_MTF_region = 3; -static constexpr float eta_scale = 0.010875; -static constexpr float phi_scale = 2 * M_PI / 576.; -static constexpr float dr2_cutoff = 0.3; -static constexpr float matching_factor_eta = 3.; -static constexpr float matching_factor_phi = 4.; -static constexpr float min_mu_propagator_p = 3.5; -static constexpr float min_mu_propagator_barrel_pT = 3.5; -static constexpr float max_mu_propagator_eta = 2.5; - -using namespace l1t; - -class L1TkMuonProducer : public edm::stream::EDProducer<> { -public: - typedef TTTrack L1TTTrackType; - typedef std::vector L1TTTrackCollectionType; - - struct PropState { //something simple, imagine it's hardware emulation - PropState() : pt(-99), eta(-99), phi(-99), sigmaPt(-99), sigmaEta(-99), sigmaPhi(-99), valid(false) {} - float pt; - float eta; - float phi; - float sigmaPt; - float sigmaEta; - float sigmaPhi; - bool valid; - }; - - enum AlgoType { kTP = 1, kDynamicWindows = 2, kMantra = 3 }; - - explicit L1TkMuonProducer(const edm::ParameterSet&); - ~L1TkMuonProducer() override; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - -private: - void produce(edm::Event&, const edm::EventSetup&) override; - PropState propagateToGMT(const L1TTTrackType& l1tk) const; - double sigmaEtaTP(const RegionalMuonCand& mu) const; - double sigmaPhiTP(const RegionalMuonCand& mu) const; - - // the TP algorithm - void runOnMTFCollection_v1(const edm::Handle&, - const edm::Handle&, - TkMuonCollection& tkMuons, - const int detector) const; - - // algo for endcap regions using dynamic windows for making the match - void runOnMTFCollection_v2(const edm::Handle&, - const edm::Handle&, - TkMuonCollection& tkMuons) const; - - // given the matching indexes, build the output collection of track muons - void build_tkMuons_from_idxs(TkMuonCollection& tkMuons, - const std::vector& matches, - const edm::Handle& l1tksH, - const edm::Handle& muonH, - int detector) const; - - void build_tkMuons_from_idxs(TkMuonCollection& tkMuons, - const std::vector& matches, - const edm::Handle& l1tksH, - const edm::Handle& emtfTksH, - int detector) const; - - // dump and convert tracks to the format needed for the MAnTra correlator - std::vector product_to_trkvec(const L1TTTrackCollectionType& l1tks) const; // tracks - // regional muon finder - std::vector product_to_muvec(const RegionalMuonCandBxCollection& l1mtfs) const; - // endcap muon finder - eventually to be moved to regional candidate - std::vector product_to_muvec(const EMTFTrackCollection& l1mus) const; - - float etaMin_; - float etaMax_; - float etaBO_; //eta value for barrel-overlap fontier - float etaOE_; //eta value for overlap-endcap fontier - bool useRegionEtaMatching_; - float zMax_; // |z_track| < zMax_ in cm - float chi2Max_; - float pTMinTra_; - float dRMax_; - int nStubsmin_; // minimum number of stubs - bool correctGMTPropForTkZ_; - bool use5ParameterFit_; - bool useTPMatchWindows_; - bool applyQuality_; - - AlgoType bmtfMatchAlgoVersion_; - AlgoType omtfMatchAlgoVersion_; - AlgoType emtfMatchAlgoVersion_; - - std::unique_ptr dwcorr_; - - std::unique_ptr mantracorr_barr_; - std::unique_ptr mantracorr_ovrl_; - std::unique_ptr mantracorr_endc_; - int mantra_n_trk_par_; - - const edm::EDGetTokenT bmtfToken_; - const edm::EDGetTokenT omtfToken_; - const edm::EDGetTokenT emtfToken_; - // the track collection, directly from the EMTF and not formatted by GT - const edm::EDGetTokenT emtfTCToken_; - const edm::EDGetTokenT > > trackToken_; -}; - -L1TkMuonProducer::L1TkMuonProducer(const edm::ParameterSet& iConfig) - : etaMin_((float)iConfig.getParameter("ETAMIN")), - etaMax_((float)iConfig.getParameter("ETAMAX")), - etaBO_(iConfig.exists("ETABARRELOVERLAP") ? (float)iConfig.getParameter("ETABARRELOVERLAP") : 0.83), - etaOE_(iConfig.exists("ETAOVERLAPENDCAP") ? (float)iConfig.getParameter("ETAOVERLAPENDCAP") : 1.24), - useRegionEtaMatching_(iConfig.exists("useRegionEtaMatching") ? iConfig.getParameter("useRegionEtaMatching") - : true), - zMax_((float)iConfig.getParameter("ZMAX")), - chi2Max_((float)iConfig.getParameter("CHI2MAX")), - pTMinTra_((float)iConfig.getParameter("PTMINTRA")), - dRMax_((float)iConfig.getParameter("DRmax")), - nStubsmin_(iConfig.getParameter("nStubsmin")), - - // --- mantra corr params - mantra_n_trk_par_(iConfig.getParameter("mantra_n_trk_par")), - bmtfToken_(consumes(iConfig.getParameter("L1BMTFInputTag"))), - omtfToken_(consumes(iConfig.getParameter("L1OMTFInputTag"))), - emtfToken_(consumes(iConfig.getParameter("L1EMTFInputTag"))), - emtfTCToken_(consumes(iConfig.getParameter("L1EMTFTrackCollectionInputTag"))), - trackToken_(consumes > >( - iConfig.getParameter("L1TrackInputTag"))) { - // --------------------- configuration of the muon algorithm type - - std::string bmtfMatchAlgoVersionString = iConfig.getParameter("bmtfMatchAlgoVersion"); - std::transform(bmtfMatchAlgoVersionString.begin(), - bmtfMatchAlgoVersionString.end(), - bmtfMatchAlgoVersionString.begin(), - ::tolower); // make lowercase - - std::string omtfMatchAlgoVersionString = iConfig.getParameter("omtfMatchAlgoVersion"); - std::transform(omtfMatchAlgoVersionString.begin(), - omtfMatchAlgoVersionString.end(), - omtfMatchAlgoVersionString.begin(), - ::tolower); // make lowercase - - std::string emtfMatchAlgoVersionString = iConfig.getParameter("emtfMatchAlgoVersion"); - std::transform(emtfMatchAlgoVersionString.begin(), - emtfMatchAlgoVersionString.end(), - emtfMatchAlgoVersionString.begin(), - ::tolower); // make lowercase - - if (bmtfMatchAlgoVersionString == "tp") - bmtfMatchAlgoVersion_ = kTP; - else if (bmtfMatchAlgoVersionString == "mantra") - bmtfMatchAlgoVersion_ = kMantra; - else - throw cms::Exception("TkMuAlgoConfig") - << "the ID " << bmtfMatchAlgoVersionString << " of the BMTF algo matcher passed is invalid\n"; - - if (omtfMatchAlgoVersionString == "tp") - omtfMatchAlgoVersion_ = kTP; - else if (omtfMatchAlgoVersionString == "mantra") - omtfMatchAlgoVersion_ = kMantra; - else - throw cms::Exception("TkMuAlgoConfig") - << "the ID " << omtfMatchAlgoVersionString << " of the OMTF algo matcher passed is invalid\n"; - - if (emtfMatchAlgoVersionString == "tp") - emtfMatchAlgoVersion_ = kTP; - else if (emtfMatchAlgoVersionString == "dynamicwindows") - emtfMatchAlgoVersion_ = kDynamicWindows; - else if (emtfMatchAlgoVersionString == "mantra") - emtfMatchAlgoVersion_ = kMantra; - else - throw cms::Exception("TkMuAlgoConfig") - << "the ID " << emtfMatchAlgoVersionString << " of the EMTF algo matcher passed is invalid\n"; - - correctGMTPropForTkZ_ = iConfig.getParameter("correctGMTPropForTkZ"); - - use5ParameterFit_ = iConfig.getParameter("use5ParameterFit"); - useTPMatchWindows_ = iConfig.getParameter("useTPMatchWindows"); - applyQuality_ = iConfig.exists("applyQualityCuts") ? iConfig.getParameter("applyQualityCuts") : false; - - produces(); - - // initializations - if (emtfMatchAlgoVersion_ == kDynamicWindows) { - // FIXME: to merge eventually into an unique file with bith phi and theta boundaries - std::string fIn_bounds_name = iConfig.getParameter("emtfcorr_boundaries").fullPath(); - std::string fIn_theta_name = iConfig.getParameter("emtfcorr_theta_windows").fullPath(); - std::string fIn_phi_name = iConfig.getParameter("emtfcorr_phi_windows").fullPath(); - const auto& bounds = L1TkMuCorrDynamicWindows::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l"); - TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str()); - TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str()); - dwcorr_ = std::make_unique(bounds, fIn_theta, fIn_phi); - - // files can be closed since the correlator code clones the TF1s - fIn_theta->Close(); - fIn_phi->Close(); - - // FIXME: more initialisation using the parameters passed from the cfg - dwcorr_->set_safety_factor(iConfig.getParameter("final_window_factor")); - dwcorr_->set_sf_initialrelax(iConfig.getParameter("initial_window_factor")); - - dwcorr_->set_relaxation_pattern(iConfig.getParameter("pt_start_relax"), - iConfig.getParameter("pt_end_relax")); - - dwcorr_->set_do_relax_factor(iConfig.getParameter("do_relax_factors")); - - dwcorr_->set_n_trk_par(iConfig.getParameter("n_trk_par")); - dwcorr_->set_min_trk_p(iConfig.getParameter("min_trk_p")); - dwcorr_->set_max_trk_aeta(iConfig.getParameter("max_trk_aeta")); - dwcorr_->set_max_trk_chi2(iConfig.getParameter("max_trk_chi2")); - dwcorr_->set_min_trk_nstubs(iConfig.getParameter("min_trk_nstubs")); - dwcorr_->set_do_trk_qual_presel(true); - } - - if (bmtfMatchAlgoVersion_ == kMantra) { - std::string fIn_bounds_name = iConfig.getParameter("mantra_bmtfcorr_boundaries").fullPath(); - std::string fIn_theta_name = iConfig.getParameter("mantra_bmtfcorr_theta_windows").fullPath(); - std::string fIn_phi_name = iConfig.getParameter("mantra_bmtfcorr_phi_windows").fullPath(); - - const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l"); - - TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str()); - TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str()); - - mantracorr_barr_ = std::make_unique(bounds, fIn_theta, fIn_phi, "mantra_barrel"); - - fIn_theta->Close(); - fIn_phi->Close(); - - // settings : NB : now hardcoded, could be read from cfg - mantracorr_barr_->set_safety_factor(0.5, 0.5); - mantracorr_barr_->setArbitrationType("MaxPt"); - } - - if (omtfMatchAlgoVersion_ == kMantra) { - std::string fIn_bounds_name = iConfig.getParameter("mantra_omtfcorr_boundaries").fullPath(); - std::string fIn_theta_name = iConfig.getParameter("mantra_omtfcorr_theta_windows").fullPath(); - std::string fIn_phi_name = iConfig.getParameter("mantra_omtfcorr_phi_windows").fullPath(); - - const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l"); - - TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str()); - TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str()); - - mantracorr_ovrl_ = std::make_unique(bounds, fIn_theta, fIn_phi, "mantra_overlap"); - - fIn_theta->Close(); - fIn_phi->Close(); - - // settings : NB : now hardcoded, could be read from cfg - mantracorr_ovrl_->set_safety_factor(0.5, 0.5); - mantracorr_ovrl_->setArbitrationType("MaxPt"); - } - - if (emtfMatchAlgoVersion_ == kMantra) { - std::string fIn_bounds_name = iConfig.getParameter("mantra_emtfcorr_boundaries").fullPath(); - std::string fIn_theta_name = iConfig.getParameter("mantra_emtfcorr_theta_windows").fullPath(); - std::string fIn_phi_name = iConfig.getParameter("mantra_emtfcorr_phi_windows").fullPath(); - - const auto& bounds = L1TkMuMantra::prepare_corr_bounds(fIn_bounds_name, "h_dphi_l"); - - TFile* fIn_theta = TFile::Open(fIn_theta_name.c_str()); - TFile* fIn_phi = TFile::Open(fIn_phi_name.c_str()); - - mantracorr_endc_ = std::make_unique(bounds, fIn_theta, fIn_phi, "mantra_endcap"); - - fIn_theta->Close(); - fIn_phi->Close(); - - // settings : NB : now hardcoded, could be read from cfg - mantracorr_endc_->set_safety_factor(0.5, 0.5); - mantracorr_endc_->setArbitrationType("MaxPt"); - } -} - -L1TkMuonProducer::~L1TkMuonProducer() {} - -// ------------ method called to produce the data ------------ -void L1TkMuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - // the L1Mu objects - edm::Handle l1bmtfH; - edm::Handle l1omtfH; - edm::Handle l1emtfH; - edm::Handle l1emtfTCH; - - iEvent.getByToken(bmtfToken_, l1bmtfH); - iEvent.getByToken(omtfToken_, l1omtfH); - iEvent.getByToken(emtfToken_, l1emtfH); - iEvent.getByToken(emtfTCToken_, l1emtfTCH); - - // the L1Tracks - edm::Handle l1tksH; - iEvent.getByToken(trackToken_, l1tksH); - - TkMuonCollection oc_bmtf_tkmuon; - TkMuonCollection oc_omtf_tkmuon; - TkMuonCollection oc_emtf_tkmuon; - - std::vector mantradf_tracks; // if needed, just encode once for all trk finders - if (bmtfMatchAlgoVersion_ == kMantra || omtfMatchAlgoVersion_ == kMantra || emtfMatchAlgoVersion_ == kMantra) { - mantradf_tracks = product_to_trkvec(*l1tksH.product()); - } - - // process each of the MTF collections separately! -- we don't want to filter the muons - - // ----------------------------------------------------- barrel - if (bmtfMatchAlgoVersion_ == kTP) - runOnMTFCollection_v1(l1bmtfH, l1tksH, oc_bmtf_tkmuon, barrel_MTF_region); - else if (bmtfMatchAlgoVersion_ == kMantra) { - const auto& muons = product_to_muvec(*l1bmtfH.product()); - const auto& match_idx = mantracorr_barr_->find_match(mantradf_tracks, muons); - build_tkMuons_from_idxs(oc_bmtf_tkmuon, match_idx, l1tksH, l1bmtfH, barrel_MTF_region); - } else { - throw cms::Exception("TkMuAlgoConfig") << " barrel : trying to run an invalid algorithm version " - << bmtfMatchAlgoVersion_ << " (this should never happen)\n"; - return; - } - - // ----------------------------------------------------- overlap - if (omtfMatchAlgoVersion_ == kTP) - runOnMTFCollection_v1(l1omtfH, l1tksH, oc_omtf_tkmuon, overlap_MTF_region); - else if (omtfMatchAlgoVersion_ == kMantra) { - const auto& muons = product_to_muvec(*l1omtfH.product()); - const auto& match_idx = mantracorr_ovrl_->find_match(mantradf_tracks, muons); - build_tkMuons_from_idxs(oc_omtf_tkmuon, match_idx, l1tksH, l1omtfH, overlap_MTF_region); - } else { - throw cms::Exception("TkMuAlgoConfig") << " overlap : trying to run an invalid algorithm version " - << omtfMatchAlgoVersion_ << " (this should never happen)\n"; - return; - } - - // ----------------------------------------------------- endcap - if (emtfMatchAlgoVersion_ == kTP) - runOnMTFCollection_v1(l1emtfH, l1tksH, oc_emtf_tkmuon, endcap_MTF_region); - else if (emtfMatchAlgoVersion_ == kDynamicWindows) - runOnMTFCollection_v2(l1emtfTCH, l1tksH, oc_emtf_tkmuon); - else if (emtfMatchAlgoVersion_ == kMantra) { - const auto& muons = product_to_muvec(*l1emtfTCH.product()); - const auto& match_idx = mantracorr_endc_->find_match(mantradf_tracks, muons); - //for the TkMu that were built from a EMTFCollection - pass the emtf track as ref - build_tkMuons_from_idxs(oc_emtf_tkmuon, match_idx, l1tksH, l1emtfTCH, endcap_MTF_region); - } else { - throw cms::Exception("TkMuAlgoConfig") << "endcap : trying to run an invalid algorithm version " - << emtfMatchAlgoVersion_ << " (this should never happen)\n"; - return; - } - - // now combine all trk muons into a single output collection! - auto oc_tkmuon = std::make_unique(); - for (const auto& p : {oc_bmtf_tkmuon, oc_omtf_tkmuon, oc_emtf_tkmuon}) { - oc_tkmuon->insert(oc_tkmuon->end(), p.begin(), p.end()); - } - - // put the new track+muon objects in the event! - iEvent.put(std::move(oc_tkmuon)); -}; - -void L1TkMuonProducer::runOnMTFCollection_v1(const edm::Handle& muonH, - const edm::Handle& l1tksH, - TkMuonCollection& tkMuons, - const int detector) const { - const L1TTTrackCollectionType& l1tks = (*l1tksH.product()); - const RegionalMuonCandBxCollection& l1mtfs = (*muonH.product()); - - int imu = 0; - for (auto l1mu = l1mtfs.begin(0); l1mu != l1mtfs.end(0); ++l1mu) { // considering BX = only - - edm::Ref l1muRef(muonH, imu); - imu++; - - float l1mu_eta = l1mu->hwEta() * eta_scale; - // get the global phi - float l1mu_phi = - MicroGMTConfiguration::calcGlobalPhi(l1mu->hwPhi(), l1mu->trackFinderType(), l1mu->processor()) * phi_scale; - - float l1mu_feta = std::abs(l1mu_eta); - if (l1mu_feta < etaMin_) - continue; - if (l1mu_feta > etaMax_) - continue; - - float drmin = 999; - - PropState matchProp; - int match_idx = -1; - int il1tk = -1; - - int nTracksMatch = 0; - - for (const auto& l1tk : l1tks) { - il1tk++; - - float l1tk_pt = l1tk.momentum().perp(); - if (l1tk_pt < pTMinTra_) - continue; - - float l1tk_z = l1tk.POCA().z(); - if (std::abs(l1tk_z) > zMax_) - continue; - - float l1tk_chi2 = l1tk.chi2(); - if (l1tk_chi2 > chi2Max_) - continue; - - int l1tk_nstubs = l1tk.getStubRefs().size(); - if (l1tk_nstubs < nStubsmin_) - continue; - - float l1tk_eta = l1tk.momentum().eta(); - float l1tk_phi = l1tk.momentum().phi(); - - float dr2 = reco::deltaR2(l1mu_eta, l1mu_phi, l1tk_eta, l1tk_phi); - if (dr2 > dr2_cutoff) - continue; - - nTracksMatch++; - - const PropState& pstate = propagateToGMT(l1tk); - if (!pstate.valid) - continue; - - float dr2prop = reco::deltaR2(l1mu_eta, l1mu_phi, pstate.eta, pstate.phi); - // FIXME: check if this matching procedure can be improved with - // a pT dependent dR window - if (dr2prop < drmin) { - drmin = dr2prop; - match_idx = il1tk; - matchProp = pstate; - } - } // over l1tks - - LogDebug("L1TkMuonProducer") << "matching index is " << match_idx; - if (match_idx >= 0) { - const L1TTTrackType& matchTk = l1tks[match_idx]; - - float sigmaEta = sigmaEtaTP(*l1mu); - float sigmaPhi = sigmaPhiTP(*l1mu); - - float etaCut = matching_factor_eta * sqrt(sigmaEta * sigmaEta + matchProp.sigmaEta * matchProp.sigmaEta); - float phiCut = matching_factor_phi * sqrt(sigmaPhi * sigmaPhi + matchProp.sigmaPhi * matchProp.sigmaPhi); - - float dEta = std::abs(matchProp.eta - l1mu_eta); - float dPhi = std::abs(deltaPhi(matchProp.phi, l1mu_phi)); - - bool matchCondition = useTPMatchWindows_ ? dEta < etaCut && dPhi < phiCut : drmin < dRMax_; - - if (matchCondition) { - edm::Ptr l1tkPtr(l1tksH, match_idx); - - const auto& p3 = matchTk.momentum(); - float p4e = sqrt(mu_mass * mu_mass + p3.mag2()); - - math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e); - - const auto& tkv3 = matchTk.POCA(); - math::XYZPoint v3(tkv3.x(), tkv3.y(), tkv3.z()); // why is this defined? - - float trkisol = -999; - - TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol); - - if (useRegionEtaMatching_) { - if (detector == barrel_MTF_region) { - if (std::abs(l1tkmu.eta()) > etaBO_) - continue; - } else if (detector == overlap_MTF_region) { - if (std::abs(l1tkmu.eta()) < etaBO_) - continue; - if (std::abs(l1tkmu.eta()) > etaOE_) - continue; - } else if (detector == endcap_MTF_region) { - if (std::abs(l1tkmu.eta()) < etaOE_) - continue; - } - } - l1tkmu.setTrackCurvature(matchTk.rInv()); - l1tkmu.setTrkzVtx((float)tkv3.z()); - l1tkmu.setdR(drmin); - l1tkmu.setNTracksMatched(nTracksMatch); - l1tkmu.setMuonDetector(detector); - l1tkmu.setQuality(l1muRef->hwQual()); - tkMuons.push_back(l1tkmu); - } - } - } //over l1mus -} - -void L1TkMuonProducer::runOnMTFCollection_v2(const edm::Handle& muonH, - const edm::Handle& l1tksH, - TkMuonCollection& tkMuons) const { - const EMTFTrackCollection& l1mus = (*muonH.product()); - const L1TTTrackCollectionType& l1trks = (*l1tksH.product()); - const auto& corr_mu_idxs = dwcorr_->find_match(l1mus, l1trks); - // it's a vector with as many entries as the L1TT vector. - // >= 0 : the idx in the EMTF vector of matched mu - // < 0: no match - - // sanity check - if (corr_mu_idxs.size() != l1trks.size()) - throw cms::Exception("TkMuAlgoOutput") - << "the size of tkmu indices does not match the size of input trk collection\n"; - - for (uint il1ttrack = 0; il1ttrack < corr_mu_idxs.size(); ++il1ttrack) { - int emtf_idx = corr_mu_idxs[il1ttrack]; - if (emtf_idx < 0) - continue; - - const L1TTTrackType& matchTk = l1trks[il1ttrack]; - const auto& p3 = matchTk.momentum(); - const auto& tkv3 = matchTk.POCA(); - float p4e = sqrt(mu_mass * mu_mass + p3.mag2()); - math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e); - - edm::Ref l1muRef; - edm::Ptr l1tkPtr(l1tksH, il1ttrack); - float trkisol = -999; // now doing as in the TP algo - TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol); - - // avoid leaking of candidates to overlap region... - if (useRegionEtaMatching_ && std::abs(l1tkmu.eta()) < etaOE_) - continue; - - l1tkmu.setTrackCurvature(matchTk.rInv()); - l1tkmu.setTrkzVtx((float)tkv3.z()); - l1tkmu.setMuonDetector(endcap_MTF_region); - tkMuons.push_back(l1tkmu); - } - - return; -} - -// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ -void L1TkMuonProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - //The following says we do not know what parameters are allowed so do no validation - // Please change this to state exactly what you do use, even if it is no parameters - edm::ParameterSetDescription desc; - desc.setUnknown(); - descriptions.addDefault(desc); -} - -L1TkMuonProducer::PropState L1TkMuonProducer::propagateToGMT(const L1TkMuonProducer::L1TTTrackType& tk) const { - auto p3 = tk.momentum(); - float tk_pt = p3.perp(); - float tk_p = p3.mag(); - float tk_eta = p3.eta(); - float tk_aeta = std::abs(tk_eta); - float tk_phi = p3.phi(); - float tk_q = tk.rInv() > 0 ? 1. : -1.; - float tk_z = tk.POCA().z(); - if (!correctGMTPropForTkZ_) - tk_z = 0; - - L1TkMuonProducer::PropState dest; - if (tk_p < min_mu_propagator_p) - return dest; - if (tk_aeta < 1.1 && tk_pt < min_mu_propagator_barrel_pT) - return dest; - if (tk_aeta > max_mu_propagator_eta) - return dest; - - //0th order: - dest.valid = true; - - float dzCorrPhi = 1.; - float deta = 0; - float etaProp = tk_aeta; - - if (tk_aeta < 1.1) { - etaProp = 1.1; - deta = tk_z / 550. / cosh(tk_aeta); - } else { - float delta = tk_z / 850.; //roughly scales as distance to 2nd station - if (tk_eta > 0) - delta *= -1; - dzCorrPhi = 1. + delta; - - float zOzs = tk_z / 850.; - if (tk_eta > 0) - deta = zOzs / (1. - zOzs); - else - deta = zOzs / (1. + zOzs); - deta = deta * tanh(tk_eta); - } - float resPhi = tk_phi - 1.464 * tk_q * cosh(1.7) / cosh(etaProp) / tk_pt * dzCorrPhi - M_PI / 144.; - resPhi = reco::reduceRange(resPhi); - - dest.eta = tk_eta + deta; - dest.phi = resPhi; - dest.pt = tk_pt; //not corrected for eloss - - dest.sigmaEta = 0.100 / tk_pt; //multiple scattering term - dest.sigmaPhi = 0.106 / tk_pt; //need a better estimate for these - return dest; -} - -double L1TkMuonProducer::sigmaEtaTP(const RegionalMuonCand& l1mu) const { - float l1mu_eta = l1mu.hwEta() * eta_scale; - if (std::abs(l1mu_eta) <= 1.55) - return 0.0288; - else if (std::abs(l1mu_eta) > 1.55 && std::abs(l1mu_eta) <= 1.65) - return 0.025; - else if (std::abs(l1mu_eta) > 1.65 && std::abs(l1mu_eta) <= 2.4) - return 0.0144; - return 0.0288; -} - -double L1TkMuonProducer::sigmaPhiTP(const RegionalMuonCand& mu) const { return 0.0126; } - -// ------------------------------------------------------------------------------------------------------------ - -std::vector L1TkMuonProducer::product_to_trkvec(const L1TTTrackCollectionType& l1tks) const { - std::vector result(l1tks.size()); - for (uint itrk = 0; itrk < l1tks.size(); ++itrk) { - auto& trk = l1tks[itrk]; - - result[itrk].pt = trk.momentum().perp(); - result[itrk].eta = trk.momentum().eta(); - result[itrk].theta = L1TkMuMantra::to_mpio2_pio2(L1TkMuMantra::eta_to_theta(trk.momentum().eta())); - result[itrk].phi = trk.momentum().phi(); - result[itrk].nstubs = trk.getStubRefs().size(); - result[itrk].chi2 = trk.chi2(); - result[itrk].charge = (trk.rInv() > 0 ? 1 : -1); - } - - return result; -} - -std::vector L1TkMuonProducer::product_to_muvec( - const RegionalMuonCandBxCollection& l1mtfs) const { - std::vector result; - for (auto l1mu = l1mtfs.begin(0); l1mu != l1mtfs.end(0); ++l1mu) // considering BX = 0 only - { - L1TkMuMantraDF::muon_df this_mu; - this_mu.pt = l1mu->hwPt() * 0.5; - this_mu.eta = l1mu->hwEta() * eta_scale; - this_mu.theta = L1TkMuMantra::to_mpio2_pio2(L1TkMuMantra::eta_to_theta(l1mu->hwEta() * eta_scale)); - this_mu.phi = - MicroGMTConfiguration::calcGlobalPhi(l1mu->hwPhi(), l1mu->trackFinderType(), l1mu->processor()) * phi_scale; - this_mu.charge = (l1mu->hwSign() == 0 ? 1 : -1); // charge sign bit (charge = (-1)^(sign)) - result.push_back(this_mu); - } - return result; -} - -std::vector L1TkMuonProducer::product_to_muvec(const EMTFTrackCollection& l1mus) const { - std::vector result(l1mus.size()); - for (uint imu = 0; imu < l1mus.size(); ++imu) { - auto& mu = l1mus[imu]; - - // dropping the emtf tracks with certain quality... - int emtfQual = (mu.Mode() == 11 || mu.Mode() == 13 || mu.Mode() == 14 || mu.Mode() == 15); - if (applyQuality_ && !emtfQual) - continue; - - result[imu].pt = mu.Pt(); - result[imu].eta = mu.Eta(); - result[imu].theta = L1TkMuMantra::to_mpio2_pio2(L1TkMuMantra::eta_to_theta(mu.Eta())); - result[imu].phi = angle_units::operators::convertDegToRad(mu.Phi_glob()); - result[imu].charge = mu.Charge(); - } - return result; -} - -void L1TkMuonProducer::build_tkMuons_from_idxs(TkMuonCollection& tkMuons, - const std::vector& matches, - const edm::Handle& l1tksH, - const edm::Handle& muonH, - int detector) const { - for (uint imatch = 0; imatch < matches.size(); ++imatch) { - int match_trk_idx = matches[imatch]; - if (match_trk_idx < 0) - continue; // this muon was not matched to any candidate - - // take properties of the track - const L1TTTrackType& matchTk = (*l1tksH.product())[match_trk_idx]; - const auto& p3 = matchTk.momentum(); - const auto& tkv3 = matchTk.POCA(); - float p4e = sqrt(mu_mass * mu_mass + p3.mag2()); - math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e); - - edm::Ptr l1tkPtr(l1tksH, match_trk_idx); - auto l1muRef = muonH.isValid() ? edm::Ref(muonH, imatch) - : edm::Ref(); - - float trkisol = -999; - TkMuon l1tkmu(l1tkp4, l1muRef, l1tkPtr, trkisol); - l1tkmu.setTrackCurvature(matchTk.rInv()); - l1tkmu.setTrkzVtx((float)tkv3.z()); - l1tkmu.setMuonDetector(detector); - l1tkmu.setQuality(l1muRef->hwQual()); - - // apply region cleaning (probably this is not the best way, but since this is going to - // be a patch and temporary, it is OK) - if (useRegionEtaMatching_) { - if (detector == barrel_MTF_region) { - if (std::abs(l1tkmu.eta()) > etaBO_) - continue; - } else if (detector == overlap_MTF_region) { - if (std::abs(l1tkmu.eta()) < etaBO_) - continue; - if (std::abs(l1tkmu.eta()) > etaOE_) - continue; - } else if (detector == endcap_MTF_region) { - if (std::abs(l1tkmu.eta()) < etaOE_) - continue; - } - } - tkMuons.push_back(l1tkmu); - } - return; -} - -void L1TkMuonProducer::build_tkMuons_from_idxs(TkMuonCollection& tkMuons, - const std::vector& matches, - const edm::Handle& l1tksH, - const edm::Handle& emtfTksH, - int detector) const { - for (uint imatch = 0; imatch < matches.size(); ++imatch) { - int match_trk_idx = matches[imatch]; - if (match_trk_idx < 0) - continue; // this muon was not matched to any candidate - - // take properties of the track - const L1TTTrackType& matchTk = (*l1tksH.product())[match_trk_idx]; - const auto& p3 = matchTk.momentum(); - const auto& tkv3 = matchTk.POCA(); - float p4e = sqrt(mu_mass * mu_mass + p3.mag2()); - math::XYZTLorentzVector l1tkp4(p3.x(), p3.y(), p3.z(), p4e); - - edm::Ptr l1tkPtr(l1tksH, match_trk_idx); - - auto l1emtfTrk = - emtfTksH.isValid() ? edm::Ref(emtfTksH, imatch) : edm::Ref(); - - float trkisol = -999; - TkMuon l1tkmu(l1tkp4, l1emtfTrk, l1tkPtr, trkisol); - l1tkmu.setTrackCurvature(matchTk.rInv()); - l1tkmu.setTrkzVtx((float)tkv3.z()); - l1tkmu.setMuonDetector(detector); - l1tkmu.setQuality(l1emtfTrk->Mode()); - - if (useRegionEtaMatching_ && std::abs(l1tkmu.eta()) < etaOE_) - continue; - - tkMuons.push_back(l1tkmu); - } - return; -} - -//define this as a plug-in -DEFINE_FWK_MODULE(L1TkMuonProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackFastJetProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackFastJetProducer.cc index 126736a5b9cca..b2c0cb4fa2eb5 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackFastJetProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackFastJetProducer.cc @@ -10,7 +10,6 @@ // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDProducer.h" #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" @@ -27,7 +26,7 @@ #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "DataFormats/L1TCorrelator/interface/TkJet.h" #include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" // geometry #include "Geometry/Records/interface/TrackerTopologyRcd.h" @@ -60,49 +59,49 @@ class L1TrackFastJetProducer : public edm::stream::EDProducer<> { static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); private: - //void beginJob() override; + //virtual void beginJob(); void produce(edm::Event&, const edm::EventSetup&) override; - //void endJob() override; + //virtual void endJob(); // track selection criteria - float trkZMax_; // in [cm] - float trkChi2dofMax_; // maximum track chi2dof - double trkBendChi2Max_; // maximum track bendchi2 - float trkPtMin_; // in [GeV] - float trkEtaMax_; // in [rad] - int trkNStubMin_; // minimum number of stubs - int trkNPSStubMin_; // minimum number of PS stubs - double deltaZ0Cut_; // save with |L1z-z0| < maxZ0 - double coneSize_; // Use anti-kt with this cone size - bool doTightChi2_; - float trkPtTightChi2_; - float trkChi2dofTightChi2_; - bool displaced_; //use prompt/displaced tracks + const float trkZMax_; // in [cm] + const float trkChi2dofMax_; // maximum track chi2dof + const double trkBendChi2Max_; // maximum track bendchi2 + const float trkPtMin_; // in [GeV] + const float trkEtaMax_; // in [rad] + const int trkNStubMin_; // minimum number of stubs + const int trkNPSStubMin_; // minimum number of PS stubs + const double deltaZ0Cut_; // save with |L1z-z0| < maxZ0 + const double coneSize_; // Use anti-kt with this cone size + const bool doTightChi2_; + const float trkPtTightChi2_; + const float trkChi2dofTightChi2_; + const bool displaced_; //use prompt/displaced tracks const edm::EDGetTokenT > > trackToken_; - edm::EDGetTokenT pvToken_; + edm::EDGetTokenT pvToken_; edm::ESGetToken tTopoToken_; }; // constructor L1TrackFastJetProducer::L1TrackFastJetProducer(const edm::ParameterSet& iConfig) - : trackToken_(consumes > >( + : trkZMax_((float)iConfig.getParameter("trk_zMax")), + trkChi2dofMax_((float)iConfig.getParameter("trk_chi2dofMax")), + trkBendChi2Max_(iConfig.getParameter("trk_bendChi2Max")), + trkPtMin_((float)iConfig.getParameter("trk_ptMin")), + trkEtaMax_((float)iConfig.getParameter("trk_etaMax")), + trkNStubMin_((int)iConfig.getParameter("trk_nStubMin")), + trkNPSStubMin_((int)iConfig.getParameter("trk_nPSStubMin")), + deltaZ0Cut_((float)iConfig.getParameter("deltaZ0Cut")), + coneSize_((float)iConfig.getParameter("coneSize")), + doTightChi2_(iConfig.getParameter("doTightChi2")), + trkPtTightChi2_((float)iConfig.getParameter("trk_ptTightChi2")), + trkChi2dofTightChi2_((float)iConfig.getParameter("trk_chi2dofTightChi2")), + displaced_(iConfig.getParameter("displaced")), + trackToken_(consumes > >( iConfig.getParameter("L1TrackInputTag"))), - pvToken_(consumes(iConfig.getParameter("L1PrimaryVertexTag"))), + pvToken_(consumes(iConfig.getParameter("L1PrimaryVertexTag"))), tTopoToken_(esConsumes(edm::ESInputTag("", ""))) { - trkZMax_ = (float)iConfig.getParameter("trk_zMax"); - trkChi2dofMax_ = (float)iConfig.getParameter("trk_chi2dofMax"); - trkBendChi2Max_ = iConfig.getParameter("trk_bendChi2Max"); - trkPtMin_ = (float)iConfig.getParameter("trk_ptMin"); - trkEtaMax_ = (float)iConfig.getParameter("trk_etaMax"); - trkNStubMin_ = (int)iConfig.getParameter("trk_nStubMin"); - trkNPSStubMin_ = (int)iConfig.getParameter("trk_nPSStubMin"); - deltaZ0Cut_ = (float)iConfig.getParameter("deltaZ0Cut"); - coneSize_ = (float)iConfig.getParameter("coneSize"); - doTightChi2_ = iConfig.getParameter("doTightChi2"); - trkPtTightChi2_ = (float)iConfig.getParameter("trk_ptTightChi2"); - trkChi2dofTightChi2_ = (float)iConfig.getParameter("trk_chi2dofTightChi2"); - displaced_ = iConfig.getParameter("displaced"); if (displaced_) produces("L1TrackFastJetsExtended"); else @@ -124,13 +123,13 @@ void L1TrackFastJetProducer::produce(edm::Event& iEvent, const edm::EventSetup& // Tracker Topology const TrackerTopology& tTopo = iSetup.getData(tTopoToken_); - edm::Handle TkPrimaryVertexHandle; - iEvent.getByToken(pvToken_, TkPrimaryVertexHandle); + edm::Handle L1PrimaryVertexHandle; + iEvent.getByToken(pvToken_, L1PrimaryVertexHandle); fastjet::JetDefinition jet_def(fastjet::antikt_algorithm, coneSize_); std::vector JetInputs; - float recoVtx = TkPrimaryVertexHandle->begin()->zvertex(); + float recoVtx = L1PrimaryVertexHandle->begin()->z0(); unsigned int this_l1track = 0; for (iterL1Track = TTTrackHandle->begin(); iterL1Track != TTTrackHandle->end(); iterL1Track++) { this_l1track++; @@ -142,9 +141,9 @@ void L1TrackFastJetProducer::produce(edm::Event& iEvent, const edm::EventSetup& theStubs = iterL1Track->getStubRefs(); int trk_nstub = (int)theStubs.size(); - if (fabs(trk_z0) > trkZMax_) + if (std::abs(trk_z0) > trkZMax_) continue; - if (fabs(iterL1Track->momentum().eta()) > trkEtaMax_) + if (std::abs(iterL1Track->momentum().eta()) > trkEtaMax_) continue; if (trk_pt < trkPtMin_) continue; @@ -172,7 +171,7 @@ void L1TrackFastJetProducer::produce(edm::Event& iEvent, const edm::EventSetup& } if (trk_nPS < trkNPSStubMin_) continue; - if (fabs(recoVtx - trk_z0) > deltaZ0Cut_) + if (std::abs(recoVtx - trk_z0) > deltaZ0Cut_) continue; fastjet::PseudoJet psuedoJet(iterL1Track->momentum().x(), diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulationProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulationProducer.cc new file mode 100644 index 0000000000000..bda124a512d5c --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetEmulationProducer.cc @@ -0,0 +1,677 @@ +/* Software to emulate the hardware 2-layer jet-finding algorithm (fixed-point). *Layers 1 and 2* + * + * 2021 + * + * Created based on Rishi Patel's L1TrackJetProducer.cc file. + * Authors: Samuel Edwin Leigh, Tyler Wu + * Rutgers, the State University of New Jersey + * Revolutionary for 250 years + */ + +//Holds data from tracks, converted from their integer versions. + +// system include files + +#include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/L1TCorrelator/interface/TkJet.h" +#include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" +#include "DataFormats/L1Trigger/interface/TkJetWord.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" +#include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" +#include "Geometry/CommonTopologies/interface/PixelGeomDetType.h" +#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" + +#include "DataFormats/L1Trigger/interface/Vertex.h" + +#include +#include +#include +#include +#include +#include +#include +#include "TH1D.h" +#include "TH2D.h" +#include +#include +#include "L1Trigger/L1TTrackMatch/interface/L1TrackJetEmulationProducer.h" + +using namespace std; +using namespace edm; +class L1TrackJetEmulationProducer : public stream::EDProducer<> { +public: + explicit L1TrackJetEmulationProducer(const ParameterSet &); + ~L1TrackJetEmulationProducer() override; + typedef TTTrack L1TTTrackType; + typedef vector L1TTTrackCollectionType; + + static void fillDescriptions(ConfigurationDescriptions &descriptions); + bool trackQualityCuts(int trk_nstub, float trk_chi2, float trk_bendchi2); + void L2_cluster(vector> L1TrkPtrs_, TrackJetEmulationMaxZBin &mzb); + virtual TrackJetEmulationEtaPhiBin *L1_cluster(TrackJetEmulationEtaPhiBin *phislice); + +private: + void beginStream(StreamID) override; + void produce(Event &, const EventSetup &) override; + void endStream() override; + + // ----------member data --------------------------- + + vector> L1TrkPtrs_; + vector zBinCount_; + vector tdtrk_; + const float MaxDzTrackPV; + const float trkZMax_; + const float trkPtMax_; + const float trkPtMin_; + const float trkEtaMax_; + const float trkChi2dofMax_; + const float trkBendChi2Max_; + const int trkNPSStubMin_; + const double minTrkJetpT_; + int etaBins_; + int phiBins_; + int zBins_; + float d0CutNStubs4_; + float d0CutNStubs5_; + int lowpTJetMinTrackMultiplicity_; + float lowpTJetMinpT_; + int highpTJetMinTrackMultiplicity_; + float highpTJetMinpT_; + bool displaced_; + float nStubs4DisplacedChi2_; + float nStubs5DisplacedChi2_; + float nStubs4DisplacedBend_; + float nStubs5DisplacedBend_; + int nDisplacedTracks_; + + float PVz; + z0_intern zStep_; + glbeta_intern etaStep_; + glbphi_intern phiStep_; + + const EDGetTokenT>> trackToken_; + const EDGetTokenT PVtxToken_; + ESGetToken tTopoToken_; +}; + +L1TrackJetEmulationProducer::L1TrackJetEmulationProducer(const ParameterSet &iConfig) + : MaxDzTrackPV((float)iConfig.getParameter("MaxDzTrackPV")), + trkZMax_((float)iConfig.getParameter("trk_zMax")), + trkPtMax_((float)iConfig.getParameter("trk_ptMax")), + trkPtMin_((float)iConfig.getParameter("trk_ptMin")), + trkEtaMax_((float)iConfig.getParameter("trk_etaMax")), + trkChi2dofMax_((float)iConfig.getParameter("trk_chi2dofMax")), + trkBendChi2Max_((float)iConfig.getParameter("trk_bendChi2Max")), + trkNPSStubMin_((int)iConfig.getParameter("trk_nPSStubMin")), + minTrkJetpT_(iConfig.getParameter("minTrkJetpT")), + etaBins_((int)iConfig.getParameter("etaBins")), + phiBins_((int)iConfig.getParameter("phiBins")), + zBins_((int)iConfig.getParameter("zBins")), + d0CutNStubs4_((float)iConfig.getParameter("d0_cutNStubs4")), + d0CutNStubs5_((float)iConfig.getParameter("d0_cutNStubs5")), + lowpTJetMinTrackMultiplicity_((int)iConfig.getParameter("lowpTJetMinTrackMultiplicity")), + lowpTJetMinpT_((float)iConfig.getParameter("lowpTJetMinpT")), + highpTJetMinTrackMultiplicity_((int)iConfig.getParameter("highpTJetMinTrackMultiplicity")), + highpTJetMinpT_((float)iConfig.getParameter("highpTJetMinpT")), + displaced_(iConfig.getParameter("displaced")), + nStubs4DisplacedChi2_((float)iConfig.getParameter("nStubs4DisplacedChi2")), + nStubs5DisplacedChi2_((float)iConfig.getParameter("nStubs5DisplacedChi2")), + nStubs4DisplacedBend_((float)iConfig.getParameter("nStubs4Displacedbend")), + nStubs5DisplacedBend_((float)iConfig.getParameter("nStubs5Displacedbend")), + nDisplacedTracks_((int)iConfig.getParameter("nDisplacedTracks")), + trackToken_(consumes>>(iConfig.getParameter("L1TrackInputTag"))), + PVtxToken_(consumes(iConfig.getParameter("VertexInputTag"))), + tTopoToken_(esConsumes(edm::ESInputTag("", ""))) { + zStep_ = convert::makeZ0(2.0 * trkZMax_ / (zBins_ + 1)); + etaStep_ = convert::makeGlbEta(2.0 * trkEtaMax_ / etaBins_); //etaStep is the width of an etabin + phiStep_ = convert::makeGlbPhi(2.0 * M_PI / phiBins_); ////phiStep is the width of a phibin + + if (displaced_) + produces("L1TrackJetsExtended"); + else + produces("L1TrackJets"); +} + +L1TrackJetEmulationProducer::~L1TrackJetEmulationProducer() {} + +void L1TrackJetEmulationProducer::produce(Event &iEvent, const EventSetup &iSetup) { + unique_ptr L1L1TrackJetProducer(new l1t::TkJetWordCollection); + + // For TTStubs + const TrackerTopology &tTopo = iSetup.getData(tTopoToken_); + + edm::Handle>> TTTrackHandle; + iEvent.getByToken(trackToken_, TTTrackHandle); + vector>::const_iterator iterL1Track; + + edm::Handle PVtx; + iEvent.getByToken(PVtxToken_, PVtx); + float PVz = (PVtx->at(0)).z0(); + + L1TrkPtrs_.clear(); + zBinCount_.clear(); + tdtrk_.clear(); + unsigned int this_l1track = 0; + for (iterL1Track = TTTrackHandle->begin(); iterL1Track != TTTrackHandle->end(); iterL1Track++) { + edm::Ptr trkPtr(TTTrackHandle, this_l1track); + this_l1track++; + float trk_pt = trkPtr->momentum().perp(); + int trk_nstubs = (int)trkPtr->getStubRefs().size(); + float trk_chi2dof = trkPtr->chi2Red(); + float trk_d0 = trkPtr->d0(); + float trk_bendchi2 = trkPtr->stubPtConsistency(); + float trk_z0 = trkPtr->z0(); + + int trk_nPS = 0; + for (int istub = 0; istub < trk_nstubs; istub++) { // loop over the stubs + DetId detId(trkPtr->getStubRefs().at(istub)->getDetId()); + if (detId.det() == DetId::Detector::Tracker) { + if ((detId.subdetId() == StripSubdetector::TOB && tTopo.tobLayer(detId) <= 3) || + (detId.subdetId() == StripSubdetector::TID && tTopo.tidRing(detId) <= 9)) + trk_nPS++; + } + } + + if (trk_nPS < trkNPSStubMin_) + continue; + if (!trackQualityCuts(trk_nstubs, trk_chi2dof, trk_bendchi2)) + continue; + if (std::abs(trk_z0 - PVz) > MaxDzTrackPV) + continue; + if (std::abs(trk_z0) > trkZMax_) + continue; + if (std::abs(trkPtr->momentum().eta()) > trkEtaMax_) + continue; + if (trk_pt < trkPtMin_) + continue; + L1TrkPtrs_.push_back(trkPtr); + zBinCount_.push_back(0); + + if ((std::abs(trk_d0) > d0CutNStubs5_ && trk_nstubs >= 5 && d0CutNStubs5_ >= 0) || + (trk_nstubs == 4 && std::abs(trk_d0) > d0CutNStubs4_ && d0CutNStubs4_ >= 0)) + tdtrk_.push_back(1); //displaced track + else + tdtrk_.push_back(0); // not displaced track + } + + if (!L1TrkPtrs_.empty()) { + TrackJetEmulationMaxZBin mzb; + + L2_cluster(L1TrkPtrs_, mzb); + if (mzb.clusters != nullptr) { + for (int j = 0; j < mzb.nclust; ++j) { + //FILL Two Layer Jets for Jet Collection + if (mzb.clusters[j].pTtot < convert::makePtFromFloat(trkPtMin_)) + continue; //protects against reading bad memory + if (mzb.clusters[j].ntracks < 1) + continue; + if (mzb.clusters[j].ntracks > 5000) + continue; + l1t::TkJetWord::glbeta_t jetEta = mzb.clusters[j].eta * convert::ETA_LSB_POW; + l1t::TkJetWord::glbphi_t jetPhi = mzb.clusters[j].phi * convert::PHI_LSB_POW; + l1t::TkJetWord::z0_t jetZ0 = mzb.zbincenter * convert::Z0_LSB_POW; + l1t::TkJetWord::pt_t jetPt = mzb.clusters[j].pTtot; + l1t::TkJetWord::nt_t totalntracks_ = mzb.clusters[j].ntracks; + l1t::TkJetWord::nx_t totalxtracks_ = mzb.clusters[j].nxtracks; + l1t::TkJetWord::tkjetunassigned_t unassigned_ = 0; + + l1t::TkJetWord trkJet(jetPt, jetEta, jetPhi, jetZ0, totalntracks_, totalxtracks_, unassigned_); + //trkJet.setDispCounters(DispCounters); + L1L1TrackJetProducer->push_back(trkJet); + } + } else if (mzb.clusters == nullptr) { + edm::LogWarning("L1TrackJetEmulationProducer") << "mzb.clusters Not Assigned!\n"; + } + + if (displaced_) + iEvent.put(std::move(L1L1TrackJetProducer), "L1TrackJetsExtended"); + else + iEvent.put(std::move(L1L1TrackJetProducer), "L1TrackJets"); + delete[] mzb.clusters; + } else if (L1TrkPtrs_.empty()) { + edm::LogWarning("L1TrackJetEmulationProducer") << "L1TrkPtrs Not Assigned!\n"; + } +} + +void L1TrackJetEmulationProducer::L2_cluster(vector> L1TrkPtrs_, TrackJetEmulationMaxZBin &mzb) { + enum TrackBitWidths { + kEtaSize = 16, // Width of z-position (40cm / 0.1) + kEtaMagSize = 3, // Width of z-position magnitude (signed) + kPtSize = 14, // Width of pt + kPtMagSize = 9, // Width of pt magnitude (unsigned) + kPhiSize = 12, + kPhiMagSize = 1, + }; + + const int nz = zBins_ + 1; + TrackJetEmulationMaxZBin all_zBins[nz]; + static TrackJetEmulationMaxZBin mzbtemp; + for (int z = 0; z < nz; ++z) + all_zBins[z] = mzbtemp; + + z0_intern zmin = convert::makeZ0(-1.0 * trkZMax_); + z0_intern zmax = zmin + 2 * zStep_; + + TrackJetEmulationEtaPhiBin epbins[phiBins_][etaBins_]; // create grid of phiBins + glbphi_intern phi = convert::makeGlbPhi(-1.0 * M_PI); + glbeta_intern eta; + glbeta_intern etamin, etamax, phimin, phimax; + for (int i = 0; i < phiBins_; ++i) { + eta = convert::makeGlbEta(-1.0 * trkEtaMax_); + for (int j = 0; j < etaBins_; ++j) { + phimin = phi; + phimax = phi + phiStep_; + etamin = eta; + eta = eta + etaStep_; + etamax = eta; + epbins[i][j].phi = (phimin + phimax) / 2; + epbins[i][j].eta = (etamin + etamax) / 2; + epbins[i][j].pTtot = 0; + epbins[i][j].ntracks = 0; + epbins[i][j].nxtracks = 0; + } // for each etabin + phi = phi + phiStep_; + } // for each phibin (finished creating epbins) + + mzb = all_zBins[0]; + mzb.ht = 0; + int ntracks = L1TrkPtrs_.size(); + // uninitalized arrays + TrackJetEmulationEtaPhiBin *L1clusters[phiBins_]; + TrackJetEmulationEtaPhiBin L2cluster[ntracks]; + + for (int zbin = 0; zbin < zBins_; ++zbin) { + for (int i = 0; i < phiBins_; ++i) { //First initialize pT, numtracks, used to 0 (or false) + for (int j = 0; j < etaBins_; ++j) { + epbins[i][j].pTtot = 0; + epbins[i][j].used = false; + epbins[i][j].ntracks = 0; + epbins[i][j].nxtracks = 0; + } //for each etabin + L1clusters[i] = epbins[i]; + } //for each phibin + + for (unsigned int k = 0; k < L1TrkPtrs_.size(); ++k) { + ap_ufixed inputTrkPt = 0; + inputTrkPt.V = L1TrkPtrs_[k]->getTrackWord()(TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, + TTTrack_TrackWord::TrackBitLocations::kRinvLSB); + pt_intern trkpt = inputTrkPt; + + ap_fixed trketainput = 0; + trketainput.V = L1TrkPtrs_[k]->getTrackWord()(TTTrack_TrackWord::TrackBitLocations::kTanlMSB, + TTTrack_TrackWord::TrackBitLocations::kTanlLSB); + ap_ufixed<64 + ETA_EXTRABITS, 32 + ETA_EXTRABITS> eta_conv = + 1.0 / convert::ETA_LSB; //conversion factor from input eta format to internal format + glbeta_intern trketa = eta_conv * trketainput; + + int Sector = L1TrkPtrs_[k]->phiSector(); + glbphi_intern trkphiSector = 0; + if (Sector < 5) { + trkphiSector = Sector * convert::makeGlbPhi(2.0 * M_PI / 9.0); + } else { + trkphiSector = + convert::makeGlbPhi(-1.0 * M_PI + M_PI / 9.0) + (Sector - 5) * convert::makeGlbPhi(2.0 * M_PI / 9.0); + } + + ap_fixed trkphiinput = 0; + trkphiinput.V = L1TrkPtrs_[k]->getTrackWord()(TTTrack_TrackWord::TrackBitLocations::kPhiMSB, + TTTrack_TrackWord::TrackBitLocations::kPhiLSB); + ap_ufixed<64 + PHI_EXTRABITS, 32 + PHI_EXTRABITS> phi_conv = + TTTrack_TrackWord::stepPhi0 / convert::PHI_LSB * + (1 << (TrackBitWidths::kPhiSize - TrackBitWidths::kPhiMagSize)); + //phi_conv is a conversion factor from input phi format to the internal format + glbeta_intern localphi = phi_conv * trkphiinput; + glbeta_intern trkphi = localphi + trkphiSector; + + ap_int inputTrkZ0 = L1TrkPtrs_[k]->getTrackWord()( + TTTrack_TrackWord::TrackBitLocations::kZ0MSB, TTTrack_TrackWord::TrackBitLocations::kZ0LSB); + ap_ufixed<32 + Z0_EXTRABITS, 1 + Z0_EXTRABITS> z0_conv = + TTTrack_TrackWord::stepZ0 / convert::Z0_LSB; //conversion factor from input z format to internal format + z0_intern trkZ = z0_conv * inputTrkZ0; + + for (int i = 0; i < phiBins_; ++i) { + for (int j = 0; j < etaBins_; ++j) { + L2cluster[k] = epbins[i][j]; + if ((zmin <= trkZ && zmax >= trkZ) && + ((epbins[i][j].eta - etaStep_ / 2 < trketa && epbins[i][j].eta + etaStep_ / 2 >= trketa) && + epbins[i][j].phi - phiStep_ / 2 < trkphi && epbins[i][j].phi + phiStep_ / 2 >= trkphi && + (zBinCount_[k] != 2))) { + zBinCount_.at(k) = zBinCount_.at(k) + 1; + + if (trkpt < convert::makePtFromFloat(trkPtMax_)) + epbins[i][j].pTtot += trkpt; + else + epbins[i][j].pTtot += convert::makePtFromFloat(trkPtMax_); + ++epbins[i][j].ntracks; + //x-bit is currently not used in firmware, so we leave nxtracks = 0 for now + } // if right bin + } // for each phibin: j loop + } // for each phibin: i loop + } // end loop over tracks + + for (int phislice = 0; phislice < phiBins_; ++phislice) { + L1clusters[phislice] = L1_cluster(epbins[phislice]); + for (int ind = 0; L1clusters[phislice][ind].pTtot != 0; ++ind) { + L1clusters[phislice][ind].used = false; + } + } + + //Create clusters array to hold output cluster data for Layer2; can't have more clusters than tracks. + //Find eta-phibin with maxpT, make center of cluster, add neighbors if not already used. + pt_intern hipT = 0; + int nclust = 0; + int phibin = 0; + int imax = -1; + int index1; //index of clusters array for each phislice + pt_intern E1 = 0; + pt_intern E0 = 0; + pt_intern E2 = 0; + l1t::TkJetWord::nt_t ntrk1, ntrk2; + l1t::TkJetWord::nx_t nxtrk1, nxtrk2; + int used1, used2, used3, used4; + + for (phibin = 0; phibin < phiBins_; ++phibin) { //Find eta-phibin with highest pT + while (true) { + hipT = 0; + for (index1 = 0; L1clusters[phibin][index1].pTtot > 0; ++index1) { + if (!L1clusters[phibin][index1].used && L1clusters[phibin][index1].pTtot >= hipT) { + hipT = L1clusters[phibin][index1].pTtot; + imax = index1; + } + } // for each index within the phibin + + if (hipT == 0) + break; // If highest pT is 0, all bins are used + E0 = hipT; // E0 is pT of first phibin of the cluster + E1 = 0; + E2 = 0; + ntrk1 = 0; + ntrk2 = 0; + nxtrk1 = 0; + nxtrk2 = 0; + L2cluster[nclust] = L1clusters[phibin][imax]; + + L1clusters[phibin][imax].used = true; + // Add pT of upper neighbor + // E1 is pT of the middle phibin (should be highest pT) + if (phibin != phiBins_ - 1) { + used1 = -1; + used2 = -1; + for (index1 = 0; L1clusters[phibin + 1][index1].pTtot != 0; ++index1) { + if (L1clusters[phibin + 1][index1].used) + continue; + if (L1clusters[phibin + 1][index1].eta - L1clusters[phibin][imax].eta <= 3 * etaStep_ / 2 && + L1clusters[phibin][imax].eta - L1clusters[phibin + 1][index1].eta <= 3 * etaStep_ / 2) { + E1 += L1clusters[phibin + 1][index1].pTtot; + ntrk1 += L1clusters[phibin + 1][index1].ntracks; + nxtrk1 += L1clusters[phibin + 1][index1].nxtracks; + if (used1 < 0) + used1 = index1; + else + used2 = index1; + } // if cluster is within one phibin + } // for each cluster in above phibin + + if (E1 < E0) { // if E1 isn't higher, E0 and E1 are their own cluster + L2cluster[nclust].pTtot += E1; + L2cluster[nclust].ntracks += ntrk1; + L2cluster[nclust].nxtracks += nxtrk1; + if (used1 >= 0) + L1clusters[phibin + 1][used1].used = true; + if (used2 >= 0) + L1clusters[phibin + 1][used2].used = true; + nclust++; + continue; + } + + if (phibin != phiBins_ - 2) { // E2 will be the pT of the third phibin (should be lower than E1) + used3 = -1; + used4 = -1; + for (index1 = 0; L1clusters[phibin + 2][index1].pTtot != 0; ++index1) { + if (L1clusters[phibin + 2][index1].used) + continue; + if (L1clusters[phibin + 2][index1].eta - L1clusters[phibin][imax].eta <= 3 * etaStep_ / 2 && + L1clusters[phibin][imax].eta - L1clusters[phibin + 2][index1].eta <= 3 * etaStep_ / 2) { + E2 += L1clusters[phibin + 2][index1].pTtot; + ntrk2 += L1clusters[phibin + 2][index1].ntracks; + nxtrk2 += L1clusters[phibin + 2][index1].nxtracks; + if (used3 < 0) + used3 = index1; + else + used4 = index1; + } + } + // if indeed E2 < E1, add E1 and E2 to E0, they're all a cluster together + // otherwise, E0 is its own cluster + if (E2 < E1) { + L2cluster[nclust].pTtot += E1 + E2; + L2cluster[nclust].ntracks += ntrk1 + ntrk2; + L2cluster[nclust].nxtracks += nxtrk1 + nxtrk2; + L2cluster[nclust].phi = L1clusters[phibin + 1][used1].phi; + if (used1 >= 0) + L1clusters[phibin + 1][used1].used = true; + if (used2 >= 0) + L1clusters[phibin + 1][used2].used = true; + if (used3 >= 0) + L1clusters[phibin + 2][used3].used = true; + if (used4 >= 0) + L1clusters[phibin + 2][used4].used = true; + } + nclust++; + continue; + } // end Not phiBins-2 + else { + L2cluster[nclust].pTtot += E1; + L2cluster[nclust].ntracks += ntrk1; + L2cluster[nclust].nxtracks += nxtrk1; + L2cluster[nclust].phi = L1clusters[phibin + 1][used1].phi; + if (used1 >= 0) + L1clusters[phibin + 1][used1].used = true; + if (used2 >= 0) + L1clusters[phibin + 1][used2].used = true; + nclust++; + continue; + } + } //End not last phibin(23) + else { //if it is phibin 23 + L1clusters[phibin][imax].used = true; + nclust++; + } + } // while hipT not 0 + } // for each phibin + + for (phibin = 0; phibin < phiBins_; ++phibin) + delete[] L1clusters[phibin]; + + // Now merge clusters, if necessary + for (int m = 0; m < nclust - 1; ++m) { + for (int n = m + 1; n < nclust; ++n) { + if (L2cluster[n].eta == L2cluster[m].eta && + ((L2cluster[n].phi - L2cluster[m].phi < 3 * phiStep_ / 2 && + L2cluster[m].phi - L2cluster[n].phi < 3 * phiStep_ / 2) || + (L2cluster[n].phi - L2cluster[m].phi > 2 * convert::makeGlbPhi(M_PI) - phiStep_ || + L2cluster[m].phi - L2cluster[n].phi > 2 * convert::makeGlbPhi(M_PI) - phiStep_))) { + if (L2cluster[n].pTtot > L2cluster[m].pTtot) { + L2cluster[m].phi = L2cluster[n].phi; + } + L2cluster[m].pTtot += L2cluster[n].pTtot; + L2cluster[m].ntracks += L2cluster[n].ntracks; + L2cluster[m].nxtracks += L2cluster[n].nxtracks; + for (int m1 = n; m1 < nclust - 1; ++m1) { + L2cluster[m1] = L2cluster[m1 + 1]; + } + nclust--; + m = -1; + break; //????? + } // end if clusters neighbor in eta + } + } // end for (m) loop + // sum up all pTs in this zbin to find ht + + pt_intern ht = 0; + for (int k = 0; k < nclust; ++k) { + if (L2cluster[k].pTtot > convert::makePtFromFloat(lowpTJetMinpT_) && + L2cluster[k].ntracks < lowpTJetMinTrackMultiplicity_) + continue; + if (L2cluster[k].pTtot > convert::makePtFromFloat(highpTJetMinpT_) && + L2cluster[k].ntracks < highpTJetMinTrackMultiplicity_) + continue; + if (L2cluster[k].pTtot > convert::makePtFromFloat(minTrkJetpT_)) + ht += L2cluster[k].pTtot; + } + // if ht is larger than previous max, this is the new vertex zbin + all_zBins[zbin].znum = zbin; + all_zBins[zbin].clusters = new TrackJetEmulationEtaPhiBin[nclust]; + all_zBins[zbin].nclust = nclust; + all_zBins[zbin].zbincenter = (zmin + zmax) / 2; + for (int k = 0; k < nclust; ++k) { + all_zBins[zbin].clusters[k].phi = L2cluster[k].phi; + all_zBins[zbin].clusters[k].eta = L2cluster[k].eta; + all_zBins[zbin].clusters[k].pTtot = L2cluster[k].pTtot; + all_zBins[zbin].clusters[k].ntracks = L2cluster[k].ntracks; + all_zBins[zbin].clusters[k].nxtracks = L2cluster[k].nxtracks; + } + all_zBins[zbin].ht = ht; + if (ht >= mzb.ht) { + mzb = all_zBins[zbin]; + mzb.zbincenter = (zmin + zmax) / 2; + } + // Prepare for next zbin! + zmin = zmin + zStep_; + zmax = zmax + zStep_; + } // for each zbin + + for (int zbin = 0; zbin < zBins_; ++zbin) { + if (zbin == mzb.znum) { + continue; + } + delete[] all_zBins[zbin].clusters; + } +} + +TrackJetEmulationEtaPhiBin *L1TrackJetEmulationProducer::L1_cluster(TrackJetEmulationEtaPhiBin *phislice) { + TrackJetEmulationEtaPhiBin *clusters = new TrackJetEmulationEtaPhiBin[etaBins_ / 2]; + for (int etabin = 0; etabin < etaBins_ / 2; ++etabin) { + clusters[etabin].pTtot = 0; + clusters[etabin].ntracks = 0; + clusters[etabin].nxtracks = 0; + clusters[etabin].phi = 0; + clusters[etabin].eta = 0; + clusters[etabin].used = false; + } + + if (clusters == nullptr) + edm::LogWarning("L1TrackJetEmulationProducer") << "Clusters memory not assigned!\n"; + + // Find eta-phibin with maxpT, make center of cluster, add neighbors if not already used + pt_intern my_pt, left_pt, right_pt, right2pt; + int nclust = 0; + right2pt = 0; + for (int etabin = 0; etabin < etaBins_; ++etabin) { + // assign values for my pT and neighbors' pT + if (phislice[etabin].used) + continue; + my_pt = phislice[etabin].pTtot; + if (etabin > 0 && !phislice[etabin - 1].used) { + left_pt = phislice[etabin - 1].pTtot; + } else + left_pt = 0; + if (etabin < etaBins_ - 1 && !phislice[etabin + 1].used) { + right_pt = phislice[etabin + 1].pTtot; + if (etabin < etaBins_ - 2 && !phislice[etabin + 2].used) { + right2pt = phislice[etabin + 2].pTtot; + } else + right2pt = 0; + } else + right_pt = 0; + + // if I'm not a cluster, move on + if (my_pt < left_pt || my_pt <= right_pt) { + // if unused pT in the left neighbor, spit it out as a cluster + if (left_pt > 0) { + clusters[nclust] = phislice[etabin - 1]; + phislice[etabin - 1].used = true; + nclust++; + } + continue; + } + + // I guess I'm a cluster-- should I use my right neighbor? + // Note: left neighbor will definitely be used because if it + // didn't belong to me it would have been used already + clusters[nclust] = phislice[etabin]; + phislice[etabin].used = true; + if (left_pt > 0) { + clusters[nclust].pTtot += left_pt; + clusters[nclust].ntracks += phislice[etabin - 1].ntracks; + clusters[nclust].nxtracks += phislice[etabin - 1].nxtracks; + } + if (my_pt >= right2pt && right_pt > 0) { + clusters[nclust].pTtot += right_pt; + clusters[nclust].ntracks += phislice[etabin + 1].ntracks; + clusters[nclust].nxtracks += phislice[etabin + 1].nxtracks; + phislice[etabin + 1].used = true; + } + nclust++; + } // for each etabin + + // Now merge clusters, if necessary + for (int m = 0; m < nclust - 1; ++m) { + if (clusters[m + 1].eta - clusters[m].eta < 3 * etaStep_ / 2 && + clusters[m].eta - clusters[m + 1].eta < 3 * etaStep_ / 2) { + if (clusters[m + 1].pTtot > clusters[m].pTtot) { + clusters[m].eta = clusters[m + 1].eta; + } + clusters[m].pTtot += clusters[m + 1].pTtot; + clusters[m].ntracks += clusters[m + 1].ntracks; // Previous version didn't add tracks when merging + clusters[m].nxtracks += clusters[m + 1].nxtracks; + for (int m1 = m + 1; m1 < nclust - 1; ++m1) + clusters[m1] = clusters[m1 + 1]; + nclust--; + m = -1; + } // end if clusters neighbor in eta + } // end for (m) loop + + for (int i = nclust; i < etaBins_ / 2; ++i) // zero out remaining unused clusters + clusters[i].pTtot = 0; + return clusters; +} + +void L1TrackJetEmulationProducer::beginStream(StreamID) {} + +void L1TrackJetEmulationProducer::endStream() {} + +bool L1TrackJetEmulationProducer::trackQualityCuts(int trk_nstub, float trk_chi2, float trk_bendchi2) { + bool PassQuality = false; + if (trk_bendchi2 < trkBendChi2Max_ && trk_chi2 < trkChi2dofMax_ && trk_nstub >= 4 && !displaced_) + PassQuality = true; + if (displaced_ && trk_bendchi2 < nStubs4DisplacedBend_ && trk_chi2 < nStubs4DisplacedChi2_ && trk_nstub == 4) + PassQuality = true; + if (displaced_ && trk_bendchi2 < nStubs5DisplacedBend_ && trk_chi2 < nStubs5DisplacedChi2_ && trk_nstub > 4) + PassQuality = true; + return PassQuality; +} + +void L1TrackJetEmulationProducer::fillDescriptions(ConfigurationDescriptions &descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1TrackJetEmulationProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.cc index 004ff56153ce1..9a46fe3704bd3 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.cc @@ -1,5 +1,7 @@ // Original Author: Rishi Patel +// Modifications: George Karathanasis, georgios.karathanasis@cern.ch, CU Boulder // Created: Wed, 01 Aug 2018 14:01:41 GMT +// Latest update: Nov 2021 (by GK) // // Track jets are clustered in a two-layer process, first by clustering in phi, // then by clustering in eta @@ -17,6 +19,7 @@ #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -26,7 +29,9 @@ #include "Geometry/CommonTopologies/interface/PixelGeomDetType.h" #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" -#include "L1Trigger/L1TTrackMatch/interface/L1TrackJetProducer.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" + +#include "L1TrackJetProducer.h" #include "TH1D.h" #include "TH2D.h" #include @@ -40,6 +45,7 @@ using namespace std; using namespace edm; using namespace l1t; + class L1TrackJetProducer : public stream::EDProducer<> { public: explicit L1TrackJetProducer(const ParameterSet &); @@ -48,10 +54,7 @@ class L1TrackJetProducer : public stream::EDProducer<> { typedef vector L1TTTrackCollectionType; static void fillDescriptions(ConfigurationDescriptions &descriptions); - bool trackQualityCuts(float trk_pt, int trk_nstub, float trk_chi2, float trk_bendchi2, float trk_d0); - void L2_cluster( - vector > L1TrkPtrs_, vector ttrk_, vector tdtrk_, vector ttdtrk_, MaxZBin &mzb); - virtual EtaPhiBin *L1_cluster(EtaPhiBin *phislice); + bool trackQualityCuts(int trk_nstub, float trk_chi2, float trk_bendchi2); private: void beginStream(StreamID) override; @@ -60,77 +63,74 @@ class L1TrackJetProducer : public stream::EDProducer<> { // ----------member data --------------------------- - const EDGetTokenT > > trackToken_; edm::ESGetToken tTopoToken_; - - vector > L1TrkPtrs_; - vector zBinCount_; - vector ttrk_; + const EDGetTokenT>> trackToken_; + const edm::EDGetTokenT> PVtxToken_; + vector> L1TrkPtrs_; vector tdtrk_; - vector ttdtrk_; float trkZMax_; float trkPtMax_; float trkPtMin_; float trkEtaMax_; - float trkChi2dofMax_; - float trkBendChi2Max_; + float nStubs4PromptChi2_; + float nStubs5PromptChi2_; + float nStubs4PromptBend_; + float nStubs5PromptBend_; int trkNPSStubMin_; int lowpTJetMinTrackMultiplicity_; + float lowpTJetThreshold_; int highpTJetMinTrackMultiplicity_; + float highpTJetThreshold_; int zBins_; int etaBins_; int phiBins_; double minTrkJetpT_; - double minJetEtLowPt_; - double minJetEtHighPt_; float zStep_; float etaStep_; float phiStep_; bool displaced_; float d0CutNStubs4_; float d0CutNStubs5_; - float nStubs4DisplacedChi2Loose_; - float nStubs5DisplacedChi2Loose_; - float nStubs4DisplacedBendLoose_; - float nStubs5DisplacedBendLoose_; - float nStubs4DisplacedChi2Tight_; - float nStubs5DisplacedChi2Tight_; - float nStubs4DisplacedBendTight_; - float nStubs5DisplacedBendTight_; + float nStubs4DisplacedChi2_; + float nStubs5DisplacedChi2_; + float nStubs4DisplacedBend_; + float nStubs5DisplacedBend_; + int nDisplacedTracks_; + float dzPVTrk_; }; L1TrackJetProducer::L1TrackJetProducer(const ParameterSet &iConfig) - : trackToken_( - consumes > >(iConfig.getParameter("L1TrackInputTag"))), - tTopoToken_(esConsumes(edm::ESInputTag("", ""))) { + : tTopoToken_(esConsumes(edm::ESInputTag("", ""))), + trackToken_(consumes>>(iConfig.getParameter("L1TrackInputTag"))), + PVtxToken_(consumes>(iConfig.getParameter("L1PVertexCollection"))) { trkZMax_ = (float)iConfig.getParameter("trk_zMax"); trkPtMax_ = (float)iConfig.getParameter("trk_ptMax"); trkPtMin_ = (float)iConfig.getParameter("trk_ptMin"); trkEtaMax_ = (float)iConfig.getParameter("trk_etaMax"); - trkChi2dofMax_ = (float)iConfig.getParameter("trk_chi2dofMax"); - trkBendChi2Max_ = (float)iConfig.getParameter("trk_bendChi2Max"); + nStubs4PromptChi2_ = (float)iConfig.getParameter("nStubs4PromptChi2"); + nStubs5PromptChi2_ = (float)iConfig.getParameter("nStubs5PromptChi2"); + nStubs4PromptBend_ = (float)iConfig.getParameter("nStubs4PromptBend"); + nStubs5PromptBend_ = (float)iConfig.getParameter("nStubs5PromptBend"); trkNPSStubMin_ = (int)iConfig.getParameter("trk_nPSStubMin"); minTrkJetpT_ = iConfig.getParameter("minTrkJetpT"); - minJetEtLowPt_ = iConfig.getParameter("minJetEtLowPt"); - minJetEtHighPt_ = iConfig.getParameter("minJetEtHighPt"); etaBins_ = (int)iConfig.getParameter("etaBins"); phiBins_ = (int)iConfig.getParameter("phiBins"); zBins_ = (int)iConfig.getParameter("zBins"); d0CutNStubs4_ = (float)iConfig.getParameter("d0_cutNStubs4"); d0CutNStubs5_ = (float)iConfig.getParameter("d0_cutNStubs5"); lowpTJetMinTrackMultiplicity_ = (int)iConfig.getParameter("lowpTJetMinTrackMultiplicity"); + lowpTJetThreshold_ = (float)iConfig.getParameter("lowpTJetThreshold"); highpTJetMinTrackMultiplicity_ = (int)iConfig.getParameter("highpTJetMinTrackMultiplicity"); + highpTJetThreshold_ = (float)iConfig.getParameter("highpTJetThreshold"); displaced_ = iConfig.getParameter("displaced"); - nStubs4DisplacedChi2Loose_ = (float)iConfig.getParameter("nStubs4DisplacedChi2_Loose"); - nStubs5DisplacedChi2Loose_ = (float)iConfig.getParameter("nStubs5DisplacedChi2_Loose"); - nStubs4DisplacedBendLoose_ = (float)iConfig.getParameter("nStubs4Displacedbend_Loose"); - nStubs5DisplacedBendLoose_ = (float)iConfig.getParameter("nStubs5Displacedbend_Loose"); - nStubs4DisplacedChi2Tight_ = (float)iConfig.getParameter("nStubs4DisplacedChi2_Tight"); - nStubs5DisplacedChi2Tight_ = (float)iConfig.getParameter("nStubs5DisplacedChi2_Tight"); - nStubs4DisplacedBendTight_ = (float)iConfig.getParameter("nStubs4Displacedbend_Tight"); - nStubs5DisplacedBendTight_ = (float)iConfig.getParameter("nStubs5Displacedbend_Tight"); - - zStep_ = 2.0 * trkZMax_ / zBins_; + nStubs4DisplacedChi2_ = (float)iConfig.getParameter("nStubs4DisplacedChi2"); + nStubs5DisplacedChi2_ = (float)iConfig.getParameter("nStubs5DisplacedChi2"); + nStubs4DisplacedBend_ = (float)iConfig.getParameter("nStubs4DisplacedBend"); + nStubs5DisplacedBend_ = (float)iConfig.getParameter("nStubs5DisplacedBend"); + nDisplacedTracks_ = (int)iConfig.getParameter("nDisplacedTracks"); + dzPVTrk_ = (float)iConfig.getParameter("MaxDzTrackPV"); + + zStep_ = 2.0 * trkZMax_ / (zBins_ + 1); // added +1 in denom etaStep_ = 2.0 * trkEtaMax_ / etaBins_; //etaStep is the width of an etabin phiStep_ = 2 * M_PI / phiBins_; ////phiStep is the width of a phibin @@ -145,23 +145,21 @@ L1TrackJetProducer::~L1TrackJetProducer() {} void L1TrackJetProducer::produce(Event &iEvent, const EventSetup &iSetup) { unique_ptr L1L1TrackJetProducer(new TkJetCollection); - // For TTStubs - const TrackerTopology &tTopo = iSetup.getData(tTopoToken_); + // Read inputs + const TrackerTopology& tTopo = iSetup.getData(tTopoToken_); - edm::Handle > > TTTrackHandle; + edm::Handle>> TTTrackHandle; iEvent.getByToken(trackToken_, TTTrackHandle); - vector >::const_iterator iterL1Track; + + edm::Handle> PVtx; + iEvent.getByToken(PVtxToken_, PVtx); + float PVz = (PVtx->at(0)).z0(); L1TrkPtrs_.clear(); - zBinCount_.clear(); - ttrk_.clear(); tdtrk_.clear(); - ttdtrk_.clear(); - unsigned int this_l1track = 0; - for (iterL1Track = TTTrackHandle->begin(); iterL1Track != TTTrackHandle->end(); iterL1Track++) { + for (unsigned int this_l1track = 0; this_l1track < TTTrackHandle->size(); this_l1track++) { edm::Ptr trkPtr(TTTrackHandle, this_l1track); - this_l1track++; float trk_pt = trkPtr->momentum().perp(); int trk_nstubs = (int)trkPtr->getStubRefs().size(); float trk_chi2dof = trkPtr->chi2Red(); @@ -177,485 +175,199 @@ void L1TrackJetProducer::produce(Event &iEvent, const EventSetup &iSetup) { trk_nPS++; } } - + // select tracks if (trk_nPS < trkNPSStubMin_) continue; - if (!trackQualityCuts(trk_pt, trk_nstubs, trk_chi2dof, trk_bendchi2, fabs(trk_d0))) + if (!trackQualityCuts(trk_nstubs, trk_chi2dof, trk_bendchi2)) + continue; + if (std::abs(PVz - trkPtr->z0()) > dzPVTrk_ && dzPVTrk_ > 0) continue; - if (fabs(iterL1Track->z0()) > trkZMax_) + if (std::abs(trkPtr->z0()) > trkZMax_) continue; - if (fabs(iterL1Track->momentum().eta()) > trkEtaMax_) + if (std::abs(trkPtr->momentum().eta()) > trkEtaMax_) continue; if (trk_pt < trkPtMin_) continue; L1TrkPtrs_.push_back(trkPtr); - zBinCount_.push_back(0); - if ((fabs(trk_d0) > d0CutNStubs5_ && trk_nstubs >= 5) || (trk_nstubs == 4 && fabs(trk_d0) > d0CutNStubs4_)) - tdtrk_.push_back(1); - else - tdtrk_.push_back(0); //displaced track - if ((trk_nstubs >= 5 && trk_chi2dof < nStubs5DisplacedChi2Tight_ && trk_bendchi2 < nStubs5DisplacedBendTight_) || - (trk_nstubs == 4 && trk_chi2dof < nStubs4DisplacedChi2Tight_ && trk_bendchi2 < nStubs4DisplacedBendTight_)) - ttrk_.push_back(1); - else - ttrk_.push_back(0); - if ((trk_nstubs >= 5 && trk_chi2dof < nStubs5DisplacedChi2Tight_ && trk_bendchi2 < nStubs5DisplacedBendTight_ && - fabs(trk_d0) > d0CutNStubs5_) || - (trk_nstubs == 4 && trk_chi2dof < nStubs4DisplacedChi2Tight_ && trk_bendchi2 < nStubs4DisplacedBendTight_ && - fabs(trk_d0) > d0CutNStubs4_)) - ttdtrk_.push_back(1); + if ((std::abs(trk_d0) > d0CutNStubs5_ && trk_nstubs >= 5 && d0CutNStubs5_ >= 0) || + (trk_nstubs == 4 && std::abs(trk_d0) > d0CutNStubs4_ && d0CutNStubs4_ >= 0)) + tdtrk_.push_back(1); //displaced track else - ttdtrk_.push_back(0); + tdtrk_.push_back(0); // not displaced track } if (!L1TrkPtrs_.empty()) { MaxZBin mzb; + mzb.znum = -1; + mzb.nclust = -1; + mzb.ht = -1; + EtaPhiBin epbins_default[phiBins_][etaBins_]; // create grid of phiBins + + float phi = -1.0 * M_PI; + float eta = -1.0 * trkEtaMax_; + for (int i = 0; i < phiBins_; ++i) { + eta = -1.0 * trkEtaMax_; + for (int j = 0; j < etaBins_; ++j) { + epbins_default[i][j].phi = (phi + (phi + phiStep_)) / 2.0; // phimin=phi; phimax= phimin+step + epbins_default[i][j].eta = (eta + (eta + etaStep_)) / 2.0; // phimin=phi; phimax phimin+step + eta += etaStep_; + } // for each etabin + phi += phiStep_; + } // for each phibin (finished creating epbins) + + std::vector zmins, zmaxs; + for (int zbin = 0; zbin < zBins_; zbin++) { + zmins.push_back(-1.0 * trkZMax_ + zStep_ * zbin); + zmaxs.push_back(-1.0 * trkZMax_ + zStep_ * zbin + zStep_ * 2); + } - L2_cluster(L1TrkPtrs_, ttrk_, tdtrk_, ttdtrk_, mzb); - edm::Ref jetRef; //null, no Calo Jet Ref - vector > L1TrackAssocJet; - if (mzb.clusters != nullptr) { - for (int j = 0; j < mzb.nclust; ++j) { - //FILL Two Layer Jets for Jet Collection - if (mzb.clusters[j].pTtot <= trkPtMin_) - continue; //protects against reading bad memory - if (mzb.clusters[j].numtracks < 1) - continue; - if (mzb.clusters[j].numtracks > 5000) - continue; - float jetEta = mzb.clusters[j].eta; - float jetPhi = mzb.clusters[j].phi; - float jetPt = mzb.clusters[j].pTtot; - float jetPx = jetPt * cos(jetPhi); - float jetPy = jetPt * sin(jetPhi); - float jetPz = jetPt * sinh(jetEta); - float jetP = jetPt * cosh(jetEta); - int totalTighttrk_ = mzb.clusters[j].numttrks; - int totalDisptrk = mzb.clusters[j].numtdtrks; - int totalTightDisptrk = mzb.clusters[j].numttdtrks; - - math::XYZTLorentzVector jetP4(jetPx, jetPy, jetPz, jetP); - L1TrackAssocJet.clear(); - for (unsigned int t = 0; t < L1TrkPtrs_.size(); ++t) { - if (L1TrackAssocJet.size() == (unsigned int)mzb.clusters[j].numtracks) - break; - float deta = L1TrkPtrs_[t]->momentum().eta() - jetEta; - float dphi = L1TrkPtrs_[t]->momentum().phi() - jetPhi; - float dZ = fabs(mzb.zbincenter - L1TrkPtrs_[t]->z0()); - if (dZ < zStep_ && fabs(deta) < etaStep_ * 2.0 && fabs(dphi) < phiStep_ * 2.0) { - L1TrackAssocJet.push_back(L1TrkPtrs_[t]); - } - } - TkJet trkJet(jetP4, - L1TrackAssocJet, - mzb.zbincenter, - mzb.clusters[j].numtracks, - totalTighttrk_, - totalDisptrk, - totalTightDisptrk); - //trkJet.setDispCounters(DispCounters); - if (!L1TrackAssocJet.empty()) - L1L1TrackJetProducer->push_back(trkJet); + // create vectors that hold data + std::vector> L1clusters; + L1clusters.reserve(phiBins_); + std::vector L2clusters; + + for (int i = 0; i < phiBins_; ++i) { + for (int j = 0; j < etaBins_; ++j) { + epbins_default[i][j].pTtot = 0; + epbins_default[i][j].used = false; + epbins_default[i][j].numtracks = 0; + epbins_default[i][j].numttrks = 0; + epbins_default[i][j].numtdtrks = 0; + epbins_default[i][j].numttdtrks = 0; + epbins_default[i][j].trackidx.clear(); } } - //free(mzb.clusters); - if (displaced_) - iEvent.put(std::move(L1L1TrackJetProducer), "L1TrackJetsExtended"); - else - iEvent.put(std::move(L1L1TrackJetProducer), "L1TrackJets"); - delete[] mzb.clusters; - } -} -void L1TrackJetProducer::L2_cluster( - vector > L1TrkPtrs_, vector ttrk_, vector tdtrk_, vector ttdtrk_, MaxZBin &mzb) { - const int nz = zBins_; - MaxZBin all_zBins[nz]; - for (int z = 0; z < nz; ++z) - all_zBins[z] = MaxZBin{0, 0, 0, nullptr, 0}; - - float zmin = -1.0 * trkZMax_; - float zmax = zmin + 2 * zStep_; - - EtaPhiBin epbins[phiBins_][etaBins_]; // create grid of phiBins - float phi = -1.0 * M_PI; - float eta; - float etamin, etamax, phimin, phimax; - for (int i = 0; i < phiBins_; ++i) { - eta = -1.0 * trkEtaMax_; - for (int j = 0; j < etaBins_; ++j) { - phimin = phi; - phimax = phi + phiStep_; - etamin = eta; - eta = eta + etaStep_; - etamax = eta; - epbins[i][j].phi = (phimin + phimax) / 2.0; - epbins[i][j].eta = (etamin + etamax) / 2.0; - } // for each etabin - phi = phi + phiStep_; - } // for each phibin (finished creating epbins) - mzb = all_zBins[0]; - int ntracks = L1TrkPtrs_.size(); - // uninitalized arrays - EtaPhiBin *L1clusters[phiBins_]; - EtaPhiBin L2cluster[ntracks]; - - for (int zbin = 0; zbin < zBins_ - 1; ++zbin) { - for (int i = 0; i < phiBins_; ++i) { //First initialize pT, numtracks, used to 0 (or false) - for (int j = 0; j < etaBins_; ++j) { - epbins[i][j].pTtot = 0; - epbins[i][j].used = false; - epbins[i][j].numtracks = 0; - epbins[i][j].numttrks = 0; - epbins[i][j].numtdtrks = 0; - epbins[i][j].numttdtrks = 0; - } //for each etabin - L1clusters[i] = epbins[i]; - } //for each phibin - - for (unsigned int k = 0; k < L1TrkPtrs_.size(); ++k) { - float trkpt = L1TrkPtrs_[k]->momentum().perp(); - float trketa = L1TrkPtrs_[k]->momentum().eta(); - float trkphi = L1TrkPtrs_[k]->momentum().phi(); - float trkZ = L1TrkPtrs_[k]->z0(); - - for (int i = 0; i < phiBins_; ++i) { - for (int j = 0; j < etaBins_; ++j) { - L2cluster[k] = epbins[i][j]; - if ((zmin <= trkZ && zmax >= trkZ) && - ((epbins[i][j].eta - etaStep_ / 2.0 <= trketa && epbins[i][j].eta + etaStep_ / 2.0 >= trketa) && - epbins[i][j].phi - phiStep_ / 2.0 <= trkphi && epbins[i][j].phi + phiStep_ / 2.0 >= trkphi && - (zBinCount_[k] != 2))) { - zBinCount_.at(k) = zBinCount_.at(k) + 1; + for (unsigned int zbin = 0; zbin < zmins.size(); ++zbin) { + // initialize matrices + float zmin = zmins[zbin]; + float zmax = zmaxs[zbin]; + EtaPhiBin epbins[phiBins_][etaBins_]; + std::copy(&epbins_default[0][0], &epbins_default[0][0] + phiBins_ * etaBins_, &epbins[0][0]); + + //clear containers + L1clusters.clear(); + L2clusters.clear(); + + // fill grid + for (unsigned int k = 0; k < L1TrkPtrs_.size(); ++k) { + float trkpt = L1TrkPtrs_[k]->momentum().perp(); + float trketa = L1TrkPtrs_[k]->momentum().eta(); + float trkphi = L1TrkPtrs_[k]->momentum().phi(); + float trkZ = L1TrkPtrs_[k]->z0(); + if (zmax < trkZ) + continue; + if (zbin == 0) { + if (zmin > trkZ) + continue; + } else { + if (zmin >= trkZ) + continue; + } + for (int i = 0; i < phiBins_; ++i) { + for (int j = 0; j < etaBins_; ++j) { + float eta_min = epbins[i][j].eta - etaStep_ / 2.0; //eta min + float eta_max = epbins[i][j].eta + etaStep_ / 2.0; //eta max + float phi_min = epbins[i][j].phi - phiStep_ / 2.0; //phi min + float phi_max = epbins[i][j].phi + phiStep_ / 2.0; //phi max + + if ((trketa < eta_min) || (trketa > eta_max) || (trkphi < phi_min) || (trkphi > phi_max)) + continue; + if (trkpt < trkPtMax_) epbins[i][j].pTtot += trkpt; else epbins[i][j].pTtot += trkPtMax_; - epbins[i][j].numttrks += ttrk_[k]; epbins[i][j].numtdtrks += tdtrk_[k]; - epbins[i][j].numttdtrks += ttdtrk_[k]; + epbins[i][j].trackidx.push_back(k); ++epbins[i][j].numtracks; - } // if right bin - } // for each phibin: j loop - } // for each phibin: i loop - } // end loop over tracks - - for (int phislice = 0; phislice < phiBins_; ++phislice) { - L1clusters[phislice] = L1_cluster(epbins[phislice]); - if (L1clusters[phislice] != nullptr) { - for (int ind = 0; L1clusters[phislice][ind].pTtot != 0; ++ind) { - L1clusters[phislice][ind].used = false; - } - } - } + } // for each phibin + } // for each phibin + } //end loop over tracks - //Create clusters array to hold output cluster data for Layer2; can't have more clusters than tracks. - //Find eta-phibin with maxpT, make center of cluster, add neighbors if not already used. - float hipT = 0; - int nclust = 0; - int phibin = 0; - int imax = -1; - int index1; //index of clusters array for each phislice - float E1 = 0; - float E0 = 0; - float E2 = 0; - int trx1, trx2; - int ttrk1, ttrk2; - int tdtrk1, tdtrk2; - int ttdtrk1, ttdtrk2; - int used1, used2, used3, used4; - - for (phibin = 0; phibin < phiBins_; ++phibin) { //Find eta-phibin with highest pT - while (true) { - hipT = 0; - for (index1 = 0; L1clusters[phibin][index1].pTtot > 0; ++index1) { - if (!L1clusters[phibin][index1].used && L1clusters[phibin][index1].pTtot >= hipT) { - hipT = L1clusters[phibin][index1].pTtot; - imax = index1; - } - } // for each index within the phibin - - if (hipT == 0) - break; // If highest pT is 0, all bins are used - E0 = hipT; // E0 is pT of first phibin of the cluster - E1 = 0; - E2 = 0; - trx1 = 0; - trx2 = 0; - ttrk1 = 0; - ttrk2 = 0; - tdtrk1 = 0; - tdtrk2 = 0; - ttdtrk1 = 0; - ttdtrk2 = 0; - L2cluster[nclust] = L1clusters[phibin][imax]; - L1clusters[phibin][imax].used = true; - // Add pT of upper neighbor - // E1 is pT of the middle phibin (should be highest pT) - if (phibin != phiBins_ - 1) { - used1 = -1; - used2 = -1; - for (index1 = 0; L1clusters[phibin + 1][index1].pTtot != 0; ++index1) { - if (L1clusters[phibin + 1][index1].used) - continue; - if (fabs(L1clusters[phibin + 1][index1].eta - L1clusters[phibin][imax].eta) <= 1.5 * etaStep_) { - E1 += L1clusters[phibin + 1][index1].pTtot; - trx1 += L1clusters[phibin + 1][index1].numtracks; - ttrk1 += L1clusters[phibin + 1][index1].numttrks; - tdtrk1 += L1clusters[phibin + 1][index1].numtdtrks; - ttdtrk1 += L1clusters[phibin + 1][index1].numttdtrks; - if (used1 < 0) - used1 = index1; - else - used2 = index1; - } // if cluster is within one phibin - } // for each cluster in above phibin - - if (E1 < E0) { // if E1 isn't higher, E0 and E1 are their own cluster - L2cluster[nclust].pTtot += E1; - L2cluster[nclust].numtracks += trx1; - L2cluster[nclust].numttrks += ttrk1; - L2cluster[nclust].numtdtrks += tdtrk1; - L2cluster[nclust].numttdtrks += ttdtrk1; - if (used1 >= 0) - L1clusters[phibin + 1][used1].used = true; - if (used2 >= 0) - L1clusters[phibin + 1][used2].used = true; - nclust++; - continue; - } - - if (phibin != phiBins_ - 2) { // E2 will be the pT of the third phibin (should be lower than E1) - used3 = -1; - used4 = -1; - for (index1 = 0; L1clusters[phibin + 2][index1].pTtot != 0; ++index1) { - if (L1clusters[phibin + 2][index1].used) - continue; - if (fabs(L1clusters[phibin + 2][index1].eta - L1clusters[phibin][imax].eta) <= 1.5 * etaStep_) { - E2 += L1clusters[phibin + 2][index1].pTtot; - trx2 += L1clusters[phibin + 2][index1].numtracks; - ttrk2 += L1clusters[phibin + 2][index1].numttrks; - tdtrk2 += L1clusters[phibin + 2][index1].numtdtrks; - ttdtrk2 += L1clusters[phibin + 2][index1].numttdtrks; - if (used3 < 0) - used3 = index1; - else - used4 = index1; - } - } - // if indeed E2 < E1, add E1 and E2 to E0, they're all a cluster together - // otherwise, E0 is its own cluster - if (E2 < E1) { - L2cluster[nclust].pTtot += E1 + E2; - L2cluster[nclust].numtracks += trx1 + trx2; - L2cluster[nclust].numttrks += ttrk1 + ttrk2; - L2cluster[nclust].numtdtrks += tdtrk1 + tdtrk2; - L2cluster[nclust].numttdtrks += ttdtrk1 + ttdtrk2; - L2cluster[nclust].phi = L1clusters[phibin + 1][used1].phi; - if (used1 >= 0) - L1clusters[phibin + 1][used1].used = true; - if (used2 >= 0) - L1clusters[phibin + 1][used2].used = true; - if (used3 >= 0) - L1clusters[phibin + 2][used3].used = true; - if (used4 >= 0) - L1clusters[phibin + 2][used4].used = true; - } - nclust++; - continue; - } // end Not phiBins-2 - else { - L2cluster[nclust].pTtot += E1; - L2cluster[nclust].numtracks += trx1; - L2cluster[nclust].numttrks += ttrk1; - L2cluster[nclust].numtdtrks += tdtrk1; - L2cluster[nclust].numttdtrks += ttdtrk1; - L2cluster[nclust].phi = L1clusters[phibin + 1][used1].phi; - if (used1 >= 0) - L1clusters[phibin + 1][used1].used = true; - if (used2 >= 0) - L1clusters[phibin + 1][used2].used = true; - nclust++; - continue; - } - } //End not last phibin(23) - else { //if it is phibin 23 - L1clusters[phibin][imax].used = true; - nclust++; - } - } // while hipT not 0 - } // for each phibin - - for (phibin = 0; phibin < phiBins_; ++phibin) - delete[] L1clusters[phibin]; - - // Now merge clusters, if necessary - for (int m = 0; m < nclust - 1; ++m) { - for (int n = m + 1; n < nclust; ++n) - if (L2cluster[n].eta == L2cluster[m].eta && (fabs(L2cluster[n].phi - L2cluster[m].phi) < 1.5 * phiStep_ || - fabs(L2cluster[n].phi - L2cluster[m].phi) > 6.0)) { - if (L2cluster[n].pTtot > L2cluster[m].pTtot) - L2cluster[m].phi = L2cluster[n].phi; - L2cluster[m].pTtot += L2cluster[n].pTtot; - L2cluster[m].numtracks += L2cluster[n].numtracks; - L2cluster[m].numttrks += L2cluster[n].numttrks; - L2cluster[m].numtdtrks += L2cluster[n].numtdtrks; - L2cluster[m].numttdtrks += L2cluster[n].numttdtrks; - for (int m1 = n; m1 < nclust - 1; ++m1) - L2cluster[m1] = L2cluster[m1 + 1]; - nclust--; - m = -1; - break; //????? - } // end if clusters neighbor in eta - } // end for (m) loop - - // sum up all pTs in this zbin to find ht - float ht = 0; - for (int k = 0; k < nclust; ++k) { - if (L2cluster[k].pTtot > minJetEtLowPt_ && L2cluster[k].numtracks < lowpTJetMinTrackMultiplicity_) - continue; - if (L2cluster[k].pTtot > minJetEtHighPt_ && L2cluster[k].numtracks < highpTJetMinTrackMultiplicity_) - continue; - if (L2cluster[k].pTtot > minTrkJetpT_) - ht += L2cluster[k].pTtot; - } + // first layer clustering - in eta for all phi bins + for (int phibin = 0; phibin < phiBins_; ++phibin) { + L1clusters.push_back(L1_clustering(epbins[phibin], etaBins_, etaStep_)); + } - // if ht is larger than previous max, this is the new vertex zbin - all_zBins[zbin].znum = zbin; - all_zBins[zbin].clusters = new EtaPhiBin[nclust]; - all_zBins[zbin].nclust = nclust; - all_zBins[zbin].zbincenter = (zmin + zmax) / 2.0; - for (int k = 0; k < nclust; ++k) { - all_zBins[zbin].clusters[k].phi = L2cluster[k].phi; - all_zBins[zbin].clusters[k].eta = L2cluster[k].eta; - all_zBins[zbin].clusters[k].pTtot = L2cluster[k].pTtot; - all_zBins[zbin].clusters[k].numtracks = L2cluster[k].numtracks; - all_zBins[zbin].clusters[k].numttrks = L2cluster[k].numttrks; - all_zBins[zbin].clusters[k].numtdtrks = L2cluster[k].numtdtrks; - all_zBins[zbin].clusters[k].numttdtrks = L2cluster[k].numttdtrks; - } - all_zBins[zbin].ht = ht; - if (ht >= mzb.ht) { - mzb = all_zBins[zbin]; - mzb.zbincenter = (zmin + zmax) / 2.0; - } - // Prepare for next zbin! - zmin = zmin + zStep_; - zmax = zmax + zStep_; - } // for each zbin - for (int zbin = 0; zbin < zBins_ - 1; ++zbin) { - if (zbin == mzb.znum) - continue; - delete[] all_zBins[zbin].clusters; - } -} + //second layer clustering in phi for all eta clusters + L2clusters = L2_clustering(L1clusters, phiBins_, phiStep_, etaStep_); -EtaPhiBin *L1TrackJetProducer::L1_cluster(EtaPhiBin *phislice) { - EtaPhiBin *clusters = new EtaPhiBin[etaBins_ / 2]; - if (clusters == nullptr) - edm::LogWarning("L1TrackJetProducer") << "Clusters memory not assigned!\n"; - - // Find eta-phibin with maxpT, make center of cluster, add neighbors if not already used - float my_pt, left_pt, right_pt, right2pt; - int nclust = 0; - right2pt = 0; - for (int etabin = 0; etabin < etaBins_; ++etabin) { - // assign values for my pT and neighbors' pT - if (phislice[etabin].used) - continue; - my_pt = phislice[etabin].pTtot; - if (etabin > 0 && !phislice[etabin - 1].used) { - left_pt = phislice[etabin - 1].pTtot; - } else - left_pt = 0; - if (etabin < etaBins_ - 1 && !phislice[etabin + 1].used) { - right_pt = phislice[etabin + 1].pTtot; - if (etabin < etaBins_ - 2 && !phislice[etabin + 2].used) { - right2pt = phislice[etabin + 2].pTtot; - } else - right2pt = 0; - } else - right_pt = 0; - - // if I'm not a cluster, move on - if (my_pt < left_pt || my_pt <= right_pt) { - // if unused pT in the left neighbor, spit it out as a cluster - if (left_pt > 0) { - clusters[nclust] = phislice[etabin - 1]; - phislice[etabin - 1].used = true; - nclust++; + // sum all cluster pTs in this zbin to find max + float sum_pt = 0; + for (unsigned int k = 0; k < L2clusters.size(); ++k) { + if (L2clusters[k].pTtot > lowpTJetThreshold_ && L2clusters[k].numtracks < lowpTJetMinTrackMultiplicity_) + continue; + if (L2clusters[k].pTtot > highpTJetThreshold_ && L2clusters[k].numtracks < highpTJetMinTrackMultiplicity_) + continue; + if (L2clusters[k].pTtot > minTrkJetpT_) + sum_pt += L2clusters[k].pTtot; } - continue; - } - // I guess I'm a cluster-- should I use my right neighbor? - // Note: left neighbor will definitely be used because if it - // didn't belong to me it would have been used already - clusters[nclust] = phislice[etabin]; - phislice[etabin].used = true; - if (left_pt > 0) { - if (clusters != nullptr) { - clusters[nclust].pTtot += left_pt; - clusters[nclust].numtracks += phislice[etabin - 1].numtracks; - clusters[nclust].numttrks += phislice[etabin - 1].numttrks; - clusters[nclust].numtdtrks += phislice[etabin - 1].numtdtrks; - clusters[nclust].numttdtrks += phislice[etabin - 1].numttdtrks; - } - } - if (my_pt >= right2pt && right_pt > 0) { - if (clusters != nullptr) { - clusters[nclust].pTtot += right_pt; - clusters[nclust].numtracks += phislice[etabin + 1].numtracks; - clusters[nclust].numttrks += phislice[etabin + 1].numttrks; - clusters[nclust].numtdtrks += phislice[etabin + 1].numtdtrks; - clusters[nclust].numttdtrks += phislice[etabin + 1].numttdtrks; - phislice[etabin + 1].used = true; - } + if (sum_pt < mzb.ht) + continue; + // if ht is larger than previous max, this is the new vertex zbin + mzb.ht = sum_pt; + mzb.znum = zbin; + mzb.clusters = L2clusters; + mzb.nclust = L2clusters.size(); + mzb.zbincenter = (zmin + zmax) / 2.0; + } //zbin loop + + vector> L1TrackAssocJet; + for (unsigned int j = 0; j < mzb.clusters.size(); ++j) { + float jetEta = mzb.clusters[j].eta; + float jetPhi = mzb.clusters[j].phi; + float jetPt = mzb.clusters[j].pTtot; + float jetPx = jetPt * cos(jetPhi); + float jetPy = jetPt * sin(jetPhi); + float jetPz = jetPt * sinh(jetEta); + float jetP = jetPt * cosh(jetEta); + int totalDisptrk = mzb.clusters[j].numtdtrks; + bool isDispJet = false; + if (totalDisptrk > nDisplacedTracks_ || totalDisptrk == nDisplacedTracks_) + isDispJet = true; + + math::XYZTLorentzVector jetP4(jetPx, jetPy, jetPz, jetP); + L1TrackAssocJet.clear(); + for (unsigned int itrk = 0; itrk < mzb.clusters[j].trackidx.size(); itrk++) + L1TrackAssocJet.push_back(L1TrkPtrs_[mzb.clusters[j].trackidx[itrk]]); + + TkJet trkJet(jetP4, L1TrackAssocJet, mzb.zbincenter, mzb.clusters[j].numtracks, 0, totalDisptrk, 0, isDispJet); + + if (!L1TrackAssocJet.empty()) + L1L1TrackJetProducer->push_back(trkJet); } - nclust++; - } // for each etabin - - // Now merge clusters, if necessary - for (int m = 0; m < nclust - 1; ++m) { - if (fabs(clusters[m + 1].eta - clusters[m].eta) < 1.5 * etaStep_) { - if (clusters[m + 1].pTtot > clusters[m].pTtot) { - clusters[m].eta = clusters[m + 1].eta; - } - clusters[m].pTtot += clusters[m + 1].pTtot; - clusters[m].numtracks += clusters[m + 1].numtracks; // Previous version didn't add tracks when merging - clusters[m].numttrks += clusters[m + 1].numttrks; - clusters[m].numtdtrks += clusters[m + 1].numtdtrks; - clusters[m].numttdtrks += clusters[m + 1].numttdtrks; - for (int m1 = m + 1; m1 < nclust - 1; ++m1) - clusters[m1] = clusters[m1 + 1]; - nclust--; - m = -1; - } // end if clusters neighbor in eta - } // end for (m) loop - - for (int i = nclust; i < etaBins_ / 2; ++i) // zero out remaining unused clusters - clusters[i].pTtot = 0; - return clusters; + + if (displaced_) + iEvent.put(std::move(L1L1TrackJetProducer), "L1TrackJetsExtended"); + else + iEvent.put(std::move(L1L1TrackJetProducer), "L1TrackJets"); + } } void L1TrackJetProducer::beginStream(StreamID) {} void L1TrackJetProducer::endStream() {} -bool L1TrackJetProducer::trackQualityCuts( - float trk_pt, int trk_nstub, float trk_chi2, float trk_bendchi2, float trk_d0) { +bool L1TrackJetProducer::trackQualityCuts(int trk_nstub, float trk_chi2, float trk_bendchi2) { bool PassQuality = false; - if (trk_bendchi2 < trkBendChi2Max_ && trk_chi2 < trkChi2dofMax_ && trk_nstub >= 4 && !displaced_) - PassQuality = true; - if (displaced_ && trk_bendchi2 < nStubs4DisplacedBendTight_ && trk_chi2 < nStubs4DisplacedChi2Tight_ && - trk_nstub == 4 && trk_d0 <= d0CutNStubs4_) - PassQuality = true; - if (displaced_ && trk_bendchi2 < nStubs4DisplacedBendLoose_ && trk_chi2 < nStubs4DisplacedChi2Loose_ && - trk_nstub == 4 && trk_d0 > d0CutNStubs4_) - PassQuality = true; - if (displaced_ && trk_bendchi2 < nStubs5DisplacedBendLoose_ && trk_chi2 < nStubs5DisplacedChi2Loose_ && trk_nstub > 4) - PassQuality = true; + if (!displaced_) { + if (trk_nstub == 4 && trk_bendchi2 < nStubs4PromptBend_ && + trk_chi2 < nStubs4PromptChi2_) // 4 stubs are the lowest track quality and have different cuts + PassQuality = true; + if (trk_nstub > 4 && trk_bendchi2 < nStubs5PromptBend_ && + trk_chi2 < nStubs5PromptChi2_) // above 4 stubs diffent selection imposed (genrally looser) + PassQuality = true; + } else { + if (trk_nstub == 4 && trk_bendchi2 < nStubs4DisplacedBend_ && + trk_chi2 < nStubs4DisplacedChi2_) // 4 stubs are the lowest track quality and have different cuts + PassQuality = true; + if (trk_nstub > 4 && trk_bendchi2 < nStubs5DisplacedBend_ && + trk_chi2 < nStubs5DisplacedChi2_) // above 4 stubs diffent selection imposed (genrally looser) + PassQuality = true; + } return PassQuality; } diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.h b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.h new file mode 100644 index 0000000000000..01b2b505944e8 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackJetProducer.h @@ -0,0 +1,252 @@ +#pragma once +#include +#include +#include +#include +#include +using namespace std; + +//Each individual box in the eta and phi dimension. +// Also used to store final cluster data for each zbin. +struct EtaPhiBin { + float pTtot; + int numtracks; + int numttrks; + int numtdtrks; + int numttdtrks; + bool used; + float phi; //average phi value (halfway b/t min and max) + float eta; //average eta value + std::vector trackidx; +}; + +//store important information for plots +struct MaxZBin { + int znum; //Numbered from 0 to nzbins (16, 32, or 64) in order + int nclust; //number of clusters in this bin + float zbincenter; + std::vector clusters; //list of all the clusters in this bin + float ht; //sum of all cluster pTs--only the zbin with the maximum ht is stored +}; + +inline std::vector L1_clustering(EtaPhiBin *phislice, int etaBins_, float etaStep_) { + std::vector clusters; + // Find eta-phibin with maxpT, make center of cluster, add neighbors if not already used + int nclust = 0; + + // get tracks in eta bins in increasing eta order + for (int etabin = 0; etabin < etaBins_; ++etabin) { + float my_pt = 0, previousbin_pt = 0; //, nextbin_pt=0, next2bin_pt=0; + float nextbin_pt = 0, nextbin2_pt = 0; + + // skip (already) used tracks + if (phislice[etabin].used) + continue; + my_pt = phislice[etabin].pTtot; + if (my_pt == 0) + continue; + //get previous bin pT + if (etabin > 0 && !phislice[etabin - 1].used) + previousbin_pt = phislice[etabin - 1].pTtot; + + // get next bins pt + if (etabin < etaBins_ - 1 && !phislice[etabin + 1].used) { + nextbin_pt = phislice[etabin + 1].pTtot; + if (etabin < etaBins_ - 2 && !phislice[etabin + 2].used) { + nextbin2_pt = phislice[etabin + 2].pTtot; + } + } + // check if pT of current cluster is higher than neighbors + if (my_pt < previousbin_pt || my_pt <= nextbin_pt) { + // if unused pT in the left neighbor, spit it out as a cluster + if (previousbin_pt > 0) { + clusters.push_back(phislice[etabin - 1]); + phislice[etabin - 1].used = true; + nclust++; + } + continue; //if it is not the local max pT skip + } + // here reach only unused local max clusters + clusters.push_back(phislice[etabin]); + phislice[etabin].used = true; //if current bin a cluster + if (previousbin_pt > 0) { + clusters[nclust].pTtot += previousbin_pt; + clusters[nclust].numtracks += phislice[etabin - 1].numtracks; + clusters[nclust].numtdtrks += phislice[etabin - 1].numtdtrks; + for (unsigned int itrk = 0; itrk < phislice[etabin - 1].trackidx.size(); itrk++) + clusters[nclust].trackidx.push_back(phislice[etabin - 1].trackidx[itrk]); + } + + if (my_pt >= nextbin2_pt && nextbin_pt > 0) { + clusters[nclust].pTtot += nextbin_pt; + clusters[nclust].numtracks += phislice[etabin + 1].numtracks; + clusters[nclust].numtdtrks += phislice[etabin + 1].numtdtrks; + for (unsigned int itrk = 0; itrk < phislice[etabin + 1].trackidx.size(); itrk++) + clusters[nclust].trackidx.push_back(phislice[etabin + 1].trackidx[itrk]); + phislice[etabin + 1].used = true; + } + + nclust++; + + } // for each etabin + + // Merge close-by clusters + for (int m = 0; m < nclust - 1; ++m) { + if (std::abs(clusters[m + 1].eta - clusters[m].eta) < 1.5 * etaStep_) { + if (clusters[m + 1].pTtot > clusters[m].pTtot) { + clusters[m].eta = clusters[m + 1].eta; + } + clusters[m].pTtot += clusters[m + 1].pTtot; + clusters[m].numtracks += clusters[m + 1].numtracks; // total ntrk + clusters[m].numtdtrks += clusters[m + 1].numtdtrks; // total ndisp + for (unsigned int itrk = 0; itrk < clusters[m + 1].trackidx.size(); itrk++) + clusters[m].trackidx.push_back(clusters[m + 1].trackidx[itrk]); + + // if remove the merged cluster - all the others must be closer to 0 + for (int m1 = m + 1; m1 < nclust - 1; ++m1) { + clusters[m1] = clusters[m1 + 1]; + //clusters.erase(clusters.begin()+m1); + } + // clusters[m1] = clusters[m1 + 1]; + clusters.erase(clusters.begin() + nclust); + nclust--; + m = -1; + } // end if clusters neighbor in eta + } // end for (m) loop + + return clusters; +} + +inline void Fill_L2Cluster(EtaPhiBin &bin, float pt, int ntrk, int ndtrk, std::vector trkidx) { + bin.pTtot += pt; + bin.numtracks += ntrk; + bin.numtdtrks += ndtrk; + for (unsigned int itrk = 0; itrk < trkidx.size(); itrk++) + bin.trackidx.push_back(trkidx[itrk]); +} + +inline float DPhi(float phi1, float phi2) { + float x = phi1 - phi2; + if (x >= M_PI) + x -= 2 * M_PI; + if (x < -1 * M_PI) + x += 2 * M_PI; + return x; +} + +inline std::vector L2_clustering(std::vector> &L1clusters, + int phiBins_, + float phiStep_, + float etaStep_) { + std::vector clusters; + for (int phibin = 0; phibin < phiBins_; ++phibin) { //Find eta-phibin with highest pT + if (L1clusters[phibin].empty()) + continue; + + // sort L1 clusters max -> min + sort(L1clusters[phibin].begin(), L1clusters[phibin].end(), [](struct EtaPhiBin &a, struct EtaPhiBin &b) { + return a.pTtot > b.pTtot; + }); + for (unsigned int imax = 0; imax < L1clusters[phibin].size(); ++imax) { + if (L1clusters[phibin][imax].used) + continue; + float pt_current = L1clusters[phibin][imax].pTtot; //current cluster (pt0) + float pt_next = 0; // next phi bin (pt1) + float pt_next2 = 0; // next to next phi bin2 (pt2) + int trk1 = 0; + int trk2 = 0; + int tdtrk1 = 0; + int tdtrk2 = 0; + std::vector trkidx1; + std::vector trkidx2; + clusters.push_back(L1clusters[phibin][imax]); + + L1clusters[phibin][imax].used = true; + + // if we are in the last phi bin, dont check phi+1 phi+2 + if (phibin == phiBins_ - 1) + continue; + std::vector used_already; //keep phi+1 clusters that have been used + for (unsigned int icluster = 0; icluster < L1clusters[phibin + 1].size(); ++icluster) { + if (L1clusters[phibin + 1][icluster].used) + continue; + if (std::abs(L1clusters[phibin + 1][icluster].eta - L1clusters[phibin][imax].eta) > 1.5 * etaStep_) + continue; + pt_next += L1clusters[phibin + 1][icluster].pTtot; + trk1 += L1clusters[phibin + 1][icluster].numtracks; + tdtrk1 += L1clusters[phibin + 1][icluster].numtdtrks; + for (unsigned int itrk = 0; itrk < L1clusters[phibin + 1][icluster].trackidx.size(); itrk++) + trkidx1.push_back(L1clusters[phibin + 1][icluster].trackidx[itrk]); + used_already.push_back(icluster); + } + + if (pt_next < pt_current) { // if pt1 used_already2; //keep used clusters in phi+2 + for (unsigned int icluster = 0; icluster < L1clusters[phibin + 2].size(); ++icluster) { + if (L1clusters[phibin + 2][icluster].used) + continue; + if (std::abs(L1clusters[phibin + 2][icluster].eta - L1clusters[phibin][imax].eta) > 1.5 * etaStep_) + continue; + pt_next2 += L1clusters[phibin + 2][icluster].pTtot; + trk2 += L1clusters[phibin + 2][icluster].numtracks; + tdtrk2 += L1clusters[phibin + 2][icluster].numtdtrks; + for (unsigned int itrk = 0; itrk < L1clusters[phibin + 2][icluster].trackidx.size(); itrk++) + trkidx2.push_back(L1clusters[phibin + 2][icluster].trackidx[itrk]); + used_already2.push_back(icluster); + } + if (pt_next2 < pt_next) { + std::vector trkidx_both; + trkidx_both.reserve(trkidx1.size() + trkidx2.size()); + trkidx_both.insert(trkidx_both.end(), trkidx1.begin(), trkidx1.end()); + trkidx_both.insert(trkidx_both.end(), trkidx2.begin(), trkidx2.end()); + Fill_L2Cluster(clusters[clusters.size() - 1], pt_next + pt_next2, trk1 + trk2, tdtrk1 + tdtrk2, trkidx_both); + clusters[clusters.size() - 1].phi = L1clusters[phibin + 1][used_already[0]].phi; + for (unsigned int iused : used_already) + L1clusters[phibin + 1][iused].used = true; + for (unsigned int iused : used_already2) + L1clusters[phibin + 2][iused].used = true; + } + } // for each L1 cluster + } // for each phibin + + int nclust = clusters.size(); + + // merge close-by clusters + for (int m = 0; m < nclust - 1; ++m) { + for (int n = m + 1; n < nclust; ++n) { + if (clusters[n].eta != clusters[m].eta) + continue; + if (std::abs(DPhi(clusters[n].phi, clusters[m].phi)) > 1.5 * phiStep_) + continue; + + if (clusters[n].pTtot > clusters[m].pTtot) + clusters[m].phi = clusters[n].phi; + + clusters[m].pTtot += clusters[n].pTtot; + clusters[m].numtracks += clusters[n].numtracks; + clusters[m].numtdtrks += clusters[n].numtdtrks; + for (unsigned int itrk = 0; itrk < clusters[n].trackidx.size(); itrk++) + clusters[m].trackidx.push_back(clusters[n].trackidx[itrk]); + for (int m1 = n; m1 < nclust - 1; ++m1) + clusters[m1] = clusters[m1 + 1]; + clusters.erase(clusters.begin() + nclust); + + nclust--; + m = -1; + } // end of n-loop + } // end of m-loop + return clusters; +} diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackObjectNtupleMaker.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackObjectNtupleMaker.cc deleted file mode 100644 index dbfc2a3bc245c..0000000000000 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackObjectNtupleMaker.cc +++ /dev/null @@ -1,2245 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// // -// Analyzer for making mini-ntuple for L1 track performance plots // -// // -////////////////////////////////////////////////////////////////////// - -//////////////////// -// FRAMEWORK HEADERS -#include "FWCore/PluginManager/interface/ModuleDef.h" -#include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" -#include "FWCore/Framework/interface/stream/EDAnalyzer.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ServiceRegistry/interface/Service.h" - -/////////////////////// -// DATA FORMATS HEADERS -#include "DataFormats/Common/interface/Handle.h" -#include "DataFormats/Common/interface/Ref.h" - -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" -#include "DataFormats/L1TrackTrigger/interface/TTCluster.h" -#include "DataFormats/L1TrackTrigger/interface/TTStub.h" -#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" -#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h" -#include "SimDataFormats/TrackingAnalysis/interface/TrackingVertex.h" -#include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h" -#include "SimDataFormats/TrackingHit/interface/PSimHit.h" -#include "SimTracker/TrackTriggerAssociation/interface/TTClusterAssociationMap.h" -#include "SimTracker/TrackTriggerAssociation/interface/TTStubAssociationMap.h" -#include "SimTracker/TrackTriggerAssociation/interface/TTTrackAssociationMap.h" -#include "Geometry/Records/interface/StackedTrackerGeometryRecord.h" - -#include "DataFormats/JetReco/interface/GenJetCollection.h" -#include "DataFormats/JetReco/interface/GenJet.h" - -//////////////////////////// -// DETECTOR GEOMETRY HEADERS -#include "MagneticField/Engine/interface/MagneticField.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" -#include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" -#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" -#include "Geometry/TrackerGeometryBuilder/interface/RectangularPixelTopology.h" -#include "Geometry/CommonDetUnit/interface/GeomDetType.h" -#include "Geometry/CommonDetUnit/interface/GeomDet.h" - -#include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h" -#include "Geometry/CommonTopologies/interface/PixelGeomDetType.h" -#include "Geometry/TrackerGeometryBuilder/interface/PixelTopologyBuilder.h" -#include "Geometry/Records/interface/StackedTrackerGeometryRecord.h" - -//////////////// -// PHYSICS TOOLS -#include "CommonTools/UtilAlgos/interface/TFileService.h" - -//My additions -#include "DataFormats/L1TCorrelator/interface/TkJet.h" -#include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" -#include "DataFormats/Math/interface/LorentzVector.h" -#include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" -#include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" -#include "DataFormats/L1TCorrelator/interface/TkHTMiss.h" -#include "DataFormats/L1TCorrelator/interface/TkHTMissFwd.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" - -/////////////// -// ROOT HEADERS -#include -#include -#include -#include -#include -#include -#include -#include - -////////////// -// STD HEADERS -#include -#include -#include - -////////////// -// NAMESPACES -using namespace std; -using namespace edm; - -////////////////////////////// -// // -// CLASS DEFINITION // -// // -////////////////////////////// - -class L1TrackObjectNtupleMaker : public edm::stream::EDAnalyzer<> { -public: - // Constructor/destructor - explicit L1TrackObjectNtupleMaker(const edm::ParameterSet& iConfig); - ~L1TrackObjectNtupleMaker() override; - - // Mandatory methods - void beginJob(); - void endJob(); - void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; - -protected: -private: - //----------------------------------------------------------------------------------------------- - // Containers of parameters passed by python configuration file - edm::ParameterSet config; - - int MyProcess; // 11/13/211 for single electrons/muons/pions, 6/15 for pions from ttbar/taus, 1 for inclusive - bool DebugMode; // lots of debug printout statements - bool SaveAllTracks; // store in ntuples not only truth-matched tracks but ALL tracks - bool SaveStubs; // option to save also stubs in the ntuples (makes them large...) - string Displaced; // "Prompt", "Displaced", "Both" - int TP_minNStub; // require TPs to have >= minNStub (defining efficiency denominator) (==0 means to only require >= 1 cluster) - int TP_minNStubLayer; // require TPs to have stubs in >= minNStubLayer layers/disks (defining efficiency denominator) - double TP_minPt; // save TPs with pt > minPt - double TP_maxEta; // save TPs with |eta| < maxEta - double TP_maxZ0; // save TPs with |z0| < maxZ0 - int L1Tk_minNStub; // require L1 tracks to have >= minNStub (this is mostly for tracklet purposes) - bool TrackingInJets; // do tracking in jets? - bool SaveTrackJets; - bool SaveTrackMET; - - edm::InputTag L1TrackInputTag; // L1 track collection - edm::InputTag MCTruthTrackInputTag; // MC truth collection - edm::InputTag L1TrackExtendedInputTag; // L1 track collection - edm::InputTag MCTruthTrackExtendedInputTag; // MC truth collection - edm::InputTag MCTruthClusterInputTag; - edm::InputTag L1StubInputTag; - edm::InputTag MCTruthStubInputTag; - edm::InputTag TrackingParticleInputTag; - edm::InputTag TrackingVertexInputTag; - edm::InputTag GenJetInputTag; - edm::InputTag RecoVertexInputTag; - edm::InputTag GenParticleInputTag; - - edm::InputTag TrackFastJetsInputTag; - edm::InputTag TrackJetsInputTag; - edm::InputTag TrackMETInputTag; - edm::InputTag TrackMHTInputTag; - - edm::InputTag TrackFastJetsExtendedInputTag; - edm::InputTag TrackJetsExtendedInputTag; - edm::InputTag TrackMETExtendedInputTag; - edm::InputTag TrackMHTExtendedInputTag; - - edm::EDGetTokenT > > ttClusterToken_; - edm::EDGetTokenT > > ttStubToken_; - edm::EDGetTokenT > ttClusterMCTruthToken_; - edm::EDGetTokenT > ttStubMCTruthToken_; - - edm::EDGetTokenT > > ttTrackToken_; - edm::EDGetTokenT > ttTrackMCTruthToken_; - edm::EDGetTokenT > > ttTrackExtendedToken_; - edm::EDGetTokenT > ttTrackMCTruthExtendedToken_; - - edm::EDGetTokenT > TrackingParticleToken_; - edm::EDGetTokenT > TrackingVertexToken_; - - edm::EDGetTokenT > GenJetToken_; - edm::EDGetTokenT > GenParticleToken_; - edm::EDGetTokenT L1VertexToken_; - - edm::EDGetTokenT > TrackFastJetsToken_; - edm::EDGetTokenT > TrackFastJetsExtendedToken_; - edm::EDGetTokenT > TrackMETToken_; - edm::EDGetTokenT > TrackMETExtendedToken_; - edm::EDGetTokenT TrackMHTToken_; - edm::EDGetTokenT TrackMHTExtendedToken_; - edm::EDGetTokenT TrackJetsToken_; - edm::EDGetTokenT TrackJetsExtendedToken_; - - edm::ESGetToken tTopoToken_; - edm::ESGetToken tGeomToken_; - - //----------------------------------------------------------------------------------------------- - // tree & branches for mini-ntuple - - bool available_; // ROOT file for histograms is open. - - TTree* eventTree; - - // primary vertex - // std::vector* m_pv_L1recotruesumpt; - // std::vector* m_pv_L1recosumpt; - std::vector* m_pv_L1reco; - // std::vector* m_pv_L1TP; - // std::vector* m_pv_L1TPsumpt; - std::vector* m_pv_MC; - // std::vector* m_pv_MCChgSumpT; - std::vector* m_MC_lep; - - // all L1 tracks (prompt) - std::vector* m_trk_pt; - std::vector* m_trk_eta; - std::vector* m_trk_phi; - std::vector* m_trk_d0; // (filled if nFitPar==5, else 999) - std::vector* m_trk_z0; - std::vector* m_trk_chi2; - std::vector* m_trk_chi2dof; - std::vector* m_trk_chi2rphi; - std::vector* m_trk_chi2rz; - std::vector* m_trk_bendchi2; - std::vector* m_trk_nstub; - std::vector* m_trk_lhits; - std::vector* m_trk_dhits; - std::vector* m_trk_seed; - std::vector* m_trk_hitpattern; - std::vector* m_trk_phiSector; - std::vector* m_trk_genuine; - std::vector* m_trk_loose; - std::vector* m_trk_unknown; - std::vector* m_trk_combinatoric; - std::vector* m_trk_fake; //0 fake, 1 track from primary interaction, 2 secondary track - std::vector* m_trk_matchtp_pdgid; - std::vector* m_trk_matchtp_pt; - std::vector* m_trk_matchtp_eta; - std::vector* m_trk_matchtp_phi; - std::vector* m_trk_matchtp_z0; - std::vector* m_trk_matchtp_dxy; - - // all L1 tracks (extended) - std::vector* m_trkExt_pt; - std::vector* m_trkExt_eta; - std::vector* m_trkExt_phi; - std::vector* m_trkExt_d0; // (filled if nFitPar==5, else 999) - std::vector* m_trkExt_z0; - std::vector* m_trkExt_chi2; - std::vector* m_trkExt_chi2dof; - std::vector* m_trkExt_chi2rphi; - std::vector* m_trkExt_chi2rz; - std::vector* m_trkExt_bendchi2; - std::vector* m_trkExt_nstub; - std::vector* m_trkExt_lhits; - std::vector* m_trkExt_dhits; - std::vector* m_trkExt_seed; - std::vector* m_trkExt_hitpattern; - std::vector* m_trkExt_phiSector; - std::vector* m_trkExt_genuine; - std::vector* m_trkExt_loose; - std::vector* m_trkExt_unknown; - std::vector* m_trkExt_combinatoric; - std::vector* m_trkExt_fake; //0 fake, 1 track from primary interaction, 2 secondary track - std::vector* m_trkExt_matchtp_pdgid; - std::vector* m_trkExt_matchtp_pt; - std::vector* m_trkExt_matchtp_eta; - std::vector* m_trkExt_matchtp_phi; - std::vector* m_trkExt_matchtp_z0; - std::vector* m_trkExt_matchtp_dxy; - - // all tracking particles - std::vector* m_tp_pt; - std::vector* m_tp_eta; - std::vector* m_tp_phi; - std::vector* m_tp_dxy; - std::vector* m_tp_d0; - std::vector* m_tp_z0; - std::vector* m_tp_d0_prod; - std::vector* m_tp_z0_prod; - std::vector* m_tp_pdgid; - std::vector* m_tp_nmatch; - std::vector* m_tp_nstub; - std::vector* m_tp_eventid; - std::vector* m_tp_charge; - - // *L1 track* properties if m_tp_nmatch > 0 (prompt) - std::vector* m_matchtrk_pt; - std::vector* m_matchtrk_eta; - std::vector* m_matchtrk_phi; - std::vector* m_matchtrk_d0; //this variable is only filled if nFitPar==5 - std::vector* m_matchtrk_z0; - std::vector* m_matchtrk_chi2; - std::vector* m_matchtrk_chi2dof; - std::vector* m_matchtrk_chi2rphi; - std::vector* m_matchtrk_chi2rz; - std::vector* m_matchtrk_bendchi2; - std::vector* m_matchtrk_nstub; - std::vector* m_matchtrk_lhits; - std::vector* m_matchtrk_dhits; - std::vector* m_matchtrk_seed; - std::vector* m_matchtrk_hitpattern; - - // *L1 track* properties if m_tp_nmatch > 0 (extended) - std::vector* m_matchtrkExt_pt; - std::vector* m_matchtrkExt_eta; - std::vector* m_matchtrkExt_phi; - std::vector* m_matchtrkExt_d0; //this variable is only filled if nFitPar==5 - std::vector* m_matchtrkExt_z0; - std::vector* m_matchtrkExt_chi2; - std::vector* m_matchtrkExt_chi2dof; - std::vector* m_matchtrkExt_chi2rphi; - std::vector* m_matchtrkExt_chi2rz; - std::vector* m_matchtrkExt_bendchi2; - std::vector* m_matchtrkExt_nstub; - std::vector* m_matchtrkExt_lhits; - std::vector* m_matchtrkExt_dhits; - std::vector* m_matchtrkExt_seed; - std::vector* m_matchtrkExt_hitpattern; - - // ALL stubs - std::vector* m_allstub_x; - std::vector* m_allstub_y; - std::vector* m_allstub_z; - std::vector* m_allstub_isBarrel; // stub is in barrel (1) or in disk (0) - std::vector* m_allstub_layer; - std::vector* m_allstub_isPSmodule; - std::vector* m_allstub_trigDisplace; - std::vector* m_allstub_trigOffset; - std::vector* m_allstub_trigPos; - std::vector* m_allstub_trigBend; - - // stub associated with tracking particle ? - std::vector* m_allstub_matchTP_pdgid; // -999 if not matched - std::vector* m_allstub_matchTP_pt; // -999 if not matched - std::vector* m_allstub_matchTP_eta; // -999 if not matched - std::vector* m_allstub_matchTP_phi; // -999 if not matched - std::vector* m_allstub_genuine; - - // // track jet variables (for each gen jet, store the sum of pt of TPs / tracks inside jet cone) - // std::vector* m_jet_eta; - // std::vector* m_jet_phi; - // std::vector* m_jet_pt; - // std::vector* m_jet_tp_sumpt; - // std::vector* m_jet_trk_sumpt; - // std::vector* m_jet_matchtrk_sumpt; - - float trueMET = 0; - float trkMET = 0; - float trkMHT = 0; - float trkHT = 0; - - float trkMETExt = 0; - float trkMHTExt = 0; - float trkHTExt = 0; - - std::vector* m_2ltrkjet_vz; - std::vector* m_2ltrkjet_p; - std::vector* m_2ltrkjet_phi; - std::vector* m_2ltrkjet_eta; - std::vector* m_2ltrkjet_pt; - std::vector* m_2ltrkjet_ntracks; - std::vector* m_2ltrkjet_nDisplaced; - std::vector* m_2ltrkjet_nTight; - std::vector* m_2ltrkjet_nTightDisplaced; - std::vector* m_2ltrkjet_ntdtrk; - - std::vector* m_trkjet_vz; - std::vector* m_trkjet_p; - std::vector* m_trkjet_phi; - std::vector* m_trkjet_eta; - std::vector* m_trkjet_pt; - std::vector* m_trkjet_ntracks; - std::vector* m_trkjet_tp_sumpt; - std::vector* m_trkjet_truetp_sumpt; - - std::vector* m_2ltrkjetExt_vz; - std::vector* m_2ltrkjetExt_p; - std::vector* m_2ltrkjetExt_phi; - std::vector* m_2ltrkjetExt_eta; - std::vector* m_2ltrkjetExt_pt; - std::vector* m_2ltrkjetExt_ntracks; - std::vector* m_2ltrkjetExt_nDisplaced; - std::vector* m_2ltrkjetExt_nTight; - std::vector* m_2ltrkjetExt_nTightDisplaced; - std::vector* m_2ltrkjetExt_ntdtrk; - - std::vector* m_trkjetExt_vz; - std::vector* m_trkjetExt_p; - std::vector* m_trkjetExt_phi; - std::vector* m_trkjetExt_eta; - std::vector* m_trkjetExt_pt; - std::vector* m_trkjetExt_ntracks; - std::vector* m_trkjetExt_tp_sumpt; - std::vector* m_trkjetExt_truetp_sumpt; -}; - -////////////////////////////////// -// // -// CLASS IMPLEMENTATION // -// // -////////////////////////////////// - -////////////// -// CONSTRUCTOR -L1TrackObjectNtupleMaker::L1TrackObjectNtupleMaker(edm::ParameterSet const& iConfig) : config(iConfig) { - MyProcess = iConfig.getParameter("MyProcess"); - DebugMode = iConfig.getParameter("DebugMode"); - SaveAllTracks = iConfig.getParameter("SaveAllTracks"); - SaveStubs = iConfig.getParameter("SaveStubs"); - Displaced = iConfig.getParameter("Displaced"); - TP_minNStub = iConfig.getParameter("TP_minNStub"); - TP_minNStubLayer = iConfig.getParameter("TP_minNStubLayer"); - TP_minPt = iConfig.getParameter("TP_minPt"); - TP_maxEta = iConfig.getParameter("TP_maxEta"); - TP_maxZ0 = iConfig.getParameter("TP_maxZ0"); - L1Tk_minNStub = iConfig.getParameter("L1Tk_minNStub"); - - TrackingInJets = iConfig.getParameter("TrackingInJets"); - SaveTrackJets = iConfig.getParameter("SaveTrackJets"); - SaveTrackMET = iConfig.getParameter("SaveTrackMET"); - - L1StubInputTag = iConfig.getParameter("L1StubInputTag"); - MCTruthClusterInputTag = iConfig.getParameter("MCTruthClusterInputTag"); - MCTruthStubInputTag = iConfig.getParameter("MCTruthStubInputTag"); - TrackingParticleInputTag = iConfig.getParameter("TrackingParticleInputTag"); - TrackingVertexInputTag = iConfig.getParameter("TrackingVertexInputTag"); - GenJetInputTag = iConfig.getParameter("GenJetInputTag"); - RecoVertexInputTag = iConfig.getParameter("RecoVertexInputTag"); - GenParticleInputTag = iConfig.getParameter("GenParticleInputTag"); - - if (Displaced == "Prompt" || Displaced == "Both") { - L1TrackInputTag = iConfig.getParameter("L1TrackInputTag"); - MCTruthTrackInputTag = iConfig.getParameter("MCTruthTrackInputTag"); - TrackFastJetsInputTag = iConfig.getParameter("TrackFastJetsInputTag"); - TrackJetsInputTag = iConfig.getParameter("TrackJetsInputTag"); - TrackMETInputTag = iConfig.getParameter("TrackMETInputTag"); - TrackMHTInputTag = iConfig.getParameter("TrackMHTInputTag"); - - ttTrackToken_ = consumes > >(L1TrackInputTag); - ttTrackMCTruthToken_ = consumes >(MCTruthTrackInputTag); - TrackFastJetsToken_ = consumes >(TrackFastJetsInputTag); - TrackJetsToken_ = consumes(TrackJetsInputTag); - TrackMETToken_ = consumes >(TrackMETInputTag); - TrackMHTToken_ = consumes(TrackMHTInputTag); - } - - if (Displaced == "Displaced" || Displaced == "Both") { - L1TrackExtendedInputTag = iConfig.getParameter("L1TrackExtendedInputTag"); - MCTruthTrackExtendedInputTag = iConfig.getParameter("MCTruthTrackExtendedInputTag"); - TrackFastJetsExtendedInputTag = iConfig.getParameter("TrackFastJetsExtendedInputTag"); - TrackJetsExtendedInputTag = iConfig.getParameter("TrackJetsExtendedInputTag"); - TrackMETExtendedInputTag = iConfig.getParameter("TrackMETExtendedInputTag"); - TrackMHTExtendedInputTag = iConfig.getParameter("TrackMHTExtendedInputTag"); - - ttTrackExtendedToken_ = consumes > >(L1TrackExtendedInputTag); - ttTrackMCTruthExtendedToken_ = - consumes >(MCTruthTrackExtendedInputTag); - TrackFastJetsExtendedToken_ = consumes >(TrackFastJetsExtendedInputTag); - TrackJetsExtendedToken_ = consumes(TrackJetsExtendedInputTag); - TrackMETExtendedToken_ = consumes >(TrackMETExtendedInputTag); - TrackMHTExtendedToken_ = consumes(TrackMHTExtendedInputTag); - } - - ttStubToken_ = consumes > >(L1StubInputTag); - ttClusterMCTruthToken_ = consumes >(MCTruthClusterInputTag); - ttStubMCTruthToken_ = consumes >(MCTruthStubInputTag); - TrackingParticleToken_ = consumes >(TrackingParticleInputTag); - TrackingVertexToken_ = consumes >(TrackingVertexInputTag); - GenJetToken_ = consumes >(GenJetInputTag); - GenParticleToken_ = consumes >(GenParticleInputTag); - L1VertexToken_ = consumes(RecoVertexInputTag); - - tTopoToken_ = esConsumes(edm::ESInputTag("", "")); - tGeomToken_ = esConsumes(edm::ESInputTag("", "")); -} - -///////////// -// DESTRUCTOR -L1TrackObjectNtupleMaker::~L1TrackObjectNtupleMaker() {} - -////////// -// END JOB -void L1TrackObjectNtupleMaker::endJob() { - // things to be done at the exit of the event Loop - // edm::LogVerbatim("Tracklet") << "L1TrackObjectNtupleMaker::endJob"; -} - -//////////// -// BEGIN JOB -void L1TrackObjectNtupleMaker::beginJob() { - // things to be done before entering the event Loop - // edm::LogVerbatim("Tracklet") << "L1TrackObjectNtupleMaker::beginJob"; - - //----------------------------------------------------------------------------------------------- - // book histograms / make ntuple - edm::Service fs; - available_ = fs.isAvailable(); - if (not available_) - return; // No ROOT file open. - - // initilize - m_trk_pt = new std::vector; - m_trk_eta = new std::vector; - m_trk_phi = new std::vector; - m_trk_z0 = new std::vector; - m_trk_d0 = new std::vector; - m_trk_chi2 = new std::vector; - m_trk_chi2dof = new std::vector; - m_trk_chi2rphi = new std::vector; - m_trk_chi2rz = new std::vector; - m_trk_bendchi2 = new std::vector; - m_trk_nstub = new std::vector; - m_trk_lhits = new std::vector; - m_trk_dhits = new std::vector; - m_trk_seed = new std::vector; - m_trk_hitpattern = new std::vector; - m_trk_phiSector = new std::vector; - m_trk_genuine = new std::vector; - m_trk_loose = new std::vector; - m_trk_unknown = new std::vector; - m_trk_combinatoric = new std::vector; - m_trk_fake = new std::vector; - m_trk_matchtp_pdgid = new std::vector; - m_trk_matchtp_pt = new std::vector; - m_trk_matchtp_eta = new std::vector; - m_trk_matchtp_phi = new std::vector; - m_trk_matchtp_z0 = new std::vector; - m_trk_matchtp_dxy = new std::vector; - - m_trkExt_pt = new std::vector; - m_trkExt_eta = new std::vector; - m_trkExt_phi = new std::vector; - m_trkExt_z0 = new std::vector; - m_trkExt_d0 = new std::vector; - m_trkExt_chi2 = new std::vector; - m_trkExt_chi2dof = new std::vector; - m_trkExt_chi2rphi = new std::vector; - m_trkExt_chi2rz = new std::vector; - m_trkExt_bendchi2 = new std::vector; - m_trkExt_nstub = new std::vector; - m_trkExt_lhits = new std::vector; - m_trkExt_dhits = new std::vector; - m_trkExt_seed = new std::vector; - m_trkExt_hitpattern = new std::vector; - m_trkExt_phiSector = new std::vector; - m_trkExt_genuine = new std::vector; - m_trkExt_loose = new std::vector; - m_trkExt_unknown = new std::vector; - m_trkExt_combinatoric = new std::vector; - m_trkExt_fake = new std::vector; - m_trkExt_matchtp_pdgid = new std::vector; - m_trkExt_matchtp_pt = new std::vector; - m_trkExt_matchtp_eta = new std::vector; - m_trkExt_matchtp_phi = new std::vector; - m_trkExt_matchtp_z0 = new std::vector; - m_trkExt_matchtp_dxy = new std::vector; - - m_tp_pt = new std::vector; - m_tp_eta = new std::vector; - m_tp_phi = new std::vector; - m_tp_dxy = new std::vector; - m_tp_d0 = new std::vector; - m_tp_z0 = new std::vector; - m_tp_d0_prod = new std::vector; - m_tp_z0_prod = new std::vector; - m_tp_pdgid = new std::vector; - m_tp_nmatch = new std::vector; - m_tp_nstub = new std::vector; - m_tp_eventid = new std::vector; - m_tp_charge = new std::vector; - - m_matchtrk_pt = new std::vector; - m_matchtrk_eta = new std::vector; - m_matchtrk_phi = new std::vector; - m_matchtrk_z0 = new std::vector; - m_matchtrk_d0 = new std::vector; - m_matchtrk_chi2 = new std::vector; - m_matchtrk_chi2dof = new std::vector; - m_matchtrk_chi2rphi = new std::vector; - m_matchtrk_chi2rz = new std::vector; - m_matchtrk_bendchi2 = new std::vector; - m_matchtrk_nstub = new std::vector; - m_matchtrk_dhits = new std::vector; - m_matchtrk_lhits = new std::vector; - m_matchtrk_seed = new std::vector; - m_matchtrk_hitpattern = new std::vector; - - m_matchtrkExt_pt = new std::vector; - m_matchtrkExt_eta = new std::vector; - m_matchtrkExt_phi = new std::vector; - m_matchtrkExt_z0 = new std::vector; - m_matchtrkExt_d0 = new std::vector; - m_matchtrkExt_chi2 = new std::vector; - m_matchtrkExt_chi2dof = new std::vector; - m_matchtrkExt_chi2rphi = new std::vector; - m_matchtrkExt_chi2rz = new std::vector; - m_matchtrkExt_bendchi2 = new std::vector; - m_matchtrkExt_nstub = new std::vector; - m_matchtrkExt_dhits = new std::vector; - m_matchtrkExt_lhits = new std::vector; - m_matchtrkExt_seed = new std::vector; - m_matchtrkExt_hitpattern = new std::vector; - - m_allstub_x = new std::vector; - m_allstub_y = new std::vector; - m_allstub_z = new std::vector; - m_allstub_isBarrel = new std::vector; - m_allstub_layer = new std::vector; - m_allstub_isPSmodule = new std::vector; - m_allstub_trigDisplace = new std::vector; - m_allstub_trigOffset = new std::vector; - m_allstub_trigPos = new std::vector; - m_allstub_trigBend = new std::vector; - m_allstub_matchTP_pdgid = new std::vector; - m_allstub_matchTP_pt = new std::vector; - m_allstub_matchTP_eta = new std::vector; - m_allstub_matchTP_phi = new std::vector; - m_allstub_genuine = new std::vector; - - // m_jet_eta = new std::vector; - // m_jet_phi = new std::vector; - // m_jet_pt = new std::vector; - // m_jet_tp_sumpt = new std::vector; - // m_jet_trk_sumpt = new std::vector; - // m_jet_matchtrk_sumpt = new std::vector; - - // m_pv_L1recotruesumpt = new std::vector; - // m_pv_L1recosumpt = new std::vector; - m_pv_L1reco = new std::vector; - // m_pv_L1TP = new std::vector; - // m_pv_L1TPsumpt = new std::vector; - m_pv_MC = new std::vector; - // m_pv_MCChgSumpT = new std::vector; - m_MC_lep = new std::vector; - - m_2ltrkjet_eta = new std::vector; - m_2ltrkjet_vz = new std::vector; - m_2ltrkjet_phi = new std::vector; - m_2ltrkjet_p = new std::vector; - m_2ltrkjet_pt = new std::vector; - m_2ltrkjet_ntracks = new std::vector; - m_2ltrkjet_nDisplaced = new std::vector; - m_2ltrkjet_nTight = new std::vector; - m_2ltrkjet_nTightDisplaced = new std::vector; - m_2ltrkjet_ntdtrk = new std::vector; - - m_trkjet_eta = new std::vector; - m_trkjet_vz = new std::vector; - m_trkjet_phi = new std::vector; - m_trkjet_p = new std::vector; - m_trkjet_pt = new std::vector; - m_trkjet_ntracks = new std::vector; - m_trkjet_tp_sumpt = new std::vector; - m_trkjet_truetp_sumpt = new std::vector; - - m_2ltrkjetExt_eta = new std::vector; - m_2ltrkjetExt_vz = new std::vector; - m_2ltrkjetExt_phi = new std::vector; - m_2ltrkjetExt_p = new std::vector; - m_2ltrkjetExt_pt = new std::vector; - m_2ltrkjetExt_ntracks = new std::vector; - m_2ltrkjetExt_nDisplaced = new std::vector; - m_2ltrkjetExt_nTight = new std::vector; - m_2ltrkjetExt_nTightDisplaced = new std::vector; - m_2ltrkjetExt_ntdtrk = new std::vector; - - m_trkjetExt_eta = new std::vector; - m_trkjetExt_vz = new std::vector; - m_trkjetExt_phi = new std::vector; - m_trkjetExt_p = new std::vector; - m_trkjetExt_pt = new std::vector; - m_trkjetExt_ntracks = new std::vector; - m_trkjetExt_tp_sumpt = new std::vector; - m_trkjetExt_truetp_sumpt = new std::vector; - - // ntuple - eventTree = fs->make("eventTree", "Event tree"); - - if (SaveAllTracks && (Displaced == "Prompt" || Displaced == "Both")) { - eventTree->Branch("trk_pt", &m_trk_pt); - eventTree->Branch("trk_eta", &m_trk_eta); - eventTree->Branch("trk_phi", &m_trk_phi); - eventTree->Branch("trk_d0", &m_trk_d0); - eventTree->Branch("trk_z0", &m_trk_z0); - eventTree->Branch("trk_chi2", &m_trk_chi2); - eventTree->Branch("trk_chi2dof", &m_trk_chi2dof); - eventTree->Branch("trk_chi2rphi", &m_trk_chi2rphi); - eventTree->Branch("trk_chi2rz", &m_trk_chi2rz); - eventTree->Branch("trk_bendchi2", &m_trk_bendchi2); - eventTree->Branch("trk_nstub", &m_trk_nstub); - eventTree->Branch("trk_lhits", &m_trk_lhits); - eventTree->Branch("trk_dhits", &m_trk_dhits); - eventTree->Branch("trk_seed", &m_trk_seed); - eventTree->Branch("trk_hitpattern", &m_trk_hitpattern); - eventTree->Branch("trk_phiSector", &m_trk_phiSector); - eventTree->Branch("trk_genuine", &m_trk_genuine); - eventTree->Branch("trk_loose", &m_trk_loose); - eventTree->Branch("trk_unknown", &m_trk_unknown); - eventTree->Branch("trk_combinatoric", &m_trk_combinatoric); - eventTree->Branch("trk_fake", &m_trk_fake); - eventTree->Branch("trk_matchtp_pdgid", &m_trk_matchtp_pdgid); - eventTree->Branch("trk_matchtp_pt", &m_trk_matchtp_pt); - eventTree->Branch("trk_matchtp_eta", &m_trk_matchtp_eta); - eventTree->Branch("trk_matchtp_phi", &m_trk_matchtp_phi); - eventTree->Branch("trk_matchtp_z0", &m_trk_matchtp_z0); - eventTree->Branch("trk_matchtp_dxy", &m_trk_matchtp_dxy); - // if (TrackingInJets) { - // eventTree->Branch("trk_injet", &m_trk_injet); - // eventTree->Branch("trk_injet_highpt", &m_trk_injet_highpt); - // eventTree->Branch("trk_injet_vhighpt", &m_trk_injet_vhighpt); - // } - } - - if (SaveAllTracks && (Displaced == "Displaced" || Displaced == "Both")) { - eventTree->Branch("trkExt_pt", &m_trkExt_pt); - eventTree->Branch("trkExt_eta", &m_trkExt_eta); - eventTree->Branch("trkExt_phi", &m_trkExt_phi); - eventTree->Branch("trkExt_d0", &m_trkExt_d0); - eventTree->Branch("trkExt_z0", &m_trkExt_z0); - eventTree->Branch("trkExt_chi2", &m_trkExt_chi2); - eventTree->Branch("trkExt_chi2dof", &m_trkExt_chi2dof); - eventTree->Branch("trkExt_chi2rphi", &m_trkExt_chi2rphi); - eventTree->Branch("trkExt_chi2rz", &m_trkExt_chi2rz); - eventTree->Branch("trkExt_bendchi2", &m_trkExt_bendchi2); - eventTree->Branch("trkExt_nstub", &m_trkExt_nstub); - eventTree->Branch("trkExt_lhits", &m_trkExt_lhits); - eventTree->Branch("trkExt_dhits", &m_trkExt_dhits); - eventTree->Branch("trkExt_seed", &m_trkExt_seed); - eventTree->Branch("trkExt_hitpattern", &m_trkExt_hitpattern); - eventTree->Branch("trkExt_phiSector", &m_trkExt_phiSector); - eventTree->Branch("trkExt_genuine", &m_trkExt_genuine); - eventTree->Branch("trkExt_loose", &m_trkExt_loose); - eventTree->Branch("trkExt_unknown", &m_trkExt_unknown); - eventTree->Branch("trkExt_combinatoric", &m_trkExt_combinatoric); - eventTree->Branch("trkExt_fake", &m_trkExt_fake); - eventTree->Branch("trkExt_matchtp_pdgid", &m_trkExt_matchtp_pdgid); - eventTree->Branch("trkExt_matchtp_pt", &m_trkExt_matchtp_pt); - eventTree->Branch("trkExt_matchtp_eta", &m_trkExt_matchtp_eta); - eventTree->Branch("trkExt_matchtp_phi", &m_trkExt_matchtp_phi); - eventTree->Branch("trkExt_matchtp_z0", &m_trkExt_matchtp_z0); - eventTree->Branch("trkExt_matchtp_dxy", &m_trkExt_matchtp_dxy); - // if (TrackingInJets) { - // eventTree->Branch("trk_injet", &m_trk_injet); - // eventTree->Branch("trk_injet_highpt", &m_trk_injet_highpt); - // eventTree->Branch("trk_injet_vhighpt", &m_trk_injet_vhighpt); - // } - } - eventTree->Branch("tp_pt", &m_tp_pt); - eventTree->Branch("tp_eta", &m_tp_eta); - eventTree->Branch("tp_phi", &m_tp_phi); - eventTree->Branch("tp_dxy", &m_tp_dxy); - eventTree->Branch("tp_d0", &m_tp_d0); - eventTree->Branch("tp_z0", &m_tp_z0); - eventTree->Branch("tp_d0_prod", &m_tp_d0_prod); - eventTree->Branch("tp_z0_prod", &m_tp_z0_prod); - eventTree->Branch("tp_pdgid", &m_tp_pdgid); - eventTree->Branch("tp_nmatch", &m_tp_nmatch); - eventTree->Branch("tp_nstub", &m_tp_nstub); - eventTree->Branch("tp_eventid", &m_tp_eventid); - eventTree->Branch("tp_charge", &m_tp_charge); - // if (TrackingInJets) { - // eventTree->Branch("tp_injet", &m_tp_injet); - // eventTree->Branch("tp_injet_highpt", &m_tp_injet_highpt); - // eventTree->Branch("tp_injet_vhighpt", &m_tp_injet_vhighpt); - // } - - if (Displaced == "Prompt" || Displaced == "Both") { - eventTree->Branch("matchtrk_pt", &m_matchtrk_pt); - eventTree->Branch("matchtrk_eta", &m_matchtrk_eta); - eventTree->Branch("matchtrk_phi", &m_matchtrk_phi); - eventTree->Branch("matchtrk_z0", &m_matchtrk_z0); - eventTree->Branch("matchtrk_d0", &m_matchtrk_d0); - eventTree->Branch("matchtrk_chi2", &m_matchtrk_chi2); - eventTree->Branch("matchtrk_chi2dof", &m_matchtrk_chi2dof); - eventTree->Branch("matchtrk_chi2rphi", &m_matchtrk_chi2rphi); - eventTree->Branch("matchtrk_chi2rz", &m_matchtrk_chi2rz); - eventTree->Branch("matchtrk_bendchi2", &m_matchtrk_bendchi2); - eventTree->Branch("matchtrk_nstub", &m_matchtrk_nstub); - eventTree->Branch("matchtrk_lhits", &m_matchtrk_lhits); - eventTree->Branch("matchtrk_dhits", &m_matchtrk_dhits); - eventTree->Branch("matchtrk_seed", &m_matchtrk_seed); - eventTree->Branch("matchtrk_hitpattern", &m_matchtrk_hitpattern); - // if (TrackingInJets) { - // eventTree->Branch("matchtrk_injet", &m_matchtrk_injet); - // eventTree->Branch("matchtrk_injet_highpt", &m_matchtrk_injet_highpt); - // eventTree->Branch("matchtrk_injet_vhighpt", &m_matchtrk_injet_vhighpt); - // } - } - - if (Displaced == "Displaced" || Displaced == "Both") { - eventTree->Branch("matchtrkExt_pt", &m_matchtrkExt_pt); - eventTree->Branch("matchtrkExt_eta", &m_matchtrkExt_eta); - eventTree->Branch("matchtrkExt_phi", &m_matchtrkExt_phi); - eventTree->Branch("matchtrkExt_z0", &m_matchtrkExt_z0); - eventTree->Branch("matchtrkExt_d0", &m_matchtrkExt_d0); - eventTree->Branch("matchtrkExt_chi2", &m_matchtrkExt_chi2); - eventTree->Branch("matchtrkExt_chi2dof", &m_matchtrkExt_chi2dof); - eventTree->Branch("matchtrkExt_chi2rphi", &m_matchtrkExt_chi2rphi); - eventTree->Branch("matchtrkExt_chi2rz", &m_matchtrkExt_chi2rz); - eventTree->Branch("matchtrkExt_bendchi2", &m_matchtrkExt_bendchi2); - eventTree->Branch("matchtrkExt_nstub", &m_matchtrkExt_nstub); - eventTree->Branch("matchtrkExt_lhits", &m_matchtrkExt_lhits); - eventTree->Branch("matchtrkExt_dhits", &m_matchtrkExt_dhits); - eventTree->Branch("matchtrkExt_seed", &m_matchtrkExt_seed); - eventTree->Branch("matchtrkExt_hitpattern", &m_matchtrkExt_hitpattern); - // if (TrackingInJets) { - // eventTree->Branch("matchtrk_injet", &m_matchtrk_injet); - // eventTree->Branch("matchtrk_injet_highpt", &m_matchtrk_injet_highpt); - // eventTree->Branch("matchtrk_injet_vhighpt", &m_matchtrk_injet_vhighpt); - // } - } - - if (SaveStubs) { - eventTree->Branch("allstub_x", &m_allstub_x); - eventTree->Branch("allstub_y", &m_allstub_y); - eventTree->Branch("allstub_z", &m_allstub_z); - eventTree->Branch("allstub_isBarrel", &m_allstub_isBarrel); - eventTree->Branch("allstub_layer", &m_allstub_layer); - eventTree->Branch("allstub_isPSmodule", &m_allstub_isPSmodule); - eventTree->Branch("allstub_trigDisplace", &m_allstub_trigDisplace); - eventTree->Branch("allstub_trigOffset", &m_allstub_trigOffset); - eventTree->Branch("allstub_trigPos", &m_allstub_trigPos); - eventTree->Branch("allstub_trigBend", &m_allstub_trigBend); - eventTree->Branch("allstub_matchTP_pdgid", &m_allstub_matchTP_pdgid); - eventTree->Branch("allstub_matchTP_pt", &m_allstub_matchTP_pt); - eventTree->Branch("allstub_matchTP_eta", &m_allstub_matchTP_eta); - eventTree->Branch("allstub_matchTP_phi", &m_allstub_matchTP_phi); - eventTree->Branch("allstub_genuine", &m_allstub_genuine); - } - - if (SaveTrackJets) { - // eventTree->Branch("pv_L1recotruesumpt", &m_pv_L1recotruesumpt); - // eventTree->Branch("pv_L1recosumpt", &m_pv_L1recosumpt); - eventTree->Branch("pv_L1reco", &m_pv_L1reco); - // eventTree->Branch("pv_L1TP", &m_pv_L1TP); - // eventTree->Branch("pv_L1TPsumpt", &m_pv_L1TPsumpt); - eventTree->Branch("MC_lep", &m_MC_lep); - // eventTree->Branch("pv_MCChgSumpT", &m_pv_MCChgSumpT); - eventTree->Branch("pv_MC", &m_pv_MC); - - if (Displaced == "Prompt" || Displaced == "Both") { - eventTree->Branch("2ltrkjet_eta", &m_2ltrkjet_eta); - eventTree->Branch("2ltrkjet_vz", &m_2ltrkjet_vz); - eventTree->Branch("2ltrkjet_p", &m_2ltrkjet_p); - eventTree->Branch("2ltrkjet_pt", &m_2ltrkjet_pt); - eventTree->Branch("2ltrkjet_phi", &m_2ltrkjet_phi); - eventTree->Branch("2ltrkjet_ntracks", &m_2ltrkjet_ntracks); - eventTree->Branch("2ltrkjet_nDisplaced", &m_2ltrkjet_nDisplaced); - eventTree->Branch("2ltrkjet_nTight", &m_2ltrkjet_nTight); - eventTree->Branch("2ltrkjet_nTightDisplaced", &m_2ltrkjet_nTightDisplaced); - eventTree->Branch("trkjet_eta", &m_trkjet_eta); - eventTree->Branch("trkjet_vz", &m_trkjet_vz); - eventTree->Branch("trkjet_p", &m_trkjet_p); - eventTree->Branch("trkjet_pt", &m_trkjet_pt); - eventTree->Branch("trkjet_phi", &m_trkjet_phi); - eventTree->Branch("trkjet_ntracks", &m_trkjet_ntracks); - eventTree->Branch("trkjet_truetp_sumpt", m_trkjet_truetp_sumpt); - } - if (Displaced == "Displaced" || Displaced == "Both") { - eventTree->Branch("2ltrkjetExt_eta", &m_2ltrkjetExt_eta); - eventTree->Branch("2ltrkjetExt_vz", &m_2ltrkjetExt_vz); - eventTree->Branch("2ltrkjetExt_p", &m_2ltrkjetExt_p); - eventTree->Branch("2ltrkjetExt_pt", &m_2ltrkjetExt_pt); - eventTree->Branch("2ltrkjetExt_phi", &m_2ltrkjetExt_phi); - eventTree->Branch("2ltrkjetExt_ntracks", &m_2ltrkjetExt_ntracks); - eventTree->Branch("2ltrkjetExt_nDisplaced", &m_2ltrkjetExt_nDisplaced); - eventTree->Branch("2ltrkjetExt_nTight", &m_2ltrkjetExt_nTight); - eventTree->Branch("2ltrkjetExt_nTightDisplaced", &m_2ltrkjetExt_nTightDisplaced); - eventTree->Branch("trkjetExt_eta", &m_trkjetExt_eta); - eventTree->Branch("trkjetExt_vz", &m_trkjetExt_vz); - eventTree->Branch("trkjetExt_p", &m_trkjetExt_p); - eventTree->Branch("trkjetExt_pt", &m_trkjetExt_pt); - eventTree->Branch("trkjetExt_phi", &m_trkjetExt_phi); - eventTree->Branch("trkjetExt_ntracks", &m_trkjetExt_ntracks); - eventTree->Branch("trkjetExt_truetp_sumpt", m_trkjetExt_truetp_sumpt); - } - } - - if (SaveTrackMET) { - eventTree->Branch("trueMET", &trueMET, "trueMET/F"); - - if (Displaced == "Prompt" || Displaced == "Both") { - eventTree->Branch("trkMET", &trkMET, "trkMET/F"); - eventTree->Branch("trkMHT", &trkMHT, "trkMHT/F"); - eventTree->Branch("trkHT", &trkHT, "trkHT/F"); - } - if (Displaced == "Displaced" || Displaced == "Both") { - eventTree->Branch("trkMETExt", &trkMETExt, "trkMETExt/F"); - eventTree->Branch("trkMHTExt", &trkMHTExt, "trkMHTExt/F"); - eventTree->Branch("trkHTExt", &trkHTExt, "trkHTExt/F"); - } - } -} - -////////// -// ANALYZE -void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { - if (not available_) - return; // No ROOT file open. - - if (!(MyProcess == 13 || MyProcess == 11 || MyProcess == 211 || MyProcess == 6 || MyProcess == 15 || - MyProcess == 1)) { - edm::LogVerbatim("Tracklet") << "The specified MyProcess is invalid! Exiting..."; - return; - } - - // clear variables - if (SaveAllTracks && (Displaced == "Prompt" || Displaced == "Both")) { - m_trk_pt->clear(); - m_trk_eta->clear(); - m_trk_phi->clear(); - m_trk_d0->clear(); - m_trk_z0->clear(); - m_trk_chi2->clear(); - m_trk_chi2dof->clear(); - m_trk_chi2rphi->clear(); - m_trk_chi2rz->clear(); - m_trk_bendchi2->clear(); - m_trk_nstub->clear(); - m_trk_lhits->clear(); - m_trk_dhits->clear(); - m_trk_seed->clear(); - m_trk_hitpattern->clear(); - m_trk_phiSector->clear(); - m_trk_genuine->clear(); - m_trk_loose->clear(); - m_trk_unknown->clear(); - m_trk_combinatoric->clear(); - m_trk_fake->clear(); - m_trk_matchtp_pdgid->clear(); - m_trk_matchtp_pt->clear(); - m_trk_matchtp_eta->clear(); - m_trk_matchtp_phi->clear(); - m_trk_matchtp_z0->clear(); - m_trk_matchtp_dxy->clear(); - } - if (SaveAllTracks && (Displaced == "Displaced" || Displaced == "Both")) { - m_trkExt_pt->clear(); - m_trkExt_eta->clear(); - m_trkExt_phi->clear(); - m_trkExt_d0->clear(); - m_trkExt_z0->clear(); - m_trkExt_chi2->clear(); - m_trkExt_chi2dof->clear(); - m_trkExt_chi2rphi->clear(); - m_trkExt_chi2rz->clear(); - m_trkExt_bendchi2->clear(); - m_trkExt_nstub->clear(); - m_trkExt_lhits->clear(); - m_trkExt_dhits->clear(); - m_trkExt_seed->clear(); - m_trkExt_hitpattern->clear(); - m_trkExt_phiSector->clear(); - m_trkExt_genuine->clear(); - m_trkExt_loose->clear(); - m_trkExt_unknown->clear(); - m_trkExt_combinatoric->clear(); - m_trkExt_fake->clear(); - m_trkExt_matchtp_pdgid->clear(); - m_trkExt_matchtp_pt->clear(); - m_trkExt_matchtp_eta->clear(); - m_trkExt_matchtp_phi->clear(); - m_trkExt_matchtp_z0->clear(); - m_trkExt_matchtp_dxy->clear(); - } - m_tp_pt->clear(); - m_tp_eta->clear(); - m_tp_phi->clear(); - m_tp_dxy->clear(); - m_tp_d0->clear(); - m_tp_z0->clear(); - m_tp_d0_prod->clear(); - m_tp_z0_prod->clear(); - m_tp_pdgid->clear(); - m_tp_nmatch->clear(); - m_tp_nstub->clear(); - m_tp_eventid->clear(); - m_tp_charge->clear(); - - if (Displaced == "Prompt" || Displaced == "Both") { - m_matchtrk_pt->clear(); - m_matchtrk_eta->clear(); - m_matchtrk_phi->clear(); - m_matchtrk_z0->clear(); - m_matchtrk_d0->clear(); - m_matchtrk_chi2->clear(); - m_matchtrk_chi2dof->clear(); - m_matchtrk_chi2rphi->clear(); - m_matchtrk_chi2rz->clear(); - m_matchtrk_bendchi2->clear(); - m_matchtrk_nstub->clear(); - m_matchtrk_lhits->clear(); - m_matchtrk_dhits->clear(); - m_matchtrk_seed->clear(); - m_matchtrk_hitpattern->clear(); - } - - if (Displaced == "Displaced" || Displaced == "Both") { - m_matchtrkExt_pt->clear(); - m_matchtrkExt_eta->clear(); - m_matchtrkExt_phi->clear(); - m_matchtrkExt_z0->clear(); - m_matchtrkExt_d0->clear(); - m_matchtrkExt_chi2->clear(); - m_matchtrkExt_chi2dof->clear(); - m_matchtrkExt_chi2rphi->clear(); - m_matchtrkExt_chi2rz->clear(); - m_matchtrkExt_bendchi2->clear(); - m_matchtrkExt_nstub->clear(); - m_matchtrkExt_lhits->clear(); - m_matchtrkExt_dhits->clear(); - m_matchtrkExt_seed->clear(); - m_matchtrkExt_hitpattern->clear(); - } - - if (SaveStubs) { - m_allstub_x->clear(); - m_allstub_y->clear(); - m_allstub_z->clear(); - m_allstub_isBarrel->clear(); - m_allstub_layer->clear(); - m_allstub_isPSmodule->clear(); - m_allstub_trigDisplace->clear(); - m_allstub_trigOffset->clear(); - m_allstub_trigPos->clear(); - m_allstub_trigBend->clear(); - m_allstub_matchTP_pdgid->clear(); - m_allstub_matchTP_pt->clear(); - m_allstub_matchTP_eta->clear(); - m_allstub_matchTP_phi->clear(); - m_allstub_genuine->clear(); - } - - // m_jet_eta->clear(); - // m_jet_phi->clear(); - // m_jet_pt->clear(); - // m_jet_tp_sumpt->clear(); - // m_jet_trk_sumpt->clear(); - // m_jet_matchtrk_sumpt->clear(); - - if (SaveTrackJets) { - if (Displaced == "Prompt" || Displaced == "Both") { - m_2ltrkjet_eta->clear(); - m_2ltrkjet_pt->clear(); - m_2ltrkjet_vz->clear(); - m_2ltrkjet_phi->clear(); - m_2ltrkjet_p->clear(); - m_2ltrkjet_ntracks->clear(); - m_2ltrkjet_nDisplaced->clear(); - m_2ltrkjet_nTight->clear(); - m_2ltrkjet_nTightDisplaced->clear(); - m_2ltrkjet_ntdtrk->clear(); - m_trkjet_eta->clear(); - m_trkjet_pt->clear(); - m_trkjet_vz->clear(); - m_trkjet_phi->clear(); - m_trkjet_p->clear(); - m_trkjet_ntracks->clear(); - m_trkjet_truetp_sumpt->clear(); - m_trkjet_tp_sumpt->clear(); - } - if (Displaced == "Displaced" || Displaced == "Both") { - m_2ltrkjetExt_eta->clear(); - m_2ltrkjetExt_pt->clear(); - m_2ltrkjetExt_vz->clear(); - m_2ltrkjetExt_phi->clear(); - m_2ltrkjetExt_p->clear(); - m_2ltrkjetExt_ntracks->clear(); - m_2ltrkjetExt_nDisplaced->clear(); - m_2ltrkjetExt_nTight->clear(); - m_2ltrkjetExt_nTightDisplaced->clear(); - m_2ltrkjetExt_ntdtrk->clear(); - m_trkjetExt_eta->clear(); - m_trkjetExt_pt->clear(); - m_trkjetExt_vz->clear(); - m_trkjetExt_phi->clear(); - m_trkjetExt_p->clear(); - m_trkjetExt_ntracks->clear(); - m_trkjetExt_truetp_sumpt->clear(); - m_trkjetExt_tp_sumpt->clear(); - } - - // m_pv_L1recotruesumpt->clear(); - // m_pv_L1recosumpt->clear(); - m_pv_L1reco->clear(); - // m_pv_L1TPsumpt->clear(); - // m_pv_L1TP->clear(); - m_pv_MC->clear(); - m_MC_lep->clear(); - // m_pv_MCChgSumpT->clear(); - } - - // ----------------------------------------------------------------------------------------------- - // retrieve various containers - // ----------------------------------------------------------------------------------------------- - - // L1 stubs - edm::Handle > > TTStubHandle; - if (SaveStubs) - iEvent.getByToken(ttStubToken_, TTStubHandle); - - // MC truth association maps - edm::Handle > MCTruthTTClusterHandle; - iEvent.getByToken(ttClusterMCTruthToken_, MCTruthTTClusterHandle); - edm::Handle > MCTruthTTStubHandle; - iEvent.getByToken(ttStubMCTruthToken_, MCTruthTTStubHandle); - - // tracking particles - edm::Handle > TrackingParticleHandle; - edm::Handle > TrackingVertexHandle; - iEvent.getByToken(TrackingParticleToken_, TrackingParticleHandle); - iEvent.getByToken(TrackingVertexToken_, TrackingVertexHandle); - - // ----------------------------------------------------------------------------------------------- - // more for TTStubs - const TrackerTopology& tTopo = iSetup.getData(tTopoToken_); - const TrackerGeometry& tGeom = iSetup.getData(tGeomToken_); - - /*edm::ESHandle geometryHandle; - iSetup.get().get(geometryHandle); - - edm::ESHandle tTopoHandle; - iSetup.get().get(tTopoHandle); - - edm::ESHandle tGeomHandle; - iSetup.get().get(tGeomHandle); - - const TrackerTopology* const tTopo = tTopoHandle.product(); - const TrackerGeometry* const theTrackerGeom = tGeomHandle.product();*/ - - //Gen particles - edm::Handle > GenParticleHandle; - iEvent.getByToken(GenParticleToken_, GenParticleHandle); - - //Vertex - edm::Handle L1TkPrimaryVertexHandle; - iEvent.getByToken(L1VertexToken_, L1TkPrimaryVertexHandle); - - // Track jets - edm::Handle > TrackFastJetsHandle; - edm::Handle > TrackFastJetsExtendedHandle; - edm::Handle TrackJetsHandle; - edm::Handle TrackJetsExtendedHandle; - std::vector::const_iterator jetIter; - - // Track MET - edm::Handle > L1TkMETHandle; - edm::Handle > L1TkMETExtendedHandle; - edm::Handle > L1TkMHTHandle; - edm::Handle > L1TkMHTExtendedHandle; - - // L1 tracks - edm::Handle > > TTTrackHandle; - edm::Handle > > TTTrackExtendedHandle; - edm::Handle > MCTruthTTTrackHandle; - edm::Handle > MCTruthTTTrackExtendedHandle; - std::vector >::const_iterator iterL1Track; - - if (Displaced == "Prompt" || Displaced == "Both") { - iEvent.getByToken(TrackFastJetsToken_, TrackFastJetsHandle); - iEvent.getByToken(TrackJetsToken_, TrackJetsHandle); - iEvent.getByToken(TrackMETToken_, L1TkMETHandle); - iEvent.getByToken(TrackMHTToken_, L1TkMHTHandle); - iEvent.getByToken(ttTrackToken_, TTTrackHandle); - iEvent.getByToken(ttTrackMCTruthToken_, MCTruthTTTrackHandle); - } - if (Displaced == "Displaced" || Displaced == "Both") { - iEvent.getByToken(TrackFastJetsExtendedToken_, TrackFastJetsExtendedHandle); - iEvent.getByToken(TrackJetsExtendedToken_, TrackJetsExtendedHandle); - iEvent.getByToken(TrackMETExtendedToken_, L1TkMETExtendedHandle); - iEvent.getByToken(TrackMHTExtendedToken_, L1TkMHTExtendedHandle); - iEvent.getByToken(ttTrackExtendedToken_, TTTrackExtendedHandle); - iEvent.getByToken(ttTrackMCTruthExtendedToken_, MCTruthTTTrackExtendedHandle); - } - - //Loop over gen particles - if (GenParticleHandle.isValid()) { - vector::const_iterator genpartIter; - - float zvtx_gen = -999; - for (genpartIter = GenParticleHandle->begin(); genpartIter != GenParticleHandle->end(); ++genpartIter) { - int status = genpartIter->status(); - if (status != 1) - continue; - zvtx_gen = genpartIter->vz(); - } - m_pv_MC->push_back(zvtx_gen); - - float trueMETx = 0; - float trueMETy = 0; - trueMET = 0; - for (size_t i = 0; i < GenParticleHandle->size(); ++i) { - const reco::GenParticle& p = (*GenParticleHandle)[i]; - int id = p.pdgId(); - bool isNeutrino = false; - if ((fabs(id) == 12 || fabs(id) == 14 || fabs(id) == 16)) - isNeutrino = true; - if ((isNeutrino || id == 1000022) && p.status() == 1) { - trueMETx += p.pt() * cos(p.phi()); - trueMETy += p.pt() * sin(p.phi()); - } - } - trueMET = sqrt(trueMETx * trueMETx + trueMETy * trueMETy); - } else { - edm::LogWarning("DataNotFound") << "\nWarning: GenParticleHandle not found in the event" << std::endl; - } - - // ---------------------------------------------------------------------------------------------- - // loop over L1 stubs - // ---------------------------------------------------------------------------------------------- - if (SaveStubs) { - for (auto gd = tGeom.dets().begin(); gd != tGeom.dets().end(); gd++) { - DetId detid = (*gd)->geographicalId(); - if (detid.subdetId() != StripSubdetector::TOB && detid.subdetId() != StripSubdetector::TID) - continue; - if (!tTopo.isLower(detid)) - continue; // loop on the stacks: choose the lower arbitrarily - DetId stackDetid = tTopo.stack(detid); // Stub module detid - - if (TTStubHandle->find(stackDetid) == TTStubHandle->end()) - continue; - - // Get the DetSets of the Clusters - edmNew::DetSet > stubs = (*TTStubHandle)[stackDetid]; - const GeomDetUnit* det0 = tGeom.idToDetUnit(detid); - const auto* theGeomDet = dynamic_cast(det0); - const PixelTopology* topol = dynamic_cast(&(theGeomDet->specificTopology())); - - // loop over stubs - for (auto stubIter = stubs.begin(); stubIter != stubs.end(); ++stubIter) { - edm::Ref >, TTStub > tempStubPtr = - edmNew::makeRefTo(TTStubHandle, stubIter); - - int isBarrel = 0; - int layer = -999999; - if (detid.subdetId() == StripSubdetector::TOB) { - isBarrel = 1; - layer = static_cast(tTopo.layer(detid)); - } else if (detid.subdetId() == StripSubdetector::TID) { - isBarrel = 0; - layer = static_cast(tTopo.layer(detid)); - } else { - edm::LogVerbatim("Tracklet") << "WARNING -- neither TOB or TID stub, shouldn't happen..."; - layer = -1; - } - - int isPSmodule = 0; - if (topol->nrows() == 960) - isPSmodule = 1; - - MeasurementPoint coords = tempStubPtr->clusterRef(0)->findAverageLocalCoordinatesCentered(); - LocalPoint clustlp = topol->localPosition(coords); - GlobalPoint posStub = theGeomDet->surface().toGlobal(clustlp); - - double tmp_stub_x = posStub.x(); - double tmp_stub_y = posStub.y(); - double tmp_stub_z = posStub.z(); - - float trigDisplace = tempStubPtr->rawBend(); - float trigOffset = tempStubPtr->bendOffset(); - float trigPos = tempStubPtr->innerClusterPosition(); - float trigBend = tempStubPtr->bendFE(); - - m_allstub_x->push_back(tmp_stub_x); - m_allstub_y->push_back(tmp_stub_y); - m_allstub_z->push_back(tmp_stub_z); - m_allstub_isBarrel->push_back(isBarrel); - m_allstub_layer->push_back(layer); - m_allstub_isPSmodule->push_back(isPSmodule); - m_allstub_trigDisplace->push_back(trigDisplace); - m_allstub_trigOffset->push_back(trigOffset); - m_allstub_trigPos->push_back(trigPos); - m_allstub_trigBend->push_back(trigBend); - - // matched to tracking particle? - edm::Ptr my_tp = MCTruthTTStubHandle->findTrackingParticlePtr(tempStubPtr); - - int myTP_pdgid = -999; - float myTP_pt = -999; - float myTP_eta = -999; - float myTP_phi = -999; - - if (my_tp.isNull() == false) { - int tmp_eventid = my_tp->eventId().event(); - if (tmp_eventid > 0) - continue; // this means stub from pileup track - myTP_pdgid = my_tp->pdgId(); - myTP_pt = my_tp->p4().pt(); - myTP_eta = my_tp->p4().eta(); - myTP_phi = my_tp->p4().phi(); - } - int tmp_stub_genuine = 0; - if (MCTruthTTStubHandle->isGenuine(tempStubPtr)) - tmp_stub_genuine = 1; - - m_allstub_matchTP_pdgid->push_back(myTP_pdgid); - m_allstub_matchTP_pt->push_back(myTP_pt); - m_allstub_matchTP_eta->push_back(myTP_eta); - m_allstub_matchTP_phi->push_back(myTP_phi); - m_allstub_genuine->push_back(tmp_stub_genuine); - } - } - } - - // ---------------------------------------------------------------------------------------------- - // loop over (prompt) L1 tracks - // ---------------------------------------------------------------------------------------------- - if (SaveAllTracks && (Displaced == "Prompt" || Displaced == "Both")) { - if (DebugMode) { - edm::LogVerbatim("Tracklet") << "\n Loop over L1 tracks!"; - edm::LogVerbatim("Tracklet") << "\n Looking at " << Displaced << " tracks!"; - } - - int this_l1track = 0; - for (iterL1Track = TTTrackHandle->begin(); iterL1Track != TTTrackHandle->end(); iterL1Track++) { - edm::Ptr > l1track_ptr(TTTrackHandle, this_l1track); - this_l1track++; - - float tmp_trk_pt = iterL1Track->momentum().perp(); - float tmp_trk_eta = iterL1Track->momentum().eta(); - float tmp_trk_phi = iterL1Track->momentum().phi(); - float tmp_trk_z0 = iterL1Track->z0(); //cm - int tmp_trk_nFitPars = iterL1Track->nFitPars(); //4 or 5 - - float tmp_trk_d0 = -999; - if (tmp_trk_nFitPars == 5) { - float tmp_trk_x0 = iterL1Track->POCA().x(); - float tmp_trk_y0 = iterL1Track->POCA().y(); - tmp_trk_d0 = -tmp_trk_x0 * sin(tmp_trk_phi) + tmp_trk_y0 * cos(tmp_trk_phi); - // tmp_trk_d0 = iterL1Track->d0(); - } - - float tmp_trk_chi2 = iterL1Track->chi2(); - float tmp_trk_chi2dof = iterL1Track->chi2Red(); - float tmp_trk_chi2rphi = iterL1Track->chi2XY(); - float tmp_trk_chi2rz = iterL1Track->chi2Z(); - float tmp_trk_bendchi2 = iterL1Track->stubPtConsistency(); - - std::vector >, TTStub > > - stubRefs = iterL1Track->getStubRefs(); - int tmp_trk_nstub = (int)stubRefs.size(); - int tmp_trk_seed = 0; - tmp_trk_seed = (int)iterL1Track->trackSeedType(); - int tmp_trk_hitpattern = 0; - tmp_trk_hitpattern = (int)iterL1Track->hitPattern(); - unsigned int tmp_trk_phiSector = iterL1Track->phiSector(); - - // ---------------------------------------------------------------------------------------------- - // loop over stubs on tracks - int tmp_trk_dhits = 0; - int tmp_trk_lhits = 0; - if (true) { - // loop over stubs - for (int is = 0; is < tmp_trk_nstub; is++) { - //detID of stub - DetId detIdStub = tGeom.idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); - MeasurementPoint coords = stubRefs.at(is)->clusterRef(0)->findAverageLocalCoordinatesCentered(); - const GeomDet* theGeomDet = tGeom.idToDet(detIdStub); - Global3DPoint posStub = theGeomDet->surface().toGlobal(theGeomDet->topology().localPosition(coords)); - - double x = posStub.x(); - double y = posStub.y(); - double z = posStub.z(); - - int layer = -999999; - if (detIdStub.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo.layer(detIdStub)); - if (DebugMode) - edm::LogVerbatim("Tracklet") - << " stub in layer " << layer << " at position x y z = " << x << " " << y << " " << z; - tmp_trk_lhits += pow(10, layer - 1); - } else if (detIdStub.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo.layer(detIdStub)); - if (DebugMode) - edm::LogVerbatim("Tracklet") - << " stub in disk " << layer << " at position x y z = " << x << " " << y << " " << z; - tmp_trk_dhits += pow(10, layer - 1); - } - } //end loop over stubs - } - // ---------------------------------------------------------------------------------------------- - - int tmp_trk_genuine = 0; - int tmp_trk_loose = 0; - int tmp_trk_unknown = 0; - int tmp_trk_combinatoric = 0; - if (MCTruthTTTrackHandle->isLooselyGenuine(l1track_ptr)) - tmp_trk_loose = 1; - if (MCTruthTTTrackHandle->isGenuine(l1track_ptr)) - tmp_trk_genuine = 1; - if (MCTruthTTTrackHandle->isUnknown(l1track_ptr)) - tmp_trk_unknown = 1; - if (MCTruthTTTrackHandle->isCombinatoric(l1track_ptr)) - tmp_trk_combinatoric = 1; - - if (DebugMode) { - edm::LogVerbatim("Tracklet") << "L1 track," - << " pt: " << tmp_trk_pt << " eta: " << tmp_trk_eta << " phi: " << tmp_trk_phi - << " z0: " << tmp_trk_z0 << " chi2: " << tmp_trk_chi2 - << " chi2rphi: " << tmp_trk_chi2rphi << " chi2rz: " << tmp_trk_chi2rz - << " nstub: " << tmp_trk_nstub; - if (tmp_trk_genuine) - edm::LogVerbatim("Tracklet") << " (is genuine)"; - if (tmp_trk_unknown) - edm::LogVerbatim("Tracklet") << " (is unknown)"; - if (tmp_trk_combinatoric) - edm::LogVerbatim("Tracklet") << " (is combinatoric)"; - } - - m_trk_pt->push_back(tmp_trk_pt); - m_trk_eta->push_back(tmp_trk_eta); - m_trk_phi->push_back(tmp_trk_phi); - m_trk_z0->push_back(tmp_trk_z0); - if (tmp_trk_nFitPars == 5) - m_trk_d0->push_back(tmp_trk_d0); - else - m_trk_d0->push_back(999.); - m_trk_chi2->push_back(tmp_trk_chi2); - m_trk_chi2dof->push_back(tmp_trk_chi2dof); - m_trk_chi2rphi->push_back(tmp_trk_chi2rphi); - m_trk_chi2rz->push_back(tmp_trk_chi2rz); - m_trk_bendchi2->push_back(tmp_trk_bendchi2); - m_trk_nstub->push_back(tmp_trk_nstub); - m_trk_dhits->push_back(tmp_trk_dhits); - m_trk_lhits->push_back(tmp_trk_lhits); - m_trk_seed->push_back(tmp_trk_seed); - m_trk_hitpattern->push_back(tmp_trk_hitpattern); - m_trk_phiSector->push_back(tmp_trk_phiSector); - m_trk_genuine->push_back(tmp_trk_genuine); - m_trk_loose->push_back(tmp_trk_loose); - m_trk_unknown->push_back(tmp_trk_unknown); - m_trk_combinatoric->push_back(tmp_trk_combinatoric); - - // ---------------------------------------------------------------------------------------------- - // for studying the fake rate - // ---------------------------------------------------------------------------------------------- - edm::Ptr my_tp = MCTruthTTTrackHandle->findTrackingParticlePtr(l1track_ptr); - - int myFake = 0; - int myTP_pdgid = -999; - float myTP_pt = -999; - float myTP_eta = -999; - float myTP_phi = -999; - float myTP_z0 = -999; - float myTP_dxy = -999; - - if (my_tp.isNull()) - myFake = 0; - else { - int tmp_eventid = my_tp->eventId().event(); - if (tmp_eventid > 0) - myFake = 2; - else - myFake = 1; - - myTP_pdgid = my_tp->pdgId(); - myTP_pt = my_tp->p4().pt(); - myTP_eta = my_tp->p4().eta(); - myTP_phi = my_tp->p4().phi(); - myTP_z0 = my_tp->vertex().z(); - - float myTP_x0 = my_tp->vertex().x(); - float myTP_y0 = my_tp->vertex().y(); - myTP_dxy = sqrt(myTP_x0 * myTP_x0 + myTP_y0 * myTP_y0); - - if (DebugMode) { - edm::LogVerbatim("Tracklet") << "TP matched to track has pt = " << my_tp->p4().pt() - << " eta = " << my_tp->momentum().eta() << " phi = " << my_tp->momentum().phi() - << " z0 = " << my_tp->vertex().z() << " pdgid = " << my_tp->pdgId() - << " dxy = " << myTP_dxy; - } - } - - m_trk_fake->push_back(myFake); - m_trk_matchtp_pdgid->push_back(myTP_pdgid); - m_trk_matchtp_pt->push_back(myTP_pt); - m_trk_matchtp_eta->push_back(myTP_eta); - m_trk_matchtp_phi->push_back(myTP_phi); - m_trk_matchtp_z0->push_back(myTP_z0); - m_trk_matchtp_dxy->push_back(myTP_dxy); - } //end track loop - } //end if SaveAllTracks - - // ---------------------------------------------------------------------------------------------- - // loop over (extended) L1 tracks - // ---------------------------------------------------------------------------------------------- - if (SaveAllTracks && (Displaced == "Displaced" || Displaced == "Both")) { - if (DebugMode) { - edm::LogVerbatim("Tracklet") << "\n Loop over L1 tracks!"; - edm::LogVerbatim("Tracklet") << "\n Looking at " << Displaced << " tracks!"; - } - - int this_l1track = 0; - for (iterL1Track = TTTrackExtendedHandle->begin(); iterL1Track != TTTrackExtendedHandle->end(); iterL1Track++) { - edm::Ptr > l1track_ptr(TTTrackExtendedHandle, this_l1track); - this_l1track++; - - float tmp_trk_pt = iterL1Track->momentum().perp(); - float tmp_trk_eta = iterL1Track->momentum().eta(); - float tmp_trk_phi = iterL1Track->momentum().phi(); - float tmp_trk_z0 = iterL1Track->z0(); //cm - int tmp_trk_nFitPars = iterL1Track->nFitPars(); //4 or 5 - - float tmp_trk_d0 = -999; - if (tmp_trk_nFitPars == 5) { - float tmp_trk_x0 = iterL1Track->POCA().x(); - float tmp_trk_y0 = iterL1Track->POCA().y(); - tmp_trk_d0 = -tmp_trk_x0 * sin(tmp_trk_phi) + tmp_trk_y0 * cos(tmp_trk_phi); - // tmp_trk_d0 = iterL1Track->d0(); - } - - float tmp_trk_chi2 = iterL1Track->chi2(); - float tmp_trk_chi2dof = iterL1Track->chi2Red(); - float tmp_trk_chi2rphi = iterL1Track->chi2XY(); - float tmp_trk_chi2rz = iterL1Track->chi2Z(); - float tmp_trk_bendchi2 = iterL1Track->stubPtConsistency(); - - std::vector >, TTStub > > - stubRefs = iterL1Track->getStubRefs(); - int tmp_trk_nstub = (int)stubRefs.size(); - int tmp_trk_seed = 0; - tmp_trk_seed = (int)iterL1Track->trackSeedType(); - int tmp_trk_hitpattern = 0; - tmp_trk_hitpattern = (int)iterL1Track->hitPattern(); - unsigned int tmp_trk_phiSector = iterL1Track->phiSector(); - - // ---------------------------------------------------------------------------------------------- - // loop over stubs on tracks - int tmp_trk_dhits = 0; - int tmp_trk_lhits = 0; - if (true) { - // loop over stubs - for (int is = 0; is < tmp_trk_nstub; is++) { - //detID of stub - DetId detIdStub = tGeom.idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); - MeasurementPoint coords = stubRefs.at(is)->clusterRef(0)->findAverageLocalCoordinatesCentered(); - const GeomDet* theGeomDet = tGeom.idToDet(detIdStub); - Global3DPoint posStub = theGeomDet->surface().toGlobal(theGeomDet->topology().localPosition(coords)); - - double x = posStub.x(); - double y = posStub.y(); - double z = posStub.z(); - - int layer = -999999; - if (detIdStub.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo.layer(detIdStub)); - if (DebugMode) - edm::LogVerbatim("Tracklet") - << " stub in layer " << layer << " at position x y z = " << x << " " << y << " " << z; - tmp_trk_lhits += pow(10, layer - 1); - } else if (detIdStub.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo.layer(detIdStub)); - if (DebugMode) - edm::LogVerbatim("Tracklet") - << " stub in disk " << layer << " at position x y z = " << x << " " << y << " " << z; - tmp_trk_dhits += pow(10, layer - 1); - } - } //end loop over stubs - } - // ---------------------------------------------------------------------------------------------- - - int tmp_trk_genuine = 0; - int tmp_trk_loose = 0; - int tmp_trk_unknown = 0; - int tmp_trk_combinatoric = 0; - if (MCTruthTTTrackExtendedHandle->isLooselyGenuine(l1track_ptr)) - tmp_trk_loose = 1; - if (MCTruthTTTrackExtendedHandle->isGenuine(l1track_ptr)) - tmp_trk_genuine = 1; - if (MCTruthTTTrackExtendedHandle->isUnknown(l1track_ptr)) - tmp_trk_unknown = 1; - if (MCTruthTTTrackExtendedHandle->isCombinatoric(l1track_ptr)) - tmp_trk_combinatoric = 1; - - if (DebugMode) { - edm::LogVerbatim("Tracklet") << "L1 track," - << " pt: " << tmp_trk_pt << " eta: " << tmp_trk_eta << " phi: " << tmp_trk_phi - << " z0: " << tmp_trk_z0 << " chi2: " << tmp_trk_chi2 - << " chi2rphi: " << tmp_trk_chi2rphi << " chi2rz: " << tmp_trk_chi2rz - << " nstub: " << tmp_trk_nstub; - if (tmp_trk_genuine) - edm::LogVerbatim("Tracklet") << " (is genuine)"; - if (tmp_trk_unknown) - edm::LogVerbatim("Tracklet") << " (is unknown)"; - if (tmp_trk_combinatoric) - edm::LogVerbatim("Tracklet") << " (is combinatoric)"; - } - - m_trkExt_pt->push_back(tmp_trk_pt); - m_trkExt_eta->push_back(tmp_trk_eta); - m_trkExt_phi->push_back(tmp_trk_phi); - m_trkExt_z0->push_back(tmp_trk_z0); - if (tmp_trk_nFitPars == 5) - m_trkExt_d0->push_back(tmp_trk_d0); - else - m_trkExt_d0->push_back(999.); - m_trkExt_chi2->push_back(tmp_trk_chi2); - m_trkExt_chi2dof->push_back(tmp_trk_chi2dof); - m_trkExt_chi2rphi->push_back(tmp_trk_chi2rphi); - m_trkExt_chi2rz->push_back(tmp_trk_chi2rz); - m_trkExt_bendchi2->push_back(tmp_trk_bendchi2); - m_trkExt_nstub->push_back(tmp_trk_nstub); - m_trkExt_dhits->push_back(tmp_trk_dhits); - m_trkExt_lhits->push_back(tmp_trk_lhits); - m_trkExt_seed->push_back(tmp_trk_seed); - m_trkExt_hitpattern->push_back(tmp_trk_hitpattern); - m_trkExt_phiSector->push_back(tmp_trk_phiSector); - m_trkExt_genuine->push_back(tmp_trk_genuine); - m_trkExt_loose->push_back(tmp_trk_loose); - m_trkExt_unknown->push_back(tmp_trk_unknown); - m_trkExt_combinatoric->push_back(tmp_trk_combinatoric); - - // ---------------------------------------------------------------------------------------------- - // for studying the fake rate - // ---------------------------------------------------------------------------------------------- - edm::Ptr my_tp = MCTruthTTTrackExtendedHandle->findTrackingParticlePtr(l1track_ptr); - - int myFake = 0; - int myTP_pdgid = -999; - float myTP_pt = -999; - float myTP_eta = -999; - float myTP_phi = -999; - float myTP_z0 = -999; - float myTP_dxy = -999; - - if (my_tp.isNull()) - myFake = 0; - else { - int tmp_eventid = my_tp->eventId().event(); - if (tmp_eventid > 0) - myFake = 2; - else - myFake = 1; - - myTP_pdgid = my_tp->pdgId(); - myTP_pt = my_tp->p4().pt(); - myTP_eta = my_tp->p4().eta(); - myTP_phi = my_tp->p4().phi(); - myTP_z0 = my_tp->vertex().z(); - - float myTP_x0 = my_tp->vertex().x(); - float myTP_y0 = my_tp->vertex().y(); - myTP_dxy = sqrt(myTP_x0 * myTP_x0 + myTP_y0 * myTP_y0); - - if (DebugMode) { - edm::LogVerbatim("Tracklet") << "TP matched to track has pt = " << my_tp->p4().pt() - << " eta = " << my_tp->momentum().eta() << " phi = " << my_tp->momentum().phi() - << " z0 = " << my_tp->vertex().z() << " pdgid = " << my_tp->pdgId() - << " dxy = " << myTP_dxy; - } - } - - m_trkExt_fake->push_back(myFake); - m_trkExt_matchtp_pdgid->push_back(myTP_pdgid); - m_trkExt_matchtp_pt->push_back(myTP_pt); - m_trkExt_matchtp_eta->push_back(myTP_eta); - m_trkExt_matchtp_phi->push_back(myTP_phi); - m_trkExt_matchtp_z0->push_back(myTP_z0); - m_trkExt_matchtp_dxy->push_back(myTP_dxy); - } //end track loop - } //end if SaveAllTracks (displaced) - - // ---------------------------------------------------------------------------------------------- - // loop over tracking particles - // ---------------------------------------------------------------------------------------------- - if (DebugMode) - edm::LogVerbatim("Tracklet") << "\n Loop over tracking particles!"; - - int this_tp = 0; - std::vector::const_iterator iterTP; - for (iterTP = TrackingParticleHandle->begin(); iterTP != TrackingParticleHandle->end(); ++iterTP) { - edm::Ptr tp_ptr(TrackingParticleHandle, this_tp); - this_tp++; - - int tmp_eventid = iterTP->eventId().event(); - if (MyProcess != 1 && tmp_eventid > 0) - continue; //only care about tracking particles from the primary interaction (except for MyProcess==1, i.e. looking at all TPs) - - float tmp_tp_pt = iterTP->pt(); - float tmp_tp_eta = iterTP->eta(); - float tmp_tp_phi = iterTP->phi(); - float tmp_tp_vz = iterTP->vz(); - float tmp_tp_vx = iterTP->vx(); - float tmp_tp_vy = iterTP->vy(); - int tmp_tp_pdgid = iterTP->pdgId(); - float tmp_tp_z0_prod = tmp_tp_vz; - float tmp_tp_d0_prod = tmp_tp_vx * sin(tmp_tp_phi) - tmp_tp_vy * cos(tmp_tp_phi); - - if (MyProcess == 13 && abs(tmp_tp_pdgid) != 13) - continue; - if (MyProcess == 11 && abs(tmp_tp_pdgid) != 11) - continue; - if ((MyProcess == 6 || MyProcess == 15 || MyProcess == 211) && abs(tmp_tp_pdgid) != 211) - continue; - - if (tmp_tp_pt < TP_minPt) - continue; - if (std::abs(tmp_tp_eta) > TP_maxEta) - continue; - - // ---------------------------------------------------------------------------------------------- - // get d0/z0 propagated back to the IP - - float tmp_tp_t = tan(2.0 * atan(1.0) - 2.0 * atan(exp(-tmp_tp_eta))); - float delx = -tmp_tp_vx; - float dely = -tmp_tp_vy; - - float A = 0.01 * 0.5696; - float Kmagnitude = A / tmp_tp_pt; - float tmp_tp_charge = tp_ptr->charge(); - float K = Kmagnitude * tmp_tp_charge; - float d = 0; - float tmp_tp_x0p = delx - (d + 1. / (2. * K) * sin(tmp_tp_phi)); - float tmp_tp_y0p = dely + (d + 1. / (2. * K) * cos(tmp_tp_phi)); - float tmp_tp_rp = sqrt(tmp_tp_x0p * tmp_tp_x0p + tmp_tp_y0p * tmp_tp_y0p); - float tmp_tp_d0 = tmp_tp_charge * tmp_tp_rp - (1. / (2. * K)); - tmp_tp_d0 = tmp_tp_d0 * (-1); //fix d0 sign - const double pi = 4.0 * atan(1.0); - float delphi = tmp_tp_phi - atan2(-K * tmp_tp_x0p, K * tmp_tp_y0p); - if (delphi < -pi) - delphi += 2.0 * pi; - if (delphi > pi) - delphi -= 2.0 * pi; - float tmp_tp_z0 = tmp_tp_vz + tmp_tp_t * delphi / (2.0 * K); - // ---------------------------------------------------------------------------------------------- - - if (std::abs(tmp_tp_z0) > TP_maxZ0) - continue; - - // for pions in ttbar, only consider TPs coming from near the IP! - float dxy = sqrt(tmp_tp_vx * tmp_tp_vx + tmp_tp_vy * tmp_tp_vy); - float tmp_tp_dxy = dxy; - if (MyProcess == 6 && (dxy > 1.0)) - continue; - - if (DebugMode && (Displaced == "Prompt" || Displaced == "Both")) - edm::LogVerbatim("Tracklet") << "Tracking particle, pt: " << tmp_tp_pt << " eta: " << tmp_tp_eta - << " phi: " << tmp_tp_phi << " z0: " << tmp_tp_z0 << " d0: " << tmp_tp_d0 - << " z_prod: " << tmp_tp_z0_prod << " d_prod: " << tmp_tp_d0_prod - << " pdgid: " << tmp_tp_pdgid << " eventID: " << iterTP->eventId().event() - << " ttclusters " << MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr).size() - << " ttstubs " << MCTruthTTStubHandle->findTTStubRefs(tp_ptr).size() << " tttracks " - << MCTruthTTTrackHandle->findTTTrackPtrs(tp_ptr).size(); - - // ---------------------------------------------------------------------------------------------- - // only consider TPs associated with >= 1 cluster, or >= X stubs, or have stubs in >= X layers (configurable options) - if (MCTruthTTClusterHandle->findTTClusterRefs(tp_ptr).empty()) { - if (DebugMode) - edm::LogVerbatim("Tracklet") << "No matching TTClusters for TP, continuing..."; - continue; - } - - std::vector >, TTStub > > - theStubRefs = MCTruthTTStubHandle->findTTStubRefs(tp_ptr); - int nStubTP = (int)theStubRefs.size(); - - // how many layers/disks have stubs? - int hasStubInLayer[11] = {0}; - for (auto& theStubRef : theStubRefs) { - DetId detid(theStubRef->getDetId()); - - int layer = -1; - if (detid.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo.layer(detid)) - 1; //fill in array as entries 0-5 - } else if (detid.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo.layer(detid)) + 5; //fill in array as entries 6-10 - } - - //treat genuine stubs separately (==2 is genuine, ==1 is not) - if (MCTruthTTStubHandle->findTrackingParticlePtr(theStubRef).isNull() && hasStubInLayer[layer] < 2) - hasStubInLayer[layer] = 1; - else - hasStubInLayer[layer] = 2; - } - - int nStubLayerTP = 0; - int nStubLayerTP_g = 0; - for (int isum : hasStubInLayer) { - if (isum >= 1) - nStubLayerTP += 1; - if (isum == 2) - nStubLayerTP_g += 1; - } - - if (DebugMode) - edm::LogVerbatim("Tracklet") << "TP is associated with " << nStubTP << " stubs, and has stubs in " << nStubLayerTP - << " different layers/disks, and has GENUINE stubs in " << nStubLayerTP_g - << " layers "; - - if (TP_minNStub > 0) { - if (DebugMode) - edm::LogVerbatim("Tracklet") << "Only consider TPs with >= " << TP_minNStub << " stubs"; - if (nStubTP < TP_minNStub) { - if (DebugMode) - edm::LogVerbatim("Tracklet") << "TP fails minimum nbr stubs requirement! Continuing..."; - continue; - } - } - if (TP_minNStubLayer > 0) { - if (DebugMode) - edm::LogVerbatim("Tracklet") << "Only consider TPs with stubs in >= " << TP_minNStubLayer << " layers/disks"; - if (nStubLayerTP < TP_minNStubLayer) { - if (DebugMode) - edm::LogVerbatim("Tracklet") << "TP fails stubs in minimum nbr of layers/disks requirement! Continuing..."; - continue; - } - } - - m_tp_pt->push_back(tmp_tp_pt); - m_tp_eta->push_back(tmp_tp_eta); - m_tp_phi->push_back(tmp_tp_phi); - m_tp_dxy->push_back(tmp_tp_dxy); - m_tp_z0->push_back(tmp_tp_z0); - m_tp_d0->push_back(tmp_tp_d0); - m_tp_z0_prod->push_back(tmp_tp_z0_prod); - m_tp_d0_prod->push_back(tmp_tp_d0_prod); - m_tp_pdgid->push_back(tmp_tp_pdgid); - m_tp_nstub->push_back(nStubTP); - m_tp_eventid->push_back(tmp_eventid); - m_tp_charge->push_back(tmp_tp_charge); - - // ---------------------------------------------------------------------------------------------- - // look for L1 tracks (prompt) matched to the tracking particle - if (Displaced == "Prompt" || Displaced == "Both") { - std::vector > > matchedTracks = - MCTruthTTTrackHandle->findTTTrackPtrs(tp_ptr); - - int nMatch = 0; - int i_track = -1; - float i_chi2dof = 99999; - - if (!matchedTracks.empty()) { - if (DebugMode && (matchedTracks.size() > 1)) - edm::LogVerbatim("Tracklet") << "TrackingParticle has more than one matched L1 track!"; - - // ---------------------------------------------------------------------------------------------- - // loop over matched L1 tracks - // here, "match" means tracks that can be associated to a TrackingParticle with at least one hit of at least one of its clusters - // https://twiki.cern.ch/twiki/bin/viewauth/CMS/SLHCTrackerTriggerSWTools#MC_truth_for_TTTrack - - for (int it = 0; it < (int)matchedTracks.size(); it++) { - bool tmp_trk_genuine = false; - bool tmp_trk_loosegenuine = false; - if (MCTruthTTTrackHandle->isGenuine(matchedTracks.at(it))) - tmp_trk_genuine = true; - if (MCTruthTTTrackHandle->isLooselyGenuine(matchedTracks.at(it))) - tmp_trk_loosegenuine = true; - if (!tmp_trk_loosegenuine) - continue; - - if (DebugMode) { - if (MCTruthTTTrackHandle->findTrackingParticlePtr(matchedTracks.at(it)).isNull()) { - edm::LogVerbatim("Tracklet") << "track matched to TP is NOT uniquely matched to a TP"; - } else { - edm::Ptr my_tp = MCTruthTTTrackHandle->findTrackingParticlePtr(matchedTracks.at(it)); - edm::LogVerbatim("Tracklet") << "TP matched to track matched to TP ... tp pt = " << my_tp->p4().pt() - << " eta = " << my_tp->momentum().eta() - << " phi = " << my_tp->momentum().phi() << " z0 = " << my_tp->vertex().z(); - } - edm::LogVerbatim("Tracklet") << " ... matched L1 track has pt = " - << matchedTracks.at(it)->momentum().perp() - << " eta = " << matchedTracks.at(it)->momentum().eta() - << " phi = " << matchedTracks.at(it)->momentum().phi() - << " chi2 = " << matchedTracks.at(it)->chi2() - << " consistency = " << matchedTracks.at(it)->stubPtConsistency() - << " z0 = " << matchedTracks.at(it)->z0() - << " nstub = " << matchedTracks.at(it)->getStubRefs().size(); - if (tmp_trk_genuine) - edm::LogVerbatim("Tracklet") << " (genuine!) "; - if (tmp_trk_loosegenuine) - edm::LogVerbatim("Tracklet") << " (loose genuine!) "; - } - - std::vector >, TTStub > > - stubRefs = matchedTracks.at(it)->getStubRefs(); - int tmp_trk_nstub = stubRefs.size(); - - if (tmp_trk_nstub < L1Tk_minNStub) - continue; - - float dmatch_pt = 999; - float dmatch_eta = 999; - float dmatch_phi = 999; - int match_id = 999; - - edm::Ptr my_tp = MCTruthTTTrackHandle->findTrackingParticlePtr(matchedTracks.at(it)); - dmatch_pt = std::abs(my_tp->p4().pt() - tmp_tp_pt); - dmatch_eta = std::abs(my_tp->p4().eta() - tmp_tp_eta); - dmatch_phi = std::abs(my_tp->p4().phi() - tmp_tp_phi); - match_id = my_tp->pdgId(); - float tmp_trk_chi2dof = matchedTracks.at(it)->chi2Red(); - - // ensure that track is uniquely matched to the TP we are looking at! - if (dmatch_pt < 0.1 && dmatch_eta < 0.1 && dmatch_phi < 0.1 && tmp_tp_pdgid == match_id && tmp_trk_genuine) { - nMatch++; - if (i_track < 0 || tmp_trk_chi2dof < i_chi2dof) { - i_track = it; - i_chi2dof = tmp_trk_chi2dof; - } - } - - } // end loop over matched L1 tracks - } // end has at least 1 matched L1 track - // ---------------------------------------------------------------------------------------------- - - float tmp_matchtrk_pt = -999; - float tmp_matchtrk_eta = -999; - float tmp_matchtrk_phi = -999; - float tmp_matchtrk_z0 = -999; - float tmp_matchtrk_d0 = -999; - float tmp_matchtrk_chi2 = -999; - float tmp_matchtrk_chi2dof = -999; - float tmp_matchtrk_chi2rphi = -999; - float tmp_matchtrk_chi2rz = -999; - float tmp_matchtrk_bendchi2 = -999; - int tmp_matchtrk_nstub = -999; - int tmp_matchtrk_dhits = -999; - int tmp_matchtrk_lhits = -999; - int tmp_matchtrk_seed = -999; - int tmp_matchtrk_hitpattern = -999; - int tmp_matchtrk_nFitPars = -999; - - if (nMatch > 1 && DebugMode) - edm::LogVerbatim("Tracklet") << "WARNING *** 2 or more matches to genuine L1 tracks ***"; - - if (nMatch > 0) { - tmp_matchtrk_pt = matchedTracks.at(i_track)->momentum().perp(); - tmp_matchtrk_eta = matchedTracks.at(i_track)->momentum().eta(); - tmp_matchtrk_phi = matchedTracks.at(i_track)->momentum().phi(); - tmp_matchtrk_z0 = matchedTracks.at(i_track)->z0(); - tmp_matchtrk_nFitPars = matchedTracks.at(i_track)->nFitPars(); - - if (tmp_matchtrk_nFitPars == 5) { - float tmp_matchtrk_x0 = matchedTracks.at(i_track)->POCA().x(); - float tmp_matchtrk_y0 = matchedTracks.at(i_track)->POCA().y(); - tmp_matchtrk_d0 = -tmp_matchtrk_x0 * sin(tmp_matchtrk_phi) + tmp_matchtrk_y0 * cos(tmp_matchtrk_phi); - // tmp_matchtrk_d0 = matchedTracks.at(i_track)->d0(); - } - - tmp_matchtrk_chi2 = matchedTracks.at(i_track)->chi2(); - tmp_matchtrk_chi2dof = matchedTracks.at(i_track)->chi2Red(); - tmp_matchtrk_chi2rphi = matchedTracks.at(i_track)->chi2XY(); - tmp_matchtrk_chi2rz = matchedTracks.at(i_track)->chi2Z(); - tmp_matchtrk_bendchi2 = matchedTracks.at(i_track)->stubPtConsistency(); - tmp_matchtrk_nstub = (int)matchedTracks.at(i_track)->getStubRefs().size(); - tmp_matchtrk_seed = (int)matchedTracks.at(i_track)->trackSeedType(); - tmp_matchtrk_hitpattern = (int)matchedTracks.at(i_track)->hitPattern(); - - // ------------------------------------------------------------------------------------------ - tmp_matchtrk_dhits = 0; - tmp_matchtrk_lhits = 0; - - std::vector >, TTStub > > - stubRefs = matchedTracks.at(i_track)->getStubRefs(); - int tmp_nstub = stubRefs.size(); - - for (int is = 0; is < tmp_nstub; is++) { - DetId detIdStub = tGeom.idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); - int layer = -999999; - if (detIdStub.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo.layer(detIdStub)); - tmp_matchtrk_lhits += pow(10, layer - 1); - } else if (detIdStub.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo.layer(detIdStub)); - tmp_matchtrk_dhits += pow(10, layer - 1); - } - } - } - - m_tp_nmatch->push_back(nMatch); - - m_matchtrk_pt->push_back(tmp_matchtrk_pt); - m_matchtrk_eta->push_back(tmp_matchtrk_eta); - m_matchtrk_phi->push_back(tmp_matchtrk_phi); - m_matchtrk_z0->push_back(tmp_matchtrk_z0); - m_matchtrk_d0->push_back(tmp_matchtrk_d0); - m_matchtrk_chi2->push_back(tmp_matchtrk_chi2); - m_matchtrk_chi2dof->push_back(tmp_matchtrk_chi2dof); - m_matchtrk_chi2rphi->push_back(tmp_matchtrk_chi2rphi); - m_matchtrk_chi2rz->push_back(tmp_matchtrk_chi2rz); - m_matchtrk_bendchi2->push_back(tmp_matchtrk_bendchi2); - m_matchtrk_nstub->push_back(tmp_matchtrk_nstub); - m_matchtrk_dhits->push_back(tmp_matchtrk_dhits); - m_matchtrk_lhits->push_back(tmp_matchtrk_lhits); - m_matchtrk_seed->push_back(tmp_matchtrk_seed); - m_matchtrk_hitpattern->push_back(tmp_matchtrk_hitpattern); - } - - // ---------------------------------------------------------------------------------------------- - // look for L1 tracks (extended) matched to the tracking particle - if (Displaced == "Displaced" || Displaced == "Both") { - std::vector > > matchedTracks = - MCTruthTTTrackExtendedHandle->findTTTrackPtrs(tp_ptr); - - int nMatch = 0; - int i_track = -1; - float i_chi2dof = 99999; - - if (!matchedTracks.empty()) { - if (DebugMode && (matchedTracks.size() > 1)) - edm::LogVerbatim("Tracklet") << "TrackingParticle has more than one matched L1 track!"; - - // ---------------------------------------------------------------------------------------------- - // loop over matched L1 tracks - // here, "match" means tracks that can be associated to a TrackingParticle with at least one hit of at least one of its clusters - // https://twiki.cern.ch/twiki/bin/viewauth/CMS/SLHCTrackerTriggerSWTools#MC_truth_for_TTTrack - - for (int it = 0; it < (int)matchedTracks.size(); it++) { - bool tmp_trk_genuine = false; - bool tmp_trk_loosegenuine = false; - if (MCTruthTTTrackExtendedHandle->isGenuine(matchedTracks.at(it))) - tmp_trk_genuine = true; - if (MCTruthTTTrackExtendedHandle->isLooselyGenuine(matchedTracks.at(it))) - tmp_trk_loosegenuine = true; - if (!tmp_trk_loosegenuine) - continue; - - if (DebugMode) { - if (MCTruthTTTrackExtendedHandle->findTrackingParticlePtr(matchedTracks.at(it)).isNull()) { - edm::LogVerbatim("Tracklet") << "track matched to TP is NOT uniquely matched to a TP"; - } else { - edm::Ptr my_tp = - MCTruthTTTrackExtendedHandle->findTrackingParticlePtr(matchedTracks.at(it)); - edm::LogVerbatim("Tracklet") << "TP matched to track matched to TP ... tp pt = " << my_tp->p4().pt() - << " eta = " << my_tp->momentum().eta() - << " phi = " << my_tp->momentum().phi() << " z0 = " << my_tp->vertex().z(); - } - edm::LogVerbatim("Tracklet") << " ... matched L1 track has pt = " - << matchedTracks.at(it)->momentum().perp() - << " eta = " << matchedTracks.at(it)->momentum().eta() - << " phi = " << matchedTracks.at(it)->momentum().phi() - << " chi2 = " << matchedTracks.at(it)->chi2() - << " consistency = " << matchedTracks.at(it)->stubPtConsistency() - << " z0 = " << matchedTracks.at(it)->z0() - << " nstub = " << matchedTracks.at(it)->getStubRefs().size(); - if (tmp_trk_genuine) - edm::LogVerbatim("Tracklet") << " (genuine!) "; - if (tmp_trk_loosegenuine) - edm::LogVerbatim("Tracklet") << " (loose genuine!) "; - } - - std::vector >, TTStub > > - stubRefs = matchedTracks.at(it)->getStubRefs(); - int tmp_trk_nstub = stubRefs.size(); - - if (tmp_trk_nstub < L1Tk_minNStub) - continue; - - float dmatch_pt = 999; - float dmatch_eta = 999; - float dmatch_phi = 999; - int match_id = 999; - - edm::Ptr my_tp = - MCTruthTTTrackExtendedHandle->findTrackingParticlePtr(matchedTracks.at(it)); - dmatch_pt = std::abs(my_tp->p4().pt() - tmp_tp_pt); - dmatch_eta = std::abs(my_tp->p4().eta() - tmp_tp_eta); - dmatch_phi = std::abs(my_tp->p4().phi() - tmp_tp_phi); - match_id = my_tp->pdgId(); - float tmp_trk_chi2dof = matchedTracks.at(it)->chi2Red(); - - // ensure that track is uniquely matched to the TP we are looking at! - if (dmatch_pt < 0.1 && dmatch_eta < 0.1 && dmatch_phi < 0.1 && tmp_tp_pdgid == match_id && tmp_trk_genuine) { - nMatch++; - if (i_track < 0 || tmp_trk_chi2dof < i_chi2dof) { - i_track = it; - i_chi2dof = tmp_trk_chi2dof; - } - } - - } // end loop over matched L1 tracks - } // end has at least 1 matched L1 track - // ---------------------------------------------------------------------------------------------- - - float tmp_matchtrkExt_pt = -999; - float tmp_matchtrkExt_eta = -999; - float tmp_matchtrkExt_phi = -999; - float tmp_matchtrkExt_z0 = -999; - float tmp_matchtrkExt_d0 = -999; - float tmp_matchtrkExt_chi2 = -999; - float tmp_matchtrkExt_chi2dof = -999; - float tmp_matchtrkExt_chi2rphi = -999; - float tmp_matchtrkExt_chi2rz = -999; - float tmp_matchtrkExt_bendchi2 = -999; - int tmp_matchtrkExt_nstub = -999; - int tmp_matchtrkExt_dhits = -999; - int tmp_matchtrkExt_lhits = -999; - int tmp_matchtrkExt_seed = -999; - int tmp_matchtrkExt_hitpattern = -999; - int tmp_matchtrkExt_nFitPars = -999; - - if (nMatch > 1 && DebugMode) - edm::LogVerbatim("Tracklet") << "WARNING *** 2 or more matches to genuine L1 tracks ***"; - - if (nMatch > 0) { - tmp_matchtrkExt_pt = matchedTracks.at(i_track)->momentum().perp(); - tmp_matchtrkExt_eta = matchedTracks.at(i_track)->momentum().eta(); - tmp_matchtrkExt_phi = matchedTracks.at(i_track)->momentum().phi(); - tmp_matchtrkExt_z0 = matchedTracks.at(i_track)->z0(); - tmp_matchtrkExt_nFitPars = matchedTracks.at(i_track)->nFitPars(); - - if (tmp_matchtrkExt_nFitPars == 5) { - float tmp_matchtrkExt_x0 = matchedTracks.at(i_track)->POCA().x(); - float tmp_matchtrkExt_y0 = matchedTracks.at(i_track)->POCA().y(); - tmp_matchtrkExt_d0 = - -tmp_matchtrkExt_x0 * sin(tmp_matchtrkExt_phi) + tmp_matchtrkExt_y0 * cos(tmp_matchtrkExt_phi); - // tmp_matchtrkExt_d0 = matchedTracks.at(i_track)->d0(); - } - - tmp_matchtrkExt_chi2 = matchedTracks.at(i_track)->chi2(); - tmp_matchtrkExt_chi2dof = matchedTracks.at(i_track)->chi2Red(); - tmp_matchtrkExt_chi2rphi = matchedTracks.at(i_track)->chi2XY(); - tmp_matchtrkExt_chi2rz = matchedTracks.at(i_track)->chi2Z(); - tmp_matchtrkExt_bendchi2 = matchedTracks.at(i_track)->stubPtConsistency(); - tmp_matchtrkExt_nstub = (int)matchedTracks.at(i_track)->getStubRefs().size(); - tmp_matchtrkExt_seed = (int)matchedTracks.at(i_track)->trackSeedType(); - tmp_matchtrkExt_hitpattern = (int)matchedTracks.at(i_track)->hitPattern(); - - // ------------------------------------------------------------------------------------------ - tmp_matchtrkExt_dhits = 0; - tmp_matchtrkExt_lhits = 0; - - std::vector >, TTStub > > - stubRefs = matchedTracks.at(i_track)->getStubRefs(); - int tmp_nstub = stubRefs.size(); - - for (int is = 0; is < tmp_nstub; is++) { - DetId detIdStub = tGeom.idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); - int layer = -999999; - if (detIdStub.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo.layer(detIdStub)); - tmp_matchtrkExt_lhits += pow(10, layer - 1); - } else if (detIdStub.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo.layer(detIdStub)); - tmp_matchtrkExt_dhits += pow(10, layer - 1); - } - } - } - - // m_tp_nmatch->push_back(nMatch); //modify to be matches for ext - m_matchtrkExt_pt->push_back(tmp_matchtrkExt_pt); - m_matchtrkExt_eta->push_back(tmp_matchtrkExt_eta); - m_matchtrkExt_phi->push_back(tmp_matchtrkExt_phi); - m_matchtrkExt_z0->push_back(tmp_matchtrkExt_z0); - m_matchtrkExt_d0->push_back(tmp_matchtrkExt_d0); - m_matchtrkExt_chi2->push_back(tmp_matchtrkExt_chi2); - m_matchtrkExt_chi2dof->push_back(tmp_matchtrkExt_chi2dof); - m_matchtrkExt_chi2rphi->push_back(tmp_matchtrkExt_chi2rphi); - m_matchtrkExt_chi2rz->push_back(tmp_matchtrkExt_chi2rz); - m_matchtrkExt_bendchi2->push_back(tmp_matchtrkExt_bendchi2); - m_matchtrkExt_nstub->push_back(tmp_matchtrkExt_nstub); - m_matchtrkExt_dhits->push_back(tmp_matchtrkExt_dhits); - m_matchtrkExt_lhits->push_back(tmp_matchtrkExt_lhits); - m_matchtrkExt_seed->push_back(tmp_matchtrkExt_seed); - m_matchtrkExt_hitpattern->push_back(tmp_matchtrkExt_hitpattern); - } - - } //end loop tracking particles - - if (SaveTrackMET) { - if (Displaced == "Prompt" || Displaced == "Both") { - if (L1TkMETHandle.isValid()) { - trkMET = L1TkMETHandle->begin()->etMiss(); - } else { - edm::LogWarning("DataNotFound") << "\nWarning: tkMET handle not found in the event" << std::endl; - } - - if (L1TkMHTHandle.isValid()) { - trkMHT = L1TkMHTHandle->begin()->EtMiss(); - trkHT = L1TkMHTHandle->begin()->etTotal(); - } else { - edm::LogWarning("DataNotFound") << "\nWarning: tkMHT handle not found in the event" << std::endl; - } - } //end prompt-track quantities - - if (Displaced == "Displaced" || Displaced == "Both") { - if (L1TkMETExtendedHandle.isValid()) { - trkMETExt = L1TkMETExtendedHandle->begin()->etMiss(); - } else { - edm::LogWarning("DataNotFound") << "\nWarning: tkMETExtended handle not found in the event" << std::endl; - } - - if (L1TkMHTExtendedHandle.isValid()) { - trkMHTExt = L1TkMHTExtendedHandle->begin()->EtMiss(); - trkHTExt = L1TkMHTExtendedHandle->begin()->etTotal(); - } else { - edm::LogWarning("DataNotFound") << "\nWarning: tkMHTExtended handle not found in the event" << std::endl; - } - } //end displaced-track quantities - } - - if (SaveTrackJets) { - if (TrackFastJetsHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) { - for (jetIter = TrackFastJetsHandle->begin(); jetIter != TrackFastJetsHandle->end(); ++jetIter) { - m_trkjet_vz->push_back(jetIter->jetVtx()); - m_trkjet_ntracks->push_back(jetIter->trkPtrs().size()); - m_trkjet_phi->push_back(jetIter->phi()); - m_trkjet_eta->push_back(jetIter->eta()); - m_trkjet_pt->push_back(jetIter->pt()); - m_trkjet_p->push_back(jetIter->p()); - } - } - if (TrackFastJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { - for (jetIter = TrackFastJetsExtendedHandle->begin(); jetIter != TrackFastJetsExtendedHandle->end(); ++jetIter) { - m_trkjetExt_vz->push_back(jetIter->jetVtx()); - m_trkjetExt_ntracks->push_back(jetIter->trkPtrs().size()); - m_trkjetExt_phi->push_back(jetIter->phi()); - m_trkjetExt_eta->push_back(jetIter->eta()); - m_trkjetExt_pt->push_back(jetIter->pt()); - m_trkjetExt_p->push_back(jetIter->p()); - } - } - if (!TrackJetsHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) { - edm::LogWarning("DataNotFound") << "\nWarning: TrackJetsHandle not found in the event" << std::endl; - } - if (!TrackJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { - edm::LogWarning("DataNotFound") << "\nWarning: TrackJetsExtendedHandle not found in the event" << std::endl; - } - if (TrackJetsHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) { - for (jetIter = TrackJetsHandle->begin(); jetIter != TrackJetsHandle->end(); ++jetIter) { - m_2ltrkjet_vz->push_back(jetIter->jetVtx()); - m_2ltrkjet_ntracks->push_back(jetIter->ntracks()); - m_2ltrkjet_phi->push_back(jetIter->phi()); - m_2ltrkjet_eta->push_back(jetIter->eta()); - m_2ltrkjet_pt->push_back(jetIter->pt()); - m_2ltrkjet_p->push_back(jetIter->p()); - m_2ltrkjet_nDisplaced->push_back(jetIter->nDisptracks()); - m_2ltrkjet_nTight->push_back(jetIter->nTighttracks()); - m_2ltrkjet_nTightDisplaced->push_back(jetIter->nTightDisptracks()); - } - } - - if (TrackJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { - for (jetIter = TrackJetsExtendedHandle->begin(); jetIter != TrackJetsExtendedHandle->end(); ++jetIter) { - m_2ltrkjetExt_vz->push_back(jetIter->jetVtx()); - m_2ltrkjetExt_ntracks->push_back(jetIter->ntracks()); - m_2ltrkjetExt_phi->push_back(jetIter->phi()); - m_2ltrkjetExt_eta->push_back(jetIter->eta()); - m_2ltrkjetExt_pt->push_back(jetIter->pt()); - m_2ltrkjetExt_p->push_back(jetIter->p()); - m_2ltrkjetExt_nDisplaced->push_back(jetIter->nDisptracks()); - m_2ltrkjetExt_nTight->push_back(jetIter->nTighttracks()); - m_2ltrkjetExt_nTightDisplaced->push_back(jetIter->nTightDisptracks()); - } - } - - if (L1TkPrimaryVertexHandle.isValid()) { - m_pv_L1reco->push_back(L1TkPrimaryVertexHandle->begin()->zvertex()); - } else { - edm::LogWarning("DataNotFound") << "\nWarning: L1TkPrimaryVertexHandle not found in the event" << std::endl; - } - } // end track jets - - eventTree->Fill(); -} // end of analyze() - -/////////////////////////// -// DEFINE THIS AS A PLUG-IN -DEFINE_FWK_MODULE(L1TrackObjectNtupleMaker); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.cc new file mode 100644 index 0000000000000..dbe75da651992 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.cc @@ -0,0 +1,639 @@ +// -*- C++ -*- +// +// Package: L1Trigger/L1TTrackMatch +// Class: L1TrackSelectionProducer +// +/**\class L1TrackSelectionProducer L1TrackSelectionProducer.cc L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.cc + + Description: Selects a set of L1Tracks based on a set of predefined criteria. + + Implementation: + Inputs: + std::vector - Each floating point TTTrack inside this collection inherits from + a bit-accurate TTTrack_TrackWord, used for emulation purposes. + Outputs: + std::vector - A collection of TTTracks selected from cuts on the TTTrack properties + std::vector - A collection of TTTracks selected from cuts on the TTTrack_TrackWord properties +*/ +// +// Original Author: Alexx Perloff +// Created: Thu, 16 Dec 2021 19:02:50 GMT +// +// + +// system include files +#include +#include +#include +#include + +// Xilinx HLS includes +#include +#include + +// user include files +#include "DataFormats/Common/interface/Handle.h" +#include "DataFormats/Common/interface/Ref.h" +#include "DataFormats/Common/interface/RefVector.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "CommonTools/Utils/interface/AndSelector.h" +#include "CommonTools/Utils/interface/EtaRangeSelector.h" +#include "CommonTools/Utils/interface/MinSelector.h" +#include "CommonTools/Utils/interface/MinFunctionSelector.h" +#include "CommonTools/Utils/interface/MinNumberSelector.h" +#include "CommonTools/Utils/interface/PtMinSelector.h" +#include "CommonTools/Utils/interface/Selection.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/EDMException.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "Geometry/Records/interface/TrackerTopologyRcd.h" + +// +// class declaration +// + +class L1TrackSelectionProducer : public edm::global::EDProducer<> { +public: + explicit L1TrackSelectionProducer(const edm::ParameterSet&); + ~L1TrackSelectionProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + // ----------constants, enums and typedefs --------- + // Relevant constants for the converted track word + enum TrackBitWidths { + kPtSize = TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1, // Width of pt + kPtMagSize = 9, // Width of pt magnitude (unsigned) + kEtaSize = TTTrack_TrackWord::TrackBitWidths::kTanlSize, // Width of eta + kEtaMagSize = 3, // Width of eta magnitude (signed) + }; + + typedef TTTrack L1Track; + typedef std::vector TTTrackCollection; + typedef edm::Handle TTTrackCollectionHandle; + typedef edm::Ref TTTrackRef; + typedef edm::RefVector TTTrackRefCollection; + typedef std::unique_ptr TTTrackRefCollectionUPtr; + + // ----------member functions ---------------------- + void printDebugInfo(const TTTrackCollectionHandle& l1TracksHandle, + const TTTrackRefCollectionUPtr& vTTTrackOutput, + const TTTrackRefCollectionUPtr& vTTTrackEmulationOutput, + const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput, + const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const; + void printTrackInfo(edm::LogInfo& log, const L1Track& track, bool printEmulation = false) const; + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + // ----------selectors ----------------------------- + // Based on recommendations from https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideGenericSelectors + struct TTTrackPtMinSelector { + TTTrackPtMinSelector(double ptMin) : ptMin_(ptMin) {} + TTTrackPtMinSelector(const edm::ParameterSet& cfg) : ptMin_(cfg.template getParameter("ptMin")) {} + bool operator()(const L1Track& t) const { return t.momentum().perp() >= ptMin_; } + + private: + double ptMin_; + }; + struct TTTrackWordPtMinSelector { + TTTrackWordPtMinSelector(double ptMin) : ptMin_(ptMin) {} + TTTrackWordPtMinSelector(const edm::ParameterSet& cfg) : ptMin_(cfg.template getParameter("ptMin")) {} + bool operator()(const L1Track& t) const { + ap_uint ptEmulationBits = t.getTrackWord()( + TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB); + ap_ufixed ptEmulation; + ptEmulation.V = ptEmulationBits.range(); + //edm::LogInfo("L1TrackSelectionProducer") << "produce::Emulation track properties::ap_uint(bits) = " << ptEmulationBits.to_string(2) + // << " ap_ufixed(bits) = " << ptEmulation.to_string(2) << " ap_ufixed(float) = " << ptEmulation.to_double(); + return ptEmulation.to_double() >= ptMin_; + } + + private: + double ptMin_; + }; + struct TTTrackAbsEtaMaxSelector { + TTTrackAbsEtaMaxSelector(double absEtaMax) : absEtaMax_(absEtaMax) {} + TTTrackAbsEtaMaxSelector(const edm::ParameterSet& cfg) + : absEtaMax_(cfg.template getParameter("absEtaMax")) {} + bool operator()(const L1Track& t) const { return std::abs(t.momentum().eta()) <= absEtaMax_; } + + private: + double absEtaMax_; + }; + struct TTTrackWordAbsEtaMaxSelector { + TTTrackWordAbsEtaMaxSelector(double absEtaMax) : absEtaMax_(absEtaMax) {} + TTTrackWordAbsEtaMaxSelector(const edm::ParameterSet& cfg) + : absEtaMax_(cfg.template getParameter("absEtaMax")) {} + bool operator()(const L1Track& t) const { + TTTrack_TrackWord::tanl_t etaEmulationBits = t.getTanlWord(); + ap_fixed etaEmulation; + etaEmulation.V = etaEmulationBits.range(); + return std::abs(etaEmulation.to_double()) <= absEtaMax_; + } + + private: + double absEtaMax_; + }; + struct TTTrackAbsZ0MaxSelector { + TTTrackAbsZ0MaxSelector(double absZ0Max) : absZ0Max_(absZ0Max) {} + TTTrackAbsZ0MaxSelector(const edm::ParameterSet& cfg) : absZ0Max_(cfg.template getParameter("absZ0Max")) {} + bool operator()(const L1Track& t) const { return std::abs(t.z0()) <= absZ0Max_; } + + private: + double absZ0Max_; + }; + struct TTTrackWordAbsZ0MaxSelector { + TTTrackWordAbsZ0MaxSelector(double absZ0Max) : absZ0Max_(absZ0Max) {} + TTTrackWordAbsZ0MaxSelector(const edm::ParameterSet& cfg) + : absZ0Max_(cfg.template getParameter("absZ0Max")) {} + bool operator()(const L1Track& t) const { return std::abs(t.getZ0()) <= absZ0Max_; } + + private: + double absZ0Max_; + }; + struct TTTrackNStubsMinSelector { + TTTrackNStubsMinSelector(double nStubsMin) : nStubsMin_(nStubsMin) {} + TTTrackNStubsMinSelector(const edm::ParameterSet& cfg) + : nStubsMin_(cfg.template getParameter("nStubsMin")) {} + bool operator()(const L1Track& t) const { return t.getStubRefs().size() >= nStubsMin_; } + + private: + double nStubsMin_; + }; + struct TTTrackWordNStubsMinSelector { + TTTrackWordNStubsMinSelector(double nStubsMin) : nStubsMin_(nStubsMin) {} + TTTrackWordNStubsMinSelector(const edm::ParameterSet& cfg) + : nStubsMin_(cfg.template getParameter("nStubsMin")) {} + bool operator()(const L1Track& t) const { return t.getNStubs() >= nStubsMin_; } + + private: + double nStubsMin_; + }; + struct TTTrackNPSStubsMinSelector { + TTTrackNPSStubsMinSelector(double nStubsMin, const TrackerTopology& tTopo) + : nPSStubsMin_(nStubsMin), tTopo_(tTopo) {} + TTTrackNPSStubsMinSelector(const edm::ParameterSet& cfg, const TrackerTopology& tTopo) + : nPSStubsMin_(cfg.template getParameter("nPSStubsMin")), tTopo_(tTopo) {} + bool operator()(const L1Track& t) const { + int nPSStubs = 0; + for (const auto& stub : t.getStubRefs()) { + DetId detId(stub->getDetId()); + if (detId.det() == DetId::Detector::Tracker) { + if ((detId.subdetId() == StripSubdetector::TOB && tTopo_.tobLayer(detId) <= 3) || + (detId.subdetId() == StripSubdetector::TID && tTopo_.tidRing(detId) <= 9)) + nPSStubs++; + } + } + return nPSStubs >= nPSStubsMin_; + } + + private: + double nPSStubsMin_; + const TrackerTopology& tTopo_; + }; + struct TTTrackBendChi2MaxSelector { + TTTrackBendChi2MaxSelector(double bendChi2Max) : bendChi2Max_(bendChi2Max) {} + TTTrackBendChi2MaxSelector(const edm::ParameterSet& cfg) + : bendChi2Max_(cfg.template getParameter("reducedBendChi2Max")) {} + bool operator()(const L1Track& t) const { return t.stubPtConsistency() < bendChi2Max_; } + + private: + double bendChi2Max_; + }; + struct TTTrackWordBendChi2MaxSelector { + TTTrackWordBendChi2MaxSelector(double bendChi2Max) : bendChi2Max_(bendChi2Max) {} + TTTrackWordBendChi2MaxSelector(const edm::ParameterSet& cfg) + : bendChi2Max_(cfg.template getParameter("reducedBendChi2Max")) {} + bool operator()(const L1Track& t) const { return t.getBendChi2() < bendChi2Max_; } + + private: + double bendChi2Max_; + }; + struct TTTrackChi2RZMaxSelector { + TTTrackChi2RZMaxSelector(double reducedChi2RZMax) : reducedChi2RZMax_(reducedChi2RZMax) {} + TTTrackChi2RZMaxSelector(const edm::ParameterSet& cfg) + : reducedChi2RZMax_(cfg.template getParameter("reducedChi2RZMax")) {} + bool operator()(const L1Track& t) const { return t.chi2ZRed() < reducedChi2RZMax_; } + + private: + double reducedChi2RZMax_; + }; + struct TTTrackWordChi2RZMaxSelector { + TTTrackWordChi2RZMaxSelector(double reducedChi2RZMax) : reducedChi2RZMax_(reducedChi2RZMax) {} + TTTrackWordChi2RZMaxSelector(const edm::ParameterSet& cfg) + : reducedChi2RZMax_(cfg.template getParameter("reducedChi2RZMax")) {} + bool operator()(const L1Track& t) const { return t.getChi2RZ() < reducedChi2RZMax_; } + + private: + double reducedChi2RZMax_; + }; + struct TTTrackChi2RPhiMaxSelector { + TTTrackChi2RPhiMaxSelector(double reducedChi2RPhiMax) : reducedChi2RPhiMax_(reducedChi2RPhiMax) {} + TTTrackChi2RPhiMaxSelector(const edm::ParameterSet& cfg) + : reducedChi2RPhiMax_(cfg.template getParameter("reducedChi2RPhiMax")) {} + bool operator()(const L1Track& t) const { return t.chi2XYRed() < reducedChi2RPhiMax_; } + + private: + double reducedChi2RPhiMax_; + }; + struct TTTrackWordChi2RPhiMaxSelector { + TTTrackWordChi2RPhiMaxSelector(double reducedChi2RPhiMax) : reducedChi2RPhiMax_(reducedChi2RPhiMax) {} + TTTrackWordChi2RPhiMaxSelector(const edm::ParameterSet& cfg) + : reducedChi2RPhiMax_(cfg.template getParameter("reducedChi2RPhiMax")) {} + bool operator()(const L1Track& t) const { return t.getChi2RPhi() < reducedChi2RPhiMax_; } + + private: + double reducedChi2RPhiMax_; + }; + struct TTTrackDeltaZMaxSelector { + TTTrackDeltaZMaxSelector(const std::vector& deltaZMaxEtaBounds, const std::vector& deltaZMax) + : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {} + TTTrackDeltaZMaxSelector(const edm::ParameterSet& cfg) + : deltaZMaxEtaBounds_(cfg.template getParameter("deltaZMaxEtaBounds")), + deltaZMax_(cfg.template getParameter("deltaZMax")) {} + bool operator()(const L1Track& t, const l1t::Vertex& v) const { + size_t etaIndex = + std::lower_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(t.momentum().eta())) - + deltaZMaxEtaBounds_.begin() - 1; + if (etaIndex > deltaZMax_.size() - 1) + etaIndex = deltaZMax_.size() - 1; + return std::abs(v.z0() - t.z0()) <= deltaZMax_[etaIndex]; + } + + private: + std::vector deltaZMaxEtaBounds_; + std::vector deltaZMax_; + }; + struct TTTrackWordDeltaZMaxSelector { + TTTrackWordDeltaZMaxSelector(const std::vector& deltaZMaxEtaBounds, const std::vector& deltaZMax) + : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {} + TTTrackWordDeltaZMaxSelector(const edm::ParameterSet& cfg) + : deltaZMaxEtaBounds_(cfg.template getParameter("deltaZMaxEtaBounds")), + deltaZMax_(cfg.template getParameter("deltaZMax")) {} + bool operator()(const L1Track& t, const l1t::VertexWord& v) const { + size_t etaIndex = + std::lower_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(t.momentum().eta())) - + deltaZMaxEtaBounds_.begin() - 1; + if (etaIndex > deltaZMax_.size() - 1) + etaIndex = deltaZMax_.size() - 1; + return std::abs(v.z0() - t.getZ0()) <= deltaZMax_[etaIndex]; + } + + private: + std::vector deltaZMaxEtaBounds_; + std::vector deltaZMax_; + }; + + typedef AndSelector + TTTrackPtMinEtaMaxZ0MaxNStubsMinSelector; + typedef AndSelector + TTTrackWordPtMinEtaMaxZ0MaxNStubsMinSelector; + typedef AndSelector + TTTrackBendChi2Chi2RZChi2RPhiMaxSelector; + typedef AndSelector + TTTrackWordBendChi2Chi2RZChi2RPhiMaxSelector; + + // ----------member data --------------------------- + const edm::EDGetTokenT l1TracksToken_; + edm::EDGetTokenT l1VerticesToken_; + edm::EDGetTokenT l1VerticesEmulationToken_; + edm::ESGetToken tTopoToken_; + const std::string outputCollectionName_; + const edm::ParameterSet cutSet_; + const double ptMin_, absEtaMax_, absZ0Max_, bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_; + const int nStubsMin_, nPSStubsMin_; + std::vector deltaZMaxEtaBounds_, deltaZMax_; + const double useDisplacedTracksDeltaZOverride_; + bool processSimulatedTracks_, processEmulatedTracks_, doDeltaZCutSim_, doDeltaZCutEmu_; + int debug_; +}; + +// +// constructors and destructor +// +L1TrackSelectionProducer::L1TrackSelectionProducer(const edm::ParameterSet& iConfig) + : l1TracksToken_(consumes(iConfig.getParameter("l1TracksInputTag"))), + tTopoToken_(esConsumes(edm::ESInputTag("", ""))), + outputCollectionName_(iConfig.getParameter("outputCollectionName")), + cutSet_(iConfig.getParameter("cutSet")), + + ptMin_(cutSet_.getParameter("ptMin")), + absEtaMax_(cutSet_.getParameter("absEtaMax")), + absZ0Max_(cutSet_.getParameter("absZ0Max")), + bendChi2Max_(cutSet_.getParameter("reducedBendChi2Max")), + reducedChi2RZMax_(cutSet_.getParameter("reducedChi2RZMax")), + reducedChi2RPhiMax_(cutSet_.getParameter("reducedChi2RPhiMax")), + nStubsMin_(cutSet_.getParameter("nStubsMin")), + nPSStubsMin_(cutSet_.getParameter("nPSStubsMin")), + deltaZMaxEtaBounds_(cutSet_.getParameter>("deltaZMaxEtaBounds")), + deltaZMax_(cutSet_.getParameter>("deltaZMax")), + + useDisplacedTracksDeltaZOverride_(iConfig.getParameter("useDisplacedTracksDeltaZOverride")), + processSimulatedTracks_(iConfig.getParameter("processSimulatedTracks")), + processEmulatedTracks_(iConfig.getParameter("processEmulatedTracks")), + debug_(iConfig.getParameter("debug")) { + // Confirm the the configuration makes sense + if (!processSimulatedTracks_ && !processEmulatedTracks_) { + throw cms::Exception("You must process at least one of the track collections (simulated or emulated)."); + } + + if (deltaZMax_.size() != deltaZMaxEtaBounds_.size() - 1) { + throw cms::Exception("The number of deltaZ cuts does not match the number of eta bins!"); + } + + if (useDisplacedTracksDeltaZOverride_ >= 0) { + deltaZMax_ = std::vector(deltaZMax_.size(), useDisplacedTracksDeltaZOverride_); + } + + // Get additional input tags and define the EDM output based on the previous configuration parameters + doDeltaZCutSim_ = false; + doDeltaZCutEmu_ = false; + if (processSimulatedTracks_) { + produces(outputCollectionName_); + if (iConfig.exists("l1VerticesInputTag")) { + l1VerticesToken_ = consumes(iConfig.getParameter("l1VerticesInputTag")); + doDeltaZCutSim_ = true; + produces(outputCollectionName_ + "Associated"); + } + } + if (processEmulatedTracks_) { + produces(outputCollectionName_ + "Emulation"); + if (iConfig.exists("l1VerticesEmulationInputTag")) { + l1VerticesEmulationToken_ = + consumes(iConfig.getParameter("l1VerticesEmulationInputTag")); + doDeltaZCutEmu_ = true; + produces(outputCollectionName_ + "AssociatedEmulation"); + } + } +} + +L1TrackSelectionProducer::~L1TrackSelectionProducer() {} + +// +// member functions +// + +void L1TrackSelectionProducer::printDebugInfo(const TTTrackCollectionHandle& l1TracksHandle, + const TTTrackRefCollectionUPtr& vTTTrackOutput, + const TTTrackRefCollectionUPtr& vTTTrackEmulationOutput, + const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput, + const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const { + edm::LogInfo log("L1TrackSelectionProducer"); + log << "The original track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are ... \n"; + for (const auto& track : *l1TracksHandle) { + printTrackInfo(log, track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << l1TracksHandle->size() << "\n\n"; + if (processSimulatedTracks_) { + log << "The selected track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are ... \n"; + for (const auto& track : *vTTTrackOutput) { + printTrackInfo(log, *track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackOutput->size() << "\n\n"; + } + if (processEmulatedTracks_) { + log << "The emulation selected track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are " + "... \n"; + for (const auto& track : *vTTTrackEmulationOutput) { + printTrackInfo(log, *track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackEmulationOutput->size() << "\n\n"; + } + if (processSimulatedTracks_ && processEmulatedTracks_) { + TTTrackRefCollection inSimButNotEmu; + TTTrackRefCollection inEmuButNotSim; + std::set_difference(vTTTrackOutput->begin(), + vTTTrackOutput->end(), + vTTTrackEmulationOutput->begin(), + vTTTrackEmulationOutput->end(), + std::back_inserter(inSimButNotEmu)); + std::set_difference(vTTTrackEmulationOutput->begin(), + vTTTrackEmulationOutput->end(), + vTTTrackOutput->begin(), + vTTTrackOutput->end(), + std::back_inserter(inEmuButNotSim)); + log << "The set of tracks selected via cuts on the simulated values which are not in the set of tracks selected " + "by cutting on the emulated values ... \n"; + for (const auto& track : inSimButNotEmu) { + printTrackInfo(log, *track, debug_ >= 3); + } + log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n" + << "The set of tracks selected via cuts on the emulated values which are not in the set of tracks selected " + "by cutting on the simulated values ... \n"; + for (const auto& track : inEmuButNotSim) { + printTrackInfo(log, *track, debug_ >= 3); + } + log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n"; + } + if (processSimulatedTracks_) { + log << "The selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, chi2rz, " + "chi2rphi, z0) values are ... \n"; + for (const auto& track : *vTTTrackAssociatedOutput) { + printTrackInfo(log, *track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedOutput->size() << "\n\n"; + } + if (processEmulatedTracks_) { + log << "The emulation selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, " + "chi2rz, chi2rphi, z0) values are " + "... \n"; + for (const auto& track : *vTTTrackAssociatedEmulationOutput) { + printTrackInfo(log, *track, debug_ >= 4); + } + log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedEmulationOutput->size() << "\n\n"; + } + if (processSimulatedTracks_ && processEmulatedTracks_) { + TTTrackRefCollection inSimButNotEmu; + TTTrackRefCollection inEmuButNotSim; + std::set_difference(vTTTrackAssociatedOutput->begin(), + vTTTrackAssociatedOutput->end(), + vTTTrackAssociatedEmulationOutput->begin(), + vTTTrackAssociatedEmulationOutput->end(), + std::back_inserter(inSimButNotEmu)); + std::set_difference(vTTTrackAssociatedEmulationOutput->begin(), + vTTTrackAssociatedEmulationOutput->end(), + vTTTrackAssociatedOutput->begin(), + vTTTrackAssociatedOutput->end(), + std::back_inserter(inEmuButNotSim)); + log << "The set of tracks selected via cuts on the simulated values which are not in the set of tracks selected " + "by cutting on the emulated values ... \n"; + for (const auto& track : inSimButNotEmu) { + printTrackInfo(log, *track, debug_ >= 3); + } + log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n" + << "The set of tracks selected via cuts on the emulated values which are not in the set of tracks selected " + "by cutting on the simulated values ... \n"; + for (const auto& track : inEmuButNotSim) { + printTrackInfo(log, *track, debug_ >= 3); + } + log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n"; + } +} + +void L1TrackSelectionProducer::printTrackInfo(edm::LogInfo& log, const L1Track& track, bool printEmulation) const { + log << "\t(" << track.momentum().perp() << ", " << track.momentum().eta() << ", " << track.momentum().phi() << ", " + << track.getStubRefs().size() << ", " << track.stubPtConsistency() << ", " << track.chi2ZRed() << ", " + << track.chi2XYRed() << ", " << track.z0() << ")\n"; + + if (printEmulation) { + ap_uint ptEmulationBits = track.getTrackWord()( + TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB); + ap_ufixed ptEmulation; + ptEmulation.V = ptEmulationBits.range(); + TTTrack_TrackWord::tanl_t etaEmulationBits = track.getTanlWord(); + ap_fixed etaEmulation; + etaEmulation.V = etaEmulationBits.range(); + log << "\t\t(" << ptEmulation.to_double() << ", " << etaEmulation.to_double() << ", " << track.getPhi() << ", " + << track.getNStubs() << ", " << track.getBendChi2() << ", " << track.getChi2RZ() << ", " << track.getChi2RPhi() + << ", " << track.getZ0() << ")\n"; + } +} + +// ------------ method called to produce the data ------------ +void L1TrackSelectionProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + auto vTTTrackOutput = std::make_unique(); + auto vTTTrackAssociatedOutput = std::make_unique(); + auto vTTTrackEmulationOutput = std::make_unique(); + auto vTTTrackAssociatedEmulationOutput = std::make_unique(); + + // Tracker Topology + const TrackerTopology& tTopo = iSetup.getData(tTopoToken_); + + TTTrackCollectionHandle l1TracksHandle; + edm::Handle l1VerticesHandle; + edm::Handle l1VerticesEmulationHandle; + + l1t::Vertex leadingVertex; + l1t::VertexWord leadingEmulationVertex; + + iEvent.getByToken(l1TracksToken_, l1TracksHandle); + size_t nOutputApproximate = l1TracksHandle->size(); + if (processSimulatedTracks_) { + if (doDeltaZCutSim_) { + iEvent.getByToken(l1VerticesToken_, l1VerticesHandle); + leadingVertex = l1VerticesHandle->at(0); + if (debug_ >= 2) { + edm::LogInfo("L1TrackSelectionProducer") << "leading vertex z0 = " << leadingVertex.z0(); + } + } + vTTTrackOutput->reserve(nOutputApproximate); + vTTTrackAssociatedOutput->reserve(nOutputApproximate); + } + if (processEmulatedTracks_) { + if (doDeltaZCutEmu_) { + iEvent.getByToken(l1VerticesEmulationToken_, l1VerticesEmulationHandle); + leadingEmulationVertex = l1VerticesEmulationHandle->at(0); + if (debug_ >= 2) { + edm::LogInfo("L1TrackSelectionProducer") << "leading emulation vertex z0 = " << leadingEmulationVertex.z0(); + } + } + vTTTrackEmulationOutput->reserve(nOutputApproximate); + vTTTrackAssociatedEmulationOutput->reserve(nOutputApproximate); + } + + TTTrackPtMinEtaMaxZ0MaxNStubsMinSelector kinSel(ptMin_, absEtaMax_, absZ0Max_, nStubsMin_); + TTTrackWordPtMinEtaMaxZ0MaxNStubsMinSelector kinSelEmu(ptMin_, absEtaMax_, absZ0Max_, nStubsMin_); + TTTrackBendChi2Chi2RZChi2RPhiMaxSelector chi2Sel(bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_); + TTTrackWordBendChi2Chi2RZChi2RPhiMaxSelector chi2SelEmu(bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_); + TTTrackDeltaZMaxSelector deltaZSel(deltaZMaxEtaBounds_, deltaZMax_); + TTTrackWordDeltaZMaxSelector deltaZSelEmu(deltaZMaxEtaBounds_, deltaZMax_); + TTTrackNPSStubsMinSelector nPSStubsSel(nPSStubsMin_, tTopo); + + for (size_t i = 0; i < nOutputApproximate; i++) { + const auto& track = l1TracksHandle->at(i); + + // Select tracks based on the floating point TTTrack + if (processSimulatedTracks_ && kinSel(track) && nPSStubsSel(track) && chi2Sel(track)) { + vTTTrackOutput->push_back(TTTrackRef(l1TracksHandle, i)); + if (doDeltaZCutSim_ && deltaZSel(track, leadingVertex)) { + vTTTrackAssociatedOutput->push_back(TTTrackRef(l1TracksHandle, i)); + } + } + + // Select tracks based on the bitwise accurate TTTrack_TrackWord + if (processEmulatedTracks_ && kinSelEmu(track) && chi2SelEmu(track)) { + vTTTrackEmulationOutput->push_back(TTTrackRef(l1TracksHandle, i)); + if (doDeltaZCutEmu_ && deltaZSelEmu(track, leadingEmulationVertex)) { + vTTTrackAssociatedEmulationOutput->push_back(TTTrackRef(l1TracksHandle, i)); + } + } + } + + if (debug_ >= 2) { + printDebugInfo(l1TracksHandle, + vTTTrackOutput, + vTTTrackEmulationOutput, + vTTTrackAssociatedOutput, + vTTTrackAssociatedEmulationOutput); + } + + // Put the outputs into the event + if (processSimulatedTracks_) { + iEvent.put(std::move(vTTTrackOutput), outputCollectionName_); + if (doDeltaZCutSim_) { + iEvent.put(std::move(vTTTrackAssociatedOutput), outputCollectionName_ + "Associated"); + } + } + if (processEmulatedTracks_) { + iEvent.put(std::move(vTTTrackEmulationOutput), outputCollectionName_ + "Emulation"); + if (doDeltaZCutEmu_) { + iEvent.put(std::move(vTTTrackAssociatedEmulationOutput), outputCollectionName_ + "AssociatedEmulation"); + } + } +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1TrackSelectionProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //L1TrackSelectionProducer + edm::ParameterSetDescription desc; + desc.add("l1TracksInputTag", edm::InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks")); + desc.addOptional("l1VerticesInputTag", edm::InputTag("L1VertexFinder", "l1vertices")); + desc.addOptional("l1VerticesEmulationInputTag", + edm::InputTag("L1VertexFinderEmulator", "l1verticesEmulation")); + desc.add("outputCollectionName", "Level1TTTracksSelected"); + { + edm::ParameterSetDescription descCutSet; + descCutSet.add("ptMin", 2.0)->setComment("pt must be greater than this value, [GeV]"); + descCutSet.add("absEtaMax", 2.4)->setComment("absolute value of eta must be less than this value"); + descCutSet.add("absZ0Max", 15.0)->setComment("z0 must be less than this value, [cm]"); + descCutSet.add("nStubsMin", 4)->setComment("number of stubs must be greater than or equal to this value"); + descCutSet.add("nPSStubsMin", 0) + ->setComment("number of stubs in the PS Modules must be greater than or equal to this value"); + + descCutSet.add("reducedBendChi2Max", 2.25)->setComment("bend chi2 must be less than this value"); + descCutSet.add("reducedChi2RZMax", 5.0)->setComment("chi2rz/dof must be less than this value"); + descCutSet.add("reducedChi2RPhiMax", 20.0)->setComment("chi2rphi/dof must be less than this value"); + + descCutSet.add>("deltaZMaxEtaBounds", {0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4}) + ->setComment("these values define the bin boundaries in |eta|"); + descCutSet.add>("deltaZMax", {0.37, 0.50, 0.60, 0.75, 1.00, 1.60}) + ->setComment( + "delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, " + "[cm]"); + desc.add("cutSet", descCutSet); + } + desc.add("useDisplacedTracksDeltaZOverride", -1.0) + ->setComment("override the deltaZ cut value for displaced tracks"); + desc.add("processSimulatedTracks", true) + ->setComment("return selected tracks after cutting on the floating point values"); + desc.add("processEmulatedTracks", true) + ->setComment("return selected tracks after cutting on the bitwise emulated values"); + desc.add("debug", 0)->setComment("Verbosity levels: 0, 1, 2, 3"); + descriptions.addWithDefaultLabel(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1TrackSelectionProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc new file mode 100644 index 0000000000000..a57bcfabe015f --- /dev/null +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc @@ -0,0 +1,385 @@ +// -*- C++ -*- +// +// Package: L1Trigger/L1TTrackMatch +// Class: L1TrackerEtMissEmulatorProducer +// +/**\class L1TrackerEtMissEmulatorProducer L1TrackerEtMissEmulatorProducer.cc + L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissEmulatorProducer.cc + + Description: Takes L1TTTracks and performs a integer emulation of Track-based + missing Et, outputting a collection of EtSum +*/ +// +// Original Author: Christopher Brown +// Created: Fri, 19 Feb 2021 +// Updated: Wed, 16 Jun 2021 +// +// + +// system include files +#include +#include +#include +// user include files +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" +#include "DataFormats/Math/interface/LorentzVector.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "L1Trigger/L1TTrackMatch/interface/Cordic.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuTrackTransform.h" + +using namespace l1t; + +class L1TrackerEtMissEmulatorProducer : public edm::stream::EDProducer<> { +public: + typedef TTTrack L1TTTrackType; + typedef std::vector L1TTTrackCollectionType; + typedef edm::RefVector L1TTTrackRefCollectionType; + typedef l1t::VertexWordCollection L1VertexCollectionType; + typedef l1t::VertexWord L1VertexType; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + + explicit L1TrackerEtMissEmulatorProducer(const edm::ParameterSet&); + ~L1TrackerEtMissEmulatorProducer() override; + +private: + virtual void beginJob(); + void produce(edm::Event&, const edm::EventSetup&) override; + virtual void endJob(); + + // ----------member data --------------------------- + + std::vector cosLUT_; // Cos LUT array + std::vector phiQuadrants_; + std::vector phiShifts_; + + l1tmetemu::z_t deltaZ0_ = 0; + + int cordicSteps_; + int debug_; + bool cordicDebug_ = false; + + bool GTTinput_ = false; + + L1TkEtMissEmuTrackTransform TrackTransform; + + std::string L1MetCollectionName_; + + const edm::EDGetTokenT pvToken_; + const edm::EDGetTokenT trackToken_; + const edm::EDGetTokenT vtxAssocTrackToken_; +}; + +// constructor// +L1TrackerEtMissEmulatorProducer::L1TrackerEtMissEmulatorProducer(const edm::ParameterSet& iConfig) + : pvToken_(consumes(iConfig.getParameter("L1VertexInputTag"))), + trackToken_(consumes(iConfig.getParameter("L1TrackInputTag"))), + vtxAssocTrackToken_( + consumes(iConfig.getParameter("L1TrackAssociatedInputTag"))) { + // Setup LUTs + TrackTransform.generateLUTs(); + phiQuadrants_ = TrackTransform.getPhiQuad(); + phiShifts_ = TrackTransform.getPhiShift(); + + // Get Emulator config parameters + cordicSteps_ = (int)iConfig.getParameter("nCordicSteps"); + debug_ = (int)iConfig.getParameter("debug"); + + GTTinput_ = (bool)iConfig.getParameter("useGTTinput"); + + TrackTransform.setGTTinput(GTTinput_); + + // Name of output ED Product + L1MetCollectionName_ = (std::string)iConfig.getParameter("L1MetCollectionName"); + + if (debug_ == 5) { + cordicDebug_ = true; + } + + // To have same bin spacing between 0 and pi/2 as between original phi + // granularity + int cosLUTbins = floor(l1tmetemu::kMaxCosLUTPhi / l1tmetemu::kStepPhi); + + // Compute LUTs + cosLUT_ = l1tmetemu::generateCosLUT(cosLUTbins); + + produces>(L1MetCollectionName_); +} + +L1TrackerEtMissEmulatorProducer::~L1TrackerEtMissEmulatorProducer() {} + +void L1TrackerEtMissEmulatorProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + + std::unique_ptr> METCollection(new std::vector(0)); + + edm::Handle L1VertexHandle; + iEvent.getByToken(pvToken_, L1VertexHandle); + + edm::Handle L1TTTrackHandle; + iEvent.getByToken(trackToken_, L1TTTrackHandle); + + edm::Handle L1TTTrackAssociatedHandle; + iEvent.getByToken(vtxAssocTrackToken_, L1TTTrackAssociatedHandle); + + // Initialize cordic class + Cordic cordicSqrt(l1tmetemu::kMETPhiBins, l1tmetemu::kMETSize, cordicSteps_, cordicDebug_); + + if (!L1VertexHandle.isValid()) { + LogError("L1TrackerEtMissEmulatorProducer") << "\nWarning: VertexCollection not found in the event. Exit\n"; + return; + } + + if (!L1TTTrackHandle.isValid()) { + LogError("L1TrackerEtMissEmulatorProducer") << "\nWarning: L1TTTrackCollection not found in the event. Exit\n"; + return; + } + + if (!L1TTTrackAssociatedHandle.isValid()) { + LogError("L1TrackerEtMissEmulatorProducer") + << "\nWarning: L1TTTrackAssociatedCollection not found in the event. Exit\n"; + return; + } + + // Initialize sector sums, need 0 initialization in case a sector has no + // tracks + l1tmetemu::Et_t sumPx[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + l1tmetemu::Et_t sumPy[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int link_totals[l1tmetemu::kNSector * 2] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int sector_totals[l1tmetemu::kNSector] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + + // Track counters + int num_quality_tracks{0}; + int num_assoc_tracks{0}; + + // Get reference to first vertex in event vertex collection + L1VertexType& vtx = const_cast(L1VertexHandle->at(0)); + + for (const auto& track : *L1TTTrackHandle) { + num_quality_tracks++; + L1TTTrackType& track_ref = const_cast(*track); // Get Reference to track to pass to TrackTransform + + // Convert to internal track representation + InternalEtWord EtTrack = TrackTransform.transformTrack(track_ref, vtx); + + if (std::find(L1TTTrackAssociatedHandle->begin(), L1TTTrackAssociatedHandle->end(), track) != + L1TTTrackAssociatedHandle->end()) { + num_assoc_tracks++; + if (debug_ == 7) { + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "Track to Vertex ID: " << num_quality_tracks << "\n" + << "Phi Sector: " << EtTrack.Sector << " pT: " << EtTrack.pt << " Phi: " << EtTrack.globalPhi + << " TanL: " << EtTrack.eta << " Z0: " << EtTrack.z0 << " Nstub: " << EtTrack.nstubs + << " Chi2rphi: " << EtTrack.chi2rphidof << " Chi2rz: " << EtTrack.chi2rzdof + << " bendChi2: " << EtTrack.bendChi2 << " PV: " << EtTrack.pV << "\n" + << "--------------------------------------------------------------\n"; + } + + if (debug_ == 2) { + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "========================Phi debug=================================\n" + << "Int pT: " << EtTrack.pt << "\n" + << "Int Phi: " << EtTrack.globalPhi << " Float Phi: " << EtTrack.phi + << " Actual Float Cos(Phi): " << cos(EtTrack.phi) << " Actual Float Sin(Phi): " << sin(EtTrack.phi) << "\n"; + } + l1tmetemu::Et_t temppx = 0; + l1tmetemu::Et_t temppy = 0; + + // Split tracks in phi quadrants and access cosLUT_, backwards iteration + // through cosLUT_ gives sin Sum sector Et -ve when cos or sin phi are -ve + sector_totals[EtTrack.Sector] += 1; + if (EtTrack.globalPhi >= phiQuadrants_[0] && EtTrack.globalPhi < phiQuadrants_[1]) { + temppx = (EtTrack.pt * cosLUT_[EtTrack.globalPhi]); + temppy = (EtTrack.pt * cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi]); + + if (debug_ == 2) { + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "Sector: " << EtTrack.Sector << " Quadrant: " << 1 << "\n" + << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): " << cosLUT_[EtTrack.globalPhi] + << " Int Sin(Phi): " << cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi] << "\n" + + << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins + << " Float Cos(Phi): " << (float)cosLUT_[EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins + << " Float Sin(Phi): " + << (float)cosLUT_[phiQuadrants_[1] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins << "\n"; + } + } else if (EtTrack.globalPhi >= phiQuadrants_[1] && EtTrack.globalPhi < phiQuadrants_[2]) { + temppx = -(EtTrack.pt * cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi]); + temppy = (EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]]); + + if (debug_ == 2) { + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "Sector: " << EtTrack.Sector << " Quadrant: " << 2 << "\n" + << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): -" + << cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi] + << " Int Sin(Phi): " << cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]] << "\n" + + << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): -" + << (float)cosLUT_[phiQuadrants_[2] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins + << " Float Sin(Phi): " << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[1]] / l1tmetemu::kGlobalPhiBins + << "\n"; + } + } else if (EtTrack.globalPhi >= phiQuadrants_[2] && EtTrack.globalPhi < phiQuadrants_[3]) { + temppx = -(EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]]); + temppy = -(EtTrack.pt * cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi]); + + if (debug_ == 2) { + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "Sector: " << EtTrack.Sector << " Quadrant: " << 3 << "\n" + << "Int Phi: " << EtTrack.globalPhi << " Int Cos(Phi): -" << cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]] + << " Int Sin(Phi): -" << cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi] << "\n" + + << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): -" + << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[2]] / l1tmetemu::kGlobalPhiBins + << " Float Sin(Phi): -" + << (float)cosLUT_[phiQuadrants_[3] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins << "\n"; + } + + } else if (EtTrack.globalPhi >= phiQuadrants_[3] && EtTrack.globalPhi < phiQuadrants_[4]) { + temppx = (EtTrack.pt * cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi]); + temppy = -(EtTrack.pt * cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]]); + + if (debug_ == 2) { + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "Sector: " << EtTrack.Sector << " Quadrant: " << 4 << "\n" + << "Int Phi: " << EtTrack.globalPhi + << " Int Cos(Phi): " << cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi] << " Int Sin(Phi): -" + << cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]] << "\n" + + << "Float Phi: " << (float)EtTrack.globalPhi / l1tmetemu::kGlobalPhiBins << " Float Cos(Phi): " + << (float)cosLUT_[phiQuadrants_[4] - 1 - EtTrack.globalPhi] / l1tmetemu::kGlobalPhiBins + << " Float Sin(Phi): -" + << (float)cosLUT_[EtTrack.globalPhi - phiQuadrants_[3]] / l1tmetemu::kGlobalPhiBins << "\n"; + } + } else { + temppx = 0; + temppy = 0; + } + + int link_number = (EtTrack.Sector * 2) + ((EtTrack.EtaSector) ? 0 : 1); + link_totals[link_number] += 1; + sumPx[link_number] += temppx; + sumPy[link_number] += temppy; + if (debug_ == 4) { + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "Sector: " << EtTrack.Sector << " Eta: " << EtTrack.EtaSector << "\n" + << "Int Track Px: " << temppx << " Int Track Py: " << temppy << "\n" + << "Float Track Px: " << (float)temppx * l1tmetemu::kStepPt + << " Float Track Py:" << (float)temppy * l1tmetemu::kStepPt << "\n" + << "Int Sector Sum Px: " << sumPx[link_number] << " Int Sector Sum Py: " << sumPy[link_number] << "\n" + << "Float Sector Sum Px: " << (float)sumPx[link_number] * l1tmetemu::kStepPt + << " Float Sector Sum Py: " << (float)sumPy[link_number] * l1tmetemu::kStepPt << "\n"; + } + } + + } // end loop over tracks + + l1tmetemu::Et_t GlobalPx = 0; + l1tmetemu::Et_t GlobalPy = 0; + + float tempsumPx = 0; + float tempsumPy = 0; + + // Global Et sum as floats to emulate rounding in HW + for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) { + tempsumPx += floor((float)sumPx[i] / (float)l1tmetemu::kGlobalPhiBins); + tempsumPy += floor((float)sumPy[i] / (float)l1tmetemu::kGlobalPhiBins); + } + + // Recast rounded temporary sums into Et_t datatype + GlobalPx = tempsumPx; + GlobalPy = tempsumPy; + + // Perform cordic sqrt, take x,y and converts to polar coordinate r,phi where + // r=sqrt(x**2+y**2) and phi = atan(y/x) + l1tmetemu::EtMiss EtMiss = cordicSqrt.toPolar(GlobalPx, GlobalPy); + + // Recentre phi + l1tmetemu::METphi_t tempPhi = 0; + + if ((GlobalPx < 0) && (GlobalPy < 0)) + tempPhi = EtMiss.Phi - l1tmetemu::kMETPhiBins / 2; + else if ((GlobalPx >= 0) && (GlobalPy >= 0)) + tempPhi = (EtMiss.Phi) + l1tmetemu::kMETPhiBins / 2; + else if ((GlobalPx >= 0) && (GlobalPy < 0)) + tempPhi = EtMiss.Phi - l1tmetemu::kMETPhiBins / 2; + else if ((GlobalPx < 0) && (GlobalPy >= 0)) + tempPhi = EtMiss.Phi - 3 * l1tmetemu::kMETPhiBins / 2; + + if (debug_ == 4 || debug_ == 6) { + std::stringstream flpxarray; + std::stringstream flpyarray; + + std::stringstream intpxarray; + std::stringstream intpyarray; + + std::stringstream totalsarray; + std::stringstream linksarray; + + for (unsigned int i = 0; i < l1tmetemu::kNSector * 2; i++) { + flpxarray << to_string(sumPx[i] * l1tmetemu::kStepPt) + "|"; + flpyarray << to_string(sumPy[i] * l1tmetemu::kStepPt) + "|"; + intpxarray << to_string(floor((float)sumPx[i] / (float)l1tmetemu::kGlobalPhiBins)) + "|"; + intpyarray << to_string(floor((float)sumPy[i] / (float)l1tmetemu::kGlobalPhiBins)) + "|"; + linksarray << to_string(link_totals[i]) + "|"; + if (i < l1tmetemu::kNSector) { + totalsarray << to_string(sector_totals[i]) + "|"; + } + } + + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "====Sector Pt====\n" + << "Float Px: " << flpxarray.str() << "\nFloat Py: " << flpyarray.str() << "\nInteger Px: " << intpyarray.str() + << "\nInteger Px: " << intpyarray.str() << "\nLink Totals: " << linksarray.str() + << "\nSector Totals: " << totalsarray.str() << "\n" + + << "====Global Pt====\n" + << "Integer Global Px: " << GlobalPx << "| Integer Global Py: " << GlobalPy << "\n" + << "Float Global Px: " << GlobalPx * l1tmetemu::kStepPt + << "| Float Global Py: " << GlobalPy * l1tmetemu::kStepPt << "\n"; + } + + if (debug_ == 4 || debug_ == 6) { + edm::LogVerbatim("L1TrackerEtMissEmulatorProducer") + << "====MET===\n" + << "Integer MET: " << EtMiss.Et << "| Integer MET phi: " << EtMiss.Phi << "\n" + << "Float MET: " << (EtMiss.Et) * l1tmetemu::kStepMET + << "| Float MET phi: " << (float)tempPhi * l1tmetemu::kStepMETPhi - M_PI << "\n" + << "# Tracks after Quality Cuts: " << num_quality_tracks << "\n" + << "# Tracks Associated to Vertex: " << num_assoc_tracks << "\n" + << "========================================================\n"; + } + + math::XYZTLorentzVector missingEt(-GlobalPx, -GlobalPy, 0, EtMiss.Et); + EtSum L1EtSum(missingEt, EtSum::EtSumType::kMissingEt, (int)EtMiss.Et, 0, (int)tempPhi, (int)num_assoc_tracks); + + METCollection->push_back(L1EtSum); + + iEvent.put(std::move(METCollection), L1MetCollectionName_); +} // end producer + +void L1TrackerEtMissEmulatorProducer::beginJob() {} + +void L1TrackerEtMissEmulatorProducer::endJob() {} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1TrackerEtMissEmulatorProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +// define this as a plug-in +DEFINE_FWK_MODULE(L1TrackerEtMissEmulatorProducer); diff --git a/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissProducer.cc b/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissProducer.cc index ceb70e27980d5..ab031e65ff838 100644 --- a/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissProducer.cc +++ b/L1Trigger/L1TTrackMatch/plugins/L1TrackerEtMissProducer.cc @@ -1,143 +1,98 @@ // Original Author: Emmanuelle Perez,40 1-A28,+41227671915, // Created: Tue Nov 12 17:03:19 CET 2013 -//Modified by Emily MacDonald, 30 Nov 2018 +// Modified by Emily MacDonald, 30 Nov 2018 +// Modified by Christopher Brown 27 March 2021 // system include files +#include #include // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/EDProducer.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/Math/interface/LorentzVector.h" -#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" #include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" - -// detector geometry -#include "MagneticField/Engine/interface/MagneticField.h" -#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" -#include "Geometry/Records/interface/TrackerTopologyRcd.h" -#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/Math/interface/LorentzVector.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" using namespace l1t; -class L1TrackerEtMissProducer : public edm::stream::EDProducer<> { +class L1TrackerEtMissProducer : public edm::global::EDProducer<> { public: typedef TTTrack L1TTTrackType; typedef std::vector L1TTTrackCollectionType; + typedef edm::RefVector L1TTTrackRefCollectionType; explicit L1TrackerEtMissProducer(const edm::ParameterSet&); ~L1TrackerEtMissProducer() override; private: - //void beginJob() override; - void produce(edm::Event&, const edm::EventSetup&) override; - //void endJob() override; + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; // ----------member data --------------------------- - float maxZ0_; // in cm - float deltaZ_; // in cm - float maxEta_; - float chi2dofMax_; - float bendChi2Max_; - float minPt_; // in GeV - int nStubsmin_; - int nPSStubsMin_; // minimum number of stubs in PS modules + const edm::EDGetTokenT trackToken_; + const edm::EDGetTokenT vtxAssocTrackToken_; + std::string L1MetCollectionName; float maxPt_; // in GeV int highPtTracks_; // saturate or truncate - bool displaced_; //prompt/displaced tracks - - const edm::EDGetTokenT pvToken_; - const edm::EDGetTokenT > > trackToken_; - edm::ESGetToken tTopoToken_; + bool debug_; }; -//constructor// +// constructor L1TrackerEtMissProducer::L1TrackerEtMissProducer(const edm::ParameterSet& iConfig) - : pvToken_(consumes(iConfig.getParameter("L1VertexInputTag"))), - trackToken_(consumes > >( - iConfig.getParameter("L1TrackInputTag"))), - tTopoToken_(esConsumes(edm::ESInputTag("", ""))) { - maxZ0_ = (float)iConfig.getParameter("maxZ0"); - deltaZ_ = (float)iConfig.getParameter("deltaZ"); - chi2dofMax_ = (float)iConfig.getParameter("chi2dofMax"); - bendChi2Max_ = (float)iConfig.getParameter("bendChi2Max"); - minPt_ = (float)iConfig.getParameter("minPt"); - nStubsmin_ = iConfig.getParameter("nStubsmin"); - nPSStubsMin_ = iConfig.getParameter("nPSStubsMin"); - maxPt_ = (float)iConfig.getParameter("maxPt"); - maxEta_ = (float)iConfig.getParameter("maxEta"); - highPtTracks_ = iConfig.getParameter("highPtTracks"); - displaced_ = iConfig.getParameter("displaced"); - - if (displaced_) - produces("L1TrackerEtMissExtended"); - else - produces("L1TrackerEtMiss"); + : trackToken_(consumes(iConfig.getParameter("L1TrackInputTag"))), + vtxAssocTrackToken_( + consumes(iConfig.getParameter("L1TrackAssociatedInputTag"))), + L1MetCollectionName(iConfig.getParameter("L1MetCollectionName")), + maxPt_(iConfig.getParameter("maxPt")), + highPtTracks_(iConfig.getParameter("highPtTracks")), + debug_(iConfig.getParameter("debug")) { + produces(L1MetCollectionName); } L1TrackerEtMissProducer::~L1TrackerEtMissProducer() {} -void L1TrackerEtMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { +void L1TrackerEtMissProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { using namespace edm; std::unique_ptr METCollection(new TkEtMissCollection); - // Tracker Topology - const TrackerTopology& tTopo = iSetup.getData(tTopoToken_); - - edm::Handle L1VertexHandle; - iEvent.getByToken(pvToken_, L1VertexHandle); - - edm::Handle L1TTTrackHandle; + edm::Handle L1TTTrackHandle; iEvent.getByToken(trackToken_, L1TTTrackHandle); - L1TTTrackCollectionType::const_iterator trackIter; - if (!L1VertexHandle.isValid()) { - LogError("L1TrackerEtMissProducer") << "\nWarning: TkPrimaryVertexCollection not found in the event. Exit\n"; - return; - } + edm::Handle L1TTTrackAssociatedHandle; + iEvent.getByToken(vtxAssocTrackToken_, L1TTTrackAssociatedHandle); if (!L1TTTrackHandle.isValid()) { LogError("L1TrackerEtMissProducer") << "\nWarning: L1TTTrackCollection not found in the event. Exit\n"; return; } + if (!L1TTTrackAssociatedHandle.isValid()) { + LogError("L1TrackerEtMissProducer") << "\nWarning: L1TTTrackAssociatedCollection not found in the event. Exit\n"; + return; + } + float sumPx = 0; float sumPy = 0; float etTot = 0; double sumPx_PU = 0; double sumPy_PU = 0; double etTot_PU = 0; - float zVTX = L1VertexHandle->begin()->zvertex(); - - for (trackIter = L1TTTrackHandle->begin(); trackIter != L1TTTrackHandle->end(); ++trackIter) { - float pt = trackIter->momentum().perp(); - float phi = trackIter->momentum().phi(); - float eta = trackIter->momentum().eta(); - float chi2dof = trackIter->chi2Red(); - float bendChi2 = trackIter->stubPtConsistency(); - float z0 = trackIter->z0(); - std::vector >, TTStub > > - theStubs = trackIter->getStubRefs(); - int nstubs = (int)theStubs.size(); - - if (pt < minPt_) - continue; - if (fabs(z0) > maxZ0_) - continue; - if (fabs(eta) > maxEta_) - continue; - if (chi2dof > chi2dofMax_) - continue; - if (bendChi2 > bendChi2Max_) - continue; + + int numqualitytracks = 0; + int numassoctracks = 0; + + for (const auto& track : *L1TTTrackHandle) { + float pt = track->momentum().perp(); + float phi = track->momentum().phi(); if (maxPt_ > 0 && pt > maxPt_) { if (highPtTracks_ == 0) @@ -146,39 +101,11 @@ void L1TrackerEtMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& pt = maxPt_; // saturate } - int nPS = 0; // number of stubs in PS modules - // loop over the stubs - for (unsigned int istub = 0; istub < (unsigned int)theStubs.size(); istub++) { - DetId detId(theStubs.at(istub)->getDetId()); - if (detId.det() == DetId::Detector::Tracker) { - if ((detId.subdetId() == StripSubdetector::TOB && tTopo.tobLayer(detId) <= 3) || - (detId.subdetId() == StripSubdetector::TID && tTopo.tidRing(detId) <= 9)) - nPS++; - } - } + numqualitytracks++; - if (nstubs < nStubsmin_) - continue; - if (nPS < nPSStubsMin_) - continue; - - if (!displaced_) { // if displaced, deltaZ = 3.0 cm, very loose - // construct deltaZ cut to be based on track eta - if (fabs(eta) >= 0 && fabs(eta) < 0.7) - deltaZ_ = 0.4; - else if (fabs(eta) >= 0.7 && fabs(eta) < 1.0) - deltaZ_ = 0.6; - else if (fabs(eta) >= 1.0 && fabs(eta) < 1.2) - deltaZ_ = 0.76; - else if (fabs(eta) >= 1.2 && fabs(eta) < 1.6) - deltaZ_ = 1.0; - else if (fabs(eta) >= 1.6 && fabs(eta) < 2.0) - deltaZ_ = 1.7; - else if (fabs(eta) >= 2.0 && fabs(eta) <= 2.4) - deltaZ_ = 2.2; - } - - if (fabs(z0 - zVTX) <= deltaZ_) { + if (std::find(L1TTTrackAssociatedHandle->begin(), L1TTTrackAssociatedHandle->end(), track) != + L1TTTrackAssociatedHandle->end()) { + numassoctracks++; sumPx += pt * cos(phi); sumPy += pt * sin(phi); etTot += pt; @@ -190,20 +117,29 @@ void L1TrackerEtMissProducer::produce(edm::Event& iEvent, const edm::EventSetup& } // end loop over tracks float et = sqrt(sumPx * sumPx + sumPy * sumPy); - double etmiss_PU = sqrt(sumPx_PU * sumPx_PU + sumPy_PU * sumPy_PU); + double etphi = atan2(sumPy, sumPx); math::XYZTLorentzVector missingEt(-sumPx, -sumPy, 0, et); - int ibx = 0; - METCollection->push_back(TkEtMiss(missingEt, TkEtMiss::kMET, etTot, etmiss_PU, etTot_PU, ibx)); - if (displaced_) - iEvent.put(std::move(METCollection), "L1TrackerEtMissExtended"); - else - iEvent.put(std::move(METCollection), "L1TrackerEtMiss"); -} // end producer + if (debug_) { + edm::LogVerbatim("L1TrackerEtMissProducer") << "====Global Pt====" + << "\n" + << "Px: " << sumPx << "| Py: " << sumPy << "\n" + << "====MET===" + << "\n" + << "MET: " << et << "| Phi: " << etphi << "\n" + + << "# Tracks after quality cuts: " << L1TTTrackHandle->size() << "\n" + << "# Tacks after additional highPt Cuts: " << numqualitytracks << "\n" + << "# Tracks associated to vertex: " << numassoctracks << "\n" + << "========================================================" + << "\n"; + } -//void L1TrackerEtMissProducer::beginJob() {} + int ibx = 0; + METCollection->push_back(TkEtMiss(missingEt, TkEtMiss::kMET, etphi, numassoctracks, ibx)); -//void L1TrackerEtMissProducer::endJob() {} + iEvent.put(std::move(METCollection), L1MetCollectionName); +} // end producer DEFINE_FWK_MODULE(L1TrackerEtMissProducer); diff --git a/L1Trigger/L1TTrackMatch/python/L1FastTrackingJetProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1FastTrackingJetProducer_cfi.py index 027fc95783ef2..ffea31f70368b 100644 --- a/L1Trigger/L1TTrackMatch/python/L1FastTrackingJetProducer_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/L1FastTrackingJetProducer_cfi.py @@ -1,8 +1,10 @@ import FWCore.ParameterSet.Config as cms +from L1Trigger.VertexFinder.VertexProducer_cff import VertexProducer + L1FastTrackingJets = cms.EDProducer("L1FastTrackingJetProducer", L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), - L1PrimaryVertexTag = cms.string("l1vertices"), + L1PrimaryVertexTag=cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()), GenInfo = cms.InputTag("TTTrackAssociatorFromPixelDigis", "Level1TTTracks"), trk_zMax = cms.double(15.), # max track z0 [cm] trk_chi2dofMax = cms.double(10.), # max track chi2/dof @@ -24,7 +26,7 @@ L1FastTrackingJetsExtended = cms.EDProducer("L1FastTrackingJetProducer", L1TrackInputTag = cms.InputTag("TTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), - L1PrimaryVertexTag = cms.string("l1vertices"), + L1PrimaryVertexTag=cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()), GenInfo = cms.InputTag("TTTrackAssociatorFromPixelDigisExtended", "Level1TTTracks"), trk_zMax = cms.double(15.), # max track z0 [cm] trk_chi2dofMax = cms.double(40.), # max track chi2 for extended tracks diff --git a/L1Trigger/L1TTrackMatch/python/L1GTTInputProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1GTTInputProducer_cfi.py new file mode 100644 index 0000000000000..e01a70d531391 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1GTTInputProducer_cfi.py @@ -0,0 +1,13 @@ +import FWCore.ParameterSet.Config as cms + +L1GTTInputProducer = cms.EDProducer('L1GTTInputProducer', + l1TracksInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), + outputCollectionName = cms.string("Level1TTTracksConverted"), + debug = cms.int32(0) # Verbosity levels: 0, 1, 2, 3 +) + +L1GTTInputProducerExtended = cms.EDProducer('L1GTTInputProducer', + l1TracksInputTag = cms.InputTag("TTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), + outputCollectionName = cms.string("Level1TTTracksExtendedConverted"), + debug = cms.int32(0) # Verbosity levels: 0, 1, 2, 3 +) diff --git a/L1Trigger/L1TTrackMatch/python/L1TkEgammaObjects_cff.py b/L1Trigger/L1TTrackMatch/python/L1TkEgammaObjects_cff.py deleted file mode 100644 index 16ff02bdb55c4..0000000000000 --- a/L1Trigger/L1TTrackMatch/python/L1TkEgammaObjects_cff.py +++ /dev/null @@ -1,8 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from L1Trigger.L1TTrackMatch.L1TkElectronTrackProducer_cfi import * - -l1TkElectronTrackEllipticProducers = cms.Sequence(L1TkElectronsEllipticMatchCrystal+L1TkElectronsEllipticMatchHGC) -l1TkElectronTrackEllipticProducersEB = cms.Sequence(L1TkElectronsEllipticMatchCrystal) -l1TkElectronTrackEllipticProducersEE = cms.Sequence(L1TkElectronsEllipticMatchHGC) - diff --git a/L1Trigger/L1TTrackMatch/python/L1TkElectronTrackProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkElectronTrackProducer_cfi.py deleted file mode 100644 index c30f631ae1810..0000000000000 --- a/L1Trigger/L1TTrackMatch/python/L1TkElectronTrackProducer_cfi.py +++ /dev/null @@ -1,100 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -L1TkElectrons = cms.EDProducer("L1TkElectronTrackProducer", - label = cms.string("EG"), # labels the collection of L1TkEmParticleProducer that is produced. - # (not really needed actually) - L1EGammaInputTag = cms.InputTag("simCaloStage2Digis",""), - # Only the L1EG objects that have ET > ETmin in GeV - # are considered. ETmin < 0 means that no cut is applied. - ETmin = cms.double( -1.0 ), - L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), - # Quality cuts on Track and Track L1EG matching criteria - TrackChi2 = cms.double(1e10), # minimum Chi2 to select tracks - TrackMinPt = cms.double(10.0), # minimum Pt to select tracks - useTwoStubsPT = cms.bool( False ), - useClusterET = cms.bool( False ), - TrackEGammaMatchType = cms.string("PtDependentCut"), - TrackEGammaDeltaPhi = cms.vdouble(0.07, 0.0, 0.0), # functional Delta Phi cut parameters to match Track with L1EG objects - TrackEGammaDeltaR = cms.vdouble(0.08, 0.0, 0.0), # functional Delta R cut parameters to match Track with L1EG objects - TrackEGammaDeltaEta = cms.vdouble(1e10, 0.0, 0.0), # Delta Eta cutoff to match Track with L1EG objects - # are considered. (unused in default configuration) - RelativeIsolation = cms.bool( True ), # default = True. The isolation variable is relative if True, - # else absolute. - # Cut on the (Trk-based) isolation: only the L1TkEmParticle for which - # the isolation is below RelIsoCut are written into - # the output collection. When RelIsoCut < 0, no cut is applied. - # When RelativeIsolation = False, IsoCut is in GeV. - # Determination of the isolation w.r.t. L1Tracks : - IsoCut = cms.double( -0.10 ), - PTMINTRA = cms.double( 2. ), # in GeV - DRmin = cms.double( 0.03), - DRmax = cms.double( 0.2 ), - maxChi2IsoTracks = cms.double(1e10), # max chi2 cut for a track to be considered for isolation computation - minNStubsIsoTracks = cms.int32(0), # min cut on # of stubs for a track to be considered for isolation computation - DeltaZ = cms.double( 0.6 ) # in cm. Used for tracks to be used isolation calculation -) -L1TkIsoElectrons = L1TkElectrons.clone( - IsoCut = cms.double( 0.10 ) -) -# for LowPt Electron -L1TkElectronsLoose = L1TkElectrons.clone( - TrackEGammaDeltaPhi = cms.vdouble(0.07, 0.0, 0.0), - TrackEGammaDeltaR = cms.vdouble(0.12, 0.0, 0.0), - TrackMinPt = cms.double( 3.0 ) -) - - -#### Additional collections that right now only the menu team is using - to be renamed/redefined by the EGamma group -# The important change is the EG seed -> PhaseII instead of PhaseI - -#barrel -L1TkElectronsCrystal = L1TkElectrons.clone( - L1EGammaInputTag = cms.InputTag("L1EGammaClusterEmuProducer"), - IsoCut = cms.double(-0.1) -) - -L1TkIsoElectronsCrystal=L1TkElectronsCrystal.clone( - IsoCut = cms.double(0.1) -) - -L1TkElectronsLooseCrystal = L1TkElectronsCrystal.clone( - TrackEGammaDeltaPhi = cms.vdouble(0.07, 0.0, 0.0), - TrackEGammaDeltaR = cms.vdouble(0.12, 0.0, 0.0), - TrackMinPt = cms.double( 3.0 ) -) - -L1TkElectronsEllipticMatchCrystal = L1TkElectronsCrystal.clone( - TrackEGammaMatchType = cms.string("EllipticalCut"), - TrackEGammaDeltaEta = cms.vdouble(0.015, 0.025,1e10) -) - - - -#endcap -L1TkElectronsHGC=L1TkElectrons.clone( - L1EGammaInputTag = cms.InputTag("l1EGammaEEProducer","L1EGammaCollectionBXVWithCuts"), - IsoCut = cms.double(-0.1) -) - - -L1TkElectronsEllipticMatchHGC = L1TkElectronsHGC.clone( - TrackEGammaMatchType = cms.string("EllipticalCut"), - TrackEGammaDeltaEta = cms.vdouble(0.01, 0.01,1e10), - maxChi2IsoTracks = cms.double(100), - minNStubsIsoTracks = cms.int32(4), -) - - -L1TkIsoElectronsHGC=L1TkElectronsHGC.clone( - DRmax = cms.double(0.4), - DeltaZ = cms.double(1.0), - maxChi2IsoTracks = cms.double(100), - minNStubsIsoTracks = cms.int32(4), - IsoCut = cms.double(0.1) - ) - -L1TkElectronsLooseHGC = L1TkElectronsHGC.clone( - TrackEGammaDeltaPhi = cms.vdouble(0.07, 0.0, 0.0), - TrackEGammaDeltaR = cms.vdouble(0.12, 0.0, 0.0), - TrackMinPt = cms.double( 3.0 ) -) diff --git a/L1Trigger/L1TTrackMatch/python/L1TkEmParticleProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkEmParticleProducer_cfi.py deleted file mode 100644 index c6375eab11c36..0000000000000 --- a/L1Trigger/L1TTrackMatch/python/L1TkEmParticleProducer_cfi.py +++ /dev/null @@ -1,55 +0,0 @@ -import FWCore.ParameterSet.Config as cms -from L1Trigger.L1TTrackMatch.l1TkEmParticleProducer_cfi import l1TkEmParticleProducer - -L1TkPhotons = l1TkEmParticleProducer.clone( - label = "EG", # labels the collection of L1TkEmParticleProducer that is produced - # (not really needed actually) - L1EGammaInputTag = ("simCaloStage2Digis",""), - # When the standard sequences are used : - # - for the Run-1 algo, use ("l1extraParticles","NonIsolated") - # or ("l1extraParticles","Isolated") - # - for the "old stage-2" algo (2x2 clustering), use - # ("SLHCL1ExtraParticles","EGamma") or ("SLHCL1ExtraParticles","IsoEGamma") - # - for the new clustering algorithm of Jean-Baptiste et al, - # use ("SLHCL1ExtraParticlesNewClustering","IsoEGamma") or - # ("SLHCL1ExtraParticlesNewClustering","EGamma"). - ETmin = -1., # Only the L1EG objects that have ET > ETmin in GeV - # are considered. ETmin < 0 means that no cut is applied. - RelativeIsolation = True, # default = True. The isolation variable is relative if true, else absolute. - IsoCut = 0.23, # Cut on the (Trk-based) isolation: only the L1TkEmParticle for which - # the isolation is below RelIsoCut are written into - # the output collection. When RelIsoCut < 0, no cut is applied. - # When RelativeIsolation = False, IsoCut is in GeV. - # Determination of the isolation w.r.t. L1Tracks : - L1TrackInputTag = ("TTTracksFromTrackletEmulation", "Level1TTTracks"), - ZMAX = 25., # in cm - CHI2MAX = 100., - PTMINTRA = 2., # in GeV - DRmin = 0.07, - DRmax = 0.30, - PrimaryVtxConstrain = False, # default = False - # if set to True, the default isolation is the PV constrained one, where L1TkPrimaryVertex - # is used to constrain the tracks entering in the calculation of the isolation - # if set to False, the isolation is computed and stored, but not used - DeltaZMax = 0.6, # in cm. Used only to compute the isolation with PrimaryVtxConstrain - L1VertexInputTag = ("L1TkPrimaryVertex") -) - - -L1TkPhotonsTightIsol = L1TkPhotons.clone( - IsoCut = 0.10 -) - -#### Additional collections that right now only the menu team is using - to be renamed/redefined by the EGamma group -# The important change is the EG seed -> PhaseII instead of PhaseI - -L1TkPhotonsCrystal=L1TkPhotons.clone( - L1EGammaInputTag = ("L1EGammaClusterEmuProducer", ), - IsoCut = -0.1 -) - -L1TkPhotonsHGC=L1TkPhotons.clone( - L1EGammaInputTag = ("l1EGammaEEProducer","L1EGammaCollectionBXVWithCuts"), - IsoCut = -0.1 -) - diff --git a/L1Trigger/L1TTrackMatch/python/L1TkHTMissEmulatorProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkHTMissEmulatorProducer_cfi.py new file mode 100644 index 0000000000000..a2cf212512dd0 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TkHTMissEmulatorProducer_cfi.py @@ -0,0 +1,23 @@ +import FWCore.ParameterSet.Config as cms + +L1TrackerEmuHTMiss = cms.EDProducer("L1TkHTMissEmulatorProducer", + L1TkJetEmulationInputTag = cms.InputTag("L1TrackJetsEmulation", "L1TrackJets"), + L1MHTCollectionName = cms.string("L1TrackerEmuHTMiss"), + jet_maxEta = cms.double(2.4), + jet_minPt = cms.double(5.0), + jet_minNtracksLowPt = cms.int32(2), + jet_minNtracksHighPt = cms.int32(3), + debug = cms.bool(False), + displaced = cms.bool(False) +) + +L1TrackerEmuHTMissExtended = cms.EDProducer("L1TkHTMissEmulatorProducer", + L1TkJetEmulationInputTag = cms.InputTag("L1TrackJetsExtendedEmulation", "L1TrackJetsExtended"), + L1MHTCollectionName = cms.string("L1TrackerEmuHTMissExtended"), + jet_maxEta = cms.double(2.4), + jet_minPt = cms.double(5.0), + jet_minNtracksLowPt = cms.int32(2), + jet_minNtracksHighPt = cms.int32(3), + debug = cms.bool(False), + displaced = cms.bool(True) +) diff --git a/L1Trigger/L1TTrackMatch/python/L1TkHTMissProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkHTMissProducer_cfi.py index e3124647b245b..bdf7c5cb669c5 100644 --- a/L1Trigger/L1TTrackMatch/python/L1TkHTMissProducer_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/L1TkHTMissProducer_cfi.py @@ -1,8 +1,9 @@ import FWCore.ParameterSet.Config as cms +from L1Trigger.VertexFinder.VertexProducer_cff import VertexProducer L1TkCaloHTMiss = cms.EDProducer("L1TkHTMissProducer", L1TkJetInputTag = cms.InputTag("L1TkCaloJets", "L1TkCaloJets"), - L1VertexInputTag = cms.InputTag("L1TkPrimaryVertex"), + L1VertexInputTag = cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()), jet_maxEta = cms.double(2.2), # maximum eta of jets for HT jet_minPt = cms.double(15.0), # minimum pt of jets for HT [GeV] jet_minNtracksHighPt=cms.int32(0), #Add track jet quality criteria pT>100 @@ -21,7 +22,7 @@ L1TrackerHTMiss = cms.EDProducer("L1TkHTMissProducer", L1TkJetInputTag = cms.InputTag("L1TrackJets", "L1TrackJets"), - L1VertexInputTag = cms.InputTag("L1TkPrimaryVertex"), + L1VertexInputTag = cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()), jet_maxEta = cms.double(2.4), jet_minPt = cms.double(5.0), jet_minNtracksLowPt=cms.int32(2), @@ -37,7 +38,7 @@ L1TrackerHTMissExtended = cms.EDProducer("L1TkHTMissProducer", L1TkJetInputTag = cms.InputTag("L1TrackJetsExtended", "L1TrackJetsExtended"), - L1VertexInputTag = cms.InputTag("L1TkPrimaryVertex"), + L1VertexInputTag = cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()), jet_maxEta = cms.double(2.4), jet_minPt = cms.double(5.0), jet_minNtracksLowPt=cms.int32(2), diff --git a/L1Trigger/L1TTrackMatch/python/L1TkMETAnalyser_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkMETAnalyser_cfi.py new file mode 100644 index 0000000000000..edd1fa9afd9b3 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TkMETAnalyser_cfi.py @@ -0,0 +1,10 @@ +import FWCore.ParameterSet.Config as cms +from L1Trigger.L1TTrackMatch.L1TrackerEtMissEmulatorProducer_cfi import L1TrackerEmuEtMiss +from L1Trigger.L1TTrackMatch.L1TrackerEtMissProducer_cfi import L1TrackerEtMiss + +L1TkMETAnalyser = cms.EDAnalyzer('L1TkMETAnalyser', + TrackMETInputTag = cms.InputTag("L1TrackerEtMiss",L1TrackerEtMiss.L1MetCollectionName.value()), + TrackMETEmuInputTag = cms.InputTag("L1TrackerEmuEtMiss",L1TrackerEmuEtMiss.L1MetCollectionName.value()), + TrackMETHWInputTag = cms.InputTag("GTTOutputFileReader"), + HW_Analysis = cms.bool(False) +) \ No newline at end of file diff --git a/L1Trigger/L1TTrackMatch/python/L1TkMuonProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkMuonProducer_cfi.py deleted file mode 100644 index c04c75a90c4d6..0000000000000 --- a/L1Trigger/L1TTrackMatch/python/L1TkMuonProducer_cfi.py +++ /dev/null @@ -1,78 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -L1TkMuons = cms.EDProducer("L1TkMuonProducer", - ############################################### - ## switches that control the algos for the regions - bmtfMatchAlgoVersion = cms.string( 'TP' ), - omtfMatchAlgoVersion = cms.string( 'MAnTra' ), - emtfMatchAlgoVersion = cms.string( 'MAnTra' ), - ############################################### common stuff - L1BMTFInputTag = cms.InputTag("simKBmtfDigis","BMTF"), - L1OMTFInputTag = cms.InputTag("simOmtfDigis","OMTF"), - L1EMTFInputTag = cms.InputTag("simEmtfDigis","EMTF"), - L1EMTFTrackCollectionInputTag = cms.InputTag("simEmtfDigis"), - L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), - ############################################### - ############################################### TP algo - ETAMIN = cms.double(0), - ETAMAX = cms.double(5.), # no cut - ETABARRELOVERLAP = cms.double(0.83), - ETAOVERLAPENDCAP = cms.double(1.24), - useRegionEtaMatching = cms.bool(True), - ZMAX = cms.double( 25. ), # in cm - CHI2MAX = cms.double( 100. ), - PTMINTRA = cms.double( 2. ), # in GeV - DRmax = cms.double( 0.5 ), - nStubsmin = cms.int32( 4 ), # minimum number of stubs -# closest = cms.bool( True ), - correctGMTPropForTkZ = cms.bool(True), - use5ParameterFit = cms.bool(False), #use 4-pars by defaults - useTPMatchWindows = cms.bool(True), - # emtfMatchAlgoVersion = cms.int32( 1 ), # version of matching EMTF with Trackes (1 or 2) - ############################################### - ############################################### DynamicWindows algo - ##### parameters for the DynamicWindows algo - eventually to put in a separate file, that will override some dummy defaults - emtfcorr_boundaries = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_boundaries.root'), - emtfcorr_theta_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_theta_q99.root'), - emtfcorr_phi_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_phi_q99.root'), - ## block to control the evolution of the matching window vs pt - ## if do_relax_factors = False ==> global scale of upper and lower boundaries by "final_window_factor" - ## if do_relax_factors = True ==> progressive linear scale, the factor is - ## - initial_window_factor for pt <= pt_start_relax - ## - final_window_factor for pt >= pt_end_relax - ## - and a linear interpolation in the middle - ## facror = 0 --> no changes to the window size - initial_window_factor = cms.double(0.0), - final_window_factor = cms.double(0.5), - pt_start_relax = cms.double(2.0), - pt_end_relax = cms.double(6.0), - do_relax_factors = cms.bool(True), - ## - n_trk_par = cms.int32(4), # 4 or 5 - min_trk_p = cms.double(3.5), - max_trk_aeta = cms.double(2.5), - max_trk_chi2 = cms.double(100.0), - min_trk_nstubs = cms.int32(4), - ############################################### - ############################################### Mantra algo - ## please NOTE that as of 6/11/2019, only these parameters are effectively used for the MAnTra correlator - # - mantra_n_trk_par = cms.int32(4), # 4 or 5 - # - mantra_bmtfcorr_boundaries = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_barrel/matching_windows_boundaries.root'), - mantra_bmtfcorr_theta_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_barrel/matching_windows_theta_q99.root'), - mantra_bmtfcorr_phi_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_barrel/matching_windows_phi_q99.root'), - # - mantra_omtfcorr_boundaries = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_overlap/matching_windows_boundaries.root'), - mantra_omtfcorr_theta_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_overlap/matching_windows_theta_q99.root'), - mantra_omtfcorr_phi_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_overlap/matching_windows_phi_q99.root'), - # - mantra_emtfcorr_boundaries = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_boundaries.root'), - mantra_emtfcorr_theta_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_theta_q99.root'), - mantra_emtfcorr_phi_windows = cms.FileInPath('L1Trigger/L1TMuon/data/MAnTra_data/matching_windows_endcap/matching_windows_phi_q99.root'), -) - -L1TkMuonsTP = L1TkMuons.clone( - emtfMatchAlgoVersion='TP', - useTPMatchWindows = True -) diff --git a/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py b/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py index 190a386700087..3515445e92bc9 100644 --- a/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py +++ b/L1Trigger/L1TTrackMatch/python/L1TkObjectProducers_cff.py @@ -53,6 +53,9 @@ from L1Trigger.VertexFinder.VertexProducer_cff import VertexProducer pVertexProducer = cms.Path( VertexProducer ) +from L1Trigger.VertexFinder.VertexProducer_cff import VertexProducer +pVertexProducer = cms.Path( VertexProducer ) + # from L1Trigger.L1TTrackMatch.L1TrackerEtMissProducer_cfi import L1TrackerEtMiss # pL1TrkMET = cms.Path( L1TrackerEtMiss ) @@ -63,8 +66,8 @@ from L1Trigger.L1TTrackMatch.L1TkMuonProducer_cfi import L1TkMuons, L1TkMuonsTP pL1TkMuon = cms.Path( L1TkMuons * L1TkMuonsTP ) -# from L1Trigger.L1TTrackMatch.L1TkGlbMuonProducer_cfi import L1TkGlbMuons -# pL1TkGlbMuon = cms.Path( L1TkGlbMuons ) +from L1Trigger.L1TTrackMatch.L1TkGlbMuonProducer_cfi import L1TkGlbMuons +pL1TkGlbMuon = cms.Path( L1TkGlbMuons ) # from L1Trigger.L1TTrackMatch.L1TrkTauFromCaloProducer_cfi import L1TrkTauFromCalo # pL1TrkTauFromCalo = cms.Path( L1TrkTauFromCalo ) diff --git a/L1Trigger/L1TTrackMatch/python/L1TkPrimaryVertexProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TkPrimaryVertexProducer_cfi.py deleted file mode 100644 index 97d4d5768cf92..0000000000000 --- a/L1Trigger/L1TTrackMatch/python/L1TkPrimaryVertexProducer_cfi.py +++ /dev/null @@ -1,44 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -L1TkPrimaryVertex = cms.EDProducer('L1TkFastVertexProducer', - -# -# Default parameters used for the plots for the TP -# - HepMCInputTag = cms.InputTag("generator"), - GenParticleInputTag = cms.InputTag("genParticles",""), - L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), - ZMAX = cms.double ( 25. ) , # in cm - CHI2MAX = cms.double( 100. ), - PTMINTRA = cms.double( 2.), # PTMIN of L1Tracks, in GeV - nVtx = cms.int32( 1 ), # number of vertices to return - nStubsmin = cms.int32( 4 ) , # minimum number of stubs - nStubsPSmin = cms.int32( 3 ), # minimum number of stubs in PS modules - nBinning = cms.int32( 601 ), # number of bins for the temp histo (from -30 cm to + 30 cm) - PTMAX = cms.double( 50. ), # in GeV. When PTMAX > 0, tracks with PT above PTMAX are considered as - # mismeasured and are treated according to HighPtTracks below. - # When PTMAX < 0, no special treatment is done for high PT tracks. - # If PTMAX < 0, no saturation or truncation is done. - HighPtTracks = cms.int32( 0 ), # when = 0 : truncation. Tracks with PT above PTMAX are ignored - # when = 1 : saturation. Tracks with PT above PTMAX are set to PT=PTMAX. - MonteCarloVertex = cms.bool( False ), # when True: dont run the vxt finding algo but pick up the MC generated vtx - doPtComp = cms.bool( True ), # track-stubs PT compatibility cut - doTightChi2 = cms.bool( False ), # chi2dof < 5 for tracks with PT > 10 - trk_ptTightChi2 = cms.double(10.0), - trk_chi2dofTightChi2 = cms.double(5.0), - WEIGHT = cms.int32(1) # WEIGHT can be set to 0, 1 or 2 for unweighted, pT weighted - # or pT2 weighted tracks respectively. - -# -# Other working point which works better for H -> TauTau, -# cf talk by Moshan Ather, Dec 12, 2014: - -# WEIGHT = cms.int32(2), -# PTMAX = cms.double( 25. ), -# nStubsmin = cms.int32( 5 ), -# HighPtTracks = cms.int32( 1), -# doPtComp = cms.bool( False ), -# CHI2MAX = cms.double( 20 ) -# - -) diff --git a/L1Trigger/L1TTrackMatch/python/L1TrackFastJetProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TrackFastJetProducer_cfi.py index 62d8d9f3a563e..4eaaf1c5bfe86 100644 --- a/L1Trigger/L1TTrackMatch/python/L1TrackFastJetProducer_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/L1TrackFastJetProducer_cfi.py @@ -1,8 +1,9 @@ import FWCore.ParameterSet.Config as cms +from L1Trigger.VertexFinder.VertexProducer_cff import VertexProducer L1TrackFastJets = cms.EDProducer("L1TrackFastJetProducer", L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), - L1PrimaryVertexTag=cms.InputTag("L1TkPrimaryVertex"), + L1PrimaryVertexTag=cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()), trk_zMax = cms.double(15.), # max track z0 [cm] trk_chi2dofMax = cms.double(10.), # max track chi2/dof trk_bendChi2Max = cms.double(2.2),# max bendChi2 cut @@ -20,7 +21,7 @@ L1TrackFastJetsExtended = cms.EDProducer("L1TrackFastJetProducer", L1TrackInputTag = cms.InputTag("TTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), - L1PrimaryVertexTag=cms.InputTag("L1TkPrimaryVertex"), + L1PrimaryVertexTag=cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()), trk_zMax = cms.double(15.), # max track z0 [cm] trk_chi2dofMax = cms.double(40.), # max track chi2 for extended tracks trk_bendChi2Max = cms.double(2.4),#Bendchi2 cut for extended tracks diff --git a/L1Trigger/L1TTrackMatch/python/L1TrackJetEmulationProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TrackJetEmulationProducer_cfi.py new file mode 100644 index 0000000000000..b7be59d0cae1b --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TrackJetEmulationProducer_cfi.py @@ -0,0 +1,60 @@ +import FWCore.ParameterSet.Config as cms +from L1Trigger.VertexFinder.VertexProducer_cff import VertexProducer + +L1TrackJetsEmulation = cms.EDProducer('L1TrackJetEmulationProducer', + L1TrackInputTag= cms.InputTag("L1GTTInputProducer", "Level1TTTracksConverted"), + VertexInputTag=cms.InputTag("L1VertexFinderEmulator", "l1verticesEmulation"), + MaxDzTrackPV = cms.double(0.5), + trk_zMax = cms.double (15.) , # maximum track z + trk_ptMax = cms.double(200.), # maximumum track pT before saturation [GeV] + trk_ptMin = cms.double(2.0), # minimum track pt [GeV] + trk_etaMax = cms.double(2.4), # maximum track eta + trk_chi2dofMax=cms.double(10.), # maximum track chi2/dof + trk_bendChi2Max=cms.double(2.2), # maximum track bendchi2 + trk_nPSStubMin=cms.int32(-1), # minimum PS stubs, -1 means no cut + minTrkJetpT=cms.double(5.), # minimum track pt to be considered for track jet + etaBins=cms.int32(24), + phiBins=cms.int32(27), + zBins=cms.int32(1), + d0_cutNStubs4=cms.double(0.15), + d0_cutNStubs5=cms.double(0.5), + lowpTJetMinTrackMultiplicity=cms.int32(2), + lowpTJetMinpT=cms.double(50.), + highpTJetMinTrackMultiplicity=cms.int32(3), + highpTJetMinpT=cms.double(100.), + displaced=cms.bool(False), #Flag for displaced tracks + nStubs4DisplacedChi2=cms.double(5.0), #Displaced track quality flags for loose/tight + nStubs4Displacedbend=cms.double(1.7), + nStubs5DisplacedChi2=cms.double(2.75), + nStubs5Displacedbend=cms.double(3.5), + nDisplacedTracks=cms.int32(2) #Number of displaced tracks required per jet +) + +L1TrackJetsExtendedEmulation = cms.EDProducer('L1TrackJetEmulationProducer', + L1TrackInputTag= cms.InputTag("L1GTTInputProducerExtended", "Level1TTTracksExtendedConverted"), + VertexInputTag=cms.InputTag("L1VertexFinderEmulator", "l1verticesEmulation"), + MaxDzTrackPV = cms.double(4.0), + trk_zMax = cms.double (15.) , # maximum track z + trk_ptMax = cms.double(200.), # maximumum track pT before saturation [GeV] + trk_ptMin = cms.double(3.0), # minimum track pt [GeV] + trk_etaMax = cms.double(2.4), # maximum track eta + trk_chi2dofMax=cms.double(40.), # maximum track chi2/dof + trk_bendChi2Max=cms.double(40.), # maximum track bendchi2 + trk_nPSStubMin=cms.int32(-1), # minimum # PS stubs, -1 means no cut + minTrkJetpT=cms.double(5.), # minimum track pt to be considered for track jet + etaBins=cms.int32(24), + phiBins=cms.int32(27), + zBins=cms.int32(10), + d0_cutNStubs4=cms.double(-1), # -1 excludes nstub=4 from disp tag + d0_cutNStubs5=cms.double(0.22), + lowpTJetMinTrackMultiplicity=cms.int32(2), + lowpTJetMinpT=cms.double(50.), + highpTJetMinTrackMultiplicity=cms.int32(3), + highpTJetMinpT=cms.double(100.), + displaced=cms.bool(True), #Flag for displaced tracks + nStubs4DisplacedChi2=cms.double(3.3), #Disp tracks selection [trk4 from disp tag process + lowpTJetMinTrackMultiplicity=cms.int32(2), #relevant only when N of z-bins >1; excludes from the HT calculation jets with low number of very energetic tracks; this cut selects the threshold on number of tracks + lowpTJetThreshold=cms.double(50.), # this threshold controls the pT of the jet + highpTJetMinTrackMultiplicity=cms.int32(3), #same as above for a different WP of tracks / pT + highpTJetThreshold=cms.double(100.), + displaced=cms.bool(True), #Flag for displaced tracks + nStubs4DisplacedChi2=cms.double(3.3), #Disp tracks selection [trk4 from disp tag +# lowpTJetMinTrackMultiplicity=cms.int32(2), #used only on zbin finding +# highpTJetMinTrackMultiplicity=cms.int32(3), #used only on zbin finding +# displaced=cms.bool(True), #Flag for displaced tracks +# nStubs4DisplacedChi2=cms.double(3.3), #Disp tracks selection [trk= 4 stubs - TP_minNStub = cms.int32(4), # require TP to have >= X number of stubs associated with it - TP_minNStubLayer = cms.int32(4), # require TP to have stubs in >= X layers/disks - TP_minPt = cms.double(2.0), # only save TPs with pt > X GeV - TP_maxEta = cms.double(2.5), # only save TPs with |eta| < X - TP_maxZ0 = cms.double(30.0), # only save TPs with |z0| < X cm - L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), # TTTracks, prompt - L1TrackExtendedInputTag = cms.InputTag("TTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), # TTTracks, extended - MCTruthTrackInputTag = cms.InputTag("TTTrackAssociatorFromPixelDigis", "Level1TTTracks"), # MCTruth track, prompt - MCTruthTrackExtendedInputTag = cms.InputTag("TTTrackAssociatorFromPixelDigisExtended", "Level1TTTracks"), # MCTruth track, extended - L1StubInputTag = cms.InputTag("TTStubsFromPhase2TrackerDigis","StubAccepted"), - MCTruthClusterInputTag = cms.InputTag("TTClusterAssociatorFromPixelDigis", "ClusterAccepted"), - MCTruthStubInputTag = cms.InputTag("TTStubAssociatorFromPixelDigis", "StubAccepted"), - TrackingParticleInputTag = cms.InputTag("mix", "MergedTrackTruth"), - TrackingVertexInputTag = cms.InputTag("mix", "MergedTrackTruth"), - ## tracking in jets stuff (--> requires AK4 genjet collection present!) - TrackingInJets = cms.bool(False), - GenJetInputTag = cms.InputTag("ak4GenJets", ""), - ##track jets and track MET - SaveTrackJets = cms.bool(True), - SaveTrackMET = cms.bool(True), - TrackFastJetsInputTag = cms.InputTag("L1TrackFastJets","L1TrackFastJets"), - TrackFastJetsExtendedInputTag = cms.InputTag("L1TrackFastJetsExtended","L1TrackFastJetsExtended"), - TrackJetsInputTag=cms.InputTag("L1TrackJets", "L1TrackJets"), - TrackJetsExtendedInputTag=cms.InputTag("L1TrackJetsExtended", "L1TrackJetsExtended"), - TrackMETInputTag = cms.InputTag("L1TrackerEtMiss","L1TrackerEtMiss","L1TrackJets"), - TrackMETExtendedInputTag = cms.InputTag("L1TrackerEtMissExtended","L1TrackerEtMissExtended"), - TrackMHTInputTag = cms.InputTag("L1TrackerHTMiss","L1TrackerHTMiss","L1TrackJets"), - TrackMHTExtendedInputTag = cms.InputTag("L1TrackerHTMissExtended","L1TrackerHTMiss"), - GenParticleInputTag = cms.InputTag("genParticles",""), - RecoVertexInputTag=cms.InputTag("L1TkPrimaryVertex"), -) - -process.ntuple = cms.Path(process.L1TrackNtuple) - -process.out = cms.OutputModule( "PoolOutputModule", - fastCloning = cms.untracked.bool( False ), - fileName = cms.untracked.string("test.root" ) - ) -process.pOut = cms.EndPath(process.out) - - - -# use this if you want to re-run the stub making -# process.schedule = cms.Schedule(process.TTClusterStub,process.TTClusterStubTruth,process.TTTracksEmulationWithTruth,process.ntuple) - -# use this if cluster/stub associators not available -# process.schedule = cms.Schedule(process.TTClusterStubTruth,process.TTTracksEmulationWithTruth,process.ntuple) - -#process.schedule = cms.Schedule(process.pPV, process.pL1TrackJets, process.pL1TrackFastJets, process.pTkMET, process.pTkMHT,process.pOut) -#process.schedule = cms.Schedule(process.pPV, process.pL1TrackJets, process.pL1TrackFastJets, process.pTkMET, process.pTkMHT, process.ntuple) -#process.schedule = cms.Schedule(process.ntuple) -process.schedule = cms.Schedule(process.TTTracksEmulationWithTruth, process.pPV, process.pL1TrackJets, process.pL1TrackFastJets, process.pTkMET, process.pTkMHT, process.ntuple) diff --git a/L1Trigger/L1TTrackMatch/python/L1TrackSelectionProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TrackSelectionProducer_cfi.py new file mode 100644 index 0000000000000..9be5ca92b8e42 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TrackSelectionProducer_cfi.py @@ -0,0 +1,53 @@ +import FWCore.ParameterSet.Config as cms + +L1TrackSelectionProducer = cms.EDProducer('L1TrackSelectionProducer', + l1TracksInputTag = cms.InputTag("L1GTTInputProducer","Level1TTTracksConverted"), + # If no vertex collection is provided, then the DeltaZ cuts will not be run + l1VerticesInputTag = cms.InputTag("L1VertexFinder", "l1vertices"), + l1VerticesEmulationInputTag = cms.InputTag("L1VertexFinderEmulator", "l1verticesEmulation"), + outputCollectionName = cms.string("Level1TTTracksSelected"), + cutSet = cms.PSet( + ptMin = cms.double(2.0), # pt must be greater than this value, [GeV] + absEtaMax = cms.double(2.4), # absolute value of eta must be less than this value + absZ0Max = cms.double(15.0), # z0 must be less than this value, [cm] + nStubsMin = cms.int32(4), # number of stubs must be greater than or equal to this value + nPSStubsMin = cms.int32(0), # the number of stubs in the PS Modules must be greater than or equal to this value + + reducedBendChi2Max = cms.double(2.25), # bend chi2 must be less than this value + reducedChi2RZMax = cms.double(5.0), # chi2rz/dof must be less than this value + reducedChi2RPhiMax = cms.double(20.0), # chi2rphi/dof must be less than this value + + #deltaZMaxEtaBounds = cms.vdouble(0.0, absEtaMax.value), # these values define the bin boundaries in |eta| + #deltaZMax = cms.vdouble(0.5), # delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, [cm] + deltaZMaxEtaBounds = cms.vdouble(0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4), # these values define the bin boundaries in |eta| + deltaZMax = cms.vdouble(0.37, 0.50, 0.60, 0.75, 1.00, 1.60), # delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, [cm] + ), + useDisplacedTracksDeltaZOverride = cms.double(-1.0), # override the deltaZ cut value for displaced tracks + processSimulatedTracks = cms.bool(True), # return selected tracks after cutting on the floating point values + processEmulatedTracks = cms.bool(True), # return selected tracks after cutting on the bitwise emulated values + debug = cms.int32(0) # Verbosity levels: 0, 1, 2, 3, 4 +) + +L1TrackSelectionProducerExtended = L1TrackSelectionProducer.clone( + l1TracksInputTag = cms.InputTag("L1GTTInputProducerExtended","Level1TTTracksExtendedConverted"), + outputCollectionName = cms.string("Level1TTTracksExtendedSelected"), + cutSet = cms.PSet( + ptMin = cms.double(3.0), # pt must be greater than this value, [GeV] + absEtaMax = cms.double(2.4), # absolute value of eta must be less than this value + absZ0Max = cms.double(15.0), # z0 must be less than this value, [cm] + nStubsMin = cms.int32(4), # number of stubs must be greater than or equal to this value + nPSStubsMin = cms.int32(0), # the number of stubs in the PS Modules must be greater than or equal to this value + + reducedBendChi2Max = cms.double(2.4), # bend chi2 must be less than this value + reducedChi2RZMax = cms.double(10.0), # chi2rz/dof must be less than this value + reducedChi2RPhiMax = cms.double(40.0), # chi2rphi/dof must be less than this value + + #deltaZMaxEtaBounds = cms.vdouble(0.0, absEtaMax.value), # these values define the bin boundaries in |eta| + #deltaZMax = cms.vdouble(0.5), # delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, [cm] + deltaZMaxEtaBounds = cms.vdouble(0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4), # these values define the bin boundaries in |eta| + deltaZMax = cms.vdouble(3.0, 3.0, 3.0, 3.0, 3.0, 3.0), # delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, [cm] + ), + useDisplacedTracksDeltaZOverride = cms.double(3.0), # Use promt/displaced tracks +) + + diff --git a/L1Trigger/L1TTrackMatch/python/L1TrackerEtMissEmulatorProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TrackerEtMissEmulatorProducer_cfi.py new file mode 100644 index 0000000000000..445f9580d671a --- /dev/null +++ b/L1Trigger/L1TTrackMatch/python/L1TrackerEtMissEmulatorProducer_cfi.py @@ -0,0 +1,20 @@ +import FWCore.ParameterSet.Config as cms +from L1Trigger.VertexFinder.VertexProducer_cff import VertexProducer +from L1Trigger.L1TTrackMatch.L1TrackSelectionProducer_cfi import L1TrackSelectionProducer + +L1TrackerEmuEtMiss = cms.EDProducer('L1TrackerEtMissEmulatorProducer', + L1TrackInputTag = cms.InputTag("L1TrackSelectionProducer", L1TrackSelectionProducer.outputCollectionName.value() + "Emulation"), + L1TrackAssociatedInputTag = cms.InputTag("L1TrackSelectionProducer", L1TrackSelectionProducer.outputCollectionName.value() + "AssociatedEmulation"), + # To bypass GTT input module use cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks") + # and set useGTTinput to false + L1VertexInputTag = cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()), + # This will use the vertex algorithm as specified in VertexProducer_cff, if using emulated vertex + # set useVertexEmulator to true + L1MetCollectionName = cms.string("L1TrackerEmuEtMiss"), + + nCordicSteps = cms.int32( 8 ), #Number of steps for cordic sqrt and phi computation + debug = cms.int32( 0 ), #0 - No Debug, 1 - LUT debug, 2 - Phi Debug, 3 - Z debug, 4 - Et Debug, 5 - Cordic Debug, 6 - Output, 7 - Every Selected Track + useGTTinput = cms.bool( True ), + +) + diff --git a/L1Trigger/L1TTrackMatch/python/L1TrackerEtMissProducer_cfi.py b/L1Trigger/L1TTrackMatch/python/L1TrackerEtMissProducer_cfi.py index 18dbf558c3e68..3501098763fbb 100644 --- a/L1Trigger/L1TTrackMatch/python/L1TrackerEtMissProducer_cfi.py +++ b/L1Trigger/L1TTrackMatch/python/L1TrackerEtMissProducer_cfi.py @@ -1,41 +1,22 @@ import FWCore.ParameterSet.Config as cms +from L1Trigger.VertexFinder.VertexProducer_cff import VertexProducer +from L1Trigger.L1TTrackMatch.L1TrackSelectionProducer_cfi import L1TrackSelectionProducer, L1TrackSelectionProducerExtended L1TrackerEtMiss = cms.EDProducer('L1TrackerEtMissProducer', - L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), - L1VertexInputTag = cms.InputTag("L1TkPrimaryVertex"), - maxZ0 = cms.double ( 15. ) , # in cm - maxEta = cms.double ( 2.4 ) , # max eta allowed for chosen tracks - chi2dofMax = cms.double( 10. ), # max chi2/dof allowed for chosen tracks - bendChi2Max = cms.double( 2.2 ),# max bendchi2 allowed for chosen tracks - minPt = cms.double( 2. ), # in GeV - deltaZ = cms.double( 3. ), # in cm - nStubsmin = cms.int32( 4 ), # min number of stubs for the tracks - nPSStubsMin = cms.int32( -1 ), # min number of stubs in the PS Modules - maxPt = cms.double( 200. ), # in GeV. When maxPt > 0, tracks with PT above maxPt are considered as + L1TrackInputTag = cms.InputTag("L1TrackSelectionProducer", L1TrackSelectionProducer.outputCollectionName.value()), + L1TrackAssociatedInputTag = cms.InputTag("L1TrackSelectionProducer", L1TrackSelectionProducer.outputCollectionName.value() + "Associated"), + L1MetCollectionName = cms.string("L1TrackerEtMiss"), + maxPt = cms.double( -10. ), # in GeV. When maxPt > 0, tracks with PT above maxPt are considered as # mismeasured and are treated according to highPtTracks below. # When maxPt < 0, no special treatment is done for high PT tracks. highPtTracks = cms.int32( 1 ), # when = 0 : truncation. Tracks with PT above maxPt are ignored # when = 1 : saturation. Tracks with PT above maxPt are set to PT=maxPt. # When maxPt < 0, no special treatment is done for high PT tracks. - displaced = cms.bool(False) # Use promt/displaced tracks + debug = cms.bool(False) ) -L1TrackerEtMissExtended = cms.EDProducer('L1TrackerEtMissProducer', - L1TrackInputTag = cms.InputTag("TTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), - L1VertexInputTag = cms.InputTag("L1TkPrimaryVertex"), - maxZ0 = cms.double ( 15. ) , # in cm - maxEta = cms.double ( 2.4 ) , # max eta allowed for chosen tracks - chi2dofMax = cms.double( 40. ), # max chi2/dof allowed for chosen tracks - bendChi2Max = cms.double( 2.4 ),# max bendchi2 allowed for chosen tracks - minPt = cms.double( 3. ), # in GeV - deltaZ = cms.double( 3.0 ), # in cm - nStubsmin = cms.int32( 4 ), # min number of stubs for the tracks - nPSStubsMin = cms.int32( -1 ), # min number of stubs in the PS Modules - maxPt = cms.double( 200. ), # in GeV. When maxPt > 0, tracks with PT above maxPt are considered as - # mismeasured and are treated according to highPtTracks below. - # When maxPt < 0, no special treatment is done for high PT tracks. - highPtTracks = cms.int32( 1 ), # when = 0 : truncation. Tracks with PT above maxPt are ignored - # when = 1 : saturation. Tracks with PT above maxPt are set to PT=maxPt. - # When maxPt < 0, no special treatment is done for high PT tracks. - displaced = cms.bool(True) # Use promt/displaced tracks +L1TrackerEtMissExtended = L1TrackerEtMiss.clone( #NOT OPTIMIZED, STUDIED, OR USED + L1TrackInputTag = cms.InputTag("L1TrackSelectionProducerExtended", L1TrackSelectionProducerExtended.outputCollectionName.value()), + L1TrackAssociatedInputTag = cms.InputTag("L1TrackSelectionProducerExtended", L1TrackSelectionProducerExtended.outputCollectionName.value() + "Associated"), + L1MetCollectionName = cms.string("L1TrackerExtendedEtMiss"), ) diff --git a/L1Trigger/L1TTrackMatch/src/Cordic.cc b/L1Trigger/L1TTrackMatch/src/Cordic.cc new file mode 100644 index 0000000000000..0ec5aca5fce1e --- /dev/null +++ b/L1Trigger/L1TTrackMatch/src/Cordic.cc @@ -0,0 +1,110 @@ +#include "L1Trigger/L1TTrackMatch/interface/Cordic.h" + +#include +#include + +using namespace l1tmetemu; + +Cordic::Cordic(int aPhiScale, int aMagnitudeBits, const int aSteps, bool debug) + : mPhiScale(aPhiScale), + mMagnitudeScale(1 << aMagnitudeBits), + mMagnitudeBits(aMagnitudeBits), + cordicSteps(aSteps), + debug(debug) { + atanLUT.reserve(aSteps); + magNormalisationLUT.reserve(aSteps); + + if (debug) { + edm::LogVerbatim("L1TkEtMissEmulator") << "=====atan LUT====="; + } + + for (int i = 0; i < aSteps; i++) { + atanLUT.push_back(METphi_t(round(mPhiScale * atan(pow(2, -i)) / (2 * M_PI)))); + if (debug) { + edm::LogVerbatim("L1TkEtMissEmulator") << atanLUT[i] << " | "; + } + } + if (debug) { + edm::LogVerbatim("L1TkEtMissEmulator") << "\n=====Normalisation LUT====="; + } + + float val = 1.0; + for (int j = 0; j < aSteps; j++) { + val = val / (pow(1 + pow(4, -j), 0.5)); + magNormalisationLUT.push_back(Et_t(round(mMagnitudeScale * val))); + if (debug) { + edm::LogVerbatim("L1TkEtMissEmulator") << magNormalisationLUT[j] << " | "; + } + } +} + +EtMiss Cordic::toPolar(Et_t x, Et_t y) const { + Et_t new_x = 0; + Et_t new_y = 0; + + METphi_t phi = 0; + METphi_t new_phi = 0; + bool sign = false; + + EtMiss ret_etmiss; + + if (debug) { + edm::LogVerbatim("L1TkEtMissEmulator") << "\n=====Cordic Steps====="; + } + + if (x >= 0 && y >= 0) { + phi = 0; + sign = true; + //x = x; + //y = y; + } else if (x < 0 && y >= 0) { + phi = mPhiScale >> 1; + sign = false; + x = -x; + //y = y; + } else if (x < 0 && y < 0) { + phi = mPhiScale >> 1; + sign = true; + x = -x; + y = -y; + } else { + phi = mPhiScale; + sign = false; + //x = x; + y = -y; + } + + for (int step = 0; step < cordicSteps; step++) { + if (y < 0) { + new_x = x - (y >> step); + new_y = y + (x >> step); + } else { + new_x = x + (y >> step); + new_y = y - (x >> step); + } + + if ((y < 0) == sign) { + new_phi = phi - atanLUT[step]; + } else { + new_phi = phi + atanLUT[step]; + } + + x = new_x; + y = new_y; + phi = new_phi; + + if (debug) { + edm::LogVerbatim("L1TkEtMissEmulator") + << " Cordic x: " << x << " Cordic y: " << y << " Cordic phi: " << phi << "\n"; + } + } + + // Cordic performs calculation in internal Et granularity, convert to final + // granularity for Et word + + // emulate fw rounding with float division then floor + float tempMET = (float)(x * magNormalisationLUT[cordicSteps - 1] * kMaxTrackPt) / ((float)kMaxMET); + ret_etmiss.Et = (int)floor(tempMET) >> (mMagnitudeBits + TTTrack_TrackWord::TrackBitWidths::kRinvSize - kMETSize); + ret_etmiss.Phi = phi; + return ret_etmiss; +} diff --git a/L1Trigger/L1TTrackMatch/src/L1TkElectronTrackMatchAlgo.cc b/L1Trigger/L1TTrackMatch/src/L1TkElectronTrackMatchAlgo.cc deleted file mode 100644 index ea300f226af49..0000000000000 --- a/L1Trigger/L1TTrackMatch/src/L1TkElectronTrackMatchAlgo.cc +++ /dev/null @@ -1,124 +0,0 @@ -// -*- C++ -*- -// -// -/**\class L1TkElectronTrackMatchAlgo - - Description: Algorithm to match L1EGamma oject with L1Track candidates - - Implementation: - [Notes on implementation] -*/ - -// system include files -#include -#include - -#include "DataFormats/Math/interface/deltaPhi.h" -#include "L1Trigger/L1TTrackMatch/interface/L1TkElectronTrackMatchAlgo.h" -namespace L1TkElectronTrackMatchAlgo { - - float constexpr max_eb_eta = 1.479; - float constexpr max_eb_z = 315.4; - float constexpr eb_rperp = 129.0; - // ------------ match EGamma and Track - void doMatch(l1t::EGammaBxCollection::const_iterator egIter, - const edm::Ptr& pTrk, - double& dph, - double& dr, - double& deta) { - GlobalPoint egPos = L1TkElectronTrackMatchAlgo::calorimeterPosition(egIter->phi(), egIter->eta(), egIter->energy()); - dph = L1TkElectronTrackMatchAlgo::deltaPhi(egPos, pTrk); - dr = L1TkElectronTrackMatchAlgo::deltaR(egPos, pTrk); - deta = L1TkElectronTrackMatchAlgo::deltaEta(egPos, pTrk); - } - // ------------ match EGamma and Track - void doMatchClusterET(l1t::EGammaBxCollection::const_iterator egIter, - const edm::Ptr& pTrk, - double& dph, - double& dr, - double& deta) { - GlobalPoint egPos = L1TkElectronTrackMatchAlgo::calorimeterPosition(egIter->phi(), egIter->eta(), egIter->energy()); - dph = L1TkElectronTrackMatchAlgo::deltaPhiClusterET(egIter, pTrk); - dr = L1TkElectronTrackMatchAlgo::deltaR(egPos, pTrk); - deta = L1TkElectronTrackMatchAlgo::deltaEta(egPos, pTrk); - } - // ------------ match EGamma and Track - void doMatch(const GlobalPoint& epos, const edm::Ptr& pTrk, double& dph, double& dr, double& deta) { - dph = L1TkElectronTrackMatchAlgo::deltaPhi(epos, pTrk); - dr = L1TkElectronTrackMatchAlgo::deltaR(epos, pTrk); - deta = L1TkElectronTrackMatchAlgo::deltaEta(epos, pTrk); - } - // --------------- calculate deltaR between Track and EGamma object - double deltaPhi(const GlobalPoint& epos, const edm::Ptr& pTrk) { - double er = epos.perp(); - double curv = pTrk->rInv(); - - double dphi_curv = (asin(er * curv / (2.0))); - double trk_phi_ecal = reco::deltaPhi(pTrk->momentum().phi(), dphi_curv); - - double dphi = reco::deltaPhi(trk_phi_ecal, epos.phi()); - return dphi; - } - // --------------- use cluster et to extrapolate tracks - double deltaPhiClusterET(l1t::EGammaBxCollection::const_iterator egIter, const edm::Ptr& pTrk) { - GlobalPoint epos = L1TkElectronTrackMatchAlgo::calorimeterPosition(egIter->phi(), egIter->eta(), egIter->energy()); - double er = epos.perp(); - double et = egIter->et(); - double pt = pTrk->momentum().perp(); - double curv = pTrk->rInv(); - - double dphi_curv = (asin(er * curv * pt / (2.0 * et))); - double trk_phi_ecal = reco::deltaPhi(pTrk->momentum().phi(), dphi_curv); - - double dphi = reco::deltaPhi(trk_phi_ecal, epos.phi()); - return dphi; - } - // --------------- calculate deltaPhi between Track and EGamma object - double deltaR(const GlobalPoint& epos, const edm::Ptr& pTrk) { - //double dPhi = fabs(reco::deltaPhi(epos.phi(), pTrk->momentum().phi())); - double dPhi = L1TkElectronTrackMatchAlgo::deltaPhi(epos, pTrk); - double dEta = deltaEta(epos, pTrk); - return sqrt(dPhi * dPhi + dEta * dEta); - } - // --------------- calculate deltaEta between Track and EGamma object - double deltaEta(const GlobalPoint& epos, const edm::Ptr& pTrk) { - double corr_eta = 999.0; - double er = epos.perp(); - double ez = epos.z(); - double z0 = pTrk->POCA().z(); - double theta = 0.0; - if (ez - z0 >= 0) - theta = atan(er / fabs(ez - z0)); - else - theta = M_PI - atan(er / fabs(ez - z0)); - corr_eta = -1.0 * log(tan(theta / 2.0)); - double deleta = (corr_eta - pTrk->momentum().eta()); - return deleta; - } - // -------------- get Calorimeter position - GlobalPoint calorimeterPosition(double phi, double eta, double e) { - double x = 0.; - double y = 0.; - double z = 0.; - double depth = 0.89 * (7.7 + log(e)); - double theta = 2 * atan(exp(-1 * eta)); - double r = 0; - if (fabs(eta) > max_eb_eta) { - double ecalZ = max_eb_z * fabs(eta) / eta; - - r = ecalZ / cos(2 * atan(exp(-1 * eta))) + depth; - x = r * cos(phi) * sin(theta); - y = r * sin(phi) * sin(theta); - z = r * cos(theta); - } else { - double zface = sqrt(cos(theta) * cos(theta) / (1 - cos(theta) * cos(theta)) * eb_rperp * eb_rperp); - r = sqrt(eb_rperp * eb_rperp + zface * zface) + depth; - x = r * cos(phi) * sin(theta); - y = r * sin(phi) * sin(theta); - z = r * cos(theta); - } - GlobalPoint pos(x, y, z); - return pos; - } - -} // namespace L1TkElectronTrackMatchAlgo diff --git a/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuAlgo.cc b/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuAlgo.cc new file mode 100644 index 0000000000000..43fdba9102032 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuAlgo.cc @@ -0,0 +1,66 @@ +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h" + +using namespace std; + +namespace l1tmetemu { + std::vector generateCosLUT(unsigned int size) { // Fill cosine LUT with integer values + float phi = 0; + std::vector cosLUT; + for (unsigned int LUT_idx = 0; LUT_idx < size; LUT_idx++) { + cosLUT.push_back((global_phi_t)(floor(cos(phi) * (kGlobalPhiBins - 1)))); + phi += l1tmetemu::kStepPhi; + } + cosLUT.push_back((global_phi_t)(0)); //Prevent overflow in last bin + return cosLUT; + } + + // Generate Eta LUT for track to vertex association + std::vector generateEtaRegionLUT(vector EtaRegions) { + std::vector LUT; + for (unsigned int q = 0; q < EtaRegions.size(); q++) { + LUT.push_back(digitizeSignedValue(EtaRegions[q], l1tmetemu::kInternalEtaWidth, l1tmetemu::kStepEta)); + //std::cout << LUT[q] << "|" << EtaRegions[q] << std::endl; + } + return LUT; + } + + std::vector generateDeltaZLUT(vector DeltaZBins) { + std::vector LUT; + for (unsigned int q = 0; q < DeltaZBins.size(); q++) { + LUT.push_back(digitizeSignedValue(DeltaZBins[q], l1tmetemu::kInternalVTXWidth, l1tmetemu::kStepZ0)); + //std::cout << LUT[q] << "|" << DeltaZBins[q] << std::endl; + } + return LUT; + } + + int unpackSignedValue(unsigned int bits, unsigned int nBits) { + int isign = 1; + unsigned int digitized_maximum = (1 << nBits) - 1; + if (bits & (1 << (nBits - 1))) { // check the sign + isign = -1; + bits = (1 << (nBits + 1)) - bits; // if negative, flip everything for two's complement encoding + } + return (int(bits & digitized_maximum)) * isign; + } + + unsigned int transformSignedValue(unsigned int bits, unsigned int oldnBits, unsigned int newnBits) { + int isign = 1; + unsigned int olddigitized_maximum = (1 << oldnBits) - 1; + unsigned int newdigitized_maximum = (1 << newnBits) - 1; + if (bits & (1 << (oldnBits - 1))) { // check the sign + isign = -1; + bits = (1 << (oldnBits + 1)) - bits; // if negative, flip everything for two's complement encoding + } + unsigned int temp = (int(bits & olddigitized_maximum)); + + temp = round(temp / (1 << (oldnBits - newnBits))); + + if (temp > newdigitized_maximum) + temp = newdigitized_maximum; + if (isign < 0) + temp = (1 << newnBits) - 1 - temp; // two's complement encoding + + return temp; + } + +} // namespace l1tmetemu diff --git a/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuTrackTransform.cc b/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuTrackTransform.cc new file mode 100644 index 0000000000000..97a880960382c --- /dev/null +++ b/L1Trigger/L1TTrackMatch/src/L1TkEtMissEmuTrackTransform.cc @@ -0,0 +1,52 @@ +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuTrackTransform.h" + +#include + +using namespace l1tmetemu; + +void L1TkEtMissEmuTrackTransform::generateLUTs() { + phiQuadrants = generatePhiSliceLUT(l1tmetemu::kNQuadrants); + phiShift = generatePhiSliceLUT(l1tmetemu::kNSector); +} + +global_phi_t L1TkEtMissEmuTrackTransform::localToGlobalPhi(TTTrack_TrackWord::phi_t local_phi, + global_phi_t sector_shift) { + int PhiMin = 0; + int PhiMax = phiQuadrants.back(); + int phiMultiplier = TTTrack_TrackWord::TrackBitWidths::kPhiSize - l1tmetemu::kInternalPhiWidth; + + int tempPhi = + floor(unpackSignedValue(local_phi, TTTrack_TrackWord::TrackBitWidths::kPhiSize) / pow(2, phiMultiplier)) + + sector_shift; + + if (tempPhi < PhiMin) { + tempPhi = tempPhi + PhiMax; + } else if (tempPhi > PhiMax) { + tempPhi = tempPhi - PhiMax; + } // else + // tempPhi = tempPhi; + + global_phi_t globalPhi = global_phi_t(tempPhi); + + return globalPhi; +} + +nstub_t L1TkEtMissEmuTrackTransform::countNStub(TTTrack_TrackWord::hit_t Hitpattern) { + nstub_t Nstub = 0; + for (int i = (TTTrack_TrackWord::kHitPatternSize - 1); i >= 0; i--) { + int k = Hitpattern >> i; + if (k & 1) + Nstub++; + } + return Nstub; +} + +std::vector L1TkEtMissEmuTrackTransform::generatePhiSliceLUT(unsigned int N) { + float sliceCentre = 0.0; + std::vector phiLUT; + for (unsigned int q = 0; q <= N; q++) { + phiLUT.push_back((global_phi_t)(sliceCentre / l1tmetemu::kStepPhi)); + sliceCentre += 2 * M_PI / N; + } + return phiLUT; +} diff --git a/L1Trigger/L1TTrackMatch/src/L1TkMuCorrDynamicWindows.cc b/L1Trigger/L1TTrackMatch/src/L1TkMuCorrDynamicWindows.cc deleted file mode 100644 index 082174f341a3e..0000000000000 --- a/L1Trigger/L1TTrackMatch/src/L1TkMuCorrDynamicWindows.cc +++ /dev/null @@ -1,408 +0,0 @@ -#include "L1Trigger/L1TTrackMatch/interface/L1TkMuCorrDynamicWindows.h" -#include "DataFormats/Math/interface/deltaPhi.h" -#include "DataFormats/Math/interface/angle_units.h" - -// ROOT includes -#include "TH1.h" -#include "TH2.h" - -L1TkMuCorrDynamicWindows::L1TkMuCorrDynamicWindows(const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi) - : wdws_theta_(bounds.size() - 1, MuMatchWindow()), - wdws_phi_(bounds.size() - 1, MuMatchWindow()), - wdws_theta_S1_(bounds.size() - 1, MuMatchWindow()), - wdws_phi_S1_(bounds.size() - 1, MuMatchWindow()) { - set_safety_factor(0.5); - set_sf_initialrelax(0.0); - set_relaxation_pattern(2.0, 6.0); - set_do_relax_factor(true); - - track_qual_presel_ = true; - - nbins_ = bounds.size() - 1; - bounds_ = bounds; - - // now load in memory the TF1 fits - - for (int ib = 0; ib < nbins_; ++ib) { - std::string wdn; - std::string nml; - std::string nmh; - TF1* fl; - TF1* fh; - - // Station 2 - wdn = std::string("wdw_theta_") + std::to_string(ib + 1); - nml = std::string("fit_low_") + std::to_string(ib + 1); - nmh = std::string("fit_high_") + std::to_string(ib + 1); - fl = (TF1*)fIn_theta->Get(nml.c_str()); - fh = (TF1*)fIn_theta->Get(nmh.c_str()); - if (fl == nullptr || fh == nullptr) - throw cms::Exception("L1TkMuCorrDynamicWindows") - << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; - wdws_theta_.at(ib).SetName(wdn); - wdws_theta_.at(ib).SetLower(fl); - wdws_theta_.at(ib).SetUpper(fh); - - wdn = std::string("wdw_phi_") + std::to_string(ib + 1); - nml = std::string("fit_low_") + std::to_string(ib + 1); - nmh = std::string("fit_high_") + std::to_string(ib + 1); - fl = (TF1*)fIn_phi->Get(nml.c_str()); - fh = (TF1*)fIn_phi->Get(nmh.c_str()); - if (fl == nullptr || fh == nullptr) - throw cms::Exception("L1TkMuCorrDynamicWindows") - << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; - wdws_phi_.at(ib).SetName(wdn); - wdws_phi_.at(ib).SetLower(fl); - wdws_phi_.at(ib).SetUpper(fh); - } -} - -L1TkMuCorrDynamicWindows::L1TkMuCorrDynamicWindows( - const std::vector& bounds, TFile* fIn_theta, TFile* fIn_phi, TFile* fIn_theta_S1, TFile* fIn_phi_S1) - : wdws_theta_(bounds.size() - 1, MuMatchWindow()), - wdws_phi_(bounds.size() - 1, MuMatchWindow()), - wdws_theta_S1_(bounds.size() - 1, MuMatchWindow()), - wdws_phi_S1_(bounds.size() - 1, MuMatchWindow()) { - set_safety_factor(0.0); - set_sf_initialrelax(0.0); - set_relaxation_pattern(2.0, 6.0); - set_do_relax_factor(true); - - track_qual_presel_ = true; - - nbins_ = bounds.size() - 1; - bounds_ = bounds; - - // now load in memory the TF1 fits - - for (int ib = 0; ib < nbins_; ++ib) { - std::string wdn; - std::string nml; - std::string nmh; - TF1* fl; - TF1* fh; - - // Station 2 - wdn = std::string("wdw_theta_") + std::to_string(ib + 1); - nml = std::string("fit_low_") + std::to_string(ib + 1); - nmh = std::string("fit_high_") + std::to_string(ib + 1); - fl = (TF1*)fIn_theta->Get(nml.c_str()); - fh = (TF1*)fIn_theta->Get(nmh.c_str()); - if (fl == nullptr || fh == nullptr) - throw cms::Exception("L1TkMuCorrDynamicWindows") - << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; - wdws_theta_.at(ib).SetName(wdn); - wdws_theta_.at(ib).SetLower(fl); - wdws_theta_.at(ib).SetUpper(fh); - - wdn = std::string("wdw_phi_") + std::to_string(ib + 1); - nml = std::string("fit_low_") + std::to_string(ib + 1); - nmh = std::string("fit_high_") + std::to_string(ib + 1); - fl = (TF1*)fIn_phi->Get(nml.c_str()); - fh = (TF1*)fIn_phi->Get(nmh.c_str()); - if (fl == nullptr || fh == nullptr) - throw cms::Exception("L1TkMuCorrDynamicWindows") - << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; - wdws_phi_.at(ib).SetName(wdn); - wdws_phi_.at(ib).SetLower(fl); - wdws_phi_.at(ib).SetUpper(fh); - - // Station 1 - MW's don't have to exist for TkMuon correlator - // It is only needed for TkMuStub - wdn = std::string("wdw_theta_") + std::to_string(ib + 1); - nml = std::string("fit_low_") + std::to_string(ib + 1); - nmh = std::string("fit_high_") + std::to_string(ib + 1); - fl = (TF1*)fIn_theta_S1->Get(nml.c_str()); - fh = (TF1*)fIn_theta_S1->Get(nmh.c_str()); - if (fl == nullptr || fh == nullptr) - throw cms::Exception("L1TkMuCorrDynamicWindows") - << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; - wdws_theta_S1_.at(ib).SetName(wdn); - wdws_theta_S1_.at(ib).SetLower(fl); - wdws_theta_S1_.at(ib).SetUpper(fh); - - wdn = std::string("wdw_phi_") + std::to_string(ib + 1); - nml = std::string("fit_low_") + std::to_string(ib + 1); - nmh = std::string("fit_high_") + std::to_string(ib + 1); - fl = (TF1*)fIn_phi_S1->Get(nml.c_str()); - fh = (TF1*)fIn_phi_S1->Get(nmh.c_str()); - if (fl == nullptr || fh == nullptr) - throw cms::Exception("L1TkMuCorrDynamicWindows") - << "TF1 named " << nml << " or " << nmh << " not found in file " << fIn_theta->GetName() << ".\n"; - wdws_phi_S1_.at(ib).SetName(wdn); - wdws_phi_S1_.at(ib).SetLower(fl); - wdws_phi_S1_.at(ib).SetUpper(fh); - } -} - -int L1TkMuCorrDynamicWindows::findBin(double val) { - // not the most efficient, nor the most elegant implementation for now - if (val < bounds_.at(0)) - return 0; - if (val >= bounds_.back()) - return (nbins_ - 1); // i.e. bounds_size() -2 - - for (uint ib = 0; ib < bounds_.size() - 1; ++ib) { - if (val >= bounds_.at(ib) && val < bounds_.at(ib + 1)) - return ib; - } - - //"Something strange happened at val. - throw cms::Exception("L1TkMuCorrDynamicWindows") << "Can't find bin.\n"; - return 0; -} - -std::vector L1TkMuCorrDynamicWindows::find_match(const EMTFTrackCollection& l1mus, - const L1TTTrackCollectionType& l1trks) { - std::vector out(l1trks.size()); - for (auto l1trkit = l1trks.begin(); l1trkit != l1trks.end(); ++l1trkit) { - float trk_pt = l1trkit->momentum().perp(); - float trk_p = l1trkit->momentum().mag(); - float trk_aeta = std::abs(l1trkit->momentum().eta()); - float trk_theta = to_mpio2_pio2(eta_to_theta(l1trkit->momentum().eta())); - float trk_phi = l1trkit->momentum().phi(); - int trk_charge = (l1trkit->rInv() > 0 ? 1 : -1); - - // porting some selections from the MuonTrackCorr finder - // https://github.com/cms-l1t-offline/cmssw/blob/l1t-phase2-932-v1.6/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc#L264 - // in future, make preselections confiuguable - bool reject_trk = false; - if (trk_p < min_trk_p_) - reject_trk = true; - if (trk_aeta > max_trk_aeta_) - reject_trk = true; - if (track_qual_presel_) { - float l1tk_chi2 = l1trkit->chi2(); - int l1tk_nstubs = l1trkit->getStubRefs().size(); - if (l1tk_chi2 >= max_trk_chi2_) - reject_trk = true; - if (l1tk_nstubs < min_trk_nstubs_) - reject_trk = true; - } - - int ibin = findBin(trk_aeta); - - std::vector> matched; // dtheta, dphi, idx - // loop on muons to see which match - for (auto l1muit = l1mus.begin(); l1muit != l1mus.end(); ++l1muit) { - // match only muons in the central bx - as the track collection refers anyway to bx 0 only - if (l1muit->BX() != 0) - continue; - - // putting everything in rad - float emtf_theta = to_mpio2_pio2(eta_to_theta(l1muit->Eta())); - float emtf_phi = angle_units::operators::convertDegToRad(l1muit->Phi_glob()); - - float dtheta = std::abs(emtf_theta - trk_theta); - float dphi = reco::deltaPhi(emtf_phi, trk_phi); - float adphi = std::abs(dphi); - - double sf_l; - double sf_h; - if (do_relax_factor_) { - sf_l = sf_progressive(trk_pt, pt_start_, pt_end_, initial_sf_l_, safety_factor_l_); - sf_h = sf_progressive(trk_pt, pt_start_, pt_end_, initial_sf_h_, safety_factor_h_); - } else { - sf_l = safety_factor_l_; - sf_h = safety_factor_h_; - } - - if ( - // emtf_theta * trk_theta > 0 && - dtheta > (1 - sf_l) * wdws_theta_.at(ibin).bound_low(trk_pt) && - dtheta <= (1 + sf_h) * wdws_theta_.at(ibin).bound_high(trk_pt) && - adphi > (1 - sf_l) * wdws_phi_.at(ibin).bound_low(trk_pt) && - adphi <= (1 + sf_h) * wdws_phi_.at(ibin).bound_high(trk_pt) && dphi * trk_charge < 0 && // sign requirement - // rndm > 0.5 - true) - matched.emplace_back(dtheta, adphi, std::distance(l1mus.begin(), l1muit)); - } - - if (reject_trk) - matched.clear(); // quick fix - to be optimised to avoid the operations above - - if (matched.empty()) - out.at(std::distance(l1trks.begin(), l1trkit)) = -1; - else { - std::sort(matched.begin(), matched.end()); // closest in theta, then in phi - out.at(std::distance(l1trks.begin(), l1trkit)) = std::get<2>(matched.at(0)); - } - } - - // now convert out to a unique set - return make_unique_coll(l1mus.size(), l1trks, out); -} - -std::vector L1TkMuCorrDynamicWindows::find_match_stub(const EMTFHitCollection& l1mus, - const L1TTTrackCollectionType& l1trks, - const int& station, - bool requireBX0) { - std::vector out(l1trks.size()); - for (auto l1trkit = l1trks.begin(); l1trkit != l1trks.end(); ++l1trkit) { - float trk_pt = l1trkit->momentum().perp(); - float trk_p = l1trkit->momentum().mag(); - float trk_aeta = std::abs(l1trkit->momentum().eta()); - float trk_theta = to_mpio2_pio2(eta_to_theta(l1trkit->momentum().eta())); - float trk_phi = l1trkit->momentum().phi(); - int trk_charge = (l1trkit->rInv() > 0 ? 1 : -1); - - // porting some selections from the MuonTrackCorr finder - // https://github.com/cms-l1t-offline/cmssw/blob/l1t-phase2-932-v1.6/L1Trigger/L1TTrackMatch/plugins/L1TkMuonProducer.cc#L264 - // for future: make preselections confiuguable - bool reject_trk = false; - if (trk_p < min_trk_p_) - reject_trk = true; - if (trk_aeta > max_trk_aeta_) - reject_trk = true; - if (track_qual_presel_) { - float l1tk_chi2 = l1trkit->chi2(); - int l1tk_nstubs = l1trkit->getStubRefs().size(); - if (l1tk_chi2 >= max_trk_chi2_) - reject_trk = true; - if (l1tk_nstubs < min_trk_nstubs_) - reject_trk = true; - } - - int ibin = findBin(trk_aeta); - - std::vector> matched; // dtheta, dphi, idx - // loop on stubs to see which match - for (auto l1muit = l1mus.begin(); l1muit != l1mus.end(); ++l1muit) { - if (!(l1muit->Is_CSC() || l1muit->Is_RPC())) - continue; - - int hit_station = l1muit->Station(); - // match only stubs in the central bx - as the track collection refers anyway to bx 0 only - if (requireBX0 && l1muit->BX() != 0) - continue; - - // allow only track matching to stubs from the given station, station= 1,2,3,4 - if (station < 5 && hit_station != station) - continue; - // in case of station=12 allow track matching to stubs from either station 1 or 2. - else if (station == 12 && hit_station > 2) // good for tkMuStub12 - continue; - // in case of station=123 allow track matching to stubs from either station 1, 2, or 3. - else if (station == 123 && hit_station > 3) // good for tkMuStub123 - continue; - // in case of station=1234 allow track matching to stubs from either station 1, 2, 3, or 4. - else if (station == 1234 && hit_station > 4) // good for tkMuStub1234 - continue; - - float emtf_theta = to_mpio2_pio2(eta_to_theta(l1muit->Eta_sim())); - float emtf_phi = angle_units::operators::convertDegToRad(l1muit->Phi_sim()); - - float dtheta = std::abs(emtf_theta - trk_theta); - float dphi = reco::deltaPhi(emtf_phi, trk_phi); - float adphi = std::abs(dphi); - - double sf_l; - double sf_h; - if (do_relax_factor_) { - sf_l = sf_progressive(trk_pt, pt_start_, pt_end_, initial_sf_l_, safety_factor_l_); - sf_h = sf_progressive(trk_pt, pt_start_, pt_end_, initial_sf_h_, safety_factor_h_); - } else { - sf_l = safety_factor_l_; - sf_h = safety_factor_h_; - } - - if (hit_station == 1 && - //if hit in station 1 use these matching windows for checking - - dtheta > (1 - sf_l) * wdws_theta_S1_.at(ibin).bound_low(trk_pt) && - dtheta <= (1 + sf_h) * wdws_theta_S1_.at(ibin).bound_high(trk_pt) && - adphi > (1 - sf_l) * wdws_phi_S1_.at(ibin).bound_low(trk_pt) && - adphi <= (1 + sf_h) * wdws_phi_S1_.at(ibin).bound_high(trk_pt) && - dphi * trk_charge < 0 && // sign requirement - true) - matched.emplace_back(dtheta, adphi, std::distance(l1mus.begin(), l1muit)); - - if (hit_station == 2 && dtheta > (1 - sf_l) * wdws_theta_.at(ibin).bound_low(trk_pt) && - dtheta <= (1 + sf_h) * wdws_theta_.at(ibin).bound_high(trk_pt) && - adphi > (1 - sf_l) * wdws_phi_.at(ibin).bound_low(trk_pt) && - adphi <= (1 + sf_h) * wdws_phi_.at(ibin).bound_high(trk_pt) && dphi * trk_charge < 0 && // sign requirement - // rndm > 0.5 - true) - matched.emplace_back(dtheta, adphi, std::distance(l1mus.begin(), l1muit)); - } - - if (reject_trk) - matched.clear(); // quick fix - to be optimised to avoid the operations above - - if (matched.empty()) - out.at(std::distance(l1trks.begin(), l1trkit)) = -1; - else { - std::sort(matched.begin(), matched.end()); // closest in theta, then in phi - out.at(std::distance(l1trks.begin(), l1trkit)) = std::get<2>(matched.at(0)); - } - } - - // return out; - - // now convert out to a unique set - auto unique_out = make_unique_coll(l1mus.size(), l1trks, out); - - return unique_out; -} - -std::vector L1TkMuCorrDynamicWindows::make_unique_coll(const unsigned int& l1musSize, - const L1TTTrackCollectionType& l1trks, - const std::vector& matches) { - std::vector out(matches.size(), -1); - - std::vector> macthed_to_emtf(l1musSize, - std::vector(0)); // one vector of matched trk idx per EMTF - - for (unsigned int itrack = 0; itrack < matches.size(); ++itrack) { - int iemtf = matches.at(itrack); - if (iemtf < 0) - continue; - macthed_to_emtf.at(iemtf).push_back(itrack); - } - - std::function track_less_than_proto = - [](int idx1, int idx2, const L1TTTrackCollectionType& l1trkcoll, int nTrackParams) { - float pt1 = l1trkcoll.at(idx1).momentum().perp(); - float pt2 = l1trkcoll.at(idx2).momentum().perp(); - return (pt1 < pt2); - }; - - // // and binds to accept only 2 params - std::function track_less_than = - std::bind(track_less_than_proto, std::placeholders::_1, std::placeholders::_2, l1trks, nTrkPars_); - - for (unsigned int iemtf = 0; iemtf < macthed_to_emtf.size(); ++iemtf) { - std::vector& thisv = macthed_to_emtf.at(iemtf); - if (thisv.empty()) - continue; - - std::sort(thisv.begin(), thisv.end(), track_less_than); - - // copy to the output - int best_trk = thisv.back(); - out.at(best_trk) = iemtf; - } - - return out; -} - -std::vector L1TkMuCorrDynamicWindows::prepare_corr_bounds(const string& fname, const string& hname) { - // find the boundaries of the match windoww - TFile* fIn = TFile::Open(fname.c_str()); - if (fIn == nullptr) { - throw cms::Exception("L1TkMuMantra") << "Can't find file " << fname << " to derive bounds.\n"; - } - TH2* h_test = (TH2*)fIn->Get(hname.c_str()); - if (h_test == nullptr) { - throw cms::Exception("L1TkMuCorrDynamicWindows") - << "Can't find histo " << hname << " in file " << fname << " to derive bounds.\n"; - } - - int nbds = h_test->GetNbinsY() + 1; - vector bounds(nbds); - for (int ib = 0; ib < nbds; ++ib) { - bounds.at(ib) = h_test->GetYaxis()->GetBinLowEdge(ib + 1); - } - fIn->Close(); - return bounds; -} diff --git a/L1Trigger/L1TTrackMatch/src/L1TkMuMantra.cc b/L1Trigger/L1TTrackMatch/src/L1TkMuMantra.cc deleted file mode 100644 index b26e25af5ab2f..0000000000000 --- a/L1Trigger/L1TTrackMatch/src/L1TkMuMantra.cc +++ /dev/null @@ -1,220 +0,0 @@ -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "L1Trigger/L1TTrackMatch/interface/L1TkMuMantra.h" -#include "DataFormats/Math/interface/deltaPhi.h" - -#include "TH2.h" -#include "TFile.h" - -using namespace L1TkMuMantraDF; - -L1TkMuMantra::L1TkMuMantra(const std::vector& bounds, - TFile* fIn_theta, - TFile* fIn_phi, - std::string name = "mantra") - : wdws_theta_(bounds.size() - 1, MuMatchWindow()), wdws_phi_(bounds.size() - 1, MuMatchWindow()) { - name_ = name; - - safety_factor_l_ = 0.0; - safety_factor_h_ = 0.0; - - sort_type_ = kMaxPt; - - // copy boundaries - nbins_ = bounds.size() - 1; - bounds_ = bounds; - - // now load in memory the TF1 fits - - for (int ib = 0; ib < nbins_; ++ib) { - std::string wdn; - std::string nml; - std::string nmc; - std::string nmh; - TF1* fl; - TF1* fc; - TF1* fh; - - wdn = name_ + std::string("_wdw_theta_") + std::to_string(ib + 1); - nml = std::string("fit_low_") + std::to_string(ib + 1); - nmc = std::string("fit_cent_") + std::to_string(ib + 1); - nmh = std::string("fit_high_") + std::to_string(ib + 1); - - fl = (TF1*)fIn_theta->Get(nml.c_str()); - fc = (TF1*)fIn_theta->Get(nmc.c_str()); - fh = (TF1*)fIn_theta->Get(nmh.c_str()); - if (fl == nullptr || fc == nullptr || fh == nullptr) { - if (verbosity_ > 0) { - LogTrace("L1TkMuMantra") << "... fit theta low : " << fl << std::endl; - LogTrace("L1TkMuMantra") << "... fit theta cent : " << fc << std::endl; - LogTrace("L1TkMuMantra") << "... fit theta high : " << fh << std::endl; - } - throw cms::Exception("L1TkMuMantra") << "TF1 named " << nml << " or " << nmc << " or " << nmh - << " not found in file " << fIn_theta->GetName() << ".\n"; - } - wdws_theta_.at(ib).SetName(wdn); - wdws_theta_.at(ib).SetLower(fl); - wdws_theta_.at(ib).SetCentral(fc); - wdws_theta_.at(ib).SetUpper(fh); - - wdn = name_ + std::string("_wdw_phi_") + std::to_string(ib + 1); - nml = std::string("fit_low_") + std::to_string(ib + 1); - nmc = std::string("fit_cent_") + std::to_string(ib + 1); - nmh = std::string("fit_high_") + std::to_string(ib + 1); - fl = (TF1*)fIn_phi->Get(nml.c_str()); - fc = (TF1*)fIn_phi->Get(nmc.c_str()); - fh = (TF1*)fIn_phi->Get(nmh.c_str()); - if (fl == nullptr || fc == nullptr || fh == nullptr) { - if (verbosity_ > 0) { - LogTrace("L1TkMuMantra") << "... fit phi low : " << fl << std::endl; - LogTrace("L1TkMuMantra") << "... fit phi cent : " << fc << std::endl; - LogTrace("L1TkMuMantra") << "... fit phi high : " << fh << std::endl; - } - throw cms::Exception("L1TkMuMantra") << "TF1 named " << nml << " or " << nmc << " or " << nmh - << " not found in file " << fIn_theta->GetName() << ".\n"; - } - wdws_phi_.at(ib).SetName(wdn); - wdws_phi_.at(ib).SetLower(fl); - wdws_phi_.at(ib).SetCentral(fc); - wdws_phi_.at(ib).SetUpper(fh); - } -} - -int L1TkMuMantra::findBin(double val) { - // FIXME: not the most efficient, nor the most elegant implementation for now - if (val < bounds_.at(0)) - return 0; - if (val >= bounds_.back()) - return (nbins_ - 1); // i.e. bounds_size() -2 - - for (uint ib = 0; ib < bounds_.size() - 1; ++ib) { - if (val >= bounds_.at(ib) && val < bounds_.at(ib + 1)) - return ib; - } - - if (verbosity_ > 0) - LogTrace("L1TkMuMantra") << "Something strange happened at val " << val << std::endl; - return 0; -} - -void L1TkMuMantra::test(double eta, double pt) { - int ibin = findBin(eta); - - LogTrace("L1TkMuMantra") << " ---- eta : " << eta << " pt: " << pt << std::endl; - LogTrace("L1TkMuMantra") << " ---- bin " << ibin << std::endl; - LogTrace("L1TkMuMantra") << " ---- " - << "- low_phi : " << wdws_phi_.at(ibin).bound_low(pt) - << "- cent_phi : " << wdws_phi_.at(ibin).bound_cent(pt) - << "- high_phi : " << wdws_phi_.at(ibin).bound_high(pt) << std::endl; - - LogTrace("L1TkMuMantra") << " ---- " - << "- low_theta : " << wdws_theta_.at(ibin).bound_low(pt) - << "- cent_theta : " << wdws_theta_.at(ibin).bound_cent(pt) - << "- high_theta : " << wdws_theta_.at(ibin).bound_high(pt) << std::endl; - - return; -} - -std::vector L1TkMuMantra::find_match(const std::vector& tracks, const std::vector& muons) { - std::vector result(muons.size(), -1); // init all TkMu to index -1 - for (uint imu = 0; imu < muons.size(); ++imu) { - muon_df mu = muons.at(imu); - std::vector> matched_trks; // sort_par, idx - for (uint itrk = 0; itrk < tracks.size(); ++itrk) { - // preselection of tracks - track_df trk = tracks.at(itrk); - if (trk.chi2 >= max_chi2) - continue; // require trk.chi2 < max_chi2 - if (trk.nstubs < min_nstubs) - continue; // require trk.nstubs >= min_nstubs - - double dphi_charge = reco::deltaPhi(trk.phi, mu.phi) * trk.charge; - // sign from theta, to avoid division by 0 - double dtheta_endc = (mu.theta - trk.theta) * sign(mu.theta); - if (sign(mu.theta) != sign(trk.theta)) { - // crossing the barrel -> remove 180 deg to the theta of the neg candidate to avoid jumps at eta = 0 - dtheta_endc -= TMath::Pi(); - } - - // lookup the values - int ibin = findBin(std::abs(trk.eta)); - - double phi_low = wdws_phi_.at(ibin).bound_low(trk.pt); - double phi_cent = wdws_phi_.at(ibin).bound_cent(trk.pt); - double phi_high = wdws_phi_.at(ibin).bound_high(trk.pt); - relax_windows(phi_low, phi_cent, phi_high); // apply the safety factor - bool in_phi = (dphi_charge > phi_low && dphi_charge < phi_high); - - double theta_low = wdws_theta_.at(ibin).bound_low(trk.pt); - double theta_cent = wdws_theta_.at(ibin).bound_cent(trk.pt); - double theta_high = wdws_theta_.at(ibin).bound_high(trk.pt); - relax_windows(theta_low, theta_cent, theta_high); // apply the safety factor - bool in_theta = (dtheta_endc > theta_low && dtheta_endc < theta_high); - - if (in_phi && in_theta) { - double sort_par = 99999; - if (sort_type_ == kMaxPt) - sort_par = trk.pt; - else if (sort_type_ == kMinDeltaPt) { - // trk.pt should always be > 0, but put this protection just in case - sort_par = (trk.pt > 0 ? std::abs(1. - (mu.pt / trk.pt)) : 0); - } - matched_trks.emplace_back(sort_par, itrk); - } - } - - // choose out of the matched tracks the best one - if (!matched_trks.empty()) { - sort(matched_trks.begin(), matched_trks.end()); - int ibest = 99999; - if (sort_type_ == kMaxPt) - ibest = matched_trks.rbegin()->second; // sorted low to high -> take last for highest pT (rbegin) - else if (sort_type_ == kMinDeltaPt) - ibest = matched_trks.begin()->second; // sorted low to high -> take first for min pT distance (begin) - result.at(imu) = ibest; - } - } - - return result; -} - -void L1TkMuMantra::relax_windows(double& low, double cent, double& high) { - double delta_high = high - cent; - double delta_low = cent - low; - - high = high + safety_factor_h_ * delta_high; - low = low - safety_factor_l_ * delta_low; - - return; -} - -void L1TkMuMantra::setArbitrationType(std::string type) { - if (verbosity_ > 0) - LogTrace("L1TkMuMantra") << "L1TkMuMantra : setting arbitration type to " << type << std::endl; - if (type == "MaxPt") - sort_type_ = kMaxPt; - else if (type == "MinDeltaPt") - sort_type_ = kMinDeltaPt; - else - throw cms::Exception("L1TkMuMantra") << "setArbitrationType : cannot understand the arbitration type passed.\n"; -} - -std::vector L1TkMuMantra::prepare_corr_bounds(std::string fname, std::string hname) { - // find the boundaries of the match windoww - TFile* fIn = TFile::Open(fname.c_str()); - if (fIn == nullptr) { - throw cms::Exception("L1TkMuMantra") << "Can't find file " << fname << " to derive bounds.\n"; - } - TH2* h_test = (TH2*)fIn->Get(hname.c_str()); - if (h_test == nullptr) { - throw cms::Exception("L1TkMuMantra") << "Can't find histo " << hname << " in file " << fname - << " to derive bounds.\n"; - } - - int nbds = h_test->GetNbinsY() + 1; - std::vector bounds(nbds); - for (int ib = 0; ib < nbds; ++ib) { - bounds.at(ib) = h_test->GetYaxis()->GetBinLowEdge(ib + 1); - } - fIn->Close(); - return bounds; -} diff --git a/L1Trigger/L1TTrackMatch/src/MuMatchWindow.cc b/L1Trigger/L1TTrackMatch/src/MuMatchWindow.cc deleted file mode 100644 index 54b527c50d141..0000000000000 --- a/L1Trigger/L1TTrackMatch/src/MuMatchWindow.cc +++ /dev/null @@ -1,40 +0,0 @@ -#include "L1Trigger/L1TTrackMatch/interface/MuMatchWindow.h" - -MuMatchWindow::MuMatchWindow() { name_ = ""; } - -MuMatchWindow::MuMatchWindow(std::string name) { SetName(name); } - -MuMatchWindow::~MuMatchWindow() {} - -void MuMatchWindow::SetLower(std::string formula) { - TF1 f("tmp", formula.c_str(), 0, 1000); - SetLower(&f); -} - -void MuMatchWindow::SetCentral(std::string formula) { - TF1 f("tmp", formula.c_str(), 0, 1000); - SetCentral(&f); -} - -void MuMatchWindow::SetUpper(std::string formula) { - TF1 f("tmp", formula.c_str(), 0, 1000); - SetUpper(&f); -} - -void MuMatchWindow::SetLower(TF1* formula) { - if (fLow_) - throw std::runtime_error("Cannot initialize twice fLow_"); - fLow_ = std::shared_ptr((TF1*)formula->Clone((name_ + std::string("low")).c_str())); -} - -void MuMatchWindow::SetCentral(TF1* formula) { - if (fCent_) - throw std::runtime_error("Cannot initialize twice fCent_"); - fCent_ = std::shared_ptr((TF1*)formula->Clone((name_ + std::string("cent")).c_str())); -} - -void MuMatchWindow::SetUpper(TF1* formula) { - if (fHigh_) - throw std::runtime_error("Cannot initialize twice fHigh_"); - fHigh_ = std::shared_ptr((TF1*)formula->Clone((name_ + std::string("high")).c_str())); -} diff --git a/L1Trigger/L1TTrackMatch/test/BuildFile.xml b/L1Trigger/L1TTrackMatch/test/BuildFile.xml new file mode 100644 index 0000000000000..f551705befad7 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/test/BuildFile.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/L1Trigger/L1TTrackMatch/test/L1TkMETAnalyser.cc b/L1Trigger/L1TTrackMatch/test/L1TkMETAnalyser.cc new file mode 100644 index 0000000000000..228c0519383ed --- /dev/null +++ b/L1Trigger/L1TTrackMatch/test/L1TkMETAnalyser.cc @@ -0,0 +1,267 @@ +#include +#include +#include +#include +#include + +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Candidate/interface/Candidate.h" +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" +#include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h" +#include "TEfficiency.h" +#include "TGraphAsymmErrors.h" +#include "TGraphErrors.h" +#include "TH1F.h" +#include "TH2F.h" +#include "TPad.h" +#include "TProfile.h" +#include "TTree.h" + +using namespace std; + +class L1TkMETAnalyser : public edm::one::EDAnalyzer { +public: + explicit L1TkMETAnalyser(const edm::ParameterSet& iConfig); + ~L1TkMETAnalyser() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void beginJob() override; + void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void endJob() override; + + edm::ParameterSet config; + + edm::InputTag TrackMETSimInputTag; + edm::InputTag TrackMETEmuInputTag; + edm::InputTag TrackMETHWInputTag; + + edm::EDGetTokenT> TrackMETSimToken_; + edm::EDGetTokenT> TrackMETEmuToken_; + edm::EDGetTokenT> TrackMETHWToken_; + + float EtScale; + float EtphiScale; + + bool available_; + TTree* eventTree; + + std::vector* m_SimMET; + std::vector* m_EmuMET; + std::vector* m_HwMET; + + std::vector* m_SimMETphi; + std::vector* m_EmuMETphi; + std::vector* m_HwMETphi; + + std::vector* m_SimNtrk; + std::vector* m_EmuNtrk; + std::vector* m_HwNtrk; + + bool HW_analysis_; + + TH1F* hisTkSimMET_; + TH1F* hisTkEmuMET_; + TH1F* hisTkHWMET_; + + TH1F* hisTkSimPhi_; + TH1F* hisTkEmuPhi_; + TH1F* hisTkHWPhi_; + + TH1F* hisTkSimNtrk_; + TH1F* hisTkEmuNtrk_; + TH1F* hisTkHWNtrk_; + + TH1F* hisMETResidual_; + TH1F* hisPhiResidual_; + TH1F* hisNtrkResidual_; +}; + +L1TkMETAnalyser::L1TkMETAnalyser(edm::ParameterSet const& iConfig) : config(iConfig) { + HW_analysis_ = iConfig.getParameter("HW_Analysis"); + + TrackMETSimInputTag = iConfig.getParameter("TrackMETInputTag"); + TrackMETEmuInputTag = iConfig.getParameter("TrackMETEmuInputTag"); + if (HW_analysis_) { + TrackMETHWInputTag = iConfig.getParameter("TrackMETHWInputTag"); + } + TrackMETSimToken_ = consumes>(TrackMETSimInputTag); + TrackMETEmuToken_ = consumes>(TrackMETEmuInputTag); + if (HW_analysis_) { + TrackMETHWToken_ = consumes>(TrackMETHWInputTag); + } + usesResource(TFileService::kSharedResource); +} + +void L1TkMETAnalyser::beginJob() { + edm::Service fs; + TFileDirectory inputDir = fs->mkdir("TkMETAnalysis"); + available_ = fs.isAvailable(); + if (not available_) + return; // No ROOT file open. + + m_SimMET = new std::vector; + m_EmuMET = new std::vector; + m_HwMET = new std::vector; + + m_SimMETphi = new std::vector; + m_EmuMETphi = new std::vector; + m_HwMETphi = new std::vector; + + m_SimNtrk = new std::vector; + m_EmuNtrk = new std::vector; + m_HwNtrk = new std::vector; + + eventTree = fs->make("eventTree", "Event tree"); + + eventTree->Branch("SimMET", &m_SimMET); + eventTree->Branch("EmuMET", &m_EmuMET); + eventTree->Branch("HwMET", &m_HwMET); + + eventTree->Branch("SimMETphi", &m_SimMETphi); + eventTree->Branch("EmuMETphi", &m_EmuMETphi); + eventTree->Branch("HwMETphi", &m_HwMETphi); + + eventTree->Branch("SimNtrk", &m_SimNtrk); + eventTree->Branch("EmuNtrk", &m_EmuNtrk); + eventTree->Branch("HwNtrk", &m_HwNtrk); + + hisTkSimMET_ = inputDir.make("hisTkSimMET_", "sim TkMET [GeV]", 101, 0, 500); + hisTkEmuMET_ = inputDir.make("hisTkEmuMET_", "emu TkMET [GeV]", 101, 0, 500); + + hisTkSimPhi_ = inputDir.make("hisTkSimPhi_", "sim phi [rad]", 101, -M_PI, M_PI); + hisTkEmuPhi_ = inputDir.make("hisTkEmuPhi_", "emu phi [rad]", 101, -M_PI, M_PI); + + hisTkSimNtrk_ = inputDir.make("hisTkSimNtrk_", "sim ntrks", 101, 0, 256); + hisTkEmuNtrk_ = inputDir.make("hisTkEmuNtrk_", "emu ntrks", 101, 0, 256); + + if (!HW_analysis_) { + hisMETResidual_ = inputDir.make("hisMETResidual_", "sim - emu TkMET [GeV]", 101, -100, 100); + hisPhiResidual_ = inputDir.make("hisPhiResidual_", "sim - emu phi [rad]", 101, -1, 1); + hisNtrkResidual_ = inputDir.make("hisNtrkResidual_", "sim - emu ntrks", 101, -10, 10); + } + + if (HW_analysis_) { + hisTkHWMET_ = inputDir.make("hisTkHWMET_", "hw TkMET [GeV]", 101, 0, 500); + hisTkHWPhi_ = inputDir.make("hisTkHWPhi_", "hw phi [rad]", 101, -M_PI, M_PI); + hisTkHWNtrk_ = inputDir.make("hisTkEmuNtrk_", "hw ntrks", 101, 0, 256); + + hisMETResidual_ = inputDir.make("hisMETResidual_", "emu - hw TkMET [GeV]", 101, -100, 100); + hisPhiResidual_ = inputDir.make("hisPhiResidual_", "emu - hw phi [rad]", 101, -1, 1); + hisNtrkResidual_ = inputDir.make("hisNtrkResidual_", "emu - hw ntrks", 101, -10, 10); + } +} + +void L1TkMETAnalyser::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + if (not available_) + return; // No ROOT file open. + + edm::Handle> L1TkMETSimHandle; + edm::Handle> L1TkMETEmuHandle; + + iEvent.getByToken(TrackMETSimToken_, L1TkMETSimHandle); + iEvent.getByToken(TrackMETEmuToken_, L1TkMETEmuHandle); + + m_SimMET->clear(); + m_EmuMET->clear(); + m_HwMET->clear(); + m_SimMETphi->clear(); + m_EmuMETphi->clear(); + m_HwMETphi->clear(); + m_SimNtrk->clear(); + m_EmuNtrk->clear(); + m_HwNtrk->clear(); + + float SimEtmiss = L1TkMETSimHandle->begin()->etMiss(); + float EmuEtmiss = L1TkMETEmuHandle->begin()->hwPt() * l1tmetemu::kStepMET; + + float SimEtPhi = L1TkMETSimHandle->begin()->etPhi(); + float EmuEtPhi = L1TkMETEmuHandle->begin()->hwPhi() * l1tmetemu::kStepMETPhi - M_PI; + + int SimEtNtrk = L1TkMETSimHandle->begin()->etQual(); + int EmuEtNtrk = L1TkMETEmuHandle->begin()->hwQual(); + + if (!HW_analysis_) { + hisMETResidual_->Fill(EmuEtmiss - SimEtmiss); + hisPhiResidual_->Fill(EmuEtPhi - SimEtPhi); + hisNtrkResidual_->Fill(EmuEtNtrk - SimEtNtrk); + } + + m_SimMET->push_back(SimEtmiss); + m_EmuMET->push_back(EmuEtmiss); + m_SimMETphi->push_back(SimEtPhi); + m_EmuMETphi->push_back(EmuEtPhi); + m_SimNtrk->push_back(SimEtNtrk); + m_EmuNtrk->push_back(EmuEtNtrk); + + hisTkSimMET_->Fill(SimEtmiss); + hisTkEmuMET_->Fill(EmuEtmiss); + + hisTkSimPhi_->Fill(SimEtPhi); + hisTkEmuPhi_->Fill(EmuEtPhi); + + hisTkSimNtrk_->Fill(SimEtNtrk); + hisTkEmuNtrk_->Fill(EmuEtNtrk); + + if (HW_analysis_) { + edm::Handle> L1TkMETHWHandle; + iEvent.getByToken(TrackMETHWToken_, L1TkMETHWHandle); + float HWEtmiss = L1TkMETHWHandle->begin()->hwPt(); + float HWEtPhi = L1TkMETHWHandle->begin()->hwPhi(); + int HWEtNtrk = L1TkMETHWHandle->begin()->hwQual(); + + hisTkHWMET_->Fill(HWEtmiss); + hisTkHWPhi_->Fill(HWEtPhi); + hisTkHWNtrk_->Fill(HWEtNtrk); + + hisMETResidual_->Fill(EmuEtmiss - HWEtmiss); + hisPhiResidual_->Fill(EmuEtPhi - HWEtPhi); + hisNtrkResidual_->Fill(EmuEtNtrk - HWEtNtrk); + + m_HwMET->push_back(HWEtmiss); + m_HwMETphi->push_back(HWEtPhi); + m_HwNtrk->push_back(HWEtNtrk); + } + eventTree->Fill(); +} + +////////// +// END JOB +void L1TkMETAnalyser::endJob() { + // things to be done at the exit of the event Loop + edm::LogInfo("L1TkMETAnalyser") << "==================== TkMET RECONSTRUCTION ======================\n" + << "MET Residual Bias: " << hisMETResidual_->GetMean() << " GeV\n" + << "MET Resolution: " << hisMETResidual_->GetStdDev() << " GeV\n" + << "Phi Residual Bias: " << hisPhiResidual_->GetMean() << " rad\n" + << "Phi Resolution: " << hisPhiResidual_->GetStdDev() << " rad\n" + << "NTrk Residual Bias: " << hisNtrkResidual_->GetMean() << " Tracks\n" + << "Ntrk Resolution: " << hisNtrkResidual_->GetStdDev() << " Tracks\n"; +} + +void L1TkMETAnalyser::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +/////////////////////////// +// DEFINE THIS AS A PLUG-IN +DEFINE_FWK_MODULE(L1TkMETAnalyser); diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackMET_cfg.py b/L1Trigger/L1TTrackMatch/test/L1TrackMET_cfg.py new file mode 100644 index 0000000000000..ca73009d2f861 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/test/L1TrackMET_cfg.py @@ -0,0 +1,113 @@ +############################################################ +# define basic process +############################################################ + +import FWCore.ParameterSet.Config as cms +import FWCore.Utilities.FileUtils as FileUtils +import os + +############################################################ +# edit options here +############################################################ +L1TRK_INST ="L1TrackMET" ### if not in input DIGRAW then we make them in the above step +process = cms.Process(L1TRK_INST) + +ReRunTracking = True +GTTInput = True + + +############################################################ +# import standard configurations +############################################################ + +process.load('Configuration.StandardSequences.Services_cff') +process.load('Configuration.EventContent.EventContent_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') + +############################################################ +# input and output +############################################################ + +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10)) + +readFiles = cms.untracked.vstring( + '/store/relval/CMSSW_11_0_0/RelValTTbar_14TeV/GEN-SIM-RECO/PU25ns_110X_mcRun4_realistic_v3_2026D49PU200-v2/10000/53F7C2B0-F6CF-C544-AFF4-3EAAF66DF18B.root', +) +secFiles = cms.untracked.vstring() + +process.source = cms.Source ("PoolSource", + fileNames = readFiles, + secondaryFileNames = secFiles, + duplicateCheckMode = cms.untracked.string('noDuplicateCheck'), + ) + + +process.TFileService = cms.Service("TFileService", fileName = cms.string('TrackMET_Emulation.root'), closeFileFast = cms.untracked.bool(True)) + +if ReRunTracking: + process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") + producerSum = process.L1HybridTracks + process.L1HybridTracksWithAssociators +else: + producerSum = None + +if GTTInput: + process.load('L1Trigger.L1TTrackMatch.L1GTTInputProducer_cfi') + producerSum = producerSum + process.L1GTTInputProducer + + + +process.load("L1Trigger.L1TTrackMatch.L1TrackerEtMissProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1TrackerEtMissEmulatorProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1TkMETAnalyser_cfi") + +############################################################ +# Primary vertex +############################################################ + +process.load('L1Trigger.VertexFinder.VertexProducer_cff') +process.VertexProducer.l1TracksInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks") + + +producerSum += process.VertexProducer + +producerName = 'VertexProducer{0}'.format("fastHisto") +producerName = producerName.replace(".","p") # legalize the name +producer = process.VertexProducer.clone() +producer.VertexReconstruction.Algorithm = cms.string("fastHisto") +process.L1TrackerEtMiss.L1VertexInputTag = cms.InputTag(producerName,"l1vertices") + + +setattr(process, producerName, producer) +producerSum += producer +producerSum += process.L1TrackerEtMiss + +process.L1TrackerEmuEtMiss.useGTTinput = GTTInput + +if GTTInput: + process.L1TrackerEmuEtMiss.L1TrackInputTag = cms.InputTag("L1GTTInputProducer","Level1TTTracksConverted") +else: + process.L1TrackerEmuEtMiss.L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks") + +EmuproducerName = 'VertexProducer{0}'.format("fastHistoEmulation") +EmuproducerName = EmuproducerName.replace(".","p") # legalize the name +Emuproducer = process.VertexProducer.clone() +Emuproducer.VertexReconstruction.Algorithm = cms.string("fastHistoEmulation") +process.L1TrackerEmuEtMiss.L1VertexInputTag = cms.InputTag(EmuproducerName,"l1verticesEmulation") + +if GTTInput: + Emuproducer.l1TracksInputTag = cms.InputTag("L1GTTInputProducer","Level1TTTracksConverted") +else: + Emuproducer.l1TracksInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks") + +setattr(process, EmuproducerName, Emuproducer) +producerSum += Emuproducer +producerSum += process.L1TrackerEmuEtMiss + +process.p = cms.Path(producerSum + process.L1TkMETAnalyser) diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc index d2acda970d4bd..fc28db284af0a 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc +++ b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker.cc @@ -8,9 +8,8 @@ // FRAMEWORK HEADERS #include "FWCore/PluginManager/interface/ModuleDef.h" #include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/InputTag.h" @@ -60,12 +59,17 @@ //My additions #include "DataFormats/L1TCorrelator/interface/TkJet.h" #include "DataFormats/L1TCorrelator/interface/TkJetFwd.h" +#include "DataFormats/L1Trigger/interface/TkJetWord.h" #include "DataFormats/Math/interface/LorentzVector.h" #include "DataFormats/L1TCorrelator/interface/TkEtMiss.h" #include "DataFormats/L1TCorrelator/interface/TkEtMissFwd.h" #include "DataFormats/L1TCorrelator/interface/TkHTMiss.h" #include "DataFormats/L1TCorrelator/interface/TkHTMissFwd.h" #include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkEtMissEmuAlgo.h" +#include "L1Trigger/L1TTrackMatch/interface/L1TkHTMissEmulatorProducer.h" /////////////// // ROOT HEADERS @@ -95,7 +99,16 @@ using namespace edm; // // ////////////////////////////// -class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { +class L1TrackObjectNtupleMaker : public edm::one::EDAnalyzer { +private: + // ----------constants, enums and typedefs --------- + typedef TTTrack L1Track; + typedef edm::Ptr L1TrackPtr; + typedef std::vector L1TrackPtrCollection; + typedef std::vector L1TrackCollection; + typedef edm::Ref L1TrackRef; + typedef edm::RefVector L1TrackRefCollection; + public: // Constructor/destructor explicit L1TrackObjectNtupleMaker(const edm::ParameterSet& iConfig); @@ -106,7 +119,10 @@ class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { void endJob() override; void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override; -protected: + // Other member functions + int getSelectedTrackIndex(const L1TrackRef& trackRef, + const edm::Handle& selectedTrackRefs) const; + private: //----------------------------------------------------------------------------------------------- // Containers of parameters passed by python configuration file @@ -123,14 +139,19 @@ class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { double TP_maxEta; // save TPs with |eta| < maxEta double TP_maxZ0; // save TPs with |z0| < maxZ0 int L1Tk_minNStub; // require L1 tracks to have >= minNStub (this is mostly for tracklet purposes) - bool TrackingInJets; // do tracking in jets? bool SaveTrackJets; - bool SaveTrackMET; - - edm::InputTag L1TrackInputTag; // L1 track collection - edm::InputTag MCTruthTrackInputTag; // MC truth collection - edm::InputTag L1TrackExtendedInputTag; // L1 track collection - edm::InputTag MCTruthTrackExtendedInputTag; // MC truth collection + bool SaveTrackSums; + + edm::InputTag L1TrackInputTag; // L1 track collection + edm::InputTag MCTruthTrackInputTag; // MC truth collection + edm::InputTag L1TrackGTTInputTag; // L1 track collection + edm::InputTag L1TrackSelectedInputTag; // L1 track collection + edm::InputTag L1TrackSelectedEmulationInputTag; // L1 track collection + edm::InputTag L1TrackExtendedInputTag; // L1 track collection + edm::InputTag MCTruthTrackExtendedInputTag; // MC truth collection + edm::InputTag L1TrackExtendedGTTInputTag; // L1 track collection + edm::InputTag L1TrackExtendedSelectedInputTag; // L1 track collection + edm::InputTag L1TrackExtendedSelectedEmulationInputTag; // L1 track collection edm::InputTag MCTruthClusterInputTag; edm::InputTag L1StubInputTag; edm::InputTag MCTruthStubInputTag; @@ -138,63 +159,77 @@ class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { edm::InputTag TrackingVertexInputTag; edm::InputTag GenJetInputTag; edm::InputTag RecoVertexInputTag; + edm::InputTag RecoVertexEmuInputTag; edm::InputTag GenParticleInputTag; edm::InputTag TrackFastJetsInputTag; edm::InputTag TrackJetsInputTag; + edm::InputTag TrackJetsEmuInputTag; edm::InputTag TrackMETInputTag; + edm::InputTag TrackMETEmuInputTag; edm::InputTag TrackMHTInputTag; + edm::InputTag TrackMHTEmuInputTag; edm::InputTag TrackFastJetsExtendedInputTag; edm::InputTag TrackJetsExtendedInputTag; + edm::InputTag TrackJetsExtendedEmuInputTag; edm::InputTag TrackMETExtendedInputTag; + //edm::InputTag TrackMETEmuExtendedInputTag; edm::InputTag TrackMHTExtendedInputTag; - - edm::EDGetTokenT > > ttClusterToken_; - edm::EDGetTokenT > > ttStubToken_; - edm::EDGetTokenT > ttClusterMCTruthToken_; - edm::EDGetTokenT > ttStubMCTruthToken_; - - edm::EDGetTokenT > > ttTrackToken_; - edm::EDGetTokenT > ttTrackMCTruthToken_; - edm::EDGetTokenT > > ttTrackExtendedToken_; - edm::EDGetTokenT > ttTrackMCTruthExtendedToken_; - - edm::EDGetTokenT > TrackingParticleToken_; - edm::EDGetTokenT > TrackingVertexToken_; - - edm::EDGetTokenT > GenJetToken_; - edm::EDGetTokenT > GenParticleToken_; + edm::InputTag TrackMHTEmuExtendedInputTag; + + edm::EDGetTokenT>> ttClusterToken_; + edm::EDGetTokenT>> ttStubToken_; + edm::EDGetTokenT> ttClusterMCTruthToken_; + edm::EDGetTokenT> ttStubMCTruthToken_; + + edm::EDGetTokenT ttTrackToken_; + edm::EDGetTokenT> ttTrackMCTruthToken_; + edm::EDGetTokenT ttTrackGTTToken_; + edm::EDGetTokenT ttTrackSelectedToken_; + edm::EDGetTokenT ttTrackSelectedEmulationToken_; + edm::EDGetTokenT ttTrackExtendedToken_; + edm::EDGetTokenT> ttTrackMCTruthExtendedToken_; + edm::EDGetTokenT ttTrackExtendedGTTToken_; + edm::EDGetTokenT ttTrackExtendedSelectedToken_; + edm::EDGetTokenT ttTrackExtendedSelectedEmulationToken_; + + edm::EDGetTokenT> TrackingParticleToken_; + edm::EDGetTokenT> TrackingVertexToken_; + edm::EDGetTokenT> GenJetToken_; + edm::EDGetTokenT> GenParticleToken_; edm::EDGetTokenT L1VertexToken_; - - edm::EDGetTokenT > TrackFastJetsToken_; - edm::EDGetTokenT > TrackFastJetsExtendedToken_; - edm::EDGetTokenT > TrackMETToken_; - edm::EDGetTokenT > TrackMETExtendedToken_; + edm::EDGetTokenT L1VertexEmuToken_; + + edm::EDGetTokenT> TrackFastJetsToken_; + edm::EDGetTokenT> TrackFastJetsExtendedToken_; + edm::EDGetTokenT> TrackMETToken_; + edm::EDGetTokenT> TrackMETExtendedToken_; + edm::EDGetTokenT> TrackMETEmuToken_; + //edm::EDGetTokenT> TrackMETEmuExtendedToken_; edm::EDGetTokenT TrackMHTToken_; edm::EDGetTokenT TrackMHTExtendedToken_; + edm::EDGetTokenT> TrackMHTEmuToken_; + edm::EDGetTokenT> TrackMHTEmuExtendedToken_; edm::EDGetTokenT TrackJetsToken_; edm::EDGetTokenT TrackJetsExtendedToken_; + edm::EDGetTokenT TrackJetsEmuToken_; + edm::EDGetTokenT TrackJetsExtendedEmuToken_; edm::ESGetToken tTopoToken_; edm::ESGetToken tGeomToken_; //----------------------------------------------------------------------------------------------- // tree & branches for mini-ntuple - bool available_; // ROOT file for histograms is open. - TTree* eventTree; // primary vertex - // std::vector* m_pv_L1recotruesumpt; - // std::vector* m_pv_L1recosumpt; std::vector* m_pv_L1reco; std::vector* m_pv_L1reco_sum; - // std::vector* m_pv_L1TP; - // std::vector* m_pv_L1TPsumpt; + std::vector* m_pv_L1reco_emu; + std::vector* m_pv_L1reco_sum_emu; std::vector* m_pv_MC; - // std::vector* m_pv_MCChgSumpT; std::vector* m_MC_lep; //gen particles @@ -233,6 +268,11 @@ class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { std::vector* m_trk_matchtp_phi; std::vector* m_trk_matchtp_z0; std::vector* m_trk_matchtp_dxy; + std::vector* m_trk_gtt_pt; + std::vector* m_trk_gtt_eta; + std::vector* m_trk_gtt_phi; + std::vector* m_trk_selected_index; + std::vector* m_trk_selected_emulation_index; // all L1 tracks (extended) std::vector* m_trkExt_pt; @@ -264,6 +304,11 @@ class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { std::vector* m_trkExt_matchtp_phi; std::vector* m_trkExt_matchtp_z0; std::vector* m_trkExt_matchtp_dxy; + std::vector* m_trkExt_gtt_pt; + std::vector* m_trkExt_gtt_eta; + std::vector* m_trkExt_gtt_phi; + std::vector* m_trkExt_selected_index; + std::vector* m_trkExt_selected_emulation_index; // all tracking particles std::vector* m_tp_pt; @@ -335,34 +380,46 @@ class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { std::vector* m_allstub_matchTP_phi; // -999 if not matched std::vector* m_allstub_genuine; - // // track jet variables (for each gen jet, store the sum of pt of TPs / tracks inside jet cone) - // std::vector* m_jet_eta; - // std::vector* m_jet_phi; - // std::vector* m_jet_pt; - // std::vector* m_jet_tp_sumpt; - // std::vector* m_jet_trk_sumpt; - // std::vector* m_jet_matchtrk_sumpt; - + //prompt float trueMET = 0; float trueTkMET = 0; float trkMET = 0; + float trkMETPhi = 0; float trkMHT = 0; float trkHT = 0; + float trkMHTEmu = 0; + float trkMHTEmuPhi = 0; + float trkHTEmu = 0; + float trkMETEmu = 0; + float trkMETEmuPhi = 0; + //displaced float trkMETExt = 0; + float trkMETPhiExt = 0; float trkMHTExt = 0; float trkHTExt = 0; - - std::vector* m_2ltrkjet_vz; - std::vector* m_2ltrkjet_p; - std::vector* m_2ltrkjet_phi; - std::vector* m_2ltrkjet_eta; - std::vector* m_2ltrkjet_pt; - std::vector* m_2ltrkjet_ntracks; - std::vector* m_2ltrkjet_nDisplaced; - std::vector* m_2ltrkjet_nTight; - std::vector* m_2ltrkjet_nTightDisplaced; - std::vector* m_2ltrkjet_ntdtrk; + float trkMHTEmuExt = 0; + float trkMHTEmuPhiExt = 0; + float trkHTEmuExt = 0; + + //fast track jet + std::vector* m_trkfastjet_vz; + std::vector* m_trkfastjet_p; + std::vector* m_trkfastjet_phi; + std::vector* m_trkfastjet_eta; + std::vector* m_trkfastjet_pt; + std::vector* m_trkfastjet_ntracks; + std::vector* m_trkfastjet_tp_sumpt; + std::vector* m_trkfastjet_truetp_sumpt; + + std::vector* m_trkfastjetExt_vz; + std::vector* m_trkfastjetExt_p; + std::vector* m_trkfastjetExt_phi; + std::vector* m_trkfastjetExt_eta; + std::vector* m_trkfastjetExt_pt; + std::vector* m_trkfastjetExt_ntracks; + std::vector* m_trkfastjetExt_tp_sumpt; + std::vector* m_trkfastjetExt_truetp_sumpt; std::vector* m_trkjet_vz; std::vector* m_trkjet_p; @@ -370,19 +427,17 @@ class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { std::vector* m_trkjet_eta; std::vector* m_trkjet_pt; std::vector* m_trkjet_ntracks; - std::vector* m_trkjet_tp_sumpt; - std::vector* m_trkjet_truetp_sumpt; - - std::vector* m_2ltrkjetExt_vz; - std::vector* m_2ltrkjetExt_p; - std::vector* m_2ltrkjetExt_phi; - std::vector* m_2ltrkjetExt_eta; - std::vector* m_2ltrkjetExt_pt; - std::vector* m_2ltrkjetExt_ntracks; - std::vector* m_2ltrkjetExt_nDisplaced; - std::vector* m_2ltrkjetExt_nTight; - std::vector* m_2ltrkjetExt_nTightDisplaced; - std::vector* m_2ltrkjetExt_ntdtrk; + std::vector* m_trkjet_nDisplaced; + std::vector* m_trkjet_nTight; + std::vector* m_trkjet_nTightDisplaced; + std::vector* m_trkjet_ntdtrk; + + std::vector* m_trkjetem_pt; + std::vector* m_trkjetem_phi; + std::vector* m_trkjetem_eta; + std::vector* m_trkjetem_z; + std::vector* m_trkjetem_ntracks; + std::vector* m_trkjetem_nxtracks; std::vector* m_trkjetExt_vz; std::vector* m_trkjetExt_p; @@ -390,8 +445,17 @@ class L1TrackObjectNtupleMaker : public edm::EDAnalyzer { std::vector* m_trkjetExt_eta; std::vector* m_trkjetExt_pt; std::vector* m_trkjetExt_ntracks; - std::vector* m_trkjetExt_tp_sumpt; - std::vector* m_trkjetExt_truetp_sumpt; + std::vector* m_trkjetExt_nDisplaced; + std::vector* m_trkjetExt_nTight; + std::vector* m_trkjetExt_nTightDisplaced; + std::vector* m_trkjetExt_ntdtrk; + + std::vector* m_trkjetemExt_pt; + std::vector* m_trkjetemExt_phi; + std::vector* m_trkjetemExt_eta; + std::vector* m_trkjetemExt_z; + std::vector* m_trkjetemExt_ntracks; + std::vector* m_trkjetemExt_nxtracks; }; ////////////////////////////////// @@ -415,9 +479,8 @@ L1TrackObjectNtupleMaker::L1TrackObjectNtupleMaker(edm::ParameterSet const& iCon TP_maxZ0 = iConfig.getParameter("TP_maxZ0"); L1Tk_minNStub = iConfig.getParameter("L1Tk_minNStub"); - TrackingInJets = iConfig.getParameter("TrackingInJets"); SaveTrackJets = iConfig.getParameter("SaveTrackJets"); - SaveTrackMET = iConfig.getParameter("SaveTrackMET"); + SaveTrackSums = iConfig.getParameter("SaveTrackSums"); L1StubInputTag = iConfig.getParameter("L1StubInputTag"); MCTruthClusterInputTag = iConfig.getParameter("MCTruthClusterInputTag"); @@ -426,51 +489,80 @@ L1TrackObjectNtupleMaker::L1TrackObjectNtupleMaker(edm::ParameterSet const& iCon TrackingVertexInputTag = iConfig.getParameter("TrackingVertexInputTag"); GenJetInputTag = iConfig.getParameter("GenJetInputTag"); RecoVertexInputTag = iConfig.getParameter("RecoVertexInputTag"); + RecoVertexEmuInputTag = iConfig.getParameter("RecoVertexEmuInputTag"); GenParticleInputTag = iConfig.getParameter("GenParticleInputTag"); if (Displaced == "Prompt" || Displaced == "Both") { L1TrackInputTag = iConfig.getParameter("L1TrackInputTag"); MCTruthTrackInputTag = iConfig.getParameter("MCTruthTrackInputTag"); + L1TrackGTTInputTag = iConfig.getParameter("L1TrackGTTInputTag"); + L1TrackSelectedInputTag = iConfig.getParameter("L1TrackSelectedInputTag"); + L1TrackSelectedEmulationInputTag = iConfig.getParameter("L1TrackSelectedEmulationInputTag"); TrackFastJetsInputTag = iConfig.getParameter("TrackFastJetsInputTag"); TrackJetsInputTag = iConfig.getParameter("TrackJetsInputTag"); + TrackJetsEmuInputTag = iConfig.getParameter("TrackJetsEmuInputTag"); TrackMETInputTag = iConfig.getParameter("TrackMETInputTag"); + TrackMETEmuInputTag = iConfig.getParameter("TrackMETEmuInputTag"); TrackMHTInputTag = iConfig.getParameter("TrackMHTInputTag"); - - ttTrackToken_ = consumes > >(L1TrackInputTag); - ttTrackMCTruthToken_ = consumes >(MCTruthTrackInputTag); - TrackFastJetsToken_ = consumes >(TrackFastJetsInputTag); + TrackMHTEmuInputTag = iConfig.getParameter("TrackMHTEmuInputTag"); + + ttTrackToken_ = consumes(L1TrackInputTag); + ttTrackMCTruthToken_ = consumes>(MCTruthTrackInputTag); + ttTrackGTTToken_ = consumes(L1TrackGTTInputTag); + ttTrackSelectedToken_ = consumes(L1TrackSelectedInputTag); + ttTrackSelectedEmulationToken_ = consumes(L1TrackSelectedEmulationInputTag); + TrackFastJetsToken_ = consumes>(TrackFastJetsInputTag); TrackJetsToken_ = consumes(TrackJetsInputTag); - TrackMETToken_ = consumes >(TrackMETInputTag); + TrackJetsEmuToken_ = consumes(TrackJetsEmuInputTag); + TrackMETToken_ = consumes>(TrackMETInputTag); + TrackMETEmuToken_ = consumes>(TrackMETEmuInputTag); TrackMHTToken_ = consumes(TrackMHTInputTag); + TrackMHTEmuToken_ = consumes>(TrackMHTEmuInputTag); } if (Displaced == "Displaced" || Displaced == "Both") { L1TrackExtendedInputTag = iConfig.getParameter("L1TrackExtendedInputTag"); MCTruthTrackExtendedInputTag = iConfig.getParameter("MCTruthTrackExtendedInputTag"); + L1TrackExtendedGTTInputTag = iConfig.getParameter("L1TrackExtendedGTTInputTag"); + L1TrackExtendedSelectedInputTag = iConfig.getParameter("L1TrackExtendedSelectedInputTag"); + L1TrackExtendedSelectedEmulationInputTag = + iConfig.getParameter("L1TrackExtendedSelectedEmulationInputTag"); TrackFastJetsExtendedInputTag = iConfig.getParameter("TrackFastJetsExtendedInputTag"); TrackJetsExtendedInputTag = iConfig.getParameter("TrackJetsExtendedInputTag"); + TrackJetsExtendedEmuInputTag = iConfig.getParameter("TrackJetsExtendedEmuInputTag"); TrackMETExtendedInputTag = iConfig.getParameter("TrackMETExtendedInputTag"); TrackMHTExtendedInputTag = iConfig.getParameter("TrackMHTExtendedInputTag"); + TrackMHTEmuInputTag = iConfig.getParameter("TrackMHTEmuInputTag"); + TrackMHTEmuExtendedInputTag = iConfig.getParameter("TrackMHTEmuExtendedInputTag"); - ttTrackExtendedToken_ = consumes > >(L1TrackExtendedInputTag); + ttTrackExtendedToken_ = consumes(L1TrackExtendedInputTag); ttTrackMCTruthExtendedToken_ = - consumes >(MCTruthTrackExtendedInputTag); - TrackFastJetsExtendedToken_ = consumes >(TrackFastJetsExtendedInputTag); + consumes>(MCTruthTrackExtendedInputTag); + ttTrackExtendedGTTToken_ = consumes(L1TrackExtendedGTTInputTag); + ttTrackExtendedSelectedToken_ = consumes(L1TrackExtendedSelectedInputTag); + ttTrackExtendedSelectedEmulationToken_ = consumes(L1TrackExtendedSelectedEmulationInputTag); + TrackFastJetsExtendedToken_ = consumes>(TrackFastJetsExtendedInputTag); TrackJetsExtendedToken_ = consumes(TrackJetsExtendedInputTag); - TrackMETExtendedToken_ = consumes >(TrackMETExtendedInputTag); + TrackJetsExtendedEmuToken_ = consumes(TrackJetsExtendedEmuInputTag); + TrackMETExtendedToken_ = consumes>(TrackMETExtendedInputTag); TrackMHTExtendedToken_ = consumes(TrackMHTExtendedInputTag); + TrackMHTEmuToken_ = consumes>(TrackMHTEmuInputTag); + TrackMHTEmuExtendedToken_ = consumes>(TrackMHTEmuExtendedInputTag); } - ttStubToken_ = consumes > >(L1StubInputTag); - ttClusterMCTruthToken_ = consumes >(MCTruthClusterInputTag); - ttStubMCTruthToken_ = consumes >(MCTruthStubInputTag); - TrackingParticleToken_ = consumes >(TrackingParticleInputTag); - TrackingVertexToken_ = consumes >(TrackingVertexInputTag); - GenJetToken_ = consumes >(GenJetInputTag); - GenParticleToken_ = consumes >(GenParticleInputTag); + ttStubToken_ = consumes>>(L1StubInputTag); + ttClusterMCTruthToken_ = consumes>(MCTruthClusterInputTag); + ttStubMCTruthToken_ = consumes>(MCTruthStubInputTag); + TrackingParticleToken_ = consumes>(TrackingParticleInputTag); + TrackingVertexToken_ = consumes>(TrackingVertexInputTag); + GenJetToken_ = consumes>(GenJetInputTag); + GenParticleToken_ = consumes>(GenParticleInputTag); L1VertexToken_ = consumes(RecoVertexInputTag); + L1VertexEmuToken_ = consumes(RecoVertexEmuInputTag); tTopoToken_ = esConsumes(edm::ESInputTag("", "")); tGeomToken_ = esConsumes(edm::ESInputTag("", "")); + + usesResource(TFileService::kSharedResource); } ///////////// @@ -527,6 +619,11 @@ void L1TrackObjectNtupleMaker::beginJob() { m_trk_matchtp_phi = new std::vector; m_trk_matchtp_z0 = new std::vector; m_trk_matchtp_dxy = new std::vector; + m_trk_gtt_pt = new std::vector; + m_trk_gtt_eta = new std::vector; + m_trk_gtt_phi = new std::vector; + m_trk_selected_index = new std::vector; + m_trk_selected_emulation_index = new std::vector; m_trkExt_pt = new std::vector; m_trkExt_eta = new std::vector; @@ -557,6 +654,11 @@ void L1TrackObjectNtupleMaker::beginJob() { m_trkExt_matchtp_phi = new std::vector; m_trkExt_matchtp_z0 = new std::vector; m_trkExt_matchtp_dxy = new std::vector; + m_trkExt_gtt_pt = new std::vector; + m_trkExt_gtt_eta = new std::vector; + m_trkExt_gtt_phi = new std::vector; + m_trkExt_selected_index = new std::vector; + m_trkExt_selected_emulation_index = new std::vector; m_tp_pt = new std::vector; m_tp_eta = new std::vector; @@ -627,53 +729,39 @@ void L1TrackObjectNtupleMaker::beginJob() { m_allstub_matchTP_phi = new std::vector; m_allstub_genuine = new std::vector; - // m_jet_eta = new std::vector; - // m_jet_phi = new std::vector; - // m_jet_pt = new std::vector; - // m_jet_tp_sumpt = new std::vector; - // m_jet_trk_sumpt = new std::vector; - // m_jet_matchtrk_sumpt = new std::vector; - - // m_pv_L1recotruesumpt = new std::vector; - // m_pv_L1recosumpt = new std::vector; m_pv_L1reco = new std::vector; m_pv_L1reco_sum = new std::vector; - // m_pv_L1TP = new std::vector; - // m_pv_L1TPsumpt = new std::vector; + m_pv_L1reco_emu = new std::vector; + m_pv_L1reco_sum_emu = new std::vector; m_pv_MC = new std::vector; - // m_pv_MCChgSumpT = new std::vector; m_MC_lep = new std::vector; - m_2ltrkjet_eta = new std::vector; - m_2ltrkjet_vz = new std::vector; - m_2ltrkjet_phi = new std::vector; - m_2ltrkjet_p = new std::vector; - m_2ltrkjet_pt = new std::vector; - m_2ltrkjet_ntracks = new std::vector; - m_2ltrkjet_nDisplaced = new std::vector; - m_2ltrkjet_nTight = new std::vector; - m_2ltrkjet_nTightDisplaced = new std::vector; - m_2ltrkjet_ntdtrk = new std::vector; - m_trkjet_eta = new std::vector; m_trkjet_vz = new std::vector; m_trkjet_phi = new std::vector; m_trkjet_p = new std::vector; m_trkjet_pt = new std::vector; m_trkjet_ntracks = new std::vector; - m_trkjet_tp_sumpt = new std::vector; - m_trkjet_truetp_sumpt = new std::vector; - - m_2ltrkjetExt_eta = new std::vector; - m_2ltrkjetExt_vz = new std::vector; - m_2ltrkjetExt_phi = new std::vector; - m_2ltrkjetExt_p = new std::vector; - m_2ltrkjetExt_pt = new std::vector; - m_2ltrkjetExt_ntracks = new std::vector; - m_2ltrkjetExt_nDisplaced = new std::vector; - m_2ltrkjetExt_nTight = new std::vector; - m_2ltrkjetExt_nTightDisplaced = new std::vector; - m_2ltrkjetExt_ntdtrk = new std::vector; + m_trkjet_nDisplaced = new std::vector; + m_trkjet_nTight = new std::vector; + m_trkjet_nTightDisplaced = new std::vector; + m_trkjet_ntdtrk = new std::vector; + + m_trkjetem_pt = new std::vector; + m_trkjetem_phi = new std::vector; + m_trkjetem_eta = new std::vector; + m_trkjetem_z = new std::vector; + m_trkjetem_ntracks = new std::vector; + m_trkjetem_nxtracks = new std::vector; + + m_trkfastjet_eta = new std::vector; + m_trkfastjet_vz = new std::vector; + m_trkfastjet_phi = new std::vector; + m_trkfastjet_p = new std::vector; + m_trkfastjet_pt = new std::vector; + m_trkfastjet_ntracks = new std::vector; + m_trkfastjet_tp_sumpt = new std::vector; + m_trkfastjet_truetp_sumpt = new std::vector; m_trkjetExt_eta = new std::vector; m_trkjetExt_vz = new std::vector; @@ -681,12 +769,29 @@ void L1TrackObjectNtupleMaker::beginJob() { m_trkjetExt_p = new std::vector; m_trkjetExt_pt = new std::vector; m_trkjetExt_ntracks = new std::vector; - m_trkjetExt_tp_sumpt = new std::vector; - m_trkjetExt_truetp_sumpt = new std::vector; + m_trkjetExt_nDisplaced = new std::vector; + m_trkjetExt_nTight = new std::vector; + m_trkjetExt_nTightDisplaced = new std::vector; + m_trkjetExt_ntdtrk = new std::vector; + + m_trkjetemExt_pt = new std::vector; + m_trkjetemExt_phi = new std::vector; + m_trkjetemExt_eta = new std::vector; + m_trkjetemExt_z = new std::vector; + m_trkjetemExt_ntracks = new std::vector; + m_trkjetemExt_nxtracks = new std::vector; + + m_trkfastjetExt_eta = new std::vector; + m_trkfastjetExt_vz = new std::vector; + m_trkfastjetExt_phi = new std::vector; + m_trkfastjetExt_p = new std::vector; + m_trkfastjetExt_pt = new std::vector; + m_trkfastjetExt_ntracks = new std::vector; + m_trkfastjetExt_tp_sumpt = new std::vector; + m_trkfastjetExt_truetp_sumpt = new std::vector; // ntuple eventTree = fs->make("eventTree", "Event tree"); - if (SaveAllTracks && (Displaced == "Prompt" || Displaced == "Both")) { eventTree->Branch("trk_pt", &m_trk_pt); eventTree->Branch("trk_eta", &m_trk_eta); @@ -717,11 +822,11 @@ void L1TrackObjectNtupleMaker::beginJob() { eventTree->Branch("trk_matchtp_phi", &m_trk_matchtp_phi); eventTree->Branch("trk_matchtp_z0", &m_trk_matchtp_z0); eventTree->Branch("trk_matchtp_dxy", &m_trk_matchtp_dxy); - // if (TrackingInJets) { - // eventTree->Branch("trk_injet", &m_trk_injet); - // eventTree->Branch("trk_injet_highpt", &m_trk_injet_highpt); - // eventTree->Branch("trk_injet_vhighpt", &m_trk_injet_vhighpt); - // } + eventTree->Branch("trk_gtt_pt", &m_trk_gtt_pt); + eventTree->Branch("trk_gtt_eta", &m_trk_gtt_eta); + eventTree->Branch("trk_gtt_phi", &m_trk_gtt_phi); + eventTree->Branch("trk_gtt_selected_index", &m_trk_selected_index); + eventTree->Branch("trk_gtt_selected_emulation_index", &m_trk_selected_emulation_index); } if (SaveAllTracks && (Displaced == "Displaced" || Displaced == "Both")) { @@ -754,11 +859,11 @@ void L1TrackObjectNtupleMaker::beginJob() { eventTree->Branch("trkExt_matchtp_phi", &m_trkExt_matchtp_phi); eventTree->Branch("trkExt_matchtp_z0", &m_trkExt_matchtp_z0); eventTree->Branch("trkExt_matchtp_dxy", &m_trkExt_matchtp_dxy); - // if (TrackingInJets) { - // eventTree->Branch("trk_injet", &m_trk_injet); - // eventTree->Branch("trk_injet_highpt", &m_trk_injet_highpt); - // eventTree->Branch("trk_injet_vhighpt", &m_trk_injet_vhighpt); - // } + eventTree->Branch("trkExt_gtt_pt", &m_trkExt_gtt_pt); + eventTree->Branch("trkExt_gtt_eta", &m_trkExt_gtt_eta); + eventTree->Branch("trkExt_gtt_phi", &m_trkExt_gtt_phi); + eventTree->Branch("trkExt_gtt_selected_index", &m_trkExt_selected_index); + eventTree->Branch("trkExt_gtt_selected_emulation_index", &m_trkExt_selected_emulation_index); } eventTree->Branch("tp_pt", &m_tp_pt); eventTree->Branch("tp_eta", &m_tp_eta); @@ -773,11 +878,6 @@ void L1TrackObjectNtupleMaker::beginJob() { eventTree->Branch("tp_nstub", &m_tp_nstub); eventTree->Branch("tp_eventid", &m_tp_eventid); eventTree->Branch("tp_charge", &m_tp_charge); - // if (TrackingInJets) { - // eventTree->Branch("tp_injet", &m_tp_injet); - // eventTree->Branch("tp_injet_highpt", &m_tp_injet_highpt); - // eventTree->Branch("tp_injet_vhighpt", &m_tp_injet_vhighpt); - // } if (Displaced == "Prompt" || Displaced == "Both") { eventTree->Branch("matchtrk_pt", &m_matchtrk_pt); @@ -796,11 +896,6 @@ void L1TrackObjectNtupleMaker::beginJob() { eventTree->Branch("matchtrk_dhits", &m_matchtrk_dhits); eventTree->Branch("matchtrk_seed", &m_matchtrk_seed); eventTree->Branch("matchtrk_hitpattern", &m_matchtrk_hitpattern); - // if (TrackingInJets) { - // eventTree->Branch("matchtrk_injet", &m_matchtrk_injet); - // eventTree->Branch("matchtrk_injet_highpt", &m_matchtrk_injet_highpt); - // eventTree->Branch("matchtrk_injet_vhighpt", &m_matchtrk_injet_vhighpt); - // } } if (Displaced == "Displaced" || Displaced == "Both") { @@ -820,11 +915,6 @@ void L1TrackObjectNtupleMaker::beginJob() { eventTree->Branch("matchtrkExt_dhits", &m_matchtrkExt_dhits); eventTree->Branch("matchtrkExt_seed", &m_matchtrkExt_seed); eventTree->Branch("matchtrkExt_hitpattern", &m_matchtrkExt_hitpattern); - // if (TrackingInJets) { - // eventTree->Branch("matchtrk_injet", &m_matchtrk_injet); - // eventTree->Branch("matchtrk_injet_highpt", &m_matchtrk_injet_highpt); - // eventTree->Branch("matchtrk_injet_vhighpt", &m_matchtrk_injet_vhighpt); - // } } if (SaveStubs) { @@ -845,81 +935,95 @@ void L1TrackObjectNtupleMaker::beginJob() { eventTree->Branch("allstub_genuine", &m_allstub_genuine); } - // if (TrackingInJets) { - // eventTree->Branch("jet_eta", &m_jet_eta); - // eventTree->Branch("jet_phi", &m_jet_phi); - // eventTree->Branch("jet_pt", &m_jet_pt); - // eventTree->Branch("jet_tp_sumpt", &m_jet_tp_sumpt); - // eventTree->Branch("jet_trk_sumpt", &m_jet_trk_sumpt); - // eventTree->Branch("jet_matchtrk_sumpt", &m_jet_matchtrk_sumpt); - // } - if (SaveTrackJets) { - // eventTree->Branch("pv_L1recotruesumpt", &m_pv_L1recotruesumpt); - // eventTree->Branch("pv_L1recosumpt", &m_pv_L1recosumpt); - eventTree->Branch("pv_L1reco", &m_pv_L1reco); - eventTree->Branch("pv_L1reco_sum", &m_pv_L1reco_sum); - // eventTree->Branch("pv_L1TP", &m_pv_L1TP); - // eventTree->Branch("pv_L1TPsumpt", &m_pv_L1TPsumpt); - eventTree->Branch("MC_lep", &m_MC_lep); - // eventTree->Branch("pv_MCChgSumpT", &m_pv_MCChgSumpT); - eventTree->Branch("pv_MC", &m_pv_MC); - - eventTree->Branch("gen_pt", &m_gen_pt); - eventTree->Branch("gen_phi", &m_gen_phi); - eventTree->Branch("gen_pdgid", &m_gen_pdgid); - eventTree->Branch("gen_z0", &m_gen_z0); + eventTree->Branch("pv_L1reco", &m_pv_L1reco); + eventTree->Branch("pv_L1reco_sum", &m_pv_L1reco_sum); + eventTree->Branch("pv_L1reco_emu", &m_pv_L1reco_emu); + eventTree->Branch("pv_L1reco_sum_emu", &m_pv_L1reco_sum_emu); + eventTree->Branch("MC_lep", &m_MC_lep); + eventTree->Branch("pv_MC", &m_pv_MC); + eventTree->Branch("gen_pt", &m_gen_pt); + eventTree->Branch("gen_phi", &m_gen_phi); + eventTree->Branch("gen_pdgid", &m_gen_pdgid); + eventTree->Branch("gen_z0", &m_gen_z0); + if (SaveTrackJets) { if (Displaced == "Prompt" || Displaced == "Both") { - eventTree->Branch("2ltrkjet_eta", &m_2ltrkjet_eta); - eventTree->Branch("2ltrkjet_vz", &m_2ltrkjet_vz); - eventTree->Branch("2ltrkjet_p", &m_2ltrkjet_p); - eventTree->Branch("2ltrkjet_pt", &m_2ltrkjet_pt); - eventTree->Branch("2ltrkjet_phi", &m_2ltrkjet_phi); - eventTree->Branch("2ltrkjet_ntracks", &m_2ltrkjet_ntracks); - eventTree->Branch("2ltrkjet_nDisplaced", &m_2ltrkjet_nDisplaced); - eventTree->Branch("2ltrkjet_nTight", &m_2ltrkjet_nTight); - eventTree->Branch("2ltrkjet_nTightDisplaced", &m_2ltrkjet_nTightDisplaced); + eventTree->Branch("trkfastjet_eta", &m_trkfastjet_eta); + eventTree->Branch("trkfastjet_vz", &m_trkfastjet_vz); + eventTree->Branch("trkfastjet_p", &m_trkfastjet_p); + eventTree->Branch("trkfastjet_pt", &m_trkfastjet_pt); + eventTree->Branch("trkfastjet_phi", &m_trkfastjet_phi); + eventTree->Branch("trkfastjet_ntracks", &m_trkfastjet_ntracks); + eventTree->Branch("trkfastjet_truetp_sumpt", m_trkfastjet_truetp_sumpt); + eventTree->Branch("trkjet_eta", &m_trkjet_eta); eventTree->Branch("trkjet_vz", &m_trkjet_vz); eventTree->Branch("trkjet_p", &m_trkjet_p); eventTree->Branch("trkjet_pt", &m_trkjet_pt); eventTree->Branch("trkjet_phi", &m_trkjet_phi); eventTree->Branch("trkjet_ntracks", &m_trkjet_ntracks); - eventTree->Branch("trkjet_truetp_sumpt", m_trkjet_truetp_sumpt); + eventTree->Branch("trkjet_nDisplaced", &m_trkjet_nDisplaced); + eventTree->Branch("trkjet_nTight", &m_trkjet_nTight); + eventTree->Branch("trkjet_nTightDisplaced", &m_trkjet_nTightDisplaced); + + eventTree->Branch("trkjetem_eta", &m_trkjetem_eta); + eventTree->Branch("trkjetem_pt", &m_trkjetem_pt); + eventTree->Branch("trkjetem_phi", &m_trkjetem_phi); + eventTree->Branch("trkjetem_z", &m_trkjetem_z); + eventTree->Branch("trkjetem_ntracks", &m_trkjetem_ntracks); + eventTree->Branch("trkjetem_nxtracks", &m_trkjetem_nxtracks); } if (Displaced == "Displaced" || Displaced == "Both") { - eventTree->Branch("2ltrkjetExt_eta", &m_2ltrkjetExt_eta); - eventTree->Branch("2ltrkjetExt_vz", &m_2ltrkjetExt_vz); - eventTree->Branch("2ltrkjetExt_p", &m_2ltrkjetExt_p); - eventTree->Branch("2ltrkjetExt_pt", &m_2ltrkjetExt_pt); - eventTree->Branch("2ltrkjetExt_phi", &m_2ltrkjetExt_phi); - eventTree->Branch("2ltrkjetExt_ntracks", &m_2ltrkjetExt_ntracks); - eventTree->Branch("2ltrkjetExt_nDisplaced", &m_2ltrkjetExt_nDisplaced); - eventTree->Branch("2ltrkjetExt_nTight", &m_2ltrkjetExt_nTight); - eventTree->Branch("2ltrkjetExt_nTightDisplaced", &m_2ltrkjetExt_nTightDisplaced); + eventTree->Branch("trkfastjetExt_eta", &m_trkfastjetExt_eta); + eventTree->Branch("trkfastjetExt_vz", &m_trkfastjetExt_vz); + eventTree->Branch("trkfastjetExt_p", &m_trkfastjetExt_p); + eventTree->Branch("trkfastjetExt_pt", &m_trkfastjetExt_pt); + eventTree->Branch("trkfastjetExt_phi", &m_trkfastjetExt_phi); + eventTree->Branch("trkfastjetExt_ntracks", &m_trkfastjetExt_ntracks); + eventTree->Branch("trkfastjetExt_truetp_sumpt", m_trkfastjetExt_truetp_sumpt); + eventTree->Branch("trkjetExt_eta", &m_trkjetExt_eta); eventTree->Branch("trkjetExt_vz", &m_trkjetExt_vz); eventTree->Branch("trkjetExt_p", &m_trkjetExt_p); eventTree->Branch("trkjetExt_pt", &m_trkjetExt_pt); eventTree->Branch("trkjetExt_phi", &m_trkjetExt_phi); eventTree->Branch("trkjetExt_ntracks", &m_trkjetExt_ntracks); - eventTree->Branch("trkjetExt_truetp_sumpt", m_trkjetExt_truetp_sumpt); + eventTree->Branch("trkjetExt_nDisplaced", &m_trkjetExt_nDisplaced); + eventTree->Branch("trkjetExt_nTight", &m_trkjetExt_nTight); + eventTree->Branch("trkjetExt_nTightDisplaced", &m_trkjetExt_nTightDisplaced); + + eventTree->Branch("trkjetemExt_eta", &m_trkjetemExt_eta); + eventTree->Branch("trkjetemExt_pt", &m_trkjetemExt_pt); + eventTree->Branch("trkjetemExt_phi", &m_trkjetemExt_phi); + eventTree->Branch("trkjetemExt_z", &m_trkjetemExt_z); + eventTree->Branch("trkjetemExt_ntracks", &m_trkjetemExt_ntracks); + eventTree->Branch("trkjetemExt_nxtracks", &m_trkjetemExt_nxtracks); } } - if (SaveTrackMET) { + if (SaveTrackSums) { eventTree->Branch("trueMET", &trueMET, "trueMET/F"); eventTree->Branch("trueTkMET", &trueTkMET, "trueTkMET/F"); if (Displaced == "Prompt" || Displaced == "Both") { eventTree->Branch("trkMET", &trkMET, "trkMET/F"); + eventTree->Branch("trkMETPhi", &trkMETPhi, "trkMETPhi/F"); + eventTree->Branch("trkMETEmu", &trkMETEmu, "trkMETEmu/F"); + eventTree->Branch("trkMETEmuPhi", &trkMETEmuPhi, "trkMETEmuPhi/F"); eventTree->Branch("trkMHT", &trkMHT, "trkMHT/F"); eventTree->Branch("trkHT", &trkHT, "trkHT/F"); + eventTree->Branch("trkMHTEmu", &trkMHTEmu, "trkMHTEmu/F"); + eventTree->Branch("trkMHTEmuPhi", &trkMHTEmuPhi, "trkMHTEmuPhi/F"); + eventTree->Branch("trkHTEmu", &trkHTEmu, "trkHTEmu/F"); } if (Displaced == "Displaced" || Displaced == "Both") { eventTree->Branch("trkMETExt", &trkMETExt, "trkMETExt/F"); + eventTree->Branch("trkMETPhiExt", &trkMETPhiExt, "trkMETPhiExt/F"); eventTree->Branch("trkMHTExt", &trkMHTExt, "trkMHTExt/F"); eventTree->Branch("trkHTExt", &trkHTExt, "trkHTExt/F"); + eventTree->Branch("trkMHTEmuExt", &trkMHTEmuExt, "trkMHTEmuExt/F"); + eventTree->Branch("trkMHTEmuPhiExt", &trkMHTEmuPhiExt, "trkMHTEmuPhiExt/F"); + eventTree->Branch("trkHTEmuExt", &trkHTEmuExt, "trkHTEmuExt/F"); } } } @@ -967,6 +1071,11 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trk_matchtp_phi->clear(); m_trk_matchtp_z0->clear(); m_trk_matchtp_dxy->clear(); + m_trk_gtt_pt->clear(); + m_trk_gtt_eta->clear(); + m_trk_gtt_phi->clear(); + m_trk_selected_index->clear(); + m_trk_selected_emulation_index->clear(); } if (SaveAllTracks && (Displaced == "Displaced" || Displaced == "Both")) { m_trkExt_pt->clear(); @@ -998,6 +1107,11 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trkExt_matchtp_phi->clear(); m_trkExt_matchtp_z0->clear(); m_trkExt_matchtp_dxy->clear(); + m_trkExt_gtt_pt->clear(); + m_trkExt_gtt_eta->clear(); + m_trkExt_gtt_phi->clear(); + m_trkExt_selected_index->clear(); + m_trkExt_selected_emulation_index->clear(); } m_tp_pt->clear(); m_tp_eta->clear(); @@ -1074,64 +1188,66 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_allstub_genuine->clear(); } - // m_jet_eta->clear(); - // m_jet_phi->clear(); - // m_jet_pt->clear(); - // m_jet_tp_sumpt->clear(); - // m_jet_trk_sumpt->clear(); - // m_jet_matchtrk_sumpt->clear(); - if (SaveTrackJets) { if (Displaced == "Prompt" || Displaced == "Both") { - m_2ltrkjet_eta->clear(); - m_2ltrkjet_pt->clear(); - m_2ltrkjet_vz->clear(); - m_2ltrkjet_phi->clear(); - m_2ltrkjet_p->clear(); - m_2ltrkjet_ntracks->clear(); - m_2ltrkjet_nDisplaced->clear(); - m_2ltrkjet_nTight->clear(); - m_2ltrkjet_nTightDisplaced->clear(); - m_2ltrkjet_ntdtrk->clear(); m_trkjet_eta->clear(); m_trkjet_pt->clear(); m_trkjet_vz->clear(); m_trkjet_phi->clear(); m_trkjet_p->clear(); m_trkjet_ntracks->clear(); - m_trkjet_truetp_sumpt->clear(); - m_trkjet_tp_sumpt->clear(); + m_trkjet_nDisplaced->clear(); + m_trkjet_nTight->clear(); + m_trkjet_nTightDisplaced->clear(); + m_trkjet_ntdtrk->clear(); + m_trkfastjet_eta->clear(); + m_trkfastjet_pt->clear(); + m_trkfastjet_vz->clear(); + m_trkfastjet_phi->clear(); + m_trkfastjet_p->clear(); + m_trkfastjet_ntracks->clear(); + m_trkfastjet_truetp_sumpt->clear(); + m_trkfastjet_tp_sumpt->clear(); + m_trkjetem_eta->clear(); + m_trkjetem_pt->clear(); + m_trkjetem_phi->clear(); + m_trkjetem_z->clear(); + m_trkjetem_ntracks->clear(); + m_trkjetem_nxtracks->clear(); } if (Displaced == "Displaced" || Displaced == "Both") { - m_2ltrkjetExt_eta->clear(); - m_2ltrkjetExt_pt->clear(); - m_2ltrkjetExt_vz->clear(); - m_2ltrkjetExt_phi->clear(); - m_2ltrkjetExt_p->clear(); - m_2ltrkjetExt_ntracks->clear(); - m_2ltrkjetExt_nDisplaced->clear(); - m_2ltrkjetExt_nTight->clear(); - m_2ltrkjetExt_nTightDisplaced->clear(); - m_2ltrkjetExt_ntdtrk->clear(); m_trkjetExt_eta->clear(); m_trkjetExt_pt->clear(); m_trkjetExt_vz->clear(); m_trkjetExt_phi->clear(); m_trkjetExt_p->clear(); m_trkjetExt_ntracks->clear(); - m_trkjetExt_truetp_sumpt->clear(); - m_trkjetExt_tp_sumpt->clear(); + m_trkjetExt_nDisplaced->clear(); + m_trkjetExt_nTight->clear(); + m_trkjetExt_nTightDisplaced->clear(); + m_trkjetExt_ntdtrk->clear(); + m_trkfastjetExt_eta->clear(); + m_trkfastjetExt_pt->clear(); + m_trkfastjetExt_vz->clear(); + m_trkfastjetExt_phi->clear(); + m_trkfastjetExt_p->clear(); + m_trkfastjetExt_ntracks->clear(); + m_trkfastjetExt_truetp_sumpt->clear(); + m_trkfastjetExt_tp_sumpt->clear(); + m_trkjetemExt_eta->clear(); + m_trkjetemExt_pt->clear(); + m_trkjetemExt_phi->clear(); + m_trkjetemExt_z->clear(); + m_trkjetemExt_ntracks->clear(); + m_trkjetemExt_nxtracks->clear(); } - // m_pv_L1recotruesumpt->clear(); - // m_pv_L1recosumpt->clear(); m_pv_L1reco->clear(); m_pv_L1reco_sum->clear(); - // m_pv_L1TPsumpt->clear(); - // m_pv_L1TP->clear(); + m_pv_L1reco_emu->clear(); + m_pv_L1reco_sum_emu->clear(); m_pv_MC->clear(); m_MC_lep->clear(); - // m_pv_MCChgSumpT->clear(); } // ----------------------------------------------------------------------------------------------- @@ -1139,19 +1255,19 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even // ----------------------------------------------------------------------------------------------- // L1 stubs - edm::Handle > > TTStubHandle; + edm::Handle>> TTStubHandle; if (SaveStubs) iEvent.getByToken(ttStubToken_, TTStubHandle); // MC truth association maps - edm::Handle > MCTruthTTClusterHandle; + edm::Handle> MCTruthTTClusterHandle; iEvent.getByToken(ttClusterMCTruthToken_, MCTruthTTClusterHandle); - edm::Handle > MCTruthTTStubHandle; + edm::Handle> MCTruthTTStubHandle; iEvent.getByToken(ttStubMCTruthToken_, MCTruthTTStubHandle); // tracking particles - edm::Handle > TrackingParticleHandle; - edm::Handle > TrackingVertexHandle; + edm::Handle> TrackingParticleHandle; + edm::Handle> TrackingVertexHandle; iEvent.getByToken(TrackingParticleToken_, TrackingParticleHandle); iEvent.getByToken(TrackingVertexToken_, TrackingVertexHandle); @@ -1161,49 +1277,76 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even const TrackerGeometry& tGeom = iSetup.getData(tGeomToken_); //Gen particles - edm::Handle > GenParticleHandle; + edm::Handle> GenParticleHandle; iEvent.getByToken(GenParticleToken_, GenParticleHandle); //Vertex - edm::Handle L1TkPrimaryVertexHandle; - iEvent.getByToken(L1VertexToken_, L1TkPrimaryVertexHandle); + edm::Handle L1PrimaryVertexHandle; + iEvent.getByToken(L1VertexToken_, L1PrimaryVertexHandle); std::vector::const_iterator vtxIter; + edm::Handle L1PrimaryVertexEmuHandle; + iEvent.getByToken(L1VertexEmuToken_, L1PrimaryVertexEmuHandle); + std::vector::const_iterator vtxEmuIter; + // Track jets - edm::Handle > TrackFastJetsHandle; - edm::Handle > TrackFastJetsExtendedHandle; + edm::Handle> TrackFastJetsHandle; + edm::Handle> TrackFastJetsExtendedHandle; edm::Handle TrackJetsHandle; edm::Handle TrackJetsExtendedHandle; + edm::Handle TrackJetsEmuHandle; + edm::Handle TrackJetsExtendedEmuHandle; std::vector::const_iterator jetIter; + std::vector::const_iterator jetemIter; - // Track MET - edm::Handle > L1TkMETHandle; - edm::Handle > L1TkMETExtendedHandle; - edm::Handle > L1TkMHTHandle; - edm::Handle > L1TkMHTExtendedHandle; + // Track Sums + edm::Handle> L1TkMETHandle; + edm::Handle> L1TkMETExtendedHandle; + edm::Handle> L1TkMETEmuHandle; + edm::Handle> L1TkMHTHandle; + edm::Handle> L1TkMHTExtendedHandle; + edm::Handle> L1TkMHTEmuHandle; + edm::Handle> L1TkMHTEmuExtendedHandle; // L1 tracks - edm::Handle > > TTTrackHandle; - edm::Handle > > TTTrackExtendedHandle; - edm::Handle > MCTruthTTTrackHandle; - edm::Handle > MCTruthTTTrackExtendedHandle; - std::vector >::const_iterator iterL1Track; + edm::Handle TTTrackHandle; + edm::Handle TTTrackExtendedHandle; + edm::Handle> MCTruthTTTrackHandle; + edm::Handle> MCTruthTTTrackExtendedHandle; + edm::Handle TTTrackGTTHandle; + edm::Handle TTTrackExtendedGTTHandle; + edm::Handle TTTrackSelectedHandle; + edm::Handle TTTrackSelectedEmulationHandle; + edm::Handle TTTrackExtendedSelectedHandle; + edm::Handle TTTrackExtendedSelectedEmulationHandle; + L1TrackCollection::const_iterator iterL1Track; if (Displaced == "Prompt" || Displaced == "Both") { iEvent.getByToken(TrackFastJetsToken_, TrackFastJetsHandle); iEvent.getByToken(TrackJetsToken_, TrackJetsHandle); + iEvent.getByToken(TrackJetsEmuToken_, TrackJetsEmuHandle); iEvent.getByToken(TrackMETToken_, L1TkMETHandle); + iEvent.getByToken(TrackMETEmuToken_, L1TkMETEmuHandle); iEvent.getByToken(TrackMHTToken_, L1TkMHTHandle); + iEvent.getByToken(TrackMHTEmuToken_, L1TkMHTEmuHandle); iEvent.getByToken(ttTrackToken_, TTTrackHandle); iEvent.getByToken(ttTrackMCTruthToken_, MCTruthTTTrackHandle); + iEvent.getByToken(ttTrackGTTToken_, TTTrackGTTHandle); + iEvent.getByToken(ttTrackSelectedToken_, TTTrackSelectedHandle); + iEvent.getByToken(ttTrackSelectedEmulationToken_, TTTrackSelectedEmulationHandle); } if (Displaced == "Displaced" || Displaced == "Both") { iEvent.getByToken(TrackFastJetsExtendedToken_, TrackFastJetsExtendedHandle); iEvent.getByToken(TrackJetsExtendedToken_, TrackJetsExtendedHandle); + iEvent.getByToken(TrackJetsExtendedEmuToken_, TrackJetsExtendedEmuHandle); iEvent.getByToken(TrackMETExtendedToken_, L1TkMETExtendedHandle); iEvent.getByToken(TrackMHTExtendedToken_, L1TkMHTExtendedHandle); + iEvent.getByToken(TrackMHTEmuExtendedToken_, L1TkMHTEmuExtendedHandle); iEvent.getByToken(ttTrackExtendedToken_, TTTrackExtendedHandle); iEvent.getByToken(ttTrackMCTruthExtendedToken_, MCTruthTTTrackExtendedHandle); + iEvent.getByToken(ttTrackExtendedGTTToken_, TTTrackExtendedGTTHandle); + iEvent.getByToken(ttTrackExtendedSelectedToken_, TTTrackExtendedSelectedHandle); + iEvent.getByToken(ttTrackExtendedSelectedEmulationToken_, TTTrackExtendedSelectedEmulationHandle); } //Loop over gen particles @@ -1221,7 +1364,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even zvtx_gen = genpartIter->vz(); //for gen vertex int id = genpartIter->pdgId(); bool isNeutrino = false; - if ((fabs(id) == 12 || fabs(id) == 14 || fabs(id) == 16)) + if ((std::abs(id) == 12 || std::abs(id) == 14 || std::abs(id) == 16)) isNeutrino = true; if (isNeutrino || id == 1000022) { trueMETx += genpartIter->pt() * cos(genpartIter->phi()); @@ -1256,14 +1399,14 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even continue; // Get the DetSets of the Clusters - edmNew::DetSet > stubs = (*TTStubHandle)[stackDetid]; + edmNew::DetSet> stubs = (*TTStubHandle)[stackDetid]; const GeomDetUnit* det0 = tGeom.idToDetUnit(detid); const auto* theGeomDet = dynamic_cast(det0); const PixelTopology* topol = dynamic_cast(&(theGeomDet->specificTopology())); // loop over stubs for (auto stubIter = stubs.begin(); stubIter != stubs.end(); ++stubIter) { - edm::Ref >, TTStub > tempStubPtr = + edm::Ref>, TTStub> tempStubPtr = edmNew::makeRefTo(TTStubHandle, stubIter); int isBarrel = 0; @@ -1348,7 +1491,8 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even int this_l1track = 0; for (iterL1Track = TTTrackHandle->begin(); iterL1Track != TTTrackHandle->end(); iterL1Track++) { - edm::Ptr > l1track_ptr(TTTrackHandle, this_l1track); + L1TrackPtr l1track_ptr(TTTrackHandle, this_l1track); + L1TrackRef l1track_ref(TTTrackGTTHandle, this_l1track); this_l1track++; float tmp_trk_pt = iterL1Track->momentum().perp(); @@ -1368,12 +1512,12 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even float tmp_trk_chi2 = iterL1Track->chi2(); float tmp_trk_chi2dof = iterL1Track->chi2Red(); - float tmp_trk_chi2rphi = iterL1Track->chi2XY(); - float tmp_trk_chi2rz = iterL1Track->chi2Z(); + float tmp_trk_chi2rphi = iterL1Track->chi2XYRed(); + float tmp_trk_chi2rz = iterL1Track->chi2ZRed(); float tmp_trk_bendchi2 = iterL1Track->stubPtConsistency(); float tmp_trk_MVA1 = -99.9; //update with actual MVA when available - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = iterL1Track->getStubRefs(); int tmp_trk_nstub = (int)stubRefs.size(); int tmp_trk_seed = 0; @@ -1390,9 +1534,9 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even // loop over stubs for (int is = 0; is < tmp_trk_nstub; is++) { //detID of stub - DetId detIdStub = theTrackerGeom->idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); + DetId detIdStub = tGeom.idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); MeasurementPoint coords = stubRefs.at(is)->clusterRef(0)->findAverageLocalCoordinatesCentered(); - const GeomDet* theGeomDet = theTrackerGeom->idToDet(detIdStub); + const GeomDet* theGeomDet = tGeom.idToDet(detIdStub); Global3DPoint posStub = theGeomDet->surface().toGlobal(theGeomDet->topology().localPosition(coords)); double x = posStub.x(); @@ -1401,13 +1545,13 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even int layer = -999999; if (detIdStub.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo->layer(detIdStub)); + layer = static_cast(tTopo.layer(detIdStub)); if (DebugMode) edm::LogVerbatim("Tracklet") << " stub in layer " << layer << " at position x y z = " << x << " " << y << " " << z; tmp_trk_lhits += pow(10, layer - 1); } else if (detIdStub.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo->layer(detIdStub)); + layer = static_cast(tTopo.layer(detIdStub)); if (DebugMode) edm::LogVerbatim("Tracklet") << " stub in disk " << layer << " at position x y z = " << x << " " << y << " " << z; @@ -1517,6 +1661,15 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trk_matchtp_phi->push_back(myTP_phi); m_trk_matchtp_z0->push_back(myTP_z0); m_trk_matchtp_dxy->push_back(myTP_dxy); + + // ---------------------------------------------------------------------------------------------- + // store the index to the selected track or -1 if not selected + // ---------------------------------------------------------------------------------------------- + m_trk_gtt_pt->push_back(l1track_ref->momentum().perp()); + m_trk_gtt_eta->push_back(l1track_ref->momentum().eta()); + m_trk_gtt_phi->push_back(l1track_ref->momentum().phi()); + m_trk_selected_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackSelectedHandle)); + m_trk_selected_emulation_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackSelectedEmulationHandle)); } //end track loop } //end if SaveAllTracks @@ -1531,7 +1684,8 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even int this_l1track = 0; for (iterL1Track = TTTrackExtendedHandle->begin(); iterL1Track != TTTrackExtendedHandle->end(); iterL1Track++) { - edm::Ptr > l1track_ptr(TTTrackExtendedHandle, this_l1track); + L1TrackPtr l1track_ptr(TTTrackExtendedHandle, this_l1track); + L1TrackRef l1track_ref(TTTrackExtendedGTTHandle, this_l1track); this_l1track++; float tmp_trk_pt = iterL1Track->momentum().perp(); @@ -1551,12 +1705,12 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even float tmp_trk_chi2 = iterL1Track->chi2(); float tmp_trk_chi2dof = iterL1Track->chi2Red(); - float tmp_trk_chi2rphi = iterL1Track->chi2XY(); - float tmp_trk_chi2rz = iterL1Track->chi2Z(); + float tmp_trk_chi2rphi = iterL1Track->chi2XYRed(); + float tmp_trk_chi2rz = iterL1Track->chi2ZRed(); float tmp_trk_bendchi2 = iterL1Track->stubPtConsistency(); float tmp_trk_MVA1 = -99.9; //update when actual MVA is available - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = iterL1Track->getStubRefs(); int tmp_trk_nstub = (int)stubRefs.size(); int tmp_trk_seed = 0; @@ -1573,9 +1727,9 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even // loop over stubs for (int is = 0; is < tmp_trk_nstub; is++) { //detID of stub - DetId detIdStub = theTrackerGeom->idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); + DetId detIdStub = tGeom.idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); MeasurementPoint coords = stubRefs.at(is)->clusterRef(0)->findAverageLocalCoordinatesCentered(); - const GeomDet* theGeomDet = theTrackerGeom->idToDet(detIdStub); + const GeomDet* theGeomDet = tGeom.idToDet(detIdStub); Global3DPoint posStub = theGeomDet->surface().toGlobal(theGeomDet->topology().localPosition(coords)); double x = posStub.x(); @@ -1584,13 +1738,13 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even int layer = -999999; if (detIdStub.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo->layer(detIdStub)); + layer = static_cast(tTopo.layer(detIdStub)); if (DebugMode) edm::LogVerbatim("Tracklet") << " stub in layer " << layer << " at position x y z = " << x << " " << y << " " << z; tmp_trk_lhits += pow(10, layer - 1); } else if (detIdStub.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo->layer(detIdStub)); + layer = static_cast(tTopo.layer(detIdStub)); if (DebugMode) edm::LogVerbatim("Tracklet") << " stub in disk " << layer << " at position x y z = " << x << " " << y << " " << z; @@ -1700,6 +1854,16 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even m_trkExt_matchtp_phi->push_back(myTP_phi); m_trkExt_matchtp_z0->push_back(myTP_z0); m_trkExt_matchtp_dxy->push_back(myTP_dxy); + + // ---------------------------------------------------------------------------------------------- + // store the index to the selected track or -1 if not selected + // ---------------------------------------------------------------------------------------------- + m_trkExt_gtt_pt->push_back(l1track_ref->momentum().perp()); + m_trkExt_gtt_eta->push_back(l1track_ref->momentum().eta()); + m_trkExt_gtt_phi->push_back(l1track_ref->momentum().phi()); + m_trkExt_selected_index->push_back(getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedHandle)); + m_trkExt_selected_emulation_index->push_back( + getSelectedTrackIndex(l1track_ref, TTTrackExtendedSelectedEmulationHandle)); } //end track loop } //end if SaveAllTracks (displaced) @@ -1747,7 +1911,6 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even // ---------------------------------------------------------------------------------------------- // get d0/z0 propagated back to the IP - float tmp_tp_t = tan(2.0 * atan(1.0) - 2.0 * atan(exp(-tmp_tp_eta))); float delx = -tmp_tp_vx; float dely = -tmp_tp_vy; @@ -1762,7 +1925,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even float tmp_tp_rp = sqrt(tmp_tp_x0p * tmp_tp_x0p + tmp_tp_y0p * tmp_tp_y0p); float tmp_tp_d0 = tmp_tp_charge * tmp_tp_rp - (1. / (2. * K)); tmp_tp_d0 = tmp_tp_d0 * (-1); //fix d0 sign - static double pi = 4.0 * atan(1.0); + const double pi = 4.0 * atan(1.0); float delphi = tmp_tp_phi - atan2(-K * tmp_tp_x0p, K * tmp_tp_y0p); if (delphi < -pi) delphi += 2.0 * pi; @@ -1797,7 +1960,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even continue; } - std::vector >, TTStub > > + std::vector>, TTStub>> theStubRefs = MCTruthTTStubHandle->findTTStubRefs(tp_ptr); int nStubTP = (int)theStubRefs.size(); @@ -1808,9 +1971,9 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even int layer = -1; if (detid.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo->layer(detid)) - 1; //fill in array as entries 0-5 + layer = static_cast(tTopo.layer(detid)) - 1; //fill in array as entries 0-5 } else if (detid.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo->layer(detid)) + 5; //fill in array as entries 6-10 + layer = static_cast(tTopo.layer(detid)) + 5; //fill in array as entries 6-10 } //treat genuine stubs separately (==2 is genuine, ==1 is not) @@ -1874,7 +2037,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even // ---------------------------------------------------------------------------------------------- // look for L1 tracks (prompt) matched to the tracking particle if (Displaced == "Prompt" || Displaced == "Both") { - std::vector > > matchedTracks = + std::vector>> matchedTracks = MCTruthTTTrackHandle->findTTTrackPtrs(tp_ptr); int nMatch = 0; @@ -1923,7 +2086,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even edm::LogVerbatim("Tracklet") << " (loose genuine!) "; } - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = matchedTracks.at(it)->getStubRefs(); int tmp_trk_nstub = stubRefs.size(); @@ -1992,8 +2155,8 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even tmp_matchtrk_chi2 = matchedTracks.at(i_track)->chi2(); tmp_matchtrk_chi2dof = matchedTracks.at(i_track)->chi2Red(); - tmp_matchtrk_chi2rphi = matchedTracks.at(i_track)->chi2XY(); - tmp_matchtrk_chi2rz = matchedTracks.at(i_track)->chi2Z(); + tmp_matchtrk_chi2rphi = matchedTracks.at(i_track)->chi2XYRed(); + tmp_matchtrk_chi2rz = matchedTracks.at(i_track)->chi2ZRed(); tmp_matchtrk_bendchi2 = matchedTracks.at(i_track)->stubPtConsistency(); tmp_matchtrk_MVA1 = -99.9; //update when MVA is available tmp_matchtrk_nstub = (int)matchedTracks.at(i_track)->getStubRefs().size(); @@ -2004,18 +2167,18 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even tmp_matchtrk_dhits = 0; tmp_matchtrk_lhits = 0; - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = matchedTracks.at(i_track)->getStubRefs(); int tmp_nstub = stubRefs.size(); for (int is = 0; is < tmp_nstub; is++) { - DetId detIdStub = theTrackerGeom->idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); + DetId detIdStub = tGeom.idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); int layer = -999999; if (detIdStub.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo->layer(detIdStub)); + layer = static_cast(tTopo.layer(detIdStub)); tmp_matchtrk_lhits += pow(10, layer - 1); } else if (detIdStub.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo->layer(detIdStub)); + layer = static_cast(tTopo.layer(detIdStub)); tmp_matchtrk_dhits += pow(10, layer - 1); } } @@ -2044,8 +2207,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even // ---------------------------------------------------------------------------------------------- // look for L1 tracks (extended) matched to the tracking particle if (Displaced == "Displaced" || Displaced == "Both") { - std::vector > > matchedTracks = - MCTruthTTTrackExtendedHandle->findTTTrackPtrs(tp_ptr); + L1TrackPtrCollection matchedTracks = MCTruthTTTrackExtendedHandle->findTTTrackPtrs(tp_ptr); int nMatch = 0; int i_track = -1; @@ -2094,7 +2256,7 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even edm::LogVerbatim("Tracklet") << " (loose genuine!) "; } - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = matchedTracks.at(it)->getStubRefs(); int tmp_trk_nstub = stubRefs.size(); @@ -2165,8 +2327,8 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even tmp_matchtrkExt_chi2 = matchedTracks.at(i_track)->chi2(); tmp_matchtrkExt_chi2dof = matchedTracks.at(i_track)->chi2Red(); - tmp_matchtrkExt_chi2rphi = matchedTracks.at(i_track)->chi2XY(); - tmp_matchtrkExt_chi2rz = matchedTracks.at(i_track)->chi2Z(); + tmp_matchtrkExt_chi2rphi = matchedTracks.at(i_track)->chi2XYRed(); + tmp_matchtrkExt_chi2rz = matchedTracks.at(i_track)->chi2ZRed(); tmp_matchtrkExt_bendchi2 = matchedTracks.at(i_track)->stubPtConsistency(); tmp_matchtrkExt_MVA = -99.9; //update when MVA is available tmp_matchtrkExt_nstub = (int)matchedTracks.at(i_track)->getStubRefs().size(); @@ -2177,18 +2339,18 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even tmp_matchtrkExt_dhits = 0; tmp_matchtrkExt_lhits = 0; - std::vector >, TTStub > > + std::vector>, TTStub>> stubRefs = matchedTracks.at(i_track)->getStubRefs(); int tmp_nstub = stubRefs.size(); for (int is = 0; is < tmp_nstub; is++) { - DetId detIdStub = theTrackerGeom->idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); + DetId detIdStub = tGeom.idToDet((stubRefs.at(is)->clusterRef(0))->getDetId())->geographicalId(); int layer = -999999; if (detIdStub.subdetId() == StripSubdetector::TOB) { - layer = static_cast(tTopo->layer(detIdStub)); + layer = static_cast(tTopo.layer(detIdStub)); tmp_matchtrkExt_lhits += pow(10, layer - 1); } else if (detIdStub.subdetId() == StripSubdetector::TID) { - layer = static_cast(tTopo->layer(detIdStub)); + layer = static_cast(tTopo.layer(detIdStub)); tmp_matchtrkExt_dhits += pow(10, layer - 1); } } @@ -2215,106 +2377,169 @@ void L1TrackObjectNtupleMaker::analyze(const edm::Event& iEvent, const edm::Even } //end loop tracking particles trueTkMET = sqrt(trueTkMETx * trueTkMETx + trueTkMETy * trueTkMETy); - if (SaveTrackMET) { + if (L1PrimaryVertexHandle.isValid()) { + for (vtxIter = L1PrimaryVertexHandle->begin(); vtxIter != L1PrimaryVertexHandle->end(); ++vtxIter) { + m_pv_L1reco->push_back(vtxIter->z0()); + m_pv_L1reco_sum->push_back(vtxIter->pt()); + } + } else + edm::LogWarning("DataNotFound") << "\nWarning: L1PrimaryVertexHandle not found" << std::endl; + + if (L1PrimaryVertexEmuHandle.isValid()) { + for (vtxEmuIter = L1PrimaryVertexEmuHandle->begin(); vtxEmuIter != L1PrimaryVertexEmuHandle->end(); ++vtxEmuIter) { + m_pv_L1reco_emu->push_back(vtxEmuIter->z0()); + m_pv_L1reco_sum_emu->push_back(vtxEmuIter->pt()); + } + } else + edm::LogWarning("DataNotFound") << "\nWarning: L1PrimaryVertexEmuHandle not found" << std::endl; + + if (SaveTrackSums) { if (Displaced == "Prompt" || Displaced == "Both") { if (L1TkMETHandle.isValid()) { trkMET = L1TkMETHandle->begin()->etMiss(); + trkMETPhi = L1TkMETHandle->begin()->p4().phi(); + } else { + edm::LogWarning("DataNotFound") << "\nWarning: tkMET handle not found" << std::endl; + } + + if (L1TkMETEmuHandle.isValid()) { + trkMETEmu = L1TkMETEmuHandle->begin()->hwPt() * l1tmetemu::kStepMET; + trkMETEmuPhi = L1TkMETEmuHandle->begin()->hwPhi() * l1tmetemu::kStepMETPhi - M_PI; } else { - edm::LogWarning("DataNotFound") << "\nWarning: tkMET handle not found in the event" << std::endl; + edm::LogWarning("DataNotFound") << "\nWarning: tkMETEmu handle not found" << std::endl; } if (L1TkMHTHandle.isValid()) { trkMHT = L1TkMHTHandle->begin()->EtMiss(); trkHT = L1TkMHTHandle->begin()->etTotal(); - } else { - edm::LogWarning("DataNotFound") << "\nWarning: tkMHT handle not found in the event" << std::endl; - } + } else + edm::LogWarning("DataNotFound") << "\nWarning: tkMHT handle not found" << std::endl; + + if (L1TkMHTEmuHandle.isValid()) { + trkMHTEmu = L1TkMHTEmuHandle->begin()->p4().energy() * l1tmhtemu::kStepMHT; + trkHTEmu = L1TkMHTEmuHandle->begin()->hwPt() * l1tmhtemu::kStepPt; + trkMHTEmuPhi = L1TkMHTEmuHandle->begin()->hwPhi() * l1tmhtemu::kStepMHTPhi - M_PI; + } else + edm::LogWarning("DataNotFound") << "\nWarning: tkMHTEmu handle not found" << std::endl; } //end prompt-track quantities if (Displaced == "Displaced" || Displaced == "Both") { if (L1TkMETExtendedHandle.isValid()) { trkMETExt = L1TkMETExtendedHandle->begin()->etMiss(); + trkMETPhiExt = L1TkMETExtendedHandle->begin()->p4().phi(); } else { - edm::LogWarning("DataNotFound") << "\nWarning: tkMETExtended handle not found in the event" << std::endl; + edm::LogWarning("DataNotFound") << "\nWarning: tkMETExtended handle not found" << std::endl; } if (L1TkMHTExtendedHandle.isValid()) { trkMHTExt = L1TkMHTExtendedHandle->begin()->EtMiss(); trkHTExt = L1TkMHTExtendedHandle->begin()->etTotal(); } else { - edm::LogWarning("DataNotFound") << "\nWarning: tkMHTExtended handle not found in the event" << std::endl; + edm::LogWarning("DataNotFound") << "\nWarning: tkMHTExtended handle not found" << std::endl; } + + if (L1TkMHTEmuExtendedHandle.isValid()) { + trkMHTEmuExt = L1TkMHTEmuExtendedHandle->begin()->p4().energy() * l1tmhtemu::kStepMHT; + trkHTEmuExt = L1TkMHTEmuExtendedHandle->begin()->hwPt() * l1tmhtemu::kStepPt; + trkMHTEmuPhiExt = L1TkMHTEmuExtendedHandle->begin()->hwPhi() * l1tmhtemu::kStepMHTPhi - M_PI; + } else + edm::LogWarning("DataNotFound") << "\nWarning: tkMHTEmuExtended handle not found" << std::endl; } //end displaced-track quantities } if (SaveTrackJets) { if (TrackFastJetsHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) { for (jetIter = TrackFastJetsHandle->begin(); jetIter != TrackFastJetsHandle->end(); ++jetIter) { + m_trkfastjet_vz->push_back(jetIter->jetVtx()); + m_trkfastjet_ntracks->push_back(jetIter->trkPtrs().size()); + m_trkfastjet_phi->push_back(jetIter->phi()); + m_trkfastjet_eta->push_back(jetIter->eta()); + m_trkfastjet_pt->push_back(jetIter->pt()); + m_trkfastjet_p->push_back(jetIter->p()); + } + } + if (TrackFastJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { + for (jetIter = TrackFastJetsExtendedHandle->begin(); jetIter != TrackFastJetsExtendedHandle->end(); ++jetIter) { + m_trkfastjetExt_vz->push_back(jetIter->jetVtx()); + m_trkfastjetExt_ntracks->push_back(jetIter->trkPtrs().size()); + m_trkfastjetExt_phi->push_back(jetIter->phi()); + m_trkfastjetExt_eta->push_back(jetIter->eta()); + m_trkfastjetExt_pt->push_back(jetIter->pt()); + m_trkfastjetExt_p->push_back(jetIter->p()); + } + } + if (!TrackJetsHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) + edm::LogWarning("DataNotFound") << "\nWarning: TrackJetsHandle not found" << std::endl; + if (!TrackJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) + edm::LogWarning("DataNotFound") << "\nWarning: TrackJetsExtendedHandle not found" << std::endl; + if (TrackJetsHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) { + for (jetIter = TrackJetsHandle->begin(); jetIter != TrackJetsHandle->end(); ++jetIter) { m_trkjet_vz->push_back(jetIter->jetVtx()); - m_trkjet_ntracks->push_back(jetIter->trkPtrs().size()); + m_trkjet_ntracks->push_back(jetIter->ntracks()); m_trkjet_phi->push_back(jetIter->phi()); m_trkjet_eta->push_back(jetIter->eta()); m_trkjet_pt->push_back(jetIter->pt()); m_trkjet_p->push_back(jetIter->p()); + m_trkjet_nDisplaced->push_back(jetIter->nDisptracks()); + m_trkjet_nTight->push_back(jetIter->nTighttracks()); + m_trkjet_nTightDisplaced->push_back(jetIter->nTightDisptracks()); } } - if (TrackFastJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { - for (jetIter = TrackFastJetsExtendedHandle->begin(); jetIter != TrackFastJetsExtendedHandle->end(); ++jetIter) { + if (TrackJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { + for (jetIter = TrackJetsExtendedHandle->begin(); jetIter != TrackJetsExtendedHandle->end(); ++jetIter) { m_trkjetExt_vz->push_back(jetIter->jetVtx()); - m_trkjetExt_ntracks->push_back(jetIter->trkPtrs().size()); + m_trkjetExt_ntracks->push_back(jetIter->ntracks()); m_trkjetExt_phi->push_back(jetIter->phi()); m_trkjetExt_eta->push_back(jetIter->eta()); m_trkjetExt_pt->push_back(jetIter->pt()); m_trkjetExt_p->push_back(jetIter->p()); - } - } - if (!TrackJetsHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) { - edm::LogWarning("DataNotFound") << "\nWarning: TrackJetsHandle not found in the event" << std::endl; - } - if (!TrackJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { - edm::LogWarning("DataNotFound") << "\nWarning: TrackJetsExtendedHandle not found in the event" << std::endl; - } - if (TrackJetsHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) { - for (jetIter = TrackJetsHandle->begin(); jetIter != TrackJetsHandle->end(); ++jetIter) { - m_2ltrkjet_vz->push_back(jetIter->jetVtx()); - m_2ltrkjet_ntracks->push_back(jetIter->ntracks()); - m_2ltrkjet_phi->push_back(jetIter->phi()); - m_2ltrkjet_eta->push_back(jetIter->eta()); - m_2ltrkjet_pt->push_back(jetIter->pt()); - m_2ltrkjet_p->push_back(jetIter->p()); - m_2ltrkjet_nDisplaced->push_back(jetIter->nDisptracks()); - m_2ltrkjet_nTight->push_back(jetIter->nTighttracks()); - m_2ltrkjet_nTightDisplaced->push_back(jetIter->nTightDisptracks()); + m_trkjetExt_nDisplaced->push_back(jetIter->nDisptracks()); + m_trkjetExt_nTight->push_back(jetIter->nTighttracks()); + m_trkjetExt_nTightDisplaced->push_back(jetIter->nTightDisptracks()); } } - if (TrackJetsExtendedHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { - for (jetIter = TrackJetsExtendedHandle->begin(); jetIter != TrackJetsExtendedHandle->end(); ++jetIter) { - m_2ltrkjetExt_vz->push_back(jetIter->jetVtx()); - m_2ltrkjetExt_ntracks->push_back(jetIter->ntracks()); - m_2ltrkjetExt_phi->push_back(jetIter->phi()); - m_2ltrkjetExt_eta->push_back(jetIter->eta()); - m_2ltrkjetExt_pt->push_back(jetIter->pt()); - m_2ltrkjetExt_p->push_back(jetIter->p()); - m_2ltrkjetExt_nDisplaced->push_back(jetIter->nDisptracks()); - m_2ltrkjetExt_nTight->push_back(jetIter->nTighttracks()); - m_2ltrkjetExt_nTightDisplaced->push_back(jetIter->nTightDisptracks()); + if (!TrackJetsEmuHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) + edm::LogWarning("DataNotFound") << "\nWarning: TrackJetsEmuHandle not found" << std::endl; + else if (TrackJetsEmuHandle.isValid() && (Displaced == "Prompt" || Displaced == "Both")) { + for (jetemIter = TrackJetsEmuHandle->begin(); jetemIter != TrackJetsEmuHandle->end(); ++jetemIter) { + m_trkjetem_ntracks->push_back(jetemIter->nt()); + m_trkjetem_phi->push_back(jetemIter->glbphi()); + m_trkjetem_eta->push_back(jetemIter->glbeta()); + m_trkjetem_pt->push_back(jetemIter->pt()); + m_trkjetem_z->push_back(jetemIter->z0()); + m_trkjetem_nxtracks->push_back(jetemIter->xt()); } } - - if (L1TkPrimaryVertexHandle.isValid()) { - for (vtxIter = L1TkPrimaryVertexHandle->begin(); vtxIter != L1TkPrimaryVertexHandle->end(); ++vtxIter) { - m_pv_L1reco->push_back(vtxIter->z0()); - m_pv_L1reco_sum->push_back(vtxIter->pt()); + if (!TrackJetsExtendedEmuHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) + edm::LogWarning("DataNotFound") << "\nWarning: TrackJetsExtendedEmuHandle not found" << std::endl; + else if (TrackJetsExtendedEmuHandle.isValid() && (Displaced == "Displaced" || Displaced == "Both")) { + for (jetemIter = TrackJetsExtendedEmuHandle->begin(); jetemIter != TrackJetsExtendedEmuHandle->end(); + ++jetemIter) { + m_trkjetemExt_ntracks->push_back(jetemIter->nt()); + m_trkjetemExt_phi->push_back(jetemIter->glbphi()); + m_trkjetemExt_eta->push_back(jetemIter->glbeta()); + m_trkjetemExt_pt->push_back(jetemIter->pt()); + m_trkjetemExt_z->push_back(jetemIter->z0()); + m_trkjetemExt_nxtracks->push_back(jetemIter->xt()); } - } else { - edm::LogWarning("DataNotFound") << "\nWarning: L1TkPrimaryVertexHandle not found in the event" << std::endl; } } // end track jets eventTree->Fill(); } // end of analyze() +int L1TrackObjectNtupleMaker::getSelectedTrackIndex(const L1TrackRef& trackRef, + const edm::Handle& selectedTrackRefs) const { + auto it = std::find_if(selectedTrackRefs->begin(), selectedTrackRefs->end(), [&trackRef](L1TrackRef const& obj) { + return obj == trackRef; + }); + if (it != selectedTrackRefs->end()) + return std::distance(selectedTrackRefs->begin(), it); + else + return -1; +} + /////////////////////////// // DEFINE THIS AS A PLUG-IN DEFINE_FWK_MODULE(L1TrackObjectNtupleMaker); diff --git a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py index de89c811c94b2..3f383d968ab36 100644 --- a/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py +++ b/L1Trigger/L1TTrackMatch/test/L1TrackObjectNtupleMaker_cfg.py @@ -9,12 +9,12 @@ ############################################################ # edit options here ############################################################ -L1TRK_INST ="L1TrackJets" ### if not in input DIGRAW then we make them in the above step +L1TRK_INST ="MyL1TrackJets" ### if not in input DIGRAW then we make them in the above step process = cms.Process(L1TRK_INST) -L1TRKALGO = 'HYBRID' #baseline, 4par fit +#L1TRKALGO = 'HYBRID' #baseline, 4par fit # L1TRKALGO = 'HYBRID_DISPLACED' #extended, 5par fit -#L1TRKALGO = 'HYBRID_PROMPTANDDISP' +L1TRKALGO = 'HYBRID_PROMPTANDDISP' DISPLACED = '' @@ -25,22 +25,33 @@ process.load('Configuration.StandardSequences.Services_cff') process.load('Configuration.EventContent.EventContent_cff') process.load('Configuration.StandardSequences.MagneticField_cff') -process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') -process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.Geometry.GeometryExtended2026D77Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D77_cff') process.load('Configuration.StandardSequences.EndOfProcess_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic', '') +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.MessageLogger.cerr.INFO.limit = cms.untracked.int32(0) # default: 0 + ############################################################ # input and output ############################################################ -process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(100)) +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(10)) readFiles = cms.untracked.vstring( - "/store/relval/CMSSW_11_1_0_pre2/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU25ns_110X_mcRun4_realistic_v2_2026D49PU200-v1/20000/F7BF4AED-51F1-9D47-B86D-6C3DDA134AB9.root" + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/c6df2819-ed05-4b98-8f92-81b7d1b1092e.root', + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/3f476d95-1ef7-4be6-977b-6bcd1a7c5678.root', + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/68d651da-4cb7-4bf4-b002-66aecc57a2bc.root', + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/db0e0ce2-4c5a-4988-9dbd-52066e40b9d2.root', + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/257a9712-0a96-47b7-897e-f5d980605e46.root', + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/bee31399-8559-4243-b539-cae1ea897def.root', + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/24629540-2377-4168-9ae5-518ddd4c43a9.root', + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/e31ba8f0-332a-4a1a-8bc0-91a12a5fe3db.root', + '/store/relval/CMSSW_12_3_0_pre4/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU_123X_mcRun4_realistic_v3_2026D77PU200-v1/2580000/17902198-4db6-4fcc-9e8c-787991b4db32.root', ) secFiles = cms.untracked.vstring() @@ -50,68 +61,116 @@ duplicateCheckMode = cms.untracked.string('noDuplicateCheck'), ) +process.source.inputCommands = cms.untracked.vstring("keep *","drop l1tTkPrimaryVertexs_L1TkPrimaryVertex__*") +process.Timing = cms.Service("Timing", + summaryOnly = cms.untracked.bool(False), + useJobReport = cms.untracked.bool(True) +) -process.TFileService = cms.Service("TFileService", fileName = cms.string('CheckingJets_CMSSW11_CMS.root'), closeFileFast = cms.untracked.bool(True)) +process.TFileService = cms.Service("TFileService", fileName = cms.string('GTTObjects_ttbar200PU.root'), closeFileFast = cms.untracked.bool(True)) ############################################################ # L1 tracking: remake stubs? ############################################################ -#process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') -#from L1Trigger.TrackTrigger.TTStubAlgorithmRegister_cfi import * -#process.load("SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff") +process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') +from L1Trigger.TrackTrigger.TTStubAlgorithmRegister_cfi import * +process.load("SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff") -#from SimTracker.TrackTriggerAssociation.TTClusterAssociation_cfi import * -#TTClusterAssociatorFromPixelDigis.digiSimLinks = cms.InputTag("simSiPixelDigis","Tracker") +from SimTracker.TrackTriggerAssociation.TTClusterAssociation_cfi import * +TTClusterAssociatorFromPixelDigis.digiSimLinks = cms.InputTag("simSiPixelDigis","Tracker") -#process.TTClusterStub = cms.Path(process.TrackTriggerClustersStubs) -#process.TTClusterStubTruth = cms.Path(process.TrackTriggerAssociatorClustersStubs) +process.TTClusterStub = cms.Path(process.TrackTriggerClustersStubs) +process.TTClusterStubTruth = cms.Path(process.TrackTriggerAssociatorClustersStubs) +# DTC emulation +process.load('L1Trigger.TrackerDTC.ProducerES_cff') +process.load('L1Trigger.TrackerDTC.ProducerED_cff') +process.dtc = cms.Path(process.TrackerDTCProducer)#*process.TrackerDTCAnalyzer) + process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") +process.load("L1Trigger.L1TTrackMatch.L1TrackSelectionProducer_cfi") process.load("L1Trigger.L1TTrackMatch.L1TrackJetProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1GTTInputProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1TrackJetEmulationProducer_cfi") process.load("L1Trigger.L1TTrackMatch.L1TrackFastJetProducer_cfi") process.load("L1Trigger.L1TTrackMatch.L1TrackerEtMissProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1TrackerEtMissEmulatorProducer_cfi") process.load("L1Trigger.L1TTrackMatch.L1TkHTMissProducer_cfi") +process.load("L1Trigger.L1TTrackMatch.L1TkHTMissEmulatorProducer_cfi") +process.load('L1Trigger.VertexFinder.VertexProducer_cff') + + +############################################################ +# Primary vertex +############################################################ +process.L1VertexFinder = process.VertexProducer.clone() +process.pPV = cms.Path(process.L1VertexFinder) +process.L1VertexFinderEmulator = process.VertexProducer.clone() +process.L1VertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" +process.L1VertexFinderEmulator.l1TracksInputTag = cms.InputTag("L1GTTInputProducer","Level1TTTracksConverted") +process.L1VertexFinderEmulator.VertexReconstruction.VxMinTrackPt = cms.double(0.0) +process.pPVemu = cms.Path(process.L1VertexFinderEmulator) + +process.L1TrackFastJets.L1PrimaryVertexTag = cms.InputTag("L1VertexFinder", "l1vertices") +process.L1TrackFastJetsExtended.L1PrimaryVertexTag = cms.InputTag("L1VertexFinder", "l1vertices") +process.L1TrackJets.L1PVertexCollection = cms.InputTag("L1VertexFinder", "l1vertices") +process.L1TrackJetsExtended.L1PVertexCollection = cms.InputTag("L1VertexFinder", "l1vertices") +process.L1TrackerEtMiss.L1VertexInputTag = cms.InputTag("L1VertexFinder", "l1vertices") +process.L1TrackerHTMiss.L1VertexInputTag = cms.InputTag("L1VertexFinder", "l1vertices") +process.L1TrackerEtMissExtended.L1VertexInputTag = cms.InputTag("L1VertexFinder", "l1vertices") +process.L1TrackerHTMissExtended.L1VertexInputTag = cms.InputTag("L1VertexFinder", "l1vertices") +process.L1TrackerEmuEtMiss.L1VertexInputTag = cms.InputTag("L1VertexFinderEmulator", "l1verticesEmulation") # HYBRID: prompt tracking if (L1TRKALGO == 'HYBRID'): - process.TTTracksEmulation = cms.Path(process.L1HybridTracks) - process.TTTracksEmulationWithTruth = cms.Path(process.L1HybridTracksWithAssociators) + process.TTTracksEmu = cms.Path(process.L1HybridTracks) + process.TTTracksEmuWithTruth = cms.Path(process.L1HybridTracksWithAssociators) + process.pL1TrackSelection = cms.Path(process.L1TrackSelectionProducer) process.pL1TrackJets = cms.Path(process.L1TrackJets) process.pL1TrackFastJets=cms.Path(process.L1TrackFastJets) + process.pL1GTTInput = cms.Path(process.L1GTTInputProducer) + process.pL1TrackJetsEmu = cms.Path(process.L1TrackJetsEmulation) process.pTkMET = cms.Path(process.L1TrackerEtMiss) + process.pTkMETEmu = cms.Path(process.L1TrackerEmuEtMiss) process.pTkMHT = cms.Path(process.L1TrackerHTMiss) + process.pTkMHTEmulator = cms.Path(process.L1TrackerEmuHTMiss) DISPLACED = 'Prompt' # HYBRID: extended tracking elif (L1TRKALGO == 'HYBRID_DISPLACED'): - process.TTTracksEmulation = cms.Path(process.L1ExtendedHybridTracks) - process.TTTracksEmulationWithTruth = cms.Path(process.L1ExtendedHybridTracksWithAssociators) + process.TTTracksEmu = cms.Path(process.L1ExtendedHybridTracks) + process.TTTracksEmuWithTruth = cms.Path(process.L1ExtendedHybridTracksWithAssociators) + process.pL1TrackSelection = cms.Path(process.L1TrackSelectionProducerExtended) process.pL1TrackJets = cms.Path(process.L1TrackJetsExtended) process.pL1TrackFastJets = cms.Path(process.L1TrackFastJetsExtended) + process.pL1GTTInput = cms.Path(process.L1GTTInputProducerExtended) + process.pL1TrackJetsEmu = cms.Path(process.L1TrackJetsExtendedEmulation) process.pTkMET = cms.Path(process.L1TrackerEtMissExtended) + #process.pTkMETEmu = cms.Path(process.L1TrackerEmuEtMissExtended) #Doesn't exist process.pTkMHT = cms.Path(process.L1TrackerHTMissExtended) + process.pTkMHTEmulator = cms.Path(process.L1TrackerEmuHTMissExtended) DISPLACED = 'Displaced'# # HYBRID: extended tracking elif (L1TRKALGO == 'HYBRID_PROMPTANDDISP'): - process.TTTracksEmulation = cms.Path(process.L1PromptExtendedHybridTracks) - process.TTTracksEmulationWithTruth = cms.Path(process.L1PromptExtendedHybridTracksWithAssociators) + process.TTTracksEmu = cms.Path(process.L1PromptExtendedHybridTracks) + process.TTTracksEmuWithTruth = cms.Path(process.L1PromptExtendedHybridTracksWithAssociators) + process.pL1TrackSelection = cms.Path(process.L1TrackSelectionProducer*process.L1TrackSelectionProducerExtended) process.pL1TrackJets = cms.Path(process.L1TrackJets*process.L1TrackJetsExtended) process.pL1TrackFastJets = cms.Path(process.L1TrackFastJets*process.L1TrackFastJetsExtended) + process.pL1GTTInput = cms.Path(process.L1GTTInputProducer*process.L1GTTInputProducerExtended) + process.pL1TrackJetsEmu = cms.Path(process.L1TrackJetsEmulation*process.L1TrackJetsExtendedEmulation) process.pTkMET = cms.Path(process.L1TrackerEtMiss*process.L1TrackerEtMissExtended) + process.pTkMETEmu = cms.Path(process.L1TrackerEmuEtMiss) process.pTkMHT = cms.Path(process.L1TrackerHTMiss*process.L1TrackerHTMissExtended) + process.pTkMHTEmulator = cms.Path(process.L1TrackerEmuHTMiss*process.L1TrackerEmuHTMissExtended) DISPLACED = 'Both' -############################################################ -# Primary vertex -############################################################ -process.load('L1Trigger.VertexFinder.VertexProducer_cff') -process.pPV = cms.Path(process.VertexProducer) ############################################################ @@ -127,7 +186,7 @@ process.L1TrackNtuple = cms.EDAnalyzer('L1TrackObjectNtupleMaker', MyProcess = cms.int32(1), DebugMode = cms.bool(False), # printout lots of debug statements - SaveAllTracks = cms.bool(True), # save *all* L1 tracks, not just truth matched to primary particle + SaveAllTracks = cms.bool(True), # save *all* L1 tracks, not just truth matched to primary particle SaveStubs = cms.bool(False), # save some info for *all* stubs Displaced = cms.string(DISPLACED),# "Prompt", "Displaced", "Both" L1Tk_minNStub = cms.int32(4), # L1 tracks with >= 4 stubs @@ -136,31 +195,41 @@ TP_minPt = cms.double(2.0), # only save TPs with pt > X GeV TP_maxEta = cms.double(2.5), # only save TPs with |eta| < X TP_maxZ0 = cms.double(15.0), # only save TPs with |z0| < X cm - L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), # TTTracks, prompt - L1TrackExtendedInputTag = cms.InputTag("TTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), # TTTracks, extended - MCTruthTrackInputTag = cms.InputTag("TTTrackAssociatorFromPixelDigis", "Level1TTTracks"), # MCTruth track, prompt - MCTruthTrackExtendedInputTag = cms.InputTag("TTTrackAssociatorFromPixelDigisExtended", "Level1TTTracks"), # MCTruth track, extended + L1TrackInputTag = cms.InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"), # TTTracks, prompt + L1TrackExtendedInputTag = cms.InputTag("TTTracksFromExtendedTrackletEmulation", "Level1TTTracks"), # TTTracks, extended + MCTruthTrackInputTag = cms.InputTag("TTTrackAssociatorFromPixelDigis", "Level1TTTracks"), # MCTruth track, prompt + MCTruthTrackExtendedInputTag = cms.InputTag("TTTrackAssociatorFromPixelDigisExtended", "Level1TTTracks"), # MCTruth track, extended + L1TrackGTTInputTag = cms.InputTag("L1GTTInputProducer","Level1TTTracksConverted"), # TTTracks, prompt, GTT converted + L1TrackExtendedGTTInputTag = cms.InputTag("L1GTTInputProducerExtended","Level1TTTracksExtendedConverted"), # TTTracks, extended, GTT converted + L1TrackSelectedInputTag = cms.InputTag("L1TrackSelectionProducer", "Level1TTTracksSelected"), # TTTracks, prompt, selected + L1TrackSelectedEmulationInputTag = cms.InputTag("L1TrackSelectionProducer", "Level1TTTracksSelectedEmulation"), # TTTracks, prompt, emulation, selected + L1TrackExtendedSelectedInputTag = cms.InputTag("L1TrackSelectionProducerExtended", "Level1TTTracksExtendedSelected"), # TTTracks, extended, selected + L1TrackExtendedSelectedEmulationInputTag = cms.InputTag("L1TrackSelectionProducerExtended", "Level1TTTracksExtendedSelectedEmulation"), # TTTracks, extended, emulation, selected L1StubInputTag = cms.InputTag("TTStubsFromPhase2TrackerDigis","StubAccepted"), MCTruthClusterInputTag = cms.InputTag("TTClusterAssociatorFromPixelDigis", "ClusterAccepted"), MCTruthStubInputTag = cms.InputTag("TTStubAssociatorFromPixelDigis", "StubAccepted"), TrackingParticleInputTag = cms.InputTag("mix", "MergedTrackTruth"), TrackingVertexInputTag = cms.InputTag("mix", "MergedTrackTruth"), - ## tracking in jets stuff (--> requires AK4 genjet collection present!) - TrackingInJets = cms.bool(False), GenJetInputTag = cms.InputTag("ak4GenJets", ""), ##track jets and track MET - SaveTrackJets = cms.bool(True), - SaveTrackMET = cms.bool(True), + SaveTrackJets = cms.bool(True), #includes emulated jets + SaveTrackSums = cms.bool(True), #includes simulated/emulated track MET, MHT, and HT TrackFastJetsInputTag = cms.InputTag("L1TrackFastJets","L1TrackFastJets"), TrackFastJetsExtendedInputTag = cms.InputTag("L1TrackFastJetsExtended","L1TrackFastJetsExtended"), - TrackJetsInputTag=cms.InputTag("L1TrackJets", "L1TrackJets"), + TrackJetsInputTag = cms.InputTag("L1TrackJets", "L1TrackJets"), TrackJetsExtendedInputTag=cms.InputTag("L1TrackJetsExtended", "L1TrackJetsExtended"), - TrackMETInputTag = cms.InputTag("L1TrackerEtMiss","L1TrackerEtMiss","L1TrackJets"), - TrackMETExtendedInputTag = cms.InputTag("L1TrackerEtMissExtended","L1TrackerEtMissExtended"), - TrackMHTInputTag = cms.InputTag("L1TrackerHTMiss","L1TrackerHTMiss","L1TrackJets"), - TrackMHTExtendedInputTag = cms.InputTag("L1TrackerHTMissExtended","L1TrackerHTMiss"), + TrackJetsEmuInputTag = cms.InputTag("L1TrackJetsEmulation","L1TrackJets"), + TrackJetsExtendedEmuInputTag = cms.InputTag("L1TrackJetsExtendedEmulation","L1TrackJetsExtended"), + TrackMETInputTag = cms.InputTag("L1TrackerEtMiss","L1TrackerEtMiss"), + TrackMETExtendedInputTag = cms.InputTag("L1TrackerEtMissExtended","L1TrackerExtendedEtMiss"), + TrackMETEmuInputTag = cms.InputTag("L1TrackerEmuEtMiss","L1TrackerEmuEtMiss"), + TrackMHTInputTag = cms.InputTag("L1TrackerHTMiss","L1TrackerHTMiss"), #includes HT + TrackMHTExtendedInputTag = cms.InputTag("L1TrackerHTMissExtended","L1TrackerHTMissExtended"), + TrackMHTEmuInputTag = cms.InputTag("L1TrackerEmuHTMiss",process.L1TrackerEmuHTMiss.L1MHTCollectionName.value()), + TrackMHTEmuExtendedInputTag = cms.InputTag("L1TrackerEmuHTMissExtended",process.L1TrackerEmuHTMissExtended.L1MHTCollectionName.value()), GenParticleInputTag = cms.InputTag("genParticles",""), - RecoVertexInputTag=cms.InputTag("VertexProducer", process.VertexProducer.l1VertexCollectionName.value()), + RecoVertexInputTag=cms.InputTag("L1VertexFinder", "l1vertices"), + RecoVertexEmuInputTag=cms.InputTag("L1VertexFinderEmulator", "l1verticesEmulation"), ) process.ntuple = cms.Path(process.L1TrackNtuple) @@ -172,14 +241,11 @@ process.pOut = cms.EndPath(process.out) - # use this if you want to re-run the stub making -# process.schedule = cms.Schedule(process.TTClusterStub,process.TTClusterStubTruth,process.TTTracksEmulationWithTruth,process.ntuple) +# process.schedule = cms.Schedule(process.TTClusterStub,process.TTClusterStubTruth,process.TTTracksEmuWithTruth,process.ntuple) # use this if cluster/stub associators not available -# process.schedule = cms.Schedule(process.TTClusterStubTruth,process.TTTracksEmulationWithTruth,process.ntuple) +# process.schedule = cms.Schedule(process.TTClusterStubTruth,process.TTTracksEmuWithTruth,process.ntuple) -#process.schedule = cms.Schedule(process.pPV, process.pL1TrackJets, process.pL1TrackFastJets, process.pTkMET, process.pTkMHT,process.pOut) -#process.schedule = cms.Schedule(process.pPV, process.pL1TrackJets, process.pL1TrackFastJets, process.pTkMET, process.pTkMHT, process.ntuple) -#process.schedule = cms.Schedule(process.ntuple) -process.schedule = cms.Schedule(process.TTTracksEmulationWithTruth, process.pPV, process.pL1TrackJets, process.pL1TrackFastJets, process.pTkMET, process.pTkMHT, process.ntuple) +process.schedule = cms.Schedule(process.TTClusterStub, process.TTClusterStubTruth, process.dtc, process.TTTracksEmuWithTruth, process.pL1GTTInput, process.pPV, process.pPVemu, process.pL1TrackSelection, process.pL1TrackJets, process.pL1TrackJetsEmu, +process.pL1TrackFastJets, process.pTkMET, process.pTkMETEmu, process.pTkMHT, process.pTkMHTEmulator, process.ntuple) diff --git a/L1Trigger/L1TTrackMatch/test/trkMET_rate.C b/L1Trigger/L1TTrackMatch/test/trkMET_rate.C new file mode 100644 index 0000000000000..4c8eac39aaeb0 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/test/trkMET_rate.C @@ -0,0 +1,428 @@ +//To find the rate from a (very very large) min bias sample, +//Runs off of the track object ntuplizer + +#include "TROOT.h" +#include "TStyle.h" +#include "TLatex.h" +#include "TFile.h" +#include "TTree.h" +#include "TChain.h" +#include "TBranch.h" +#include "TLeaf.h" +#include "TCanvas.h" +#include "TLegend.h" +#include "TH1.h" +#include "TH2.h" +#include "TF1.h" +#include "TProfile.h" +#include "TProfile2D.h" +#include "TMath.h" +#include + +#include +#include +#include + +using namespace std; +TH1D* GetCumulative(TH1D* plot); + +void trkMET_rate() { + TChain* tree = new TChain("L1TrackNtuple/eventTree"); + // tree->Add("/uscms_data/d3/csavard/working_dir/for_Emily/CMSSW_11_1_3/src/L1Trigger/TrackFindingTracklet/test/crab_output/crab_nu_gun/results/NuGun_PU200_TDR.root"); + tree->Add("CheckingJets_CMSSW11_CMS.root"); + + if (tree->GetEntries() == 0) { + cout << "File doesn't exist or is empty, returning..." << endl; + return; + } + + // define leafs & branches + float trueMET = 0; + float trueTkMET = 0; + float trkMET = 0; + vector* pv_L1reco; + //gen particles + vector* gen_pt; + vector* gen_phi; + vector* gen_pdgid; + + // tracking particles + vector* tp_pt; + vector* tp_eta; + vector* tp_phi; + vector* tp_dxy; + vector* tp_z0; + vector* tp_d0; + vector* tp_pdgid; + vector* tp_nmatch; + vector* tp_nstub; + // vector* tp_nLayers; + vector* tp_eventid; + // vector* tp_signal; + vector* tp_charge; + + // *L1 track* properties, for tracking particles matched to a L1 track + vector* matchtrk_pt; + vector* matchtrk_eta; + vector* matchtrk_phi; + vector* matchtrk_d0; + vector* matchtrk_z0; + vector* matchtrk_chi2; + vector* matchtrk_MVA1; + vector* matchtrk_bendchi2; + vector* matchtrk_nstub; + vector* matchtrk_seed; + + // all L1 tracks + vector* trk_pt; + vector* trk_eta; + vector* trk_phi; + vector* trk_z0; + vector* trk_chi2; + vector* trk_MVA1; + vector* trk_bendchi2; + vector* trk_nstub; + vector* trk_seed; + vector* trk_fake; + + TBranch* b_gen_pt; + TBranch* b_gen_phi; + TBranch* b_gen_pdgid; + + TBranch* b_tp_pt; + TBranch* b_tp_eta; + TBranch* b_tp_phi; + TBranch* b_tp_dxy; + TBranch* b_tp_z0; + TBranch* b_tp_d0; + TBranch* b_tp_pdgid; + TBranch* b_tp_nmatch; + // TBranch* b_tp_nLayers; + TBranch* b_tp_nstub; + TBranch* b_tp_eventid; + // TBranch* b_tp_signal; + TBranch* b_tp_charge; + + TBranch* b_matchtrk_pt; + TBranch* b_matchtrk_eta; + TBranch* b_matchtrk_phi; + TBranch* b_matchtrk_d0; + TBranch* b_matchtrk_z0; + TBranch* b_matchtrk_chi2; + TBranch* b_matchtrk_MVA1; + TBranch* b_matchtrk_bendchi2; + TBranch* b_matchtrk_nstub; + TBranch* b_matchtrk_seed; + + TBranch* b_trk_pt; + TBranch* b_trk_eta; + TBranch* b_trk_phi; + TBranch* b_trk_z0; + TBranch* b_trk_chi2; + TBranch* b_trk_MVA1; + TBranch* b_trk_bendchi2; + TBranch* b_trk_nstub; + TBranch* b_trk_seed; + TBranch* b_trk_fake; + + TBranch* b_pv_L1reco; + TBranch* b_trueMET; + TBranch* b_trueTkMET; + TBranch* b_trkMET; + + trueMET = 0; + trueTkMET = 0; + trkMET = 0; + + gen_pt = 0; + gen_phi = 0; + gen_pdgid = 0; + + tp_pt = 0; + tp_eta = 0; + tp_phi = 0; + tp_dxy = 0; + tp_z0 = 0; + tp_d0 = 0; + tp_pdgid = 0; + tp_nmatch = 0; + // tp_nLayers = 0; + tp_nstub = 0; + tp_eventid = 0; + // tp_signal = 0; + tp_charge = 0; + + matchtrk_pt = 0; + matchtrk_eta = 0; + matchtrk_phi = 0; + matchtrk_d0 = 0; + matchtrk_z0 = 0; + matchtrk_chi2 = 0; + matchtrk_MVA1 = 0; + matchtrk_bendchi2 = 0; + matchtrk_nstub = 0; + matchtrk_seed = 0; + + trk_pt = 0; + trk_eta = 0; + trk_phi = 0; + trk_z0 = 0; + trk_chi2 = 0; + trk_MVA1 = 0; + trk_bendchi2 = 0; + trk_nstub = 0; + trk_seed = 0; + trk_fake = 0; + + pv_L1reco = 0; + + tree->SetBranchAddress("pv_L1reco", &pv_L1reco, &b_pv_L1reco); + tree->SetBranchAddress("trueMET", &trueMET, &b_trueMET); + tree->SetBranchAddress("trueTkMET", &trueTkMET, &b_trueTkMET); + tree->SetBranchAddress("trkMET", &trkMET, &b_trkMET); + tree->SetBranchAddress("gen_pt", &gen_pt, &b_gen_pt); + tree->SetBranchAddress("gen_phi", &gen_phi, &b_gen_phi); + tree->SetBranchAddress("gen_pdgid", &gen_pdgid, &b_gen_pdgid); + + tree->SetBranchAddress("tp_pt", &tp_pt, &b_tp_pt); + tree->SetBranchAddress("tp_eta", &tp_eta, &b_tp_eta); + tree->SetBranchAddress("tp_phi", &tp_phi, &b_tp_phi); + tree->SetBranchAddress("tp_dxy", &tp_dxy, &b_tp_dxy); + tree->SetBranchAddress("tp_z0", &tp_z0, &b_tp_z0); + tree->SetBranchAddress("tp_d0", &tp_d0, &b_tp_d0); + tree->SetBranchAddress("tp_pdgid", &tp_pdgid, &b_tp_pdgid); + tree->SetBranchAddress("tp_nmatch", &tp_nmatch, &b_tp_nmatch); + // tree->SetBranchAddress("tp_nLayers", &tp_nLayers, &b_tp_nLayers); + tree->SetBranchAddress("tp_nstub", &tp_nstub, &b_tp_nstub); + tree->SetBranchAddress("tp_eventid", &tp_eventid, &b_tp_eventid); + // tree->SetBranchAddress("tp_signal", &tp_signal, &b_tp_signal); + tree->SetBranchAddress("tp_charge", &tp_charge, &b_tp_charge); + + tree->SetBranchAddress("matchtrk_pt", &matchtrk_pt, &b_matchtrk_pt); + tree->SetBranchAddress("matchtrk_eta", &matchtrk_eta, &b_matchtrk_eta); + tree->SetBranchAddress("matchtrk_phi", &matchtrk_phi, &b_matchtrk_phi); + tree->SetBranchAddress("matchtrk_d0", &matchtrk_d0, &b_matchtrk_d0); + tree->SetBranchAddress("matchtrk_z0", &matchtrk_z0, &b_matchtrk_z0); + tree->SetBranchAddress("matchtrk_chi2", &matchtrk_chi2, &b_matchtrk_chi2); + tree->SetBranchAddress("matchtrk_MVA1", &matchtrk_MVA1, &b_matchtrk_MVA1); + tree->SetBranchAddress("matchtrk_bendchi2", &matchtrk_bendchi2, &b_matchtrk_bendchi2); + tree->SetBranchAddress("matchtrk_nstub", &matchtrk_nstub, &b_matchtrk_nstub); + + tree->SetBranchAddress("trk_pt", &trk_pt, &b_trk_pt); + tree->SetBranchAddress("trk_eta", &trk_eta, &b_trk_eta); + tree->SetBranchAddress("trk_phi", &trk_phi, &b_trk_phi); + tree->SetBranchAddress("trk_z0", &trk_z0, &b_trk_z0); + tree->SetBranchAddress("trk_chi2", &trk_chi2, &b_trk_chi2); + tree->SetBranchAddress("trk_MVA1", &trk_MVA1, &b_trk_MVA1); + tree->SetBranchAddress("trk_bendchi2", &trk_bendchi2, &b_trk_bendchi2); + tree->SetBranchAddress("trk_nstub", &trk_nstub, &b_trk_nstub); + tree->SetBranchAddress("trk_fake", &trk_fake, &b_trk_fake); + + //Need trkMET from tracking particles, and trkMET from tracks + + float numBins = 100.0; + float cutoff = 200.0 - 0.1; + float TP_minPt = 2.0; + float TP_maxEta = 2.4; + float chi2dof_cut = 10.0; + float bendchi2_cut = 2.2; + + TH1D* trueTkMET_thresh = new TH1D("trueTkMET_thresh", + "trueTkMET_thresh;trueTkMET threshold (GeV);Occurrences", + numBins, + 0, + numBins); //using tracking particles + TH1D* recoTkMET_thresh = new TH1D( + "recoTkMET_thresh", "recoTkMET_thresh;recoTkMET threshold (GeV);Occurrences", numBins, 0, numBins); //using tracks + + bool rerun_trueTkMET = false; + bool rerun_recoTkMET = false; + + int nevt = tree->GetEntries(); + cout << "number of events = " << nevt << endl; + + // event loop + for (int i = 0; i < nevt; i++) { + tree->GetEntry(i); + if (i % 10000 == 0) + std::cout << i << "/" << nevt << std::endl; + + float trueTkMET_ntuple = 0; //grab these from ntuple + float recoTkMET_ntuple = 0; //grab these from ntuple + + if (!rerun_trueTkMET) + trueTkMET_ntuple = trueTkMET; + if (!rerun_recoTkMET) + recoTkMET_ntuple = trkMET; + + if (rerun_trueTkMET) { + float trueTkMET_calc = 0; + float trueTkMETx = 0; + float trueTkMETy = 0; + // tracking particle loop + for (int it = 0; it < (int)tp_pt->size(); it++) { + float this_tp_pt = tp_pt->at(it); + float this_tp_eta = tp_eta->at(it); + float this_tp_phi = tp_phi->at(it); + int this_tp_signal = tp_eventid->at(it); + float deltaZ = std::abs(tp_z0->at(it) - pv_L1reco->at(0)); + + // kinematic cuts + if (tp_pt->at(it) < TP_minPt) + continue; + if (std::abs(this_tp_eta) > TP_maxEta) + continue; + if (tp_nstub->at(it) < 4) + continue; + if (std::abs(tp_z0->at(it)) > 15) + continue; + // if (this_tp_signal!=0) continue; + // if (tp_dxy->at(it) > 1) continue; + if (tp_charge->at(it) == 0) + continue; + + float deltaZ_cut = 3.0; // cuts out PU + if (std::abs(this_tp_eta) >= 0 && std::abs(this_tp_eta) < 0.7) + deltaZ_cut = 0.4; + else if (std::abs(this_tp_eta) >= 0.7 && std::abs(this_tp_eta) < 1.0) + deltaZ_cut = 0.6; + else if (std::abs(this_tp_eta) >= 1.0 && std::abs(this_tp_eta) < 1.2) + deltaZ_cut = 0.76; + else if (std::abs(this_tp_eta) >= 1.2 && std::abs(this_tp_eta) < 1.6) + deltaZ_cut = 1.0; + else if (std::abs(this_tp_eta) >= 1.6 && std::abs(this_tp_eta) < 2.0) + deltaZ_cut = 1.7; + else if (std::abs(this_tp_eta) >= 2.0 && std::abs(this_tp_eta) <= 2.4) + deltaZ_cut = 2.20; + + if (deltaZ > deltaZ_cut) + continue; + + trueTkMETx += this_tp_pt * cos(this_tp_phi); + trueTkMETy += this_tp_pt * sin(this_tp_phi); + } // end of tracking particle loop + + trueTkMET_calc = sqrt(trueTkMETx * trueTkMETx + trueTkMETy * trueTkMETy); + trueTkMET_ntuple = trueTkMET_calc; + } //re-run trueTkMET + + if (rerun_recoTkMET) { //also useful for checking different track quality cuts + float recoTkMET_calc = 0; + float recoTkMETx = 0; + float recoTkMETy = 0; + + for (int it = 0; it < (int)trk_pt->size(); it++) { + float thisTrk_pt = trk_pt->at(it); + float thisTrk_eta = trk_eta->at(it); + int thisTrk_nstub = trk_nstub->at(it); + float thisTrk_chi2dof = trk_chi2->at(it) / (2 * thisTrk_nstub - 4); + float thisTrk_bendchi2 = trk_bendchi2->at(it); + float thisTrk_phi = trk_phi->at(it); + float thisTrk_MVA = trk_MVA1->at(it); + int thisTrk_fake = trk_fake->at(it); + float thisTrk_z0 = trk_z0->at(it); + float deltaZ = thisTrk_z0 - pv_L1reco->at(0); + + float deltaZ_cut = 3.0; // cuts out PU + if (std::abs(thisTrk_eta) >= 0 && std::abs(thisTrk_eta) < 0.7) + deltaZ_cut = 0.4; + else if (std::abs(thisTrk_eta) >= 0.7 && std::abs(thisTrk_eta) < 1.0) + deltaZ_cut = 0.6; + else if (std::abs(thisTrk_eta) >= 1.0 && std::abs(thisTrk_eta) < 1.2) + deltaZ_cut = 0.76; + else if (std::abs(thisTrk_eta) >= 1.2 && std::abs(thisTrk_eta) < 1.6) + deltaZ_cut = 1.0; + else if (std::abs(thisTrk_eta) >= 1.6 && std::abs(thisTrk_eta) < 2.0) + deltaZ_cut = 1.7; + else if (std::abs(thisTrk_eta) >= 2.0 && std::abs(thisTrk_eta) <= 2.4) + deltaZ_cut = 2.20; + + if (thisTrk_pt < TP_minPt || std::abs(thisTrk_eta) > TP_maxEta || thisTrk_nstub < 4 || + std::abs(thisTrk_z0) > 15) + continue; + if (std::abs(deltaZ) > deltaZ_cut) + continue; + + if (thisTrk_chi2dof < chi2dof_cut && thisTrk_bendchi2 < bendchi2_cut) { + recoTkMETx += thisTrk_pt * cos(thisTrk_phi); + recoTkMETy += thisTrk_pt * sin(thisTrk_phi); + } + } //end loop over tracks + + recoTkMET_calc = sqrt(recoTkMETx * recoTkMETx + recoTkMETy * recoTkMETy); + recoTkMET_ntuple = recoTkMET_calc; + } //re-run reco tkMET + + trueTkMET_thresh->Fill(trueTkMET_ntuple); + recoTkMET_thresh->Fill(recoTkMET_ntuple); + } // end event loop + + // ------------------------------------------------------------------------------------------- + trueTkMET_thresh->SetStats(0); + recoTkMET_thresh->SetStats(0); + trueTkMET_thresh->SetLineColor(kBlack); + recoTkMET_thresh->SetLineColor(kRed); + trueTkMET_thresh->SetTitle(""); + recoTkMET_thresh->SetTitle(""); + + TLegend* leg = new TLegend(0.48, 0.68, 0.88, 0.88); + leg->SetBorderSize(0); + leg->SetFillStyle(0); + leg->SetTextSize(0.04); + leg->SetTextFont(42); + leg->AddEntry(trueTkMET_thresh, "trueTkMET", "l"); + leg->AddEntry(recoTkMET_thresh, "recoTkMET", "l"); + + TH1D* fCumulative_true = GetCumulative(trueTkMET_thresh); + TH1D* fCumulative_reco = GetCumulative(recoTkMET_thresh); + fCumulative_true->Scale(4.0e3 / fCumulative_true->GetBinContent(1)); + fCumulative_reco->Scale(4.0e3 / fCumulative_reco->GetBinContent(1)); + + fCumulative_true->SetTitle("MinBias Events PU 200; Track MET [GeV]; L1 Rate [kHz]"); + fCumulative_true->SetMarkerSize(0.7); + fCumulative_true->SetMarkerStyle(20); + fCumulative_true->SetMarkerColor(fCumulative_true->GetLineColor()); + + fCumulative_reco->SetMarkerSize(0.7); + fCumulative_reco->SetMarkerStyle(20); + fCumulative_reco->SetMarkerColor(fCumulative_reco->GetLineColor()); + + // fCumulative_true->Rebin(2); fCumulative_reco->Rebin(2); + + TCanvas* can = new TCanvas("can", "can"); + can->SetGridx(); + can->SetGridy(); + can->SetLogy(); + + fCumulative_true->GetYaxis()->SetRangeUser(1E-01, 1E05); + + fCumulative_true->Draw(); + fCumulative_reco->Draw("same"); + leg->Draw("same"); + + TLine* line_rate = new TLine(0, 35, numBins, 35); + line_rate->SetLineColor(kBlack); + line_rate->SetLineWidth(2); + line_rate->Draw("SAME"); + + std::cout << "Track MET Threshold at 35kHz " + << fCumulative_reco->GetBinLowEdge(fCumulative_reco->FindLastBinAbove(35)) << std::endl; + + can->SaveAs("trkMET_minBias_RatePlot.root"); +} + +TH1D* GetCumulative(TH1D* plot) { + std::string newName = Form("cumulative_%s", plot->GetName()); + TH1D* temp = (TH1D*)plot->Clone(newName.c_str()); + temp->SetDirectory(0); + for (int i = 0; i < plot->GetNbinsX() + 1; i++) { + double content(0.0), error2(0.0); + for (int j = i; j < plot->GetNbinsX() + 1; j++) { + content += plot->GetBinContent(j); + error2 += plot->GetBinError(j) * plot->GetBinError(j); + } + temp->SetBinContent(i, content); + temp->SetBinError(i, TMath::Sqrt(error2)); + } + return temp; +} diff --git a/L1Trigger/L1TTrackMatch/test/trkMET_turnOn.C b/L1Trigger/L1TTrackMatch/test/trkMET_turnOn.C new file mode 100644 index 0000000000000..4e70940e340b2 --- /dev/null +++ b/L1Trigger/L1TTrackMatch/test/trkMET_turnOn.C @@ -0,0 +1,433 @@ +//To make basic turn-on curve for trkMET +//Runs off of the track object ntuplizer + +#include "TROOT.h" +#include "TStyle.h" +#include "TLatex.h" +#include "TFile.h" +#include "TTree.h" +#include "TChain.h" +#include "TBranch.h" +#include "TLeaf.h" +#include "TCanvas.h" +#include "TLegend.h" +#include "TH1.h" +#include "TH2.h" +#include "TF1.h" +#include "TProfile.h" +#include "TProfile2D.h" +#include "TMath.h" +#include + +#include +#include +#include + +using namespace std; + +void trkMET_turnOn() { + TChain* tree = new TChain("L1TrackNtuple/eventTree"); + // tree->Add("/uscms_data/d3/csavard/working_dir/for_Emily/CMSSW_11_1_3/src/L1Trigger/TrackFindingTracklet/test/crab_output/crab_ttbar_pu200/results/TTbar_PU200_D49.root"); + tree->Add("CheckingJets_CMSSW11_CMS.root"); + + if (tree->GetEntries() == 0) { + cout << "File doesn't exist or is empty, returning..." << endl; + return; + } + + // define leafs & branches + float trueMET = 0; + float trueTkMET = 0; + float trkMET = 0; + vector* pv_L1reco; + //gen particles + vector* gen_pt; + vector* gen_phi; + vector* gen_pdgid; + + // tracking particles + vector* tp_pt; + vector* tp_eta; + vector* tp_phi; + vector* tp_dxy; + vector* tp_z0; + vector* tp_d0; + vector* tp_pdgid; + vector* tp_nmatch; + vector* tp_nstub; + // vector* tp_nLayers; + vector* tp_eventid; + // vector* tp_signal; + vector* tp_charge; + + // *L1 track* properties, for tracking particles matched to a L1 track + vector* matchtrk_pt; + vector* matchtrk_eta; + vector* matchtrk_phi; + vector* matchtrk_d0; + vector* matchtrk_z0; + vector* matchtrk_chi2; + vector* matchtrk_MVA1; + vector* matchtrk_bendchi2; + vector* matchtrk_nstub; + vector* matchtrk_seed; + + // all L1 tracks + vector* trk_pt; + vector* trk_eta; + vector* trk_phi; + vector* trk_z0; + vector* trk_chi2; + vector* trk_MVA1; + vector* trk_bendchi2; + vector* trk_nstub; + vector* trk_seed; + vector* trk_fake; + + TBranch* b_gen_pt; + TBranch* b_gen_phi; + TBranch* b_gen_pdgid; + + TBranch* b_tp_pt; + TBranch* b_tp_eta; + TBranch* b_tp_phi; + TBranch* b_tp_dxy; + TBranch* b_tp_z0; + TBranch* b_tp_d0; + TBranch* b_tp_pdgid; + TBranch* b_tp_nmatch; + // TBranch* b_tp_nLayers; + TBranch* b_tp_nstub; + TBranch* b_tp_eventid; + // TBranch* b_tp_signal; + TBranch* b_tp_charge; + + TBranch* b_matchtrk_pt; + TBranch* b_matchtrk_eta; + TBranch* b_matchtrk_phi; + TBranch* b_matchtrk_d0; + TBranch* b_matchtrk_z0; + TBranch* b_matchtrk_chi2; + TBranch* b_matchtrk_MVA1; + TBranch* b_matchtrk_bendchi2; + TBranch* b_matchtrk_nstub; + TBranch* b_matchtrk_seed; + + TBranch* b_trk_pt; + TBranch* b_trk_eta; + TBranch* b_trk_phi; + TBranch* b_trk_z0; + TBranch* b_trk_chi2; + TBranch* b_trk_MVA1; + TBranch* b_trk_bendchi2; + TBranch* b_trk_nstub; + TBranch* b_trk_seed; + TBranch* b_trk_fake; + + TBranch* b_pv_L1reco; + TBranch* b_trueMET; + TBranch* b_trueTkMET; + TBranch* b_trkMET; + + trueMET = 0; + trueTkMET = 0; + trkMET = 0; + + gen_pt = 0; + gen_phi = 0; + gen_pdgid = 0; + + tp_pt = 0; + tp_eta = 0; + tp_phi = 0; + tp_dxy = 0; + tp_z0 = 0; + tp_d0 = 0; + tp_pdgid = 0; + tp_nmatch = 0; + // tp_nLayers = 0; + tp_nstub = 0; + tp_eventid = 0; + // tp_signal = 0; + tp_charge = 0; + + matchtrk_pt = 0; + matchtrk_eta = 0; + matchtrk_phi = 0; + matchtrk_d0 = 0; + matchtrk_z0 = 0; + matchtrk_chi2 = 0; + matchtrk_MVA1 = 0; + matchtrk_bendchi2 = 0; + matchtrk_nstub = 0; + matchtrk_seed = 0; + + trk_pt = 0; + trk_eta = 0; + trk_phi = 0; + trk_z0 = 0; + trk_chi2 = 0; + trk_MVA1 = 0; + trk_bendchi2 = 0; + trk_nstub = 0; + trk_seed = 0; + trk_fake = 0; + + pv_L1reco = 0; + + tree->SetBranchAddress("pv_L1reco", &pv_L1reco, &b_pv_L1reco); + tree->SetBranchAddress("trueMET", &trueMET, &b_trueMET); + tree->SetBranchAddress("trueTkMET", &trueTkMET, &b_trueTkMET); + tree->SetBranchAddress("trkMET", &trkMET, &b_trkMET); + tree->SetBranchAddress("gen_pt", &gen_pt, &b_gen_pt); + tree->SetBranchAddress("gen_phi", &gen_phi, &b_gen_phi); + tree->SetBranchAddress("gen_pdgid", &gen_pdgid, &b_gen_pdgid); + + tree->SetBranchAddress("tp_pt", &tp_pt, &b_tp_pt); + tree->SetBranchAddress("tp_eta", &tp_eta, &b_tp_eta); + tree->SetBranchAddress("tp_phi", &tp_phi, &b_tp_phi); + tree->SetBranchAddress("tp_dxy", &tp_dxy, &b_tp_dxy); + tree->SetBranchAddress("tp_z0", &tp_z0, &b_tp_z0); + tree->SetBranchAddress("tp_d0", &tp_d0, &b_tp_d0); + tree->SetBranchAddress("tp_pdgid", &tp_pdgid, &b_tp_pdgid); + tree->SetBranchAddress("tp_nmatch", &tp_nmatch, &b_tp_nmatch); + // tree->SetBranchAddress("tp_nLayers", &tp_nLayers, &b_tp_nLayers); + tree->SetBranchAddress("tp_nstub", &tp_nstub, &b_tp_nstub); + tree->SetBranchAddress("tp_eventid", &tp_eventid, &b_tp_eventid); + // tree->SetBranchAddress("tp_signal", &tp_signal, &b_tp_signal); + tree->SetBranchAddress("tp_charge", &tp_charge, &b_tp_charge); + + tree->SetBranchAddress("matchtrk_pt", &matchtrk_pt, &b_matchtrk_pt); + tree->SetBranchAddress("matchtrk_eta", &matchtrk_eta, &b_matchtrk_eta); + tree->SetBranchAddress("matchtrk_phi", &matchtrk_phi, &b_matchtrk_phi); + tree->SetBranchAddress("matchtrk_d0", &matchtrk_d0, &b_matchtrk_d0); + tree->SetBranchAddress("matchtrk_z0", &matchtrk_z0, &b_matchtrk_z0); + tree->SetBranchAddress("matchtrk_chi2", &matchtrk_chi2, &b_matchtrk_chi2); + tree->SetBranchAddress("matchtrk_MVA1", &matchtrk_MVA1, &b_matchtrk_MVA1); + tree->SetBranchAddress("matchtrk_bendchi2", &matchtrk_bendchi2, &b_matchtrk_bendchi2); + tree->SetBranchAddress("matchtrk_nstub", &matchtrk_nstub, &b_matchtrk_nstub); + + tree->SetBranchAddress("trk_pt", &trk_pt, &b_trk_pt); + tree->SetBranchAddress("trk_eta", &trk_eta, &b_trk_eta); + tree->SetBranchAddress("trk_phi", &trk_phi, &b_trk_phi); + tree->SetBranchAddress("trk_z0", &trk_z0, &b_trk_z0); + tree->SetBranchAddress("trk_chi2", &trk_chi2, &b_trk_chi2); + tree->SetBranchAddress("trk_MVA1", &trk_MVA1, &b_trk_MVA1); + tree->SetBranchAddress("trk_bendchi2", &trk_bendchi2, &b_trk_bendchi2); + tree->SetBranchAddress("trk_nstub", &trk_nstub, &b_trk_nstub); + tree->SetBranchAddress("trk_fake", &trk_fake, &b_trk_fake); + + //Need trkMET from tracking particles, and trkMET from tracks + + float numBins = 100.0; + float cutoff = 300.0 - 0.1; + float TP_minPt = 2.0; + float TP_maxEta = 2.4; + float chi2dof_cut = 10.0; + float bendchi2_cut = 2.2; + + TH1F* h_trueMET = new TH1F("trueMET", ";trueMET [GeV]; Events", numBins, 0, 500.0); + TH1F* h_trueTkMET = new TH1F("trueTkMET", ";trueTkMET [GeV]; Events", numBins, 0, 500.0); + TH1F* h_recoTkMET = new TH1F("recoTkMET", ";recoTkMET [GeV]; Events", numBins, 0, 500.0); + + TH1F* h_trueTkMET_num = new TH1F("trueTkMET_turnon", ";trueMET [GeV]; Events", numBins, 0, 500.0); + TH1F* h_recoTkMET_num = new TH1F("recoTkMET_turnon", ";trueMET [GeV]; Events", numBins, 0, 500.0); + + //From rate code + float trueTkMET_rate = 49.0; + float recoTkMET_rate = 49.0; + + bool rerun_trueMET = true; + bool rerun_trueTkMET = true; + bool rerun_recoTkMET = true; + + int nevt = tree->GetEntries(); + cout << "number of events = " << nevt << endl; + + // event loop + for (int i = 0; i < nevt; i++) { + tree->GetEntry(i); + if (i % 10000 == 0) + std::cout << i << "/" << nevt << std::endl; + + float trueMET_ntuple = trueMET; //grab these from ntuple + float trueTkMET_ntuple = trueTkMET; //grab these from ntuple + float recoTkMET_ntuple = trkMET; //grab these from ntuple + + if (rerun_trueMET) { + float trueMETx = 0.0; + float trueMETy = 0.0; + float trueMET_calc = 0.0; + for (size_t i = 0; i < gen_pt->size(); ++i) { + int id = gen_pdgid->at(i); + float pt = gen_pt->at(i); + float phi = gen_phi->at(i); + bool isNeutrino = false; + if ((fabs(id) == 12 || fabs(id) == 14 || fabs(id) == 16)) + isNeutrino = true; + if ((isNeutrino || id == 1000022)) { //only gen parts saved are status==1 + trueMETx += pt * cos(phi); + trueMETy += pt * sin(phi); + } + } + trueMET_calc = sqrt(trueMETx * trueMETx + trueMETy * trueMETy); + trueMET_ntuple = trueMET_calc; + } //re-run true MET (gen particles) + + if (rerun_trueTkMET) { + float trueTkMET_calc = 0; + float trueTkMETx = 0; + float trueTkMETy = 0; + // tracking particle loop + for (int it = 0; it < (int)tp_pt->size(); it++) { + float this_tp_pt = tp_pt->at(it); + float this_tp_eta = tp_eta->at(it); + float this_tp_phi = tp_phi->at(it); + int this_tp_eventID = tp_eventid->at(it); + + // kinematic cuts + if (tp_pt->at(it) < TP_minPt) + continue; + if (fabs(this_tp_eta) > TP_maxEta) + continue; + if (tp_nstub->at(it) < 4) + continue; + if (fabs(tp_z0->at(it)) > 15) + continue; + if (this_tp_eventID != 0) + continue; // hard interaction only + // if (tp_dxy->at(it) > 1) continue; + if (tp_charge->at(it) == 0) + continue; + + trueTkMETx += this_tp_pt * cos(this_tp_phi); + trueTkMETy += this_tp_pt * sin(this_tp_phi); + } // end of tracking particle loop + trueTkMET_calc = sqrt(trueTkMETx * trueTkMETx + trueTkMETy * trueTkMETy); + trueTkMET_ntuple = trueTkMET_calc; + } // re-run true trk MET + + if (rerun_recoTkMET) { //also useful for checking performance of new track quality cuts + float recoTkMET_calc = 0; + float recoTkMETx = 0; + float recoTkMETy = 0; + // loop over all tracks + for (int it = 0; it < (int)trk_pt->size(); it++) { + float thisTrk_pt = trk_pt->at(it); + float thisTrk_eta = trk_eta->at(it); + int thisTrk_nstub = trk_nstub->at(it); + float thisTrk_chi2dof = trk_chi2->at(it) / (2 * thisTrk_nstub - 4); + float thisTrk_bendchi2 = trk_bendchi2->at(it); + float thisTrk_phi = trk_phi->at(it); + float thisTrk_MVA = trk_MVA1->at(it); + int thisTrk_fake = trk_fake->at(it); + float thisTrk_z0 = trk_z0->at(it); + float deltaZ = thisTrk_z0 - pv_L1reco->at(0); + + float deltaZ_cut = 3.0; // cuts out PU + if (fabs(thisTrk_eta) >= 0 && fabs(thisTrk_eta) < 0.7) + deltaZ_cut = 0.4; + else if (fabs(thisTrk_eta) >= 0.7 && fabs(thisTrk_eta) < 1.0) + deltaZ_cut = 0.6; + else if (fabs(thisTrk_eta) >= 1.0 && fabs(thisTrk_eta) < 1.2) + deltaZ_cut = 0.76; + else if (fabs(thisTrk_eta) >= 1.2 && fabs(thisTrk_eta) < 1.6) + deltaZ_cut = 1.0; + else if (fabs(thisTrk_eta) >= 1.6 && fabs(thisTrk_eta) < 2.0) + deltaZ_cut = 1.7; + else if (fabs(thisTrk_eta) >= 2.0 && fabs(thisTrk_eta) <= 2.4) + deltaZ_cut = 2.20; + + if (thisTrk_pt < TP_minPt || fabs(thisTrk_eta) > TP_maxEta || thisTrk_nstub < 4 || fabs(thisTrk_z0) > 15) + continue; + if (fabs(deltaZ) > deltaZ_cut) + continue; + + // if (thisTrk_pt>200.0) thisTrk_pt = 200.0; + + if (thisTrk_chi2dof < chi2dof_cut && thisTrk_bendchi2 < bendchi2_cut) { + recoTkMETx += thisTrk_pt * cos(thisTrk_phi); + recoTkMETy += thisTrk_pt * sin(thisTrk_phi); + } + } //end loop over tracks + recoTkMET_calc = sqrt(recoTkMETx * recoTkMETx + recoTkMETy * recoTkMETy); + if (recoTkMET_calc != recoTkMET_ntuple) + std::cout << "Ugh: " << recoTkMET_calc << ", " << recoTkMET_ntuple << std::endl; + + recoTkMET_ntuple = recoTkMET_calc; + } //re-run reco trk MET + + h_trueMET->Fill(trueMET_ntuple); + h_trueTkMET->Fill(trueTkMET_ntuple); + h_recoTkMET->Fill(recoTkMET_ntuple); + + //get rate cuts from Rate Plot script + //if reco MET passes cut, fill with trueMET + if (trueTkMET_ntuple > 49) + h_trueTkMET_num->Fill(trueMET_ntuple); + if (recoTkMET_ntuple > 49) + h_recoTkMET_num->Fill(trueMET_ntuple); + } // end event loop + + //Draw + h_trueMET->SetLineColor(kBlack); + h_trueMET->SetLineStyle(2); + h_trueTkMET->SetLineColor(kBlack); + h_recoTkMET->SetLineColor(kRed); + + TLegend* leg = new TLegend(0.55, 0.15, 0.85, 0.35); + leg->SetBorderSize(0); + leg->SetFillStyle(0); + leg->SetTextSize(0.04); + leg->SetTextFont(42); + leg->AddEntry(h_trueTkMET, "trueTkMET", "l"); + leg->AddEntry(h_recoTkMET, "recoTkMET", "l"); + + // calculate the recoTkMET trigger turn on curve + h_trueMET->Rebin(2); + h_trueTkMET_num->Rebin(2); + h_recoTkMET_num->Rebin(2); + h_trueMET->Sumw2(); + h_trueTkMET->Sumw2(); + h_trueTkMET_num->Sumw2(); + + TH1F* h_TkMET_turnon = (TH1F*)h_trueTkMET_num->Clone(); + h_TkMET_turnon->SetName("trueTkMET_turnon"); + h_TkMET_turnon->SetStats(0); + h_TkMET_turnon->SetTitle("; Gen-level MET [GeV]; Efficiency"); + h_TkMET_turnon->Divide(h_trueTkMET_num, h_trueMET, 1.0, 1.0, "B"); + h_TkMET_turnon->SetMarkerStyle(20); + h_TkMET_turnon->SetMarkerSize(0.7); + h_TkMET_turnon->SetMarkerColor(kBlack); + h_TkMET_turnon->SetLineColor(kBlack); + + h_recoTkMET_num->Sumw2(); + TH1F* h_recoTkMET_turnon = (TH1F*)h_recoTkMET_num->Clone(); + h_recoTkMET_turnon->SetName("recoTkMET_turnon"); + h_recoTkMET_turnon->SetStats(0); + h_recoTkMET_turnon->SetTitle("; Gen-level MET [GeV]; Efficiency"); + h_recoTkMET_turnon->Divide(h_recoTkMET_num, h_trueMET, 1.0, 1.0, "B"); + h_recoTkMET_turnon->SetMarkerStyle(20); + h_recoTkMET_turnon->SetMarkerSize(0.7); + h_recoTkMET_turnon->SetMarkerColor(kRed); + h_recoTkMET_turnon->SetLineColor(kRed); + + TCanvas* can = new TCanvas("can", "can", 800, 600); + can->SetGridx(); + can->SetGridy(); + h_TkMET_turnon->SetMinimum(0); + h_TkMET_turnon->SetMaximum(1.1); + h_TkMET_turnon->Draw(); + h_recoTkMET_turnon->Draw("same"); + leg->Draw("same"); + + float trueTkMET_95eff = h_TkMET_turnon->GetBinLowEdge(h_TkMET_turnon->FindFirstBinAbove(0.95)); + float recoTkMET_95eff = h_recoTkMET_turnon->GetBinLowEdge(h_recoTkMET_turnon->FindFirstBinAbove(0.95)); + + std::cout << "Online (true) Track MET at " << trueTkMET_rate << " GeV = " << trueTkMET_95eff << " GeV (offline)" + << std::endl; + std::cout << "Online (reco) Track MET at " << recoTkMET_rate << " GeV = " << recoTkMET_95eff << " GeV (offline)" + << std::endl; + + can->SaveAs("trkMET_ttbarPU200_TurnOnPlot.root"); +} diff --git a/L1Trigger/Phase2L1GMT/BuildFile.xml b/L1Trigger/Phase2L1GMT/BuildFile.xml new file mode 100644 index 0000000000000..e3ce9c6b7da87 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/BuildFile.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/L1Trigger/Phase2L1GMT/interface/Constants.h b/L1Trigger/Phase2L1GMT/interface/Constants.h new file mode 100644 index 0000000000000..de88ba9f2b1da --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/Constants.h @@ -0,0 +1,1327 @@ +#ifndef PHASE2GMT_CONSTANTS +#define PHASE2GMT_CONSTANTS + +#include "ap_int.h" + +namespace Phase2L1GMT { + + // INPUT Dataformat + // Track + const int BITSTTCURV = 15; + const int BITSTTCURV2 = 27; + const int BITSTTPHI = 12; + const int BITSTTTANL = 16; + // Not used in the emulator now, but will in future + const int BITSTTZ0 = 12; + const int BITSTTD0 = 13; + const int BITSTTCHI2 = 4; + const int BITSTTBENDCHI2 = 3; + const int BITSTTMASK = 7; + const int BITSTTTRACKMVA = 3; + const int BITSTTOTHERMVA = 6; + + // Bitwidth for common internal variables in GMT + const int BITSPT = 13; + const int BITSPHI = 13; + const int BITSETA = 13; + const int BITSZ0 = 10; + const int BITSD0 = 12; + + //Muon ROI + const int BITSSTUBCOORD = 8; + const int BITSSTUBETA = 8; + const int BITSSTUBID = 9; + const int BITSSTUBPHIQUALITY = 4; + const int BITSSTUBETAQUALITY = 4; + const int BITSSTUBTIME = 8; + const int BITSSTAMUONQUALITY = 6; + const int BITSMUONBX = 4; + + //PreTrackMatherdMuon + const int BITSMATCHQUALITY = 9; + const int BITSMUONBETA = 4; + + //Track Muon Match + const int BITSSIGMAETA = 4; + const int BITSSIGMACOORD = 4; + const int BITSPROPCOORD = 9; + const int BITSPROPSIGMACOORD_A = 5; + const int BITSPROPSIGMACOORD_B = 5; + const int BITSPROPSIGMAETA_A = 5; + const int BITSPROPSIGMAETA_B = 5; + + // OUTPUT Dataformat + // Bitwidth for standalone muons to CL1 and GT + const int BITSSAZ0 = 5; + const int BITSSAD0 = 7; + const int BITSSAQUALITY = 4; + + // Bitwidth for dataformat to GT + const int BITSGTPT = 16; + const int BITSGTPHI = 13; + const int BITSGTETA = 14; + const int BITSGTZ0 = 10; + const int BITSGTD0 = 10; + const int BITSGTQUALITY = 8; + const int BITSGTISO = 4; + + const float maxCurv_ = 0.00855; // 2 GeV pT Rinv is in cm + const float maxPhi_ = 1.026; // relative to the center of the sector + const float maxTanl_ = 8.0; + const float maxZ0_ = 30.; + const float maxD0_ = 15.4; + const int barrelLimit0_ = 181 / 4; + const int barrelLimit1_ = 160 / 4; + const int barrelLimit2_ = 140 / 4; + const int barrelLimit3_ = 110 / 4; + const int barrelLimit4_ = 0; + + // LSB + const float LSBpt = 0.03125; + const float LSBphi = 2. * M_PI / pow(2, BITSPHI); + const float LSBeta = 2. * M_PI / pow(2, BITSETA); + const float LSBGTz0 = 2. * maxZ0_ / pow(2, BITSZ0); + const float LSBGTd0 = 2. * maxD0_ / pow(2, BITSD0); + const float LSBSAz0 = 1.875; + const float LSBSAd0 = 3.85; + + typedef ap_uint<64> wordtype; + + inline uint64_t twos_complement(long long int v, uint bits) { + uint64_t mask = (1 << bits) - 1; + if (v >= 0) + return v & mask; + else + return (~(-v) + 1) & mask; + } + + template + inline int wordconcat(T& word, int bstart, long int input, int bitsize) { + int bend = bstart + bitsize - 1; + word.range(bend, bstart) = twos_complement(input, bitsize); + return bend + 1; + } + + const int ptShifts[9][5] = {{1, 86, -1, 0, 0}, + {86, 1184, 0, -85, 0}, + {1184, 1674, 1, 507, 0}, + {1674, 2367, 2, 925, 0}, + {2367, 3346, 3, 1222, 0}, + {3346, 4732, 4, 1431, 0}, + {4732, 6691, 5, 1580, 0}, + {6691, 10923, 6, 1686, 0}, + {10923, 16384, -2, 0, 1857}}; + + const ap_uint ptLUT[1858] = { + 8191, 8128, 8035, 7944, 7855, 7767, 7682, 7598, 7517, 7437, 7358, 7282, 7207, 7133, 7061, 6991, 6921, 6853, 6787, + 6722, 6658, 6595, 6533, 6473, 6413, 6355, 6298, 6242, 6186, 6132, 6079, 6026, 5975, 5924, 5874, 5825, 5777, 5730, + 5683, 5638, 5592, 5548, 5504, 5461, 5419, 5377, 5336, 5296, 5256, 5217, 5178, 5140, 5103, 5066, 5029, 4993, 4958, + 4923, 4888, 4855, 4821, 4788, 4755, 4723, 4692, 4660, 4629, 4599, 4569, 4539, 4510, 4481, 4453, 4424, 4397, 4369, + 4342, 4315, 4289, 4263, 4237, 4211, 4186, 4161, 4136, 4112, 4088, 4064, 4041, 4018, 3995, 3972, 3949, 3927, 3905, + 3884, 3862, 3841, 3820, 3799, 3779, 3758, 3738, 3718, 3699, 3679, 3660, 3641, 3622, 3603, 3585, 3567, 3548, 3531, + 3513, 3495, 3478, 3461, 3444, 3427, 3410, 3393, 3377, 3361, 3345, 3329, 3313, 3297, 3282, 3267, 3251, 3236, 3221, + 3207, 3192, 3178, 3163, 3149, 3135, 3121, 3107, 3093, 3080, 3066, 3053, 3039, 3026, 3013, 3000, 2987, 2975, 2962, + 2950, 2937, 2925, 2913, 2901, 2889, 2877, 2865, 2853, 2842, 2830, 2819, 2807, 2796, 2785, 2774, 2763, 2752, 2741, + 2731, 2720, 2709, 2699, 2689, 2678, 2668, 2658, 2648, 2638, 2628, 2618, 2608, 2599, 2589, 2580, 2570, 2561, 2551, + 2542, 2533, 2524, 2515, 2506, 2497, 2488, 2479, 2470, 2461, 2453, 2444, 2436, 2427, 2419, 2411, 2402, 2394, 2386, + 2378, 2370, 2362, 2354, 2346, 2338, 2330, 2322, 2315, 2307, 2300, 2292, 2284, 2277, 2270, 2262, 2255, 2248, 2241, + 2233, 2226, 2219, 2212, 2205, 2198, 2191, 2185, 2178, 2171, 2164, 2158, 2151, 2144, 2138, 2131, 2125, 2118, 2112, + 2106, 2099, 2093, 2087, 2081, 2074, 2068, 2062, 2056, 2050, 2044, 2038, 2032, 2026, 2020, 2015, 2009, 2003, 1997, + 1992, 1986, 1980, 1975, 1969, 1964, 1958, 1953, 1947, 1942, 1936, 1931, 1926, 1920, 1915, 1910, 1905, 1900, 1894, + 1889, 1884, 1879, 1874, 1869, 1864, 1859, 1854, 1849, 1844, 1840, 1835, 1830, 1825, 1820, 1816, 1811, 1806, 1802, + 1797, 1792, 1788, 1783, 1779, 1774, 1770, 1765, 1761, 1756, 1752, 1748, 1743, 1739, 1735, 1730, 1726, 1722, 1718, + 1713, 1709, 1705, 1701, 1697, 1693, 1689, 1684, 1680, 1676, 1672, 1668, 1664, 1660, 1657, 1653, 1649, 1645, 1641, + 1637, 1633, 1629, 1626, 1622, 1618, 1614, 1611, 1607, 1603, 1600, 1596, 1592, 1589, 1585, 1582, 1578, 1574, 1571, + 1567, 1564, 1560, 1557, 1553, 1550, 1547, 1543, 1540, 1536, 1533, 1530, 1526, 1523, 1520, 1516, 1513, 1510, 1507, + 1503, 1500, 1497, 1494, 1491, 1487, 1484, 1481, 1478, 1475, 1472, 1469, 1466, 1462, 1459, 1456, 1453, 1450, 1447, + 1444, 1441, 1438, 1435, 1432, 1430, 1427, 1424, 1421, 1418, 1415, 1412, 1409, 1407, 1404, 1401, 1398, 1395, 1393, + 1390, 1387, 1384, 1382, 1379, 1376, 1373, 1371, 1368, 1365, 1363, 1360, 1357, 1355, 1352, 1350, 1347, 1344, 1342, + 1339, 1337, 1334, 1332, 1329, 1326, 1324, 1321, 1319, 1316, 1314, 1312, 1309, 1307, 1304, 1302, 1299, 1297, 1295, + 1292, 1290, 1287, 1285, 1283, 1280, 1278, 1276, 1273, 1271, 1269, 1266, 1264, 1262, 1260, 1257, 1255, 1253, 1251, + 1248, 1246, 1244, 1242, 1239, 1237, 1235, 1233, 1231, 1229, 1226, 1224, 1222, 1220, 1218, 1216, 1214, 1212, 1209, + 1207, 1205, 1203, 1201, 1199, 1197, 1195, 1193, 1191, 1189, 1187, 1185, 1183, 1181, 1179, 1177, 1175, 1173, 1171, + 1169, 1167, 1165, 1163, 1161, 1159, 1157, 1155, 1154, 1152, 1150, 1148, 1146, 1144, 1142, 1140, 1139, 1137, 1135, + 1133, 1131, 1129, 1128, 1126, 1124, 1122, 1120, 1118, 1117, 1115, 1113, 1111, 1110, 1108, 1106, 1104, 1103, 1101, + 1099, 1097, 1096, 1094, 1092, 1091, 1089, 1087, 1085, 1084, 1082, 1080, 1079, 1077, 1075, 1074, 1072, 1071, 1069, + 1067, 1066, 1064, 1062, 1061, 1059, 1058, 1056, 1054, 1053, 1051, 1050, 1048, 1046, 1045, 1043, 1042, 1040, 1039, + 1037, 1036, 1034, 1033, 1031, 1030, 1028, 1027, 1025, 1024, 1022, 1021, 1019, 1018, 1016, 1015, 1013, 1012, 1010, + 1009, 1007, 1006, 1004, 1003, 1002, 1000, 999, 997, 996, 994, 993, 992, 990, 989, 987, 986, 985, 983, + 982, 980, 979, 978, 976, 975, 974, 972, 971, 970, 968, 967, 966, 964, 963, 962, 960, 959, 958, + 956, 955, 954, 952, 951, 950, 949, 947, 946, 945, 943, 942, 941, 940, 938, 937, 936, 935, 933, + 932, 931, 930, 928, 927, 926, 925, 923, 922, 921, 920, 919, 917, 916, 915, 914, 913, 911, 910, + 909, 908, 907, 906, 904, 903, 902, 901, 900, 899, 897, 896, 895, 894, 893, 892, 891, 889, 888, + 887, 886, 885, 884, 883, 882, 880, 879, 878, 877, 876, 875, 874, 873, 872, 871, 869, 868, 867, + 866, 865, 864, 863, 862, 861, 860, 859, 858, 857, 856, 855, 854, 853, 851, 850, 849, 848, 847, + 846, 845, 844, 843, 842, 841, 840, 839, 838, 837, 836, 835, 834, 833, 832, 831, 830, 829, 828, + 827, 826, 825, 824, 823, 822, 821, 820, 820, 819, 818, 817, 816, 815, 814, 813, 812, 811, 810, + 809, 808, 807, 806, 805, 804, 804, 803, 802, 801, 800, 799, 798, 797, 796, 795, 794, 793, 793, + 792, 791, 790, 789, 788, 787, 786, 785, 785, 784, 783, 782, 781, 780, 779, 778, 778, 777, 776, + 775, 774, 773, 772, 772, 771, 770, 769, 768, 767, 767, 766, 765, 764, 763, 762, 761, 761, 760, + 759, 758, 757, 757, 756, 755, 754, 753, 752, 752, 751, 750, 749, 748, 748, 747, 746, 745, 744, + 744, 743, 742, 741, 741, 740, 739, 738, 737, 737, 736, 735, 734, 734, 733, 732, 731, 730, 730, + 729, 728, 727, 727, 726, 725, 724, 724, 723, 722, 721, 721, 720, 719, 718, 718, 717, 716, 716, + 715, 714, 713, 713, 712, 711, 710, 710, 709, 708, 708, 707, 706, 705, 705, 704, 703, 703, 702, + 701, 700, 700, 699, 698, 698, 697, 696, 696, 695, 694, 694, 693, 692, 691, 691, 690, 689, 689, + 688, 687, 687, 686, 685, 685, 684, 683, 683, 682, 681, 681, 680, 679, 679, 678, 677, 677, 676, + 675, 675, 674, 673, 673, 672, 672, 671, 670, 670, 669, 668, 668, 667, 666, 666, 665, 664, 664, + 663, 663, 662, 661, 661, 660, 659, 659, 658, 658, 657, 656, 656, 655, 655, 654, 653, 653, 652, + 651, 651, 650, 650, 649, 648, 648, 647, 647, 646, 645, 645, 644, 644, 643, 643, 642, 641, 641, + 640, 640, 639, 638, 638, 637, 637, 636, 636, 635, 634, 634, 633, 633, 632, 631, 631, 630, 630, + 629, 629, 628, 628, 627, 626, 626, 625, 625, 624, 624, 623, 622, 622, 621, 621, 620, 620, 619, + 619, 618, 618, 617, 616, 616, 615, 615, 614, 614, 613, 613, 612, 612, 611, 611, 610, 609, 609, + 608, 608, 607, 607, 606, 606, 605, 605, 604, 604, 603, 603, 602, 602, 601, 601, 600, 600, 599, + 599, 598, 597, 597, 596, 596, 595, 595, 594, 594, 593, 593, 592, 592, 591, 591, 590, 589, 588, + 587, 586, 585, 584, 583, 582, 581, 580, 579, 578, 577, 576, 575, 574, 573, 573, 572, 571, 570, + 569, 568, 567, 566, 565, 564, 563, 562, 561, 561, 560, 559, 558, 557, 556, 555, 554, 553, 553, + 552, 551, 550, 549, 548, 547, 547, 546, 545, 544, 543, 542, 541, 541, 540, 539, 538, 537, 536, + 536, 535, 534, 533, 532, 532, 531, 530, 529, 528, 528, 527, 526, 525, 524, 524, 523, 522, 521, + 521, 520, 519, 518, 517, 517, 516, 515, 514, 514, 513, 512, 511, 511, 510, 509, 508, 508, 507, + 506, 505, 505, 504, 503, 503, 502, 501, 500, 500, 499, 498, 498, 497, 496, 495, 495, 494, 493, + 493, 492, 491, 491, 490, 489, 489, 488, 487, 486, 486, 485, 484, 484, 483, 482, 482, 481, 480, + 480, 479, 478, 478, 477, 477, 476, 475, 475, 474, 473, 473, 472, 471, 471, 470, 469, 469, 468, + 468, 467, 466, 466, 465, 464, 464, 463, 463, 462, 461, 461, 460, 460, 459, 458, 458, 457, 457, + 456, 455, 455, 454, 454, 453, 452, 452, 451, 451, 450, 450, 449, 448, 448, 447, 447, 446, 446, + 445, 444, 444, 443, 443, 442, 442, 441, 440, 440, 439, 439, 438, 438, 437, 437, 436, 436, 435, + 434, 434, 433, 433, 432, 432, 431, 431, 430, 430, 429, 429, 428, 428, 427, 427, 426, 425, 425, + 424, 424, 423, 423, 422, 422, 421, 421, 420, 420, 419, 419, 418, 418, 417, 416, 415, 414, 413, + 412, 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 399, 398, 397, 396, 395, + 394, 393, 392, 391, 391, 390, 389, 388, 387, 386, 385, 385, 384, 383, 382, 381, 380, 380, 379, + 378, 377, 376, 375, 375, 374, 373, 372, 371, 371, 370, 369, 368, 368, 367, 366, 365, 364, 364, + 363, 362, 361, 361, 360, 359, 358, 358, 357, 356, 356, 355, 354, 353, 353, 352, 351, 351, 350, + 349, 348, 348, 347, 346, 346, 345, 344, 344, 343, 342, 342, 341, 340, 340, 339, 338, 338, 337, + 336, 336, 335, 334, 334, 333, 333, 332, 331, 331, 330, 329, 329, 328, 328, 327, 326, 326, 325, + 325, 324, 323, 323, 322, 322, 321, 320, 320, 319, 319, 318, 317, 317, 316, 316, 315, 315, 314, + 313, 313, 312, 312, 311, 311, 310, 310, 309, 308, 308, 307, 307, 306, 306, 305, 305, 304, 304, + 303, 303, 302, 302, 301, 301, 300, 300, 299, 298, 298, 297, 297, 296, 296, 296, 295, 295, 294, + 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 281, 281, 280, 279, 278, 277, 276, + 275, 274, 273, 273, 272, 271, 270, 269, 268, 268, 267, 266, 265, 264, 264, 263, 262, 261, 260, + 260, 259, 258, 257, 257, 256, 255, 254, 254, 253, 252, 251, 251, 250, 249, 249, 248, 247, 246, + 246, 245, 244, 244, 243, 242, 242, 241, 240, 240, 239, 238, 238, 237, 236, 236, 235, 235, 234, + 233, 233, 232, 231, 231, 230, 230, 229, 228, 228, 227, 227, 226, 226, 225, 224, 224, 223, 223, + 222, 221, 221, 220, 220, 219, 219, 218, 218, 217, 217, 216, 215, 215, 214, 214, 213, 213, 212, + 212, 211, 211, 210, 210, 209, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, + 196, 195, 195, 194, 193, 192, 191, 190, 190, 189, 188, 187, 186, 186, 185, 184, 183, 182, 182, + 181, 180, 179, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172, 172, 171, 170, 170, 169, 168, + 168, 167, 166, 166, 165, 165, 164, 163, 163, 162, 162, 161, 160, 160, 159, 159, 158, 157, 157, + 156, 156, 155, 155, 154, 154, 153, 152, 152, 151, 151, 150, 150, 149, 149, 148, 148, 148, 147, + 146, 145, 144, 143, 142, 141, 140, 140, 139, 138, 137, 136, 135, 134, 134, 133, 132, 131, 130, + 130, 129, 128, 127, 127, 126, 125, 124, 124, 123, 122, 122, 121, 120, 120, 119, 118, 118, 117, + 117, 116, 115, 115, 114, 113, 113, 112, 112, 111, 111, 110, 110, 109, 108, 108, 107, 107, 106, + 106, 105, 105, 105, 104, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 95, 94, 93, 92, + 91, 91, 90, 89, 88, 88, 87, 86, 86, 85, 84, 84, 83, 82, 82, 81, 81, 80, 79, + 79, 78, 78, 77, 77, 76, 76, 75, 75, 74, 74, 73, 73, 72, 72, 71, 71, 70, 70, + 69, 69, 68, 68, 68, 67, 67, 66, 66, 66, 65, 65, 64, 64, 64}; + + const int etaShifts[4][5] = { + {0, 3230, 1, 0, 0}, {3230, 9594, 2, 808, 0}, {9594, 23557, 4, 2608, 0}, {23557, 32768, -2, 0, 4081}}; + + const uint etaLUT[4082] = { + 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 11, + 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 20, 20, 21, 22, 22, 23, 24, + 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 32, 33, 34, 34, 35, 36, + 36, 37, 38, 38, 39, 39, 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 46, 47, 48, + 48, 49, 50, 50, 51, 52, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 59, 60, + 60, 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68, 69, 69, 70, 71, 71, 72, + 73, 73, 74, 74, 75, 76, 76, 77, 78, 78, 79, 80, 80, 81, 81, 82, 83, 83, 84, + 85, 85, 86, 87, 87, 88, 88, 89, 90, 90, 91, 92, 92, 93, 94, 94, 95, 95, 96, + 97, 97, 98, 99, 100, 100, 100, 101, 102, 102, 103, 104, 104, 105, 106, 106, 107, 107, 108, + 109, 109, 110, 111, 111, 112, 113, 113, 114, 114, 115, 116, 116, 117, 118, 118, 119, 120, 120, + 121, 121, 122, 123, 123, 124, 125, 125, 126, 126, 127, 128, 128, 129, 130, 130, 131, 132, 132, + 133, 133, 134, 135, 135, 136, 137, 137, 138, 139, 139, 140, 140, 141, 142, 142, 143, 144, 144, + 145, 145, 146, 147, 147, 148, 149, 149, 150, 151, 151, 152, 152, 153, 154, 154, 155, 156, 156, + 157, 157, 158, 159, 159, 160, 161, 161, 162, 163, 163, 164, 164, 165, 166, 166, 167, 168, 168, + 169, 169, 170, 171, 171, 172, 173, 173, 174, 175, 175, 176, 176, 177, 178, 178, 179, 180, 180, + 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 188, 189, 190, 190, 191, 192, 192, + 193, 193, 194, 195, 195, 196, 197, 197, 198, 198, 199, 200, 200, 201, 202, 202, 203, 204, 204, + 205, 205, 206, 207, 207, 208, 209, 209, 210, 210, 211, 212, 212, 213, 214, 214, 215, 215, 216, + 217, 217, 218, 219, 219, 220, 220, 221, 222, 222, 223, 224, 224, 225, 226, 226, 227, 227, 228, + 229, 229, 230, 231, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 237, 238, 239, 239, 240, + 241, 241, 242, 242, 243, 244, 244, 245, 246, 246, 247, 247, 248, 249, 249, 250, 251, 251, 252, + 252, 253, 254, 254, 255, 256, 256, 257, 257, 258, 259, 259, 260, 261, 261, 262, 262, 263, 264, + 264, 265, 266, 266, 267, 267, 268, 269, 269, 270, 271, 271, 272, 272, 273, 274, 274, 275, 276, + 276, 277, 277, 278, 279, 279, 280, 280, 281, 282, 282, 283, 284, 284, 285, 285, 286, 287, 287, + 288, 289, 289, 290, 290, 291, 292, 292, 293, 294, 294, 295, 295, 296, 297, 297, 298, 299, 299, + 300, 300, 301, 302, 302, 303, 303, 304, 305, 305, 306, 307, 307, 308, 308, 309, 310, 310, 311, + 312, 312, 313, 313, 314, 315, 315, 316, 316, 317, 318, 318, 319, 320, 320, 321, 321, 322, 323, + 323, 324, 324, 325, 326, 326, 327, 328, 328, 329, 329, 330, 331, 331, 332, 333, 333, 334, 334, + 335, 336, 336, 337, 337, 338, 339, 339, 340, 341, 341, 342, 342, 343, 344, 344, 345, 345, 346, + 347, 347, 348, 349, 349, 350, 350, 351, 352, 352, 353, 353, 354, 355, 355, 356, 357, 357, 358, + 358, 359, 360, 360, 361, 361, 362, 363, 363, 364, 364, 365, 366, 366, 367, 368, 368, 369, 369, + 370, 371, 371, 372, 372, 373, 374, 374, 375, 375, 376, 377, 377, 378, 379, 379, 380, 380, 381, + 382, 382, 383, 383, 384, 385, 385, 386, 386, 387, 388, 388, 389, 390, 390, 391, 391, 392, 393, + 393, 394, 394, 395, 396, 396, 397, 397, 398, 399, 399, 400, 400, 401, 402, 402, 403, 404, 404, + 405, 405, 406, 407, 407, 408, 408, 409, 410, 410, 411, 411, 412, 413, 413, 414, 414, 415, 416, + 416, 417, 417, 418, 419, 419, 420, 420, 421, 422, 422, 423, 424, 424, 425, 425, 426, 427, 427, + 428, 428, 429, 430, 430, 431, 431, 432, 433, 433, 434, 434, 435, 436, 436, 437, 437, 438, 439, + 439, 440, 440, 441, 442, 442, 443, 443, 444, 445, 445, 446, 446, 447, 448, 448, 449, 449, 450, + 451, 451, 452, 452, 453, 454, 454, 455, 455, 456, 457, 457, 458, 458, 459, 460, 460, 461, 461, + 462, 463, 463, 464, 464, 465, 466, 466, 467, 467, 468, 469, 469, 470, 470, 471, 472, 472, 473, + 473, 474, 475, 475, 476, 476, 477, 478, 478, 479, 479, 480, 481, 481, 482, 482, 483, 483, 484, + 485, 485, 486, 486, 487, 488, 488, 489, 489, 490, 491, 491, 492, 492, 493, 494, 494, 495, 495, + 496, 497, 497, 498, 498, 499, 500, 500, 501, 501, 502, 502, 503, 504, 504, 505, 505, 506, 507, + 507, 508, 508, 509, 510, 510, 511, 511, 512, 513, 513, 514, 514, 515, 515, 516, 517, 517, 518, + 518, 519, 520, 520, 521, 521, 522, 523, 523, 524, 524, 525, 526, 526, 527, 527, 528, 528, 529, + 530, 530, 531, 531, 532, 533, 533, 534, 534, 535, 535, 536, 537, 537, 538, 538, 539, 540, 540, + 541, 541, 542, 543, 543, 544, 544, 545, 545, 546, 547, 547, 548, 548, 549, 550, 550, 551, 551, + 552, 552, 553, 554, 554, 555, 555, 556, 557, 557, 558, 558, 559, 559, 560, 561, 561, 562, 562, + 563, 564, 564, 565, 565, 566, 566, 567, 568, 568, 569, 569, 570, 570, 571, 572, 572, 573, 573, + 574, 575, 575, 576, 576, 577, 577, 578, 579, 579, 580, 580, 581, 581, 582, 583, 583, 584, 584, + 585, 586, 586, 587, 587, 588, 588, 589, 590, 590, 591, 591, 592, 592, 593, 594, 594, 595, 595, + 596, 596, 597, 598, 598, 599, 599, 600, 601, 601, 602, 602, 603, 603, 604, 605, 605, 606, 606, + 607, 607, 608, 609, 609, 610, 610, 611, 611, 612, 613, 613, 614, 614, 615, 615, 616, 617, 617, + 618, 618, 619, 619, 620, 621, 621, 622, 622, 623, 623, 624, 625, 625, 626, 626, 627, 627, 628, + 629, 629, 630, 630, 631, 631, 632, 633, 633, 634, 634, 635, 635, 636, 636, 637, 638, 638, 639, + 639, 640, 640, 641, 642, 642, 643, 643, 644, 644, 645, 646, 646, 647, 647, 648, 648, 649, 650, + 650, 651, 651, 652, 652, 653, 653, 654, 655, 655, 656, 656, 657, 657, 658, 659, 659, 660, 660, + 661, 661, 662, 662, 663, 664, 664, 665, 665, 666, 666, 667, 668, 668, 669, 669, 670, 670, 671, + 671, 672, 673, 673, 674, 674, 675, 675, 676, 677, 677, 678, 678, 679, 679, 680, 680, 681, 682, + 682, 683, 683, 684, 684, 685, 685, 686, 687, 687, 688, 688, 689, 689, 690, 690, 691, 692, 692, + 693, 693, 694, 694, 695, 695, 696, 697, 697, 698, 698, 699, 699, 700, 700, 701, 702, 702, 703, + 703, 704, 704, 705, 705, 706, 707, 707, 708, 708, 709, 709, 710, 710, 711, 712, 712, 713, 713, + 714, 714, 715, 715, 716, 717, 717, 718, 718, 719, 719, 720, 720, 721, 721, 722, 723, 723, 724, + 724, 725, 725, 726, 726, 727, 728, 728, 729, 729, 730, 730, 731, 731, 732, 732, 733, 734, 734, + 735, 735, 736, 736, 737, 737, 738, 738, 739, 740, 740, 741, 741, 742, 742, 743, 743, 744, 744, + 745, 746, 746, 747, 747, 748, 748, 749, 749, 750, 750, 751, 752, 752, 753, 753, 754, 754, 755, + 755, 756, 756, 757, 758, 758, 759, 759, 760, 760, 761, 761, 762, 762, 763, 763, 764, 765, 765, + 766, 766, 767, 767, 768, 768, 769, 769, 770, 771, 771, 772, 772, 773, 773, 774, 774, 775, 775, + 776, 776, 777, 778, 778, 779, 779, 780, 780, 781, 781, 782, 782, 783, 783, 784, 784, 785, 786, + 786, 787, 787, 788, 788, 789, 789, 790, 790, 791, 791, 792, 793, 793, 794, 794, 795, 795, 796, + 796, 797, 797, 798, 798, 799, 799, 800, 801, 801, 802, 802, 803, 803, 804, 804, 805, 805, 806, + 806, 807, 807, 808, 809, 809, 810, 810, 811, 811, 812, 812, 813, 813, 814, 814, 815, 815, 816, + 816, 817, 818, 818, 819, 819, 820, 820, 821, 821, 822, 822, 823, 823, 824, 824, 825, 825, 826, + 827, 827, 828, 828, 829, 829, 830, 830, 831, 831, 832, 832, 833, 833, 834, 834, 835, 835, 836, + 837, 837, 838, 838, 839, 839, 840, 840, 841, 841, 842, 842, 843, 843, 844, 844, 845, 845, 846, + 846, 847, 848, 848, 849, 849, 850, 850, 851, 851, 852, 852, 853, 853, 854, 854, 855, 855, 856, + 856, 857, 857, 858, 858, 859, 859, 860, 861, 861, 862, 862, 863, 863, 864, 864, 865, 865, 866, + 866, 867, 867, 868, 868, 869, 869, 870, 870, 871, 871, 872, 872, 873, 873, 874, 874, 875, 876, + 876, 877, 877, 878, 878, 879, 879, 880, 880, 881, 881, 882, 882, 883, 883, 884, 884, 885, 885, + 886, 886, 887, 887, 888, 888, 889, 889, 890, 890, 891, 891, 892, 892, 893, 894, 894, 895, 895, + 896, 896, 897, 897, 898, 898, 899, 899, 900, 900, 901, 901, 902, 902, 903, 903, 904, 904, 905, + 905, 906, 906, 907, 907, 908, 908, 909, 909, 910, 910, 911, 911, 912, 912, 913, 913, 914, 914, + 915, 915, 916, 916, 917, 917, 918, 918, 919, 919, 920, 920, 921, 921, 922, 922, 923, 923, 924, + 925, 925, 926, 926, 927, 927, 928, 928, 929, 929, 930, 930, 931, 931, 932, 932, 933, 933, 934, + 934, 935, 935, 936, 936, 937, 937, 938, 938, 939, 939, 940, 940, 941, 941, 942, 942, 943, 943, + 944, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, + 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, + 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, + 1000, 1001, 1002, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, + 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1030, 1031, 1032, 1033, 1034, 1035, + 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1050, 1051, 1052, 1053, + 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1067, 1068, 1069, 1070, 1071, + 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, + 1090, 1091, 1092, 1093, 1094, 1095, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, + 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1118, 1119, 1120, 1121, 1122, 1123, 1124, + 1125, 1126, 1127, 1128, 1129, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1139, 1140, 1141, + 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1157, 1158, + 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1174, 1175, + 1176, 1177, 1178, 1179, 1180, 1181, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1189, 1190, 1191, 1192, + 1193, 1194, 1195, 1196, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1203, 1204, 1205, 1206, 1207, 1208, 1209, + 1210, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1223, 1224, 1225, + 1226, 1227, 1228, 1229, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1236, 1237, 1238, 1239, 1240, 1241, 1241, + 1242, 1243, 1244, 1245, 1246, 1247, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1253, 1254, 1255, 1256, 1257, 1258, + 1259, 1259, 1260, 1261, 1262, 1263, 1264, 1264, 1265, 1266, 1267, 1268, 1269, 1269, 1270, 1271, 1272, 1273, 1274, + 1275, 1275, 1276, 1277, 1278, 1279, 1280, 1280, 1281, 1282, 1283, 1284, 1285, 1285, 1286, 1287, 1288, 1289, 1290, + 1290, 1291, 1292, 1293, 1294, 1295, 1295, 1296, 1297, 1298, 1299, 1300, 1300, 1301, 1302, 1303, 1304, 1304, 1305, + 1306, 1307, 1308, 1309, 1309, 1310, 1311, 1312, 1313, 1314, 1314, 1315, 1316, 1317, 1318, 1318, 1319, 1320, 1321, + 1322, 1323, 1323, 1324, 1325, 1326, 1327, 1327, 1328, 1329, 1330, 1331, 1331, 1332, 1333, 1334, 1335, 1336, 1336, + 1337, 1338, 1339, 1340, 1340, 1341, 1342, 1343, 1344, 1344, 1345, 1346, 1347, 1348, 1348, 1349, 1350, 1351, 1352, + 1352, 1353, 1354, 1355, 1356, 1356, 1357, 1358, 1359, 1360, 1360, 1361, 1362, 1363, 1364, 1364, 1365, 1366, 1367, + 1368, 1368, 1369, 1370, 1371, 1372, 1372, 1373, 1374, 1375, 1376, 1376, 1377, 1378, 1379, 1380, 1380, 1381, 1382, + 1383, 1383, 1384, 1385, 1386, 1387, 1387, 1388, 1389, 1390, 1391, 1391, 1392, 1393, 1394, 1394, 1395, 1396, 1397, + 1398, 1398, 1399, 1400, 1401, 1401, 1402, 1403, 1404, 1405, 1405, 1406, 1407, 1408, 1408, 1409, 1410, 1411, 1412, + 1412, 1413, 1414, 1415, 1415, 1416, 1417, 1418, 1418, 1419, 1420, 1421, 1422, 1422, 1423, 1424, 1425, 1425, 1426, + 1427, 1428, 1428, 1429, 1430, 1431, 1432, 1432, 1433, 1434, 1435, 1435, 1436, 1437, 1438, 1438, 1439, 1440, 1441, + 1441, 1442, 1443, 1444, 1444, 1445, 1446, 1447, 1448, 1448, 1449, 1450, 1451, 1451, 1452, 1453, 1454, 1454, 1455, + 1456, 1457, 1457, 1458, 1459, 1460, 1460, 1461, 1462, 1463, 1463, 1464, 1465, 1466, 1466, 1467, 1468, 1469, 1469, + 1470, 1471, 1472, 1472, 1473, 1474, 1475, 1475, 1476, 1477, 1478, 1478, 1479, 1480, 1480, 1481, 1482, 1483, 1483, + 1484, 1485, 1486, 1486, 1487, 1488, 1489, 1489, 1490, 1491, 1492, 1492, 1493, 1494, 1495, 1495, 1496, 1497, 1497, + 1498, 1499, 1500, 1500, 1501, 1502, 1503, 1503, 1504, 1505, 1505, 1506, 1507, 1508, 1508, 1509, 1510, 1511, 1511, + 1512, 1513, 1514, 1514, 1515, 1516, 1516, 1517, 1518, 1519, 1519, 1520, 1521, 1521, 1522, 1523, 1524, 1524, 1525, + 1526, 1527, 1527, 1528, 1529, 1529, 1530, 1531, 1532, 1532, 1533, 1534, 1534, 1535, 1536, 1537, 1537, 1538, 1539, + 1539, 1540, 1541, 1542, 1542, 1543, 1544, 1544, 1545, 1546, 1547, 1547, 1548, 1549, 1549, 1550, 1551, 1552, 1552, + 1553, 1554, 1554, 1555, 1556, 1556, 1557, 1558, 1559, 1559, 1560, 1561, 1561, 1562, 1563, 1564, 1564, 1565, 1566, + 1566, 1567, 1568, 1568, 1569, 1570, 1571, 1571, 1572, 1573, 1573, 1574, 1575, 1575, 1576, 1577, 1578, 1578, 1579, + 1580, 1580, 1581, 1582, 1582, 1583, 1584, 1585, 1585, 1586, 1587, 1587, 1588, 1589, 1589, 1590, 1591, 1591, 1592, + 1593, 1594, 1594, 1595, 1596, 1596, 1597, 1598, 1598, 1599, 1600, 1600, 1601, 1602, 1602, 1603, 1604, 1605, 1605, + 1606, 1607, 1607, 1608, 1609, 1609, 1610, 1611, 1611, 1612, 1613, 1613, 1614, 1615, 1615, 1616, 1617, 1617, 1618, + 1619, 1620, 1620, 1621, 1622, 1622, 1623, 1624, 1624, 1625, 1626, 1626, 1627, 1628, 1628, 1629, 1630, 1630, 1631, + 1632, 1632, 1633, 1634, 1634, 1635, 1636, 1636, 1637, 1638, 1638, 1639, 1640, 1640, 1641, 1642, 1642, 1643, 1644, + 1644, 1645, 1646, 1646, 1647, 1648, 1648, 1649, 1650, 1650, 1651, 1652, 1652, 1653, 1654, 1654, 1655, 1656, 1656, + 1657, 1658, 1658, 1659, 1660, 1660, 1661, 1662, 1662, 1663, 1664, 1664, 1665, 1666, 1666, 1667, 1668, 1668, 1669, + 1670, 1670, 1671, 1672, 1672, 1673, 1674, 1674, 1675, 1676, 1676, 1677, 1677, 1678, 1679, 1679, 1680, 1681, 1681, + 1682, 1683, 1683, 1684, 1685, 1685, 1686, 1687, 1687, 1688, 1689, 1689, 1690, 1690, 1691, 1692, 1692, 1693, 1694, + 1694, 1695, 1696, 1696, 1697, 1698, 1698, 1699, 1700, 1700, 1701, 1701, 1702, 1703, 1703, 1704, 1705, 1705, 1706, + 1707, 1707, 1708, 1709, 1709, 1710, 1710, 1711, 1712, 1712, 1713, 1714, 1714, 1715, 1716, 1716, 1717, 1717, 1718, + 1719, 1719, 1720, 1721, 1721, 1722, 1723, 1723, 1724, 1724, 1725, 1726, 1726, 1727, 1728, 1728, 1729, 1729, 1730, + 1731, 1731, 1732, 1733, 1733, 1734, 1735, 1735, 1736, 1736, 1737, 1738, 1738, 1739, 1740, 1740, 1741, 1741, 1742, + 1743, 1743, 1744, 1745, 1745, 1746, 1746, 1747, 1748, 1748, 1749, 1750, 1750, 1751, 1751, 1752, 1753, 1753, 1754, + 1755, 1755, 1756, 1756, 1757, 1758, 1758, 1759, 1759, 1760, 1761, 1761, 1762, 1763, 1763, 1764, 1764, 1765, 1766, + 1766, 1767, 1768, 1768, 1769, 1769, 1770, 1771, 1771, 1772, 1772, 1773, 1774, 1774, 1775, 1775, 1776, 1777, 1777, + 1778, 1779, 1779, 1780, 1780, 1781, 1782, 1782, 1783, 1783, 1784, 1785, 1785, 1786, 1786, 1787, 1788, 1788, 1789, + 1790, 1790, 1791, 1791, 1792, 1793, 1793, 1794, 1794, 1795, 1796, 1796, 1797, 1797, 1798, 1799, 1799, 1800, 1800, + 1801, 1802, 1802, 1803, 1803, 1804, 1805, 1805, 1806, 1806, 1807, 1808, 1808, 1809, 1809, 1810, 1811, 1811, 1812, + 1812, 1813, 1814, 1814, 1815, 1815, 1816, 1817, 1817, 1818, 1818, 1819, 1820, 1820, 1821, 1821, 1822, 1822, 1823, + 1824, 1824, 1825, 1825, 1826, 1827, 1827, 1828, 1828, 1829, 1830, 1830, 1831, 1831, 1832, 1833, 1833, 1834, 1834, + 1835, 1835, 1836, 1837, 1837, 1838, 1838, 1839, 1840, 1840, 1841, 1841, 1842, 1843, 1843, 1844, 1844, 1845, 1845, + 1846, 1847, 1847, 1848, 1848, 1849, 1850, 1850, 1851, 1851, 1852, 1852, 1853, 1854, 1854, 1855, 1855, 1856, 1857, + 1857, 1858, 1858, 1859, 1859, 1860, 1861, 1861, 1862, 1862, 1863, 1863, 1864, 1865, 1865, 1866, 1866, 1867, 1867, + 1868, 1869, 1869, 1870, 1870, 1871, 1871, 1872, 1873, 1873, 1874, 1874, 1875, 1876, 1876, 1877, 1877, 1878, 1878, + 1879, 1880, 1880, 1881, 1881, 1882, 1882, 1883, 1883, 1884, 1885, 1885, 1886, 1886, 1887, 1887, 1888, 1889, 1889, + 1890, 1890, 1891, 1891, 1892, 1893, 1893, 1894, 1894, 1895, 1895, 1896, 1897, 1897, 1898, 1898, 1899, 1899, 1900, + 1900, 1901, 1902, 1902, 1903, 1903, 1904, 1904, 1905, 1906, 1906, 1907, 1907, 1908, 1908, 1909, 1909, 1910, 1911, + 1911, 1912, 1912, 1913, 1913, 1914, 1914, 1915, 1916, 1916, 1917, 1917, 1918, 1918, 1919, 1919, 1920, 1921, 1921, + 1922, 1922, 1923, 1923, 1924, 1924, 1925, 1926, 1926, 1927, 1927, 1928, 1928, 1929, 1929, 1930, 1931, 1931, 1932, + 1932, 1933, 1933, 1934, 1934, 1935, 1935, 1936, 1937, 1937, 1938, 1938, 1939, 1939, 1940, 1940, 1941, 1941, 1942, + 1943, 1943, 1944, 1944, 1945, 1945, 1946, 1946, 1947, 1947, 1948, 1949, 1949, 1950, 1950, 1951, 1951, 1952, 1952, + 1953, 1953, 1954, 1955, 1955, 1956, 1956, 1957, 1957, 1958, 1958, 1959, 1959, 1960, 1960, 1961, 1962, 1962, 1963, + 1963, 1964, 1964, 1965, 1965, 1966, 1966, 1967, 1967, 1968, 1969, 1969, 1970, 1970, 1971, 1971, 1972, 1972, 1973, + 1973, 1974, 1974, 1975, 1976, 1976, 1977, 1977, 1978, 1978, 1979, 1979, 1980, 1980, 1981, 1981, 1982, 1982, 1983, + 1983, 1984, 1985, 1985, 1986, 1986, 1987, 1987, 1988, 1988, 1989, 1989, 1990, 1990, 1991, 1991, 1992, 1992, 1993, + 1994, 1994, 1995, 1995, 1996, 1996, 1997, 1997, 1998, 1998, 1999, 1999, 2000, 2000, 2001, 2001, 2002, 2002, 2003, + 2004, 2004, 2005, 2005, 2006, 2006, 2007, 2007, 2008, 2008, 2009, 2009, 2010, 2010, 2011, 2011, 2012, 2012, 2013, + 2013, 2014, 2014, 2015, 2016, 2016, 2017, 2017, 2018, 2018, 2019, 2019, 2020, 2020, 2021, 2021, 2022, 2022, 2023, + 2023, 2024, 2024, 2025, 2025, 2026, 2026, 2027, 2027, 2028, 2028, 2029, 2029, 2030, 2030, 2031, 2032, 2032, 2033, + 2033, 2034, 2034, 2035, 2035, 2036, 2036, 2037, 2037, 2038, 2038, 2039, 2039, 2040, 2040, 2041, 2041, 2042, 2042, + 2043, 2043, 2044, 2044, 2045, 2045, 2046, 2046, 2047, 2047, 2048, 2048, 2049, 2049, 2050, 2050, 2051, 2051, 2052, + 2052, 2053, 2053, 2054, 2054, 2055, 2055, 2056, 2056, 2057, 2057, 2058, 2058, 2059, 2059, 2060, 2060, 2061, 2061, + 2062, 2062, 2063, 2064, 2064, 2065, 2065, 2066, 2066, 2067, 2067, 2068, 2068, 2069, 2069, 2069, 2071, 2073, 2075, + 2077, 2079, 2081, 2083, 2085, 2087, 2089, 2091, 2093, 2095, 2096, 2098, 2100, 2102, 2104, 2106, 2108, 2110, 2112, + 2114, 2116, 2118, 2120, 2122, 2124, 2126, 2128, 2129, 2131, 2133, 2135, 2137, 2139, 2141, 2143, 2145, 2147, 2148, + 2150, 2152, 2154, 2156, 2158, 2160, 2162, 2164, 2165, 2167, 2169, 2171, 2173, 2175, 2177, 2178, 2180, 2182, 2184, + 2186, 2188, 2189, 2191, 2193, 2195, 2197, 2199, 2200, 2202, 2204, 2206, 2208, 2210, 2211, 2213, 2215, 2217, 2219, + 2220, 2222, 2224, 2226, 2227, 2229, 2231, 2233, 2235, 2236, 2238, 2240, 2242, 2243, 2245, 2247, 2249, 2251, 2252, + 2254, 2256, 2258, 2259, 2261, 2263, 2265, 2266, 2268, 2270, 2271, 2273, 2275, 2277, 2278, 2280, 2282, 2284, 2285, + 2287, 2289, 2290, 2292, 2294, 2295, 2297, 2299, 2301, 2302, 2304, 2306, 2307, 2309, 2311, 2312, 2314, 2316, 2317, + 2319, 2321, 2322, 2324, 2326, 2327, 2329, 2331, 2332, 2334, 2336, 2337, 2339, 2341, 2342, 2344, 2346, 2347, 2349, + 2351, 2352, 2354, 2355, 2357, 2359, 2360, 2362, 2364, 2365, 2367, 2368, 2370, 2372, 2373, 2375, 2376, 2378, 2380, + 2381, 2383, 2384, 2386, 2388, 2389, 2391, 2392, 2394, 2396, 2397, 2399, 2400, 2402, 2403, 2405, 2407, 2408, 2410, + 2411, 2413, 2414, 2416, 2417, 2419, 2421, 2422, 2424, 2425, 2427, 2428, 2430, 2431, 2433, 2435, 2436, 2438, 2439, + 2441, 2442, 2444, 2445, 2447, 2448, 2450, 2451, 2453, 2454, 2456, 2457, 2459, 2460, 2462, 2463, 2465, 2466, 2468, + 2469, 2471, 2472, 2474, 2475, 2477, 2478, 2480, 2481, 2483, 2484, 2486, 2487, 2489, 2490, 2492, 2493, 2495, 2496, + 2498, 2499, 2501, 2502, 2503, 2505, 2506, 2508, 2509, 2511, 2512, 2514, 2515, 2517, 2518, 2519, 2521, 2522, 2524, + 2525, 2527, 2528, 2530, 2531, 2532, 2534, 2535, 2537, 2538, 2540, 2541, 2542, 2544, 2545, 2547, 2548, 2549, 2551, + 2552, 2554, 2555, 2557, 2558, 2559, 2561, 2562, 2564, 2565, 2566, 2568, 2569, 2570, 2572, 2573, 2575, 2576, 2577, + 2579, 2580, 2582, 2583, 2584, 2586, 2587, 2588, 2590, 2591, 2593, 2594, 2595, 2597, 2598, 2599, 2601, 2602, 2603, + 2605, 2606, 2608, 2609, 2610, 2612, 2613, 2614, 2616, 2617, 2618, 2620, 2621, 2622, 2624, 2625, 2626, 2628, 2629, + 2630, 2632, 2633, 2634, 2636, 2637, 2638, 2640, 2641, 2642, 2644, 2645, 2646, 2648, 2649, 2650, 2651, 2653, 2654, + 2655, 2657, 2658, 2659, 2661, 2662, 2663, 2665, 2666, 2667, 2668, 2670, 2671, 2672, 2674, 2675, 2676, 2677, 2679, + 2680, 2681, 2683, 2684, 2685, 2686, 2688, 2689, 2690, 2692, 2693, 2694, 2695, 2697, 2698, 2699, 2700, 2702, 2703, + 2704, 2705, 2707, 2708, 2709, 2710, 2712, 2713, 2714, 2715, 2717, 2718, 2719, 2720, 2722, 2723, 2724, 2725, 2727, + 2728, 2729, 2730, 2732, 2733, 2734, 2735, 2737, 2738, 2739, 2740, 2741, 2743, 2744, 2745, 2746, 2748, 2749, 2750, + 2751, 2752, 2754, 2755, 2756, 2757, 2759, 2760, 2761, 2762, 2763, 2765, 2766, 2767, 2768, 2769, 2771, 2772, 2773, + 2774, 2775, 2777, 2778, 2779, 2780, 2781, 2783, 2784, 2785, 2786, 2787, 2788, 2790, 2791, 2792, 2793, 2794, 2796, + 2797, 2798, 2799, 2800, 2801, 2803, 2804, 2805, 2806, 2807, 2808, 2810, 2811, 2812, 2813, 2814, 2815, 2817, 2818, + 2819, 2820, 2821, 2822, 2823, 2825, 2826, 2827, 2828, 2829, 2830, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2840, + 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2849, 2850, 2851, 2852, 2853, 2854, 2855, 2857, 2858, 2859, 2860, 2861, + 2862, 2863, 2864, 2865, 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2877, 2878, 2879, 2880, 2881, 2882, + 2883, 2884, 2885, 2887, 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2899, 2900, 2901, 2902, 2903, + 2904, 2905, 2906, 2907, 2908, 2909, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, + 2924, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940, 2941, 2943, 2944, + 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2963, + 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, + 2984, 2985, 2986, 2987, 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3000, 3001, 3002, + 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, + 3022, 3023, 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, + 3041, 3042, 3043, 3044, 3045, 3046, 3047, 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, + 3060, 3061, 3062, 3062, 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 3077, + 3078, 3079, 3080, 3081, 3082, 3083, 3084, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, + 3096, 3097, 3098, 3099, 3100, 3100, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111, 3112, 3113, + 3114, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126, 3126, 3127, 3128, 3129, 3130, + 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3137, 3138, 3139, 3140, 3141, 3142, 3143, 3144, 3145, 3146, 3146, 3147, + 3148, 3149, 3150, 3151, 3152, 3153, 3154, 3155, 3156, 3156, 3157, 3158, 3159, 3160, 3161, 3162, 3163, 3164, 3164, + 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3172, 3173, 3174, 3175, 3176, 3177, 3178, 3179, 3180, 3180, 3181, + 3182, 3183, 3184, 3185, 3186, 3187, 3187, 3188, 3189, 3190, 3191, 3192, 3193, 3194, 3194, 3194}; + + const ap_uint lt_prop_coord1_0[512] = { + 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, 165, 164, 164, + 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, + 165, 166, 166, 166, 166, 166, 167, 167, 167, 166, 166, 166, 166, 166, 165, 165, 164, 164, 163, 163, 163, 162, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, 162, 162, 162, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 162, 162, 162, 162, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 159, 159, + 158, 158, 157, 156, 155, 154, 154, 153, 152, 151, 149, 148, 147, 146, 145, 144, 142, 141, 140, 139, 137, 136, 135, + 133, 132, 131, 130, 128, 127, 126, 124, 123, 122, 121, 119, 118, 117, 116, 115, 113, 112, 111, 110, 109, 108, 107, + 105, 104, 103, 102, 101, 100, 99, 98, 98, 97, 96, 95, 94, 93, 93, 92, 91, 91, 90, 89, 89, 88, 88, + 87, 87, 87, 86, 86, 85, 85, 85, 84, 84, 83, 82, 82, 81, 81, 80, 80, 80, 79, 79, 78, 78, 78, + 77, 76, 76, 75, 75, 74, 73, 73, 72, 72, 71, 71, 71, 70, 70, 70, 69, 69, 68, 67, 67, 66, 65, + 65, 64, 64, 63, 63, 62, 62, 62, 61, 61, 61, 60, 60, 60, 59, 59, 58, 58, 58, 57, 57, 57, 56, + 56, 56, 56, 55, 55, 55, 55, 54, 54, 54, 54, 53, 53, 52, 52, 52, 51, 51, 50, 50, 49, 48, 48, + 47, 47, 47, 46, 46, 46, 46, 45, 45, 45, 45, 45, 45, 44, 44, 44, 43, 43, 43, 43, 42, 42, 42, + 42, 41, 41, 41, 41, 40, 40, 40, 40, 39, 39, 39, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38}; + + const ap_uint lt_prop_coord1_1[512] = { + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 179, 179, 179, 180, 180, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 182, 182, 182, 182, 183, 183, 183, 184, 184, + 184, 184, 184, 184, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 181, 181, 181, 181, 180, 180, 180, 180, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 177, 177, 177, 176, 176, 176, 176, 175, 175, 175, 175, 175, 175, + 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 173, 173, 173, 172, 172, 172, 171, 170, 170, 169, 169, 169, 168, + 168, 168, 167, 167, 166, 165, 165, 164, 163, 162, 161, 160, 159, 158, 158, 157, 156, 156, 155, 154, 154, 153, 153, + 153, 152, 152, 152, 152, 151, 151, 151, 150, 150, 149, 149, 148, 147, 147, 146, 145, 144, 144, 143, 142, 142, 141, + 141, 140, 140, 139, 138, 138, 137, 136, 135, 134, 133, 131, 130, 129, 128, 127, 126, 125, 124, 124, 123, 123, 122, + 122, 122, 122, 121, 121, 121, 120, 120, 119, 118, 117, 116, 115, 114, 114, 113, 113, 112, 112, 112, 112, 111, 111, + 111, 110, 109, 109, 108, 108, 107, 106, 106, 105, 104, 103, 103, 102, 101, 100, 99, 98, 97, 95, 94, 94, 93, + 93, 92, 92, 93, 93, 93, 93, 94, 93, 93, 92, 92, 91, 90, 89, 88, 87, 86, 85, 85, 84, 84, 83, + 83, 82, 82, 81, 81, 80, 80, 79, 79, 78, 78, 78, 77, 77, 76, 76, 75, 75, 74, 74, 73, 73, 72, + 72, 71, 71, 71, 70, 70, 70, 70, 70, 69, 69, 69, 68, 68, 67, 67, 66, 66, 65, 64, 64, 63, 63, + 62, 62, 61, 61, 61, 60, 60, 60, 60, 59, 59, 58, 58, 57, 57, 56, 56, 55, 55, 54, 54, 54, 54, + 53, 53, 53, 53, 53, 52, 52, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45}; + + const ap_uint lt_prop_coord1_2[512] = { + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 187, 187, 187, 187, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 185, 185, 184, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 182, 182, 182, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 179, 179, 179, 179, 178, 178, 177, 177, 176, 175, 175, 174, 174, 174, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 172, 172, 172, 172, 172, 172, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, + 172, 172, 172, 172, 172, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 171, + 171, 171, 171, 171, 170, 170, 169, 169, 168, 168, 168, 167, 167, 166, 166, 166, 165, 164, 163, 162, 162, 161, 160, + 159, 158, 158, 158, 158, 158, 159, 159, 159, 160, 160, 160, 159, 158, 157, 156, 155, 154, 154, 153, 153, 153, 153, + 153, 153, 154, 154, 154, 154, 154, 153, 153, 152, 151, 150, 149, 147, 146, 145, 143, 142, 141, 140, 139, 139, 138, + 138, 138, 138, 138, 138, 137, 136, 136, 134, 133, 132, 131, 130, 129, 128, 128, 127, 127, 127, 126, 126, 126, 125, + 125, 124, 123, 123, 122, 121, 119, 118, 117, 115, 114, 113, 112, 111, 110, 110, 110, 109, 109, 110, 110, 109, 109, + 109, 108, 107, 106, 105, 104, 103, 103, 102, 102, 102, 102, 102, 102, 102, 101, 101, 100, 99, 98, 97, 95, 94, + 93, 93, 92, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88, 87, 87, 86, 85, 85, 84, 83, 82, 82, + 81, 81, 80, 80, 79, 79, 79, 78, 78, 77, 77, 76, 75, 75, 74, 73, 72, 72, 71, 71, 70, 70, 70, + 70, 69, 69, 69, 68, 68, 67, 67, 66, 66, 66, 65, 65, 65, 65, 64, 64, 63, 63, 62, 62, 61, 60, + 60, 59, 58, 58, 58, 57, 57, 57, 57, 57, 57, 56, 56, 55, 55, 54, 53, 52, 52, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 50, 50, 50, 49, 48, 48, 47, 47, 46, 46, 45, 45, 45, 45, 45, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46}; + + const ap_uint lt_prop_coord1_3[512] = { + 177, 177, 177, 177, 177, 177, 178, 178, 178, 179, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 179, 179, 179, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 178, 178, 178, 178, 179, + 179, 179, 179, 179, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 179, 179, + 179, 179, 179, 180, 180, 180, 180, 180, 180, 179, 179, 179, 178, 178, 177, 176, 176, 176, 175, 175, 175, 175, 174, + 174, 174, 174, 174, 173, 173, 173, 172, 172, 172, 172, 171, 171, 171, 170, 170, 170, 170, 169, 169, 169, 169, 168, + 168, 168, 167, 167, 167, 167, 166, 166, 166, 166, 165, 165, 165, 164, 164, 164, 163, 163, 163, 162, 162, 162, 161, + 161, 161, 160, 160, 160, 159, 159, 159, 158, 158, 158, 157, 157, 157, 156, 156, 155, 155, 155, 154, 154, 153, 153, + 152, 152, 152, 151, 151, 150, 150, 149, 149, 148, 147, 147, 146, 145, 144, 143, 142, 141, 141, 140, 139, 138, 138, + 137, 137, 136, 136, 135, 135, 134, 134, 133, 133, 132, 132, 131, 130, 129, 129, 128, 127, 126, 125, 125, 124, 123, + 123, 122, 121, 121, 120, 119, 119, 118, 117, 116, 115, 115, 114, 113, 113, 112, 112, 112, 111, 111, 111, 111, 110, + 109, 109, 108, 107, 106, 105, 104, 104, 103, 103, 103, 102, 102, 102, 102, 102, 101, 101, 100, 100, 99, 98, 98, + 97, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 90, 90, 89, 89, 88, 88, 87, 86, 85, 84, 84, + 83, 82, 81, 81, 80, 80, 79, 79, 78, 78, 78, 78, 77, 77, 76, 76, 76, 75, 74, 74, 73, 72, 72, + 71, 70, 70, 70, 69, 69, 69, 69, 69, 69, 69, 68, 68, 67, 66, 66, 65, 64, 64, 63, 63, 63, 62, + 62, 62, 61, 61, 61, 61, 60, 60, 60, 59, 59, 59, 58, 58, 57, 57, 56, 55, 55, 55, 54, 54, 54, + 54, 54, 54, 54, 54, 53, 53, 53, 52, 52, 51, 50, 50, 49, 49, 49, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48}; + + const ap_uint lt_prop_coord1_4[512] = { + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, + 163, 163, 163, 163, 163, 162, 162, 162, 161, 161, 160, 160, 159, 159, 158, 158, 157, 157, 157, 156, 156, 155, 155, + 155, 155, 154, 154, 154, 154, 153, 153, 152, 152, 151, 150, 149, 148, 147, 146, 144, 143, 142, 140, 139, 138, 137, + 135, 134, 133, 132, 131, 131, 130, 129, 128, 127, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 116, + 115, 114, 113, 113, 112, 111, 111, 110, 109, 108, 108, 107, 106, 106, 105, 104, 104, 103, 103, 103, 102, 102, 101, + 101, 100, 100, 99, 99, 98, 98, 97, 97, 97, 96, 96, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95}; + + const ap_uint lt_prop_coord2_0[512] = { + 203, 203, 203, 203, 203, 203, 203, 203, 204, 204, 205, 205, 206, 207, 208, 208, 209, 210, 211, 212, 212, 213, 213, + 214, 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, 218, 219, 219, 220, 221, 222, 222, 223, 224, 225, 226, 226, + 226, 227, 227, 227, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 225, 225, 225, 225, 225, 225, 225, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 223, 223, 223, 223, 222, 222, 222, 222, 222, 222, 222, 223, 223, 223, 223, 223, 223, 223, 223, 222, 222, 221, 221, + 220, 219, 219, 218, 217, 217, 216, 215, 214, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 204, 203, 202, + 202, 201, 201, 201, 200, 200, 199, 198, 198, 197, 195, 194, 192, 190, 188, 185, 183, 181, 179, 178, 176, 175, 174, + 172, 171, 170, 169, 168, 166, 165, 164, 162, 161, 159, 158, 156, 155, 153, 152, 150, 149, 147, 146, 145, 144, 143, + 142, 141, 140, 140, 139, 138, 137, 136, 136, 135, 134, 133, 133, 132, 131, 130, 129, 129, 128, 127, 126, 126, 125, + 124, 123, 123, 122, 121, 121, 120, 119, 118, 118, 117, 116, 116, 115, 114, 114, 113, 113, 112, 111, 111, 110, 110, + 109, 109, 108, 107, 107, 106, 106, 105, 105, 104, 104, 104, 103, 103, 102, 102, 101, 101, 101, 100, 100, 100, 99, + 99, 99, 99, 98, 98, 98, 97, 97, 97, 96, 96, 96, 95, 95, 94, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93}; + const ap_uint lt_prop_coord2_1[512] = { + 148, 148, 148, 148, 148, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 155, 155, + 155, 155, 155, 154, 154, 154, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, + 152, 152, 152, 151, 151, 150, 150, 150, 149, 148, 148, 147, 147, 146, 145, 145, 144, 143, 143, 142, 141, 141, 140, + 140, 139, 138, 138, 137, 137, 136, 136, 135, 134, 133, 133, 132, 131, 130, 129, 127, 126, 125, 124, 123, 123, 122, + 122, 121, 121, 121, 120, 120, 119, 119, 118, 117, 116, 115, 114, 113, 112, 112, 112, 112, 112, 112, 111, 111, 111, + 111, 110, 109, 108, 107, 107, 106, 105, 104, 104, 103, 103, 102, 102, 101, 100, 100, 99, 98, 97, 96, 96, 95, + 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 89, 89, 88, 88, 87, 86, 86, 85, 85, 84, 83, + 83, 82, 82, 82, 81, 81, 80, 80, 80, 79, 79, 78, 78, 77, 77, 76, 76, 75, 75, 74, 74, 73, 73, + 72, 72, 71, 71, 71, 70, 70, 70, 70, 70, 69, 69, 69, 69, 68, 68, 68, 67, 67, 66, 66, 65, 65, + 64, 63, 63, 62, 62, 61, 61, 61, 60, 60, 59, 59, 58, 58, 57, 56, 56, 55, 55, 54, 54, 54, 54, + 54, 54, 54, 54, 53, 53, 53, 52, 52, 51, 51, 50, 50, 49, 48, 48, 47, 47, 46, 46, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45}; + + const ap_uint lt_prop_coord2_2[512] = { + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 78, 78, 78, 78, 78, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 76, 76, 76, 76, 75, 75, 74, 73, 73, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 74, 74, 74, 74, 74, + 74, 73, 72, 72, 71, 70, 69, 69, 68, 68, 68, 68, 68, 68, 68, 67, 67, 67, 66, 66, 66, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 66, + 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 69, 69, 69, 69, 68, 68, 67, + 67, 66, 66, 65, 65, 66, 67, 69, 72, 75, 79, 84, 89, 95, 101, 107, 114, 120, 127, 133, 139, 144, 149, + 154, 158, 161, 163, 165, 165, 165, 165, 164, 163, 162, 160, 160, 159, 158, 158, 158, 158, 157, 157, 157, 157, 158, + 158, 158, 158, 158, 158, 158, 157, 157, 157, 156, 156, 155, 154, 152, 151, 149, 147, 145, 143, 142, 140, 139, 138, + 137, 136, 135, 134, 134, 133, 133, 132, 131, 131, 130, 129, 129, 128, 127, 126, 126, 125, 124, 124, 123, 123, 122, + 122, 121, 121, 120, 120, 119, 118, 118, 117, 116, 115, 113, 112, 111, 110, 109, 109, 108, 107, 107, 107, 107, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108}; + + const ap_uint lt_prop_coord2_3[512] = { + 25, 25, 25, 25, 25, 25, 24, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 24, 24, 24, 24, + 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 22, 22, 22, 22, 21, 21, 21, 21, 21, 21, 21, 22, 22, 23, 23, 23, + 23, 23, 23, 22, 21, 20, 20, 19, 18, 18, 17, 17, 17, 18, 18, 19, 20, 21, 22, 23, 24, 26, 27, + 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 58, 60, 62, 65, 67, 70, 72, 74, + 77, 79, 82, 84, 86, 89, 91, 94, 96, 98, 101, 103, 105, 107, 110, 112, 114, 116, 118, 120, 122, 124, 125, + 127, 129, 130, 132, 133, 134, 136, 137, 138, 139, 140, 141, 141, 142, 142, 143, 143, 143, 143, 142, 142, 141, 140, + 139, 138, 136, 135, 134, 133, 132, 131, 131, 130, 130, 129, 129, 129, 128, 128, 127, 127, 127, 126, 125, 124, 124, + 123, 122, 120, 119, 118, 117, 116, 115, 114, 114, 113, 112, 112, 111, 111, 111, 111, 111, 111, 111, 111, 111, 110, + 110, 109, 109, 108, 107, 106, 105, 104, 103, 103, 102, 101, 100, 99, 99, 98, 97, 97, 96, 96, 95, 94, 94, + 93, 93, 92, 91, 91, 90, 89, 89, 88, 88, 88, 87, 87, 87, 86, 86, 86, 86, 85, 85, 84, 84, 84, + 83, 82, 82, 81, 81, 80, 79, 79, 78, 78, 78, 77, 77, 76, 76, 76, 75, 75, 75, 74, 74, 73, 72, + 72, 72, 71, 71, 71, 71, 70, 70, 70, 70, 69, 69, 69, 68, 68, 67, 66, 66, 65, 64, 63, 63, 62, + 62, 61, 61, 60, 60, 60, 59, 59, 59, 59, 59, 58, 58, 58, 57, 57, 57, 56, 56, 56, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 54, 54, 54, 53, 53, 52, 51, 50, 49, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47}; + + const ap_uint lt_prop_coord2_4[512] = { + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 171, 171, 171, 170, 170, 170, 169, 169, 169, 168, + 168, 167, 167, 166, 166, 165, 164, 164, 163, 162, 161, 160, 160, 159, 158, 157, 156, 156, 155, 154, 153, 152, 152, + 151, 150, 149, 149, 148, 147, 146, 146, 145, 144, 144, 143, 142, 141, 141, 140, 139, 139, 138, 137, 136, 136, 135, + 134, 133, 133, 132, 131, 130, 130, 129, 128, 128, 127, 126, 126, 125, 124, 123, 122, 121, 120, 119, 119, 118, 117, + 116, 116, 115, 115, 114, 113, 113, 112, 111, 111, 110, 109, 108, 108, 107, 106, 106, 105, 104, 104, 103, 103, 103, + 102, 102, 102, 102, 101, 101, 101, 100, 100, 100, 99, 98, 97, 96, 95, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93}; + + const ap_uint lt_res0_coord1_0[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_coord1_1[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_coord1_2[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_coord1_3[512] = { + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_coord1_4[512] = { + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_coord2_0[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}; + + const ap_uint lt_res0_coord2_1[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_coord2_2[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_coord2_3[512] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_coord2_4[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_eta1_0[512] = { + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_eta1_1[512] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, + 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_eta1_2[512] = { + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_eta1_3[512] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res0_eta1_4[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; + + const ap_uint lt_res0_eta2_0[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}; + + const ap_uint lt_res0_eta2_1[512] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; + + const ap_uint lt_res0_eta2_2[512] = { + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; + + const ap_uint lt_res0_eta2_3[512] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; + + const ap_uint lt_res0_eta2_4[512] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}; + + ////shift those by 24 + const ap_uint lt_res1_coord1_0[512] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, + 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, + 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 5, 5, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; + + const ap_uint lt_res1_coord1_1[512] = { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, + 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, + 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 18, 18, 18, + 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 13, 13, 13, 13, 12, + 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 6, + 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, + 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + const ap_uint lt_res1_coord1_2[512] = { + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; + + const ap_uint lt_res1_coord1_3[512] = { + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, + 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, + 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; + + const ap_uint lt_res1_coord1_4[512] = { + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; + + const ap_uint lt_res1_coord2_0[512] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + const ap_uint lt_res1_coord2_1[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}; + + const ap_uint lt_res1_coord2_2[512] = { + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, + 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, + 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 11, 11, 10, 9, 8, 8, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; + + const ap_uint lt_res1_coord2_3[512] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, + 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; + + const ap_uint lt_res1_coord2_4[512] = { + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, + 13, 13, 12, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, + 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, + 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; + const ap_uint lt_res1_eta_0[512] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; + + const ap_uint lt_res1_eta_1[512] = { + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + const ap_uint lt_res1_eta_2[512] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + const ap_uint lt_res1_eta_3[512] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + const ap_uint lt_res1_eta_4[512] = { + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, + 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}; + +// const ap_uint<8> lt_tpsID[256] = { +// 40, 56, 64, 88, 64, 32, 60, 56, 56, 56, 56, 56, 56, 56, 56, 56, 28, 56, 56, 54, 36, 36, 36, 36, 36, 36, +// 36, 36, 32, 28, 28, 28, 28, 52, 56, 52, 52, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 28, 56, 52, 52, +// 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 28, 52, 36, 36, 36, 36, 36, 36, 36, 36, 56, 56, 36, 56, +// 36, 36, 28, 60, 60, 60, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 28, 120, 120, 120, 92, 92, 64, 64, +// 64, 64, 64, 64, 64, 64, 64, 64, 28, 120, 152, 128, 100, 124, 80, 80, 64, 100, 64, 64, 64, 64, 64, 64, 28, 88, +// 92, 64, 92, 60, 60, 60, 92, 60, 60, 60, 60, 60, 60, 60, 36, 88, 88, 64, 64, 60, 60, 60, 60, 60, 60, 60, +// 92, 92, 92, 92, 28, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 28, 92, 92, 92, 92, 92, +// 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 28, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, +// 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, +// 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}; + + +// NEW LUT with Low Pt (Bin 0, Pt<8 GeV) increased quality requirement. WP95. No changes for Pt>8 + const ap_uint<8> lt_tpsID[256] = {59, 56, 64, 88, 64, 32, 60, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 33, 56, 56, 54, 36, 36, 36, 36, 36, 36, 36, 36, 32, 28, 28, 28, + 53, 52, 56, 52, 52, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 40, 56, 52, 52, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 47, 52, 36, 36, 36, 36, 36, 36, 36, 36, 56, 56, 36, 56, 36, 36, + 60, 60, 60, 60, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 58,120,120,120, 92, 92, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 58,120,152,128,100,124, 80, 80, 64,100, 64, 64, 64, 64, 64, 64, + 53, 88, 92, 64, 92, 60, 60, 60, 92, 60, 60, 60, 60, 60, 60, 60, + 64, 88, 88, 64, 64, 60, 60, 60, 60, 60, 60, 60, 92, 92, 92, 92, + 41, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, + 49, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 38, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}; + + +} // namespace Phase2L1GMT +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h b/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h new file mode 100644 index 0000000000000..b890d5571afa1 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h @@ -0,0 +1,95 @@ +#ifndef PHASE2GMT_CONEVRTEDTTRACK +#define PHASE2GMT_CONEVRTEDTTRACK +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +namespace Phase2L1GMT { + + class ConvertedTTTrack { + public: + ConvertedTTTrack(const uint& charge, + const int& curvature, + const uint& abseta, + const uint& pt, + const int& eta, + const int& phi, + const int& z0, + const int& d0, + const int& quality, + const ap_uint<96>& word) + : charge_(charge), + curvature_(curvature), + abseta_(abseta), + pt_(pt), + eta_(eta), + phi_(phi), + z0_(z0), + d0_(d0), + quality_(quality), + word_(word) {} + + const uint charge() const { return charge_; } + + const int curvature() const { return curvature_; } + const uint abseta() const { return abseta_; } + + const uint pt() const { return pt_; } + + const int eta() const { return eta_; } + const int phi() const { return phi_; } + + void setPhi(int phi) { phi_ = phi; } + + const int z0() const { return z0_; } + const int d0() const { return d0_; } + const int quality() const { return quality_; } + const float offline_pt() const { return offline_pt_; } + const float offline_eta() const { return offline_eta_; } + const float offline_phi() const { return offline_phi_; } + + const ap_uint<96>& word() const { return word_; } + void setOfflineQuantities(float pt, float eta, float phi) { + offline_pt_ = pt; + offline_eta_ = eta; + offline_phi_ = phi; + } + + void print() const { + LogDebug("ConvertedTTTrack") << "converted track : charge=" << charge_ << " curvature=" << curvature_ + << " pt=" << offline_pt_ << "," << pt_ << " eta=" << offline_eta_ << "," << eta_ + << " phi=" << offline_phi_ << "," << phi_ << " z0=" << z0_ << " d0=" << d0_ + << " quality=" << quality_; + } + + void printWord() const { + LogDebug("ConvertedTTTrack") << "converted track : word=" << std::setfill('0') << std::setw(8) << std::hex + << (long long unsigned int)((word_ >> 64).to_uint64()) << std::setfill('0') + << std::setw(16) << std::hex + << (long long unsigned int)((word_ & 0xffffffffffffffff).to_uint64()); + } + + void setTrkPtr(const edm::Ptr >& trkPtr) { trkPtr_ = trkPtr; } + + const edm::Ptr > trkPtr() const { return trkPtr_; } + + private: + uint charge_; + int curvature_; + uint abseta_; + uint pt_; + int eta_; + int phi_; + int z0_; + int d0_; + uint quality_; + float offline_pt_; + float offline_eta_; + float offline_phi_; + ap_uint<96> word_; + + edm::Ptr > trkPtr_; + }; +} // namespace Phase2L1GMT + +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/Isolation.h b/L1Trigger/Phase2L1GMT/interface/Isolation.h new file mode 100644 index 0000000000000..c04b806505898 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/Isolation.h @@ -0,0 +1,246 @@ +// =========================================================================== +// +// Filename: Isolation.h +// +// Description: +// +// Version: 1.0 +// Created: 02/23/2021 01:16:43 PM +// Revision: none +// Compiler: g++ +// +// Author: Zhenbin Wu, zhenbin.wu@gmail.com +// +// =========================================================================== + +#ifndef PHASE2GMT_ISOLATION +#define PHASE2GMT_ISOLATION + +#include "L1Trigger/Phase2L1GMT/interface/TopologicalAlgorithm.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +namespace Phase2L1GMT { + class Isolation : public TopoAlgo { + public: + Isolation(const edm::ParameterSet &iConfig); + ~Isolation(); + Isolation(const Isolation &cpy); + + unsigned compute_trk_iso(l1t::TrackerMuon &in_mu, ConvertedTTTrack &in_trk); + + void isolation_allmu_alltrk(std::vector &trkMus, std::vector &convertedTracks); + + private: + void DumpOutputs(std::vector &trkMus); + int SetAbsIsolationBits(int accum); + int SetRelIsolationBits(int accum, int mupt); + int OverlapRemoval(unsigned &ovrl, std::vector &overlaps); + + const static int c_iso_dangle_max = 260; //@ < 260 x 2pi/2^13 = 0.2 rad + const static int c_iso_dz_max = 17; //@ < 17 x 60/2^10 = 1 cm + const static int c_iso_pt_min = 120; //@ >= , 120 x 25MeV = 3 GeV + + // Assuming 4 bits for Muon isolation + int absiso_thrL; + int absiso_thrM; + int absiso_thrT; + double reliso_thrL; + double reliso_thrM; + double reliso_thrT; + bool verbose_; + bool dumpForHLS_; + std::ofstream dumpOutput; + + typedef ap_ufixed<9, 9, AP_TRN, AP_SAT> iso_accum_t; + typedef ap_ufixed<9, 0> reliso_thresh_t; + }; + + inline Isolation::Isolation(const edm::ParameterSet &iConfig) + : absiso_thrL(iConfig.getParameter("AbsIsoThresholdL")), + absiso_thrM(iConfig.getParameter("AbsIsoThresholdM")), + absiso_thrT(iConfig.getParameter("AbsIsoThresholdT")), + reliso_thrL(iConfig.getParameter("RelIsoThresholdL")), + reliso_thrM(iConfig.getParameter("RelIsoThresholdM")), + reliso_thrT(iConfig.getParameter("RelIsoThresholdT")), + verbose_(iConfig.getParameter("verbose")), + dumpForHLS_(iConfig.getParameter("IsodumpForHLS")) { + dumpForHLS_ = true; + if (dumpForHLS_) { + dumpInput.open("Isolation_Mu_Track_infolist.txt", std::ofstream::out); + dumpOutput.open("Isolation_Mu_Isolation.txt", std::ofstream::out); + } + } + + inline Isolation::~Isolation() { + if (dumpForHLS_) { + dumpInput.close(); + dumpOutput.close(); + } + } + + inline Isolation::Isolation(const Isolation &cpy) : TopoAlgo(cpy) {} + + inline void Isolation::DumpOutputs(std::vector &trkMus) { + static int nevto = 0; + for (unsigned int i = 0; i < trkMus.size(); ++i) { + auto mu = trkMus.at(i); + if (mu.hwPt() != 0) { + double convertphi = mu.hwPhi() * LSBphi; + if (convertphi > M_PI) { + convertphi -= 2 * M_PI; + } + dumpOutput << nevto << " " << i << " " << mu.hwPt() * LSBpt << " " << mu.hwEta() * LSBeta << " " << convertphi + << " " << mu.hwZ0() * LSBGTz0 << " " << mu.hwIso() << endl; + } + } + nevto++; + } + + inline int Isolation::SetAbsIsolationBits(int accum) { + int iso = (accum <= absiso_thrT ? 3 : accum <= absiso_thrM ? 2 : accum <= absiso_thrL ? 1 : 0); + + if (verbose_) { + edm::LogInfo("Isolation") << " [DEBUG Isolation] : absiso_threshold L : " << absiso_thrL << " accum " << accum + << " bit set : " << (accum < absiso_thrL); + edm::LogInfo("Isolation") << " [DEBUG Isolation] : absiso_threshold M : " << absiso_thrM << " accum " << accum + << " bit set : " << (accum < absiso_thrM); + edm::LogInfo("Isolation") << " [DEBUG Isolation] : absiso_threshold T : " << absiso_thrT << " accum " << accum + << " bit set : " << (accum < absiso_thrT); + edm::LogInfo("Isolation") << " [DEBUG Isolation] : absiso : " << (iso); + } + return iso; + } + + inline int Isolation::SetRelIsolationBits(int accum, int mupt) { + const static reliso_thresh_t relisoL(reliso_thrL); + const static reliso_thresh_t relisoM(reliso_thrM); + const static reliso_thresh_t relisoT(reliso_thrT); + + iso_accum_t thrL = relisoL * mupt; + iso_accum_t thrM = relisoM * mupt; + iso_accum_t thrT = relisoT * mupt; + + int iso = (accum <= thrT.to_int() ? 3 : accum <= thrM.to_int() ? 2 : accum <= thrL.to_int() ? 1 : 0); + + if (verbose_) { + edm::LogInfo("Isolation") << " [DEBUG Isolation] : reliso_threshold L : " << thrL << " accum " << accum + << " bit set : " << (accum < thrL.to_int()); + edm::LogInfo("Isolation") << " [DEBUG Isolation] : reliso_threshold M : " << thrM << " accum " << accum + << " bit set : " << (accum < thrM.to_int()); + edm::LogInfo("Isolation") << " [DEBUG Isolation] : reliso_threshold T : " << thrT << " accum " << accum + << " bit set : " << (accum < thrT.to_int()); + edm::LogInfo("Isolation") << " [DEBUG Isolation] : reliso : " << (iso << 2) << " org " << iso; + } + + return iso << 2; + } + + inline void Isolation::isolation_allmu_alltrk(std::vector &trkMus, + std::vector &convertedTracks) { + load(trkMus, convertedTracks); + if (dumpForHLS_) { + DumpInputs(); + } + + static int itest = 0; + if (verbose_) { + edm::LogInfo("Isolation") << "........ RUNNING TEST NUMBER .......... " << itest++; + } + + for (auto &mu : trkMus) { + int accum = 0; + int iso_ = 0; + std::vector overlaps; + for (auto t : convertedTracks) { + unsigned ovrl = compute_trk_iso(mu, t); + if (ovrl != 0) { + accum += OverlapRemoval(ovrl, overlaps) * t.pt(); + } + } + + // Only 8 bit for accumation? + mu.setHwIsoSum(accum); + + iso_accum_t temp(accum); + accum = temp.to_int(); + + mu.setHwIsoSumAp(accum); + + iso_ |= SetAbsIsolationBits(accum); + iso_ |= SetRelIsolationBits(accum, mu.hwPt()); + + mu.setHwIso(iso_); + } + + if (dumpForHLS_) { + DumpOutputs(trkMus); + } + } + + // === FUNCTION ============================================================ + // Name: Isolation::OverlapRemoval + // Description: + // =========================================================================== + inline int Isolation::OverlapRemoval(unsigned &ovrl, std::vector &overlaps) { + for (auto i : overlaps) { + // same tracks with Phi can be off by 1 LSB + unsigned diff = ovrl - i; + if (diff <= 1 || diff == unsigned(-1)) { + // When Overlap, return 0 so that this track won't be consider + return 0; + } + } + overlaps.push_back(ovrl); + return 1; + } // ----- end of function Isolation::OverlapRemoval ----- + + inline unsigned Isolation::compute_trk_iso(l1t::TrackerMuon &in_mu, ConvertedTTTrack &in_trk) { + int dphi = deltaPhi(in_mu.hwPhi(), in_trk.phi()); + int deta = deltaEta(in_mu.hwEta(), in_trk.eta()); + int dz0 = deltaZ0(in_mu.hwZ0(), in_trk.z0()); + + bool pass_deta = (deta < c_iso_dangle_max ? true : false); + bool pass_dphi = (dphi < c_iso_dangle_max ? true : false); + bool pass_dz0 = (dz0 < c_iso_dz_max ? true : false); + bool pass_trkpt = (in_trk.pt() >= c_iso_pt_min ? true : false); + bool pass_ovrl = (deta > 0 || dphi > 0 ? true : false); + + if (verbose_) { + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : Start of debug msg for compute_trk_iso"; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : incoming muon (pt / eta / phi / z0 / isvalid)"; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : MU = " << in_mu.hwPt() << " / " << in_mu.hwEta() + << " / " << in_mu.hwPhi() << " / " << in_mu.hwZ0() << " / " << 1; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : incoming track (pt / eta / phi / z0 / isvalid)"; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : TRK = " << in_trk.pt() << " / " << in_trk.eta() << " / " + << in_trk.phi() << " / " << in_trk.z0() << " / " << 1; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : Delta phi : " << dphi; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : Delta eta : " << deta; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : Delta z0 : " << dz0; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : pass_deta : " << pass_deta; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : pass_dphi : " << pass_dphi; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : pass_dz0 : " << pass_dz0; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : pass_trkpt : " << pass_trkpt; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : pass_ovrl : " << pass_ovrl; + } + // match conditions + if (pass_deta && pass_dphi && pass_dz0 && pass_trkpt && pass_ovrl) { + if (verbose_) { + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : THE TRACK WAS MATCHED"; + edm::LogInfo("Isolation") << " [DEBUG compute_trk_iso] : RETURN : " << in_trk.pt(); + } + + //return in_trk.pt(); + // Return fixed bit output for duplication removal. + // dZ0(8bis) + deta(10bits)+dphi(10bits) + unsigned int retbits = 0; + retbits |= (dz0 & ((1 << 9) - 1)) << 20; + retbits |= (deta & ((1 << 11) - 1)) << 10; + retbits |= (dphi & ((1 << 11) - 1)); + return retbits; + } else { + return 0; + } + } +} // namespace Phase2L1GMT +#endif // ----- #ifndef PHASE2GMT_ISOLATION ----- diff --git a/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h b/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h new file mode 100644 index 0000000000000..81607c571c702 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h @@ -0,0 +1,46 @@ +#ifndef L1TPHASE2GMTBARRELSTUBPROCESSOR +#define L1TPHASE2GMTBARRELSTUBPROCESSOR + +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhDigi.h" +#include "DataFormats/L1DTTrackFinder/interface/L1Phase2MuDTPhContainer.h" +#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThDigi.h" +#include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "CondFormats/L1TObjects/interface/L1TMuonBarrelParams.h" +#include "CondFormats/DataRecord/interface/L1TMuonBarrelParamsRcd.h" + +class L1TPhase2GMTBarrelStubProcessor { +public: + L1TPhase2GMTBarrelStubProcessor(); + L1TPhase2GMTBarrelStubProcessor(const edm::ParameterSet&); + + ~L1TPhase2GMTBarrelStubProcessor(); + + l1t::MuonStubCollection makeStubs(const L1Phase2MuDTPhContainer*, const L1MuDTChambThContainer*); + +private: + l1t::MuonStub buildStub(const L1Phase2MuDTPhDigi&, const L1MuDTChambThDigi*); + l1t::MuonStub buildStubNoEta(const L1Phase2MuDTPhDigi&); + + int calculateEta(uint, int, uint, uint); + int minPhiQuality_; + + int minBX_; + int maxBX_; + + std::vector eta1_; + std::vector eta2_; + std::vector eta3_; + std::vector coarseEta1_; + std::vector coarseEta2_; + std::vector coarseEta3_; + std::vector coarseEta4_; + std::vector phiOffset_; + int phiBFactor_; + int verbose_; + double phiLSB_; + double etaLSB_; +}; + +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTEndcapStubProcessor.h b/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTEndcapStubProcessor.h new file mode 100644 index 0000000000000..a4402827fce10 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTEndcapStubProcessor.h @@ -0,0 +1,43 @@ + +#ifndef L1TPHASE2GMTENDCAPSTUBPROCESSOR +#define L1TPHASE2GMTENDCAPSTUBPROCESSOR + +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigi.h" +#include "DataFormats/MuonData/interface/MuonDigiCollection.h" +#include "DataFormats/MuonDetId/interface/CSCDetId.h" +#include "L1Trigger/L1TMuon/interface/GeometryTranslator.h" +#include "DataFormats/RPCDigi/interface/RPCDigi.h" +#include "DataFormats/MuonDetId/interface/RPCDetId.h" +#include "L1Trigger/L1TMuon/interface/MuonTriggerPrimitive.h" +#include "L1Trigger/L1TTwinMux/interface/RPCHitCleaner.h" + +class L1TPhase2GMTEndcapStubProcessor { +public: + L1TPhase2GMTEndcapStubProcessor(); + L1TPhase2GMTEndcapStubProcessor(const edm::ParameterSet&); + ~L1TPhase2GMTEndcapStubProcessor(); + + l1t::MuonStubCollection makeStubs(const MuonDigiCollection& csc, + const MuonDigiCollection& rpc, + const L1TMuon::GeometryTranslator* t, + const edm::EventSetup& iSetup); + +private: + l1t::MuonStub buildCSCOnlyStub(const CSCDetId&, const CSCCorrelatedLCTDigi&, const L1TMuon::GeometryTranslator*); + l1t::MuonStub buildRPCOnlyStub(const RPCDetId&, const RPCDigi&, const L1TMuon::GeometryTranslator*); + l1t::MuonStubCollection combineStubs(const l1t::MuonStubCollection&, const l1t::MuonStubCollection&); + + int minBX_; + int maxBX_; + double coord1LSB_; + double coord2LSB_; + double eta1LSB_; + double eta2LSB_; + double etaMatch_; + double phiMatch_; + bool verbose_; +}; + +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/MuonROI.h b/L1Trigger/Phase2L1GMT/interface/MuonROI.h new file mode 100644 index 0000000000000..54dabcd2fb4c7 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/MuonROI.h @@ -0,0 +1,119 @@ +#ifndef PHASE2GMT_MUONROI +#define PHASE2GMT_MUONROI +#include +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" +#include "DataFormats/L1Trigger/interface/L1TObjComparison.h" +#include "DataFormats/L1Trigger/interface/BXVector.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +namespace Phase2L1GMT { + + class MuonROI { + public: + MuonROI(int bx, uint charge, uint pt, uint quality) : bx_(bx), charge_(charge), pt_(pt), quality_(quality) {} + + const int bx() const { return bx_; } + + const uint charge() const { return charge_; } + + const uint pt() const { return pt_; } + const int quality() const { return quality_; } + + const float offline_pt() const { return offline_pt_; } + + void setOfflinePt(float pt) { offline_pt_ = pt; } + + void addStub(const l1t::MuonStubRef& stub) { stubs_.push_back(stub); } + + void setMuonRef(const l1t::RegionalMuonCandRef& ref) { + muRef_ = ref; + isGlobal_ = true; + } + bool isGlobalMuon() const { return isGlobal_; } + + const l1t::RegionalMuonCandRef& muonRef() const { return muRef_; } + + friend std::ostream& operator<<(std::ostream& s, const MuonROI& id) { + s.setf(ios::right, ios::adjustfield); + s << "ROI:" + << " " + << "BX: " << setw(5) << id.bx_ << " " + << "charge:" << setw(5) << id.charge_ << " " + << "pt:" << setw(5) << id.pt_ << " " + << "quality:" << setw(5) << id.quality_ << " " + << "offline pt:" << setw(5) << id.offline_pt_; + return s; + } + + const l1t::MuonStubRefVector& stubs() const { return stubs_; } + + ap_uint<64> stubWord(const l1t::MuonStubRef& stub) const { + ap_uint<64> word = 0; + word = word | twos_complement(stub->coord1(), BITSSTUBCOORD); + word = word | (twos_complement(stub->coord2(), BITSSTUBCOORD) << BITSSTUBCOORD); + word = word | (twos_complement(stub->eta1(), BITSSTUBETA) << (2 * BITSSTUBCOORD)); + word = word | (twos_complement(stub->eta2(), BITSSTUBETA) << (2 * BITSSTUBCOORD + BITSSTUBETA)); + word = word | (twos_complement(stub->quality(), BITSSTUBPHIQUALITY) << (2 * BITSSTUBCOORD + 2 * BITSSTUBETA)); + word = word | (twos_complement(stub->etaQuality(), BITSSTUBETAQUALITY) + << (2 * BITSSTUBCOORD + 2 * BITSSTUBETA + BITSSTUBPHIQUALITY)); + word = word | (twos_complement(stub->bxNum(), BITSSTUBTIME) + << (2 * BITSSTUBCOORD + 2 * BITSSTUBETA + BITSSTUBPHIQUALITY + BITSSTUBETAQUALITY)); + word = word | (twos_complement(stub->id(), BITSSTUBID) + << (2 * BITSSTUBCOORD + 2 * BITSSTUBETA + BITSSTUBPHIQUALITY + BITSSTUBETAQUALITY + BITSSTUBTIME)); + return word; + } + + ap_uint<32> roiWord() const { + ap_uint<32> word = 0; + word = word | twos_complement(bx_, BITSMUONBX); + word = word | (twos_complement(isGlobal_, 1) << (BITSMUONBX)); + word = word | (twos_complement(charge_, 1) << (BITSMUONBX + 1)); + word = word | (twos_complement(pt_, BITSPT) << (BITSMUONBX + 2)); + word = word | (twos_complement(quality_, BITSSTAMUONQUALITY) << (BITSMUONBX + 2 + BITSPT)); + return word; + } + + void printROILine() const { + ap_uint<64> s0 = 0x1ff000000000000; + ap_uint<64> s1 = 0x1ff000000000000; + ap_uint<64> s2 = 0x1ff000000000000; + ap_uint<64> s3 = 0x1ff000000000000; + ap_uint<64> s4 = 0x1ff000000000000; + for (const auto& s : stubs_) { + if (s->tfLayer() == 0) + s0 = stubWord(s); + if (s->tfLayer() == 1) + s1 = stubWord(s); + if (s->tfLayer() == 2) + s2 = stubWord(s); + if (s->tfLayer() == 3) + s3 = stubWord(s); + if (s->tfLayer() == 4) + s4 = stubWord(s); + } + LogDebug("MuonROI") << "MuonROI " << std::setfill('0') << std::setw(8) << std::hex + << (long long unsigned int)(roiWord().to_uint64()) << std::setfill('0') << std::setw(16) + << std::hex << (long long unsigned int)(s4.to_uint64()) << std::setfill('0') << std::setw(16) + << std::hex << (long long unsigned int)(s3.to_uint64()) << std::setfill('0') << std::setw(16) + << std::hex << (long long unsigned int)(s2.to_uint64()) << std::setfill('0') << std::setw(16) + << std::hex << (long long unsigned int)(s1.to_uint64()) << std::setfill('0') << std::setw(16) + << std::hex << (long long unsigned int)(s0.to_uint64()); + } + + private: + int bx_; + uint charge_; + uint pt_; + uint quality_; + bool isGlobal_; + float offline_pt_; + + l1t::MuonStubRefVector stubs_; + l1t::RegionalMuonCandRef muRef_; + }; +} // namespace Phase2L1GMT + +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/Node.h b/L1Trigger/Phase2L1GMT/interface/Node.h new file mode 100644 index 0000000000000..418aff66d5c80 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/Node.h @@ -0,0 +1,196 @@ +#ifndef PHASE2GMT_NODE +#define PHASE2GMT_NODE +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "L1Trigger/Phase2L1GMT/interface/TrackConverter.h" +#include "L1Trigger/Phase2L1GMT/interface/ROITempAssociator.h" +#include "L1Trigger/Phase2L1GMT/interface/TrackMuonMatchAlgorithm.h" +#include "L1Trigger/Phase2L1GMT/interface/Isolation.h" +#include "L1Trigger/Phase2L1GMT/interface/Tauto3Mu.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" + +namespace Phase2L1GMT { + + class Node { + public: + Node(const edm::ParameterSet& iConfig) + : verbose_(iConfig.getParameter("verbose")), + tt_track_converter_(new TrackConverter(iConfig.getParameter("trackConverter"))), + roi_assoc_(new ROITempAssociator(iConfig.getParameter("roiTrackAssociator"))), + track_mu_match_(new TrackMuonMatchAlgorithm(iConfig.getParameter("trackMatching"))), + isolation_(new Isolation(iConfig.getParameter("isolation"))), + tauto3mu_(new Tauto3Mu(iConfig.getParameter("tauto3mu"))) {} + + ~Node() {} + + std::vector processEvent(const std::vector >& tracks, + const l1t::ObjectRefBxCollection& muonTracks, + const l1t::MuonStubRefVector& stubs) { + //Split tracks to the links as they come + std::vector > tracks0 = associateTracksWithNonant(tracks, 0); + std::vector > tracks1 = associateTracksWithNonant(tracks, 1); + std::vector > tracks2 = associateTracksWithNonant(tracks, 2); + std::vector > tracks3 = associateTracksWithNonant(tracks, 3); + std::vector > tracks4 = associateTracksWithNonant(tracks, 4); + std::vector > tracks5 = associateTracksWithNonant(tracks, 5); + std::vector > tracks6 = associateTracksWithNonant(tracks, 6); + std::vector > tracks7 = associateTracksWithNonant(tracks, 7); + std::vector > tracks8 = associateTracksWithNonant(tracks, 8); + + //Transition stubs to different nonants with overlap + l1t::MuonStubRefVector stubs0 = associateStubsWithNonant(stubs, 0); + l1t::MuonStubRefVector stubs1 = associateStubsWithNonant(stubs, 1); + l1t::MuonStubRefVector stubs2 = associateStubsWithNonant(stubs, 2); + l1t::MuonStubRefVector stubs3 = associateStubsWithNonant(stubs, 3); + l1t::MuonStubRefVector stubs4 = associateStubsWithNonant(stubs, 4); + l1t::MuonStubRefVector stubs5 = associateStubsWithNonant(stubs, 5); + l1t::MuonStubRefVector stubs6 = associateStubsWithNonant(stubs, 6); + l1t::MuonStubRefVector stubs7 = associateStubsWithNonant(stubs, 7); + l1t::MuonStubRefVector stubs8 = associateStubsWithNonant(stubs, 8); + + //Convert TT tracks to our internal tracking format + std::vector convertedTracks0 = tt_track_converter_->convertTracks(tracks0); + std::vector convertedTracks1 = tt_track_converter_->convertTracks(tracks1); + std::vector convertedTracks2 = tt_track_converter_->convertTracks(tracks2); + std::vector convertedTracks3 = tt_track_converter_->convertTracks(tracks3); + std::vector convertedTracks4 = tt_track_converter_->convertTracks(tracks4); + std::vector convertedTracks5 = tt_track_converter_->convertTracks(tracks5); + std::vector convertedTracks6 = tt_track_converter_->convertTracks(tracks6); + std::vector convertedTracks7 = tt_track_converter_->convertTracks(tracks7); + std::vector convertedTracks8 = tt_track_converter_->convertTracks(tracks8); + + //Build ROIs per nonant + std::vector rois0 = roi_assoc_->associate(0, muonTracks, stubs0); + std::vector rois1 = roi_assoc_->associate(0, muonTracks, stubs1); + std::vector rois2 = roi_assoc_->associate(0, muonTracks, stubs2); + std::vector rois3 = roi_assoc_->associate(0, muonTracks, stubs3); + std::vector rois4 = roi_assoc_->associate(0, muonTracks, stubs4); + std::vector rois5 = roi_assoc_->associate(0, muonTracks, stubs5); + std::vector rois6 = roi_assoc_->associate(0, muonTracks, stubs6); + std::vector rois7 = roi_assoc_->associate(0, muonTracks, stubs7); + std::vector rois8 = roi_assoc_->associate(0, muonTracks, stubs8); + + //run track - muon matching per nonant + std::vector mu0 = track_mu_match_->processNonant(convertedTracks0, rois0); + std::vector mu1 = track_mu_match_->processNonant(convertedTracks1, rois1); + std::vector mu2 = track_mu_match_->processNonant(convertedTracks2, rois2); + std::vector mu3 = track_mu_match_->processNonant(convertedTracks3, rois3); + std::vector mu4 = track_mu_match_->processNonant(convertedTracks4, rois4); + std::vector mu5 = track_mu_match_->processNonant(convertedTracks5, rois5); + std::vector mu6 = track_mu_match_->processNonant(convertedTracks6, rois6); + std::vector mu7 = track_mu_match_->processNonant(convertedTracks7, rois7); + std::vector mu8 = track_mu_match_->processNonant(convertedTracks8, rois8); + if (verbose_) + printf("Matching Nonant 5 with %zu tracks and %zu rois and %zu stubs\n", + convertedTracks5.size(), + rois5.size(), + stubs5.size()); + + //clean neighboring nonants + std::vector muCleaned = track_mu_match_->cleanNeighbor(mu0, mu8, mu1, true); + std::vector muCleaned1 = track_mu_match_->cleanNeighbor(mu1, mu0, mu2, false); + std::vector muCleaned2 = track_mu_match_->cleanNeighbor(mu2, mu1, mu3, true); + std::vector muCleaned3 = track_mu_match_->cleanNeighbor(mu3, mu2, mu4, false); + std::vector muCleaned4 = track_mu_match_->cleanNeighbor(mu4, mu3, mu5, true); + std::vector muCleaned5 = track_mu_match_->cleanNeighbor(mu5, mu4, mu6, false); + std::vector muCleaned6 = track_mu_match_->cleanNeighbor(mu6, mu5, mu7, true); + std::vector muCleaned7 = track_mu_match_->cleanNeighbor(mu7, mu6, mu8, false); + std::vector muCleaned8 = + track_mu_match_->cleanNeighbor(mu8, mu7, mu0, false); //ARGH! 9 sectors - so some duplicates very rarely + + //merge all the collections + std::copy(muCleaned1.begin(), muCleaned1.end(), std::back_inserter(muCleaned)); + std::copy(muCleaned2.begin(), muCleaned2.end(), std::back_inserter(muCleaned)); + std::copy(muCleaned3.begin(), muCleaned3.end(), std::back_inserter(muCleaned)); + std::copy(muCleaned4.begin(), muCleaned4.end(), std::back_inserter(muCleaned)); + std::copy(muCleaned5.begin(), muCleaned5.end(), std::back_inserter(muCleaned)); + std::copy(muCleaned6.begin(), muCleaned6.end(), std::back_inserter(muCleaned)); + std::copy(muCleaned7.begin(), muCleaned7.end(), std::back_inserter(muCleaned)); + std::copy(muCleaned8.begin(), muCleaned8.end(), std::back_inserter(muCleaned)); + + std::vector trackMatchedMuonsNoIso = track_mu_match_->convert(muCleaned, 32); + + //Isolation and tau3mu will read those muons and all 9 collections of convertedTracks* + std::vector convertedTracks = convertedTracks0; + std::copy(convertedTracks1.begin(), convertedTracks1.end(), std::back_inserter(convertedTracks)); + std::copy(convertedTracks2.begin(), convertedTracks2.end(), std::back_inserter(convertedTracks)); + std::copy(convertedTracks3.begin(), convertedTracks3.end(), std::back_inserter(convertedTracks)); + std::copy(convertedTracks4.begin(), convertedTracks4.end(), std::back_inserter(convertedTracks)); + std::copy(convertedTracks5.begin(), convertedTracks5.end(), std::back_inserter(convertedTracks)); + std::copy(convertedTracks6.begin(), convertedTracks6.end(), std::back_inserter(convertedTracks)); + std::copy(convertedTracks7.begin(), convertedTracks7.end(), std::back_inserter(convertedTracks)); + std::copy(convertedTracks8.begin(), convertedTracks8.end(), std::back_inserter(convertedTracks)); + + //sorter here: + std::vector sortedTrackMuonsNoIso = track_mu_match_->sort(trackMatchedMuonsNoIso, 12); + + isolation_->isolation_allmu_alltrk(sortedTrackMuonsNoIso, convertedTracks); + + //tauto3mu_->GetTau3Mu(sortedTrackMuonsNoIso, convertedTracks); + + track_mu_match_->outputGT(sortedTrackMuonsNoIso); + + return sortedTrackMuonsNoIso; //when we add more collections like tau3mu etc we change that + } + + private: + int verbose_; + std::unique_ptr tt_track_converter_; + std::unique_ptr roi_assoc_; + std::unique_ptr track_mu_match_; + std::unique_ptr isolation_; + std::unique_ptr tauto3mu_; + + std::vector > associateTracksWithNonant( + const std::vector >& tracks, uint processor) { + std::vector > out; + for (const auto& track : tracks) { + if (track->phiSector() == processor) { + out.push_back(track); + } + } + return out; + } + + l1t::MuonStubRefVector associateStubsWithNonant(const l1t::MuonStubRefVector& allStubs, uint processor) { + l1t::MuonStubRefVector out; + + ap_int center = ap_int((processor * 910) / 32); + + for (const auto& s : allStubs) { + ap_int phi = 0; + if (s->quality() & 0x1) + phi = s->coord1(); + else + phi = s->coord2(); + + ap_int deltaPhi = phi - center; + ap_uint absDeltaPhi = + (deltaPhi < 0) ? ap_uint(-deltaPhi) : ap_uint(deltaPhi); + if (absDeltaPhi < 42) + out.push_back(s); + + /* if (processor==0 && phi>=-3000/32 && phi<=3000/32 ) */ + /* out.push_back(s); */ + /* else if (processor==1 && (phi>=-1000/32 && phi<=5000/32) ) */ + /* out.push_back(s); */ + /* else if (processor==2 && (phi>=500/32 && phi<=6500/32) ) */ + /* out.push_back(s); */ + /* else if (processor==3 && (phi>=2000/32 || phi<=-8000/32) ) */ + /* out.push_back(s); */ + /* else if (processor==4 && (phi>=4500/32 || phi<=-6000/32) ) */ + /* out.push_back(s); */ + /* else if (processor==5 && (phi>=6000/32 || phi<=-4500/32) ) */ + /* out.push_back(s); */ + /* else if (processor==6 && (phi>=8000/32 || phi<=-2000/32) ) */ + /* out.push_back(s); */ + /* else if (processor==7 && (phi>=-7000/32 && phi<=0) ) */ + /* out.push_back(s); */ + /* else if (processor==8 && (phi>=-4500/32 && phi<=1000/32) ) */ + /* out.push_back(s); */ + } + return out; + } + }; +} // namespace Phase2L1GMT + +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h b/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h new file mode 100644 index 0000000000000..76faa13e7cd45 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h @@ -0,0 +1,167 @@ +#ifndef PHASE2GMT_PRETRACKMATCHEDMUON +#define PHASE2GMT_PRETRACKMATCHEDMUON + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "DataFormats/Common/interface/Ptr.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/L1TrackTrigger/interface/TTStub.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h" +#include "DataFormats/TrackerCommon/interface/TrackerTopology.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" + +#include + +namespace Phase2L1GMT { + + class PreTrackMatchedMuon { + public: + PreTrackMatchedMuon(const uint& charge, + const uint& pt, + const int& eta, + const int& phi, + const int& z0, + const int& d0, + const uint& beta = 15) + : charge_(charge), + pt_(pt), + eta_(eta), + phi_(phi), + z0_(z0), + d0_(d0), + beta_(beta), + isGlobal_(false), + quality_(0), + stubID0_(511), + stubID1_(511), + stubID2_(511), + stubID3_(511), + stubID4_(511), + valid_(false) {} + + const uint charge() const { return charge_; } + const uint pt() const { return pt_; } + const int eta() const { return eta_; } + const int phi() const { return phi_; } + const int z0() const { return z0_; } + const int d0() const { return d0_; } + const uint beta() const { return beta_; } + + bool isGlobalMuon() const { return isGlobal_; } + const int quality() const { return quality_; } + const int offline_pt() const { return offline_pt_; } + const float offline_eta() const { return offline_eta_; } + const float offline_phi() const { return offline_phi_; } + + const uint stubID0() const { return stubID0_; } + const uint stubID1() const { return stubID1_; } + const uint stubID2() const { return stubID2_; } + const uint stubID3() const { return stubID3_; } + const uint stubID4() const { return stubID4_; } + bool valid() const { return valid_; } + + void setQuality(uint quality) { quality_ = quality; } + void setValid(bool v) { valid_ = v; } + + void setOfflineQuantities(float pt, float eta, float phi) { + offline_pt_ = pt; + offline_eta_ = eta; + offline_phi_ = phi; + } + + void addMuonRef(const l1t::RegionalMuonCandRef& ref) { + muRef_.push_back(ref); + isGlobal_ = true; + } + + void resetGlobal() { isGlobal_ = false; } + + const std::vector& muonRef() const { return muRef_; } + void addStub(const l1t::MuonStubRef& stub) { + stubs_.push_back(stub); + if (stub->tfLayer() == 0) + stubID0_ = stub->id(); + else if (stub->tfLayer() == 1) + stubID1_ = stub->id(); + else if (stub->tfLayer() == 2) + stubID2_ = stub->id(); + else if (stub->tfLayer() == 3) + stubID3_ = stub->id(); + else if (stub->tfLayer() == 4) + stubID4_ = stub->id(); + } + + const l1t::MuonStubRefVector& stubs() const { return stubs_; } + + void setTrkPtr(const edm::Ptr >& trkPtr) { trkPtr_ = trkPtr; } + + const edm::Ptr > trkPtr() const { return trkPtr_; } + + void print() const { + LogDebug("PreTrackMatchedMuon") << "preconstructed muon : charge=" << charge_ << " pt=" << offline_pt_ << "," + << pt_ << " eta=" << offline_eta_ << "," << eta_ << " phi=" << offline_phi_ << "," + << phi_ << " z0=" << z0_ << " d0=" << d0_ << " quality=" << quality_ + << " isGlobal=" << isGlobal_ << " valid=" << valid_ << " stubs: " << stubID0_ + << " " << stubID1_ << " " << stubID2_ << " " << stubID3_ << " " << stubID4_; + } + + uint64_t lsb() const { + uint64_t w = charge_ & 0x1; + w = w | (twos_complement(pt_, BITSPT) << 1); + w = w | (twos_complement(phi_, BITSPHI) << (BITSPT + 1)); + w = w | (twos_complement(eta_, BITSETA) << (BITSPHI + BITSPT + 1)); + w = w | (twos_complement(z0_, BITSZ0) << (BITSETA + BITSPHI + BITSPT + 1)); + w = w | (twos_complement(d0_, BITSD0) << (BITSZ0 + BITSETA + BITSPHI + BITSPT + 1)); + return w; + } + + uint64_t msb() const { + uint64_t w2 = 0; + w2 = twos_complement(stubID0_, BITSSTUBID); + w2 = w2 | (twos_complement(stubID1_, BITSSTUBID) << BITSSTUBID); + w2 = w2 | (twos_complement(stubID2_, BITSSTUBID) << (2 * BITSSTUBID)); + w2 = w2 | (twos_complement(stubID3_, BITSSTUBID) << (3 * BITSSTUBID)); + w2 = w2 | (twos_complement(stubID4_, BITSSTUBID) << (4 * BITSSTUBID)); + w2 = w2 | (twos_complement(isGlobal_, 1) << (5 * BITSSTUBID)); + w2 = w2 | (twos_complement(beta_, BITSMUONBETA) << (5 * BITSSTUBID + 1)); + w2 = w2 | (twos_complement(quality_, BITSMATCHQUALITY) << (BITSMUONBETA + 5 * BITSSTUBID + 1)); + w2 = w2 | (twos_complement(valid_, 1) << (BITSMATCHQUALITY + BITSMUONBETA + 5 * BITSSTUBID + 1)); + return w2; + } + + void printWord() const { + LogDebug("PreTrackMatchedMuon") << "PreTrackMatchedMuon : word=" << std::setfill('0') << std::setw(16) << std::hex + << (long long unsigned int)(msb() >> 2) << std::setfill('0') << std::setw(16) + << std::hex + << (long long unsigned int)((lsb() | (msb() << 62)) & 0xffffffffffffffff); + } + + private: + uint charge_; + uint pt_; + int eta_; + int phi_; + int z0_; + int d0_; + uint beta_; + bool isGlobal_; + uint quality_; + float offline_pt_; + float offline_eta_; + float offline_phi_; + uint stubID0_; + uint stubID1_; + uint stubID2_; + uint stubID3_; + uint stubID4_; + bool valid_; + l1t::MuonStubRefVector stubs_; + std::vector muRef_; + edm::Ptr > trkPtr_; + }; +} // namespace Phase2L1GMT + +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/ROITempAssociator.h b/L1Trigger/Phase2L1GMT/interface/ROITempAssociator.h new file mode 100644 index 0000000000000..9cc9a08243bde --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/ROITempAssociator.h @@ -0,0 +1,130 @@ +#ifndef PHASE2GMT_TEMPORARY_ASSOCIATOR +#define PHASE2GMT_TEMPORARY_ASSOCIATOR + +#include "ap_int.h" +#include "L1Trigger/Phase2L1GMT/interface/MuonROI.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +namespace Phase2L1GMT { + + class ROITempAssociator { + public: + ROITempAssociator(const edm::ParameterSet& iConfig) {} + ~ROITempAssociator() {} + + std::vector associate(int bx, + const l1t::ObjectRefBxCollection& muons, + const l1t::MuonStubRefVector& stubs) { + std::vector out; + l1t::MuonStubRefVector usedStubs; + + if (muons.size() > 0) { + for (unsigned int i = 0; i < muons.size(bx); ++i) { + const l1t::RegionalMuonCandRef& mu = muons.at(bx, i); + uint pt = mu->hwPt(); + uint charge = mu->hwSign(); + + float eta = mu->hwEta() * 0.010875; + + int globalPhi = 0; + if (mu->trackFinderType() == l1t::bmtf) { + globalPhi = mu->processor() * 48 + mu->hwPhi() - 24; + } else { + globalPhi = mu->processor() * 96 + mu->hwPhi() + 24; + } + + float phi = globalPhi * 2 * M_PI / 576.0; + if (phi > (M_PI)) + phi = phi - 2 * M_PI; + else if (phi < (-M_PI)) + phi = phi + 2 * M_PI; + + MuonROI roi(bx, charge, pt, 1); + roi.setMuonRef(mu); + l1t::MuonStubRefVector cleanedStubs = clean(stubs, usedStubs); + + for (unsigned int layer = 0; layer <= 4; ++layer) { + l1t::MuonStubRefVector selectedStubs = selectLayerBX(cleanedStubs, bx, layer); + int bestStubINT = -1; + float dPhi = 1000.0; + + for (uint i = 0; i < selectedStubs.size(); ++i) { + const l1t::MuonStubRef& stub = selectedStubs[i]; + float deltaPhi = (stub->quality() & 0x1) ? stub->offline_coord1() - phi : stub->offline_coord2() - phi; + if (deltaPhi > M_PI) + deltaPhi = deltaPhi - 2 * M_PI; + else if (deltaPhi < -M_PI) + deltaPhi = deltaPhi + 2 * M_PI; + deltaPhi = fabs(deltaPhi); + float deltaEta = (stub->etaQuality() == 0 || (stub->etaQuality() & 0x1)) + ? fabs(stub->offline_eta1() - eta) + : fabs(stub->offline_eta2() - eta); + if (deltaPhi < (M_PI / 6.0) && deltaEta < 0.3 && deltaPhi < dPhi) { + dPhi = deltaPhi; + bestStubINT = i; + } + } + if (bestStubINT >= 0) { + roi.addStub(selectedStubs[bestStubINT]); + usedStubs.push_back(selectedStubs[bestStubINT]); + } + } + if (out.size() < 16 && !roi.stubs().empty()) + out.push_back(roi); + } + } + //Now the stubs only . Find per layer + + l1t::MuonStubRefVector cleanedStubs = clean(stubs, usedStubs); + + while (!cleanedStubs.empty()) { + MuonROI roi(bx, 0, 0, 0); + roi.addStub(cleanedStubs[0]); + usedStubs.push_back(cleanedStubs[0]); + for (unsigned int layer = 0; layer <= 4; ++layer) { + if (layer == cleanedStubs[0]->tfLayer()) + continue; + l1t::MuonStubRefVector selectedStubs = selectLayerBX(cleanedStubs, bx, layer); + if (!selectedStubs.empty()) { + roi.addStub(selectedStubs[0]); + usedStubs.push_back(selectedStubs[0]); + } + } + if (!roi.stubs().empty()) + if (out.size() < 16) + out.push_back(roi); + cleanedStubs = clean(cleanedStubs, usedStubs); + } + return out; + } + + private: + l1t::MuonStubRefVector selectLayerBX(const l1t::MuonStubRefVector& all, int bx, uint layer) { + l1t::MuonStubRefVector out; + for (const auto& stub : all) { + if (stub->bxNum() == bx && stub->tfLayer() == layer) + out.push_back(stub); + } + return out; + } + + l1t::MuonStubRefVector clean(const l1t::MuonStubRefVector& all, const l1t::MuonStubRefVector& used) { + l1t::MuonStubRefVector out; + for (const auto& stub : all) { + bool keep = true; + for (const auto& st : used) { + if (st == stub) { + keep = false; + break; + } + } + if (keep) + out.push_back(stub); + } + return out; + } + }; +} // namespace Phase2L1GMT + +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/Tauto3Mu.h b/L1Trigger/Phase2L1GMT/interface/Tauto3Mu.h new file mode 100644 index 0000000000000..d117a5971a8d9 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/Tauto3Mu.h @@ -0,0 +1,154 @@ +// =========================================================================== +// +// Filename: Tauto3Mu.h +// +// Description: +// +// Version: 1.0 +// Created: 03/15/2021 07:33:59 PM +// Revision: none +// Compiler: g++ +// +// Author: Zhenbin Wu, zhenbin.wu@gmail.com +// +// =========================================================================== + +#ifndef PHASE2GMT_TAUTO3MU +#define PHASE2GMT_TAUTO3MU + +#include "L1Trigger/Phase2L1GMT/interface/TopologicalAlgorithm.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +namespace Phase2L1GMT { + class Tauto3Mu : public TopoAlgo { + public: + Tauto3Mu(const edm::ParameterSet &iConfig); + ~Tauto3Mu(); + Tauto3Mu(const Tauto3Mu &cpy); + // Interface function + bool GetTau3Mu(std::vector &trkMus, std::vector &convertedTracks); + + private: + bool Find3MuComb(std::vector &trkMus); + + bool FindCloset3Mu(std::vector > &mu_phis, + std::vector > &nearby3mu); + + int Get3MuDphi(unsigned target, unsigned obj1, unsigned obj2); + + int Get3MuMass(unsigned target, unsigned obj1, unsigned obj2); + + int GetDiMass(const l1t::TrackerMuon &mu1, const l1t::TrackerMuon &mu2); + }; + + inline Tauto3Mu::Tauto3Mu(const edm::ParameterSet &iConfig) {} + + inline Tauto3Mu::~Tauto3Mu() {} + + inline Tauto3Mu::Tauto3Mu(const Tauto3Mu &cpy) : TopoAlgo(cpy) {} + + // === FUNCTION ============================================================ + // Name: Tauto3Mu::GetTau3Mu + // Description: + // =========================================================================== + inline bool Tauto3Mu::GetTau3Mu(std::vector &trkMus, + std::vector &convertedTracks) { + Find3MuComb(trkMus); + return true; + } // ----- end of function Tauto3Mu::GetTau3Mu ----- + + // === FUNCTION ============================================================ + // Name: Tauto3Mu::Find3MuComb + // Description: + // =========================================================================== + inline bool Tauto3Mu::Find3MuComb(std::vector &trkMus) { + // vector< phi, index of trackerMuon > + std::vector > mu_phis; + for (unsigned i = 0; i < trkMus.size(); ++i) { + mu_phis.push_back(std::make_pair(trkMus.at(i).hwPhi(), i)); + } + + std::sort(mu_phis.begin(), mu_phis.end()); + + std::vector > nearby3mu; + std::vector mu3mass; + FindCloset3Mu(mu_phis, nearby3mu); + + for (unsigned i = 0; i < trkMus.size(); ++i) { + int trimass = Get3MuMass(i, nearby3mu.at(i).first, nearby3mu.at(i).second); + mu3mass.push_back(trimass); + } + + return true; + } // ----- end of function Tauto3Mu::Find3MuComb ----- + + // === FUNCTION ============================================================ + // Name: Tauto3Mu::Get3MuMass + // Description: + // =========================================================================== + inline int Tauto3Mu::Get3MuMass(unsigned target, unsigned obj1, unsigned obj2) { + int mass12 = GetDiMass(trkMus->at(target), trkMus->at(obj1)); + int mass23 = GetDiMass(trkMus->at(obj1), trkMus->at(obj2)); + int mass31 = GetDiMass(trkMus->at(obj2), trkMus->at(target)); + + return mass12 + mass23 + mass31; + } // ----- end of function Tauto3Mu::Get3MuMass ----- + + // === FUNCTION ============================================================ + // Name: Tauto3Mu::GetDiMass + // Description: + // =========================================================================== + inline int Tauto3Mu::GetDiMass(const l1t::TrackerMuon &mu1, const l1t::TrackerMuon &mu2) { + int deta = deltaEta(mu1.hwEta(), mu2.hwEta()); + int dphi = deltaPhi(mu1.hwPhi(), mu2.hwPhi()); + int mass = 2 * mu1.hwPt() * mu2.hwPt() * (cosh(deta) - cos(dphi)); + return mass; + } // ----- end of function Tauto3Mu::GetDiMass ----- + + // === FUNCTION ============================================================ + // Name: Tauto3Mu::FindCloset3Mu + // Description: + // =========================================================================== + inline bool Tauto3Mu::FindCloset3Mu(std::vector > &mu_phis, + std::vector > &nearby3mu) { + nearby3mu.clear(); + + std::vector > temp(mu_phis); + + // Round the last 2 to first element of vector + temp.insert(temp.begin(), mu_phis.back()); + temp.insert(temp.begin(), *(mu_phis.rbegin() - 1)); + // Append the first two element to vector + temp.push_back(mu_phis.front()); + temp.push_back(*(mu_phis.begin() + 1)); + + for (unsigned i = 2; i < temp.size() - 2; ++i) { + int combleft = Get3MuDphi(temp[i].second, temp[i - 1].second, temp[i - 2].second); + std::pair neighbors(temp[i - 1].second, temp[i - 2].second); + int mincomb(combleft); + + int combcenter = Get3MuDphi(temp[i].second, temp[i - 1].second, temp[i + 1].second); + if (combcenter < mincomb) { + neighbors = std::make_pair(temp[i - 1].second, temp[i + 1].second); + mincomb = combcenter; + } + + int combright = Get3MuDphi(temp[i].second, temp[i + 1].second, temp[i + 2].second); + if (combright < mincomb) { + neighbors = std::make_pair(temp[i + 1].second, temp[i + 2].second); + } + + nearby3mu.push_back(neighbors); + } + + return true; + } // ----- end of function Tauto3Mu::FindCloset3Mu ----- + + inline int Tauto3Mu::Get3MuDphi(unsigned target, unsigned obj1, unsigned obj2) { + int dPhi1 = deltaPhi(trkMus->at(target).hwPhi(), trkMus->at(obj1).hwPhi()); + int dPhi2 = deltaPhi(trkMus->at(target).hwPhi(), trkMus->at(obj2).hwPhi()); + return dPhi1 + dPhi2; + } +} // namespace Phase2L1GMT + +#endif // ----- #ifndef PHASE2GMT_TAUTO3MU ----- diff --git a/L1Trigger/Phase2L1GMT/interface/TopologicalAlgorithm.h b/L1Trigger/Phase2L1GMT/interface/TopologicalAlgorithm.h new file mode 100644 index 0000000000000..8a17bb292dcb7 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/TopologicalAlgorithm.h @@ -0,0 +1,117 @@ +// =========================================================================== +// +// Filename: TopologicalAlgorithm.h +// +// Description: A base class for all the topological algorithms +// +// Version: 1.0 +// Created: 03/03/2021 10:14:23 AM +// Revision: none +// Compiler: g++ +// +// Author: Zhenbin Wu, zhenbin.wu@gmail.com +// +// =========================================================================== + +#ifndef PHASE2GMT_TOPOLOGICALALGORITHM +#define PHASE2GMT_TOPOLOGICALALGORITHM + +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" +#include "L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h" +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" + +#include + +namespace Phase2L1GMT { + + class TopoAlgo { + public: + TopoAlgo(); + ~TopoAlgo(); + TopoAlgo(const TopoAlgo &cpy); + void load(std::vector &trkMus, std::vector &convertedTracks); + void DumpInputs(); + + int deltaEta(const int eta1, const int eta2); + int deltaZ0(const int Z01, const int Z02); + int deltaPhi(int phi1, int phi2); + + protected: + std::vector *trkMus; + std::vector *convertedTracks; + std::ofstream dumpInput; + }; + + inline TopoAlgo::TopoAlgo() {} + + inline TopoAlgo::~TopoAlgo() {} + + inline TopoAlgo::TopoAlgo(const TopoAlgo &cpy) {} + + // === FUNCTION ============================================================ + // Name: TopoAlgo::load + // Description: + // =========================================================================== + inline void TopoAlgo::load(std::vector &trkMus_, std::vector &convertedTracks_) { + trkMus = &trkMus_; + convertedTracks = &convertedTracks_; + } // ----- end of function TopoAlgo::load ----- + + inline void TopoAlgo::DumpInputs() { + static int nevti = 0; + int totalsize = 0; + // Current setting + int constexpr exptotal = 12 + 18 * 100; // N_Muon + N_TRK_LINKS * NTRKperlinks + for (unsigned int i = 0; i < 12; ++i) { + if (i < trkMus->size()) + dumpInput << " " << nevti << " 0 " << i << " " << trkMus->at(i).hwPt() * LSBpt << " " + << trkMus->at(i).hwEta() * LSBeta << " " << trkMus->at(i).hwPhi() * LSBphi << " " + << trkMus->at(i).hwZ0() * LSBGTz0 << " " << trkMus->at(i).charge() << std::endl; + else + dumpInput << " " << nevti << " 0 " << i << " " << 0 << " " << 0 << " " << 0 << " " << 0 << " " << 0 + << std::endl; + totalsize++; + } + for (unsigned int i = 0; i < convertedTracks->size(); ++i) { + dumpInput << " " << nevti << " 1 " << i << " " << convertedTracks->at(i).pt() * LSBpt << " " + << convertedTracks->at(i).eta() * LSBeta << " " << convertedTracks->at(i).phi() * LSBphi << " " + << convertedTracks->at(i).z0() * LSBGTz0 << " " << convertedTracks->at(i).charge() << " " + << convertedTracks->at(i).quality() << std::endl; + totalsize++; + } + int ntrks = convertedTracks->size(); + // Pat the remaining + while (totalsize < exptotal) { + dumpInput << " " << nevti << " 1 " << ntrks++ << " " << 0 << " " << 0 << " " << 0 << " " << 0 << " " << 0 << " " + << 0 << std::endl; + totalsize++; + } + nevti++; + } + + inline int TopoAlgo::deltaEta(const int eta1, const int eta2) { + static const int maxbits = (1 << BITSETA) - 1; + int deta = abs(eta1 - eta2); + deta &= maxbits; + return deta; + } + + inline int TopoAlgo::deltaZ0(const int Z01, const int Z02) { + static const int maxbits = (1 << BITSZ0) - 1; + int dZ0 = abs(Z01 - Z02); + dZ0 &= maxbits; + return dZ0; + } + + // Ideal the object should carry its own ap types once we finalize + inline int TopoAlgo::deltaPhi(int phi1, int phi2) { + static const int maxbits = (1 << BITSPHI) - 1; + static const int pibits = (1 << (BITSPHI - 1)); + int dphi = abs(phi1 - phi2); + if (dphi >= pibits) + dphi = maxbits - dphi; + return dphi; + } +} // namespace Phase2L1GMT + +#endif // ----- #ifndef PHASE2GMT_TOPOLOGICALALGORITHM ----- diff --git a/L1Trigger/Phase2L1GMT/interface/TrackConverter.h b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h new file mode 100644 index 0000000000000..e42fb43bd4a9e --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/TrackConverter.h @@ -0,0 +1,91 @@ +#ifndef PHASE2GMT_TRACKCONVERTER +#define PHASE2GMT_TRACKCONVERTER + +#include "L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +namespace Phase2L1GMT { + + class TrackConverter { + public: + TrackConverter(const edm::ParameterSet& iConfig) : verbose_(iConfig.getParameter("verbose")) {} + ~TrackConverter() {} + + std::vector convertTracks(const std::vector >& tracks) { + std::vector out; + out.reserve(tracks.size()); + for (const auto& t : tracks) + out.push_back(convert(t)); + return out; + } + + private: + int verbose_; + typedef ap_uint<96> wordtype; + + uint generateQuality(const edm::Ptr >& track) { return 1; } + + uint ptLookup(uint absCurv) { + for (auto i : ptShifts) { + if (absCurv >= uint(i[0]) && absCurv < uint(i[1])) { + if (i[2] < 0) + return i[4]; + else + return (absCurv >> i[2]) + i[3]; + } + } + return 0; + } + + uint etaLookup(uint absTanL) { + for (auto i : etaShifts) { + if (absTanL >= uint(i[0]) && absTanL < uint(i[1])) { + if (i[2] < 0) + return i[4]; + else + return (absTanL >> i[2]) + i[3]; + } + } + return 0; + } + + ConvertedTTTrack convert(const edm::Ptr >& track) { + uint charge = (track->rInv() < 0) ? 1 : 0; + int curvature = track->rInv() * (1 << (BITSTTCURV - 1)) / maxCurv_; + int phi = track->phi() * (1 << (BITSPHI - 1)) / (M_PI); + int tanLambda = track->tanL() * (1 << (BITSTTTANL - 1)) / maxTanl_; + int z0 = track->z0() * (1 << (BITSZ0 - 1)) / maxZ0_; + int d0 = track->d0() * (1 << (BITSD0 - 1)) / maxD0_; + //calculate pt + uint absCurv = curvature > 0 ? (curvature) : (-curvature); + uint pt = ptLUT[ptLookup(absCurv)]; + uint quality = generateQuality(track); + uint absTanL = tanLambda > 0 ? (tanLambda) : (-tanLambda); + uint absEta = etaLUT[etaLookup(absTanL)]; + int eta = tanLambda > 0 ? (absEta) : (-absEta); + + ap_int phiSec = ap_int(phi) - + ap_int((track->phiSector() * 40 * M_PI / 180.) * (1 << (BITSPHI - 1)) / (M_PI)); + ap_int phiCorrected = ap_int(phiSec + track->phiSector() * 910); + + wordtype word = 0; + int bstart = 0; + bstart = wordconcat(word, bstart, curvature, BITSTTCURV); + bstart = wordconcat(word, bstart, phiSec, BITSTTPHI); + bstart = wordconcat(word, bstart, tanLambda, BITSTTTANL); + bstart = wordconcat(word, bstart, z0, BITSZ0); + bstart = wordconcat(word, bstart, d0, BITSD0); + bstart = wordconcat(word, bstart, uint(track->chi2()), 4); + + ConvertedTTTrack convertedTrack(charge, curvature, absEta, pt, eta, phiCorrected.to_int(), z0, d0, quality, word); + convertedTrack.setOfflineQuantities(track->momentum().transverse(), track->eta(), track->phi()); + if (verbose_) + convertedTrack.print(); + convertedTrack.setTrkPtr(track); + return convertedTrack; + } + }; +} // namespace Phase2L1GMT + +#endif diff --git a/L1Trigger/Phase2L1GMT/interface/TrackMuonMatchAlgorithm.h b/L1Trigger/Phase2L1GMT/interface/TrackMuonMatchAlgorithm.h new file mode 100644 index 0000000000000..387f723f859c3 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/interface/TrackMuonMatchAlgorithm.h @@ -0,0 +1,626 @@ +#ifndef PHASE2GMT_TRACKMUONMATCHALGO +#define PHASE2GMT_TRACKMUONMATCHALGO + +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack_TrackWord.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1TMuonPhase2/interface/MuonStub.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" +#include "DataFormats/L1Trigger/interface/L1TObjComparison.h" +#include "L1Trigger/Phase2L1GMT/interface/TrackConverter.h" +#include "L1Trigger/Phase2L1GMT/interface/PreTrackMatchedMuon.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" +#include "L1Trigger/Phase2L1GMT/interface/MuonROI.h" +#include "L1Trigger/Phase2L1GMT/interface/ConvertedTTTrack.h" +#include + +namespace Phase2L1GMT { + + const unsigned int PHIDIVIDER = 1 << (BITSPHI - BITSSTUBCOORD); + const unsigned int ETADIVIDER = 1 << (BITSETA - BITSSTUBETA); + + typedef struct { + ap_int coord1; + ap_uint sigma_coord1; + ap_int coord2; + ap_uint sigma_coord2; + ap_int eta; + ap_uint sigma_eta1; + ap_uint sigma_eta2; + ap_uint<1> valid; + ap_uint<1> is_barrel; + } propagation_t; + + typedef struct { + ap_uint quality; + ap_uint id; + ap_uint<1> valid; + bool isGlobal; + l1t::RegionalMuonCandRef muRef; + l1t::MuonStubRef stubRef; + + } match_t; + + class TrackMuonMatchAlgorithm { + public: + TrackMuonMatchAlgorithm(const edm::ParameterSet& iConfig) : verbose_(iConfig.getParameter("verbose")) {} + + ~TrackMuonMatchAlgorithm() {} + + std::vector processNonant(const std::vector& convertedTracks, + const std::vector& rois) { + std::vector preMuons; + for (const auto& track : convertedTracks) { + PreTrackMatchedMuon mu = processTrack(track, rois); + if (mu.valid() && preMuons.size() < 16) + preMuons.push_back(mu); + } + std::vector cleanedMuons = clean(preMuons); + return cleanedMuons; + } + + std::vector cleanNeighbor(const std::vector& muons, + const std::vector& muonsPrevious, + const std::vector& muonsNext, + bool equality) { + std::vector out; + + if (muons.empty()) + return out; + + if (verbose_ == 1) { + printf("-----Cleaning Up Muons in the neighbours\n"); + printf("Before:\n"); + } + + for (uint i = 0; i < muons.size(); ++i) { + if (verbose_ == 1) { + muons[i].print(); + } + ap_uint<5> mask = 0x1f; + for (uint j = 0; j < muonsPrevious.size(); ++j) { + mask = mask & cleanMuon(muons[i], muonsPrevious[j], equality); + } + for (uint j = 0; j < muonsNext.size(); ++j) { + mask = mask & cleanMuon(muons[i], muonsNext[j], equality); + } + if (mask) { + if (verbose_ == 1) + printf("kept\n"); + out.push_back(muons[i]); + } else { + if (verbose_ == 1) + printf("discarded\n"); + } + } + return out; + } + + std::vector convert(std::vector& muons, uint maximum) { + std::vector out; + for (const auto& mu : muons) { + if (out.size() == maximum) + break; + l1t::TrackerMuon muon(mu.trkPtr(), mu.charge(), mu.pt(), mu.eta(), mu.phi(), mu.z0(), mu.d0(), mu.quality()); + //muon.setMuonRef(mu.muonRef()); + for (const auto& stub : mu.stubs()) + muon.addStub(stub); + out.push_back(muon); + if (verbose_ == 1) { + printf("Final Muon:"); + muon.print(); + } + } + return out; + } + + bool outputGT(std::vector& muons) { + for (auto& mu : muons) { + wordtype word1 = 0; + wordtype word2 = 0; + + int bstart = 0; + bstart = wordconcat(word1, bstart, mu.hwPt(), BITSGTPT); + bstart = wordconcat(word1, bstart, mu.hwPhi(), BITSGTPHI); + bstart = wordconcat(word1, bstart, mu.hwEta(), BITSGTETA); + bstart = wordconcat(word1, bstart, mu.hwZ0(), BITSGTZ0); + bstart = wordconcat(word1, bstart, (mu.hwD0() >> 2), BITSGTD0); + + bstart = 0; + bstart = wordconcat(word2, bstart, mu.hwCharge(), 1); + bstart = wordconcat(word2, bstart, mu.hwQual(), BITSGTQUALITY); + bstart = wordconcat(word2, bstart, mu.hwIso(), BITSGTISO); + bstart = wordconcat(word2, bstart, mu.hwBeta(), BITSMUONBETA); + + std::array wordout = {{word1, word2}}; + mu.setWord(wordout); + } + return true; + } + + std::vector sort(std::vector& muons, uint maximum) { + if (muons.size() < 2) + return muons; + + std::sort(muons.begin(), muons.end(), [](l1t::TrackerMuon a, l1t::TrackerMuon b) { return a.hwPt() > b.hwPt(); }); + std::vector out; + for (unsigned int i = 0; i < muons.size(); ++i) { + out.push_back(muons[i]); + if (i == (maximum - 1)) + break; + } + + return out; + } + + private: + int verbose_; + + propagation_t propagate(const ConvertedTTTrack& track, uint layer) { + ap_uint prop_coord1 = 0; + ap_uint prop_coord2 = 0; + ap_uint res0_coord1 = 0; + ap_uint res1_coord1 = 0; + ap_uint res0_coord2 = 0; + ap_uint res1_coord2 = 0; + ap_uint res0_eta1 = 0; + ap_uint res1_eta = 0; + ap_uint res0_eta2 = 0; + ap_uint<1> is_barrel = 0; + + uint reducedAbsEta = track.abseta() / 8; + + if (layer == 0) { + prop_coord1 = lt_prop_coord1_0[reducedAbsEta]; + prop_coord2 = lt_prop_coord2_0[reducedAbsEta]; + res0_coord1 = lt_res0_coord1_0[reducedAbsEta]; + res1_coord1 = lt_res1_coord1_0[reducedAbsEta]; + res0_coord2 = lt_res0_coord2_0[reducedAbsEta]; + res1_coord2 = lt_res1_coord2_0[reducedAbsEta]; + res0_eta1 = lt_res0_eta1_0[reducedAbsEta]; + res1_eta = lt_res1_eta_0[reducedAbsEta]; + res0_eta2 = lt_res0_eta2_0[reducedAbsEta]; + is_barrel = reducedAbsEta < barrelLimit0_ ? 1 : 0; + } else if (layer == 1) { + prop_coord1 = lt_prop_coord1_1[reducedAbsEta]; + prop_coord2 = lt_prop_coord2_1[reducedAbsEta]; + res0_coord1 = lt_res0_coord1_1[reducedAbsEta]; + res1_coord1 = lt_res1_coord1_1[reducedAbsEta]; + res0_coord2 = lt_res0_coord2_1[reducedAbsEta]; + res1_coord2 = lt_res1_coord2_1[reducedAbsEta]; + res0_eta1 = lt_res0_eta1_1[reducedAbsEta]; + res1_eta = lt_res1_eta_1[reducedAbsEta]; + res0_eta2 = lt_res0_eta2_1[reducedAbsEta]; + is_barrel = reducedAbsEta < barrelLimit1_ ? 1 : 0; + + } else if (layer == 2) { + prop_coord1 = lt_prop_coord1_2[reducedAbsEta]; + prop_coord2 = lt_prop_coord2_2[reducedAbsEta]; + res0_coord1 = lt_res0_coord1_2[reducedAbsEta]; + res1_coord1 = lt_res1_coord1_2[reducedAbsEta]; + res0_coord2 = lt_res0_coord2_2[reducedAbsEta]; + res1_coord2 = lt_res1_coord2_2[reducedAbsEta]; + res0_eta1 = lt_res0_eta1_2[reducedAbsEta]; + res1_eta = lt_res1_eta_2[reducedAbsEta]; + res0_eta2 = lt_res0_eta2_2[reducedAbsEta]; + is_barrel = reducedAbsEta < barrelLimit2_ ? 1 : 0; + + } else if (layer == 3) { + prop_coord1 = lt_prop_coord1_3[reducedAbsEta]; + prop_coord2 = lt_prop_coord2_3[reducedAbsEta]; + res0_coord1 = lt_res0_coord1_3[reducedAbsEta]; + res1_coord1 = lt_res1_coord1_3[reducedAbsEta]; + res0_coord2 = lt_res0_coord2_3[reducedAbsEta]; + res1_coord2 = lt_res1_coord2_3[reducedAbsEta]; + res0_eta1 = lt_res0_eta1_3[reducedAbsEta]; + res1_eta = lt_res1_eta_3[reducedAbsEta]; + res0_eta2 = lt_res0_eta2_3[reducedAbsEta]; + is_barrel = reducedAbsEta < barrelLimit3_ ? 1 : 0; + + } else if (layer == 4) { + prop_coord1 = lt_prop_coord1_4[reducedAbsEta]; + prop_coord2 = lt_prop_coord2_4[reducedAbsEta]; + res0_coord1 = lt_res0_coord1_4[reducedAbsEta]; + res1_coord1 = lt_res1_coord1_4[reducedAbsEta]; + res0_coord2 = lt_res0_coord2_4[reducedAbsEta]; + res1_coord2 = lt_res1_coord2_4[reducedAbsEta]; + res0_eta1 = lt_res0_eta1_4[reducedAbsEta]; + res1_eta = lt_res1_eta_4[reducedAbsEta]; + res0_eta2 = lt_res0_eta2_4[reducedAbsEta]; + is_barrel = 0; + } + + propagation_t out; + ap_int curvature = track.curvature(); + ap_int phi = track.phi(); + ap_int c1kFull = prop_coord1 * curvature; + ap_int c1k = (c1kFull) / 1024; + ap_int coord1 = phi - c1k; + + out.coord1 = coord1 / PHIDIVIDER; + + ap_int c2kFull = prop_coord2 * curvature; + + ap_int c2k = (c2kFull) / 1024; + if (is_barrel) + out.coord2 = -c2k / PHIDIVIDER; + else + out.coord2 = (phi - c2k) / PHIDIVIDER; + + ap_int eta = track.eta(); + out.eta = eta / ETADIVIDER; + + ap_uint<2 * BITSTTCURV - 2> curvature2All = curvature * curvature; + ap_uint curvature2 = curvature2All / 2; + + //Remember to change emulator with new k2 + ap_uint rescoord1k = (res1_coord1 * curvature2) >> 23; + ap_ufixed sigma_coord1 = res0_coord1 + rescoord1k; + out.sigma_coord1 = ap_uint(sigma_coord1); + + ap_uint rescoord2k = (res1_coord2 * curvature2) >> 23; + ap_ufixed sigma_coord2 = res0_coord2 + rescoord2k; + out.sigma_coord2 = ap_uint(sigma_coord2); + + ap_uint resetak = (res1_eta * curvature2) >> 23; + ap_ufixed sigma_eta1 = res0_eta1 + resetak; + out.sigma_eta1 = ap_uint(sigma_eta1); + ap_ufixed sigma_eta2 = res0_eta2 + resetak; + out.sigma_eta2 = ap_uint(sigma_eta2); + out.valid = 1; + out.is_barrel = is_barrel; + + if (verbose_ == 1) + + printf("Propagating to layer %d:is barrel=%d coords=%d+-%d , %d +-%d etas = %d +- %d +-%d\n", + int(layer), + out.is_barrel.to_int(), + out.coord1.to_int(), + out.sigma_coord1.to_int(), + out.coord2.to_int(), + out.sigma_coord2.to_int(), + out.eta.to_int(), + out.sigma_eta1.to_int(), + out.sigma_eta2.to_int()); + + return out; + } + + ap_uint deltaEta(const ap_int& eta1, const ap_int& eta2) { + ap_fixed dEta = eta1 - eta2; + if (dEta < 0) + return ap_uint(-dEta); + else + return ap_uint(dEta); + } + + ap_uint deltaCoord(const ap_int& phi1, const ap_int& phi2) { + ap_int dPhiRoll = phi1 - phi2; + ap_ufixed dPhi; + if (dPhiRoll < 0) + dPhi = ap_ufixed(-dPhiRoll); + else + dPhi = ap_ufixed(dPhiRoll); + + return ap_uint(dPhi); + } + + match_t match(const propagation_t prop, const l1t::MuonStubRef& stub) { + if (verbose_ == 1) { + printf("Matching to "); + stub->print(); + } + //Matching of Coord1 + ap_uint<1> coord1Matched; + ap_uint deltaCoord1 = deltaCoord(prop.coord1, stub->coord1()); + if (deltaCoord1 <= prop.sigma_coord1 && (stub->quality() & 0x1)) { + coord1Matched = 1; + } else { + coord1Matched = 0; + } + if (verbose_ == 1) + printf("Coord1 matched=%d delta=%d res=%d\n", + coord1Matched.to_int(), + deltaCoord1.to_int(), + prop.sigma_coord1.to_int()); + + //Matching of Coord2 + ap_uint<1> coord2Matched; + ap_uint deltaCoord2 = deltaCoord(prop.coord2, stub->coord2()); + if (deltaCoord2 <= prop.sigma_coord2 && (stub->quality() & 0x2)) { + coord2Matched = 1; + } else { + coord2Matched = 0; + } + if (verbose_ == 1) + printf("Coord2 matched=%d delta=%d res=%d\n", + coord2Matched.to_int(), + deltaCoord2.to_int(), + prop.sigma_coord2.to_int()); + + //Matching of Eta1 + + ap_uint<1> eta1Matched; + + //if we have really bad quality[Barrel no eta] + //increase the resolution + ap_ufixed prop_sigma_eta1; + if (stub->etaQuality() == 0) + prop_sigma_eta1 = prop.sigma_eta1 + 6; + else + prop_sigma_eta1 = prop.sigma_eta1; + + ap_uint deltaEta1 = deltaEta(prop.eta, stub->eta1()); + if (deltaEta1 <= prop_sigma_eta1 && (stub->etaQuality() == 0 || (stub->etaQuality() & 0x1))) + eta1Matched = 1; + else + eta1Matched = 0; + + if (verbose_ == 1) + printf("eta1 matched=%d delta=%d res=%d\n", eta1Matched.to_int(), deltaEta1.to_int(), prop_sigma_eta1.to_int()); + + //Matching of Eta2 + + ap_uint<1> eta2Matched; + + ap_uint deltaEta2 = deltaEta(prop.eta, stub->eta2()); + if (deltaEta2 <= prop.sigma_eta2 && (stub->etaQuality() & 0x2)) + eta2Matched = 1; + else + eta2Matched = 0; + match_t out; + out.id = stub->id(); + + if (verbose_ == 1) + printf("eta2 matched=%d delta=%d res=%d\n", eta2Matched.to_int(), deltaEta2.to_int(), prop.sigma_eta2.to_int()); + + //if barrel, coord1 has to always be matched, coord2 maybe and eta1 is needed if etaQ=0 or then the one that depends on eta quality + if (prop.is_barrel) { + out.valid = (coord1Matched == 1 && (eta1Matched == 1 || eta2Matched == 1)); + if (out.valid == 0) { + out.quality = 0; + } else { + out.quality = 32 - deltaCoord1; + if (coord2Matched == 1) + out.quality += 32 - deltaCoord2; + } + } + //if endcap each coordinate is independent except the case where phiQuality=1 and etaQuality==3 + else { + bool match1 = (coord1Matched == 1 && eta1Matched == 1); + bool match2 = (coord2Matched == 1 && eta2Matched == 1); + bool match3 = + (coord1Matched == 1 && (eta1Matched || eta2Matched) && stub->etaQuality() == 3 && stub->quality() == 1); + out.valid = match1 || match2 || match3; + if (out.valid == 0) + out.quality = 0; + else { + out.quality = 0; + if (match1 || match3) + out.quality += 32 - deltaCoord1; + if (match2) + out.quality += 32 - deltaCoord2; + } + } + if (verbose_ == 1) + printf("GlobalMatchQuality = %d\n", out.quality.to_int()); + out.stubRef = stub; + return out; + } + + match_t propagateAndMatch(const ConvertedTTTrack& track, const l1t::MuonStubRef& stub) { + propagation_t prop = propagate(track, stub->tfLayer()); + return match(prop, stub); + } + + match_t getBest(const std::vector matches) { + match_t best = matches[0]; + for (const auto& m : matches) { + if (m.quality > best.quality) + best = m; + } + + return best; + } + + PreTrackMatchedMuon processTrack(const ConvertedTTTrack& track, const std::vector& rois) { + std::vector matchInfo0; + std::vector matchInfo1; + std::vector matchInfo2; + std::vector matchInfo3; + std::vector matchInfo4; + + if (verbose_ == 1 && !rois.empty()) { + printf("-----------processing new track----------"); + track.print(); + } + for (const auto& roi : rois) { + if (verbose_ == 1) { + printf("New ROI with %d stubs \n", int(roi.stubs().size())); + } + for (const auto& stub : roi.stubs()) { + match_t m = propagateAndMatch(track, stub); + if (m.valid == 1) { + if (roi.isGlobalMuon() && roi.muonRef().isNonnull()) { + m.isGlobal = true; + m.muRef = roi.muonRef(); + } + + if (stub->tfLayer() == 0) + matchInfo0.push_back(m); + else if (stub->tfLayer() == 1) + matchInfo1.push_back(m); + else if (stub->tfLayer() == 2) + matchInfo2.push_back(m); + else if (stub->tfLayer() == 3) + matchInfo3.push_back(m); + else if (stub->tfLayer() == 4) + matchInfo4.push_back(m); + } + } + } + + ap_ufixed<6, 6, AP_TRN_ZERO, AP_SAT_SYM> ptPenalty = ap_ufixed<6, 6, AP_TRN_ZERO, AP_SAT_SYM>(track.pt() / 32); + + ap_uint quality = 0; + PreTrackMatchedMuon muon(track.charge(), track.pt(), track.eta(), track.phi(), track.z0(), track.d0()); + + if (!matchInfo0.empty()) { + match_t b = getBest(matchInfo0); + if (b.valid) { + muon.addStub(b.stubRef); + if (b.isGlobal) + muon.addMuonRef(b.muRef); + quality += b.quality; + } + } + if (!matchInfo1.empty()) { + match_t b = getBest(matchInfo1); + if (b.valid) { + muon.addStub(b.stubRef); + if (b.isGlobal) + muon.addMuonRef(b.muRef); + quality += b.quality; + } + } + if (!matchInfo2.empty()) { + match_t b = getBest(matchInfo2); + if (b.valid) { + muon.addStub(b.stubRef); + if (b.isGlobal) + muon.addMuonRef(b.muRef); + quality += b.quality; + } + } + if (!matchInfo3.empty()) { + match_t b = getBest(matchInfo3); + if (b.valid) { + muon.addStub(b.stubRef); + if (b.isGlobal) + muon.addMuonRef(b.muRef); + quality += b.quality; + } + } + if (!matchInfo4.empty()) { + match_t b = getBest(matchInfo4); + if (b.valid) { + muon.addStub(b.stubRef); + if (b.isGlobal) + muon.addMuonRef(b.muRef); + quality += b.quality; + } + } + + muon.setOfflineQuantities(track.offline_pt(), track.offline_eta(), track.offline_phi()); + muon.setTrkPtr(track.trkPtr()); + + ap_uint<8> etaAddr = muon.eta() < 0 ? ap_uint<8>(-muon.eta() / 256) : ap_uint<8>((muon.eta()) / 256); + ap_uint<8> ptAddr = muon.pt() > 4095 ? ap_uint<8>(15) : ap_uint<8>(muon.pt() / 256); + ap_uint<8> addr = ptAddr | (etaAddr << 4); + ap_uint<8> qualityCut = lt_tpsID[addr]; + + if (quality >= qualityCut) { + muon.setValid(true); + muon.setQuality(quality + ptPenalty); + } else { + muon.setValid(false); + muon.setQuality(0); + muon.resetGlobal(); + } + if (verbose_ == 1) + muon.print(); + + if (verbose_ == 1 && !rois.empty()) { //patterns for HLS + + printf("TPS %d", track.trkPtr()->phiSector()); + track.printWord(); + + for (uint i = 0; i < 16; ++i) { + if (rois.size() > i) { + rois[i].printROILine(); + } else { + printf("%08x", 0); + printf("%016lx", 0x1ff000000000000); + printf("%016lx", 0x1ff000000000000); + printf("%016lx", 0x1ff000000000000); + printf("%016lx", 0x1ff000000000000); + printf("%016lx", 0x1ff000000000000); + } + } + muon.printWord(); + printf("\n"); + } + return muon; + } + + ap_uint<5> cleanMuon(const PreTrackMatchedMuon& mu, const PreTrackMatchedMuon& other, bool eq) { + ap_uint<5> valid = 0; + ap_uint<5> overlap = 0; + if (mu.stubID0() != 511) { + valid = valid | 0x1; + if (mu.stubID0() == other.stubID0()) + overlap = overlap | 0x1; + } + if (mu.stubID1() != 511) { + valid = valid | 0x2; + if (mu.stubID1() == other.stubID1()) + overlap = overlap | 0x2; + } + if (mu.stubID2() != 511) { + valid = valid | 0x4; + if (mu.stubID2() == other.stubID2()) + overlap = overlap | 0x4; + } + if (mu.stubID3() != 511) { + valid = valid | 0x8; + if (mu.stubID3() == other.stubID3()) + overlap = overlap | 0x8; + } + if (mu.stubID4() != 511) { + valid = valid | 0x10; + if (mu.stubID4() == other.stubID4()) + overlap = overlap | 0x10; + } + + if (((mu.quality() < other.quality()) && (!eq)) || ((mu.quality() <= other.quality()) && (eq))) + return valid & (~overlap); + else + return valid; + } + + std::vector clean(std::vector& muons) { + std::vector out; + if (muons.empty()) + return out; + if (verbose_ == 1) { + printf("-----Cleaning Up Muons in the same Nonant\n"); + printf("Before:\n"); + } + for (uint i = 0; i < muons.size(); ++i) { + if (verbose_ == 1) + muons[i].print(); + + ap_uint<5> mask = 0x1f; + for (uint j = 0; j < muons.size(); ++j) { + if (i == j) + continue; + mask = mask & cleanMuon(muons[i], muons[j], false); + } + if (mask) { + if (verbose_ == 1) + printf("kept\n"); + out.push_back(muons[i]); + } else { + if (verbose_ == 1) + printf("discarded\n"); + } + } + return out; + } + }; +} // namespace Phase2L1GMT + +#endif diff --git a/L1Trigger/Phase2L1GMT/plugins/BuildFile.xml b/L1Trigger/Phase2L1GMT/plugins/BuildFile.xml new file mode 100644 index 0000000000000..517b69ea337ab --- /dev/null +++ b/L1Trigger/Phase2L1GMT/plugins/BuildFile.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTProducer.cc new file mode 100644 index 0000000000000..dc8f78b14f18d --- /dev/null +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTProducer.cc @@ -0,0 +1,136 @@ +#include +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h" +#include "L1Trigger/Phase2L1GMT/interface/Node.h" + +// +// class declaration +// +using namespace Phase2L1GMT; +using namespace l1t; + +class Phase2L1TGMTProducer : public edm::stream::EDProducer<> { +public: + explicit Phase2L1TGMTProducer(const edm::ParameterSet&); + ~Phase2L1TGMTProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void beginStream(edm::StreamID) override; + void produce(edm::Event&, const edm::EventSetup&) override; + void endStream() override; + std::unique_ptr node_; + edm::EDGetTokenT srcTracks_; + edm::EDGetTokenT > srcStubs_; + edm::EDGetTokenT > bmtfTracks_; + edm::EDGetTokenT > emtfTracks_; + edm::EDGetTokenT > omtfTracks_; + int minTrackStubs_; + int bxMin_; + int bxMax_; +}; + +Phase2L1TGMTProducer::Phase2L1TGMTProducer(const edm::ParameterSet& iConfig) + : node_(new Node(iConfig)), + srcTracks_(consumes(iConfig.getParameter("srcTracks"))), + srcStubs_(consumes >(iConfig.getParameter("srcStubs"))), + bmtfTracks_(consumes >(iConfig.getParameter("srcBMTF"))), + emtfTracks_(consumes >(iConfig.getParameter("srcEMTF"))), + omtfTracks_(consumes >(iConfig.getParameter("srcOMTF"))), + minTrackStubs_(iConfig.getParameter("minTrackStubs")), + bxMin_(iConfig.getParameter("muonBXMin")), + bxMax_(iConfig.getParameter("muonBXMax")) + +{ + produces >(); +} + +Phase2L1TGMTProducer::~Phase2L1TGMTProducer() { + // do anything here that needs to be done at destruction time + // (e.g. close files, deallocate resources etc.) +} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void Phase2L1TGMTProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + Handle trackHandle; + iEvent.getByToken(srcTracks_, trackHandle); + std::vector > tracks; + for (uint i = 0; i < trackHandle->size(); ++i) { + edm::Ptr track(trackHandle, i); + if (track->momentum().transverse() < 2.0) + continue; + if (track->getStubRefs().size() >= (unsigned int)(minTrackStubs_)) + tracks.push_back(track); + } + + Handle > stubHandle; + iEvent.getByToken(srcStubs_, stubHandle); + l1t::MuonStubRefVector stubs; + for (uint i = 0; i < stubHandle->size(); ++i) { + l1t::MuonStubRef stub(stubHandle, i); + if (stub->bxNum() >= bxMin_ && stub->bxNum() <= bxMax_) + stubs.push_back(stub); + } + + ObjectRefBxCollection muonTracks; + // BXVector muonTracks; + + Handle > bmtfHandle; + iEvent.getByToken(bmtfTracks_, bmtfHandle); + Handle > emtfHandle; + iEvent.getByToken(emtfTracks_, emtfHandle); + Handle > omtfHandle; + iEvent.getByToken(omtfTracks_, omtfHandle); + + for (int bx = bxMin_; bx <= bxMax_; ++bx) { + if (bx >= bmtfHandle->getFirstBX() && bx <= bmtfHandle->getLastBX()) + for (size_t i = 0; i < bmtfHandle->size(bx); ++i) { + RegionalMuonCandRef muon(bmtfHandle, i); + muonTracks.push_back(bx, muon); + } + if (bx >= omtfHandle->getFirstBX() && bx <= omtfHandle->getLastBX()) + for (size_t i = 0; i < omtfHandle->size(bx); ++i) { + RegionalMuonCandRef muon(omtfHandle, i); + muonTracks.push_back(bx, muon); + } + if (bx >= emtfHandle->getFirstBX() && bx <= emtfHandle->getLastBX()) + for (size_t i = 0; i < emtfHandle->size(bx); ++i) { + RegionalMuonCandRef muon(emtfHandle, i); + muonTracks.push_back(bx, muon); + } + } + + std::vector out = node_->processEvent(tracks, muonTracks, stubs); + std::unique_ptr > out1 = std::make_unique >(out); + iEvent.put(std::move(out1)); +} + +// ------------ method called once each stream before processing any runs, lumis or events ------------ +void Phase2L1TGMTProducer::beginStream(edm::StreamID) {} + +// ------------ method called once each stream after processing all runs, lumis and events ------------ +void Phase2L1TGMTProducer::endStream() {} + +void Phase2L1TGMTProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(Phase2L1TGMTProducer); diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTSAMuonProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTSAMuonProducer.cc new file mode 100644 index 0000000000000..8091ba34f0fc4 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTSAMuonProducer.cc @@ -0,0 +1,179 @@ +// -*- C++ -*- +// +// Package: L1Trigger/Phase2L1GMT +// Class: Phase2L1TGMTSAMuonProducer +// +/**\class Phase2L1TGMTSAMuonProducer Phase2L1TGMTSAMuonProducer.cc L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTSAMuonProducer.cc + + Description: [one line class summary] + + Implementation: + [Notes on implementation] +*/ +// +// Original Author: Zhenbin Wu +// Created: Fri, 30 Apr 2021 19:10:59 GMT +// +// + +#ifndef PHASE2GMT_SAMUONPRODUCER +#define PHASE2GMT_SAMUONPRODUCER + +// system include files +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h" +#include "DataFormats/L1Trigger/interface/L1MuonParticle.h" + +#include "L1Trigger/Phase2L1GMT/interface/Constants.h" +#include "DataFormats/L1TMuonPhase2/interface/SAMuon.h" +// +// class declaration +// +using namespace Phase2L1GMT; +using namespace l1t; + +class Phase2L1TGMTSAMuonProducer : public edm::stream::EDProducer<> { +public: + explicit Phase2L1TGMTSAMuonProducer(const edm::ParameterSet&); + ~Phase2L1TGMTSAMuonProducer() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void beginStream(edm::StreamID) override; + void produce(edm::Event&, const edm::EventSetup&) override; + void endStream() override; + + l1t::SAMuon Convertl1tMuon(const l1t::Muon& mu, const int bx_); + + // ----------member data --------------------------- + edm::EDGetTokenT > muonToken_; + unsigned int Nprompt; + unsigned int Ndisplaced; +}; + +Phase2L1TGMTSAMuonProducer::Phase2L1TGMTSAMuonProducer(const edm::ParameterSet& iConfig) + : muonToken_(consumes(iConfig.getParameter("muonToken"))), + Nprompt(iConfig.getParameter("Nprompt")), + Ndisplaced(iConfig.getParameter("Ndisplaced")) { + produces >("promptSAMuons").setBranchAlias("prompt"); + produces >("displacedSAMuons").setBranchAlias("displaced"); +} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void Phase2L1TGMTSAMuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + edm::Handle muon; + iEvent.getByToken(muonToken_, muon); + + // Output + std::vector prompt; + std::vector displaced; + + for (int bx = muon->getFirstBX(); bx <= muon->getLastBX(); ++bx) { + //TODO: We are expecting to send all BX. Using bx0 for now + if (bx != 0) { + continue; + } + + for (uint i = 0; i < muon->size(bx); ++i) { + const l1t::Muon& mu = muon->at(bx, i); + + //TODO: Still looking for a way to get displaced muon + if (abs(mu.hwDXY()) > 0) + displaced.push_back(Convertl1tMuon(mu, bx)); + else + prompt.push_back(Convertl1tMuon(mu, bx)); + } + + // Sort by hwPt + std::sort(prompt.begin(), prompt.end(), std::greater<>()); + std::sort(displaced.begin(), displaced.end(), std::greater<>()); + + // Store into output, allow up to 18 prompt + 18 displayed + if (prompt.size() > Nprompt) { + prompt.resize(Nprompt); + } + if (displaced.size() > Ndisplaced) { + displaced.resize(Ndisplaced); + } + } + + std::unique_ptr > prompt_ptr = std::make_unique >(prompt); + std::unique_ptr > displaced_ptr = std::make_unique >(displaced); + iEvent.put(std::move(prompt_ptr), "promptSAMuons"); + iEvent.put(std::move(displaced_ptr), "displacedSAMuons"); +} + +// === FUNCTION ============================================================ +// Name: Phase2L1TGMTSAMuonProducer::Convertl1tMuon +// Description: +// =========================================================================== +SAMuon Phase2L1TGMTSAMuonProducer::Convertl1tMuon(const l1t::Muon& mu, const int bx_) { + ap_uint qual = mu.hwQual(); + int charge = mu.charge() > 0 ? 0 : 1; + + ap_uint pt = round(mu.pt() / LSBpt); + ap_int phi = round(mu.phi() / LSBphi); + ap_int eta = round(mu.eta() / LSBeta); + // FIXME: Below are not well defined in phase1 GMT + // Using the version from Correlator for now + ap_int z0 = 0; // No tracks info in Phase 1 + // Use 2 bits with LSB = 30cm for BMTF and 25cm for EMTF currently, but subjet to change + ap_int d0 = mu.hwDXY(); + + int bstart = 0; + wordtype word(0); + bstart = wordconcat(word, bstart, pt > 0, 1); + bstart = wordconcat(word, bstart, pt, BITSGTPT); + bstart = wordconcat(word, bstart, phi, BITSGTPHI); + bstart = wordconcat(word, bstart, eta, BITSGTETA); + bstart = wordconcat(word, bstart, z0, BITSSAZ0); + bstart = wordconcat(word, bstart, d0, BITSSAD0); + bstart = wordconcat(word, bstart, charge, 1); + bstart = wordconcat(word, bstart, qual, BITSSAQUALITY); + + SAMuon samuon(mu, charge, pt.to_uint(), eta.to_int(), phi.to_int(), z0.to_int(), d0.to_int(), qual.to_uint()); + samuon.setWord(word); + return samuon; +} // ----- end of function Phase2L1TGMTSAMuonProducer::Convertl1tMuon ----- + +// ------------ method called once each stream before processing any runs, lumis or events ------------ +void Phase2L1TGMTSAMuonProducer::beginStream(edm::StreamID) { + // please remove this method if not needed +} + +// ------------ method called once each stream after processing all runs, lumis and events ------------ +void Phase2L1TGMTSAMuonProducer::endStream() { + // please remove this method if not needed +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void Phase2L1TGMTSAMuonProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("muonToken", edm::InputTag("simGmtStage2Digis")); + desc.add("Nprompt", 12); + desc.add("Ndisplaced", 12); + descriptions.add("standaloneMuons", desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(Phase2L1TGMTSAMuonProducer); +#endif diff --git a/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc new file mode 100644 index 0000000000000..44d0d8d84f9c1 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTStubProducer.cc @@ -0,0 +1,236 @@ +#include +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTEndcapStubProcessor.h" +#include "L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h" + +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/ESProducts.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +// +// class declaration +// + +class Phase2L1TGMTStubProducer : public edm::stream::EDProducer<> { +public: + explicit Phase2L1TGMTStubProducer(const edm::ParameterSet&); + ~Phase2L1TGMTStubProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void beginStream(edm::StreamID) override; + void produce(edm::Event&, const edm::EventSetup&) override; + void endStream() override; + + edm::EDGetTokenT> srcCSC_; + edm::EDGetTokenT srcDT_; + edm::EDGetTokenT srcDTTheta_; + edm::EDGetTokenT srcRPC_; + + L1TPhase2GMTEndcapStubProcessor* procEndcap_; + L1TPhase2GMTBarrelStubProcessor* procBarrel_; + L1TMuon::GeometryTranslator* translator_; + int verbose_; +}; + +Phase2L1TGMTStubProducer::Phase2L1TGMTStubProducer(const edm::ParameterSet& iConfig) + : srcCSC_( + consumes>(iConfig.getParameter("srcCSC"))), + srcDT_(consumes(iConfig.getParameter("srcDT"))), + srcDTTheta_(consumes(iConfig.getParameter("srcDTTheta"))), + srcRPC_(consumes(iConfig.getParameter("srcRPC"))), + procEndcap_(new L1TPhase2GMTEndcapStubProcessor(iConfig.getParameter("Endcap"))), + procBarrel_(new L1TPhase2GMTBarrelStubProcessor(iConfig.getParameter("Barrel"))), + verbose_(iConfig.getParameter("verbose")) { + produces(); + edm::ConsumesCollector consumesColl(consumesCollector()); + translator_ = new L1TMuon::GeometryTranslator(consumesColl); +} + +Phase2L1TGMTStubProducer::~Phase2L1TGMTStubProducer() { + // do anything here that needs to be done at destruction time + // (e.g. close files, deallocate resources etc.) + if (procEndcap_ != nullptr) + delete procEndcap_; + if (procBarrel_ != nullptr) + delete procBarrel_; + if (translator_ != nullptr) + delete translator_; +} + +// +// member functions +// + +// ------------ method called to produce the data ------------ +void Phase2L1TGMTStubProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + translator_->checkAndUpdateGeometry(iSetup); + + Handle> cscDigis; + iEvent.getByToken(srcCSC_, cscDigis); + + Handle rpcDigis; + iEvent.getByToken(srcRPC_, rpcDigis); + + Handle dtDigis; + iEvent.getByToken(srcDT_, dtDigis); + + Handle dtThetaDigis; + iEvent.getByToken(srcDTTheta_, dtThetaDigis); + + //Generate a unique stub ID + l1t::MuonStubCollection stubs; + + uint count0 = 0; + uint count1 = 0; + uint count2 = 0; + uint count3 = 0; + uint count4 = 0; + + l1t::MuonStubCollection stubsEndcap = procEndcap_->makeStubs(*cscDigis, *rpcDigis, translator_, iSetup); + for (auto& stub : stubsEndcap) { + if (stub.tfLayer() == 0) { + stub.setID(count0); + count0++; + } else if (stub.tfLayer() == 1) { + stub.setID(count1); + count1++; + } else if (stub.tfLayer() == 2) { + stub.setID(count2); + count2++; + } else if (stub.tfLayer() == 3) { + stub.setID(count3); + count3++; + } else { + stub.setID(count4); + count4++; + } + stubs.push_back(stub); + } + l1t::MuonStubCollection stubsBarrel = procBarrel_->makeStubs(dtDigis.product(), dtThetaDigis.product()); + for (auto& stub : stubsBarrel) { + if (stub.tfLayer() == 0) { + stub.setID(count0); + count0++; + } else if (stub.tfLayer() == 1) { + stub.setID(count1); + count1++; + } else if (stub.tfLayer() == 2) { + stub.setID(count2); + count2++; + } else if (stub.tfLayer() == 3) { + stub.setID(count3); + count3++; + } else { + stub.setID(count4); + count4++; + } + stubs.push_back(stub); + } + + iEvent.put(std::make_unique(stubs)); +} + +// ------------ method called once each stream before processing any runs, lumis or events ------------ +void Phase2L1TGMTStubProducer::beginStream(edm::StreamID) {} + +// ------------ method called once each stream after processing all runs, lumis and events ------------ +void Phase2L1TGMTStubProducer::endStream() {} + +void Phase2L1TGMTStubProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + // gmtStubs + edm::ParameterSetDescription desc; + desc.add("verbose", 0); + desc.add("srcCSC", edm::InputTag("simCscTriggerPrimitiveDigis")); + desc.add("srcDT", edm::InputTag("dtTriggerPhase2PrimitiveDigis")); + desc.add("srcDTTheta", edm::InputTag("simDtTriggerPrimitiveDigis")); + desc.add("srcRPC", edm::InputTag("simMuonRPCDigis")); + { + edm::ParameterSetDescription psd0; + psd0.add("verbose", 0); + psd0.add("minBX", 0); + psd0.add("maxBX", 0); + psd0.add("coord1LSB", 0.02453124992); + psd0.add("eta1LSB", 0.024586688); + psd0.add("coord2LSB", 0.02453124992); + psd0.add("eta2LSB", 0.024586688); + psd0.add("phiMatch", 0.05); + psd0.add("etaMatch", 0.1); + desc.add("Endcap", psd0); + } + { + edm::ParameterSetDescription psd0; + psd0.add("verbose", 0); + psd0.add("minPhiQuality", 0); + psd0.add("minThetaQuality", 0); + psd0.add("minBX", 0); + psd0.add("maxBX", 0); + psd0.add("phiLSB", 0.02453124992); + psd0.add("phiBDivider", 16); + psd0.add("etaLSB", 0.024586688); + psd0.add>( + "eta_1", + { + -46, -45, -43, -41, -39, -37, -35, -30, -28, -26, -23, -20, -18, -15, -9, -6, -3, -1, + 1, 3, 6, 9, 15, 18, 20, 23, 26, 28, 30, 35, 37, 39, 41, 43, 45, 1503, + }); + psd0.add>( + "eta_2", + { + -41, -39, -38, -36, -34, -32, -30, -26, -24, -22, -20, -18, -15, -13, -8, -5, -3, -1, + 1, 3, 5, 8, 13, 15, 18, 20, 22, 24, 26, 30, 32, 34, 36, 38, 39, 1334, + }); + psd0.add>( + "eta_3", + { + -35, -34, -32, -31, -29, -27, -26, -22, -20, -19, -17, -15, -13, -11, -6, -4, -2, -1, + 1, 2, 4, 6, 11, 13, 15, 17, 19, 20, 22, 26, 27, 29, 31, 32, 34, 1148, + }); + psd0.add>("coarseEta_1", + { + 0, + 23, + 41, + }); + psd0.add>("coarseEta_2", + { + 0, + 20, + 36, + }); + psd0.add>("coarseEta_3", + { + 0, + 17, + 31, + }); + psd0.add>("coarseEta_4", + { + 0, + 14, + 27, + }); + psd0.add>("phiOffset", + { + 1, + 0, + 0, + 0, + }); + desc.add("Barrel", psd0); + } + descriptions.add("gmtStubs", desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(Phase2L1TGMTStubProducer); diff --git a/L1Trigger/Phase2L1GMT/python/gmt_cff.py b/L1Trigger/Phase2L1GMT/python/gmt_cff.py new file mode 100644 index 0000000000000..96c12f0436fe1 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/python/gmt_cff.py @@ -0,0 +1,3 @@ +import FWCore.ParameterSet.Config as cms +from L1Trigger.Phase2L1GMT.gmt_cfi import * +phase2GMT = cms.Sequence(gmtStubs*gmtMuons) diff --git a/L1Trigger/Phase2L1GMT/python/gmt_cfi.py b/L1Trigger/Phase2L1GMT/python/gmt_cfi.py new file mode 100644 index 0000000000000..858005d14881b --- /dev/null +++ b/L1Trigger/Phase2L1GMT/python/gmt_cfi.py @@ -0,0 +1,83 @@ +import FWCore.ParameterSet.Config as cms + +gmtStubs = cms.EDProducer("Phase2L1TGMTStubProducer", + verbose = cms.int32(0), + srcCSC = cms.InputTag("simCscTriggerPrimitiveDigis"), + srcDT = cms.InputTag("dtTriggerPhase2PrimitiveDigis"), + srcDTTheta = cms.InputTag("simDtTriggerPrimitiveDigis"), + srcRPC = cms.InputTag("simMuonRPCDigis"), + Endcap =cms.PSet( + verbose = cms.uint32(0), + minBX = cms.int32(0), + maxBX = cms.int32(0), + coord1LSB = cms.double(0.00076660156*32), + eta1LSB = cms.double(7.68334e-04*32), + coord2LSB = cms.double(0.00076660156*32), + eta2LSB = cms.double(7.68334e-04*32), + phiMatch = cms.double(0.05), + etaMatch = cms.double(0.1) + ), + Barrel = cms.PSet( + verbose = cms.int32(0), + minPhiQuality = cms.int32(0),#was 5 + minThetaQuality = cms.int32(0), + minBX = cms.int32(0), + maxBX = cms.int32(0), + phiLSB = cms.double(0.00076660156*32), + phiBDivider = cms.int32(16), + etaLSB = cms.double(7.68334e-04*32), + eta_1 = cms.vint32(int(-1503/32),int(-1446/32),int(-1387/32),int(-1327/32),int(-1266/32),int(-1194/32),int(-1125/32),int(-985/32),int(-916/32),int(-839/32),int(-752/32),int(-670/32),int(-582/32),int(-489/32),int(-315/32),int(-213/32),int(-115/32),int(-49/32),int(49/32),int(115/32),int(213/32),int(315/32),int(489/32),int(582/32),int(670/32),int(752/32),int(839/32),int(916/32),int(985/32),int(1125/32),int(1194/32),int(1266/32),int(1327/32),int(1387/32),int(1446/32), 1503), + eta_2 = cms.vint32(int(-1334/32),int(-1279/32),int(-1227/32),int(-1168/32),int(-1109/32),int(-1044/32),int(-982/32),int(-861/32),int(-793/32),int(-720/32),int(-648/32),int(-577/32),int(-496/32),int(-425/32),int(-268/32),int(-185/32),int(-97/32),int(-51/32),int(51/32),int(97/32),int(185/32),int(268/32),int(425/32),int(496/32),int(577/32),int(648/32),int(720/32),int(793/32),int(861/32),int(982/32),int(1044/32),int(1109/32),int(1168/32),int(1227/32),int(1279/32),1334), + eta_3 = cms.vint32(int(-1148/32),int(-1110/32),int(-1051/32),int(-1004/32),int(-947/32),int(-895/32),int(-839/32),int(-728/32),int(-668/32),int(-608/32),int(-546/32),int(-485/32),int(-425/32),int(-366/32),int(-222/32),int(-155/32),int(-87/32),int(-40/32),int(40/32),int(87/32),int(155/32),int(222/32),int(366/32),int(425/32),int(485/32),int(546/32),int(608/32),int(668/32),int(728/32),int(839/32),int(895/32),int(947/32),int(1004/32),int(1051/32),int(1110/32), 1148), + + coarseEta_1 = cms.vint32(int(0/32),int(758/32),int(1336/32)), + coarseEta_2 = cms.vint32(int(0/32),int(653/32),int(1168/32)), + coarseEta_3 = cms.vint32(int(0/32),int(552/32),int(1001/32)), + coarseEta_4 = cms.vint32(int(0/32),int(478/32),int(878/32)), + phiOffset = cms.vint32(int(33/32),int(-8/32),int(+14/32),0) + ) + +) + + + + + +gmtMuons = cms.EDProducer('Phase2L1TGMTProducer', + srcTracks = cms.InputTag("TTTracksFromTrackletEmulation:Level1TTTracks"), + srcStubs = cms.InputTag('gmtStubs'), + srcBMTF = cms.InputTag('simBmtfDigis','BMTF'), + srcEMTF = cms.InputTag('simEmtfDigis','EMTF'), + srcOMTF = cms.InputTag('simOmtfDigis','OMTF'), + minTrackStubs = cms.int32(4), + muonBXMin = cms.int32(0), + muonBXMax = cms.int32(0), + verbose = cms.int32(0), + trackConverter = cms.PSet( + verbose = cms.int32(0) + ), + roiTrackAssociator = cms.PSet( + verbose=cms.int32(0) + ), + trackMatching = cms.PSet( + verbose=cms.int32(0) + ), + isolation = cms.PSet( + AbsIsoThresholdL = cms.int32(160), + AbsIsoThresholdM = cms.int32(120), + AbsIsoThresholdT = cms.int32(80), + RelIsoThresholdL = cms.double(0.1), + RelIsoThresholdM = cms.double(0.05), + RelIsoThresholdT = cms.double(0.01), + verbose = cms.int32(0), + IsodumpForHLS = cms.int32(1), + ), + tauto3mu = cms.PSet() + +) + +standaloneMuons = cms.EDProducer('Phase2L1TGMTSAMuonProducer', + muonToken = cms.InputTag('simGmtStage2Digis'), + Nprompt = cms.uint32(12), + Ndisplaced = cms.uint32(12) + ) diff --git a/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc new file mode 100644 index 0000000000000..2e19c3a0f2f02 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTBarrelStubProcessor.cc @@ -0,0 +1,188 @@ +#include "L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTBarrelStubProcessor.h" +#include +#include +#include +#include + +L1TPhase2GMTBarrelStubProcessor::L1TPhase2GMTBarrelStubProcessor() : minPhiQuality_(0), minBX_(-3), maxBX_(3) {} + +L1TPhase2GMTBarrelStubProcessor::L1TPhase2GMTBarrelStubProcessor(const edm::ParameterSet& iConfig) + : minPhiQuality_(iConfig.getParameter("minPhiQuality")), + minBX_(iConfig.getParameter("minBX")), + maxBX_(iConfig.getParameter("maxBX")), + eta1_(iConfig.getParameter >("eta_1")), + eta2_(iConfig.getParameter >("eta_2")), + eta3_(iConfig.getParameter >("eta_3")), + coarseEta1_(iConfig.getParameter >("coarseEta_1")), + coarseEta2_(iConfig.getParameter >("coarseEta_2")), + coarseEta3_(iConfig.getParameter >("coarseEta_3")), + coarseEta4_(iConfig.getParameter >("coarseEta_4")), + phiOffset_(iConfig.getParameter >("phiOffset")), + phiBFactor_(iConfig.getParameter("phiBDivider")), + verbose_(iConfig.getParameter("verbose")), + phiLSB_(iConfig.getParameter("phiLSB")), + etaLSB_(iConfig.getParameter("etaLSB")) {} + +L1TPhase2GMTBarrelStubProcessor::~L1TPhase2GMTBarrelStubProcessor() {} + +l1t::MuonStub L1TPhase2GMTBarrelStubProcessor::buildStub(const L1Phase2MuDTPhDigi& phiS, + const L1MuDTChambThDigi* etaS) { + l1t::MuonStub stub = buildStubNoEta(phiS); + + //Now full eta + int qeta1 = -16384; + int qeta2 = -16384; + int eta1 = -16384; + int eta2 = -16384; + + bool hasEta = false; + for (uint i = 0; i < 7; ++i) { + if (etaS->position(i) == 0) + continue; + if (!hasEta) { + hasEta = true; + eta1 = calculateEta(i, etaS->whNum(), etaS->scNum(), etaS->stNum()); + + if (etaS->quality(i) == 1) + qeta1 = 2; + else + qeta1 = 1; + } else { + eta2 = calculateEta(i, etaS->whNum(), etaS->scNum(), etaS->stNum()); + if (etaS->quality(i) == 1) + qeta2 = 2; + else + qeta2 = 1; + } + } + + if (qeta2 > 0) { //both stubs->average + stub.setEta(eta1, eta2, 3); + stub.setOfflineQuantities(stub.offline_coord1(), stub.offline_coord2(), eta1 * etaLSB_, eta2 * etaLSB_); + + } else if (qeta1 > 0) { //Good single stub + stub.setEta(eta1, 0, 1); + stub.setOfflineQuantities(stub.offline_coord1(), stub.offline_coord2(), eta1 * etaLSB_, 0.0); + } + + return stub; +} + +l1t::MuonStub L1TPhase2GMTBarrelStubProcessor::buildStubNoEta(const L1Phase2MuDTPhDigi& phiS) { + int wheel = phiS.whNum(); + int abswheel = fabs(phiS.whNum()); + int sign = wheel > 0 ? 1 : -1; + int sector = phiS.scNum(); + int station = phiS.stNum(); + double globalPhi = (sector * 30) + phiS.phi() * 30. / 65535.; + if (globalPhi < -180) + globalPhi += 360; + if (globalPhi > 180) + globalPhi -= 360; + globalPhi = globalPhi * M_PI / 180.; + int phi = int(globalPhi / phiLSB_) + phiOffset_[station - 1]; + int phiB = phiS.phiBend() / phiBFactor_; + uint tag = phiS.index(); + int bx = phiS.bxNum() - 20; + int quality = 3; + uint tfLayer = phiS.stNum() - 1; + int eta = -16384; + if (station == 1) { + eta = coarseEta1_[abswheel]; + } else if (station == 2) { + eta = coarseEta2_[abswheel]; + } else if (station == 3) { + eta = coarseEta3_[abswheel]; + } else if (station == 4) { + eta = coarseEta4_[abswheel]; + } + + //override!!! + // eta=abswheel; + + //Now full eta + + eta = eta * sign; + l1t::MuonStub stub(wheel, sector, station, tfLayer, phi, phiB, tag, bx, quality, eta, 0, 0, 1); + stub.setOfflineQuantities(globalPhi, float(phiB), eta* etaLSB_, 0.0); + return stub; +} + +l1t::MuonStubCollection L1TPhase2GMTBarrelStubProcessor::makeStubs(const L1Phase2MuDTPhContainer* phiContainer, + const L1MuDTChambThContainer* etaContainer) { + l1t::MuonStubCollection out; + for (int bx = minBX_; bx <= maxBX_; bx++) { + for (int wheel = -2; wheel <= 2; wheel++) { + for (int sector = 0; sector < 12; sector++) { + for (int station = 1; station < 5; station++) { + bool hasEta = false; + const L1MuDTChambThDigi* tseta = etaContainer->chThetaSegm(wheel, station, sector, bx); + if (tseta != nullptr) { + hasEta = true; + } + + for (const auto& phiDigi : *phiContainer->getContainer()) { + if ((phiDigi.bxNum() - 20) != bx || phiDigi.whNum() != wheel || phiDigi.scNum() != sector || + phiDigi.stNum() != station) + continue; + if (phiDigi.quality() < minPhiQuality_) + continue; + if (hasEta) { + out.push_back(buildStub(phiDigi, tseta)); + } else { + out.push_back(buildStubNoEta(phiDigi)); + } + } + } + } + } + } + + if (verbose_) { + printf("Barrel Stubs\n"); + for (const auto& stub : out) + printf( + "Barrel Stub bx=%d TF=%d etaRegion=%d phiRegion=%d depthRegion=%d coord1=%f,%d coord2=%f,%d eta1=%f,%d " + "eta2=%f,%d quality=%d etaQuality=%d\n", + stub.bxNum(), + stub.tfLayer(), + stub.etaRegion(), + stub.phiRegion(), + stub.depthRegion(), + stub.offline_coord1(), + stub.coord1(), + stub.offline_coord2(), + stub.coord2(), + stub.offline_eta1(), + stub.eta1(), + stub.offline_eta2(), + stub.eta2(), + stub.quality(), + stub.etaQuality()); + } + + return out; +} + +int L1TPhase2GMTBarrelStubProcessor::calculateEta(uint i, int wheel, uint sector, uint station) { + int eta = 0; + if (wheel > 0) { + eta = 7 * wheel + 3 - i; + } else if (wheel < 0) { + eta = 7 * wheel + i - 3; + } else { + if (sector == 0 || sector == 3 || sector == 4 || sector == 7 || sector == 8 || sector == 11) + eta = i - 3; + else + eta = 3 - i; + } + + if (station == 1) + eta = eta1_[eta + 17]; + else if (station == 2) + eta = eta2_[eta + 17]; + else + eta = eta3_[eta + 17]; + + return eta; +} diff --git a/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTEndcapStubProcessor.cc b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTEndcapStubProcessor.cc new file mode 100644 index 0000000000000..4287ed0401bf9 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/src/L1TPhase2GMTEndcapStubProcessor.cc @@ -0,0 +1,341 @@ +#include "L1Trigger/Phase2L1GMT/interface/L1TPhase2GMTEndcapStubProcessor.h" +#include "L1Trigger/L1TMuon/interface/MuonTriggerPrimitive.h" +#include +#include +#include +#include + +L1TPhase2GMTEndcapStubProcessor::L1TPhase2GMTEndcapStubProcessor() : minBX_(-3), maxBX_(3) {} + +L1TPhase2GMTEndcapStubProcessor::L1TPhase2GMTEndcapStubProcessor(const edm::ParameterSet& iConfig) + : minBX_(iConfig.getParameter("minBX")), + maxBX_(iConfig.getParameter("maxBX")), + coord1LSB_(iConfig.getParameter("coord1LSB")), + coord2LSB_(iConfig.getParameter("coord2LSB")), + eta1LSB_(iConfig.getParameter("eta1LSB")), + eta2LSB_(iConfig.getParameter("eta2LSB")), + etaMatch_(iConfig.getParameter("etaMatch")), + phiMatch_(iConfig.getParameter("phiMatch")), + verbose_(iConfig.getParameter("verbose")) {} + +L1TPhase2GMTEndcapStubProcessor::~L1TPhase2GMTEndcapStubProcessor() {} + +l1t::MuonStub L1TPhase2GMTEndcapStubProcessor::buildCSCOnlyStub(const CSCDetId& detid, + const CSCCorrelatedLCTDigi& digi, + const L1TMuon::GeometryTranslator* translator) { + int endcap = detid.endcap(); + int station = detid.station(); + int chamber = detid.chamber(); + int ring = detid.ring(); + + L1TMuon::TriggerPrimitive primitive(detid, digi); + + const GlobalPoint& gp = translator->getGlobalPoint(primitive); + + int phi = int(gp.phi().value() / coord1LSB_); + int eta1 = int(gp.eta() / eta1LSB_); + + int wheel = 0; + int sign = endcap == 1 ? -1 : 1; + + if (ring == 3) + wheel = sign * 3; + else if (ring == 2) + wheel = sign * 4; + else if (ring == 1) + wheel = sign * 5; + + int sector = fabs(chamber); + + int bx = digi.getBX() - 8; + int quality = 1; + + uint tfLayer = 0; + if ((ring == 3 || ring == 2) && station == 1) //ME1/3 + tfLayer = 4; + else if (ring == 1 && station == 1) //ME1/3 + tfLayer = 0; + else if (station == 2) //ME2/2 + tfLayer = 2; + else if (station == 3) //ME3/2 + tfLayer = 1; + else if (station == 4) //ME4/2 + tfLayer = 3; + + l1t::MuonStub stub(wheel, sector, station, tfLayer, phi, 0, 0, bx, quality, eta1, 0, 1, 0); + + stub.setOfflineQuantities(gp.phi().value(), 0.0, gp.eta(), 0.0); + return stub; +} + +l1t::MuonStub L1TPhase2GMTEndcapStubProcessor::buildRPCOnlyStub(const RPCDetId& detid, + const RPCDigi& digi, + const L1TMuon::GeometryTranslator* translator) { + L1TMuon::TriggerPrimitive primitive(detid, digi); + const GlobalPoint& gp = translator->getGlobalPoint(primitive); + + int phi2 = int(gp.phi().value() / coord2LSB_); + int eta2 = int(gp.eta() / eta2LSB_); + + int wheel = -(6 - detid.ring()) * detid.region(); + int sector = (detid.sector() - 1) * 6 + detid.subsector(); + int station = detid.station(); + bool tag = detid.trIndex(); + int bx = digi.bx(); + int quality = 2; + + int ring = detid.ring(); + + uint tfLayer = 0; + + if ((ring == 3 || ring == 2) && station == 1) //ME1/3 + tfLayer = 4; + // else if (ring==1 && station==1) //ME1/3 + // tfLayer=0; + else if (station == 2) //ME2/2 + tfLayer = 2; + else if (station == 3) //ME3/2 + tfLayer = 1; + else if (station == 4) //ME4/2 + tfLayer = 3; + + l1t::MuonStub stub(wheel, sector, station, tfLayer, 0, phi2, tag, bx, quality, 0, eta2, 2, 0); + stub.setOfflineQuantities(gp.phi().value(), gp.phi().value(), gp.eta(), gp.eta()); + return stub; +} + +l1t::MuonStubCollection L1TPhase2GMTEndcapStubProcessor::combineStubs(const l1t::MuonStubCollection& cscStubs, + const l1t::MuonStubCollection& rpcStubs) { + l1t::MuonStubCollection out; + l1t::MuonStubCollection usedRPC; + l1t::MuonStubCollection cleanedRPC; + + l1t::MuonStubCollection cleanedCSC; + + //clean ME11 ambiguities + l1t::MuonStubCollection allCSC = cscStubs; + + while (!allCSC.empty()) { + l1t::MuonStub stub = allCSC[0]; + l1t::MuonStubCollection freeCSC; + for (uint i = 1; i < allCSC.size(); ++i) { + if ((stub.etaRegion() == allCSC[i].etaRegion()) && (stub.depthRegion() == allCSC[i].depthRegion()) && + (fabs(deltaPhi(stub.offline_coord1(), allCSC[i].offline_coord1())) < 0.001)) { + if (fabs(stub.offline_eta1() - allCSC[i].offline_eta1()) > 0.001) { + stub.setEta(stub.eta1(), allCSC[i].eta1(), 3); + stub.setOfflineQuantities(stub.offline_coord1(), 0.0, stub.offline_eta1(), allCSC[i].offline_eta1()); + } + } else { + freeCSC.push_back(allCSC[i]); + } + } + cleanedCSC.push_back(stub); + allCSC = freeCSC; + } + + for (const auto& csc : cleanedCSC) { + int nRPC = 0; + float phiF = 0.0; + float etaF = 0.0; + int phi = 0; + int eta = 0; + for (const auto& rpc : rpcStubs) { + if (csc.depthRegion() != rpc.depthRegion()) + continue; + if (fabs(deltaPhi(csc.offline_coord1(), rpc.offline_coord2())) < phiMatch_ && + fabs(csc.offline_eta1() - rpc.offline_eta2()) < etaMatch_ && csc.bxNum() == rpc.bxNum()) { + phiF += rpc.offline_coord2(); + etaF += rpc.offline_eta2(); + phi += rpc.coord2(); + eta += rpc.eta2(); + nRPC++; + usedRPC.push_back(rpc); + } + } + + int finalRPCPhi = 0; + int finalRPCEta = 0; + double offline_finalRPCPhi = 0; + double offline_finalRPCEta = 0; + if (nRPC != 0) { + finalRPCPhi = phi / nRPC; + finalRPCEta = eta / nRPC; + offline_finalRPCPhi = phiF / nRPC; + offline_finalRPCEta = etaF / nRPC; + l1t::MuonStub stub(csc.etaRegion(), + csc.phiRegion(), + csc.depthRegion(), + csc.tfLayer(), + csc.coord1(), + finalRPCPhi, + 0, + csc.bxNum(), + 3, + csc.eta1(), + finalRPCEta, + 3, + 0); + stub.setOfflineQuantities(csc.offline_coord1(), offline_finalRPCPhi, csc.offline_eta1(), offline_finalRPCEta); + out.push_back(stub); + } else { + out.push_back(csc); + } + } + + //clean the RPC from the used ones + + for (const auto& rpc : rpcStubs) { + bool keep = true; + for (const auto& rpc2 : usedRPC) { + if (rpc == rpc2) { + keep = false; + break; + } + } + if (keep) + cleanedRPC.push_back(rpc); + } + + while (!cleanedRPC.empty()) { + l1t::MuonStubCollection freeRPC; + + int nRPC = 1; + float phiF = cleanedRPC[0].offline_coord2(); + float etaF = cleanedRPC[0].offline_eta2(); + int phi = cleanedRPC[0].coord2(); + int eta = cleanedRPC[0].eta2(); + + for (unsigned i = 1; i < cleanedRPC.size(); ++i) { + if (fabs(deltaPhi(cleanedRPC[0].offline_coord2(), cleanedRPC[i].offline_coord2())) < phiMatch_ && + cleanedRPC[0].depthRegion() == cleanedRPC[i].depthRegion() && + fabs(cleanedRPC[0].offline_eta2() - cleanedRPC[i].offline_eta2()) < etaMatch_ && + cleanedRPC[0].bxNum() == cleanedRPC[i].bxNum()) { + phiF += cleanedRPC[i].offline_coord2(); + etaF += cleanedRPC[i].offline_eta2(); + phi += cleanedRPC[i].coord2(); + eta += cleanedRPC[i].eta2(); + nRPC++; + } else { + freeRPC.push_back(cleanedRPC[i]); + } + } + l1t::MuonStub stub(cleanedRPC[0].etaRegion(), + cleanedRPC[0].phiRegion(), + cleanedRPC[0].depthRegion(), + cleanedRPC[0].tfLayer(), + 0, + phi / nRPC, + 0, + cleanedRPC[0].bxNum(), + 2, + 0, + eta / nRPC, + 2, + 0); + stub.setOfflineQuantities(phiF / nRPC, phiF / nRPC, etaF / nRPC, etaF / nRPC); + out.push_back(stub); + cleanedRPC = freeRPC; + }; + return out; +} + +l1t::MuonStubCollection L1TPhase2GMTEndcapStubProcessor::makeStubs( + const MuonDigiCollection& csc, + const MuonDigiCollection& cleaned, + const L1TMuon::GeometryTranslator* t, + const edm::EventSetup& iSetup) { + l1t::MuonStubCollection cscStubs; + auto chamber = csc.begin(); + auto chend = csc.end(); + for (; chamber != chend; ++chamber) { + auto digi = (*chamber).second.first; + auto dend = (*chamber).second.second; + for (; digi != dend; ++digi) { + l1t::MuonStub stub = buildCSCOnlyStub((*chamber).first, *digi, t); + if (stub.bxNum() >= minBX_ && stub.bxNum() <= maxBX_) + cscStubs.push_back(stub); + } + } + + l1t::MuonStubCollection rpcStubs; + + auto rpcchamber = cleaned.begin(); + auto rpcchend = cleaned.end(); + for (; rpcchamber != rpcchend; ++rpcchamber) { + if ((*rpcchamber).first.region() == 0) + continue; + auto digi = (*rpcchamber).second.first; + auto dend = (*rpcchamber).second.second; + for (; digi != dend; ++digi) { + l1t::MuonStub stub = buildRPCOnlyStub((*rpcchamber).first, *digi, t); + if (stub.bxNum() >= minBX_ && stub.bxNum() <= maxBX_) + rpcStubs.push_back(stub); + } + } + + l1t::MuonStubCollection combinedStubs = combineStubs(cscStubs, rpcStubs); + + if (verbose_) { + printf("CSC Stubs\n"); + for (const auto& stub : cscStubs) + printf( + "CSC Stub bx=%d TF=%d etaRegion=%d phiRegion=%d depthRegion=%d coord1=%f,%d coord2=%f,%d eta1=%f,%d " + "eta2=%f,%d quality=%d etaQuality=%d\n", + stub.bxNum(), + stub.tfLayer(), + stub.etaRegion(), + stub.phiRegion(), + stub.depthRegion(), + stub.offline_coord1(), + stub.coord1(), + stub.offline_coord2(), + stub.coord2(), + stub.offline_eta1(), + stub.eta1(), + stub.offline_eta2(), + stub.eta2(), + stub.quality(), + stub.etaQuality()); + printf("RPC Stubs\n"); + for (const auto& stub : rpcStubs) + printf( + "RPC Stub bx=%d TF=%d etaRegion=%d phiRegion=%d depthRegion=%d coord1=%f,%d coord2=%f,%d eta1=%f,%d " + "eta2=%f,%d quality=%d etaQuality=%d\n", + stub.bxNum(), + stub.tfLayer(), + stub.etaRegion(), + stub.phiRegion(), + stub.depthRegion(), + stub.offline_coord1(), + stub.coord1(), + stub.offline_coord2(), + stub.coord2(), + stub.offline_eta1(), + stub.eta1(), + stub.offline_eta2(), + stub.eta2(), + stub.quality(), + stub.etaQuality()); + for (const auto& stub : combinedStubs) + printf( + "Combined Stub bx=%d TF=%d etaRegion=%d phiRegion=%d depthRegion=%d coord1=%f,%d coord2=%f,%d eta1=%f,%d " + "eta2=%f,%d quality=%d etaQuality=%d\n", + stub.bxNum(), + stub.tfLayer(), + stub.etaRegion(), + stub.phiRegion(), + stub.depthRegion(), + stub.offline_coord1(), + stub.coord1(), + stub.offline_coord2(), + stub.coord2(), + stub.offline_eta1(), + stub.eta1(), + stub.offline_eta2(), + stub.eta2(), + stub.quality(), + stub.etaQuality()); + } + + return combinedStubs; +} diff --git a/L1Trigger/Phase2L1GMT/test/gmtStudy.py b/L1Trigger/Phase2L1GMT/test/gmtStudy.py new file mode 100644 index 0000000000000..c04e360bd1384 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/test/gmtStudy.py @@ -0,0 +1,255 @@ +import ROOT,itertools,math +from array import array +from DataFormats.FWLite import Events, Handle +ROOT.FWLiteEnabler.enable() +# + +#0.005 +#idCut=[ +#20, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 48, 44, 44, 44, 60, 20, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 48, 20, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 60, 20, 24, 20, 44, 44, 44, 44, 44, 44, 44, 44, 20, 44, 44, 44, 60, 20, 24, 24, 24, 24, 44, 24, 24, 24, 20, 44, 40, 44, 44, 48, 44, 20, 44, 44, 48, 48, 48, 48, 60, 48, 48, 60, 60, 48, 60, 60, 60, 20, 44, 60, 60, 60, 60, 60, 60, 60, 48, 60, 60, 44, 60, 60, 60, 20, 40, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 16, 20, 60, 60, 60, 60, 60, 60, 60, 60, 48, 60, 44, 60, 60, 60, 16, 20, 44, 60, 60, 60, 60, 60, 48, 60, 60, 60, 60, 60, 60, 60, 20, 20, 40, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 48, 60, 20, 16, 20, 44, 48, 44, 44, 44, 60, 60, 60, 60, 48, 48, 48, 60, 20, 20, 20, 60, 44, 60, 60, 60, 60, 44, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60] + +#0.006 + +idCut=[ +36, 56, 64, 64, 32, 32, 60, 56, 56, 56, 56, 56, 56, 56, 56, 56, #0 +28, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 28, 28, 28, 28, #16 +28, 52, 56, 52, 52, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, #32 +28, 52, 52, 52, 56, 56, 56, 56, 56, 56, 56, 28, 56, 56, 56, 56, #48 +28, 36, 36, 36, 36, 36, 36, 36, 36, 36, 56, 56, 36, 56, 36, 36, #64 +28, 56, 60, 60, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, #80 +28, 92, 120, 120, 92, 92, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, #96 +28, 120, 152, 128, 100, 124, 80, 80, 64, 64, 64, 64, 64, 64, 64,64, #112 +28, 88, 92, 64, 92, 60, 60, 60, 92, 60, 60, 60, 60, 60, 60, 60, #128 +36, 88, 88, 64, 64, 60, 60, 60, 60, 60, 60, 60, 92, 92, 92,92, #144 +28, 64, 92, 88, 88, 88, 88, 88, 88, 88, 88, 88, 120, 120, 120,120, #160 +28, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,92, #176 +28, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,92, #192 +64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,64, #208 +64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,64, #224 +64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64] #240 + +idCut=[ +40, 56, 64, 88, 64, 32, 60, 56, 56, 56, 56, 56, 56, 56, 56, 56, #0 +28, 56, 56, 54, 36, 36, 36, 36, 36, 36, 36, 36, 32, 28, 28, 28, #16 +28, 52, 56, 52, 52, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, #32 +28, 56, 52, 52, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, #48 +28, 52, 36, 36, 36, 36, 36, 36, 36, 36, 56, 56, 36, 56, 36, 36, #64 +28, 60, 60, 60, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, #80 +28, 120, 120, 120, 92, 92, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, #96 +28, 120, 152, 128, 100, 124, 80, 80, 64, 100, 64, 64, 64, 64, 64,64, #112 +28, 88, 92, 64, 92, 60, 60, 60, 92, 60, 60, 60, 60, 60, 60, 60, #128 +36, 88, 88, 64, 64, 60, 60, 60, 60, 60, 60, 60, 92, 92, 92,92, #144 +28, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,88, #160 +28, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,92, #176 +28, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,92, #192 +64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,64, #208 +64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,64, #224 +64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64] #240 + + +def ID(eta,pt,quality): + p=pt + if p>4095: + p=4095 + p=p/256 + e=int(abs(eta)) + e=e/256 + addr=(e<<4) | p + if (quality-min(64,pt/32))>=(idCut[addr]): + return True + else: + return False + +#verbose=False +#tag='singleMuonOfficial' +#isData=False +#tag='signal' + +def strAppend(s): + return "root://cmsxrootd.fnal.gov/"+s + +from dy200 import * +from jpsi import * +from minbias import * +tag='/uscmst1b_scratch/lpc1/3DayLifetime/bachtis/DY200' +#events=Events(['/uscmst1b_scratch/lpc1/3DayLifetime/bachtis/MinBias.root' +# ]) +events=Events(map(strAppend,dy200)) + +#events=Events(minbias) +#events=Events(['reprocess.root']) + +def fetchTracks(event): + trackHandle = Handle('vector,Phase2TrackerDigi,edm::refhelper::FindForDetSetVector > > >') + event.getByLabel("TTTracksFromTrackletEmulation:Level1TTTracks",trackHandle) + return trackHandle.product() + + +def fetchTPS(event,tag,etamax=3.0): + phiSeg2 = Handle ('vector') + event.getByLabel(tag,phiSeg2) + return filter(lambda x: abs(x.eta())') + event.getByLabel(tag,phiSeg2) + return phiSeg2.product() + + +def fetchGEN(event,etaMax=3.0): + genH = Handle ('vector') + event.getByLabel('genParticles',genH) + genMuons=filter(lambda x: abs(x.pdgId())==13 and x.status()==1 and abs(x.eta()) math.pi: + res -= 2*math.pi + while res < -math.pi: + res += 2*math.pi + return res + +def deltaR( *args ): + return math.sqrt( deltaR2(*args) ) + +def deltaR2( e1, p1, e2, p2): + de = e1 - e2 + dp = deltaPhi(p1, p2) + return de*de + dp*dp + + + + +quality = ROOT.TH3D("quality","",16,0,4096,16,0,4096,128,0,512) +qualityAll = ROOT.TH3D("qualityAll","",16,0,4096,16,0,4096,128,0,512) +histoData={'effpt':{}, 'effeta':{},'geneta':{},'genphi':{},'effphi':{}} +histoData['genpt'] = ROOT.TH1D("genpt","genpt",50,0,50) + +thresholds=[1,3,5,15,20] +for t in thresholds: + histoData['effpt'][t] = ROOT.TH1D("effpt_"+str(t),"effpt_"+str(t),50,0,50) + histoData['effeta'][t] = ROOT.TH1D("effeta_"+str(t),"effeta_"+str(t),48,-2.4,2.4) + histoData['effphi'][t] = ROOT.TH1D("effphi_"+str(t),"effphi_"+str(t),32,-math.pi,math.pi) + histoData['geneta'][t] = ROOT.TH1D("geneta_"+str(t),"effeta_"+str(t),48,-2.4,2.4) + histoData['genphi'][t] = ROOT.TH1D("genphi_"+str(t),"genphi_"+str(t),32,-math.pi,math.pi) + + + + +histoData['rate']= ROOT.TH1D("rate","rate",50,0,100) +histoData['rate20eta']= ROOT.TH1D("rate20eta","rate",8,0,8) + + +BUNCHFACTOR=40000*2760.0/3564.0 + +QUALITYCUT=0 +verbose=0 +counter=-1 +for event in events: + counter=counter+1 + if counter==100000: + break; + gen=fetchGEN(event,2.4) + stubs = fetchStubs(event,'gmtStubs') + tps = filter(lambda x: ID(x.hwEta(),x.hwPt(),x.hwQual()),fetchTPS(event,'gmtMuons')) +# tps = fetchTPS(event,'gmtMuons') + tracks=fetchTracks(event) + + if verbose: + for t in sorted(tracks,key=lambda x: x.momentum().transverse(),reverse=True): + print("Track ",t.eta(),t.phi(),t.momentum().transverse(),t.getStubRefs().size()) + for t in sorted(tps,key=lambda x: x.pt(),reverse=True): + print("Tracker Muon pt={pt} eta={eta} phi={phi} qual={qual}".format(pt=t.pt(),eta=t.eta(),phi=t.phi(),qual=t.hwQual)) + + # import pdb;pdb.set_trace() + for s in stubs: + print(" All Stub depth={depth} eta={eta1},{eta1I},{eta2},{eta2I} phi={phi1},{phi1I},{phi2},{phi2I} qualities={etaQ},{phiQ}".format(depth=s.depthRegion(),eta1=s.offline_eta1(),eta1I=s.eta1(),eta2=s.offline_eta2(),eta2I=s.eta2(),phi1=s.offline_coord1(),phi1I=s.coord1(),phi2=s.offline_coord2(),phi2I=s.coord2(),etaQ=s.etaQuality(),phiQ=s.quality())) + + + if len(tps)>0: + tpsInEta =filter(lambda x: abs(x.eta())<2.4,tps) + if len(tpsInEta)>0: + best=max(tpsInEta,key=lambda x: x.pt()) + qualityAll.Fill(abs(best.hwEta()),best.hwPt(),best.hwQual()-min(63,best.hwPt()/32)) + pt=best.pt() + if pt>99.9: + pt=99.9 + histoData['rate'].Fill(pt) + if pt>20: + histoData['rate20eta'].Fill(abs(best.hwEta())/512) +# import pdb;pdb.set_trace() + + + if counter %1000==0: + print(counter) + if verbose: + print ("EVENT:",counter) + + #efficiencies -loop on gen + for g in gen: + histoData['genpt'].Fill(g.pt()) + for thres in thresholds: + if g.pt()>(thres+2.0): + histoData['geneta'][thres].Fill(g.eta()) + histoData['genphi'][thres].Fill(g.phi()) + + if verbose: + print("Gen Muon pt={pt} eta={eta} phi={phi} charge={charge}".format(pt=g.pt(),eta=g.eta(),phi=g.phi(),charge=g.charge())) + + foundMatch=False + tpsMatched = sorted(filter(lambda x: deltaR(g.eta(),g.phi(),x.eta(),x.phi())<0.3, tps),key=lambda x:x.pt(),reverse=True) +# if len(tpsMatched)==0 and g.pt()>10: +# print("Not Matched ",g.pt(),g.eta(),len(tps)) +# import pdb;pdb.set_trace() + if len(tpsMatched)>0: + foundMatch=True + + if verbose: + for t in tpsMatched: + print(" -> matched track ->Tracker Muon pt={pt} eta={eta} phi={phi} qual={qual}".format(pt=t.pt(),eta=t.eta(),phi=t.phi(),qual=t.hwQual())) + best=tpsMatched[0] + quality.Fill(abs(best.hwEta()),best.hwPt(),best.hwQual()-min(63,best.hwPt()/32)) + for thres in thresholds: + overThreshold = filter(lambda x: x.pt()>thres,tpsMatched) + if len(overThreshold)>0: + histoData['effpt'][thres].Fill(g.pt()) + if g.pt()>(thres+2.0): + histoData['effeta'][thres].Fill(g.eta()) + histoData['effphi'][thres].Fill(g.phi()) + + + + + + + + stubsMatched = filter(lambda x: deltaR(g.eta(),g.phi(),x.offline_eta1(),x.offline_coord1())<0.3, stubs) + if verbose: + for s in stubsMatched: + print(" -> matched stub -> Muon Stub eta={eta1},{eta2} phi={phi1},{phi2} qualities={etaQ},{phiQ}".format(eta1=s.offline_eta1(),eta2=s.offline_eta2(),phi1=s.offline_coord1(),phi2=s.offline_coord2(),etaQ=s.etaQuality(),phiQ=s.quality())) + + + +f=ROOT.TFile("tpsResults_output.root","RECREATE") +f.cd() +quality.Write() +qualityAll.Write() + +c = histoData['rate'].GetCumulative(False) +c.Scale(float(BUNCHFACTOR)/float(counter)) +c.Write("rate") + +for t in thresholds: + g = ROOT.TGraphAsymmErrors(histoData['effpt'][t],histoData['genpt']) + g.Write("eff_"+str(t)) + g = ROOT.TGraphAsymmErrors(histoData['effeta'][t],histoData['geneta'][t]) + g.Write("effeta_"+str(t)) + g = ROOT.TGraphAsymmErrors(histoData['effphi'][t],histoData['genphi'][t]) + g.Write("effphi_"+str(t)) + +f.Close() + diff --git a/L1Trigger/Phase2L1GMT/test/makeTrackConversionLUTs.py b/L1Trigger/Phase2L1GMT/test/makeTrackConversionLUTs.py new file mode 100644 index 0000000000000..50ce892d3cddc --- /dev/null +++ b/L1Trigger/Phase2L1GMT/test/makeTrackConversionLUTs.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python +# encoding: utf-8 + +# File : makeTrackConversionLUTs.py +# Author : Zhenbin Wu +# Contact : zhenbin.wu@gmail.com +# Date : 2021 Apr 13 +# +# Description : + +from __future__ import division +import math +import numpy as np +from collections import defaultdict, Counter +from pprint import pprint + +BITSABSCURV=14 +BITSPT=13 +maxCurv = 0.00855 +ptLSB=0.025 +ptLUT=[] +pts = [] +ptshifts = [] + + +BITSTTTANL=16-1 +BITSETA=13-1 +maxTanL=8.0 +etaLSB = math.pi/ (1<= upperbound): + sel = orgx[val_>=upperbound] + uppershift = -1 if isPT else -2 + ## sel[-1]+1 , since we will use < in the final function + sht = [sel[0], sel[-1]+1, uppershift, 0, int(upperbound/lsb)] + shifts.append(sht) + orgx = orgx[val_<=upperbound] + val_ = val_[val_<=upperbound] + if isPT: + bfrom=orgx[0] + else: + bitcross=orgx[-1] + if lowerbound is not None and np.any(val_ <= lowerbound): + sel = orgx[val_<=lowerbound] + lowershift = -2 if isPT else -1 + sht = [sel[0], sel[-1]+1, lowershift, 0, lowerbound/lsb] + shifts.append(sht) + orgx = orgx[val_>=lowerbound] + val_ = val_[val_>= lowerbound] + bitcross=orgx[-1] + + if nb > 1: + ### Important: We can only shift by nb-1 bit to keep the precision + shiftx_ = ((orgx >> (nb-1)) ) + if len(shiftx_) == 0: + continue + if len(x) > 0: + shifty_ = int(x[-1] + 1 - shiftx_[0]) ## +1 to make sure it won't overlap + shiftx_ = shiftx_ + shifty_ + else: + shiftx_ = orgx + x_, pickx_ = np.unique(shiftx_, return_index=True) + val_ = np.take(val_, pickx_) + x = np.append(x, x_) + val = np.append(val, val_) + if nb == 0: + sht = [bfrom, bitcross+1, 0, shifty_, 0 ] + else: + sht = [bfrom, bitcross+1, nb-1, shifty_, 0 ] + shifts.append(sht) + # print("Shifting {nbit} bits with intercept {itsect}, input start from {bfrom} ({ffrom}) to {bto} ({fto}), LUT size {nLUT} ".format( + # nbit=nb, itsect=shifty_, bfrom=bfrom, bto=bitcross, ffrom=fltLUT[bfrom], fto=fltLUT[bitcross], nLUT =len(val_))) + bfrom = bitcross+1 + + return shifts + +def Modification(inval, intINT, config): + for cfg in config: + if inval >= cfg[0] and inval < cfg[1]: + if cfg[2] < 0 and cfg[4]!=0: + if cfg[2] == -1: + return cfg[2], -1, cfg[4] + if cfg[2] == -2: + return cfg[2], 9999999, cfg[4] + elif cfg[2] < 0 and cfg[4]==0: + return cfg[2], inval, intINT + else: + return cfg[2], (inval >> cfg[2] ) + cfg[3], intINT + +def GetLUTModified(orgLUT, shiftMap, isPT=False): + tempmap = defaultdict(list) + x= [] + y= [] + for i, pINT in enumerate(orgLUT): + ii = i + if isPT: + ii+=1 + nshift, newidx, newINT = Modification(ii, pINT, shiftMap) + tempmap[newidx].append(newINT) + + con = consecutive(list(tempmap.keys())) + for k, v in tempmap.items(): + if k == -1 or k == 9999999: + continue + setv = set(v) + x.append(k) + if len(setv) == 1: + y.append(v[0]) + elif len(setv) == 2 or len(setv) ==3: + contv = Counter(v) + ## The counter was sorted, descending in python3 and asending in python2 + ## This will result in slightly different LUT when running + isallequal = (len(set(contv.values())) == 1) + if isallequal: + ## Using min for now. To be decided + y.append(min(contv.keys())) + else: + y.append(contv.most_common(1)[0][0]) + else: + print("----- allow up to 3 values per bins") + return x, y + +def ProducedFinalLUT(LUT, k, isPT=False, bounderidx=False): + k = np.asarray(k).astype(int) + if isPT: + k[:, [0, 1]] +=1 + k[k[:, 2] > 0, 3] +=1 + x, y = GetLUTModified(LUT, k,isPT) + if x[0] != 0: + for i in k: + if i[2] < 0: + continue + else: + i[3] -= x[0] + k = k[k[:, 0].argsort()] + x, y = GetLUTModified(LUT, k, isPT) + if bounderidx: + ### Has + if np.any(k[:,2] == -1): + y.insert(0, str(k[k[:,2] == -1, 4][0])) + k[k[:,2] == -1, 4] = 0 + k[k[:, 2] >= 0, 3] +=1 + if np.any(k[:,2] == -2): + y.append(str(k[k[:,2] == -2, 4][0])) + k[k[:,2] == -2, 4] = len(y)-1 + return k, x, y + +### PT +def LookUp(inpt, shiftmap, LUT, bounderidx): + for i in shiftmap: + if inpt >=i[0] and inpt < i[1]: + if i[2] < 0: + if bounderidx: + return i[4], LUT[i[4]] + else: + return -1, i[4] + else: + return (inpt >> i[2])+i[3], LUT[(inpt >> i[2])+i[3]] + +def ptChecks(shiftmap, LUT, bounderidx=False): + for i in range(1,(1< (1< 0.025 ): + print("pt : ", i, pOB, pts[i-1], ptLUT[i-1], idx, pINT, int(pINT)*0.025) + +def etaChecks(shiftmap, LUT, bounderidx=False): + for i in range(0,(1<<(BITSTTTANL))): + tanL = (maxTanL*i)/(1< 2.45: + continue + eINT = int(eta*(1< etaLSB ): + print("eta : ", i, eta, eINT, idx, etaINT, int(etaINT)*etaLSB) + ## For high eta region, we allow up to 2LSB + if eta >= 1.59 and (abs(eta - int(etaINT)*etaLSB) > etaLSB * 2 ): + print("eta : ", i, eta, eINT, idx, etaINT, int(etaINT)*etaLSB) + + +def PrintPTLUT(k, ptLUT): + shiftout = [] + for i in k: + ii = [str(j) for j in i] + temp = ",".join(ii) + shiftout.append("{" + temp +"}") + print("int ptShifts[{nOps}][5]={{".format(nOps=len(k)) + ", ".join(shiftout) + "};") + print("ap_uint ptLUT[{address}]={{".format(address=len(ptLUT))+', '.join(ptLUT)+'};') + +def PrintEtaLUT(k, etaLUT): + shiftout = [] + for i in k: + ii = [str(j) for j in i] + temp = ",".join(ii) + shiftout.append("{" + temp +"}") + print("int etaShifts[{nOps}][5]={{".format(nOps=len(k)) + ", ".join(shiftout) + "};") + print("ap_uint etaLUT[{address}]={{".format(address=len(etaLUT)) +', '.join(etaLUT)+'};') + +if __name__ == "__main__": + bounderidx=True + GetPtLUT() + k = GetLUTwrtLSB(pts, ptLSB, isPT=True, nbits=[ 1, 2, 3, 4, 5, 6, 7], lowerbound=2, upperbound=((1< 1: + print("index is not continuous: ", con) + # ptChecks(k, y, bounderidx=bounderidx) + # print("Total size of LUT is %d" % len(y)) + PrintPTLUT(k, y) + + # # ### Eta + GetEtaLUT() + k = GetLUTwrtLSB(etas, etaLSB, isPT=False, nbits=[0, 1, 2, 3, 5], upperbound =2.45) + k, x, y = ProducedFinalLUT(etaLUT, k, bounderidx=bounderidx) + con = consecutive(x) + if len(con) > 1: + print("index is not continuous: ", con) + # etaChecks(k, y, bounderidx=bounderidx) + # print("Total size of LUT is %d" % len(y)) + PrintEtaLUT(k, y) diff --git a/L1Trigger/Phase2L1GMT/test/runGMT.py b/L1Trigger/Phase2L1GMT/test/runGMT.py new file mode 100644 index 0000000000000..cec51bb3cf1dd --- /dev/null +++ b/L1Trigger/Phase2L1GMT/test/runGMT.py @@ -0,0 +1,187 @@ +# Auto generated configuration file +# using: +# Revision: 1.19 +# Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v +# with command line options: step1 --conditions 111X_mcRun4_realistic_T15_v3 -n 2 --era Phase2C9 --eventcontent FEVTDEBUGHLT --runUnscheduled file:/eos/cms/store/relval/CMSSW_11_0_0/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/PU25ns_110X_mcRun4_realistic_v3_2026D49PU200-v2/10000/01054EE2-1B51-C449-91A2-5202A60D16A3.root -s RAW2DIGI,L1TrackTrigger,L1 --datatier FEVTDEBUGHLT --customise SLHCUpgradeSimulations/Configuration/aging.customise_aging_1000,L1Trigger/Configuration/customisePhase2TTNoMC.customisePhase2TTNoMC,Configuration/DataProcessing/Utils.addMonitoring --geometry Extended2026D49 --fileout file:/tmp/step1_Reprocess_TrackTrigger_L1.root --no_exec --nThreads 8 --python step1_L1_ProdLike.py --filein das:/TT_TuneCP5_14TeV-powheg-pythia8/Phase2HLTTDRWinter20DIGI-PU200_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW +import FWCore.ParameterSet.Config as cms + +from Configuration.Eras.Era_Phase2C9_cff import Phase2C9 + +process = cms.Process('L1',Phase2C9) + +# import of standard configurations +process.load('Configuration.StandardSequences.Services_cff') +process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') +process.load('FWCore.MessageService.MessageLogger_cfi') +process.load('Configuration.EventContent.EventContent_cff') +process.load('SimGeneral.MixingModule.mixNoPU_cfi') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.StandardSequences.RawToDigi_Data_cff') +process.load('Configuration.StandardSequences.L1TrackTrigger_cff') +process.load('Configuration.StandardSequences.SimL1Emulator_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(18), + output = cms.optional.untracked.allowed(cms.int32,cms.PSet), +) + +# Input source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring( ( +#'/store/mc/Phase2HLTTDRWinter20DIGI/JPsiToMuMu_Pt0to100-pythia8_TuneCP5-gun/GEN-SIM-DIGI-RAW/PU200_110X_mcRun4_realistic_v3-v2/20000/087AA768-91E6-124F-B226-DC00C45D967D.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/PU200_pilot_110X_mcRun4_realistic_v3-v2/10000/0036F7A2-BADA-1E4E-8FE7-ABE1A9AEC350.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/PU200_pilot_110X_mcRun4_realistic_v3-v2/10000/007C3CAA-5209-3B47-8755-4C6D0A3A5CD2.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/PU200_pilot_110X_mcRun4_realistic_v3-v2/10000/00AECAEC-8DFE-8D49-AF78-A55FCEBB46B7.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/PU200_pilot_110X_mcRun4_realistic_v3-v2/10000/00B04974-FAC3-5A4E-B5AE-9483D8FAD5B1.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/PU200_pilot_110X_mcRun4_realistic_v3-v2/10000/00D64490-55F9-7E4E-B3CE-BE668F1A5938.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/PU200_pilot_110X_mcRun4_realistic_v3-v2/10000/01708416-15F1-5B47-A8A0-B32D355622DB.root' + ) ), + secondaryFileNames = cms.untracked.vstring() +# skipEvents=cms.untracked.uint32(36) +) + +process.options = cms.untracked.PSet( + FailPath = cms.untracked.vstring(), + IgnoreCompletely = cms.untracked.vstring(), + Rethrow = cms.untracked.vstring(), + SkipEvent = cms.untracked.vstring(), + allowUnscheduled = cms.obsolete.untracked.bool, + canDeleteEarly = cms.untracked.vstring(), + emptyRunLumiMode = cms.obsolete.untracked.string, + eventSetup = cms.untracked.PSet( + forceNumberOfConcurrentIOVs = cms.untracked.PSet( + + ), + numberOfConcurrentIOVs = cms.untracked.uint32(1) + ), + fileMode = cms.untracked.string('FULLMERGE'), + forceEventSetupCacheClearOnNewRun = cms.untracked.bool(False), + makeTriggerResults = cms.obsolete.untracked.bool, + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfStreams = cms.untracked.uint32(0), + numberOfThreads = cms.untracked.uint32(1), + printDependencies = cms.untracked.bool(False), + sizeOfStackForThreadsInKB = cms.optional.untracked.uint32, + throwIfIllegalParameter = cms.untracked.bool(True), + wantSummary = cms.untracked.bool(False) +) + +# Production Info +process.configurationMetadata = cms.untracked.PSet( + annotation = cms.untracked.string('step1 nevts:2'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# Output definition + +process.FEVTDEBUGHLToutput = cms.OutputModule("PoolOutputModule", + dataset = cms.untracked.PSet( + dataTier = cms.untracked.string('FEVTDEBUGHLT'), + filterName = cms.untracked.string('') + ), + fileName = cms.untracked.string('reprocess.root'), + outputCommands = cms.untracked.vstring( + "drop *_*_*_*", + "keep *_gmtMuons_*_*", + "keep *_gmtStubs_*_*", + "keep *_genParticles_*_*", + "keep *_TTTracksFromTrackletEmulation_Level1TTTracks_*", + "keep *_L1TkMuons_*_*" + ), + splitLevel = cms.untracked.int32(0) +) + +# Additional output definition + +# Other statements +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, '111X_mcRun4_realistic_T15_v3', '') + +## +#Calibrate Digis +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +process.CalibratedDigis.dtDigiTag = "simMuonDTDigis" +process.CalibratedDigis.scenario = 0 + +#DTTriggerPhase2 +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.dtTriggerPhase2PrimitiveDigis.debug = False +process.dtTriggerPhase2PrimitiveDigis.dump = False +process.dtTriggerPhase2PrimitiveDigis.scenario = 0 + +process.load("L1Trigger.Phase2L1GMT.gmt_cff") +process.gmtMuons.trackMatching.verbose=1 +process.gmtMuons.verbose=0 +process.gmtMuons.trackConverter.verbose=0 + + + +#process.schedule = cms.Schedule(process.L1TrackTrigger_step,process.pL1TMuonTPS,process.endjob_step,process.e) # Adding MuonTPS + + +# Path and EndPath definitions +process.raw2digi_step = cms.Path(process.RawToDigi) +process.L1TrackTrigger_step = cms.Path(process.L1TrackTrigger) +#process.pL1TkPhotonsCrystal = cms.Path(process.L1TkPhotonsCrystal) +#process.pL1TkIsoElectronsCrystal = cms.Path(process.L1TkIsoElectronsCrystal) +#process.pL1TkElectronsLooseCrystal = cms.Path(process.L1TkElectronsLooseCrystal) +#process.pL1TkElectronsLooseHGC = cms.Path(process.L1TkElectronsLooseHGC) +#process.pL1TkElectronsHGC = cms.Path(process.L1TkElectronsHGC) +process.pL1TkMuon = cms.Path(process.L1TkMuons+process.L1TkMuonsTP) +#process.pL1TkElectronsEllipticMatchHGC = cms.Path(process.L1TkElectronsEllipticMatchHGC) +#process.pL1TkElectronsCrystal = cms.Path(process.L1TkElectronsCrystal) +#process.pL1TkPhotonsHGC = cms.Path(process.L1TkPhotonsHGC) +#process.pL1TkIsoElectronsHGC = cms.Path(process.L1TkIsoElectronsHGC) +#process.pL1TkElectronsEllipticMatchCrystal = cms.Path(process.L1TkElectronsEllipticMatchCrystal) +#process.L1simulation_step = cms.Path(process.SimL1Emulator) +process.testpath=cms.Path(process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis*process.phase2GMT) +process.endjob_step = cms.EndPath(process.endOfProcess) +process.FEVTDEBUGHLToutput_step = cms.EndPath(process.FEVTDEBUGHLToutput) + +# Schedule definition +process.schedule = cms.Schedule(process.raw2digi_step,process.L1TrackTrigger_step,process.testpath,process.endjob_step,process.FEVTDEBUGHLToutput_step) +from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask +associatePatAlgosToolsTask(process) + +#Setup FWK for multithreaded +#process.options.numberOfThreads=cms.untracked.uint32(1) +#process.options.numberOfStreams=cms.untracked.uint32(0) +#process.options.numberOfConcurrentLuminosityBlocks=cms.untracked.uint32(1) + +# customisation of the process. + +# Automatic addition of the customisation function from SLHCUpgradeSimulations.Configuration.aging +from SLHCUpgradeSimulations.Configuration.aging import customise_aging_1000 + +#call to customisation function customise_aging_1000 imported from SLHCUpgradeSimulations.Configuration.aging +#process = customise_aging_1000(process) + +# Automatic addition of the customisation function from L1Trigger.Configuration.customisePhase2TTNoMC +from L1Trigger.Configuration.customisePhase2TTNoMC import customisePhase2TTNoMC + +#call to customisation function customisePhase2TTNoMC imported from L1Trigger.Configuration.customisePhase2TTNoMC +process = customisePhase2TTNoMC(process) + +# Automatic addition of the customisation function from Configuration.DataProcessing.Utils +from Configuration.DataProcessing.Utils import addMonitoring + +#call to customisation function addMonitoring imported from Configuration.DataProcessing.Utils +process = addMonitoring(process) + +# End of customisation functions +#do not add changes to your config after this point (unless you know what you are doing) +from FWCore.ParameterSet.Utilities import convertToUnscheduled +process=convertToUnscheduled(process) + + +# Customisation from command line + +# Add early deletion of temporary data products to reduce peak memory need +from Configuration.StandardSequences.earlyDeleteSettings_cff import customiseEarlyDelete +process = customiseEarlyDelete(process) +# End adding early deletion diff --git a/L1Trigger/Phase2L1GMT/test/submitCrab.py b/L1Trigger/Phase2L1GMT/test/submitCrab.py new file mode 100644 index 0000000000000..ab0d0069b9924 --- /dev/null +++ b/L1Trigger/Phase2L1GMT/test/submitCrab.py @@ -0,0 +1,52 @@ +import os + + +data = { +# 'DY0':'/DYToLL_M-50_TuneCP5_14TeV-pythia8/Phase2HLTTDRWinter20DIGI-NoPU_pilot_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', +# 'DY140a':'/DYToLL_M-50_TuneCP5_14TeV-pythia8/Phase2HLTTDRWinter20DIGI-PU140_pilot1_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', +# 'DY140b':'/DYToLL_M-50_TuneCP5_14TeV-pythia8/Phase2HLTTDRWinter20DIGI-PU140_pilot_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', + 'DY200a':'/DYToLL_M-50_TuneCP5_14TeV-pythia8/Phase2HLTTDRWinter20DIGI-PU200_pilot_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', + 'DY200b':'/DYToLL_M-50_TuneCP5_14TeV-pythia8/Phase2HLTTDRWinter20DIGI-PU200_pilot2_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', +# 'SingleMu0':'/DoubleMuon_gun_FlatPt-1To100/Phase2HLTTDRWinter20DIGI-NoPU_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', +# 'SingleMu140':'/DoubleMuon_gun_FlatPt-1To100/Phase2HLTTDRWinter20DIGI-PU140_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', +# 'SingleMu200':'/DoubleMuon_gun_FlatPt-1To100/Phase2HLTTDRWinter20DIGI-PU200_110X_mcRun4_realistic_v3-v3/GEN-SIM-DIGI-RAW', +# 'TT200':'/TT_TuneCP5_14TeV-powheg-pythia8/Phase2HLTTDRWinter20DIGI-PU200_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', +# 'JPsiToMuMu':'/JPsiToMuMu_Pt0to100-pythia8_TuneCP5-gun/Phase2HLTTDRWinter20DIGI-NoPU_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', + 'JPsiToMuMu200a':'/JPsiToMuMu_Pt0to100-pythia8_TuneCP5-gun/Phase2HLTTDRWinter20DIGI-PU200_110X_mcRun4_realistic_v3-v2/GEN-SIM-DIGI-RAW', + 'JPsiToMuMu200b':'/JPsiToMuMu_Pt0to100-pythia8_TuneCP5-gun/Phase2HLTTDRWinter20DIGI-PU200_110X_mcRun4_realistic_v3_ext1-v3/GEN-SIM-DIGI-RAW', + 'MinBias200_a':'/MinBias_TuneCP5_14TeV-pythia8/Phase2HLTTDRWinter20DIGI-PU200_110X_mcRun4_realistic_v3-v3/GEN-SIM-DIGI-RAW', + 'MinBias200_b':'/MinBias_TuneCP5_14TeV-pythia8/Phase2HLTTDRWinter20DIGI-PU200_BSzpz35_BSzpz35_110X_mcRun4_realistic_v3_ext1-v2/GEN-SIM-DIGI-RAW', + 'MinBias200_c':'/MinBias_TuneCP5_14TeV-pythia8/Phase2HLTTDRWinter20DIGI-PU200_withNewMB_110X_mcRun4_realistic_v3_ext1-v2/GEN-SIM-DIGI-RAW' +} + + +for tag,dataset in data.iteritems(): + FILE=""" +from CRABClient.UserUtilities import config +config = config() +config.General.requestName = 'skim_{tag}' +config.General.workArea = 'crab_projects' +config.General.transferOutputs = True +config.General.transferLogs = False +config.JobType.pluginName = 'Analysis' +config.JobType.psetName = 'runGMT.py' +config.Data.inputDataset = '{dataset}' +config.Data.inputDBS = 'global' +config.Data.splitting = 'FileBased' +config.Data.unitsPerJob = 1 +config.Data.outLFNDirBase = '/store/user/bachtis/L1TF4' +config.Data.publication = True +config.Data.ignoreLocality = True +config.Data.outputDatasetTag = 'PHASEII_{tag}' +config.Site.storageSite = 'T3_US_FNALLPC' +config.Site.whitelist = ['T2_US_*'] +config.JobType.allowUndistributedCMSSW = True +config.JobType.maxMemoryMB = 4000 +""".format(tag=tag,dataset=dataset) + f=open("crab_{tag}.py".format(tag=tag),"w") + print(FILE) + f.write(FILE) + f.close() + os.system("crab submit -c crab_{PT}.py".format(PT=tag)) + + diff --git a/L1Trigger/Phase2L1GMT/test/test.py b/L1Trigger/Phase2L1GMT/test/test.py new file mode 100644 index 0000000000000..96b038e2b408f --- /dev/null +++ b/L1Trigger/Phase2L1GMT/test/test.py @@ -0,0 +1,254 @@ +# Auto generated configuration file +# using: +# Revision: 1.19 +# Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v +# with command line options: step1 --processName=L1REPR --conditions auto:phase2_realistic_T15 -n 10 --era Phase2C9 --eventcontent FEVTDEBUGHLT -s RAW2DIGI,L1 --datatier FEVTDEBUGHLT --geometry Extended2026D49 --fileout file:/tmp/step1_Reprocess_L1.root --no_exec --nThreads 8 --python step1_L1_Reprocess.py --filein das:/MinBias_TuneCP5_14TeV-pythia8/Phase2HLTTDRSummer20L1T-PU200_111X_mcRun4_realistic_T15_v1-v2/FEVT --customise L1Trigger/Configuration/customisePhase2.addHcalTriggerPrimitives --no_exec +import FWCore.ParameterSet.Config as cms + +from Configuration.Eras.Era_Phase2C9_cff import Phase2C9 + +process = cms.Process('L1REPR',Phase2C9) + +# import of standard configurations +process.load('Configuration.StandardSequences.Services_cff') +process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') +process.load('FWCore.MessageService.MessageLogger_cfi') +process.load('Configuration.EventContent.EventContent_cff') +process.load('SimGeneral.MixingModule.mixNoPU_cfi') +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.StandardSequences.L1TrackTrigger_cff') # Needed for MuonTPS +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +#process.load('L1Trigger.L1TMuonTPS.L1TTrackerPlusStubs_cfi') # Adding MuonTPS + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(5000), + output = cms.optional.untracked.allowed(cms.int32,cms.PSet) +) +process.MessageLogger.cerr.FwkReport.reportEvery = 100 + +# Input source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring( + +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/00006128-B6E9-164F-86F0-A650029BF556.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/008F2D30-9CB9-3149-BACC-44E377BD4339.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/01DCAE84-9A84-BA46-A3C9-911FE21B772B.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/03354C18-02BB-BC4E-AC41-929415ACBA10.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/04B5B609-AE07-2845-A953-C7381AFA4BA3.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/053B903A-B414-B34C-8A0C-576E52ED40BB.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0741BA70-FB5D-5F45-83BA-F21E36F4A6A0.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/07D0DC19-75A6-EF43-86AC-500087D5F044.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0A246F64-6D90-FB4A-A363-024F172686F1.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0A597E05-0A6F-CC4B-B091-6B48314BE330.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0AB846BB-0972-A046-BC9A-C571E6BAC3C5.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0BB165E7-1A72-BF45-A0BC-DFC90CA0087F.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0CFC45A2-D468-B846-A203-777B97A43120.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0D0AA151-EA54-0C42-9E2B-0D9A6430596F.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0D2CB354-3047-8C41-89ED-25662E1AC832.root', +'/store/mc/Phase2HLTTDRWinter20DIGI/DYToLL_M-50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW/NoPU_pilot_110X_mcRun4_realistic_v3-v2/20000/0E673C7A-1C1F-4948-9C05-5DD69FBB4098.root' + + + + + +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/0398918A-BD7A-6C4D-8696-6F061FF08845.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/045A4B0F-D7AA-1C44-B097-F700F9C11881.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/09E56A06-CFFA-2A46-90BA-2CF4F6C7BDC8.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/0ACCD724-9CA3-FA4D-B85B-70C5A999E089.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/0E408E15-DCEB-5546-BD16-0B45D2F5D590.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/12A09A17-6734-1244-B789-A6A79829E12B.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/12E755CC-059B-D94D-B2C0-57C2C189F4DE.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/1946CACB-2903-2649-B33C-66FB7D7F3ACC.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/19667D5B-49B9-EF45-A911-EB17EAA1E67D.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/2012FA01-916D-6C4B-8CD1-2D86920B06ED.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/234CE519-87C5-DB44-9457-E679AD595E75.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/23B4B535-51AB-9945-8BD9-9CB011277E28.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/2873F537-D329-8840-8A51-A452BACB8F66.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/2CA0BA6A-B735-C54C-8D5F-BA6A0AFE3D37.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/2D5E99B7-5876-3B44-9253-4E1B22DB02B0.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/2EFCE00C-524C-F642-B951-2825189FE8A7.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/2FFD6E4F-C824-B140-B285-A65983FF54FF.root', +#'/store/mc/Phase2HLTTDRWinter20DIGI/DoubleMuon_gun_FlatPt-1To100/GEN-SIM-DIGI-RAW/NoPU_110X_mcRun4_realistic_v3-v2/30000/330FA1A0-652B-AA49-B0C9-729965D8A0E4.root' + + + ), + secondaryFileNames = cms.untracked.vstring() +) + +process.options = cms.untracked.PSet( + FailPath = cms.untracked.vstring(), + IgnoreCompletely = cms.untracked.vstring(), + Rethrow = cms.untracked.vstring(), + SkipEvent = cms.untracked.vstring(), + allowUnscheduled = cms.obsolete.untracked.bool, + canDeleteEarly = cms.untracked.vstring(), + emptyRunLumiMode = cms.obsolete.untracked.string, + eventSetup = cms.untracked.PSet( + forceNumberOfConcurrentIOVs = cms.untracked.PSet( + ), + numberOfConcurrentIOVs = cms.untracked.uint32(1) + ), + fileMode = cms.untracked.string('FULLMERGE'), + forceEventSetupCacheClearOnNewRun = cms.untracked.bool(False), + makeTriggerResults = cms.obsolete.untracked.bool, + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfStreams = cms.untracked.uint32(0), + numberOfThreads = cms.untracked.uint32(1), + printDependencies = cms.untracked.bool(False), + sizeOfStackForThreadsInKB = cms.optional.untracked.uint32, + throwIfIllegalParameter = cms.untracked.bool(True), + wantSummary = cms.untracked.bool(False) +) + +# Production Info +process.configurationMetadata = cms.untracked.PSet( + annotation = cms.untracked.string('step1 nevts:10'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# Output definition + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('test.root'), + outputCommands = cms.untracked.vstring( + "drop *_*_*_*", + "keep *_simCscTriggerPrimitiveDigis_*_*", + "keep *_dtTriggerPhase2PrimitiveDigis_*_*", + "keep *_simDtTriggerPrimitiveDigis_*_*", + "keep *_simMuonRPCDigis_*_*", + "keep *_simMuonME0*_*_*", + "keep *_simMuonGEMDigis*_*_*", + "keep *_simBmtfDigis_*_*", + "keep *_simEmtfDigis_*_*", + "keep *_simOmtfDigis_*_*", + "keep *_genParticles_*_*", + "keep *_TTTracksFromTrackletEmulation_Level1TTTracks_*" + ) +) + +# Additional output definition + +# Other statements +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase2_realistic_T15', '') + +# Path and EndPath definitions +process.L1TrackTrigger_step = cms.Path(process.L1TrackTrigger) # Needed for MuonTPS +#process.pL1TMuonTPS = cms.Path(process.l1TrackerPlusStubsSequence) # Adding MuonTPS +process.endjob_step = cms.EndPath(process.endOfProcess) +process.e = cms.EndPath(process.out) + + +#Calibrate Digis +process.load("L1Trigger.DTTriggerPhase2.CalibratedDigis_cfi") +process.CalibratedDigis.dtDigiTag = "simMuonDTDigis" +process.CalibratedDigis.scenario = 0 + +#DTTriggerPhase2 +process.load("L1Trigger.DTTriggerPhase2.dtTriggerPhase2PrimitiveDigis_cfi") +process.dtTriggerPhase2PrimitiveDigis.debug = False +process.dtTriggerPhase2PrimitiveDigis.dump = False +process.dtTriggerPhase2PrimitiveDigis.scenario = 0 + + + + +#process.schedule = cms.Schedule(process.L1TrackTrigger_step,process.pL1TMuonTPS,process.endjob_step,process.e) # Adding MuonTPS + + +process.stubs = cms.EDProducer("Phase2L1TGMTStubProducer", + verbose = cms.int32(0), + srcCSC = cms.InputTag("simCscTriggerPrimitiveDigis"), + srcDT = cms.InputTag("dtTriggerPhase2PrimitiveDigis"), + srcDTTheta = cms.InputTag("simDtTriggerPrimitiveDigis"), + srcRPC = cms.InputTag("simMuonRPCDigis"), + Endcap =cms.PSet( + verbose = cms.uint32(0), + minBX = cms.int32(0), + maxBX = cms.int32(0), + coord1LSB = cms.double(0.00076660156*32), + eta1LSB = cms.double(7.68334e-04*32), + coord2LSB = cms.double(0.00076660156*32), + eta2LSB = cms.double(7.68334e-04*32), + phiMatch = cms.double(0.05), + etaMatch = cms.double(0.1) + ), + Barrel = cms.PSet( + verbose = cms.int32(0), + minPhiQuality = cms.int32(0), + minThetaQuality = cms.int32(0), + minBX = cms.int32(-100), + maxBX = cms.int32(100), + phiLSB = cms.double(0.00076660156*32), + phiBDivider = cms.int32(1), + etaLSB = cms.double(7.68334e-04*32), + eta_1 = cms.vint32(-1503/32,-1446/32,-1387/32,-1327/32,-1266/32,-1194/32,-1125/32,-985/32,-916/32,-839/32,-752/32,-670/32,-582/32,-489/32,-315/32,-213/32,-115/32,-49/32,49/32, 115/32, 213/32, 315/32, 489/32, 582/32, 670/32, 752/32, 839/32, 916/32, 985/32, 1125/32, 1194/32, 1266/32, 1327/32, 1387/32, 1446/32, 1503), + eta_2 = cms.vint32(-1334/32,-1279/32,-1227/32,-1168/32,-1109/32,-1044/32,-982/32,-861/32,-793/32,-720/32,-648/32,-577/32,-496/32,-425/32,-268/32,-185/32,-97/32,-51/32,51/32, 97/32, 185/32, 268/32, 425/32, 496/32, 577/32, 648/32, 720/32, 793/32, 861/32, 982/32, 1044/32, 1109/32, 1168/32, 1227/32, 1279/32, 1334), + eta_3 = cms.vint32(-1148/32,-1110/32,-1051/32,-1004/32,-947/32,-895/32,-839/32,-728/32,-668/32,-608/32,-546/32,-485/32,-425/32,-366/32,-222/32,-155/32,-87/32,-40/32,40/32, 87/32, 155/32, 222/32, 366/32, 425/32, 485/32, 546/32, 608/32, 668/32, 728/32, 839/32, 895/32, 947/32, 1004/32, 1051/32, 1110/32, 1148), + coarseEta_1 = cms.vint32(0/32,758/32,1336/32), + coarseEta_2 = cms.vint32(0/32,653/32,1168/32), + coarseEta_3 = cms.vint32(0/32,552/32,1001/32), + coarseEta_4 = cms.vint32(0/32,478/32,878/32), + phiOffset = cms.vint32(75/32,-30/32,+26/32,0) + ) + +) + + + + + +process.prod = cms.EDProducer('Phase2L1TGMTProducer', + srcTracks = cms.InputTag("TTTracksFromTrackletEmulation:Level1TTTracks"), + srcStubs = cms.InputTag('stubs'), + srcBMTF = cms.InputTag('simBmtfDigis','BMTF'), + srcEMTF = cms.InputTag('simEmtfDigis','EMTF'), + srcOMTF = cms.InputTag('simOmtfDigis','OMTF'), + muonBXMin = cms.int32(0), + muonBXMax = cms.int32(0), + IsoThreshold1 = cms.int32(0), + IsoThreshold2 = cms.int32(0), + IsoThreshold3 = cms.int32(0), + IsoThreshold4 = cms.int32(0), + verbose = cms.int32(0), + IsodumpForHLS = cms.int32(0) + ) +process.testpath=cms.Path(process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis*process.stubs*process.prod) +#process.testpath=cms.Path(process.CalibratedDigis*process.dtTriggerPhase2PrimitiveDigis) +process.schedule = cms.Schedule(process.L1TrackTrigger_step,process.testpath,process.endjob_step,process.e) + + +from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask +associatePatAlgosToolsTask(process) + +#Setup FWK for multithreaded +process.options.numberOfThreads=cms.untracked.uint32(1) +process.options.numberOfStreams=cms.untracked.uint32(0) +process.options.numberOfConcurrentLuminosityBlocks=cms.untracked.uint32(1) + +# customisation of the process. + +# Automatic addition of the customisation function from L1Trigger.Configuration.customisePhase2 +from L1Trigger.Configuration.customisePhase2 import addHcalTriggerPrimitives + +#call to customisation function addHcalTriggerPrimitives imported from L1Trigger.Configuration.customisePhase2 +process = addHcalTriggerPrimitives(process) + +# End of customisation functions + +# Customisation from command line + +# Automatic addition of the customisation function from L1Trigger.Configuration.customisePhase2TTNoMC # To make the cfg work +from L1Trigger.Configuration.customisePhase2TTNoMC import customisePhase2TTNoMC # To make the cfg work + +#call to customisation function customisePhase2TTNoMC imported from L1Trigger.Configuration.customisePhase2TTNoMC # To make the cfg work +process = customisePhase2TTNoMC(process) # To make the cfg work + +# Add early deletion of temporary data products to reduce peak memory need +from Configuration.StandardSequences.earlyDeleteSettings_cff import customiseEarlyDelete +process = customiseEarlyDelete(process) +# End adding early deletion diff --git a/L1Trigger/Phase2L1ParticleFlow/BuildFile.xml b/L1Trigger/Phase2L1ParticleFlow/BuildFile.xml index abb7c1bbd93ba..28ac6a5e6e71c 100644 --- a/L1Trigger/Phase2L1ParticleFlow/BuildFile.xml +++ b/L1Trigger/Phase2L1ParticleFlow/BuildFile.xml @@ -1,17 +1,19 @@ - + + - - - - - - - + + + + + + + + diff --git a/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_HGCal3D_TC_110X.root b/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_HGCal3D_TC_110X.root new file mode 100644 index 0000000000000..e8bb52877d7e2 Binary files /dev/null and b/L1Trigger/Phase2L1ParticleFlow/data/hadcorr_HGCal3D_TC_110X.root differ diff --git a/L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_Pion_vs_Neutrino_BDTweights_1116.xml.gz b/L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_Pion_vs_Neutrino_BDTweights_1116.xml.gz new file mode 100644 index 0000000000000..0f26ff848b9a1 Binary files /dev/null and b/L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_Pion_vs_Neutrino_BDTweights_1116.xml.gz differ diff --git a/L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_vs_Pion_BDTweights_1116.xml.gz b/L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_vs_Pion_BDTweights_1116.xml.gz new file mode 100644 index 0000000000000..3533552585b07 Binary files /dev/null and b/L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_vs_Pion_BDTweights_1116.xml.gz differ diff --git a/L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_110X.root b/L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_110X.root new file mode 100644 index 0000000000000..86697b30c081e Binary files /dev/null and b/L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_110X.root differ diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h deleted file mode 100644 index 28f804be48937..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_BitwisePFAlgo_h -#define L1Trigger_Phase2L1ParticleFlow_BitwisePFAlgo_h - -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" - -struct pfalgo_config; - -namespace l1tpf_impl { - class BitwisePFAlgo : public PFAlgoBase { - public: - BitwisePFAlgo(const edm::ParameterSet&); - ~BitwisePFAlgo() override; - void runPF(Region& r) const override; - - protected: - enum class AlgoChoice { algo3, algo2hgc } algo_; - std::shared_ptr config_; - }; - -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h b/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h deleted file mode 100644 index 3a61bf2ee8ecd..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_CoeFile_h -#define L1Trigger_Phase2L1ParticleFlow_CoeFile_h - -// system include files -#include -#include -#include -#include -#include -#include - -// user include files -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" - -namespace l1tpf_impl { - class COEFile { - public: - COEFile(const edm::ParameterSet&); - ~COEFile(); - - void close() { fclose(file); } - template - bool getBit(T value, unsigned bit) { - return (value >> bit) & 1; - } - bool is_open() { return (file != nullptr); } - void writeHeaderToFile(); - void writeTracksToFile(const std::vector& regions, bool print = false); - - protected: - FILE* file; - std::string coeFileName, bset_string_; - unsigned int ntracksmax, phiSlices; - static constexpr unsigned int tracksize = 96; - boost::dynamic_bitset<> bset_; - const std::vector track_word_block_sizes = {14, 1, 12, 16, 12, 13, 4, 3, 7, 14}; - int debug_; - }; -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h deleted file mode 100644 index 4de6832b8806b..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h +++ /dev/null @@ -1,259 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_H -#define L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_H - -#if defined(__GXX_EXPERIMENTAL_CXX0X__) or defined(CMSSW) -#include -#include -#define L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE -#else -#include -#endif - -namespace l1t { - class PFTrack; - class PFCluster; - class PFCandidate; - class Muon; -} // namespace l1t - -// the serialization may be hidden if needed -#include -#include - -namespace l1tpf_impl { - - struct CaloCluster { - int16_t hwPt; - int16_t hwEmPt; - int16_t hwPtErr; - int16_t hwEta; - int16_t hwPhi; - uint16_t hwFlags; - bool isEM, used; - const l1t::PFCluster *src; - - // sorting - bool operator<(const CaloCluster &other) const { return hwPt > other.hwPt; } - -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - static constexpr float PT_SCALE = 4.0; // quantize in units of 0.25 GeV (can be changed) - static constexpr float ETAPHI_FACTOR = 4; // size of an ecal crystal in phi in integer units (our choice) - static constexpr float ETAPHI_SCALE = - ETAPHI_FACTOR * - (180. / M_PI); // M_PI/180 is the size of an ECal crystal; we make a grid that is 4 times that size - static constexpr int16_t PHI_WRAP = 360 * ETAPHI_FACTOR; // what is 3.14 in integer - - static int16_t ptToInt16(float pt) { // avoid overflows - return std::min(round(pt * CaloCluster::PT_SCALE), std::numeric_limits::max()); - } - - // filling from floating point - void fill(float pt, - float emPt, - float ptErr, - float eta, - float phi, - bool em, - unsigned int flags, - const l1t::PFCluster *source = nullptr) { - hwPt = CaloCluster::ptToInt16(pt); - hwEmPt = CaloCluster::ptToInt16(emPt); - hwPtErr = CaloCluster::ptToInt16(ptErr); - hwEta = round(eta * CaloCluster::ETAPHI_SCALE); - hwPhi = int16_t(round(phi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP; - isEM = em; - used = false; - hwFlags = flags; - src = source; - } - - float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; } - float floatEmPt() const { return float(hwEmPt) / CaloCluster::PT_SCALE; } - float floatPtErr() const { return float(hwPtErr) / CaloCluster::PT_SCALE; } - static float minFloatPt() { return float(1.0) / CaloCluster::PT_SCALE; } - float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; } - float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; } - void setFloatPt(float pt) { hwPt = round(pt * CaloCluster::PT_SCALE); } - void setFloatEmPt(float emPt) { hwEmPt = round(emPt * CaloCluster::PT_SCALE); } -#endif - }; - - // https://twiki.cern.ch/twiki/bin/view/CMS/L1TriggerPhase2InterfaceSpecifications - struct InputTrack { - uint16_t hwInvpt; - int32_t hwVtxEta; - int32_t hwVtxPhi; - bool hwCharge; - int16_t hwZ0; - uint16_t hwChi2, hwStubs; - uint16_t hwFlags; - const l1t::PFTrack *src; - -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - static constexpr float INVPT_SCALE = 2E4; // 1%/pt @ 100 GeV is 2 bits - static constexpr float VTX_PHI_SCALE = 1 / 1.6E-3; // 5 micro rad is 2 bits - static constexpr float VTX_ETA_SCALE = 1 / 1E-4; // no idea, but assume it's somewhat worse than phi - static constexpr float Z0_SCALE = 20; // 1mm is 2 bits - static constexpr int32_t VTX_ETA_1p3 = 1.3 * InputTrack::VTX_ETA_SCALE; - - // filling from floating point - void fillInput( - float pt, float eta, float phi, int charge, float dz, unsigned int flags, const l1t::PFTrack *source = nullptr) { - hwInvpt = std::min(round(1 / pt * InputTrack::INVPT_SCALE), std::numeric_limits::max()); - hwVtxEta = round(eta * InputTrack::VTX_ETA_SCALE); - hwVtxPhi = round(phi * InputTrack::VTX_PHI_SCALE); - hwCharge = (charge > 0); - hwZ0 = round(dz * InputTrack::Z0_SCALE); - hwFlags = flags; - src = source; - } - - float floatVtxPt() const { return 1 / (float(hwInvpt) / InputTrack::INVPT_SCALE); } - float floatVtxEta() const { return float(hwVtxEta) / InputTrack::VTX_ETA_SCALE; } - float floatVtxPhi() const { return float(hwVtxPhi) / InputTrack::VTX_PHI_SCALE; } - float floatDZ() const { return float(hwZ0) / InputTrack::Z0_SCALE; } - int intCharge() const { return hwCharge ? +1 : -1; } -#endif - }; - - struct PropagatedTrack : public InputTrack { - int16_t hwPt; - int16_t hwPtErr; - int16_t hwCaloPtErr; - int16_t hwEta; // at calo - int16_t hwPhi; // at calo - bool muonLink; - bool used; // note: this flag is not used in the default PF, but is used in alternative algos - bool fromPV; - - // sorting - bool operator<(const PropagatedTrack &other) const { return hwPt > other.hwPt; } - -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - void fillPropagated( - float pt, float ptErr, float caloPtErr, float caloEta, float caloPhi, unsigned int quality, bool isMuon) { - hwPt = CaloCluster::ptToInt16(pt); - hwPtErr = CaloCluster::ptToInt16(ptErr); - hwCaloPtErr = CaloCluster::ptToInt16(caloPtErr); - // saturation protection - if (hwPt == std::numeric_limits::max()) { - hwCaloPtErr = hwPt / 4; - } - hwEta = round(caloEta * CaloCluster::ETAPHI_SCALE); - hwPhi = int16_t(round(caloPhi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP; - muonLink = isMuon; - used = false; - } - - float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; } - float floatPtErr() const { return float(hwPtErr) / CaloCluster::PT_SCALE; } - float floatCaloPtErr() const { return float(hwCaloPtErr) / CaloCluster::PT_SCALE; } - float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; } - float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; } -#endif - }; - - struct Muon { - int16_t hwPt; - int16_t hwEta; // at calo - int16_t hwPhi; // at calo - uint16_t hwFlags; - bool hwCharge; - const l1t::Muon *src; - - // sorting - bool operator<(const Muon &other) const { return hwPt > other.hwPt; } - -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - void fill(float pt, float eta, float phi, int charge, unsigned int flags, const l1t::Muon *source = nullptr) { - // we assume we use the same discrete ieta, iphi grid for all particles - hwPt = round(pt * CaloCluster::PT_SCALE); - hwEta = round(eta * CaloCluster::ETAPHI_SCALE); - hwPhi = int16_t(round(phi * CaloCluster::ETAPHI_SCALE)) % CaloCluster::PHI_WRAP; - hwCharge = (charge > 0); - hwFlags = flags; - src = source; - } - float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; } - float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; } - float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; } - int intCharge() const { return hwCharge ? +1 : -1; } -#endif - }; - - struct PFParticle { - int16_t hwPt; - int16_t hwEta; // at calo face - int16_t hwPhi; - uint8_t hwId; // CH=0, EL=1, NH=2, GAMMA=3, MU=4 - int16_t hwVtxEta; // propagate back to Vtx for charged particles (if useful?) - int16_t hwVtxPhi; - uint16_t hwFlags; - CaloCluster cluster; - PropagatedTrack track; - bool chargedPV; - uint16_t hwPuppiWeight; - uint16_t hwStatus; // for debugging - const l1t::Muon *muonsrc; - const l1t::PFCandidate *src; - - // sorting - bool operator<(const PFParticle &other) const { return hwPt > other.hwPt; } - -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - static constexpr float PUPPI_SCALE = 100; - - float floatPt() const { return float(hwPt) / CaloCluster::PT_SCALE; } - float floatEta() const { return float(hwEta) / CaloCluster::ETAPHI_SCALE; } - float floatPhi() const { return float(hwPhi) / CaloCluster::ETAPHI_SCALE; } - float floatVtxEta() const { - return (track.hwPt > 0 ? track.floatVtxEta() : float(hwVtxEta) / CaloCluster::ETAPHI_SCALE); - } - float floatVtxPhi() const { - return (track.hwPt > 0 ? track.floatVtxPhi() : float(hwVtxPhi) / CaloCluster::ETAPHI_SCALE); - } - float floatDZ() const { return float(track.hwZ0) / InputTrack::Z0_SCALE; } - float floatPuppiW() const { return float(hwPuppiWeight) / PUPPI_SCALE; } - int intCharge() const { return (track.hwPt > 0 ? track.intCharge() : 0); } - void setPuppiW(float w) { hwPuppiWeight = std::round(w * PUPPI_SCALE); } - void setFloatPt(float pt) { hwPt = round(pt * CaloCluster::PT_SCALE); } -#endif - }; - - struct InputRegion { - float etaCenter, etaMin, etaMax, phiCenter, phiHalfWidth; - float etaExtra, phiExtra; - std::vector calo; - std::vector emcalo; - std::vector track; - std::vector muon; - - InputRegion() - : etaCenter(), - etaMin(), - etaMax(), - phiCenter(), - phiHalfWidth(), - etaExtra(), - phiExtra(), - calo(), - emcalo(), - track(), - muon() {} - InputRegion( - float etacenter, float etamin, float etamax, float phicenter, float phihalfwidth, float etaextra, float phiextra) - : etaCenter(etacenter), - etaMin(etamin), - etaMax(etamax), - phiCenter(phicenter), - phiHalfWidth(phihalfwidth), - etaExtra(etaextra), - phiExtra(phiextra), - calo(), - emcalo(), - track(), - muon() {} - }; - -} // namespace l1tpf_impl -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h b/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h deleted file mode 100644 index 11df865e31afc..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputsIO_H -#define L1Trigger_Phase2L1ParticleFlow_DiscretePFInputsIO_H - -#include -#include -#include - -#include "DiscretePFInputs.h" - -namespace l1tpf_impl { - inline void writeToFile(const CaloCluster &c, FILE *file) { - fwrite(&c.hwPt, 2, 1, file); - fwrite(&c.hwEmPt, 2, 1, file); - fwrite(&c.hwPtErr, 2, 1, file); - fwrite(&c.hwEta, 2, 1, file); - fwrite(&c.hwPhi, 2, 1, file); - fwrite(&c.hwFlags, 2, 1, file); - fwrite(&c.isEM, 1, 1, file); - // used is not written out - // src is not written out - } - inline void readFromFile(CaloCluster &c, FILE *file) { - fread(&c.hwPt, 2, 1, file); - fread(&c.hwEmPt, 2, 1, file); - fread(&c.hwPtErr, 2, 1, file); - fread(&c.hwEta, 2, 1, file); - fread(&c.hwPhi, 2, 1, file); - fread(&c.hwFlags, 2, 1, file); - fread(&c.isEM, 1, 1, file); - c.used = false; - c.src = nullptr; - } - - inline void writeToFile(const InputTrack &t, FILE *file) { - fwrite(&t.hwInvpt, 2, 1, file); - fwrite(&t.hwVtxEta, 4, 1, file); - fwrite(&t.hwVtxPhi, 4, 1, file); - fwrite(&t.hwCharge, 1, 1, file); - fwrite(&t.hwZ0, 2, 1, file); - fwrite(&t.hwChi2, 2, 1, file); - fwrite(&t.hwStubs, 2, 1, file); - fwrite(&t.hwFlags, 2, 1, file); - // src is not written out - } - inline void readFromFile(InputTrack &t, FILE *file) { - fread(&t.hwInvpt, 2, 1, file); - fread(&t.hwVtxEta, 4, 1, file); - fread(&t.hwVtxPhi, 4, 1, file); - fread(&t.hwCharge, 1, 1, file); - fread(&t.hwZ0, 2, 1, file); - fread(&t.hwChi2, 2, 1, file); - fread(&t.hwStubs, 2, 1, file); - fread(&t.hwFlags, 2, 1, file); - t.src = nullptr; - } - inline void writeToFile(const PropagatedTrack &t, FILE *file) { - writeToFile(static_cast(t), file); - fwrite(&t.hwPt, 2, 1, file); - fwrite(&t.hwPtErr, 2, 1, file); - fwrite(&t.hwCaloPtErr, 2, 1, file); - fwrite(&t.hwEta, 2, 1, file); - fwrite(&t.hwPhi, 2, 1, file); - // muonLink, used, fromPV are transient - } - inline void readFromFile(PropagatedTrack &t, FILE *file) { - readFromFile(static_cast(t), file); - fread(&t.hwPt, 2, 1, file); - fread(&t.hwPtErr, 2, 1, file); - fread(&t.hwCaloPtErr, 2, 1, file); - fread(&t.hwEta, 2, 1, file); - fread(&t.hwPhi, 2, 1, file); - t.muonLink = false; - t.used = false; - t.fromPV = false; - } - - inline void writeToFile(const Muon &m, FILE *file) { - fwrite(&m.hwPt, 2, 1, file); - fwrite(&m.hwEta, 2, 1, file); - fwrite(&m.hwPhi, 2, 1, file); - fwrite(&m.hwFlags, 2, 1, file); - fwrite(&m.hwCharge, 1, 1, file); - } - inline void readFromFile(Muon &m, FILE *file) { - fread(&m.hwPt, 2, 1, file); - fread(&m.hwEta, 2, 1, file); - fread(&m.hwPhi, 2, 1, file); - fread(&m.hwFlags, 2, 1, file); - fread(&m.hwCharge, 1, 1, file); - m.src = nullptr; - } - - inline void writeToFile(const float &pug, FILE *file) { fwrite(&pug, sizeof(float), 1, file); } - inline void readFromFile(float &pug, FILE *file) { fread(&pug, sizeof(float), 1, file); } - - template - void writeManyToFile(const std::vector &objs, FILE *file) { - uint32_t number = objs.size(); - fwrite(&number, 4, 1, file); - for (uint32_t i = 0; i < number; ++i) - writeToFile(objs[i], file); - } - - template - void readManyFromFile(std::vector &objs, FILE *file) { - uint32_t number; - fread(&number, 4, 1, file); - objs.resize(number); - for (uint32_t i = 0; i < number; ++i) - readFromFile(objs[i], file); - } - - inline void writeToFile(const InputRegion &r, FILE *file) { - assert(4 == sizeof(float)); - fwrite(&r.etaCenter, 4, 1, file); - fwrite(&r.etaMin, 4, 1, file); - fwrite(&r.etaMax, 4, 1, file); - fwrite(&r.phiCenter, 4, 1, file); - fwrite(&r.phiHalfWidth, 4, 1, file); - fwrite(&r.etaExtra, 4, 1, file); - fwrite(&r.phiExtra, 4, 1, file); - writeManyToFile(r.calo, file); - writeManyToFile(r.emcalo, file); - writeManyToFile(r.track, file); - writeManyToFile(r.muon, file); - } - inline void readFromFile(InputRegion &r, FILE *file) { - assert(4 == sizeof(float)); - fread(&r.etaCenter, 4, 1, file); - fread(&r.etaMin, 4, 1, file); - fread(&r.etaMax, 4, 1, file); - fread(&r.phiCenter, 4, 1, file); - fread(&r.phiHalfWidth, 4, 1, file); - fread(&r.etaExtra, 4, 1, file); - fread(&r.phiExtra, 4, 1, file); - readManyFromFile(r.calo, file); - readManyFromFile(r.emcalo, file); - readManyFromFile(r.track, file); - readManyFromFile(r.muon, file); - } - -} // namespace l1tpf_impl -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h new file mode 100644 index 0000000000000..15004caa2f803 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h @@ -0,0 +1,76 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_L1TCorrelatorLayer1PatternFileWriter_h +#define L1Trigger_Phase2L1ParticleFlow_L1TCorrelatorLayer1PatternFileWriter_h + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h" +#include "L1Trigger/DemonstratorTools/interface/utilities.h" + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +class L1TCorrelatorLayer1PatternFileWriter { +public: + L1TCorrelatorLayer1PatternFileWriter(const edm::ParameterSet& iConfig, const l1ct::Event& eventTemplate); + ~L1TCorrelatorLayer1PatternFileWriter(); + + void write(const l1ct::Event& event); + void flush(); + +private: + enum class Partition { Barrel, HGCal, HGCalNoTk, HF }; + + Partition partition_; + const unsigned int tmuxFactor_ = 6; // not really configurable in current architecture + bool writeInputs_, writeOutputs_; + std::map> channelIdsInput_, channelIdsOutput_; + std::map channelSpecsInput_, channelSpecsOutput_; + + const unsigned int tfTimeslices_ = 3, tfLinksFactor_ = 1; // not really configurable in current architecture + const unsigned int hgcTimeslices_ = 3, hgcLinksFactor_ = 4; // not really configurable in current architecture + const unsigned int gctTimeslices_ = 1, gctSectors_ = 3; // not really configurable in current architecture + const unsigned int gctLinksEcal_ = 1, gctLinksHad_ = 2; // could be made configurable later + const unsigned int gmtTimeslices_ = 3, gmtLinksFactor_ = 1; // not really configurable in current architecture + const unsigned int gttTimeslices_ = 1, gttLinksFactor_ = 1; // not really configurable in current architecture + uint32_t gmtNumberOfMuons_; + uint32_t gttNumberOfPVs_; + uint32_t gttLatency_; + + std::vector outputRegions_, outputLinksPuppi_; + unsigned int nPuppiFramesPerRegion_; + int32_t outputBoard_, outputLinkEgamma_; + uint32_t nEgammaObjectsOut_; + + // Common stuff related to the format + uint32_t nInputFramesPerBX_, nOutputFramesPerBX_; + const std::string fileFormat_; + + // final helper + const uint32_t eventsPerFile_; + uint32_t eventIndex_; + std::unique_ptr inputFileWriter_, outputFileWriter_; + + static Partition parsePartition(const std::string& partition); + + void configTimeSlices(const edm::ParameterSet& iConfig, + const std::string& prefix, + unsigned int nSectors, + unsigned int nTimeSlices, + unsigned int linksFactor); + void configSectors(const edm::ParameterSet& iConfig, + const std::string& prefix, + unsigned int nSectors, + unsigned int linksFactor); + void configLinks(const edm::ParameterSet& iConfig, + const std::string& prefix, + unsigned int linksFactor, + unsigned int offset); + + void writeTF(const l1ct::Event& event, l1t::demo::EventData& out); + void writeBarrelGCT(const l1ct::Event& event, l1t::demo::EventData& out); + void writeHGC(const l1ct::Event& event, l1t::demo::EventData& out); + void writeGMT(const l1ct::Event& event, l1t::demo::EventData& out); + void writeGTT(const l1ct::Event& event, l1t::demo::EventData& out); + void writePuppi(const l1ct::Event& event, l1t::demo::EventData& out); + void writeEgamma(const l1ct::Event& event, l1t::demo::EventData& out); +}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h deleted file mode 100644 index fe5bd5378ec03..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_LinearizedPuppiAlgo_h -#define L1Trigger_Phase2L1ParticleFlow_LinearizedPuppiAlgo_h - -#include "L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h" - -namespace l1tpf_impl { - - class LinearizedPuppiAlgo : public PuppiAlgo { - public: - LinearizedPuppiAlgo(const edm::ParameterSet &); - ~LinearizedPuppiAlgo() override; - - const std::vector &puGlobalNames() const override; - void doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const override; - void runNeutralsPU(Region &r, float npu, const std::vector &globals) const override; - - protected: - void computePuppiWeights(Region &r, - float npu, - const std::vector &alphaC, - const std::vector &alphaF) const; - - std::vector puppiPriors_, puppiPriorsPhotons_; - std::vector puppiPtSlopes_, puppiPtSlopesPhotons_; - std::vector puppiPtZeros_, puppiPtZerosPhotons_; - std::vector puppiAlphaSlopes_, puppiAlphaSlopesPhotons_; - std::vector puppiAlphaZeros_, puppiAlphaZerosPhotons_; - std::vector puppiAlphaCrops_, puppiAlphaCropsPhotons_; - }; - -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h deleted file mode 100644 index c6342d9efddfe..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_PFAlgo2HGC_h -#define L1Trigger_Phase2L1ParticleFlow_PFAlgo2HGC_h - -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" - -namespace l1tpf_impl { - class PFAlgo2HGC : public PFAlgoBase { - public: - PFAlgo2HGC(const edm::ParameterSet &); - void runPF(Region &r) const override; - - protected: - float drMatchMu_; - enum class MuMatchMode { BoxBestByPtRatio, DrBestByPtRatio, DrBestByPtDiff } muMatchMode_; - float drMatch_, ptMatchLow_, ptMatchHigh_, maxInvisiblePt_; - bool useTrackCaloSigma_, rescaleUnmatchedTrack_, caloTrkWeightedAverage_; - enum class TkCaloLinkMetric { BestByDR = 0, BestByDRPt = 1, BestByDR2Pt2 = 2 }; - TkCaloLinkMetric tkCaloLinkMetric_; - bool caloReLinkStep_; - float caloReLinkDr_, caloReLinkThreshold_; - bool rescaleTracks_, sumTkCaloErr2_, ecalPriority_, trackEmUseAlsoTrackSigma_, emCaloUseAlsoCaloSigma_; - unsigned int tightTrackMinStubs_; - float tightTrackMaxChi2_, tightTrackMaxInvisiblePt_; - enum GoodTrackStatus { GoodTK_Calo_TkPt = 0, GoodTK_Calo_TkCaloPt = 1, GoodTk_Calo_CaloPt = 2, GoodTK_NoCalo = 3 }; - enum BadTrackStatus { BadTK_NoCalo = 1 }; - - /// do muon track linking (also sets track.muonLink) - void link_tk2mu(Region &r, std::vector &tk2mu, std::vector &mu2tk) const; - - /// track to calo matching - // tk2calo[itk] = icalo or -1 - void link_tk2calo(Region &r, std::vector &tk2calo) const; - - /// for each calo, compute the sum of the track pt - void sum_tk2calo(Region &r, - const std::vector &tk2calo, - std::vector &calo2ntk, - std::vector &calo2sumtkpt, - std::vector &calo2sumtkpterr) const; - - /// promote unlinked low pt tracks to hadrons - void unlinkedtk_algo(Region &r, const std::vector &tk2calo) const; - - /// try to recover split hadron showers (v1.0): - // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt - // add this pt to the calo pt of the other cluster - // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events - void calo_relink(Region &r, - const std::vector &calo2ntk, - const std::vector &calo2sumtkpt, - const std::vector &calo2sumtkpterr) const; - - /// process matched calo clusters, compare energy to sum track pt, compute track rescaling factor if needed - // alpha[icalo] = x < 1 if all tracks linked to icalo must have their pt rescaled by x - void linkedcalo_algo(Region &r, - const std::vector &calo2ntk, - const std::vector &calo2sumtkpt, - const std::vector &calo2sumtkpterr, - std::vector &calo2alpha) const; - - /// process matched tracks, if necessary rescale or average - void linkedtk_algo(Region &r, - const std::vector &tk2calo, - const std::vector &calo2ntk, - const std::vector &calo2alpha) const; - - /// process unmatched calo clusters - void unlinkedcalo_algo(Region &r) const; - - /// save muons in output list - void save_muons(Region &r, const std::vector &tk2mu) const; - }; - -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h deleted file mode 100644 index 5972218dc10fd..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_PFAlgo3_h -#define L1Trigger_Phase2L1ParticleFlow_PFAlgo3_h - -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" - -namespace l1tpf_impl { - class PFAlgo3 : public PFAlgoBase { - public: - PFAlgo3(const edm::ParameterSet &); - void runPF(Region &r) const override; - - protected: - float drMatchMu_; - enum class MuMatchMode { BoxBestByPtRatio, DrBestByPtRatio, DrBestByPtDiff } muMatchMode_; - float drMatch_, ptMatchLow_, ptMatchHigh_, maxInvisiblePt_; - bool useTrackCaloSigma_, rescaleUnmatchedTrack_, caloTrkWeightedAverage_; - enum class TkCaloLinkMetric { BestByDR = 0, BestByDRPt = 1, BestByDR2Pt2 = 2 }; - float drMatchEm_, ptMinFracMatchEm_, drMatchEmHad_; - float emHadSubtractionPtSlope_; - TkCaloLinkMetric tkCaloLinkMetric_; - bool caloReLinkStep_; - float caloReLinkDr_, caloReLinkThreshold_; - bool rescaleTracks_, sumTkCaloErr2_, ecalPriority_, trackEmUseAlsoTrackSigma_, trackEmMayUseCaloMomenta_, - emCaloUseAlsoCaloSigma_; - unsigned int tightTrackMinStubs_; - float tightTrackMaxChi2_, tightTrackMaxInvisiblePt_; - enum GoodTrackStatus { GoodTK_Calo_TkPt = 0, GoodTK_Calo_TkCaloPt = 1, GoodTk_Calo_CaloPt = 2, GoodTK_NoCalo = 3 }; - enum BadTrackStatus { BadTK_NoCalo = 1 }; - - /// do muon track linking (also sets track.muonLink) - void link_tk2mu(Region &r, std::vector &tk2mu, std::vector &mu2tk) const; - - /// match all tracks to the closest EM cluster - // tk2em[itrack] = iem, or -1 if unmatched - void link_tk2em(Region &r, std::vector &tk2em) const; - - /// match all em to the closest had (can happen in parallel to the above) - // em2calo[iem] = icalo or -1 - void link_em2calo(Region &r, std::vector &em2calo) const; - - /// for each EM cluster, count and add up the pt of all the corresponding tracks (skipping muons) - void sum_tk2em(Region &r, - const std::vector &tk2em, - std::vector &em2ntk, - std::vector &em2sumtkpt, - std::vector &em2sumtkpterr) const; - - /// process ecal clusters after linking - void emcalo_algo(Region &r, - const std::vector &em2ntk, - const std::vector &em2sumtkpt, - const std::vector &em2sumtkpterr) const; - - /// promote all flagged tracks to electrons - void emtk_algo(Region &r, - const std::vector &tk2em, - const std::vector &em2ntk, - const std::vector &em2sumtkpterr) const; - - /// subtract EM component from Calo clusters for all photons and electrons (within tracker coverage) - void sub_em2calo(Region &r, const std::vector &em2calo) const; - - /// track to calo matching - // tk2calo[itk] = icalo or -1 - void link_tk2calo(Region &r, std::vector &tk2calo) const; - - /// for each calo, compute the sum of the track pt - void sum_tk2calo(Region &r, - const std::vector &tk2calo, - std::vector &calo2ntk, - std::vector &calo2sumtkpt, - std::vector &calo2sumtkpterr) const; - - /// promote unlinked low pt tracks to hadrons - void unlinkedtk_algo(Region &r, const std::vector &tk2calo) const; - - /// try to recover split hadron showers (v1.0): - // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt - // add this pt to the calo pt of the other cluster - // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events - void calo_relink(Region &r, - const std::vector &calo2ntk, - const std::vector &calo2sumtkpt, - const std::vector &calo2sumtkpterr) const; - - /// process matched calo clusters, compare energy to sum track pt, compute track rescaling factor if needed - // alpha[icalo] = x < 1 if all tracks linked to icalo must have their pt rescaled by x - void linkedcalo_algo(Region &r, - const std::vector &calo2ntk, - const std::vector &calo2sumtkpt, - const std::vector &calo2sumtkpterr, - std::vector &calo2alpha) const; - - /// process matched tracks, if necessary rescale or average - void linkedtk_algo(Region &r, - const std::vector &tk2calo, - const std::vector &calo2ntk, - const std::vector &calo2alpha) const; - - /// process unmatched calo clusters - void unlinkedcalo_algo(Region &r) const; - - /// save muons in output list - void save_muons(Region &r, const std::vector &tk2mu) const; - }; - -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h b/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h deleted file mode 100644 index f0286a221222f..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_PFAlgoBase_h -#define L1Trigger_Phase2L1ParticleFlow_PFAlgoBase_h - -#include - -#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -namespace l1tpf_impl { - - class PFAlgoBase { - public: - PFAlgoBase(const edm::ParameterSet &); - virtual ~PFAlgoBase(); - virtual void runPF(Region &r) const = 0; - - protected: - int debug_; - void initRegion(Region &r) const; - PFParticle &addTrackToPF(Region &r, const PropagatedTrack &tk) const { return addTrackToPF(r.pf, tk); } - PFParticle &addCaloToPF(Region &r, const CaloCluster &calo) const { return addCaloToPF(r.pf, calo); } - PFParticle &addTrackToPF(std::vector &pfs, const PropagatedTrack &tk) const; - PFParticle &addCaloToPF(std::vector &pfs, const CaloCluster &calo) const; - }; - -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h b/L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h deleted file mode 100644 index 0b6cfa60f6fca..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_PUAlgoBase_h -#define L1Trigger_Phase2L1ParticleFlow_PUAlgoBase_h - -#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -namespace l1tpf_impl { - - class PUAlgoBase { - public: - PUAlgoBase(const edm::ParameterSet &); - virtual ~PUAlgoBase(); - - /// global operations - enum class VertexAlgo { Old, TP, External }; - virtual void doVertexing(std::vector &rs, - VertexAlgo algo, - float &vz) const; // region is not const since it sets the fromPV bit of the tracks - - virtual void runChargedPV(Region &r, float z0) const; - - virtual const std::vector &puGlobalNames() const; - virtual void doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const = 0; - virtual void runNeutralsPU(Region &r, float npu, const std::vector &globals) const = 0; - - protected: - int debug_; - float etaCharged_, vtxRes_; - bool vtxAdaptiveCut_; - }; - -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h b/L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h deleted file mode 100644 index 297209cde949d..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_PuppiAlgo_h -#define L1Trigger_Phase2L1ParticleFlow_PuppiAlgo_h - -#include "L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h" - -namespace l1tpf_impl { - - class PuppiAlgo : public PUAlgoBase { - public: - PuppiAlgo(const edm::ParameterSet &); - ~PuppiAlgo() override; - - const std::vector &puGlobalNames() const override; - void doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const override; - void runNeutralsPU(Region &r, float npu, const std::vector &globals) const override; - - protected: - virtual void computePuppiMedRMS( - const std::vector &rs, float &alphaCMed, float &alphaCRms, float &alphaFMed, float &alphaFRms) const; - virtual void fillPuppi(Region &r) const; - virtual void computePuppiAlphas(const Region &r, std::vector &alphaC, std::vector &alphaF) const; - void computePuppiWeights(Region &r, - const std::vector &alphaC, - const std::vector &alphaF, - float alphaCMed, - float alphaCRms, - float alphaFMed, - float alphaFRms) const; - - float puppiDr_, puppiDrMin_, puppiPtMax_; - std::vector puppiEtaCuts_, puppiPtCuts_, puppiPtCutsPhotons_; - std::vector intPuppiEtaCuts_, intPuppiPtCuts_, intPuppiPtCutsPhotons_; - bool puppiUsingBareTracks_; - }; - -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/Region.h b/L1Trigger/Phase2L1ParticleFlow/interface/Region.h deleted file mode 100644 index b022bace35f69..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/Region.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_Region_h -#define L1Trigger_Phase2L1ParticleFlow_Region_h - -#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputs.h" -#include "DataFormats/Math/interface/deltaPhi.h" - -namespace l1tpf_impl { - struct Region : public InputRegion { - std::vector pf; - std::vector puppi; - unsigned int caloOverflow, emcaloOverflow, trackOverflow, muonOverflow, pfOverflow, puppiOverflow; - - const bool relativeCoordinates; // whether the eta,phi in each region are global or relative to the region center - const unsigned int ncaloMax, nemcaloMax, ntrackMax, nmuonMax, npfMax, npuppiMax; - Region(float etamin, - float etamax, - float phicenter, - float phiwidth, - float etaextra, - float phiextra, - bool useRelativeCoordinates, - unsigned int ncalomax, - unsigned int nemcalomax, - unsigned int ntrackmax, - unsigned int nmuonmax, - unsigned int npfmax, - unsigned int npuppimax) - : InputRegion(0.5 * (etamin + etamax), etamin, etamax, phicenter, 0.5 * phiwidth, etaextra, phiextra), - pf(), - puppi(), - caloOverflow(), - emcaloOverflow(), - trackOverflow(), - muonOverflow(), - pfOverflow(), - puppiOverflow(), - relativeCoordinates(useRelativeCoordinates), - ncaloMax(ncalomax), - nemcaloMax(nemcalomax), - ntrackMax(ntrackmax), - nmuonMax(nmuonmax), - npfMax(npfmax), - npuppiMax(npuppimax) {} - - enum InputType { calo_type = 0, emcalo_type = 1, track_type = 2, l1mu_type = 3, n_input_types = 4 }; - static const char* inputTypeName(int inputType); - - enum OutputType { - any_type = 0, - charged_type = 1, - neutral_type = 2, - electron_type = 3, - pfmuon_type = 4, - charged_hadron_type = 5, - neutral_hadron_type = 6, - photon_type = 7, - n_output_types = 8 - }; - static const char* outputTypeName(int outputType); - - unsigned int nInput(InputType type) const; - unsigned int nOutput(OutputType type, bool puppi, bool fiducial = true) const; - - // global coordinates - bool contains(float eta, float phi) const { - float dphi = deltaPhi(phiCenter, phi); - return (etaMin - etaExtra < eta && eta <= etaMax + etaExtra && -phiHalfWidth - phiExtra < dphi && - dphi <= phiHalfWidth + phiExtra); - } - // global coordinates - bool fiducial(float eta, float phi) const { - float dphi = deltaPhi(phiCenter, phi); - return (etaMin < eta && eta <= etaMax && -phiHalfWidth < dphi && dphi <= phiHalfWidth); - } - // possibly local coordinates - bool fiducialLocal(float localEta, float localPhi) const { - if (relativeCoordinates) { - float dphi = deltaPhi(0.f, localPhi); - return (etaMin < localEta + etaCenter && localEta + etaCenter <= etaMax && -phiHalfWidth < dphi && - dphi <= phiHalfWidth); - } - float dphi = deltaPhi(phiCenter, localPhi); - return (etaMin < localEta && localEta <= etaMax && -phiHalfWidth < dphi && dphi <= phiHalfWidth); - } - float regionAbsEta() const { return std::abs(etaCenter); } - float globalAbsEta(float localEta) const { return std::abs(relativeCoordinates ? localEta + etaCenter : localEta); } - float globalEta(float localEta) const { return relativeCoordinates ? localEta + etaCenter : localEta; } - float globalPhi(float localPhi) const { return relativeCoordinates ? localPhi + phiCenter : localPhi; } - float localEta(float globalEta) const { return relativeCoordinates ? globalEta - etaCenter : globalEta; } - float localPhi(float globalPhi) const { return relativeCoordinates ? deltaPhi(globalPhi, phiCenter) : globalPhi; } - - void zero() { - calo.clear(); - emcalo.clear(); - track.clear(); - muon.clear(); - pf.clear(); - puppi.clear(); - caloOverflow = 0; - emcaloOverflow = 0; - trackOverflow = 0; - muonOverflow = 0; - pfOverflow = 0; - puppiOverflow = 0; - } - - void inputSort(); - }; - -} // namespace l1tpf_impl - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h b/L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h deleted file mode 100644 index 11ca55c1d981e..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_RegionMapper_h -#define L1Trigger_Phase2L1ParticleFlow_RegionMapper_h - -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" -#include "DataFormats/Math/interface/deltaPhi.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "DataFormats/L1TCorrelator/interface/TkMuon.h" -#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" - -#include - -namespace l1tpf_impl { - class RegionMapper { - // This does the input and filling of regions. - public: - RegionMapper(const edm::ParameterSet &); - - // add object, without tracking references - void addTrack(const l1t::PFTrack &t); - void addMuon(const l1t::Muon &t); - void addMuon(const l1t::TkMuon &t); - void addCalo(const l1t::PFCluster &t); - void addEmCalo(const l1t::PFCluster &t); - - // add object, tracking references - void addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref); - void addMuon(const l1t::Muon &t, l1t::PFCandidate::MuonRef ref); - void addCalo(const l1t::PFCluster &t, l1t::PFClusterRef ref); - void addEmCalo(const l1t::PFCluster &t, l1t::PFClusterRef ref); - - void clear(); - std::vector ®ions() { return regions_; } - - std::unique_ptr fetch(bool puppi = true, float ptMin = 0.01) const; - std::unique_ptr fetchCalo(float ptMin = 0.01, bool emcalo = false) const; - std::unique_ptr fetchTracks(float ptMin = 0.01, bool fromPV = false) const; - - std::pair totAndMaxInput(/*Region::InputType*/ int type) const; - std::pair totAndMaxOutput(/*Region::OutputType*/ int type, bool puppi) const; - std::unique_ptr> vecInput(int type) const; - std::unique_ptr> vecOutput(int type, bool puppi) const; - - protected: - std::vector regions_; - bool useRelativeRegionalCoordinates_; // whether the eta,phi in each region are global or relative to the region center - enum class TrackAssoMode { atVertex, atCalo, any = 999 } trackRegionMode_; - - // these are used to link items back - std::unordered_map clusterRefMap_; - std::unordered_map trackRefMap_; - std::unordered_map muonRefMap_; - }; - -} // namespace l1tpf_impl -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_hybrid_sort_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_hybrid_sort_ref.h new file mode 100644 index 0000000000000..58fcd2390bc05 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_hybrid_sort_ref.h @@ -0,0 +1,355 @@ +#ifndef BITONIC_HYBRID_REF_H +#define BITONIC_HYBRID_REF_H + +#include +#include + +namespace hybridBitonicSortUtils { + inline unsigned int PowerOf2LessThan(unsigned int n) { + unsigned int i = 1; + unsigned int prev = 1; + if (n <= 1) + return n; + while (i < n) { + i <<= 1; + if (i < n) { + prev = i; + } else { + return prev; + } + } + // shouldn't happen + assert(false); + } + + template + void compAndSwap(T a[], int i, int j, bool dir) { + if (dir) { + if (a[j] < a[i]) + std::swap(a[i], a[j]); + } else { + if (a[i] < a[j]) + std::swap(a[i], a[j]); + } + } + + inline unsigned int bitonicMergeLatencyRef(unsigned int nIn) { + if (nIn <= 1) + return 0; + return 1 + + std::max(bitonicMergeLatencyRef(PowerOf2LessThan(nIn)), bitonicMergeLatencyRef(nIn - PowerOf2LessThan(nIn))); + } + + inline unsigned int bitonicSortLatencyRef(unsigned int nIn, unsigned int nOut) { + if (nIn <= 1) + return 0; + unsigned int sort1Size = nIn / 2, sort2Size = nIn - sort1Size; + unsigned int sort1Latency = bitonicSortLatencyRef(sort1Size, nOut); + unsigned int sort2Latency = bitonicSortLatencyRef(sort2Size, nOut); + unsigned int mergeLatency = bitonicMergeLatencyRef(std::min(sort1Size, nOut) + std::min(sort2Size, nOut)); + return std::max(sort1Latency, sort2Latency) + mergeLatency; + } + + inline unsigned int hybridBitonicSortLatencyRef(unsigned int nIn, unsigned int nOut) { + if (nIn <= 1) + return 0; + if (nIn == 5 || nIn == 6) + return 3; + if (nIn == 12) + return 8; + if (nIn == 13) + return 9; + unsigned int sort1Size = nIn / 2, sort2Size = nIn - sort1Size; + unsigned int sort1Latency = hybridBitonicSortLatencyRef(sort1Size, nOut); + unsigned int sort2Latency = hybridBitonicSortLatencyRef(sort2Size, nOut); + unsigned int mergeLatency = bitonicMergeLatencyRef(std::min(sort1Size, nOut) + std::min(sort2Size, nOut)); + return std::max(sort1Latency, sort2Latency) + mergeLatency; + } + + // may be specialized for different types if needed + template + void clear(T& t) { + t.clear(); + } + +} // namespace hybridBitonicSortUtils + +template +void hybridBitonicMergeRef(T a[], int N, int low, bool dir) { + int k = hybridBitonicSortUtils::PowerOf2LessThan(N); + int k2 = N - k; + if (N > 1) { + for (int i = low; i < low + k; i++) { + if (i + k < low + N) + hybridBitonicSortUtils::compAndSwap(a, i, i + k, dir); + } + if (N > 2) { + hybridBitonicMergeRef(a, k, low, dir); + hybridBitonicMergeRef(a, k2, low + k, dir); + } + } +} + +template +void check_sorted(T a[], int N, int low, bool dir) { + bool ok = true; + if (dir) { + for (int i = 1; i < N; ++i) + ok = ok && (!(a[low + i - 1] > a[low + i])); + } else { + for (int i = 1; i < N; ++i) + ok = ok && (!(a[low + i - 1] < a[low + i])); + } + if (!ok) { + printf("ERROR in sorting[N=%d,low=%d,dir=%d]: ", N, low, int(dir)); + //for (int i = 0; i < N; ++i) printf("%d[%s] ", a[low+i].intPt(), a[low+i].pack().to_string(16).c_str()); + //for (int i = 0; i < N; ++i) printf("%d ", a[low+i]); + printf("\n"); + fflush(stdout); + assert(ok); + } +} + +template +void hybridBitonicSortRef(T a[], int N, int low, bool dir, bool hybrid) { + if (hybrid) { // sorting networks defined by hand for a few cases + switch (N) { + case 2: + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 1, dir); + return; + case 3: + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 1, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 2, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 1, dir); + //check_sorted(a, N, low, dir); + return; + case 4: + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 1, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 3, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 2, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 3, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 2, dir); + //check_sorted(a, N, low, dir); + return; + case 5: + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 1, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 3, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 3, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 4, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 2, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 4, dir); + //-- + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 2, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 4, dir); + //-- + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 3, dir); + //check_sorted(a, N, low, dir); + return; + case 6: + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 3, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 2, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 1, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 3, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 4, low + 5, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 3, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 5, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 1, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 5, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 2, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 4, dir); + //check_sorted(a, N, low, dir); + return; + case 12: + for (int i = 0; i < 12; i += 2) { + hybridBitonicSortUtils::compAndSwap(a, low + i, low + i + 1, dir); + } + //--- + for (int i = 0; i < 12; i += 4) { + hybridBitonicSortUtils::compAndSwap(a, low + i + 0, low + i + 2, dir); + hybridBitonicSortUtils::compAndSwap(a, low + i + 1, low + i + 3, dir); + } + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 5, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 6, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 11, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 9, low + 10, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 2, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 6, low + 10, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 5, low + 9, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 4, low + 8, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 7, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 6, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 5, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 9, low + 10, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 11, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 8, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 10, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 3, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 5, low + 6, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 8, low + 9, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 5, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 6, low + 8, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 9, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 5, low + 6, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 8, dir); + //check_sorted(a, N, low, dir); + return; + case 13: + for (int i = 0; i + 1 < 13; i += 2) { + hybridBitonicSortUtils::compAndSwap(a, low + i, low + i + 1, dir); + } + //--- + for (int i = 0; i + 3 < 13; i += 4) { + hybridBitonicSortUtils::compAndSwap(a, low + i + 0, low + i + 2, dir); + hybridBitonicSortUtils::compAndSwap(a, low + i + 1, low + i + 3, dir); + } + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 5, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 6, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 7, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 8, low + 12, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 0, low + 8, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 9, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 10, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 11, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 4, low + 12, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 2, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 12, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 11, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 4, low + 8, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 5, low + 10, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 6, low + 9, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 1, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 8, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 6, low + 12, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 10, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 5, low + 9, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 2, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 5, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 6, low + 8, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 9, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 10, low + 12, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 6, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 5, low + 8, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 10, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 9, low + 12, dir); + //--- + hybridBitonicSortUtils::compAndSwap(a, low + 3, low + 4, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 5, low + 6, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 7, low + 8, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 9, low + 10, dir); + hybridBitonicSortUtils::compAndSwap(a, low + 11, low + 12, dir); + //check_sorted(a, N, low, dir); + return; + } + } + + // general case + if (N > 1) { + int lowerSize = N / 2; + int upperSize = N - N / 2; + bool notDir = not dir; + hybridBitonicSortRef(a, lowerSize, low, notDir, hybrid); + hybridBitonicSortRef(a, upperSize, low + lowerSize, dir, hybrid); + hybridBitonicMergeRef(a, N, low, dir); + //check_sorted(a, N, low, dir); + } +} + +template +void hybrid_bitonic_sort_and_crop_ref( + unsigned int nIn, unsigned int nOut, const T in[], T out[], bool hybrid = true) { // just an interface + T work[nIn]; + for (unsigned int i = 0; i < nIn; ++i) { + work[i] = in[i]; + } + hybridBitonicSortRef(work, nIn, 0, false, hybrid); + for (unsigned int i = 0; i < nOut; ++i) { + out[i] = work[i]; + } +} + +template +void folded_hybrid_bitonic_sort_and_crop_ref( + unsigned int nIn, unsigned int nOut, const T in[], T out[], bool hybrid = true) { // just an interface + unsigned int nHalf = (nIn + 1) / 2; + T work[nHalf], halfsorted[nHalf]; + //printf("hybrid sort input %u items: ", nIn); + //for (int i = 0; i < nIn; ++i) printf("%d.%03d ", work[i].intPt(), work[i].intEta()); + //for (int i = 0; i < nIn; ++i) if (in[i].hwPt) printf("[%d]%s ", i, in[i].pack().to_string(16).c_str()); + //printf("\n"); + //fflush(stdout); + for (int o = 1; o >= 0; --o) { + for (unsigned int i = 0; i < nHalf && 2 * i + o < nIn; ++i) { + work[i] = in[2 * i + o]; + } + if ((nIn % 2 == 1) && (o == 1)) { + hybridBitonicSortUtils::clear(work[nHalf - 1]); + } + hybridBitonicSortRef(work, nHalf, 0, false, hybrid); + //printf("hybrid sort offset %d with %u items: ", o, nHalf); + //for (int i = 0; i < nHalf; ++i) printf("%d.%03d ", work[i].intPt(), work[i].intEta()); + //for (int i = 0; i < nHalf; ++i) printf("%s ", work[i].pack().to_string(16).c_str()); + //printf("\n"); + //fflush(stdout); + for (unsigned int i = 1; i < nHalf; ++i) + assert(!(work[i - 1] < work[i])); + if (o == 1) { + for (unsigned int i = 0; i < nHalf; ++i) { + halfsorted[i] = work[i]; + } + } + } + // now merge work with the reversed of half-sorted + unsigned int nMerge = std::min(nOut, nHalf); + T tomerge[2 * nMerge]; + for (unsigned int i = 0; i < nMerge; ++i) { + tomerge[nMerge - i - 1] = halfsorted[i]; + tomerge[nMerge + i] = work[i]; + } + //printf("hybrid sort tomerge %u items before: ", 2*nMerge); + //for (int i = 0; i < 2*nMerge; ++i) printf("%d.%03d ", tomerge[i].intPt(), tomerge[i].intEta()); + //for (int i = 0; i < 2*nMerge; ++i) printf("%s ", tomerge[i].pack().to_string(16).c_str()); + //printf("\n"); + hybridBitonicMergeRef(tomerge, 2 * nMerge, 0, false); + //printf("hybrid sort tomerge %u items after: ", 2*nMerge); + //for (int i = 0; i < 2*nMerge; ++i) printf("%d.%03d ", tomerge[i].intPt(), tomerge[i].intEta()); + //for (int i = 0; i < nOut; ++i) printf("%s ", tomerge[i].pack().to_string(16).c_str()); + //printf("\n"); + //fflush(stdout); + for (unsigned int i = 0; i < nOut; ++i) { + out[i] = tomerge[i]; + if (i > 0) + assert(!(out[i - 1] < out[i])); + } +} + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_sort_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_sort_ref.h new file mode 100644 index 0000000000000..b9ba3f5d481fa --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_sort_ref.h @@ -0,0 +1,144 @@ +#ifndef BITONIC_NEW_H +#define BITONIC_NEW_H + +#include +#include + +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +inline unsigned int PowerOf2LessThan(unsigned int n) { + unsigned int i = 1; + unsigned int prev = 1; + if (n <= 1) + return n; + while (i < n) { + i <<= 1; + if (i < n) { + prev = i; + } else { + return prev; + } + } + // shouldn't happen + assert(false); +} + +template +void bitonicMerge(T in[], int InSize, T out[], int OutSize, bool dir) { + //printDebug; + + // size == 1 -> pass through + if (InSize <= 1) { + for (int i = 0; i < std::min(InSize, OutSize); ++i) + out[i] = in[i]; + return; + } + + if (InSize > 1) { + int LowerSize = PowerOf2LessThan(InSize); //-- LowerSize >= Size / 2 + int UpperSize = InSize - LowerSize; //-- UpperSize < LowerSiz + + if (LowerSize < UpperSize) + dbgCout() << "[ERROR]" << __FUNCTION__ << " LowerSize (" << LowerSize << ") not > of UpperSize (" << UpperSize + << ")" << std::endl; + + for (int i = 0; i < UpperSize; ++i) { + if ((in[i] > in[i + LowerSize]) == dir) { + // this checks should refer to the comments, "just needs to be long enough" + if (i < OutSize) + out[i] = in[i + LowerSize]; + if (i + LowerSize < OutSize) + out[i + LowerSize] = in[i]; + } else { + if (i < OutSize) + out[i] = in[i]; + if (i + LowerSize < OutSize) + out[i + LowerSize] = in[i + LowerSize]; + } + } + + // Copy the residual at the end. This limits the sorting in the overall descending direction (if out != in). + if (LowerSize > UpperSize) { + for (int i = UpperSize; i < LowerSize; ++i) { + if (i < OutSize) + out[i] = in[i]; + } + } + + T out2[LowerSize]; + bitonicMerge(out, LowerSize, out2, LowerSize, dir); + + T out3[UpperSize]; + bitonicMerge(out + LowerSize, UpperSize, out3, UpperSize, dir); + + // copy back to out; direction dependent. + if (dir) // ascending -- Copy up to OutSize + { + for (int i = 0; i < OutSize; ++i) { + if (i < UpperSize) + out[OutSize - i - 1] = out3[UpperSize - i - 1]; + else + out[OutSize - i - 1] = out2[LowerSize - i - 1 + UpperSize]; + } + + } else { //descending + for (int i = 0; i < LowerSize; ++i) { + if (i < OutSize) + out[i] = out2[i]; + } + for (int i = LowerSize; i < OutSize; ++i) + out[i] = out3[i - LowerSize]; + } + + } // InSize>1 + +} // bitonicMerge + +template +void bitonicSort(const T in[], int Start, int InSize, T out[], int OutSize, bool dir) { + if (InSize <= 1) // copy in-> out and exit + { + for (int i = 0; i < std::min(InSize, OutSize); ++i) + out[i] = in[i + Start]; + return; + } + + int LowerInSize = InSize / 2; + int UpperInSize = InSize - LowerInSize; //-- UpperSize >= LowerSize + + int LowerOutSize = std::min(OutSize, LowerInSize); + int UpperOutSize = std::min(OutSize, UpperInSize); + + // sorted output + T OutTmp[LowerOutSize + UpperOutSize]; + + // sort first half + bitonicSort(in, + Start, + LowerInSize, + OutTmp, + LowerOutSize, + not dir); // the not dir enforce the sorting in overall descending direction. + + // sort second half + bitonicSort(in, Start + LowerInSize, UpperInSize, OutTmp + LowerOutSize, UpperOutSize, dir); + + // create a temporary output vector "large enough" and then copy back + int OutSize2 = LowerOutSize + UpperOutSize; + T outTmp2[OutSize2]; + bitonicMerge(OutTmp, LowerOutSize + UpperOutSize, outTmp2, OutSize2, dir); + //copy back to out the first OutSize + for (int i = 0; i < OutSize; ++i) { + if (dir) { //ascending + out[OutSize - 1 - i] = outTmp2[OutSize2 - 1 - i]; + } else { //descending + out[i] = outTmp2[i]; + } + } +} + +template +void bitonic_sort_and_crop_ref(unsigned int nIn, unsigned int nOut, const T in[], T out[]) { // just an interface + bitonicSort(in, 0, nIn, out, nOut, 0); +} +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_activation.h b/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_activation.h new file mode 100644 index 0000000000000..81c344e861e88 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_activation.h @@ -0,0 +1,249 @@ +// +// rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks +// +// Copyright (C) 2017 EJ Kreinar +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef NNET_ACTIVATION_H_ +#define NNET_ACTIVATION_H_ + +#include +#include "ap_fixed.h" +#include "nnet_common.h" + +namespace nnet { + + struct activ_config { + // IO size + static const unsigned n_in = 10; + + // Internal info + static const unsigned table_size = 1024; + + // Resource reuse info + static const unsigned io_type = io_parallel; + static const unsigned reuse_factor = 1; + + // Internal data type definitions + //typedef ap_fixed<18,8> table_t; + typedef float table_t; + }; + + // ************************************************* + // LINEAR Activation -- See Issue 53 + // ************************************************* + template + void linear(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) { + for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) { + res[ii] = data[ii]; + } + } + + // ************************************************* + // RELU Activation + // ************************************************* + template + void relu(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) { + data_T datareg; + for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) { + datareg = data[ii]; + if (datareg > 0) + res[ii] = datareg; + else + res[ii] = 0; + } + } + + template + void relu_max(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) { + data_T datareg; + for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) { + datareg = data[ii]; + if (datareg < 0) + res[ii] = 0; + else if (datareg > MAX_INT) + res[ii] = MAX_INT; + else + res[ii] = datareg; + } + } + + template + void relu6(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) { + relu_max(data, res); + } + + // ************************************************* + // Sigmoid Activation + // ************************************************* + template + inline out_T sigmoid_fcn_float(float input) { + return 1.0 / (1 + exp(-input)); + } + + template + void init_sigmoid_table(res_T table_out[N_TABLE]) { + // Default logistic sigmoid function: + // result = 1/(1+e^(-x)) + for (unsigned ii = 0; ii < N_TABLE; ii++) { + // First, convert from table index to X-value (signed 8-bit, range -8 to +8) + float in_val = 2 * 8.0 * (ii - float(N_TABLE) / 2.0) / float(N_TABLE); + // Next, compute lookup table function + res_T real_val = sigmoid_fcn_float(in_val); + //std::cout << "Lookup table In Value: " << in_val << " Result: " << real_val << std::endl; + table_out[ii] = (res_T)real_val; + } + } + + template + void sigmoid(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) { + // Initialize the lookup table + res_T sigmoid_table[CONFIG_T::table_size]; + init_sigmoid_table(sigmoid_table); + + // Index into the lookup table based on data + int data_round; + unsigned index; + for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) { + data_round = data[ii] * CONFIG_T::table_size / 16; + index = data_round + 8 * CONFIG_T::table_size / 16; + /*if (index < 0) + index = 0;*/ + if (index > CONFIG_T::table_size - 1) + index = CONFIG_T::table_size - 1; + res[ii] = (res_T)sigmoid_table[index]; + } + } + + // ************************************************* + // Softmax Activation + // ************************************************* + inline float exp_fcn_float(float input) { return exp(input); } + + template + void init_exp_table(typename CONFIG_T::table_t table_out[N_TABLE]) { + for (unsigned ii = 0; ii < N_TABLE; ii++) { + // First, convert from table index to X-value (signed 8-bit, range -8 to +8) + float in_val = 2 * 8.0 * (ii - float(N_TABLE) / 2.0) / float(N_TABLE); + // Next, compute lookup table function + typename CONFIG_T::table_t real_val = exp_fcn_float(in_val); + //std::cout << "Lookup table In Value: " << in_val << " Result: " << real_val << std::endl; + table_out[ii] = real_val; + } + } + + template + void init_invert_table(typename CONFIG_T::table_t table_out[N_TABLE]) { + // Inversion function: + // result = 1/x + for (unsigned ii = 0; ii < N_TABLE; ii++) { + // First, convert from table index to X-value (signed 8-bit, range 0 to +64) + float in_val = 64.0 * ii / float(N_TABLE); + // Next, compute lookup table function + if (in_val > 0.0) + table_out[ii] = 1.0 / in_val; + else + table_out[ii] = 0.0; + } + } + + template + void softmax(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) { + // Initialize the lookup table + typename CONFIG_T::table_t exp_table[CONFIG_T::table_size]; + init_exp_table(exp_table); + + typename CONFIG_T::table_t invert_table[CONFIG_T::table_size]; + init_invert_table(invert_table); + + // Index into the lookup table based on data for exponentials + typename CONFIG_T::table_t exp_res[CONFIG_T::n_in]; // different, independent, fixed point precision + typename CONFIG_T::table_t exp_diff_res[CONFIG_T::n_in] + [CONFIG_T::n_in]; // different, independent, fixed point precision + int data_round; + int index; + for (int ii = 0; ii < CONFIG_T::n_in; ii++) { + exp_res[ii] = 0; + } + for (int ii = 0; ii < CONFIG_T::n_in; ii++) { + for (int jj = 0; jj < CONFIG_T::n_in; jj++) { + if (ii == jj) + exp_diff_res[ii][jj] = 1; + else { + data_round = (data[jj] - data[ii]) * CONFIG_T::table_size / 16; + index = data_round + 8 * CONFIG_T::table_size / 16; + if (index < 0) + index = 0; + if (index > CONFIG_T::table_size - 1) + index = CONFIG_T::table_size - 1; + exp_diff_res[ii][jj] = exp_table[index]; + } + exp_res[ii] += exp_diff_res[ii][jj]; + } + } + + //Second loop to invert + for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) { + int exp_res_index = exp_res[ii] * CONFIG_T::table_size / 64; + if (exp_res_index < 0) + exp_res_index = 0; + if (exp_res_index > CONFIG_T::table_size - 1) + exp_res_index = CONFIG_T::table_size - 1; + //typename CONFIG_T::table_t exp_res_invert = invert_table[exp_res_index]; + res[ii] = (res_T)invert_table[exp_res_index]; + } + } + + // ************************************************* + // TanH Activation + // ************************************************* + template + void init_tanh_table(typename CONFIG_T::table_t table_out[N_TABLE]) { + // Implement tanh lookup + for (unsigned ii = 0; ii < N_TABLE; ii++) { + // First, convert from table index to X-value (signed 8-bit, range -4 to +4) + float in_val = 2 * 4.0 * (ii - float(N_TABLE) / 2.0) / float(N_TABLE); + // Next, compute lookup table function + typename CONFIG_T::table_t real_val = tanh(in_val); + //std::cout << "Tanh: Lookup table Index: " << ii<< " In Value: " << in_val << " Result: " << real_val << std::endl; + table_out[ii] = real_val; + } + } + + template + void tanh(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) { + // Initialize the lookup table + typename CONFIG_T::table_t tanh_table[CONFIG_T::table_size]; + init_tanh_table(tanh_table); + + // Index into the lookup table based on data + int data_round; + int index; + for (int ii = 0; ii < CONFIG_T::n_in; ii++) { + data_round = data[ii] * CONFIG_T::table_size / 8; + index = data_round + 4 * CONFIG_T::table_size / 8; + //std::cout << "Input: " << data[ii] << " Round: " << data_round << " Index: " << index << std::endl; + if (index < 0) + index = 0; + if (index > CONFIG_T::table_size - 1) + index = CONFIG_T::table_size - 1; + res[ii] = (res_T)tanh_table[index]; + } + } + +} // namespace nnet + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_common.h b/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_common.h new file mode 100644 index 0000000000000..bc934e7628184 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_common.h @@ -0,0 +1,37 @@ +// +// rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks +// +// Copyright (C) 2017 EJ Kreinar +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef NNET_COMMON_H_ +#define NNET_COMMON_H_ + +#include "ap_fixed.h" + +namespace nnet { + + // Common type definitions + enum io_type { io_parallel = 0, io_serial }; + + // Default data types (??) TODO: Deprecate + //typedef ap_fixed<16,4> weight_t_def; + //typedef ap_fixed<16,4> bias_t_def; + //typedef ap_fixed<32,10> accum_t_def; + +} // namespace nnet + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_layer.h b/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_layer.h new file mode 100644 index 0000000000000..0eacce9bf95a7 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_layer.h @@ -0,0 +1,104 @@ +// +// rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks +// +// Copyright (C) 2017 EJ Kreinar +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef NNET_LAYER_H_ +#define NNET_LAYER_H_ + +#include "nnet_common.h" +#include + +namespace nnet { + + struct layer_config { + // Internal data type definitions + typedef float bias_t; + typedef float weight_t; + typedef float accum_t; + + // Layer Sizes + static const unsigned n_in = 10; + static const unsigned n_out = 10; + + // Resource reuse info + static const unsigned io_type = io_parallel; + static const unsigned reuse_factor = 1; + static const bool store_weights_in_bram = false; + static const unsigned n_zeros = 0; + static const bool use_lowlatency = true; + // partitioning arrays cyclically to go with roll factors? + }; + +#define DIV_ROUNDUP(n, d) ((n + d - 1) / d) + + template + void compute_layer(data_T data[CONFIG_T::n_in], + res_T res[CONFIG_T::n_out], + typename CONFIG_T::weight_t weights[CONFIG_T::n_in * CONFIG_T::n_out], + typename CONFIG_T::bias_t biases[CONFIG_T::n_out]) { + unsigned cycle_factor = DIV_ROUNDUP(CONFIG_T::n_in * CONFIG_T::n_out, CONFIG_T::reuse_factor); + typename CONFIG_T::weight_t mult[CONFIG_T::n_in * CONFIG_T::n_out]; + /* + if(CONFIG_T::use_lowlatency) { + int multiplier_limit = ceil(float(CONFIG_T::n_in*CONFIG_T::n_out) / float(CONFIG_T::reuse_factor)) - floor(float(CONFIG_T::n_zeros) / float(CONFIG_T::reuse_factor)); + } + */ + typename CONFIG_T::accum_t acc[CONFIG_T::n_out]; + for (unsigned iacc = 0; iacc < CONFIG_T::n_out; iacc++) { + acc[iacc] = (typename CONFIG_T::accum_t)biases[iacc]; + } + unsigned rufactor = CONFIG_T::reuse_factor; + if (CONFIG_T::use_lowlatency) { + rufactor = CONFIG_T::n_in; + cycle_factor = CONFIG_T::n_out; + } + data_T cache; + for (unsigned ii = 0; ii < rufactor; ii++) { + if (CONFIG_T::use_lowlatency) { + cache = data[ii]; + } + for (unsigned jj = 0; jj < cycle_factor; jj++) { + unsigned windex = ii * cycle_factor + jj; + unsigned index = windex / CONFIG_T::n_out; + if (windex > CONFIG_T::n_in * CONFIG_T::n_out - 1) + continue; + if (CONFIG_T::use_lowlatency) { + mult[windex] = cache * (weights[windex]); + } else { + int aindex = windex / CONFIG_T::n_in; + acc[aindex] += data[index] * weights[windex]; + } + } + } + if (CONFIG_T::use_lowlatency) { + // Accumulate multiplication result + for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) { + for (unsigned jj = 0; jj < CONFIG_T::n_out; jj++) { + int index = ii * CONFIG_T::n_out + jj; + acc[jj] += mult[index]; + } + } + } + for (unsigned ires = 0; ires < CONFIG_T::n_out; ires++) { + res[ires] = (res_T)(acc[ires]); + } + } + +} // namespace nnet + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h b/L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h new file mode 100644 index 0000000000000..3169a84b6f715 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h @@ -0,0 +1,35 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_dbgPrintf_h +#define L1Trigger_Phase2L1ParticleFlow_dbgPrintf_h + +#ifdef CMSSW_GIT_HASH +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include + +inline edm::LogPrint dbgCout() { return edm::LogPrint("L1TCorrelator"); } +inline edm::LogProblem dbgCerr() { return edm::LogProblem("L1TCorrelator"); } + +template +inline void dbgPrintf(const char *formatString, Args &&...args) { + char buff[1024]; + std::fill(buff, buff + 1024, '\0'); + int ret = snprintf(buff, 1023, formatString, std::forward(args)...); + if (ret > 0 && ret < 1023 && buff[ret - 1] == '\n') + buff[ret - 1] = '\0'; + edm::LogPrint("L1TCorrelator") << std::string_view(buff); +} + +#else // outside CMSSW: just use std::cout and printf + +#include + +inline std::ostream &dbgCout() { return std::cout; } +inline std::ostream &dbgCerr() { return std::cerr; } + +template +inline void dbgPrintf(const char *formatString, Args &&...args) { + printf(formatString, std::forward(args)...); +} + +#endif + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h b/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h new file mode 100644 index 0000000000000..1a50810c2179b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h @@ -0,0 +1,49 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_deregionizer_input_h +#define L1Trigger_Phase2L1ParticleFlow_deregionizer_input_h + +#include +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +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 + + DeregionizerInput(std::vector ®ionEtaCenter, + std::vector ®ionPhiCenter, + const std::vector &inputRegions); + + void setDebug(bool debug = true) { debug_ = debug; } + + enum regionIndex { + centralBarl = 0, + negBarl = 1, + posBarl = 2, + negHGCal = 3, + posHGCal = 4, + forwardHGCal = 5 /*, HF = 6*/ + }; + void orderRegions(int order[nEtaRegions]); + + const std::vector > > &orderedInRegionsPuppis() const { + return orderedInRegionsPuppis_; + }; + + private: + std::vector regionEtaCenter_; + std::vector regionPhiCenter_; + std::vector > > orderedInRegionsPuppis_; + + bool debug_ = false; + + unsigned int orderRegionsInPhi(const float eta, const float phi, const float etaComp) const; + void initRegions(const std::vector &inputRegions); + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h new file mode 100644 index 0000000000000..7a68a0db80a9e --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h @@ -0,0 +1,52 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_deregionizer_ref_h +#define L1Trigger_Phase2L1ParticleFlow_deregionizer_ref_h + +#include +#include "deregionizer_input.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + class DeregionizerEmulator { + public: + DeregionizerEmulator(const unsigned int nPuppiFinalBuffer = 128, + const unsigned int nPuppiPerClk = 6, + const unsigned int nPuppiFirstBuffers = 12, + const unsigned int nPuppiSecondBuffers = 32, + const unsigned int nPuppiThirdBuffers = 64); + + // note: this one will work only in CMSSW + DeregionizerEmulator(const edm::ParameterSet &iConfig); + + ~DeregionizerEmulator(){}; + + void setDebug(bool debug = true) { debug_ = debug; } + + void run(const DeregionizerInput 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_; + + static std::vector mergeXtoY(const unsigned int X, + const unsigned int Y, + const std::vector &inLeft, + const std::vector &inRight); + + static void accumulateToY(const unsigned int Y, + const std::vector &in, + std::vector &out, + std::vector &truncated); + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h new file mode 100644 index 0000000000000..010fa8801d692 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h @@ -0,0 +1,97 @@ +#ifndef L2EGENCODER_REF_H +#define L2EGENCODER_REF_H + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "DataFormats/L1TParticleFlow/interface/egamma.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + struct L2EgEncoderEmulator { + L2EgEncoderEmulator(unsigned int nTKELE_OUT, unsigned int nTKPHO_OUT) + : nTkEleOut_(nTKELE_OUT), nTkPhoOut_(nTKPHO_OUT), nEncodedWords_(nTKELE_OUT * 1.5 + nTKPHO_OUT * 1.5) { + assert(nTkEleOut_ % 2 == 0); + assert(nTkPhoOut_ % 2 == 0); + }; + + L2EgEncoderEmulator(const edm::ParameterSet& iConfig); + + void toFirmware(const std::vector>& encoded_in, ap_uint<64> encoded_fw[]) const; + + std::vector> encodeLayer2EgObjs(const std::vector& photons, + const std::vector& electrons) const { + std::vector> ret; + + auto encoded_photons = encodeLayer2(photons); + encoded_photons.resize(nTkPhoOut_, {0}); + auto encoded_eles = encodeLayer2(electrons); + encoded_eles.resize(nTkEleOut_, {0}); + // + encodeLayer2To64bits(encoded_eles, ret); + encodeLayer2To64bits(encoded_photons, ret); + return ret; + } + + template + std::vector> encodeLayer2EgObjs_trivial(const std::vector& egs, int n) const { + std::vector> ret; + + auto encoded_egs = encodeLayer2_trivial(egs); + encoded_egs.resize(n, {0}); + // + encodeLayer2To64bits(encoded_egs, ret); + + return ret; + } + + private: + template + ap_uint<96> encodeLayer2(const T& egiso) const { + return egiso.toGT().pack(); + } + + template + std::vector> encodeLayer2(const std::vector& egisos) const { + std::vector> ret; + ret.reserve(egisos.size()); + for (const auto& egiso : egisos) { + ret.push_back(encodeLayer2(egiso)); + } + return ret; + } + // + template + ap_uint<96> encodeLayer2_trivial(const T& egiso) const { + ap_uint<96> ret = 0; + ret(T::BITWIDTH - 1, 0) = egiso.pack(); + return ret; + } + + template + std::vector> encodeLayer2_trivial(const std::vector& egisos) const { + std::vector> ret; + for (const auto& egiso : egisos) { + ret.push_back(encodeLayer2_trivial(egiso)); + } + return ret; + } + + void encodeLayer2To64bits(const std::vector>& packed96, std::vector>& packed64) const { + for (unsigned int i = 0; i < packed96.size(); i += 2) { + packed64.push_back(packed96[i](63, 0)); + packed64.push_back((ap_uint<32>(packed96[i + 1](95, 64)), ap_uint<32>(packed96[i](95, 64)))); + packed64.push_back(packed96[i + 1](63, 0)); + } + } + + unsigned int nTkEleOut_; + unsigned int nTkPhoOut_; + unsigned int nEncodedWords_; + }; + +} // namespace l1ct +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h new file mode 100644 index 0000000000000..c5b75b37384e6 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h @@ -0,0 +1,138 @@ +#ifndef L2EgSorter_REF_H +#define L2EgSorter_REF_H + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "DataFormats/L1TParticleFlow/interface/egamma.h" +#include "DataFormats/L1TParticleFlow/interface/pf.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_hybrid_sort_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#include + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + class L2EgSorterEmulator { + public: + L2EgSorterEmulator(unsigned int nBoards, unsigned int nEGPerBoard, unsigned int nEGOut, bool debug) + : nBOARDS(nBoards), nEGPerBoard(nEGPerBoard), nEGOut(nEGOut), debug_(debug) {} + + L2EgSorterEmulator(const edm::ParameterSet &iConfig); + + virtual ~L2EgSorterEmulator() {} + + template + void toFirmware(const std::vector &in, + EGIsoObj (&photons_in)[NBoards][NObjs], + EGIsoEleObj (&eles_in)[NBoards][NObjs]) const { + for (unsigned int ib = 0; ib < NBoards; ib++) { + const auto &board = in[ib]; + for (unsigned int io = 0; io < NObjs; io++) { + EGIsoObj pho; + EGIsoEleObj ele; + if (io < board.egphoton.size()) + pho = board.egphoton[io]; + else + pho.clear(); + if (io < board.egelectron.size()) + ele = board.egelectron[io]; + else + ele.clear(); + + photons_in[ib][io] = pho; + eles_in[ib][io] = ele; + } + } + } + + void toFirmware(const std::vector &out_photons, + const std::vector &out_eles, + EGIsoObj out_egphs[/*nObjOut*/], + EGIsoEleObj out_egeles[/*nObjOut*/]) const; + + void run(const std::vector &in, + std::vector &out_photons, + std::vector &out_eles) const; + + void setDebug(int verbose) { debug_ = verbose; } + + unsigned int nInputBoards() const { return nBOARDS; } + unsigned int nInputObjPerBoard() const { return nEGPerBoard; } + unsigned int nOutputObj() const { return nEGOut; } + + private: + template + void resize_input(std::vector &in) const { + if (in.size() > nEGPerBoard) { + in.resize(nEGPerBoard); + } else if (in.size() < nEGPerBoard) { + for (unsigned int i = 0, diff = (nEGPerBoard - in.size()); i < diff; ++i) { + in.push_back(T()); + in.back().clear(); + } + } + } + + template + static bool comparePt(const T &obj1, const T &obj2) { + return (obj1.hwPt > obj2.hwPt); + } + + template + void print_objects(const std::vector &objs, const std::string &label) const { + for (unsigned int i = 0; i < objs.size(); ++i) { + dbgCout() << label << " [" << i << "] pt: " << objs[i].hwPt << " eta: " << objs[i].hwEta + << " phi: " << objs[i].hwPhi << " qual: " << objs[i].hwQual.to_string(2) << std::endl; + } + } + + template + void merge_boards(const std::vector &in_board1, + const std::vector &in_board2, + std::vector &out, + unsigned int nOut) const { + // we crate a bitonic list + out = in_board1; + std::reverse(out.begin(), out.end()); + std::copy(in_board2.begin(), in_board2.end(), std::back_inserter(out)); + hybridBitonicMergeRef(&out[0], out.size(), 0, false); + + // std::merge(in_board1.begin(), in_board1.end(), in_board2_copy.begin(), in_board2_copy.end(), std::back_inserter(out), comparePt); + if (out.size() > nOut) + out.resize(nOut); + } + + template + void merge(const std::vector> &in_objs, std::vector &out) const { + if (in_objs.size() == 1) { + std::copy(in_objs[0].begin(), in_objs[0].end(), std::back_inserter(out)); + if (out.size() > nEGOut) + out.resize(nEGOut); + } else if (in_objs.size() == 2) { + merge_boards(in_objs[0], in_objs[1], out, nEGOut); + } else { + std::vector> to_merge; + for (unsigned int id = 0, idn = 1; id < in_objs.size(); id += 2, idn = id + 1) { + if (idn >= in_objs.size()) { + to_merge.push_back(in_objs[id]); + } else { + std::vector pair_merge; + merge_boards(in_objs[id], in_objs[idn], pair_merge, nEGPerBoard); + to_merge.push_back(pair_merge); + } + } + merge(to_merge, out); + } + } + + const unsigned int nBOARDS; + const unsigned int nEGPerBoard; + const unsigned int nEGOut; + int debug_; + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pfeginput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pfeginput_ref.h new file mode 100644 index 0000000000000..599eae5484522 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pfeginput_ref.h @@ -0,0 +1,56 @@ +#ifndef PFEGINPUT_REF_H +#define PFEGINPUT_REF_H + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "DataFormats/L1TParticleFlow/interface/egamma.h" +#include "DataFormats/L1TParticleFlow/interface/pf.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + struct EGInputSelectorEmuConfig { + EGInputSelectorEmuConfig(const edm::ParameterSet &iConfig); + EGInputSelectorEmuConfig(unsigned int emIdMask, unsigned int nHADCALO_IN, unsigned int nEMCALO_OUT, int debug) + : idMask(emIdMask), nHADCALO_IN(nHADCALO_IN), nEMCALO_OUT(nEMCALO_OUT), debug(debug) {} + + emid_t idMask; + unsigned int nHADCALO_IN; + unsigned int nEMCALO_OUT; + + int debug; + }; + + class EGInputSelectorEmulator { + public: + EGInputSelectorEmulator(const EGInputSelectorEmuConfig &config) : cfg(config), debug_(cfg.debug) {} + + virtual ~EGInputSelectorEmulator() {} + + void toFirmware(const PFInputRegion &in, HadCaloObj hadcalo[/*nCALO*/]) const; + void toFirmware(const std::vector &emcalo_sel, l1ct::EmCaloObj emcalo[]) const; + + void select_eginput(const l1ct::HadCaloObjEmu &in, l1ct::EmCaloObjEmu &out, bool &valid_out) const; + void select_eginputs(const std::vector &hadcalo_in, + std::vector &emcalo_sel) const; + + /// if the hadcalo passes the EM selection, do the conversion, otherwise zero-out the result + void select_or_clear(const l1ct::HadCaloObjEmu &hadcalo_in, l1ct::EmCaloObjEmu &emcalo_out) const; + + /// apply select_or_clear on all elements of the input vector + void select_or_clear(const std::vector &hadcalo_in, + std::vector &emcalo_out) const; + + // void run(const PFInputRegion &in, OutputRegion &out) const; + + void setDebug(int debug) { debug_ = debug; } + + private: + EGInputSelectorEmuConfig cfg; + int debug_; + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h new file mode 100644 index 0000000000000..b75be595ee9df --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h @@ -0,0 +1,316 @@ +#ifndef PFTKEGALGO_REF_H +#define PFTKEGALGO_REF_H + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "DataFormats/L1TParticleFlow/interface/egamma.h" +#include "DataFormats/L1TParticleFlow/interface/pf.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + struct PFTkEGAlgoEmuConfig { + unsigned int nTRACK; + unsigned int nTRACK_EGIN; + unsigned int nEMCALO_EGIN; + unsigned int nEM_EGOUT; + + bool filterHwQuality; + bool doBremRecovery; + bool writeBeforeBremRecovery; + int caloHwQual; + bool doEndcapHwQual; + float emClusterPtMin; // GeV + float dEtaMaxBrem; + float dPhiMaxBrem; + + std::vector absEtaBoundaries; + std::vector dEtaValues; + std::vector dPhiValues; + float trkQualityPtMin; // GeV + bool writeEgSta; + + struct IsoParameters { + IsoParameters(const edm::ParameterSet &); + IsoParameters(float tkQualityPtMin, float dZ, float dRMin, float dRMax) + : tkQualityPtMin(Scales::makePtFromFloat(tkQualityPtMin)), + dZ(Scales::makeZ0(dZ)), + dRMin2(Scales::makeDR2FromFloatDR(dRMin)), + dRMax2(Scales::makeDR2FromFloatDR(dRMax)) {} + pt_t tkQualityPtMin; + ap_int dZ; + int dRMin2; + int dRMax2; + }; + + IsoParameters tkIsoParams_tkEle; + IsoParameters tkIsoParams_tkEm; + IsoParameters pfIsoParams_tkEle; + IsoParameters pfIsoParams_tkEm; + bool doTkIso; + bool doPfIso; + EGIsoEleObjEmu::IsoType hwIsoTypeTkEle; + EGIsoObjEmu::IsoType hwIsoTypeTkEm; + int debug = 0; + + PFTkEGAlgoEmuConfig(const edm::ParameterSet &iConfig); + PFTkEGAlgoEmuConfig(unsigned int nTrack, + unsigned int nTrack_in, + unsigned int nEmCalo_in, + unsigned int nEmOut, + bool filterHwQuality, + bool doBremRecovery, + bool writeBeforeBremRecovery = false, + int caloHwQual = 4, + bool doEndcapHwQual = false, + float emClusterPtMin = 2., + float dEtaMaxBrem = 0.02, + float dPhiMaxBrem = 0.1, + const std::vector &absEtaBoundaries = {0.0, 1.5}, + const std::vector &dEtaValues = {0.015, 0.01}, + const std::vector &dPhiValues = {0.07, 0.07}, + float trkQualityPtMin = 10., + bool writeEgSta = false, + const IsoParameters &tkIsoParams_tkEle = {2., 0.6, 0.03, 0.2}, + const IsoParameters &tkIsoParams_tkEm = {2., 0.6, 0.07, 0.3}, + const IsoParameters &pfIsoParams_tkEle = {1., 0.6, 0.03, 0.2}, + const IsoParameters &pfIsoParams_tkEm = {1., 0.6, 0.07, 0.3}, + bool doTkIso = true, + bool doPfIso = false, + EGIsoEleObjEmu::IsoType hwIsoTypeTkEle = EGIsoEleObjEmu::IsoType::TkIso, + EGIsoObjEmu::IsoType hwIsoTypeTkEm = EGIsoObjEmu::IsoType::TkIsoPV, + int debug = 0) + + : nTRACK(nTrack), + nTRACK_EGIN(nTrack_in), + nEMCALO_EGIN(nEmCalo_in), + nEM_EGOUT(nEmOut), + filterHwQuality(filterHwQuality), + doBremRecovery(doBremRecovery), + writeBeforeBremRecovery(writeBeforeBremRecovery), + caloHwQual(caloHwQual), + doEndcapHwQual(doEndcapHwQual), + emClusterPtMin(emClusterPtMin), + dEtaMaxBrem(dEtaMaxBrem), + dPhiMaxBrem(dPhiMaxBrem), + absEtaBoundaries(absEtaBoundaries), + dEtaValues(dEtaValues), + dPhiValues(dPhiValues), + trkQualityPtMin(trkQualityPtMin), + writeEgSta(writeEgSta), + tkIsoParams_tkEle(tkIsoParams_tkEle), + tkIsoParams_tkEm(tkIsoParams_tkEm), + pfIsoParams_tkEle(pfIsoParams_tkEle), + pfIsoParams_tkEm(pfIsoParams_tkEm), + doTkIso(doTkIso), + doPfIso(doPfIso), + hwIsoTypeTkEle(hwIsoTypeTkEle), + hwIsoTypeTkEm(hwIsoTypeTkEm), + debug(debug) {} + }; + + class PFTkEGAlgoEmulator { + public: + PFTkEGAlgoEmulator(const PFTkEGAlgoEmuConfig &config) : cfg(config), debug_(cfg.debug) {} + + virtual ~PFTkEGAlgoEmulator() {} + + void toFirmware(const PFInputRegion &in, PFRegion ®ion, EmCaloObj calo[/*nCALO*/], TkObj track[/*nTRACK*/]) const; + void toFirmware(const OutputRegion &out, EGIsoObj out_egphs[], EGIsoEleObj out_egeles[]) const; + void toFirmware(const PFInputRegion &in, + const l1ct::PVObjEmu &pvin, + PFRegion ®ion, + TkObj track[/*nTRACK*/], + PVObj &pv) const; + + void run(const PFInputRegion &in, OutputRegion &out) const; + void runIso(const PFInputRegion &in, const std::vector &pvs, OutputRegion &out) const; + + void setDebug(int verbose) { debug_ = verbose; } + + bool writeEgSta() const { return cfg.writeEgSta; } + + private: + void link_emCalo2emCalo(const std::vector &emcalo, std::vector &emCalo2emCalo) const; + + void link_emCalo2tk(const PFRegionEmu &r, + const std::vector &emcalo, + const std::vector &track, + std::vector &emCalo2tk) const; + + //FIXME: still needed + float deltaPhi(float phi1, float phi2) const; + + void sel_emCalo(unsigned int nmax_sel, + const std::vector &emcalo, + std::vector &emcalo_sel) const; + + void eg_algo(const PFRegionEmu ®ion, + const std::vector &emcalo, + const std::vector &track, + const std::vector &emCalo2emCalo, + const std::vector &emCalo2tk, + std::vector &egstas, + std::vector &egobjs, + std::vector &egeleobjs) const; + + void addEgObjsToPF(std::vector &egstas, + std::vector &egobjs, + std::vector &egeleobjs, + const std::vector &emcalo, + const std::vector &track, + const int calo_idx, + const unsigned int hwQual, + const pt_t ptCorr, + const int tk_idx, + const std::vector &components = {}) const; + + EGObjEmu &addEGStaToPF(std::vector &egobjs, + const EmCaloObjEmu &calo, + const unsigned int hwQual, + const pt_t ptCorr, + const std::vector &components) const; + + EGIsoObjEmu &addEGIsoToPF(std::vector &egobjs, + const EmCaloObjEmu &calo, + const unsigned int hwQual, + const pt_t ptCorr) const; + + EGIsoEleObjEmu &addEGIsoEleToPF(std::vector &egobjs, + const EmCaloObjEmu &calo, + const TkObjEmu &track, + const unsigned int hwQual, + const pt_t ptCorr) const; + + // FIXME: reimplemented from PFAlgoEmulatorBase + template + void ptsort_ref(int nIn, int nOut, const std::vector &in, std::vector &out) const { + out.resize(nOut); + for (int iout = 0; iout < nOut; ++iout) { + out[iout].clear(); + } + for (int it = 0; it < nIn; ++it) { + for (int iout = 0; iout < nOut; ++iout) { + if (in[it].hwPt >= out[iout].hwPt) { + for (int i2 = nOut - 1; i2 > iout; --i2) { + out[i2] = out[i2 - 1]; + } + out[iout] = in[it]; + break; + } + } + } + } + + template + int deltaR2(const T &charged, const EGIsoObjEmu &egphoton) const { + // NOTE: we compare Tk at vertex against the calo variable... + return dr2_int(charged.hwVtxEta(), charged.hwVtxPhi(), egphoton.hwEta, egphoton.hwPhi); + } + + template + int deltaR2(const T &charged, const EGIsoEleObjEmu &egele) const { + return dr2_int(charged.hwVtxEta(), charged.hwVtxPhi(), egele.hwVtxEta(), egele.hwVtxPhi()); + } + + int deltaR2(const PFNeutralObjEmu &neutral, const EGIsoObjEmu &egphoton) const { + return dr2_int(neutral.hwEta, neutral.hwPhi, egphoton.hwEta, egphoton.hwPhi); + } + + int deltaR2(const PFNeutralObjEmu &neutral, const EGIsoEleObjEmu &egele) const { + // NOTE: we compare Tk at vertex against the calo variable... + return dr2_int(neutral.hwEta, neutral.hwPhi, egele.hwVtxEta(), egele.hwVtxPhi()); + } + + template + ap_int deltaZ0(const T &charged, const EGIsoObjEmu &egphoton, z0_t z0) const { + ap_int delta = charged.hwZ0 - z0; + if (delta < 0) + delta = -delta; + return delta; + } + + template + ap_int deltaZ0(const T &charged, const EGIsoEleObjEmu &egele, z0_t z0) const { + ap_int delta = charged.hwZ0 - egele.hwZ0; + if (delta < 0) + delta = -delta; + return delta; + } + + template + void compute_sumPt(iso_t &sumPt, + iso_t &sumPtPV, + const std::vector &objects, + unsigned int nMaxObj, + const TEG &egobj, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const { + for (unsigned int itk = 0; itk < std::min(objects.size(), nMaxObj); ++itk) { + const auto &obj = objects[itk]; + + if (obj.hwPt < params.tkQualityPtMin) + continue; + + int dR2 = deltaR2(obj, egobj); + + if (dR2 > params.dRMin2 && dR2 < params.dRMax2) { + sumPt += obj.hwPt; + if (deltaZ0(obj, egobj, z0) < params.dZ) { + sumPtPV += obj.hwPt; + } + } + } + } + + template + void compute_sumPt(iso_t &sumPt, + iso_t &sumPtPV, + const std::vector &objects, + unsigned int nMaxObj, + const TEG &egobj, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const { + for (unsigned int itk = 0; itk < std::min(objects.size(), nMaxObj); ++itk) { + const auto &obj = objects[itk]; + + if (obj.hwPt < params.tkQualityPtMin) + continue; + + int dR2 = deltaR2(obj, egobj); + + if (dR2 > params.dRMin2 && dR2 < params.dRMax2) { + sumPt += obj.hwPt; + // PF neutrals are not constrained by PV (since their Z0 is 0 by design) + sumPtPV += obj.hwPt; + } + } + } + + void compute_isolation(std::vector &egobjs, + const std::vector &objects, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const; + void compute_isolation(std::vector &egobjs, + const std::vector &objects, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const; + void compute_isolation(std::vector &egobjs, + const std::vector &charged, + const std::vector &neutrals, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const; + void compute_isolation(std::vector &egobjs, + const std::vector &charged, + const std::vector &neutrals, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const; + + PFTkEGAlgoEmuConfig cfg; + int debug_; + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h new file mode 100644 index 0000000000000..e0f59a04b2f31 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegsorter_ref.h @@ -0,0 +1,125 @@ +#ifndef FIRMWARE_PFTKEGSORTER_REF_H +#define FIRMWARE_PFTKEGSORTER_REF_H + +#include +#include + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#endif + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + class PFTkEGSorterEmulator { + public: + PFTkEGSorterEmulator(const unsigned int nObjToSort = 6, const unsigned int nObjSorted = 16) + : nObjToSort_(nObjToSort), nObjSorted_(nObjSorted), debug_(false) {} + +#ifdef CMSSW_GIT_HASH + PFTkEGSorterEmulator(const edm::ParameterSet& iConfig) + : PFTkEGSorterEmulator(iConfig.getParameter("nObjToSort"), + iConfig.getParameter("nObjSorted")) {} + +#endif + + ~PFTkEGSorterEmulator(){}; + + void setDebug(bool debug = true) { debug_ = debug; }; + + template + void run(const std::vector& pfregions, + const std::vector& outregions, + const std::vector& region_index, + std::vector& eg_sorted_inBoard) { + std::vector eg_unsorted_inBoard = eg_sorted_inBoard; + mergeEGObjFromRegions(pfregions, outregions, region_index, eg_unsorted_inBoard); + + if (debug_) { + dbgCout() << "\nUNSORTED\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"; + + eg_sorted_inBoard = eg_unsorted_inBoard; + std::reverse(eg_sorted_inBoard.begin(), eg_sorted_inBoard.end()); + std::stable_sort(eg_sorted_inBoard.begin(), eg_sorted_inBoard.end(), comparePt); + if (eg_sorted_inBoard.size() > nObjSorted_) + eg_sorted_inBoard.resize(nObjSorted_); + + if (debug_) { + 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"; + } + } + + private: + unsigned int nObjToSort_, nObjSorted_; + bool debug_; + + 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 + static bool comparePt(T obj1, T obj2) { + return (obj1.hwPt > obj2.hwPt); + } + + template + void mergeEGObjFromRegions(const std::vector& pfregions, + const std::vector& outregions, + const std::vector& region_index, + std::vector& eg_unsorted_inBoard) { + for (unsigned int i : region_index) { + const auto& region = pfregions[i].region; + + if (debug_) + 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++) { + 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_) + dbgCout() << "\n"; + } + } + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1PFHtEmulator.h b/L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1PFHtEmulator.h new file mode 100644 index 0000000000000..68e575e491cfa --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1PFHtEmulator.h @@ -0,0 +1,131 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_HTMHT_h +#define L1Trigger_Phase2L1ParticleFlow_HTMHT_h + +#include "DataFormats/L1TParticleFlow/interface/jets.h" +#include "DataFormats/L1TParticleFlow/interface/sums.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h" + +#ifndef CMSSW_GIT_HASH +#include "hls_math.h" +#endif + +#include +#include +#include +#include "ap_int.h" +#include "ap_fixed.h" + +namespace P2L1HTMHTEmu { + typedef l1ct::pt_t pt_t; // Type for pt/ht 1 unit = 0.25 GeV; max = 16 TeV + typedef l1ct::glbeta_t etaphi_t; // Type for eta & phi + + typedef ap_fixed<12, 3> radians_t; + typedef ap_fixed<9, 2> cossin_t; + typedef ap_fixed<16, 13> pxy_t; + + static constexpr int N_TABLE = 2048; + + // Class for intermediate variables + class PtPxPy { + public: + pt_t pt = 0.; + pxy_t px = 0.; + pxy_t py = 0.; + + PtPxPy operator+(const PtPxPy& b) const { + PtPxPy c; + c.pt = this->pt + b.pt; + c.px = this->px + b.px; + c.py = this->py + b.py; + return c; + } + }; + + namespace Scales { + const ap_fixed<12, -4> scale_degToRad = M_PI / 180.; + }; // namespace Scales + + template + void init_sinphi_table(table_T table_out[N]) { + for (int i = 0; i < N; i++) { + float x = i * (M_PI / 180.) / 2.; + table_T sin_x = std::sin(x); + table_out[i] = sin_x; + } + } + template + table_t sine_with_conversion(etaphi_t hwPhi) { + table_t sin_table[N]; + init_sinphi_table(sin_table); + table_t out = sin_table[hwPhi]; + return out; + } + + inline etaphi_t phi_cordic(pxy_t y, pxy_t x) { +#ifdef CMSSW_GIT_HASH + ap_fixed<12, 3> phi = atan2(y.to_double(), x.to_double()); // hls_math.h not available yet in CMSSW +#else + ap_fixed<12, 3> phi = hls::atan2(y, x); +#endif + ap_fixed<16, 9> etaphiscale = (float)l1ct::Scales::INTPHI_PI / M_PI; // radians to hwPhi + return phi * etaphiscale; + } + + inline PtPxPy mht_compute(l1ct::Jet jet) { + // Add an extra bit to px/py for the sign, and one additional bit to improve precision (pt_t is ap_ufixed<14, 12>) + PtPxPy v_pxpy; + + //Initialize table once + cossin_t sin_table[N_TABLE]; + init_sinphi_table(sin_table); + + cossin_t sinphi; + cossin_t cosphi; + bool sign = jet.hwPhi.sign(); + + etaphi_t hwphi = jet.hwPhi; + + // Reduce precision of hwPhi + ap_int<10> phi; + phi.V = hwphi(11, 1); + phi = (phi > 0) ? phi : (ap_int<10>)-phi; //Only store values for positive phi, pick up sign later + + sinphi = sin_table[phi]; + + sinphi = (sign > 0) ? (cossin_t)(-sign * sinphi) : sinphi; // Change sign bit if hwPt is negative, sin(-x)=-sin(x) + cosphi = sin_table[phi + 90 * 2]; //cos(x)=sin(x+90). Do nothing with sign, cos(-θ) = cos θ, + + v_pxpy.pt = jet.hwPt; + v_pxpy.py = jet.hwPt * sinphi; + v_pxpy.px = jet.hwPt * cosphi; + + return v_pxpy; + } +} // namespace P2L1HTMHTEmu + +//TODO replace with l1ct::Jet +inline l1ct::Sum htmht(std::vector jets) { + // compute jet px, py + std::vector ptpxpy; + ptpxpy.resize(jets.size()); + std::transform( + jets.begin(), jets.end(), ptpxpy.begin(), [](const l1ct::Jet& jet) { return P2L1HTMHTEmu::mht_compute(jet); }); + + // Sum pt, px, py over jets + P2L1HTMHTEmu::PtPxPy hthxhy = std::accumulate(ptpxpy.begin(), ptpxpy.end(), P2L1HTMHTEmu::PtPxPy()); + + // Compute the MHT magnitude and direction + l1ct::Sum ht; + ht.hwSumPt = hthxhy.pt; +#ifdef CMSSW_GIT_HASH + ht.hwPt = + sqrt(((hthxhy.px * hthxhy.px) + (hthxhy.py * hthxhy.py)).to_double()); // hls_math.h not available yet in CMSSW +#else + ht.hwPt = hls::sqrt(((hthxhy.px * hthxhy.px) + (hthxhy.py * hthxhy.py))); +#endif + ht.hwPhi = P2L1HTMHTEmu::phi_cordic(hthxhy.py, hthxhy.px); + return ht; +} + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h b/L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h new file mode 100644 index 0000000000000..00be9c8ee7d69 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h @@ -0,0 +1,151 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_L1SeedConePFJetEmulator_h +#define L1Trigger_Phase2L1ParticleFlow_L1SeedConePFJetEmulator_h + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "DataFormats/L1TParticleFlow/interface/jets.h" + +#include +#include +#include +#include + +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +class L1SCJetEmu { +public: + // Data types and constants used in the FPGA and FPGA-optimized functions + // This header file is also for use in the standalone FPGA-tools simulation + // and thus contains no CMSSW/EDM specific content + typedef l1ct::pt_t pt_t; + typedef l1ct::glbeta_t etaphi_t; // Type for eta & phi + typedef ap_int<13> detaphi_t; // Type for deta & dphi + typedef ap_fixed<18, 23> detaphi2_t; // Type for deta^2 & dphi^2 + typedef ap_fixed<22, 22> pt_etaphi_t; // Type for product of pt with deta & dphi + typedef l1ct::PuppiObjEmu Particle; + + class Jet : public l1ct::Jet { + public: + std::vector constituents; + }; + + L1SCJetEmu(bool debug, float coneSize, unsigned nJets); + + std::vector emulateEvent(std::vector& parts) const; + +private: + // Configuration settings + bool debug_; + float coneSize_; + unsigned nJets_; + detaphi2_t rCone2_; + + // constants for the axis update + typedef ap_ufixed<18, -2> inv_pt_t; + static constexpr int N_table_inv_pt = 1024; + inv_pt_t inv_pt_table_[N_table_inv_pt]; + + static constexpr int ceillog2(int x) { return (x <= 2) ? 1 : 1 + ceillog2((x + 1) / 2); } + + static constexpr int floorlog2(int x) { return (x < 2) ? 0 : 1 + floorlog2(x / 2); } + + template + static constexpr int pow(int x) { + return x == 0 ? 1 : B * pow(x - 1); + } + + static constexpr int pow2(int x) { return pow<2>(x); } + + /* --- + * 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. + * --- */ + template + static 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)); + } + } + + class OpPuppiObjMax { + public: + Particle operator()(Particle a, Particle b) { return a.hwPt >= b.hwPt ? a : b; } + }; + + static OpPuppiObjMax op_max; + + template + static inline float real_val_from_idx(unsigned i) { + // Treat the index as the top N bits + static constexpr int NB = ceillog2(N); // number of address bits for table + data_T x(0); + // The MSB of 1 is implicit in the table + x[x.width - 1] = 1; + // So we can use the next NB bits for real data + x(x.width - 2, x.width - NB - 1) = i; + return (float)x; + } + + template + static inline unsigned idx_from_real_val(data_T x) { + // Slice the top N bits to get an index into the table + static constexpr int NB = ceillog2(N); // number of address bits for table + // Slice the top-1 NB bits of the value + // the MSB of '1' is implicit, so only slice below that + ap_uint y = x(x.width - 2, x.width - NB - 1); + return (unsigned)y(NB - 1, 0); + } + + template + static void init_invert_table(table_T table_out[N]) { + // The template data_T is the data type used to address the table + for (unsigned i = 0; i < N; i++) { + float x = real_val_from_idx(i); + table_T inv_x = 1 / x; + table_out[i] = inv_x; + } + } + + template + static table_t invert_with_shift(const in_t in, const table_t inv_table[N], bool debug = false) { + // find the first '1' in the denominator + int msb = 0; + for (int b = 0; b < in.width; b++) { + if (in[b]) + msb = b; + } + // shift up the denominator such that the left-most bit (msb) is '1' + in_t in_shifted = in << (in.width - msb - 1); + // lookup the inverse of the shifted input + int idx = idx_from_real_val(in_shifted); + table_t inv_in = inv_table[idx]; + // shift the output back + table_t out = inv_in << (in.width - msb - 1); + if (debug) { + dbgCout() << " x " << in << ", msb = " << msb << ", shift = " << (in.width - msb) << ", idx = " << idx + << std::endl; + dbgCout() << " pre 1 / " << in_shifted << " = " << inv_in << "(" << 1 / (float)in_shifted << ")" << std::endl; + dbgCout() << " post 1 / " << in << " = " << out << "(" << 1 / (float)in << ")" << std::endl; + } + return out; + } + + static detaphi_t deltaPhi(Particle a, Particle b); + bool inCone(Particle seed, Particle part) const; + Jet makeJet_HW(const std::vector& parts) const; + +}; // class L1SCJetEmu + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/hgcalinput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/hgcalinput_ref.h new file mode 100644 index 0000000000000..aa99831c369ba --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/hgcalinput_ref.h @@ -0,0 +1,15 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_newfirmware_hgcalinput_ref_h +#define L1Trigger_Phase2L1ParticleFlow_newfirmware_hgcalinput_ref_h + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +namespace l1ct { + class HgcalClusterDecoderEmulator { + public: + HgcalClusterDecoderEmulator(){}; + ~HgcalClusterDecoderEmulator(); + l1ct::HadCaloObjEmu decode(const ap_uint<256> &in) const; + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/muonGmtToL1ct_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/muonGmtToL1ct_ref.h new file mode 100644 index 0000000000000..4d1705d1b1778 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/muonGmtToL1ct_ref.h @@ -0,0 +1,23 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_newfirmware_muonGmtToL1ct_ref_h +#define L1Trigger_Phase2L1ParticleFlow_newfirmware_muonGmtToL1ct_ref_h + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + class GMTMuonDecoderEmulator { + public: + GMTMuonDecoderEmulator(float z0Scale, float dxyScale); + GMTMuonDecoderEmulator(const edm::ParameterSet &iConfig); + ~GMTMuonDecoderEmulator(); + l1ct::MuObjEmu decode(const ap_uint<64> &in) const; + + protected: + float z0Scale_, dxyScale_; + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h new file mode 100644 index 0000000000000..585156036ca9a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h @@ -0,0 +1,225 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_l1converters_tracks_tkinput_ref_h +#define L1Trigger_Phase2L1ParticleFlow_l1converters_tracks_tkinput_ref_h + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include +#include + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + class TrackInputEmulator { + public: + enum class Region { Barrel, Endcap, Any }; // but only Endcap supported for now + + /// encoding used in the digitized track word + enum class Encoding { + Stepping, // J = sign(F) * floor(abs(F)/LSB); F = sign(J) * ( abs(J) + 0.5 ) * LSB + Biased, // J = floor(F/LSB); F = (J + 0.5)*LSB + Unbiased // J = round(F/LSB); F = J * LSB + }; + + TrackInputEmulator(const edm::ParameterSet &iConfig); + TrackInputEmulator(Region = Region::Endcap, Encoding encoding = Encoding::Stepping, bool bitwise = true); + + std::pair decodeTrack(ap_uint<96> tkword, const l1ct::PFRegionEmu §or) const { + return decodeTrack(tkword, sector, bitwise_); + } + std::pair decodeTrack(ap_uint<96> tkword, + const l1ct::PFRegionEmu §or, + bool bitwise) const; + + //== Unpackers == + static bool valid(const ap_uint<96> &tkword) { return tkword[95]; } + static bool charge(const ap_uint<96> &tkword) { return !tkword[94]; } + + static ap_int<15> signedRinv(const ap_uint<96> &tkword) { return ap_int<15>(tkword(94, 80)); } + static ap_int<12> signedZ0(const ap_uint<96> &tkword) { return ap_int<12>(tkword(47, 36)); } + static ap_int<16> signedTanl(const ap_uint<96> &tkword) { return ap_int<16>(tkword(63, 48)); } + static ap_int<12> signedPhi(const ap_uint<96> &tkword) { return ap_int<12>(tkword(79, 68)); } + + //=== Floating point conversions === + /// just unpack tanl to a float + float floatTanl(ap_int<16> tanl) const { return toFloat_(tanl) / (1 << 12); } + + /// convert track-word int tanl into float eta (at vertex) in radiants (exact) + float floatEta(ap_int<16> tanl) const; + + /// convert track-word Rinv into float pt (almost exact) + float floatPt(ap_int<15> Rinv) const; + + /// convert track-word int phi into float phi (at vertex) in radiants (exact) + float floatPhi(ap_int<12> phi) const; + + /// convert track-word int z0 into float z0 in cm (exact) + float floatZ0(ap_int<12> z0) const; + + //=== Configuration of floating point conversions + void setRinvToPtFactor(float rInvToPt) { rInvToPt_ = rInvToPt; } + void setPhiScale(float phiScale) { phiScale_ = phiScale; } + void setZ0Scale(float z0Scale) { z0Scale_ = z0Scale; } + + //=== Bitwise accurate conversions === + l1ct::pt_t convPt(ap_int<15> Rinv) const; + + /// convert track-word int tanl into eta *at vertex* in layer 1 units + l1ct::glbeta_t convEta(ap_int<16> tanl) const; + + /// convert track-word int phi into phi *at vertex* in layer 1 units + l1ct::phi_t convPhi(ap_int<12> phi) const; + + l1ct::z0_t convZ0(ap_int<12> z0) const; + + //=== Configuration for bitwise accurate conversions === + void configPt(int lutBits); + + void configEta(int lutBits, int preOffs, int shift, int postOffs, bool lutSigned, bool endcap); + + void configPhi(int bits); + + void configZ0(int bits); + + //=== Track propagation to calo (float parametrization, no rounding) === + // + // barrel DEta propagation, in layer-1 units (float parameterization, no rounding) + float floatDEtaBarrel(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const; + // barrel DPhi propagation, in layer-1 units (float parameterization, no rounding) + float floatDPhiBarrel(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const; + + void setDEtaBarrelParams(float pZ0) { dEtaBarrelParamZ0_ = pZ0; } + void setDPhiBarrelParams(float pC) { dPhiBarrelParamC_ = pC; } + + //=== Track propagation to calo (bitwise accurate) === + l1ct::tkdeta_t calcDEtaBarrel(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const; + l1ct::tkdphi_t calcDPhiBarrel(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const; + + //=== Configuration of bitwise accurate propagation to calo === + void configDEtaBarrel(int dEtaBarrelBits, int dEtaBarrelZ0PreShift, int dEtaBarrelZ0PostShift, float offs = 0); + void configDPhiBarrel(int dPhiBarrelBits, int dPhiBarrelRInvPreShift, int dPhiBarrelRInvPostShift, float offs = 0); + + // endcap DEta propagation, in layer-1 units (float parameterization, no rounding) + float floatDEtaHGCal(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const; + // endcap DPhi propagation, in layer-1 units (float parameterization, no rounding) + float floatDPhiHGCal(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const; + + void setDEtaHGCalParams(float pZ0, float pRinv2C, float pRinv2ITanl1, float pRinv2ITanl2) { + dEtaHGCalParamZ0_ = pZ0; + dEtaHGCalParamRInv2C_ = pRinv2C; + dEtaHGCalParamRInv2ITanl1_ = pRinv2ITanl1; + dEtaHGCalParamRInv2ITanl2_ = pRinv2ITanl2; + } + void setDPhiHGCalParams(float pZ0, float pC) { + dPhiHGCalParamZ0_ = pZ0; + dPhiHGCalParamC_ = pC; + } + + //=== Track propagation to calo (bitwise accurate) === + l1ct::tkdeta_t calcDEtaHGCal(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const; + l1ct::tkdphi_t calcDPhiHGCal(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const; + + //=== Configuration of bitwise accurate propagation to calo === + void configDEtaHGCal(int dEtaHGCalBits, + int dEtaHGCalZ0PreShift, + int dEtaHGCalRInvPreShift, + int dEtaHGCalLUTBits, + int dEtaHGCalLUTShift, + float offs = 0); + void configDPhiHGCal(int dPhiHGCalBits, + int dPhiHGCalZ0PreShift, + int dPhiHGCalZ0PostShift, + int dPhiHGCalRInvShift, + int dPhiHGCalTanlInvShift, + int dPhiHGCalTanlLUTBits, + float offs = 0); + + /// conservative cut to select tracks that may have |eta| > 1.25 or |calo eta| > 1.25 + static bool mayReachHGCal(ap_int<16> tanl) { return (tanl > 6000) || (tanl < -6000); } + /// conservative cut to avoid filling LUTs outside of the tracker range + static bool withinTracker(ap_int<16> tanl) { return (-25000 < tanl) && (tanl < 25000); } + /// conservative cut to avoid filling LUTs outside of the barrel range + static bool withinBarrel(ap_int<16> tanl) { return (-13000 < tanl) && (tanl < 13000); } + + void setDebug(bool debug = true) { debug_ = debug; } + + // access to bare LUTs + //const std::vector &dEtaBarrelLUT() const { return dEtaBarrelLUT_; } + //const std::vector &dPhiBarrelTanlLUT() const { return dPhiBarrelTanlLUT_; } + const std::vector &dEtaHGCalLUT() const { return dEtaHGCalLUT_; } + const std::vector &dPhiHGCalTanlLUT() const { return dPhiHGCalTanlLUT_; } + const std::vector &tanlLUT() const { return tanlLUT_; } + const std::vector &ptLUT() const { return ptLUT_; } + + protected: + // utilities + template + inline float toFloat_(ap_int signedVal) const { + float ret = signedVal.to_float(); + switch (encoding_) { + case Encoding::Stepping: + return (signedVal >= 0 ? ret + 0.5 : ret - 0.5); + case Encoding::Biased: + return ret + 0.5; + default: + return ret; + } + } + + /// Region for which the emulation is configured + Region region_; + + /// Encoding used for track word inputs + Encoding encoding_; + + /// Whether to run the bitwise accurate or floating point conversions + bool bitwise_; + + /// Main constants + float rInvToPt_, phiScale_, z0Scale_; + + /// Parameters for track propagation in floating point + float dEtaBarrelParamZ0_; + float dPhiBarrelParamC_; + + /// Parameters for track propagation in floating point + float dEtaHGCalParamZ0_, dEtaHGCalParamRInv2C_, dEtaHGCalParamRInv2ITanl1_, dEtaHGCalParamRInv2ITanl2_; + float dPhiHGCalParamZ0_, dPhiHGCalParamC_; + + // vtx phi conversion parameters + int vtxPhiMult_, vtxPhiOffsPos_, vtxPhiOffsNeg_, vtxPhiBitShift_; + + // z0 conversion parameters + int z0Mult_, z0OffsPos_, z0OffsNeg_, z0BitShift_; + + // deta parameters in barrel region + int dEtaBarrelBits_, dEtaBarrelZ0PreShift_, dEtaBarrelZ0PostShift_, dEtaBarrelOffs_, dEtaBarrelZ0_; + + // dphi parameters in barrel region + int dPhiBarrelBits_, dPhiBarrelRInvPreShift_, dPhiBarrelRInvPostShift_, dPhiBarrelOffs_, dPhiBarrelC_; + + // deta parameters in hgcal region + int dEtaHGCalBits_, dEtaHGCalZ0PreShift_, dEtaHGCalZ0_, dEtaHGCalRInvPreShift_, dEtaHGCalTanlShift_, + dEtaHGCalLUTShift_, dEtaHGCalTanlTermOffs_, dEtaHGCalTanlTermShift_, dEtaHGCalOffs_; + std::vector dEtaHGCalLUT_; + + // dphi parameters in hgcal region + int dPhiHGCalBits_, dPhiHGCalZ0PreShift_, dPhiHGCalZ0_, dPhiHGCalZ0PostShift_, dPhiHGCalRInvShift_, + dPhiHGCalTanlShift_, dPhiHGCalTanlInvShift_, dPhiHGCalPreOffs_, dPhiHGCalOffs_; + std::vector dPhiHGCalTanlLUT_; + + // tanl to eta LUT parameters + int tanlLUTPreOffs_, tanlLUTShift_, tanlLUTPostOffs_; + std::vector tanlLUT_; + bool tanlLUTSigned_; + + // Rinv to pR LUT parameters + int ptLUTShift_; + std::vector ptLUT_; + + /// enable debug printout in some metods + bool debug_; + }; +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h new file mode 100644 index 0000000000000..ee9dbc93206a7 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h @@ -0,0 +1,48 @@ +#ifndef PFALGO2HGC_REF_H +#define PFALGO2HGC_REF_H + +#include "pfalgo_common_ref.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + class PFAlgo2HGCEmulator : public PFAlgoEmulatorBase { + public: + PFAlgo2HGCEmulator(unsigned int nTrack, + unsigned int nCalo, + unsigned int nMu, + unsigned int nSelCalo, + unsigned int dR2Max_Tk_Mu, + unsigned int dR2Max_Tk_Calo, + pt_t tk_MaxInvPt_Loose, + pt_t tk_MaxInvPt_Tight) + : PFAlgoEmulatorBase( + nTrack, nCalo, nMu, nSelCalo, dR2Max_Tk_Mu, dR2Max_Tk_Calo, tk_MaxInvPt_Loose, tk_MaxInvPt_Tight) {} + + // note: this one will work only in CMSSW + PFAlgo2HGCEmulator(const edm::ParameterSet& iConfig); + + ~PFAlgo2HGCEmulator() override {} + + void run(const PFInputRegion& in, OutputRegion& out) const override; + + /// moves all objects from out.pfphoton to the beginning of out.pfneutral: nothing to do for this algo + void mergeNeutrals(OutputRegion& out) const override {} + + void toFirmware(const PFInputRegion& in, + PFRegion& region, + HadCaloObj calo[/*nCALO*/], + TkObj track[/*nTRACK*/], + MuObj mu[/*nMU*/]) const; + void toFirmware(const OutputRegion& out, + PFChargedObj outch[/*nTRACK*/], + PFNeutralObj outne[/*nSELCALO*/], + PFChargedObj outmu[/*nMU*/]) const; + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h new file mode 100644 index 0000000000000..85a1a01db572d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h @@ -0,0 +1,78 @@ +#ifndef PFALGO3_REF_H +#define PFALGO3_REF_H + +#include "pfalgo_common_ref.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + class PFAlgo3Emulator : public PFAlgoEmulatorBase { + public: + PFAlgo3Emulator(unsigned int nTrack, + unsigned int nEmCalo, + unsigned int nCalo, + unsigned int nMu, + unsigned int nPhoton, + unsigned int nSelCalo, + unsigned int nAllNeutral, + unsigned int dR2Max_Tk_Mu, + unsigned int dR2Max_Tk_Em, + unsigned int dR2Max_Em_Calo, + unsigned int dR2Max_Tk_Calo, + pt_t tk_MaxInvPt_Loose, + pt_t tk_MaxInvPt_Tight) + : PFAlgoEmulatorBase( + nTrack, nCalo, nMu, nSelCalo, dR2Max_Tk_Mu, dR2Max_Tk_Calo, tk_MaxInvPt_Loose, tk_MaxInvPt_Tight), + nEMCALO_(nEmCalo), + nPHOTON_(nPhoton), + nALLNEUTRAL_(nAllNeutral), + dR2MAX_TK_EM_(dR2Max_Tk_Em), + dR2MAX_EM_CALO_(dR2Max_Em_Calo) {} + + // note: this one will work only in CMSSW + PFAlgo3Emulator(const edm::ParameterSet& iConfig); + + ~PFAlgo3Emulator() override {} + + void run(const PFInputRegion& in, OutputRegion& out) const override; + + void toFirmware(const PFInputRegion& in, + PFRegion& region, + HadCaloObj calo[/*nCALO*/], + EmCaloObj emcalo[/*nEMCALO*/], + TkObj track[/*nTRACK*/], + MuObj mu[/*nMU*/]) const; + void toFirmware(const OutputRegion& out, + PFChargedObj outch[/*nTRACK*/], + PFNeutralObj outpho[/*nPHOTON*/], + PFNeutralObj outne[/*nSELCALO*/], + PFChargedObj outmu[/*nMU*/]) const; + + /// moves all objects from out.pfphoton to the beginning of out.pfneutral + void mergeNeutrals(OutputRegion& out) const override; + + protected: + unsigned int nEMCALO_, nPHOTON_, nALLNEUTRAL_; + unsigned int dR2MAX_TK_EM_; + unsigned int dR2MAX_EM_CALO_; + + int tk_best_match_ref(unsigned int dR2MAX, + const std::vector& calo, + const l1ct::TkObjEmu& track) const; + int em_best_match_ref(unsigned int dR2MAX, + const std::vector& calo, + const l1ct::EmCaloObjEmu& em) const; + + void pfalgo3_em_ref(const PFInputRegion& in, + const std::vector& iMu /*[nTRACK]*/, + std::vector& iEle /*[nTRACK]*/, + OutputRegion& out, + std::vector& hadcalo_out /*[nCALO]*/) const; + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_common_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_common_ref.h new file mode 100644 index 0000000000000..eacb4ee7ff178 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_common_ref.h @@ -0,0 +1,131 @@ +#ifndef PFALGO_COMMON_REF_H +#define PFALGO_COMMON_REF_H + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" +#include "pfalgo_types.h" + +#include +#include + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + class PFAlgoEmulatorBase { + public: + PFAlgoEmulatorBase(unsigned int nTrack, + unsigned int nCalo, + unsigned int nMu, + unsigned int nSelCalo, + unsigned int dR2Max_Tk_Mu, + unsigned int dR2Max_Tk_Calo, + pt_t tk_MaxInvPt_Loose, + pt_t tk_MaxInvPt_Tight) + : nTRACK_(nTrack), + nCALO_(nCalo), + nMU_(nMu), + nSELCALO_(nSelCalo), + dR2MAX_TK_MU_(dR2Max_Tk_Mu), + dR2MAX_TK_CALO_(dR2Max_Tk_Calo), + tk_MAXINVPT_LOOSE_(tk_MaxInvPt_Loose), + tk_MAXINVPT_TIGHT_(tk_MaxInvPt_Tight), + debug_(false) {} + + virtual ~PFAlgoEmulatorBase(); + + void loadPtErrBins( + unsigned int nbins, const float absetas[], const float scales[], const float offs[], bool verbose = false); + void loadPtErrBins(const edm::ParameterSet& iConfig); + + void setDebug(bool debug = true) { debug_ = debug; } + + virtual void run(const PFInputRegion& in, OutputRegion& out) const = 0; + + /// moves all objects from out.pfphoton to the beginning of out.pfneutral + virtual void mergeNeutrals(OutputRegion& out) const = 0; + + protected: + // config + unsigned int nTRACK_, nCALO_, nMU_; + unsigned int nSELCALO_; + unsigned int dR2MAX_TK_MU_; + unsigned int dR2MAX_TK_CALO_; + pt_t tk_MAXINVPT_LOOSE_, tk_MAXINVPT_TIGHT_; + + struct ptErrBin { + glbeta_t abseta; + ptErrScale_t scale; + ptErrOffs_t offs; + }; + std::vector ptErrBins_; + + bool debug_; + + // tools + template + int best_match_with_pt_ref(int dR2MAX, const COV& calo, const TkObjEmu& track, const pt_t& trackCaloPtErr) const; + + template + void ptsort_ref(int nIn, int nOut, const TV& in, TV& out) const; + + pt_t ptErr_ref(const PFRegionEmu& region, const TkObjEmu& track) const; + + void pfalgo_mu_ref(const PFInputRegion& in, OutputRegion& out, std::vector& iMu) const; + + void fillPFCand(const TkObjEmu& track, PFChargedObjEmu& pf, bool isMu, bool isEle) const; + void fillPFCand(const HadCaloObjEmu& calo, PFNeutralObjEmu& pf, bool isPhoton = false) const; + void fillPFCand(const EmCaloObjEmu& calo, PFNeutralObjEmu& pf, bool isPhoton = true) const; + }; + +} // namespace l1ct +//=== begin implementation part + +template +int l1ct::PFAlgoEmulatorBase::best_match_with_pt_ref(int dR2MAX, + const COV& calo, + const TkObjEmu& track, + const pt_t& trackCaloPtErr) const { + pt_t caloPtMin = track.hwPt - 2 * trackCaloPtErr; + if (caloPtMin < 0) + caloPtMin = 0; + float ptErr = std::max(Scales::INTPT_LSB, Scales::floatPt(trackCaloPtErr)); + ptscale_t dptscale = float(dR2MAX) / (ptErr * ptErr); + int dr2min = 0, ibest = -1; + for (int ic = 0, nCAL = calo.size(); ic < nCAL; ++ic) { + if (calo[ic].hwPt <= caloPtMin) + continue; + int dr2 = dr2_int(track.hwEta, track.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); + if (dr2 >= dR2MAX) + continue; + pt_t dpt = track.hwPt - calo[ic].hwPt; + dr2 += int((dpt * dpt) * dptscale); + if (ibest == -1 || dr2 < dr2min) { + dr2min = dr2; + ibest = ic; + } + } + return ibest; +} + +template +void l1ct::PFAlgoEmulatorBase::ptsort_ref(int nIn, int nOut, const TV& in, TV& out) const { + out.resize(nOut); + for (int iout = 0; iout < nOut; ++iout) { + out[iout].clear(); + } + for (int it = 0; it < nIn; ++it) { + for (int iout = 0; iout < nOut; ++iout) { + if (in[it].hwPt >= out[iout].hwPt) { + for (int i2 = nOut - 1; i2 > iout; --i2) { + out[i2] = out[i2 - 1]; + } + out[iout] = in[it]; + break; + } + } + } +} + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h new file mode 100644 index 0000000000000..8eec4d19ac22b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h @@ -0,0 +1,29 @@ +#ifndef PFALGODUMMY_REF_H +#define PFALGODUMMY_REF_H + +#include "pfalgo_common_ref.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + class PFAlgoDummyEmulator : public PFAlgoEmulatorBase { + public: + PFAlgoDummyEmulator(unsigned int nCalo, unsigned int nMu) : PFAlgoEmulatorBase(0, nCalo, nMu, 0, 0, 0, 0, 0) {} + + // note: this one will work only in CMSSW + PFAlgoDummyEmulator(const edm::ParameterSet& iConfig); + + ~PFAlgoDummyEmulator() override {} + + void run(const PFInputRegion& in, OutputRegion& out) const override; + + /// moves all objects from out.pfphoton to the beginning of out.pfneutral: nothing to do for this algo + void mergeNeutrals(OutputRegion& out) const override {} + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_types.h b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_types.h new file mode 100644 index 0000000000000..ae47e3f85a9cb --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_types.h @@ -0,0 +1,14 @@ +#ifndef FIRMWARE_PFALGO_TYPES_H +#define FIRMWARE_PFALGO_TYPES_H + +#include "DataFormats/L1TParticleFlow/interface/datatypes.h" + +namespace l1ct { + + typedef ap_ufixed<17, 17 - 4, AP_TRN, AP_SAT> ptscale_t; + typedef ap_ufixed<9, 1> ptErrScale_t; + typedef ap_fixed<10, 6> ptErrOffs_t; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_bits.h b/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_bits.h new file mode 100644 index 0000000000000..f1aa84e38104b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_bits.h @@ -0,0 +1,17 @@ +#ifndef FIRMWARE_LINPUPPI_BITS_H +#define FIRMWARE_LINPUPPI_BITS_H + +#define LINPUPPI_ptLSB 0.25 +#define LINPUPPI_DR2LSB 1.9e-5 +#define LINPUPPI_dzLSB 0.05 +#define LINPUPPI_pt2LSB LINPUPPI_ptLSB* LINPUPPI_ptLSB +#define LINPUPPI_pt2DR2_scale LINPUPPI_ptLSB* LINPUPPI_ptLSB / LINPUPPI_DR2LSB + +#define LINPUPPI_sum_bitShift 15 +#define LINPUPPI_x2_bits 6 // decimal bits the discriminator values +#define LINPUPPI_alpha_bits 5 // decimal bits of the alpha values +#define LINPUPPI_alphaSlope_bits 5 // decimal bits of the alphaSlope values +#define LINPUPPI_ptSlope_bits 6 // decimal bits of the ptSlope values +#define LINPUPPI_weight_bits 8 + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h new file mode 100644 index 0000000000000..dea624afd1a5a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h @@ -0,0 +1,223 @@ +#ifndef LINPUPPI_REF_H +#define LINPUPPI_REF_H + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +#include + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + class LinPuppiEmulator { + public: + enum class SortAlgo { Insertion, BitonicRUFL, BitonicHLS, Hybrid, FoldedHybrid }; + + LinPuppiEmulator(unsigned int nTrack, + unsigned int nIn, + unsigned int nOut, + unsigned int nVtx, + unsigned int dR2Min, + unsigned int dR2Max, + unsigned int iptMax, + unsigned int dzCut, + double ptSlopeNe, + double ptSlopePh, + double ptZeroNe, + double ptZeroPh, + double alphaSlope, + double alphaZero, + double alphaCrop, + double priorNe, + double priorPh, + pt_t ptCut, + unsigned int nFinalSort = 0, + SortAlgo finalSortAlgo = SortAlgo::Insertion) + : nTrack_(nTrack), + nIn_(nIn), + nOut_(nOut), + nVtx_(nVtx), + dR2Min_(dR2Min), + dR2Max_(dR2Max), + iptMax_(iptMax), + dzCut_(dzCut), + absEtaBins_(), + ptSlopeNe_(1, ptSlopeNe), + ptSlopePh_(1, ptSlopePh), + ptZeroNe_(1, ptZeroNe), + ptZeroPh_(1, ptZeroPh), + alphaSlope_(1, alphaSlope), + alphaZero_(1, alphaZero), + alphaCrop_(1, alphaCrop), + priorNe_(1, priorNe), + priorPh_(1, priorPh), + ptCut_(1, ptCut), + nFinalSort_(nFinalSort ? nFinalSort : nOut), + finalSortAlgo_(finalSortAlgo), + debug_(false), + fakePuppi_(false) {} + + LinPuppiEmulator(unsigned int nTrack, + unsigned int nIn, + unsigned int nOut, + unsigned int nVtx, + unsigned int dR2Min, + unsigned int dR2Max, + unsigned int iptMax, + unsigned int dzCut, + glbeta_t etaCut, + double ptSlopeNe_0, + double ptSlopeNe_1, + double ptSlopePh_0, + double ptSlopePh_1, + double ptZeroNe_0, + double ptZeroNe_1, + double ptZeroPh_0, + double ptZeroPh_1, + double alphaSlope_0, + double alphaSlope_1, + double alphaZero_0, + double alphaZero_1, + double alphaCrop_0, + double alphaCrop_1, + double priorNe_0, + double priorNe_1, + double priorPh_0, + double priorPh_1, + pt_t ptCut_0, + pt_t ptCut_1, + unsigned int nFinalSort = 0, + SortAlgo finalSortAlgo = SortAlgo::Insertion); + + LinPuppiEmulator(unsigned int nTrack, + unsigned int nIn, + unsigned int nOut, + unsigned int nVtx, + unsigned int dR2Min, + unsigned int dR2Max, + unsigned int iptMax, + unsigned int dzCut, + const std::vector &absEtaBins, + const std::vector &ptSlopeNe, + const std::vector &ptSlopePh, + const std::vector &ptZeroNe, + const std::vector &ptZeroPh, + const std::vector &alphaSlope, + const std::vector &alphaZero, + const std::vector &alphaCrop, + const std::vector &priorNe, + const std::vector &priorPh, + const std::vector &ptCut, + unsigned int nFinalSort, + SortAlgo finalSortAlgo) + : nTrack_(nTrack), + nIn_(nIn), + nOut_(nOut), + nVtx_(nVtx), + dR2Min_(dR2Min), + dR2Max_(dR2Max), + iptMax_(iptMax), + dzCut_(dzCut), + absEtaBins_(absEtaBins), + ptSlopeNe_(ptSlopeNe), + ptSlopePh_(ptSlopePh), + ptZeroNe_(ptZeroNe), + ptZeroPh_(ptZeroPh), + alphaSlope_(alphaSlope), + alphaZero_(alphaZero), + alphaCrop_(alphaCrop), + priorNe_(priorNe), + priorPh_(priorPh), + ptCut_(ptCut), + nFinalSort_(nFinalSort), + finalSortAlgo_(finalSortAlgo), + debug_(false), + fakePuppi_(false) {} + + LinPuppiEmulator(const edm::ParameterSet &iConfig); + + // charged + void linpuppi_chs_ref(const PFRegionEmu ®ion, + const PVObjEmu &pv, + const std::vector &pfch /*[nTrack]*/, + std::vector &outallch /*[nTrack]*/) const; + //vtx vetor + void linpuppi_chs_ref(const PFRegionEmu ®ion, + const std::vector &pv /*[nVtx]*/, + const std::vector &pfch /*[nTrack]*/, + std::vector &outallch /*[nTrack]*/) const; + + // neutrals, in the tracker + void linpuppi_flt(const PFRegionEmu ®ion, + const std::vector &track /*[nTrack]*/, + const std::vector &pv /*[nVtx]*/, + const std::vector &pfallne /*[nIn]*/, + std::vector &outallne_nocut /*[nIn]*/, + std::vector &outallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const; + void linpuppi_ref(const PFRegionEmu ®ion, + const std::vector &track /*[nTrack]*/, + const std::vector &pv /*[nVtx]*/, + const std::vector &pfallne /*[nIn]*/, + std::vector &outallne_nocut /*[nIn]*/, + std::vector &outallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const; + void linpuppi_ref(const PFRegionEmu ®ion, + const std::vector &track /*[nTrack]*/, + const std::vector &pv /*[nVtx]*/, + const std::vector &pfallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const { + std::vector outallne_nocut, outallne; + linpuppi_ref(region, track, pv, pfallne, outallne_nocut, outallne, outselne); + } + + // neutrals, forward + void fwdlinpuppi_ref(const PFRegionEmu ®ion, + const std::vector &caloin /*[nIn]*/, + std::vector &outallne_nocut /*[nIn]*/, + std::vector &outallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const; + void fwdlinpuppi_flt(const PFRegionEmu ®ion, + const std::vector &caloin /*[nIn]*/, + std::vector &outallne_nocut /*[nIn]*/, + std::vector &outallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const; + + static void puppisort_and_crop_ref(unsigned int nOutMax, + const std::vector &in, + std::vector &out, + SortAlgo algo = SortAlgo::Insertion); + + // for CMSSW + void run(const PFInputRegion &in, const std::vector &pvs, OutputRegion &out) const; + + void setDebug(bool debug = true) { debug_ = debug; } + + // instead of running Puppi, write Puppi debug information into the output Puppi candidates + void setFakePuppi(bool fakePuppi = true) { fakePuppi_ = fakePuppi; } + + protected: + unsigned int nTrack_, nIn_, nOut_, + nVtx_; // nIn_, nOut refer to the calorimeter clusters or neutral PF candidates as input and as output (after sorting) + unsigned int dR2Min_, dR2Max_, iptMax_, dzCut_; + std::vector absEtaBins_; + std::vector ptSlopeNe_, ptSlopePh_, ptZeroNe_, ptZeroPh_; + std::vector alphaSlope_, alphaZero_, alphaCrop_; + std::vector priorNe_, priorPh_; + std::vector ptCut_; + unsigned int nFinalSort_; // output after a full sort of charged + neutral + SortAlgo finalSortAlgo_; + + bool debug_; + bool fakePuppi_; + // utility + unsigned int find_ieta(const PFRegionEmu ®ion, eta_t eta) const; + std::pair sum2puppiPt_ref(uint64_t sum, pt_t pt, unsigned int ieta, bool isEM, int icand) const; + std::pair sum2puppiPt_flt(float sum, float pt, unsigned int ieta, bool isEM, int icand) const; + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.h new file mode 100644 index 0000000000000..91d36a366a1ae --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.h @@ -0,0 +1,186 @@ +#ifndef multififo_regionizer_elements_ref_h +#define multififo_regionizer_elements_ref_h + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +#include +#include +#include + +namespace l1ct { + namespace multififo_regionizer { + template + inline void shift(T& from, T& to) { + to = from; + from.clear(); + } + template + inline void pop_back(TL& from, T& to) { + assert(!from.empty()); + to = from.back(); + from.pop_back(); + } + + inline int dphi_wrap(int local_phi) { + if (local_phi > l1ct::Scales::INTPHI_PI) + local_phi -= l1ct::Scales::INTPHI_TWOPI; + else if (local_phi <= -l1ct::Scales::INTPHI_PI) + local_phi += l1ct::Scales::INTPHI_TWOPI; + return local_phi; + } + + template + inline void push_to_fifo(const T& t, int local_eta, int local_phi, std::list& fifo) { + fifo.push_front(t); + fifo.front().hwEta = local_eta; + fifo.front().hwPhi = local_phi; + } + + template + inline void maybe_push(const T& t, + const l1ct::PFRegionEmu& sector, + const l1ct::PFRegionEmu& region, + std::list& fifo, + bool useAlsoVtxCoords); + template <> + inline void maybe_push(const l1ct::TkObjEmu& t, + const l1ct::PFRegionEmu& sector, + const l1ct::PFRegionEmu& region, + std::list& fifo, + bool useAlsoVtxCoords); + + template + class RegionBuffer { + public: + RegionBuffer() : nfifos_(0) {} + void initFifos(unsigned int nfifos); + void initRegion(const l1ct::PFRegionEmu& region, bool useAlsoVtxCoords) { + region_ = region; + useAlsoVtxCoords_ = useAlsoVtxCoords; + } + void flush(); + void maybe_push(int fifo, const T& t, const l1ct::PFRegionEmu& sector); + T pop(); + + private: + unsigned int nfifos_; + bool useAlsoVtxCoords_; + l1ct::PFRegionEmu region_; + std::vector> fifos_; + std::vector, std::vector>> queues_; + + T pop_next_trivial_(); + void fifos_to_stage_(std::vector& staging_area); + void queue_to_stage_(std::vector& queue, std::vector& staging_area); + void stage_to_queue_(std::vector& staging_area, std::vector& queue); + T pop_queue_(std::vector& queue); + }; + + // forward decl for later + template + class RegionMux; + + template + class RegionBuilder { + public: + RegionBuilder() {} + RegionBuilder(unsigned int iregion, unsigned int nsort) : iregion_(iregion), sortbuffer_(nsort) {} + void push(const T& in); + void pop(RegionMux& out); + + private: + unsigned int iregion_; + std::vector sortbuffer_; + }; + + template + class RegionMux { + public: + RegionMux() : nregions_(0) {} + RegionMux(unsigned int nregions, + unsigned int nsort, + unsigned int nout, + bool streaming, + unsigned int outii = 0, + unsigned int pauseii = 0) + : nregions_(nregions), + nsort_(nsort), + nout_(nout), + outii_(outii), + pauseii_(pauseii), + streaming_(streaming), + buffer_(nregions * nsort), + iter_(0), + ireg_(nregions) { + assert(streaming ? (outii * nout >= nsort) : (nout == nsort)); + for (auto& t : buffer_) + t.clear(); + } + void push(unsigned int region, std::vector& in); + bool stream(bool newevt, std::vector& out); + + private: + unsigned int nregions_, nsort_, nout_, outii_, pauseii_; + bool streaming_; + std::vector buffer_; + unsigned int iter_, ireg_; + }; + + // out of the Regionizer since it doesn't depend on T and may be shared + struct Route { + unsigned short int sector, link, region, fifo; + Route(unsigned short int from_sector, + unsigned short int from_link, + unsigned short int to_region, + unsigned short int to_fifo) + : sector(from_sector), link(from_link), region(to_region), fifo(to_fifo) {} + }; + + template + class Regionizer { + public: + Regionizer() {} + Regionizer(unsigned int nsorted, + unsigned int nout, + bool streaming, + unsigned int outii = 0, + unsigned int pauseii = 0, + bool useAlsoVtxCoords = false); + void initSectors(const std::vector>& sectors); + void initSectors(const DetectorSector& sector); + void initRegions(const std::vector& regions); + void initRouting(const std::vector routes, bool validateRoutes = true); + + void reset() { + flush(); + nevt_ = 0; + } + + // single clock emulation + bool step(bool newEvent, const std::vector& links, std::vector& out, bool mux = true); + + // single clock emulation + bool muxonly_step(bool newEvent, bool mayFlush, const std::vector& nomux_out, std::vector& out); + + void destream(int iclock, const std::vector& streams, std::vector& out); + + private: + unsigned int nsectors_, nregions_, nsorted_, nout_, outii_, pauseii_; + bool streaming_, useAlsoVtxCoords_; + std::vector sectors_; + std::vector> buffers_; + std::vector> builders_; + RegionMux bigmux_; + std::vector routes_; + unsigned int nevt_; + + void flush() { + for (auto& b : buffers_) + b.flush(); + } + }; + + } // namespace multififo_regionizer +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.icc new file mode 100644 index 0000000000000..e4feaef449d5a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.icc @@ -0,0 +1,395 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +template +void l1ct::multififo_regionizer::maybe_push(const T& t, + const l1ct::PFRegionEmu& sector, + const l1ct::PFRegionEmu& region, + std::list& fifo, + bool /*useAlsoVtxCoords*/) { + int local_eta = sector.hwGlbEtaOf(t).to_int() - region.hwEtaCenter.to_int(); + int local_phi = dphi_wrap(sector.hwGlbPhiOf(t).to_int() - region.hwPhiCenter.to_int()); + if (region.isInside(local_eta, local_phi)) { + push_to_fifo(t, local_eta, local_phi, fifo); + } +} +template <> +void l1ct::multififo_regionizer::maybe_push(const l1ct::TkObjEmu& t, + const l1ct::PFRegionEmu& sector, + const l1ct::PFRegionEmu& region, + std::list& fifo, + bool useAlsoVtxCoords) { + int local_eta_c = sector.hwGlbEtaOf(t).to_int() - region.hwEtaCenter.to_int(); + int local_phi_c = dphi_wrap(sector.hwGlbPhiOf(t).to_int() - region.hwPhiCenter.to_int()); + int local_eta_v = sector.hwGlbEta(t.hwVtxEta()).to_int() - region.hwEtaCenter.to_int(); + int local_phi_v = dphi_wrap(sector.hwGlbPhi(t.hwVtxPhi()).to_int() - region.hwPhiCenter.to_int()); + if (region.isInside(local_eta_c, local_phi_c) || (useAlsoVtxCoords && region.isInside(local_eta_v, local_phi_v))) { + push_to_fifo(t, local_eta_c, local_phi_c, fifo); + /* printf(" pushed track pT %6d eta %+5d phi %+5d from sector eta %+5d phi %+5d to region eta %+5d phi %+5d\n", + t.intPt(), t.intEta(), t.intPhi(), + sector.intEtaCenter(), sector.intPhiCenter(), + region.intEtaCenter(), region.intPhiCenter()); + } else { + printf(" drop track pT %6d eta %+5d phi %+5d from sector eta %+5d phi %+5d to region eta %+5d phi %+5d\n", + t.intPt(), t.intEta(), t.intPhi(), + sector.intEtaCenter(), sector.intPhiCenter(), + region.intEtaCenter(), region.intPhiCenter()); + + */ + } +} + +template +void l1ct::multififo_regionizer::RegionBuffer::initFifos(unsigned int nfifos) { + assert(nfifos_ == 0); + nfifos_ = nfifos; + fifos_.resize(nfifos); + unsigned int nmerged = nfifos; + while (nmerged > 3) { + assert(nmerged % 2 == 0); + nmerged /= 2; + queues_.emplace_back(std::vector(nmerged), std::vector(nmerged)); + for (auto& t : queues_.back().first) + t.clear(); + for (auto& t : queues_.back().second) + t.clear(); + } + if (!(nfifos == 1 || nfifos == 2 || nfifos == 3 || nfifos == 4 || nfifos == 6 || nfifos == 8 || nfifos == 12)) { + dbgCerr() << "Error, created regionizer for nfifos == " << nfifos << ", not supported." << std::endl; + } + assert(nfifos == 1 || nfifos == 2 || nfifos == 3 || nfifos == 4 || nfifos == 6 || nfifos == 8 || nfifos == 12); +} + +template +void l1ct::multififo_regionizer::RegionBuffer::flush() { + for (auto& f : fifos_) + f.clear(); + for (auto& p : queues_) { + for (auto& t : p.first) + t.clear(); + for (auto& t : p.second) + t.clear(); + } +} + +template +void l1ct::multififo_regionizer::RegionBuffer::maybe_push(int fifo, const T& t, const l1ct::PFRegionEmu& sector) { + if (t.hwPt != 0) + l1ct::multififo_regionizer::maybe_push(t, sector, region_, fifos_[fifo], useAlsoVtxCoords_); +} + +template +T l1ct::multififo_regionizer::RegionBuffer::pop() { + if (nfifos_ <= 3) + return pop_next_trivial_(); + assert(!queues_.empty()); + for (unsigned int istep = 0, nsteps = queues_.size(); istep < nsteps; ++istep) { + if (istep == 0) + fifos_to_stage_(queues_.front().first); + else + queue_to_stage_(queues_[istep - 1].second, queues_[istep].first); + stage_to_queue_(queues_[istep].first, queues_[istep].second); + } + return pop_queue_(queues_.back().second); +} + +template +T l1ct::multififo_regionizer::RegionBuffer::pop_next_trivial_() { + T ret; + ret.clear(); + for (unsigned int j = 0; j < nfifos_; ++j) { + if (!fifos_[j].empty()) { + pop_back(fifos_[j], ret); + break; + } + } + return ret; +} + +template +void l1ct::multififo_regionizer::RegionBuffer::fifos_to_stage_(std::vector& staging_area) { + assert(staging_area.size() * 2 == nfifos_); + // shift data from each pair of fifos to the staging area + for (unsigned int j = 0; j < nfifos_ / 2; ++j) { + if (staging_area[j].hwPt != 0) + continue; + for (unsigned int i = 2 * j; i <= 2 * j + 1; ++i) { + if (!fifos_[i].empty()) { + pop_back(fifos_[i], staging_area[j]); + break; + } + } + } +} + +template +void l1ct::multififo_regionizer::RegionBuffer::queue_to_stage_(std::vector& queue, std::vector& staging_area) { + assert(staging_area.size() * 2 == queue.size()); + // shift data from each pair of fifos to the staging area + for (unsigned int j = 0, n = staging_area.size(); j < n; ++j) { + if (staging_area[j].hwPt != 0) + continue; + for (unsigned int i = 2 * j; i <= 2 * j + 1; ++i) { + if (queue[i].hwPt != 0) { + shift(queue[i], staging_area[j]); + break; + } + } + } +} + +template +void l1ct::multififo_regionizer::RegionBuffer::stage_to_queue_(std::vector& staging_area, std::vector& queue) { + assert(staging_area.size() == queue.size()); + // then from staging area to queue + for (unsigned int j = 0, n = staging_area.size(); j < n; ++j) { + if (staging_area[j].hwPt != 0 && queue[j].hwPt == 0) { + shift(staging_area[j], queue[j]); + } + } +} + +template +T l1ct::multififo_regionizer::RegionBuffer::pop_queue_(std::vector& queue) { + T ret; + ret.clear(); + for (T& t : queue) { + if (t.hwPt != 0) { + ret = t; + t.clear(); + break; + } + } + return ret; +} + +template +void l1ct::multififo_regionizer::RegionBuilder::push(const T& in) { + unsigned int i = 0, nsort = sortbuffer_.size(); + T work = in; + while (i < nsort && in.hwPt <= sortbuffer_[i].hwPt) + i++; + while (i < nsort) { + std::swap(work, sortbuffer_[i]); + i++; + } +} + +template +void l1ct::multififo_regionizer::RegionBuilder::pop(RegionMux& out) { + out.push(iregion_, sortbuffer_); +} + +template +void l1ct::multififo_regionizer::RegionMux::push(unsigned int region, std::vector& in) { + assert(nregions_ > 0); + assert(region < nregions_); + assert(in.size() == nsort_); + for (unsigned int i = 0, n = in.size(); i < n; ++i) { + shift(in[i], buffer_[region * nsort_ + i]); + } +} + +template +bool l1ct::multififo_regionizer::RegionMux::stream(bool newevt, std::vector& out) { + assert(out.size() == nout_); + if (newevt) { + iter_ = 0; + ireg_ = 0; + } + if (ireg_ < nregions_) { + if (!streaming_) { + for (unsigned int i = 0; i < nout_; ++i) { + out[i] = buffer_[ireg_ * nsort_ + i]; + } + } else { + for (unsigned int i = 0, j = 0; i < nout_; ++i, j += outii_) { + if (j < nsort_) { + out[i] = buffer_[ireg_ * nsort_ + j]; + } else { + out[i].clear(); + } + } + for (unsigned int i = 1; i < nsort_; ++i) { + shift(buffer_[ireg_ * nsort_ + i], buffer_[ireg_ * nsort_ + i - 1]); + } + } + if (iter_ >= outii_) { + assert(pauseii_ > 0); + for (unsigned int i = 0; i < nout_; ++i) { + out[i].clear(); + } + } + if (++iter_ >= (outii_ + pauseii_)) { + ireg_++; + iter_ = 0; + } + return true; + } else { + for (unsigned int i = 0; i < nout_; ++i) { + out[i].clear(); + } + return false; + } +} + +template +l1ct::multififo_regionizer::Regionizer::Regionizer(unsigned int nsorted, + unsigned int nout, + bool streaming, + unsigned int outii, + unsigned int pauseii, + bool useAlsoVtxCoords) + : nsectors_(0), + nregions_(0), + nsorted_(nsorted), + nout_(nout), + outii_(outii), + pauseii_(pauseii), + streaming_(streaming), + useAlsoVtxCoords_(useAlsoVtxCoords), + nevt_(0) {} + +template +void l1ct::multififo_regionizer::Regionizer::initSectors(const std::vector>& sectors) { + assert(nsectors_ == 0); + nsectors_ = sectors.size(); + sectors_.resize(nsectors_); + for (unsigned int i = 0; i < nsectors_; ++i) { + sectors_[i] = sectors[i].region; + } +} + +template +void l1ct::multififo_regionizer::Regionizer::initSectors(const DetectorSector& sector) { + assert(nsectors_ == 0); + nsectors_ = 1; + sectors_.resize(1, sector.region); +} + +template +void l1ct::multififo_regionizer::Regionizer::initRegions(const std::vector& regions) { + assert(nregions_ == 0); + unsigned int nregions = regions.size(); + nregions_ = nregions; + // buffers and builders + buffers_.resize(nregions); + builders_.resize(nregions); + for (unsigned int i = 0; i < nregions; ++i) { + buffers_[i].initRegion(regions[i].region, useAlsoVtxCoords_); + builders_[i] = RegionBuilder(i, nsorted_); + } + // bigmux + bigmux_ = RegionMux(nregions, nsorted_, nout_, streaming_, outii_, pauseii_); +} + +template +void l1ct::multififo_regionizer::Regionizer::initRouting(const std::vector routes, bool validateRoutes) { + assert(nregions_ > 0 && routes_.empty()); + routes_ = routes; + std::vector nfifos(nregions_, 0); + for (const auto& r : routes) { + assert(r.region < nregions_); + nfifos[r.region] = std::max(nfifos[r.region], r.fifo + 1); + } + for (unsigned int i = 0; i < nregions_; ++i) { + buffers_[i].initFifos(nfifos[i]); + } + + if (validateRoutes) { + std::vector> routed(nregions_); + for (unsigned int i = 0; i < nregions_; ++i) { + routed[i].reserve(nfifos[i]); + for (unsigned int j = 0; j < nfifos[i]; ++j) { + routed[i].emplace_back(0, 0, nregions_, 0); + } + } + for (const auto& r : routes) { + if (routed[r.region][r.fifo].region != nregions_) { + dbgPrintf("ERROR: duplicate route: %u,%u -> %u,%u and %u,%u -> %u,%u\n", + routed[r.region][r.fifo].sector, + routed[r.region][r.fifo].link, + routed[r.region][r.fifo].region, + routed[r.region][r.fifo].fifo, + r.sector, + r.link, + r.region, + r.fifo); + } + routed[r.region][r.fifo] = r; + } + for (unsigned int i = 0; i < nregions_; ++i) { + for (unsigned int j = 0; j < nfifos[i]; ++j) { + if (routed[i][j].region == nregions_) { + dbgPrintf("ERROR: missing route to %u,%u\n", i, j); + } + } + } + } +} + +template +bool l1ct::multififo_regionizer::Regionizer::step(bool newEvent, + const std::vector& links, + std::vector& out, + bool mux) { + if (newEvent) { + flush(); + nevt_++; + } + unsigned int nlinks_sector = links.size() / nsectors_; + for (const auto& r : routes_) { + unsigned int index = nlinks_sector * r.sector + r.link; + //printf("processing route (%2u,%2u)[%2u] -> (%2u,%u)\n", r.sector, r.link, index, r.region, r.fifo); + buffers_[r.region].maybe_push(r.fifo, links[index], sectors_[r.sector]); + } + out.resize(nregions_); + for (unsigned int i = 0; i < nregions_; ++i) { + out[i] = buffers_[i].pop(); + } + if (mux) { + std::vector work; + std::swap(work, out); + return muxonly_step(newEvent, /*flush=*/false, work, out); // don't flush twice + } else { + return true; + } +} + +template +bool l1ct::multififo_regionizer::Regionizer::muxonly_step(bool newEvent, + bool mayFlush, + const std::vector& nomux_out, + std::vector& out) { + if (newEvent && mayFlush) { + flush(); + nevt_++; + } + assert(nomux_out.size() == nregions_); + out.resize(nout_); + for (unsigned int i = 0; i < nregions_; ++i) { + if (newEvent) + builders_[i].pop(bigmux_); + builders_[i].push(nomux_out[i]); + } + return bigmux_.stream(newEvent && (nevt_ > 1), out); +} + +template +void l1ct::multififo_regionizer::Regionizer::destream(int iclock, + const std::vector& streams, + std::vector& out) { + assert(streaming_ && outii_ > 0); + assert(streams.size() == nout_); + unsigned int local_clk = iclock % (outii_ + pauseii_); + if (local_clk == 0) { + out.resize(nsorted_); + for (auto& o : out) + o.clear(); + } + for (unsigned int i = 0, j = local_clk; j < nsorted_; ++i, j += outii_) { + if (local_clk < outii_) + out[j] = streams[i]; + else + out[j].clear(); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h new file mode 100644 index 0000000000000..63aad616bc3b0 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h @@ -0,0 +1,121 @@ +#ifndef multififo_regionizer_ref_h +#define multififo_regionizer_ref_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.h" +#include + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + class EGInputSelectorEmulator; + struct EGInputSelectorEmuConfig; +} // namespace l1ct + +namespace l1ct { + class MultififoRegionizerEmulator : public RegionizerEmulator { + public: + MultififoRegionizerEmulator(unsigned int nendcaps, + unsigned int nclocks, + unsigned int ntk, + unsigned int ncalo, + unsigned int nem, + unsigned int nmu, + bool streaming, + unsigned int outii, + bool useAlsoVtxCoords); + + enum class BarrelSetup { Full54, Full27, Central18, Central9, Phi18, Phi9 }; + MultififoRegionizerEmulator(BarrelSetup barrelSetup, + unsigned int nHCalLinks, + unsigned int nECalLinks, + 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); + + // note: this one will work only in CMSSW + MultififoRegionizerEmulator(const edm::ParameterSet& iConfig); + + ~MultififoRegionizerEmulator() 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, + std::vector& out, + bool mux = true); + bool step(bool newEvent, + const std::vector& links, + std::vector& out, + bool mux = true); + bool step(bool newEvent, + const std::vector& links, + std::vector& out, + bool mux = true); + bool step(bool newEvent, + const std::vector& links, + std::vector& out, + bool mux = true); + 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); + void destream(int iclock, + const std::vector& tk_out, + const std::vector& em_out, + const std::vector& calo_out, + const std::vector& mu_out, + 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); + + // convert links to firmware + void toFirmware(const std::vector& emu, TkObj fw[/*NTK_SECTORS*NTK_LINKS*/]); + void toFirmware(const std::vector& emu, HadCaloObj fw[/*NCALO_SECTORS*NCALO_LINKS*/]); + void toFirmware(const std::vector& emu, EmCaloObj fw[/*NCALO_SECTORS*NCALO_LINKS*/]); + void toFirmware(const std::vector& emu, MuObj fw[/*NMU_LINKS*/]); + + 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; + unsigned int nendcaps_, nclocks_, ntk_, ncalo_, nem_, nmu_, outii_, pauseii_, nregions_; + bool streaming_; + enum EmInterceptMode { noIntercept = 0, interceptPreFifo, interceptPostFifo } emInterceptMode_; + std::unique_ptr interceptor_; + bool init_; + + multififo_regionizer::Regionizer tkRegionizer_; + multififo_regionizer::Regionizer hadCaloRegionizer_; + multififo_regionizer::Regionizer emCaloRegionizer_; + multififo_regionizer::Regionizer muRegionizer_; + std::vector tkRoutes_, caloRoutes_, emCaloRoutes_, muRoutes_; + + template + void fillCaloLinks_(unsigned int iclock, const std::vector>& in, std::vector& links); + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h new file mode 100644 index 0000000000000..5ae375d54f819 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h @@ -0,0 +1,30 @@ +#ifndef REGIONIZER_BASE_REF_H +#define REGIONIZER_BASE_REF_H + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + + class RegionizerEmulator { + public: + RegionizerEmulator(bool useAlsoVtxCoords = true) : useAlsoVtxCoords_(useAlsoVtxCoords), debug_(false) {} + RegionizerEmulator(const edm::ParameterSet& iConfig); + + virtual ~RegionizerEmulator(); + + void setDebug(bool debug = true) { debug_ = debug; } + + virtual void initSectorsAndRegions(const RegionizerDecodedInputs& in, const std::vector& out) {} + virtual void run(const RegionizerDecodedInputs& in, std::vector& out); + + protected: + bool useAlsoVtxCoords_; + bool debug_; + }; + +} // namespace l1ct +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h new file mode 100644 index 0000000000000..ae76062083fea --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h @@ -0,0 +1,210 @@ +#ifndef tdr_regionizer_elements_ref_h +#define tdr_regionizer_elements_ref_h + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +#include +#include +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" +#else +#include "../../utils/dbgPrintf.h" +#endif + +namespace l1ct { + namespace tdr_regionizer { + + inline int dphi_wrap(int local_phi) { + if (local_phi > l1ct::Scales::INTPHI_PI) + local_phi -= l1ct::Scales::INTPHI_TWOPI; + else if (local_phi <= -l1ct::Scales::INTPHI_PI) + local_phi += l1ct::Scales::INTPHI_TWOPI; + return local_phi; + } + + struct RegionInfo { + RegionInfo(unsigned int idx, int regphi, int regeta) : index(idx), phi(regphi), eta(regeta) {} + unsigned int index; + int phi; + int eta; + }; + + inline bool sortRegionInfo(RegionInfo& a, RegionInfo& b) { + if (a.phi < b.phi) + return true; + if (a.phi > b.phi) + return false; + if (a.eta < b.eta) + return true; + if (a.eta > b.eta) + return false; + return false; + } + + template + class PipeObject { + public: + PipeObject() {} + PipeObject(const T& obj, + unsigned int phiindex, + unsigned int etaindex, + bool phioverlap, + bool etaoverlap, + int glbphi, + int glbeta, + unsigned int clk); + + const unsigned int getClock() { return linkobjclk_; } + void setClock(unsigned int clock) { linkobjclk_ = clock; } + const unsigned int getPhi() { return phiindex_; } + const unsigned int getEta() { return etaindex_; } + const bool getPhiOverlap() { return phioverlap_; } + const bool getEtaOverlap() { return etaoverlap_; } + const unsigned int getCount() { return objcount_; } + unsigned int getCountAndInc() { return objcount_++; } + void incCount() { objcount_++; } + const int getPt() { return obj_.hwPt.to_int(); } + const int getGlbPhi() { return glbphi_; } + const int getGlbEta() { return glbeta_; } + + T getObj() { return obj_; } + + private: + T obj_; + unsigned int phiindex_, etaindex_; + bool phioverlap_, etaoverlap_; + int glbphi_, glbeta_; + unsigned int linkobjclk_, objcount_; + }; + + template + class Pipe { + public: + Pipe(unsigned int nphi = 9) : clkindex_(0), nphi_(nphi) {} + + void addObj( + T obj, unsigned int phiindex, unsigned int etaindex, bool phioverlap, bool etaoverlap, int glbphi, int glbeta); + PipeObject& getObj(unsigned int index) { return data_[index]; } + T getRawObj(unsigned int index) { return data_[index].getObj(); } + + unsigned int getClock(unsigned int index = 0) { return getObj(index).getClock(); } + void setClock(unsigned int clock, unsigned int index = 0) { return getObj(index).setClock(clock); } + unsigned int getPhi(unsigned int index = 0) { return getObj(index).getPhi(); } + unsigned int getEta(unsigned int index = 0) { return getObj(index).getEta(); } + bool getPhiOverlap(unsigned int index = 0) { return getObj(index).getPhiOverlap(); } + bool getEtaOverlap(unsigned int index = 0) { return getObj(index).getEtaOverlap(); } + unsigned int getCount(unsigned int index = 0) { return getObj(index).getCount(); } + unsigned int getCountAndInc(unsigned int index = 0) { return getObj(index).getCountAndInc(); } + void incCount(unsigned int index = 0) { getObj(index).incCount(); } + void erase(unsigned int index = 0) { data_.erase(data_.begin() + index); } + int getPt(unsigned int index = 0) { return getObj(index).getPt(); } + int getGlbPhi(unsigned int index = 0) { return getObj(index).getGlbPhi(); } + int getGlbEta(unsigned int index = 0) { return getObj(index).getGlbEta(); } + + int getClosedIndexForObject(unsigned int index = 0); + int getPipeIndexForObject(unsigned int index = 0); + + unsigned int getSize() { return data_.size(); } + + void reset() { + clkindex_ = 0; + data_.clear(); + } + + private: + unsigned int clkindex_, nphi_; + std::vector> data_; + }; + + template + class Regionizer { + public: + Regionizer() {} + Regionizer( + unsigned int neta, unsigned int nregions, unsigned int maxobjects, int etaoffset, int etawidth, int nclocks); + void initSectors(const std::vector>& sectors); + void initSectors(const DetectorSector& sector); + void initRegions(const std::vector& regions); + + unsigned int getSize() { return pipes_.size(); } + unsigned int getPipeSize(unsigned int index) { return getPipe(index).getSize(); } + + bool setIndicesOverlaps(const T& obj, + unsigned int& phiindex, + unsigned int& etaindex, + bool& phioverlap, + bool& etaoverlap, + int& glbphi, + int& glbeta, + unsigned int index); + + void addToPipe(const T& obj, unsigned int index); + void setPipe(const std::vector& objvec, unsigned int index); + void setPipes(const std::vector>& objvecvec); + Pipe& getPipe(unsigned int index) { return pipes_[index]; } + + int getPipeTime(int linkIndex, int linkTimeOfObject, int linkAlgoClockRunningTime); + int popLinkObject(int linkIndex, int currentTimeOfObject); + int timeNextFromIndex(unsigned int index, int time) { return getPipeTime(index, pipes_[index].getClock(), time); } + + void initTimes(); + + int getClosedIndexForObject(unsigned int linknum, unsigned int index = 0) { + return pipes_[linknum].getClosedIndexForObject(index); + } + int getPipeIndexForObject(unsigned int linknum, unsigned int index = 0) { + return pipes_[linknum].getPipeIndexForObject(index); + } + void addToSmallRegion(unsigned int linkNum, unsigned int index = 0); + + void run(bool debug = false); + + void reset(); + + std::vector getSmallRegion(unsigned int index); + + void printDebug(int count) { + dbgCout() << count << "\tindex\tpt\teta\tphi" << std::endl; + dbgCout() << "PIPES" << std::endl; + for (unsigned int i = 0; i < getSize(); i++) { + for (unsigned int j = 0; j < getPipeSize(i); j++) { + dbgCout() << "\t" << i << " " << j << "\t" << getPipe(i).getPt(j) << "\t" << getPipe(i).getGlbEta(j) << "\t" + << getPipe(i).getGlbPhi(j) << std::endl; + } + dbgCout() << "-------------------------------" << std::endl; + } + dbgCout() << "SMALL REGIONS" << std::endl; + for (unsigned int i = 0; i < nregions_; i++) { + for (unsigned int j = 0; j < smallRegionObjects_[i].size(); j++) { + dbgCout() << "\t" << i << " " << j << "\t" << smallRegionObjects_[i][j].hwPt.to_int() << "\t" + << smallRegionObjects_[i][j].hwEta.to_int() + regionmap_[i].eta << "\t" + << smallRegionObjects_[i][j].hwPhi.to_int() + regionmap_[i].phi << std::endl; + } + dbgCout() << "-------------------------------" << std::endl; + } + dbgCout() << "TIMES" << std::endl; + for (unsigned int i = 0; i < timeOfNextObject_.size(); i++) { + dbgCout() << " " << timeOfNextObject_[i]; + } + dbgCout() << "\n-------------------------------" << std::endl; + } + + private: + unsigned int neta_, nregions_, maxobjects_, nsectors_; + int etaoffset_, etawidth_, nclocks_; + std::vector sectors_; + std::vector regions_; + std::vector regionmap_; + + std::vector> pipes_; + std::vector timeOfNextObject_; + std::vector> smallRegionObjects_; //keep count to see if small region is full + }; + + } // namespace tdr_regionizer +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc new file mode 100644 index 0000000000000..98d16a95c61cc --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc @@ -0,0 +1,325 @@ +template +l1ct::tdr_regionizer::PipeObject::PipeObject(const T& obj, + unsigned int phiindex, + unsigned int etaindex, + bool phioverlap, + bool etaoverlap, + int glbphi, + int glbeta, + unsigned int clk) + : obj_(obj), + phiindex_(phiindex), + etaindex_(etaindex), + phioverlap_(phioverlap), + etaoverlap_(etaoverlap), + glbphi_(glbphi), + glbeta_(glbeta), + linkobjclk_(clk) { + objcount_ = 0; +} + +template +void l1ct::tdr_regionizer::Pipe::addObj( + T obj, unsigned int phiindex, unsigned int etaindex, bool phioverlap, bool etaoverlap, int glbphi, int glbeta) { + data_.emplace_back(PipeObject(obj, phiindex, etaindex, phioverlap, etaoverlap, glbphi, glbeta, clkindex_++)); +} +//explicit for tracker to handle clocking +template <> +inline void l1ct::tdr_regionizer::Pipe::addObj(l1ct::TkObjEmu obj, + unsigned int phiindex, + unsigned int etaindex, + bool phioverlap, + bool etaoverlap, + int glbphi, + int glbeta) { + data_.emplace_back( + PipeObject(obj, phiindex, etaindex, phioverlap, etaoverlap, glbphi, glbeta, clkindex_++)); + if (clkindex_ % 3 == 2) + clkindex_++; //this is for tracker, could I get this generically maybe? +} + +template +int l1ct::tdr_regionizer::Pipe::getClosedIndexForObject(unsigned int index) { + switch (getCount(index)) { + case 0: + return getPhi(index) * 2 + getEta(index); + case 1: + if (getPhiOverlap(index) && !getEtaOverlap(index)) + return ((getPhi(index) + 1) % nphi_) * 2 + getEta(index); + else //eta overlap, or 4-small-region overlap + return getPhi(index) * 2 + getEta(index) + 1; + case 2: + return ((getPhi(index) + 1) % nphi_) * 2 + getEta(index); + case 3: + return ((getPhi(index) + 1) % nphi_) * 2 + getEta(index) + 1; + default: + dbgCout() << "Impossible object count!" << std::endl; + exit(0); + } +} + +template +int l1ct::tdr_regionizer::Pipe::getPipeIndexForObject(unsigned int index) { + switch (getCount(index)) { + case 0: + return getPhi(index); + case 1: + if (getPhiOverlap(index) && !getEtaOverlap(index)) + return (getPhi(index) + 1) % nphi_; + else + return getPhi(index); + case 2: + case 3: + return (getPhi(index) + 1) % nphi_; + default: + dbgCout() << "Impossible object count!" << std::endl; + exit(0); + } +} + +template +l1ct::tdr_regionizer::Regionizer::Regionizer( + unsigned int neta, unsigned int nregions, unsigned int maxobjects, int etaoffset, int etawidth, int nclocks) + : neta_(neta), + nregions_(nregions), + maxobjects_(maxobjects), + nsectors_(0), + etaoffset_(etaoffset), + etawidth_(etawidth), + nclocks_(nclocks) { + smallRegionObjects_.resize(nregions); +} + +template +void l1ct::tdr_regionizer::Regionizer::initSectors(const std::vector>& sectors) { + assert(nsectors_ == 0); + nsectors_ = sectors.size(); + sectors_.resize(nsectors_); + pipes_.resize(nsectors_); + for (unsigned int i = 0; i < nsectors_; ++i) { + sectors_[i] = sectors[i].region; + } +} + +template +void l1ct::tdr_regionizer::Regionizer::initSectors(const DetectorSector& sector) { + assert(nsectors_ == 0); + nsectors_ = 1; + sectors_.resize(1, sector.region); + pipes_.resize(nsectors_); +} + +template +void l1ct::tdr_regionizer::Regionizer::initRegions(const std::vector& regions) { + regions_.resize(regions.size()); + regionmap_.clear(); + for (unsigned int i = 0; i < regions.size(); ++i) { + regions_[i] = regions[i].region; + if (etaoffset_ - etawidth_ <= regions_[i].intEtaCenter() && regions_[i].intEtaCenter() < etaoffset_ + etawidth_) { + regionmap_.emplace_back(i, regions_[i].intPhiCenter(), regions_[i].intEtaCenter()); + } + } + assert(regionmap_.size() == nregions_); + std::sort(regionmap_.begin(), regionmap_.end(), sortRegionInfo); +} + +template +bool l1ct::tdr_regionizer::Regionizer::setIndicesOverlaps(const T& obj, + unsigned int& phiindex, + unsigned int& etaindex, + bool& phioverlap, + bool& etaoverlap, + int& glbphi, + int& glbeta, + unsigned int index) { + glbphi = sectors_[index].hwGlbPhiOf(obj).to_int(); + glbeta = sectors_[index].hwGlbEtaOf(obj).to_int(); + phiindex = nregions_; + etaindex = nregions_; + phioverlap = false; + etaoverlap = false; + bool isset = false; + for (unsigned int i = 0; i < nregions_; i++) { + int regphi = dphi_wrap(glbphi - regionmap_[i].phi); + int regeta = glbeta - regionmap_[i].eta; + + if (regions_[regionmap_[i].index].isInside(regeta, regphi)) { + if (isset) { + if (i / neta_ != phiindex) + phioverlap = true; + if (i % neta_ != etaindex) + etaoverlap = true; + } + if (i / neta_ < phiindex || (i > (nregions_ - neta_) && phiindex == 0)) { + phiindex = i / neta_; + } + if (i % neta_ < etaindex) { + etaindex = i % neta_; + isset = true; //only need to check eta to set since there is full coverage in each board in phi + } + } + } + if (isset && etaindex == 1 && etaoverlap) { + etaoverlap = false; + } + return isset; +} + +template +void l1ct::tdr_regionizer::Regionizer::addToPipe(const T& obj, unsigned int index) { + assert(index < getSize()); + unsigned int phiindex, etaindex; + bool phioverlap, etaoverlap; + int glbphi, glbeta; + bool isset = setIndicesOverlaps(obj, phiindex, etaindex, phioverlap, etaoverlap, glbphi, glbeta, index); + if (isset) { + pipes_[index].addObj(obj, phiindex, etaindex, phioverlap, etaoverlap, glbphi, glbeta); + } +} + +template +void l1ct::tdr_regionizer::Regionizer::setPipe(const std::vector& objvec, unsigned int index) { + assert(index < getSize()); + pipes_[index].reset(); + for (unsigned int i = 0; i < objvec.size(); i++) { + addToPipe(objvec[i], index); + } +} + +template +void l1ct::tdr_regionizer::Regionizer::setPipes(const std::vector>& objvecvec) { + assert(getSize() == objvecvec.size()); + for (unsigned int i = 0; i < getSize(); i++) { + setPipe(objvecvec[i], i); + } +} + +template +int l1ct::tdr_regionizer::Regionizer::getPipeTime(int linkIndex, + int linkTimeOfObject, + int linkAlgoClockRunningTime) { + const int LINK_TO_ALGO_CLK_OFFSET = 2; //13; // in units of algo clock + int linkObjectArrival = (nsectors_ - 1 - linkIndex) + LINK_TO_ALGO_CLK_OFFSET + linkTimeOfObject; + + return (linkAlgoClockRunningTime < 0 || linkObjectArrival > linkAlgoClockRunningTime + 4) + ? linkObjectArrival + : (linkAlgoClockRunningTime + 4); +} + +template +int l1ct::tdr_regionizer::Regionizer::popLinkObject(int linkIndex, int currentTimeOfObject) { + pipes_[linkIndex].incCount(); + + //determine which object is next and at what time + unsigned int countToBeDone = 1; + if (pipes_[linkIndex].getPhiOverlap() && pipes_[linkIndex].getEtaOverlap()) + countToBeDone = 4; + else if (pipes_[linkIndex].getPhiOverlap() || pipes_[linkIndex].getEtaOverlap()) + countToBeDone = 2; + + if (countToBeDone == pipes_[linkIndex].getCount()) { + //pop off leading object, done with it + pipes_[linkIndex].erase(); + + //get time of next object + if (pipes_[linkIndex].getSize()) + return getPipeTime(linkIndex, pipes_[linkIndex].getClock(), currentTimeOfObject); + else //no more objects on link + return -1; + } else { + //increment time for next overlapped object on this link + return currentTimeOfObject + 1; + } +} + +template +void l1ct::tdr_regionizer::Regionizer::initTimes() { + for (unsigned int l = 0; l < getSize(); ++l) { + if (getPipeSize(l)) { + timeOfNextObject_.push_back(timeNextFromIndex(l, -1)); + } else { + timeOfNextObject_.push_back(-1); + } + } +} + +template +void l1ct::tdr_regionizer::Regionizer::addToSmallRegion(unsigned int linkNum, unsigned int index) { + T theobj = pipes_[linkNum].getRawObj(index); + unsigned int regind = getClosedIndexForObject(linkNum); + theobj.hwPhi = dphi_wrap(pipes_[linkNum].getGlbPhi(index) - regionmap_[regind].phi); + theobj.hwEta = pipes_[linkNum].getGlbEta(index) - regionmap_[regind].eta; + smallRegionObjects_[regind].push_back(theobj); +} + +template +void l1ct::tdr_regionizer::Regionizer::run(bool debug) { + unsigned int loopCount = 0; + if (debug) + printDebug(loopCount); + while (loopCount < 972) { //this is the max allowable if nothing ever blocks + //init min time, pipe, and link index + // to find the target pipe currently with action + int minp = -1; + int minl = -1; + int minTime = 0; + + //do pipe-full handling + for (unsigned int l = 0; l < getSize(); ++l) { + if (timeOfNextObject_[l] >= 0 && smallRegionObjects_[getClosedIndexForObject(l)].size() == maxobjects_) { + //pipe is full so proceed to next object + //'remove' the selected object from its link + timeOfNextObject_[l] = popLinkObject(l, timeOfNextObject_[l]); + } //end pipe-full handling loop + } + + //do find object handling + for (unsigned int l = 0; l < getSize(); ++l) { + if (timeOfNextObject_[l] >= 0 && (minl == -1 || timeOfNextObject_[l] < minTime)) { + //found new 'selected' link object and pipe + minp = getPipeIndexForObject(l); + minTime = timeOfNextObject_[l]; + minl = l; + } else if (getPipeSize(l) && minl >= 0 && minp == getPipeIndexForObject(l) && timeOfNextObject_[l] == minTime) { + //have pipe conflict, so need to wait a clock + ++timeOfNextObject_[l]; + } + } + + if (minl < 0) + break; //exit case + + //'put' object in small region + addToSmallRegion(minl); + + //'remove' the selected object from its link + int nextTime = popLinkObject(minl, timeOfNextObject_[minl]); + if (nextTime > nclocks_) + break; + timeOfNextObject_[minl] = nextTime; + ++loopCount; + } //end main loop + + if (debug) + printDebug(loopCount); +} + +template +void l1ct::tdr_regionizer::Regionizer::reset() { + for (unsigned int i = 0; i < getSize(); i++) { + pipes_[i].reset(); + } + timeOfNextObject_.clear(); + for (unsigned int i = 0; i < nregions_; i++) { + smallRegionObjects_[i].clear(); + } +} + +template +std::vector l1ct::tdr_regionizer::Regionizer::getSmallRegion(unsigned int index) { + for (unsigned int i = 0; i < nregions_; i++) { + if (regionmap_[i].index == index) + return smallRegionObjects_[i]; + } + return {}; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h new file mode 100644 index 0000000000000..f9a4bc693f31e --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h @@ -0,0 +1,67 @@ +#ifndef tdr_regionizer_ref_h +#define tdr_regionizer_ref_h + +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h" + +namespace edm { + class ParameterSet; +} + +namespace l1ct { + class TDRRegionizerEmulator : public RegionizerEmulator { + public: + TDRRegionizerEmulator(unsigned int netaslices, + unsigned int ntk, + unsigned int ncalo, + unsigned int nem, + unsigned int nmu, + int nclocks, + bool dosort); + + // note: this one will work only in CMSSW + TDRRegionizerEmulator(const edm::ParameterSet& iConfig); + + ~TDRRegionizerEmulator() override; + + static const int NTK_SECTORS = 9, NTK_LINKS = 2; // max objects per sector per clock cycle + static const int NCALO_SECTORS = 4, NCALO_LINKS = 4; + static const int NEMCALO_SECTORS = 4, NEMCALO_LINKS = 4; + static const int NMU_LINKS = 2; + static const int MAX_TK_EVT = 108, MAX_EMCALO_EVT = 162, MAX_CALO_EVT = 162, + MAX_MU_EVT = 162; //all at TMUX 6, per link + //assuming 96b for tracks, 64b for emcalo, calo, mu + static const int NUMBER_OF_SMALL_REGIONS = 18; + static const int NETA_SMALL = 2; + + void initSectorsAndRegions(const RegionizerDecodedInputs& in, const std::vector& out) override; + + // TODO: implement + void run(const RegionizerDecodedInputs& in, std::vector& out) override; + + // link emulation from decoded inputs (for simulation) + void fillLinks(const RegionizerDecodedInputs& in, std::vector>& links); + void fillLinks(const RegionizerDecodedInputs& in, std::vector>& links); + void fillLinks(const RegionizerDecodedInputs& in, std::vector>& links); + void fillLinks(const RegionizerDecodedInputs& in, std::vector>& links); + + // convert links to firmware + void toFirmware(const std::vector& emu, TkObj fw[NTK_SECTORS][NTK_LINKS]); + void toFirmware(const std::vector& emu, HadCaloObj fw[NCALO_SECTORS][NCALO_LINKS]); + void toFirmware(const std::vector& emu, EmCaloObj fw[NCALO_SECTORS][NCALO_LINKS]); + void toFirmware(const std::vector& emu, MuObj fw[NMU_LINKS]); + + private: + unsigned int netaslices_, ntk_, ncalo_, nem_, nmu_, nregions_; + int nclocks_; + bool dosort_, init_; + + std::vector> tkRegionizers_; + std::vector> hadCaloRegionizers_; + std::vector> emCaloRegionizers_; + std::vector> muRegionizers_; + }; + +} // namespace l1ct + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/TauNNIdHW.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/TauNNIdHW.h new file mode 100644 index 0000000000000..159aa476d8077 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/TauNNIdHW.h @@ -0,0 +1,168 @@ +#ifndef L1Trigger_Phase2L1ParticleFlow_TAUNNIDHW_H_ +#define L1Trigger_Phase2L1ParticleFlow_TAUNNIDHW_H_ + +#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h" + +#include +#include +#include "ap_int.h" +#include "ap_fixed.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/tau_parameters.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_layer.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_activation.h" + +//hls-fpga-machine-learning insert weights +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w1.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b1.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w2.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b2.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w3.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b3.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w4.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b4.h" + +typedef ap_ufixed<16, 14> pt_t; +typedef ap_fixed<10, 4> etaphi_t; + +namespace L1TauEmu { + // Data types and constants used in the FPGA and FPGA-optimized functions + //etaphi_base maps physical eta phi units onto bits + //This way, the least significant bit of etaphi_t is exactly 0.01 + //Even though 0.01 is not a power of 2 + static float etaphi_base = 100. / 64; + static float z0_base = 0.05; + static float dxy_base = 0.05; + typedef ap_ufixed<16, 14> pt_t; // 1 unit = 0.25 GeV; + typedef ap_fixed<10, 4> etaphi_t; // 1 unit = 0.01; + typedef ap_fixed<12, 6> detaphi_t; // type for the difference between etas or phis + typedef ap_fixed<18, 9> detaphi2_t; // type for detaphi_t squared + typedef ap_fixed<22, 16> pt_etaphi_t; // type for product of pt with deta or phi + typedef ap_int<8> dxy_t; + typedef ap_int<10> z0_t; + typedef ap_uint<5> count_t; // type for multiplicity + typedef ap_uint<5> id_t; // type for multiplicity + + // constants for the axis update + typedef ap_ufixed<18, -2> inv_pt_t; + static constexpr int N_table_inv_pt = 1024; + static const detaphi_t TWOPI = 3.14159 * 2. * etaphi_base; + static const detaphi_t PI = 3.14159 * etaphi_base; + static const detaphi_t HALFPI = 3.14159 / 2 * etaphi_base; + static const detaphi_t RCONE = 0.4 * 100 / 128; + static const detaphi_t R2CONE = RCONE * RCONE; + // + static const etaphi_t FIDUCIAL_ETA_PHI = 5.11 * etaphi_base; + + constexpr int ceillog2(int x) { return (x <= 2) ? 1 : 1 + ceillog2((x + 1) / 2); } + constexpr int floorlog2(int x) { return (x < 2) ? 0 : 1 + floorlog2(x / 2); } + constexpr int pow2(int x) { return x == 0 ? 1 : 2 * pow2(x - 1); } + + template + inline float real_val_from_idx(unsigned i) { + // Treat the index as the top N bits + static constexpr int NB = ceillog2(N); // number of address bits for table + data_T x(0); + // The MSB of 1 is implicit in the table + x[x.width - 1] = 1; + // So we can use the next NB bits for real data + x(x.width - 2, x.width - NB - 1) = i; + return (float)x; + } + + template + inline unsigned idx_from_real_val(data_T x) { + // Slice the top N bits to get an index into the table + static constexpr int NB = ceillog2(N); // number of address bits for table + // Slice the top-1 NB bits of the value + // the MSB of '1' is implicit, so only slice below that + ap_uint y = x(x.width - 2, x.width - NB - 1); + return (unsigned)y(NB - 1, 0); + } + + template + void init_invert_table(table_T table_out[N]) { + // The template data_T is the data type used to address the table + for (unsigned i = 0; i < N; i++) { + float x = real_val_from_idx(i); + table_T inv_x = 1 / x; + table_out[i] = inv_x; + } + } + + template + table_t invert_with_shift(in_t in, bool debug = false) { + table_t inv_table[N]; + init_invert_table(inv_table); + + // find the first '1' in the denominator + int msb = 0; + for (int b = 0; b < in.width; b++) { + if (in[b]) + msb = b; + } + // shift up the denominator such that the left-most bit (msb) is '1' + in_t in_shifted = in << (in.width - msb - 1); + // lookup the inverse of the shifted input + int idx = idx_from_real_val(in_shifted); + table_t inv_in = inv_table[idx]; + // shift the output back + table_t out = inv_in << (in.width - msb - 1); + + return out; + } + + inline detaphi_t deltaPhi(l1t::PFCandidate a, l1t::PFCandidate b) { + // scale the particle eta, phi to hardware units + etaphi_t aphi = etaphi_t(a.phi() * etaphi_base); + etaphi_t bphi = etaphi_t(b.phi() * etaphi_base); + detaphi_t dphi = detaphi_t(aphi) - detaphi_t(bphi); + // phi wrap + detaphi_t dphi0 = + dphi > detaphi_t(l1ct::Scales::INTPHI_PI) ? detaphi_t(l1ct::Scales::INTPHI_TWOPI - dphi) : detaphi_t(dphi); + detaphi_t dphi1 = + dphi < detaphi_t(-l1ct::Scales::INTPHI_PI) ? detaphi_t(l1ct::Scales::INTPHI_TWOPI + dphi) : detaphi_t(dphi); + //dphi > PI ? detaphi_t(TWOPI - dphi) : detaphi_t(dphi); + //dphi < -PI ? detaphi_t(TWOPI + dphi) : detaphi_t(dphi); + detaphi_t dphiw = dphi > detaphi_t(0) ? dphi0 : dphi1; + return dphiw; + } + + inline bool inCone(l1t::PFCandidate seed, l1t::PFCandidate part, detaphi_t cone2) { + // scale the particle eta, phi to hardware units + etaphi_t seta = etaphi_t(seed.eta() * etaphi_base); + etaphi_t peta = etaphi_t(part.eta() * etaphi_base); + detaphi_t deta = detaphi_t(seta) - detaphi_t(peta); + detaphi_t dphi = deltaPhi(seed, part); + bool ret = (deta * deta + dphi * dphi) < cone2; + return ret; + } + +}; // namespace L1TauEmu + +class TauNNIdHW { +public: + TauNNIdHW(); + ~TauNNIdHW(); + + void initialize(const std::string &iName, int iNParticles); + void SetNNVectorVar(); + result_t EvaluateNN(); + result_t compute(const l1t::PFCandidate &iSeed, std::vector &iParts); + //void print(); + + std::string fInput_; + unsigned fNParticles_; + unique_ptr fPt_; + unique_ptr fEta_; + unique_ptr fPhi_; + unique_ptr fId_; + //FILE *file_; + +private: + std::vector NNvectorVar_; +}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/tau_parameters.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/tau_parameters.h new file mode 100644 index 0000000000000..c6344e19f7c52 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/tau_parameters.h @@ -0,0 +1,100 @@ +#ifndef PARAMETERS_H_ +#define PARAMETERS_H_ + +#include +#include "ap_int.h" +#include "ap_fixed.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_layer.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_activation.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/nnet_common.h" + +//hls-fpga-machine-learning insert numbers +#define N_INPUTS 80 +#define N_LAYER_1 25 +#define N_LAYER_2 10 +#define N_LAYER_3 10 +#define N_OUTPUTS 1 + +//hls-fpga-machine-learning insert layer-precision + +typedef ap_fixed<24, 12> input2_t; +typedef ap_fixed<16, 8> input_t; +typedef ap_fixed<16, 8> layer1_t; +typedef ap_fixed<16, 8> layer2_t; +typedef ap_fixed<16, 8> layer3_t; +typedef ap_fixed<16, 8> result_t; +typedef ap_fixed<16, 8> accum_default_t; +typedef ap_fixed<16, 8> weight_default_t; +typedef ap_fixed<16, 8> bias_default_t; + +//hls-fpga-machine-learning insert layer-config +struct config1 : nnet::layer_config { + static const unsigned n_in = N_INPUTS; + static const unsigned n_out = N_LAYER_1; + static const unsigned io_type = nnet::io_parallel; + static const unsigned reuse_factor = 1; + //static const unsigned reuse_factor = 6; + static const unsigned n_zeros = 0; + static const bool store_weights_in_bram = false; + typedef accum_default_t accum_t; + typedef bias_default_t bias_t; + typedef weight_default_t weight_t; +}; +struct relu_config1 : nnet::activ_config { + static const unsigned n_in = N_LAYER_1; + static const unsigned table_size = 1024; + static const unsigned io_type = nnet::io_parallel; +}; +struct config2 : nnet::layer_config { + static const unsigned n_in = N_LAYER_1; + static const unsigned n_out = N_LAYER_2; + static const unsigned io_type = nnet::io_parallel; + static const unsigned reuse_factor = 1; + //static const unsigned reuse_factor = 6; + static const unsigned n_zeros = 0; + static const bool store_weights_in_bram = false; + typedef accum_default_t accum_t; + typedef bias_default_t bias_t; + typedef weight_default_t weight_t; +}; +struct relu_config2 : nnet::activ_config { + static const unsigned n_in = N_LAYER_2; + static const unsigned table_size = 1024; + static const unsigned io_type = nnet::io_parallel; +}; +struct config3 : nnet::layer_config { + static const unsigned n_in = N_LAYER_2; + static const unsigned n_out = N_LAYER_3; + static const unsigned io_type = nnet::io_parallel; + static const unsigned reuse_factor = 1; + //static const unsigned reuse_factor = 6; + static const unsigned n_zeros = 0; + static const bool store_weights_in_bram = false; + typedef accum_default_t accum_t; + typedef bias_default_t bias_t; + typedef weight_default_t weight_t; +}; +struct relu_config3 : nnet::activ_config { + static const unsigned n_in = N_LAYER_3; + static const unsigned table_size = 1024; + static const unsigned io_type = nnet::io_parallel; +}; +struct config4 : nnet::layer_config { + static const unsigned n_in = N_LAYER_3; + static const unsigned n_out = N_OUTPUTS; + static const unsigned io_type = nnet::io_parallel; + static const unsigned reuse_factor = 1; + //static const unsigned reuse_factor = 6; + static const unsigned n_zeros = 0; + static const bool store_weights_in_bram = false; + typedef accum_default_t accum_t; + typedef bias_default_t bias_t; + typedef weight_default_t weight_t; +}; +struct sigmoid_config4 : nnet::activ_config { + static const unsigned n_in = N_OUTPUTS; + static const unsigned table_size = 1024; + static const unsigned io_type = nnet::io_parallel; +}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b1.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b1.h new file mode 100644 index 0000000000000..055cdca44f47b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b1.h @@ -0,0 +1,15 @@ +//Numpy array shape [25] +//Min -1.101188778877 +//Max 1.014160394669 +//Number of zeros 2 + +#ifndef B1_H_ +#define B1_H_ + +weight_default_t b1[25] = {0.8776568174, -0.0888396949, -0.1198173761, -0.0066847582, -0.0117284302, + -0.0283335019, 0.0000000000, -1.1011887789, -0.0135271018, -0.0323914811, + 0.5437909961, -0.0175916012, 0.5357875228, -0.3656347692, 0.2423969060, + 1.0141603947, 0.0000000000, -0.7741876245, 0.9614976048, 0.5918464661, + -0.3908625543, -0.2043008506, -0.3004969060, -0.1039064825, 0.5963121057}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b2.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b2.h new file mode 100644 index 0000000000000..89fbfedcc9606 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b2.h @@ -0,0 +1,20 @@ +//Numpy array shape [10] +//Min -0.819882214069 +//Max 0.973487198353 +//Number of zeros 0 + +#ifndef B2_H_ +#define B2_H_ + +weight_default_t b2[10] = {-0.8198822141, + 0.7516837120, + 0.6504452229, + -0.0292063691, + -0.0308178961, + 0.9734871984, + 0.1587447226, + -0.3352679014, + -0.0403082110, + 0.9563522935}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b3.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b3.h new file mode 100644 index 0000000000000..685f2119739f9 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b3.h @@ -0,0 +1,20 @@ +//Numpy array shape [10] +//Min -0.128828719258 +//Max 1.138555169106 +//Number of zeros 0 + +#ifndef B3_H_ +#define B3_H_ + +weight_default_t b3[10] = {1.0009469986, + -0.0118703200, + 0.5378767252, + 0.6056469083, + -0.0177963823, + 0.3281430006, + -0.0163392760, + 1.1385551691, + -0.1288287193, + 0.5457931757}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b4.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b4.h new file mode 100644 index 0000000000000..f6bfeb3075407 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/b4.h @@ -0,0 +1,11 @@ +//Numpy array shape [1] +//Min -0.572278082371 +//Max -0.572278082371 +//Number of zeros 0 + +#ifndef B4_H_ +#define B4_H_ + +weight_default_t b4[1] = {-0.5722780824}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w1.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w1.h new file mode 100644 index 0000000000000..36336cfbc1bb0 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w1.h @@ -0,0 +1,296 @@ +//Numpy array shape [80, 25] +//Min -3.289977788925 +//Max 3.700143098831 +//Number of zeros 0 + +#ifndef W1_H_ +#define W1_H_ + +weight_default_t w1[2000] = { + -0.0275631975, 0.1840968430, 0.0017615402, -0.0511833914, -0.0200780518, -0.0042256247, -0.0364550948, + 0.0384720340, -0.0489867255, -0.0225831568, -0.0905258134, -0.0269556697, 0.0101243807, 0.1125041321, + 0.0465865135, 0.0026750101, -0.0463647135, 0.0408502258, 0.0250505060, 0.0417109914, 0.1548669636, + 0.0711558312, 0.1098393202, -0.0506406687, -0.0291560069, -0.6492317319, 0.2198102921, 0.1887888014, + 0.0349061787, -0.0283092018, -1.0081952810, -0.0272938609, 1.0008006096, 0.0338130370, -0.0007302842, + -0.0617842078, -0.0273153540, -0.3009278476, -0.6890239120, -0.2352750599, 0.3157918751, 0.0302133597, + 0.5854118466, -0.6246618629, -0.2802330554, 0.0929862931, -0.8329776525, 1.2516969442, -0.6786904931, + -0.1535482258, -0.7423998713, 0.4872898161, 0.5682671666, 0.0370868929, -0.0022424087, -0.1562964022, + -0.0046133399, -0.1033513546, 0.0123399999, -0.0044850325, -0.2373198271, -0.0159488562, 0.0260351524, + 0.3955667615, 0.2467150390, 0.4625576437, -0.0292643905, -0.7233461738, 0.2747081518, -0.1658903807, + 0.7204536200, 0.8856796622, 0.5151911974, 0.3123708665, 0.1316079199, 0.5885148048, 0.0295058079, + 0.4927506149, 0.0299622882, -0.0262605082, -1.0056939125, -0.0008065328, -1.3022788763, 0.0055024284, + -0.0289485976, 0.2242033482, 0.0042681322, 0.5684482455, -0.3274582922, 0.2859292626, 1.1116024256, + 0.0214838646, -0.6427668929, 0.7815344334, 0.1261892021, 0.2290971130, -1.2223799229, -0.4961220622, + 1.0111559629, 0.6050338745, 0.5045208931, 0.2650687695, -0.7037590146, 0.0297495946, 0.0222873390, + 0.6111736894, 0.0005295388, -0.5739755630, 0.0052538514, -0.0307949428, -0.1104973704, 0.0296904631, + 0.5579725504, -0.1175562739, 0.4259014130, -0.1541411281, 0.0119326226, -0.6764405966, 0.9869034290, + 0.3535545766, 0.0040392140, 0.1765626371, -0.4597047269, -0.6800388098, 0.3780533969, -0.8040967584, + -0.6617923379, -0.7268909812, 0.0169448685, -0.0069919117, 0.8752303720, -0.0284540299, 0.4849638045, + 0.0029829517, -0.0327314287, -0.1543710381, -0.0053135268, -0.2826291621, 0.1962907910, -0.0196111575, + -0.9708192945, 0.0061271563, 0.4227552414, -0.8056537509, -0.5267382264, -1.0296963453, -0.3315088451, + -0.0536016747, -0.1942309588, -0.3144842982, 0.5679528117, -1.9735404253, 0.9347930551, -0.0300587546, + -0.0339946374, -0.7351798415, -0.0418845899, -0.1872052401, -0.0383353606, -0.0133074354, 1.1689522266, + 0.0359998457, 0.3681480289, 0.0382503718, 0.4525004029, 0.7792146206, -0.0130382665, -0.2055867761, + -2.0509274006, 0.8194679022, -1.9078072309, -0.0428799093, -0.3958085477, -0.3275701106, 0.6287524104, + 0.4016268849, 0.3687422872, -0.9715765119, -0.0442459360, -0.0036972165, 0.8315604329, -0.0365467891, + -0.2349074483, 0.0066335849, -0.0011842133, -0.0949637517, 0.0012807772, -0.1491129249, -0.2132425010, + -0.4479730725, 0.3647912443, -0.0349627361, -0.1971846074, 0.8265561461, 0.1157044247, 0.4788555801, + 0.5409259200, 0.4084890485, -0.3301912248, -0.1015564576, 0.0552721694, -0.1001074612, 0.0117295543, + -0.0081389183, -0.0320042521, 0.1011462882, 0.0058988929, -0.0258922745, -0.0222880021, -0.0649969801, + 0.1800477803, -0.0160458256, 0.0775651112, -0.0058082407, 0.1404013932, 0.0138113825, -0.0076866262, + 0.0423264354, -0.0252220053, -0.0024362383, 0.1017613336, -0.1683959067, -0.0741082877, 0.1154814586, + 0.0737652481, -0.0575968660, 0.0525054187, 0.3668349385, -0.0134584792, -0.0107941143, -0.0590788126, + -0.0428394340, 0.1588237137, 0.0307290424, 0.0128393173, 0.0514947511, -0.0478221104, 0.0371550396, + -0.2819215953, 0.3036379218, -0.2870236635, -0.0292269941, 0.1646602750, 0.2382705659, 0.2441869527, + 0.1541452259, -0.4535261393, 0.7680447102, -0.4386458099, -0.2863874733, 0.2696151137, 0.1384935081, + 0.3358684182, 0.0214936174, -0.0302639008, -0.4491205513, 0.0185948946, -0.6768887639, 0.0131031843, + 0.0409274511, -0.3085698485, 0.0321140029, 0.0778901279, -0.3827026486, 0.6066994071, -0.0433584340, + 0.0426415466, -0.5007877350, -0.3528825939, 0.6109297276, -0.0108267041, 0.2303432971, -0.1687270403, + 0.2333775014, -0.1115449220, 0.3741680384, -0.2567584515, 0.5571648479, -0.0433077328, 0.0437150858, + 0.0754363760, 0.0162365548, -1.0052497387, -0.0245950222, 0.0104747498, 0.1608157903, -0.0057357922, + 0.2024615258, 0.2402681261, 0.0871868879, 0.2321397513, 0.0325985588, 0.2439140677, 0.1481058747, + 0.0567306653, -0.3911590278, -0.2595056295, -0.0403101370, 0.6333256960, 0.4113848507, 0.6748535037, + -1.2513297796, -0.7839609385, 0.0329567418, -0.0024726763, -0.1283916235, 0.0336718298, -0.0657793283, + -0.0131994374, -0.0059115877, -0.2056767642, 0.0290575884, -0.4871744812, -0.7013683319, -0.8681734204, + -0.5431044102, -0.0054946318, -0.4296252728, -0.5223876834, 0.3792691529, -0.4847563803, 0.5626786351, + 0.5225822330, -1.0988533497, -0.5452597141, -0.4102534056, 0.1492930502, -1.1875908375, -0.0405668244, + 0.0112952217, -1.0899050236, 0.0220720507, 1.0389884710, -0.0009252541, -0.0136074265, -0.4482565820, + -0.0367560871, 0.5741182566, 0.1035321355, 1.0542180538, -0.9191005826, -0.0282482989, 0.9454858899, + -0.7347041965, -0.7605232000, -2.1308665276, -0.0733887479, 0.4966790676, -0.3489643931, 0.3535223007, + 0.2120424807, 0.0650976971, 0.7401156425, -0.0076716733, -0.0485326760, 0.2756471336, -0.0225947145, + -0.7769182920, 0.0330444016, -0.0061788419, -0.3183784783, 0.0289460383, 0.1563081443, 0.0019258521, + 0.0561595149, 0.2160817832, 0.0098051056, -0.5246943235, 1.1672511101, 0.0638373643, -0.5476062298, + -0.3600058556, -0.4550855160, 0.8063696623, 0.1595083326, -0.4357669950, -0.7297945619, -0.8471348882, + 0.0006241986, -0.0226010084, 0.4875481427, 0.0267590918, 0.5019536018, 0.0281460695, -0.0385978222, + 0.2667064071, 0.0006921819, -0.2500030696, 0.6910701394, -0.3940408528, -0.2922672033, -0.0233109239, + 0.0973728672, -0.4336659908, -0.7539330125, -0.7263449430, 0.7418795824, 0.6334456205, -0.8008428812, + -0.3402410150, -0.0469207838, -0.1598144323, 0.0065430230, 0.0235820860, -0.0462826975, -0.0961134136, + -0.0456765778, 0.1207541078, 0.0114686005, 0.0099800816, 0.0039214366, -0.0475820675, -0.0156605877, + -0.2458557189, 0.0061893822, -0.0153258415, 0.0390211679, 0.0085149910, -0.0563477352, 0.0585263297, + 0.1308556795, 0.0291182809, -0.0494102761, -0.0279191844, 0.0002100755, 0.5546772480, -0.2250652909, + -0.5960002542, 0.0368660912, 0.0351069830, -1.0457959175, -0.0193158034, -0.0687266514, 0.0294584874, + 0.0304741058, -0.6063022017, 0.0479554087, 0.3543168604, -0.1647543758, 0.4151002765, 0.5927023292, + 0.0369217135, 0.1877718866, -0.4108899236, -0.8684850931, -0.0650646091, -0.5334713459, 0.3685727119, + -0.0024711322, 0.3164618611, 0.3290246427, 0.3174677789, 0.5689647198, 0.0119487131, -0.0017232411, + 0.1511385888, -0.0245076306, -0.2573692799, 0.0345959328, -0.0144945998, -0.3072093129, 0.0377629474, + 0.2019411772, -0.0135241337, 0.7739552855, -0.0872047544, -0.0106268898, -0.2725397050, -0.1122459993, + 0.3538818359, 0.2059551775, 0.5403658748, -0.1154610962, -0.4107205868, 0.4160876274, 0.0399494767, + -0.3815422058, 0.4317961633, -0.0273265708, -0.0011414662, -0.4350538254, -0.0436208844, 0.0784541443, + -0.0078072771, -0.0214462057, -0.5320805311, -0.0219098926, -0.5725433230, -0.2413637787, -1.2555998564, + -0.1182860062, -0.0321678072, 0.4499124289, 0.1929507703, 0.1390888542, -0.1651152074, 0.0169600658, + 0.0079317233, 0.4918144941, -0.4162785411, 0.1136433110, -0.7038186789, -0.4256927967, -0.0443868265, + 0.0119067803, 0.6235798001, 0.0439075939, -0.1331029534, -0.0209721494, -0.0101545481, -0.5826767683, + 0.0016922839, 0.0107500199, 0.6613684297, 0.0096620312, -0.8467749953, -0.0212519523, -0.2839061916, + 0.0088990871, -0.3103987575, -0.0481924191, 0.2750563025, 0.7255851626, 0.0206207428, -0.1890642494, + -0.9130650163, -0.3930812180, -0.1302175373, 0.0280487537, -0.0232239123, -0.4841814637, 0.0483692400, + 0.9080810547, -0.0317223892, -0.0076600569, -0.9822427034, -0.0170758255, 0.1477649659, 0.1290871054, + -0.4550983310, -0.4435813427, 0.0177123286, 0.6803352237, -0.1834562719, -1.1524848938, -1.0398877859, + -0.4649286866, 0.4694361389, 0.3323754072, -0.1144977063, 0.4595791698, 0.0876737237, 0.8537898660, + -0.0482646413, 0.0048400983, -0.7586640716, 0.0464481227, -0.5925642252, -0.0411571264, -0.0424648672, + -0.1133467332, 0.0350278206, -0.4751182497, -0.5563073158, -0.1296347231, 0.0313198157, -0.0102985613, + 0.1861536503, 0.5267242193, 0.0368519723, -0.3862408698, 0.2183276862, -0.2191678733, 0.5044022202, + -0.2727276385, -0.5753355026, -0.7795884013, -0.4371784329, -0.0385104008, 0.0453653373, 0.9454209805, + -0.0213055965, 0.4308182895, -0.0147529943, 0.0073038843, -0.3879997432, -0.0085734846, -0.3646063507, + 0.8428437114, -0.5474193096, -0.1213414371, -0.0447582118, 0.3180017769, -0.6903175712, -1.5116691589, + -0.4761842191, 0.3577857614, 0.8554373980, -0.3223759830, -0.3117367029, 0.0420887396, 0.0089452937, + -0.0616157129, 0.0011440844, -0.0256317016, -0.0264497921, -0.0221411716, 0.0136214150, -0.0284178350, + 0.0181288514, -0.0289485678, 0.0008052384, 0.0214692168, -0.0017591950, 0.0450270809, -0.4118867815, + -0.0074286349, 0.0637306646, -0.0332321078, -0.2063446492, 0.1343170851, 0.0676441118, -0.0789061263, + 0.0039714044, 0.0469334908, -0.4258472323, -0.0031129576, 0.1694611311, -0.0229218155, 0.0065105185, + -0.1568274647, 0.0442711748, -0.4040796161, 0.0128678223, 0.0067370874, -0.0270004030, -0.0364642292, + -0.2776701748, -0.2626651525, -0.2820671797, 0.6879999638, -0.0167431831, -0.0217852611, 0.2239535451, + 0.1765681207, 0.0004533622, 0.1616515517, 0.4690179527, -0.2932064235, -0.1863811612, -0.4326858819, + 0.5367636681, 0.8232741952, -0.0076241791, -0.0208735596, 0.3781396747, 0.0083103403, 0.0368625633, + -0.0208129082, -0.0092617041, -0.0518519543, 0.0075824461, -0.2745567262, 0.7515665889, -0.3270216882, + -0.1037794799, 0.0054932609, -0.0004360063, 1.5855798721, -0.5013164282, 0.2409702539, 0.5102282763, + 0.0323204994, 0.0443114154, -0.0743079633, 0.5015363693, -0.4499847591, -0.5266178250, -0.0303816795, + 0.0113547444, -0.4145325720, 0.0155029558, -0.5903900266, 0.0132576860, -0.0552800857, -0.3000935614, + -0.0300054196, -0.1883252263, 0.1547352970, -0.4416965246, 0.0176533815, 0.0298686288, 0.0877649859, + 0.3754878938, 0.5241811872, -0.1328917295, 0.1846721023, -0.0684443712, 0.0305131841, -0.0899124667, + 0.0746154487, -0.2723464668, 0.0320945904, -0.0005060069, 0.0357921608, 0.4950470328, -0.0148497112, + 0.1005883962, 0.0352807678, 0.0172633622, -0.0869081467, -0.0152430534, -0.1883669794, -0.2390221804, + 0.0668689683, -2.5013699532, -0.0269711744, -0.1674331278, 0.1789376289, -1.2393864393, -0.2605231106, + 0.4330428243, 0.2570144534, -0.0086775580, -0.1490048021, -0.5241391063, -0.0278369375, 0.2762182951, + 0.0199576281, 0.0066871047, 0.7151912451, -0.0024265163, 0.3064782321, 0.0487763546, -0.0112981694, + -0.2035348862, 0.0493254997, -0.2012788653, 0.1452431232, -0.2540090382, 0.2975836694, -0.0369952545, + 0.0682778209, -0.1628300995, 0.0986325592, -0.7109689116, 0.3238805830, 0.5708168745, 0.0253408048, + -0.2716795206, 0.9938709736, -0.0739620626, 0.0717267692, 0.0293982662, -0.0265223514, -0.3170827329, + 0.0181263424, -0.7185852528, 0.0195867456, 0.0033374443, 0.3110558093, 0.0028834590, 0.2549804747, + -0.4352625012, -0.0825110674, 0.0671706498, 0.0240719654, -0.5600070953, 0.3716776669, 0.6693077683, + -0.1732302159, -0.0300535280, -0.3385710716, -0.0674085692, 0.1381938905, -0.8376773596, -0.2104889005, + -0.3976771533, 0.0174542665, -0.0294472463, 0.5069975257, 0.0314344503, 0.1266442239, -0.0184428375, + -0.0113735562, -0.6051728725, -0.0321377702, -0.2472074926, 0.4815337062, -0.2199861258, 0.7497748137, + -0.0454755314, 0.3922365904, -0.6062285304, -1.6602826118, -0.6259492040, 0.5432906747, 0.8129641414, + -0.1297754496, -0.1781818271, -0.0433640033, 0.0857717618, -0.0634498149, -0.0337122343, 0.0376215614, + -0.1296353936, -0.0357829705, 0.0735422820, -0.0182135999, 0.0211684871, -0.0388115384, 0.0320480876, + 0.0199006833, 0.0938707665, -0.0393314250, -0.2282720208, -0.0348386541, 0.0919079781, -0.0631114319, + -0.2506425679, -0.1178641915, 0.0474984273, -0.0599489510, 0.0388556086, 0.0208455287, 0.1706432998, + -0.3912288845, 0.0646863803, -0.0412294790, 0.0065013990, -0.6113595366, -0.0309886932, -0.4187072515, + 0.0181138869, 0.0137019735, 0.5188140869, -0.0054722503, -0.1139752790, -0.2633494437, -0.1226351783, + -1.1872086525, 0.0032318123, 0.1287258714, -0.0034283027, 0.2808924615, 0.0632052049, -0.2965689003, + -0.0082631623, 0.3466319144, -0.2775699794, 0.2096666694, -0.2093079388, -0.2335083485, -0.0226903427, + -0.0181468017, 0.2967273891, -0.0483438261, 0.2503305972, -0.0409849882, 0.0516897514, 0.3434285820, + -0.0291223079, -0.1667241752, -0.1001765728, 0.2396512926, 0.5946724415, -0.0358862393, -0.0951117501, + -0.1029280201, -0.2618341744, 0.3290935159, 0.0175822675, -0.4756616056, -0.1702777147, 0.1173091084, + 0.6074576974, 0.1073398814, -0.3684058785, 0.0480201729, -0.0015499704, 0.5559393167, 0.0338939913, + -0.4553005397, 0.0349906124, 0.0031389890, -0.3105476499, 0.0079499427, -0.1186323687, 0.2069108784, + -1.0224379301, 0.0116371298, -0.0004839785, 0.0869038552, 0.0972586870, -0.0391659029, 0.2789616585, + 0.0861895606, 0.0461108424, -0.1098890752, 0.0860277712, -0.4243687093, -0.0834341794, 0.0190984122, + -0.0063930326, 0.0137155987, 0.7129291892, -0.0202291254, 0.3586359024, -0.0238374118, -0.0155034000, + -0.7634453177, 0.0053239241, -0.4975944161, -0.0906796083, -0.3312668502, -0.2476382852, -0.0328092724, + 0.1509385556, 0.2201244086, -0.6723868847, -0.1287524849, 0.9522626996, 0.4031330645, -0.0488846414, + -0.6026415229, -0.0940965116, 0.2768926620, -0.8198524117, -0.0326367989, -0.0255582817, 0.8920773268, + -0.0109668858, 0.3828944266, 0.0119301453, -0.0123951333, -0.1709069312, 0.0238716714, -0.1706337482, + 0.3240826428, 0.0393569022, 0.4952742457, -0.0015368350, -0.0197133217, 0.0394634083, -0.2541337311, + -0.2783952951, 0.3719478846, -0.1173014492, -0.3776190877, -0.4898634553, 0.4771644473, -0.1552882195, + -0.0168435965, 0.0220468529, -0.0234047771, -0.1242834181, -0.0035077333, -0.7012911439, 0.0329820998, + -0.0014328394, 0.2872559428, -0.0355794802, 0.2669203281, 0.0872863978, 0.0738353357, -0.4003589749, + 0.0020517111, -0.4586439133, 0.5128808618, 0.0952107608, 0.0757242739, -0.1753569543, -0.0696651936, + -0.2118204683, 0.2049609423, -0.7322594523, -0.2756121457, -0.3130523264, 0.0488914773, 0.0454624332, + 0.1791424453, 0.0192562677, 0.6879280806, -0.0109258108, -0.0589247681, -0.5332060456, -0.0355291367, + -0.6683956981, 0.7817873955, -0.3539718986, 0.5217394829, 0.0450545587, 1.2865257263, -0.4225950837, + -0.9668461084, -0.2438656390, 0.6077676415, 0.7250677347, 0.2058400363, -0.6094794869, -0.0127743725, + -0.0269410182, -0.0443292111, -0.0047174916, -0.0286554936, 0.0164860860, 0.0216391198, 0.0000547430, + 0.0034230519, -0.0193539821, -0.0048638578, -0.0331782587, -0.1216600835, 0.0783850402, -0.2200009823, + -0.5484527349, -0.0338481553, 0.1067893505, 0.0193015374, 0.0190553423, 0.0077600847, 0.0194670819, + 0.0364076868, 0.0389590003, -0.0194327328, -0.5235614777, -0.3690682352, -0.0535990894, 0.0222456716, + -0.0237181541, -0.3437302709, 0.0336950310, -0.2471015453, 0.0347703956, 0.0105486372, -0.1146475747, + -0.0128530264, -0.7887002230, -0.2139095515, -0.2573784292, 0.5604884624, -0.0414251201, 0.0268225595, + -0.0052164104, -0.4037641585, 0.5882292390, 0.1508283466, 0.0373637229, -0.5168998837, -0.5980069041, + 0.0902188942, -0.3578412831, 0.4200122952, 0.0489844419, -0.0343268141, 0.2538180053, -0.0488515757, + 0.1652212143, 0.0102397157, -0.0399376042, 0.6666966081, -0.0027583018, 0.6611607671, 0.2796159685, + 0.3751438558, 0.2801287174, -0.0047272928, -0.7540323734, -0.1706158668, -0.4846105278, -0.5296305418, + -0.0237145554, 0.0754747763, -0.4194953144, 0.4079932868, 0.1623633057, -0.3142811954, -0.6698747873, + -0.0349363089, 0.0393353440, 0.4525082111, 0.0487212576, -0.1602965444, 0.0442362241, -0.0024233470, + -0.2512975633, 0.0364286639, -0.4211257696, -0.1201224327, -0.7451843023, -1.2653163671, 0.0160685070, + 0.0687002018, -0.1986775994, -0.1360448450, -0.0749344677, -0.1515689939, 0.1962397844, -0.2993898094, + -0.1054843217, -0.5224688649, -0.0881583691, 0.3346495926, -0.0048073307, 0.0400011428, 0.7032503486, + 0.0217781998, 0.5896643400, -0.0448040739, 0.0197922196, -0.5217272639, -0.0366307609, -0.5235586762, + 0.7335209846, -0.6986209154, -1.3687721491, 0.0277355798, 0.8085011244, 0.1786081195, -0.1857656986, + -0.1415506601, 0.6941767931, 0.5569129586, 0.0070422618, -0.7057129145, -1.6167650223, 0.4103705585, + -0.6340282559, -0.0154078826, 0.0446273200, 0.8124088049, -0.0420845263, 0.1450776011, 0.0106168017, + 0.0039060870, -0.3815846443, 0.0423646010, 0.0475320518, 0.3476380408, -0.5829945207, -0.6226695180, + -0.0224926602, 0.6960749626, 0.2341582626, -1.4045158625, 0.2748194635, -0.0400918908, -0.0817347243, + 0.0842497200, 0.1486685127, 0.5849114060, 0.1625861973, -0.2580044866, 0.0302444436, -0.0218294747, + 0.1385417581, -0.0310730822, -0.5560604930, -0.0437082313, -0.0103870695, -0.0567841679, -0.0021472089, + 0.0536326170, 0.1611684412, -0.1831469238, 0.2545364499, -0.0459524058, -0.1049438119, 0.2443634421, + 0.0227323826, 0.1885968298, 0.0852972195, 0.1999463588, 0.0207023229, 0.0881121606, -0.5414125919, + -0.3002434075, -0.1424637288, 0.0200603493, 0.0113324746, 0.5935490727, 0.0293819644, 0.6670605540, + -0.0253547784, -0.0393749438, -0.7709679008, -0.0365138873, -0.4396755397, 0.6884223819, -0.2611112595, + -1.8774693012, -0.0382625945, 0.8725510836, -0.4928644598, -0.2189266533, 0.2001470923, 0.5869948268, + 0.5472967625, 0.7693622112, -0.5423539877, -0.0667493343, 0.0380085669, -0.0239525307, -0.0449014418, + 0.0077688210, -0.1430912316, 0.0260939710, 0.0525648743, 0.0446856730, 0.0048831305, 0.1151780188, + -0.0031947494, -0.0155405290, -0.1372660995, -0.0895780846, -1.4037353992, -0.0026806965, -0.1067251340, + 0.0272771921, -0.0559473746, 0.0230121389, -0.0061843856, 0.0015697938, 0.0832877457, -0.0696524903, + -0.3867762685, 0.8635419607, -0.0891173854, 0.0034306645, -0.0194078218, -0.6117094159, -0.0385323875, + 0.0980508998, 0.0028843454, 0.0030354180, -0.5710870028, -0.0170821771, -0.3774715364, -0.0032055390, + -0.0651721805, 0.0269364621, 0.0278133489, -0.2507851720, 0.2601221800, 0.6104131937, -0.2581859231, + 0.4611452520, 0.1026301757, 0.5664731860, -0.4654701352, 0.8525296450, -0.7390667200, 0.1472975314, + -0.0111428984, -0.0404090881, 0.3386467993, 0.0248792283, -0.2538463473, -0.0259546135, -0.0171344150, + -0.3922840655, -0.0310988780, -0.1847026944, -0.1067288741, 0.0350882299, 0.0545480996, -0.0285120849, + -0.1929141283, 0.1348992586, 0.4968050718, 0.2134823650, -0.0042959554, -0.3756020069, -0.0269969516, + -0.1611916125, -0.2077403367, -0.2371500582, -0.6373690367, -0.0304267760, -0.0349376425, 0.7959181666, + -0.0316127092, -0.1119868234, 0.0337211527, -0.0071961484, -0.0262746271, 0.0020413511, -0.2010388523, + 0.2658497691, 0.0118317511, -0.5845263004, 0.0029303320, -0.0133678624, -0.0977094546, -0.3142478466, + 0.3855778277, 0.2161775231, 0.2007939517, -0.0901769325, -0.1543459892, 0.0224080794, 0.2095545381, + 0.4173698127, -0.0358691216, -0.0145311728, 0.9287641644, 0.0244402178, 0.9638146758, 0.0150271170, + -0.0541157387, -0.4310163558, -0.0316328891, -0.4609151185, 0.1989493966, -0.3272954524, -0.7784904838, + -0.0165412538, 0.2622301280, -0.6295908093, 0.2951786220, 0.2422311753, 0.8495292068, 0.6268782020, + 0.1836655438, -0.6979805231, 0.1071579084, -1.9053711891, 0.5337630510, -0.0393848419, 0.0199204572, + 0.3263296187, 0.0102138408, 0.4045059979, 0.0067795031, 0.0336568840, -0.0957986638, -0.0441556461, + -0.4123474360, 0.1715452522, -3.2899777889, -0.1192793176, -0.0152495131, -0.1897758394, 0.1874453872, + -0.6838648319, 0.4448648095, 0.3387575150, 0.7274349332, -0.2438905537, -0.1766054630, 0.2571379244, + -0.3342683911, -0.0333744362, -0.0496788397, -0.0060048699, 0.0281973872, 0.0298788287, -0.5464175940, + -0.0316888839, -0.0078338645, -0.0942152888, 0.0147767402, -0.0103216004, -0.0674225315, -1.3291354179, + -0.3171196878, 0.0113801248, 0.0392228104, 0.2852381170, -0.1502476782, 0.0695211142, 0.0142092993, + 0.2161683738, 0.1448096037, 0.1512847692, -0.8002882004, -0.0595479496, 0.5712021589, -0.0227902662, + 0.0353799127, 0.1896413714, -0.0004423037, 0.9913336039, -0.0143754967, -0.0395907573, -0.6992436051, + 0.0183372013, -0.8203246593, 0.5868998766, -0.4024432600, -1.3700423241, -0.0025487542, 0.9975725412, + -0.2618308365, -0.6395715475, 0.2104645967, 0.5754511952, 0.7471023798, 1.0783131123, -0.7854349017, + -0.0068165897, 0.1311189681, 0.1236141175, -0.0060322173, -0.0189587362, -0.2687618136, 0.0417966880, + 0.0198493917, -0.0133285644, 0.0169729777, 0.0958536118, -0.0073037259, 0.1229945868, -0.1836925745, + 0.1018262282, -1.1953188181, -0.0320160165, -0.1015609577, -0.0014065404, 0.0876024812, -0.0653611943, + -0.0779995173, -0.0327110328, 0.0981066823, 0.0758420303, 0.4111435711, -0.3568826318, 0.3434506059, + 0.0279183425, -0.0183128715, -0.2883189619, -0.0283980723, -0.2920386493, 0.0278911013, -0.0313658006, + 0.6201892495, 0.0323423184, -0.0395300500, -0.4890304804, -0.3237088025, 0.1850017756, -0.0082991496, + -0.2044751197, -0.2546317875, -0.1463038176, 1.0237698555, 0.2653035820, 0.1094458923, -0.3526209593, + 0.0814269111, -0.1548318565, 0.4255304635, -0.1347719580, -0.0227344986, -0.0373442285, -0.1933275908, + 0.0265721716, -0.1351318061, -0.0286027025, 0.0318547115, -0.4003780782, 0.0147478320, 0.0300735664, + 0.2054808438, 0.3550937772, 0.0463373661, -0.0228597168, 0.0476531982, -0.4984072745, 0.8174489141, + 0.1830573529, 0.2413281500, 0.1680587232, -0.1579141021, 0.3081762493, -0.1589800268, -0.1786419451, + 0.5353065729, -0.0170124173, 0.0236417912, 1.8752166033, 0.0207607262, 0.3994472623, -0.0423962586, + -0.0356416479, -0.1865476072, 0.0499989428, -0.2910636365, 0.3568102717, -0.8324245811, -0.4837874174, + 0.0449443720, 0.3211084306, 0.4314349890, -0.5057532787, 1.0553083420, 0.4730113745, 0.1899735034, + 0.3485227227, -0.4126980603, -0.4424137771, -0.1170865819, 0.4439237416, 0.0269787647, 0.0181932710, + 0.3949256539, 0.0440328233, 0.2834262550, -0.0164299011, 0.0375958458, -0.2360804081, -0.0036757477, + -0.8198620081, -0.0002998045, -0.7792702317, -0.5419439077, -0.0194247607, 0.2417463362, -0.4271444976, + -0.0764846727, 0.1383299977, 0.5036548972, 0.2920281589, 0.8199911118, -0.5878306627, -1.2778795958, + 0.7124420404, 1.3059445620, -0.0286112316, 0.0316767804, 0.1078707576, 0.0366549157, 1.7090015411, + 0.0080462322, 0.0222956222, -0.1941069961, 0.0396030061, -0.0920261592, 1.0979866982, -0.7296712399, + -0.5150372982, 0.0039320104, 0.6271898746, -0.8605564833, -1.2512462139, 1.1115969419, 0.0502445102, + -0.0068334118, 0.1084898785, -0.3850990832, 0.4214206636, -1.0038114786, 0.2044304609, 0.0078590885, + -0.0108357556, -0.3498951197, -0.0056974664, -0.2641506791, -0.0335249528, -0.0272149052, -0.3646773696, + -0.0355445854, -0.5063526630, 0.3608566523, -0.4627398551, -0.2056866288, 0.0314389728, 0.3119669855, + -0.0745992735, 0.2019843161, 0.4260723293, 0.1498487443, 0.5227327943, 0.1954478025, -0.3949721754, + -1.0407074690, -0.2556259632, 0.5501220226, -0.0202705264, 0.0399887599, 0.0332411751, 0.0181643404, + 0.4340880811, -0.0158595555, 0.0280248299, -0.7869564891, -0.0438322090, -0.2051930130, 0.5463204384, + -0.2414627969, -1.2405043840, 0.0408474468, 0.2430282831, -0.8686886430, -0.3778093159, 0.2200338393, + 0.8543496728, 1.0129809380, 0.9148719907, -0.1336318254, -0.0621013120, -0.0424140245, 0.0459826365, + -0.0464573763, -0.0030330308, -0.2646920979, -0.0006133430, -0.0221885610, 0.0077072424, -0.0334133096, + 0.0190080479, -0.0366195552, 0.0594232604, -0.0967265293, 0.1483206749, -1.0690969229, 0.0136405267, + -0.2495157272, -0.0741728023, 0.1747024208, -0.0292489193, 0.0105351172, -0.1137630865, -0.0775343254, + 0.0247715060, -0.4604588449, 0.5981205702, -0.6210471988, -0.0354419947, -0.0266215336, 0.1559787691, + -0.0235465523, 0.6589985490, -0.0131545644, -0.0098283142, 0.1084643453, -0.0228822827, 0.2508457601, + 0.3650615811, 0.1267749220, -0.0162414368, -0.0315973312, 0.7237749696, -0.0600906387, 0.8835039735, + 1.2918497324, 0.1131694168, -0.1085247472, -0.2277299166, 0.0366072915, 0.1433445960, 0.3335800171, + 0.3501141369, 0.0115572810, 0.0318727382, 0.5640623569, -0.0335407257, 0.0249900799, 0.0038993331, + -0.0248970166, -0.2782051861, -0.0410117395, 0.2523306310, 0.3517462909, 0.2121896595, -0.1162448376, + 0.0054595582, -0.4676983058, 0.4563185275, -0.1712279469, -0.1131843030, 0.5749317408, 0.0786591992, + 0.0123988315, 0.2857176960, 0.1028187424, -0.4653768241, -0.0813126788, -0.0188388824, 0.0421144478, + 0.9026269317, -0.0141519532, 0.1383557618, 0.0367890857, 0.0053361808, -0.0178884547, 0.0094673038, + -0.2738531828, 0.3822990954, -0.1030377969, -0.3883157372, 0.0101224557, 0.1001654044, -0.0747024119, + 0.6006180048, 0.6424841285, 0.1733836979, 0.4141313434, 0.2577677667, 0.0196546391, 0.0306565147, + -0.0644585490, 1.1456140280, -0.0261694919, -0.0351552740, 0.0118874945, -0.0269273873, 0.2447904199, + 0.0277601518, -0.0310750119, -0.8901538253, -0.0329257250, -0.7822555900, 0.8472951651, -0.5997539163, + -0.5599926710, -0.0345624685, -0.0284180790, -0.3063721359, 0.1183450669, 0.7996146083, 1.3596835136, + 0.5488421917, 0.2623258829, -0.8360809088, -1.0534168482, 0.2761985064, 0.0701652467, 0.0265866555, + -0.0175058469, -0.5787774324, 0.0162952580, -0.5390081406, 0.0217363723, 0.0048607374, 0.5082998276, + 0.0298146345, 0.7032709122, -0.4476767182, 0.6333382726, -0.0702254623, -0.0111619607, -0.2203527093, + -1.3252762556, 0.1918622106, -0.5391735435, -0.6053310037, -0.4060880840, -0.5177740455, 0.7152566314, + -0.1525194645, -0.7066713572, -0.1851055920, -0.0405507907, -0.0179623142, 0.6384886503, -0.0350592025, + 0.2167061567, -0.0110048875, 0.0403056815, 0.1018915400, 0.0335987471, 0.1785299480, 0.0907991529, + -0.9045218825, -0.2081759572, 0.0145147778, 0.2902441025, 0.1892959177, -0.6062126756, -0.1715902835, + -0.2030725628, -0.0454456098, -0.0325598530, 0.0316967256, -1.0412836075, 0.1042325199, 0.7389448881, + -0.0315108448, 0.0161139406, 0.6608737111, -0.0278646350, 0.6341997385, 0.0240364224, 0.0289974492, + -1.0020937920, -0.0050924048, -0.8173771501, 0.0980714336, -0.6252622604, -1.0978114605, 0.0140398778, + 0.4661926031, -0.0560285747, -0.5825963616, 0.9664432406, 0.4695834517, 0.1042769328, 0.6328668594, + -0.8096875548, -0.1974821538, 0.0603384487, 0.1525808424, 0.0068174973, 0.0268414356, -0.7763271332, + 0.0174683444, 0.2644013166, -0.0111980326, -0.0471895151, -0.0116205923, -0.0227108840, -0.1594015211, + 0.0952647924, 0.0387158804, -0.9336721897, 0.0474351905, 0.0543322414, -0.1767173111, -0.0091935284, + -0.1534161121, 0.0854202509, 0.0338279344, 0.1157898754, -0.0844622776, 0.0474394448, 0.3694055676, + -0.6652798057, 0.0305196084, -0.0066180341, 0.8347792625, 0.0477602221, 0.4235672951, -0.0132840648, + 0.0128012868, -0.0184550937, 0.0343486406, 0.0460694805, -0.1225851104, -0.1292703748, -0.1817471832, + -0.0478985421, 0.2783367634, -0.5327829719, -0.2661572695, 0.8686574101, -0.0709094033, -0.0582687892, + 0.0423842631, -0.1033001021, 0.6995526552, -0.1032795608, 0.3756015301, -0.0467913263, 0.0386442803, + 0.2745943069, 0.0066912882, -0.1094110534, -0.0350673199, -0.0435243323, -0.2208653539, 0.0376370810, + 0.6540331244, -0.8201739788, 0.1041640341, 0.0678936169, 0.0339470543, -0.1251623631, -0.5500101447, + 0.2536099851, -0.5599420071, -0.8515334129, -0.8221063614, 0.0267463233, 0.3377620280, 0.0956432298, + -0.7992894650, 0.0376259387, -0.0492405891, 0.0248947479, -0.8014723063, 0.0386015065, 0.3422433138, + -0.0049428940, -0.0233486611, 0.0531458147, 0.0204061605, -0.4921406209, 0.2143180966, -0.9124107361, + -0.5282543302, -0.0082188137, 0.3940183222, -0.0703973770, 0.2838156521, 0.1259212643, -0.0552438870, + 0.0686918423, -0.0180950686, -0.0875097886, -0.2869284451, 0.1590942740, 0.3322785795, 0.0325080790, + 0.0033236369, 0.0557972416, -0.0277688149, 0.4219309092, 0.0037146322, -0.0338882506, -0.4120204747, + 0.0432067402, -0.7439932227, 0.3922487497, -0.4141609371, -0.3591470718, 0.0238076113, 0.2847858965, + 0.1163747385, -0.3206885457, 0.1907688230, 0.0906408504, 0.3747521043, 0.2750247419, -0.7959539294, + -1.1823486090, 0.1879484802, 0.9548650384, -0.0111556277, 0.0337821878, 3.7001430988, 0.0358772390, + 1.1270211935, -0.0360346325, -0.0162308309, -0.0125768138, -0.0061665662, 0.0613936894, -0.3352574110, + 0.2092920393, -0.3123878837, -0.0001231916, 0.6323376298, -0.6722851396, -1.9193249941, -1.1372646093, + -0.6384195685, -0.6505790353, -0.1470468044, 0.0513535812, 0.0227893032, -0.3263072968, 0.2549263537, + -0.0148570053, 0.0227769949, 0.3594914079, 0.0248929597, 0.0588637441, 0.0340429060, -0.0331005305, + -0.2544456422, 0.0161518119, -0.1758094430, 0.5367755294, -0.7055914998, -0.3781234324, -0.0464113355, + 0.0190908965, 0.2719711363, -0.4060737491, 0.6330465078, 0.7658862472, 0.3664361835, 0.1379054785, + -0.3733623028, -0.6987259984, -0.0851245970, 1.5353600979, -0.0303403623, 0.0126178898, 0.8448222876, + -0.0277430657, 0.0630089492, 0.0197844543, 0.0351737067, -0.3107087314, 0.0025146492, -0.3074116111, + -0.0241411477, -0.4679161012, -0.8294273615, 0.0100592971, -0.1811828911, 0.1472923756, 0.0489724167, + 0.7992106080, 0.2863916159, 0.0960692614, 0.4893977344, -0.3130331337}; +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w2.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w2.h new file mode 100644 index 0000000000000..85181031c98ab --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w2.h @@ -0,0 +1,47 @@ +//Numpy array shape [25, 10] +//Min -1.045674681664 +//Max 0.718651175499 +//Number of zeros 0 + +#ifndef W2_H_ +#define W2_H_ + +weight_default_t w2[250] = { + -0.7057377100, 0.1404066533, 0.2397147864, -0.0538846180, -0.0136500485, -1.0456746817, 0.2339422107, + -0.2464046478, -0.0155451894, 0.3114753366, 0.0252490267, 0.0652531609, 0.2230684459, -0.0703721792, + -0.0061709168, -0.4667471945, 0.2732006609, -0.1566423327, -0.0504947454, -0.2795722485, 0.3157102764, + -0.2208270580, -0.3470733166, -0.0298985839, 0.0033523447, 0.4046282768, -0.3606239557, 0.6249889731, + -0.0325289443, 0.3911077976, -0.0111113638, 0.0061787963, 0.0062978785, -0.0141930580, 0.0326538198, + -0.0164757688, -0.0086768735, 0.0389737710, -0.0255079512, 0.0343580954, -0.0220158268, 0.0359050333, + 0.0078137182, -0.0094889030, 0.0315879099, -0.0038071091, -0.0228841919, 0.0211039726, -0.0303417332, + 0.0266918801, 0.0846779272, -0.1972407401, -0.2197024226, -0.0482244752, -0.0594943352, 0.6427704096, + -0.1127861366, 0.3480221033, -0.0235439185, 0.1047359556, -0.0122122988, -0.0466807000, 0.0192838348, + 0.0184221603, 0.0298816897, 0.0179036893, 0.0378936641, -0.0134130828, 0.0245604031, -0.0230461247, + 0.4430962801, -0.3229490817, -0.4796850085, -0.0328346863, -0.0463326760, -0.1059406400, 0.0650193691, + 0.1677540839, -0.0191161763, -0.9446775317, 0.0047525112, -0.0430214256, -0.0086042080, -0.0065273754, + 0.0322899334, -0.0063139671, -0.0088419663, -0.0265105683, 0.0207859948, 0.0300601982, -0.0358567573, + -0.0101170968, -0.0055280370, 0.0417956375, -0.0293978676, 0.0215279460, -0.0163401272, 0.0019495651, + -0.0018129245, -0.0349077098, 0.0724146366, 0.4244908690, 0.3408450186, 0.0095429150, -0.0044469568, + -0.1800813526, 0.1598049104, -0.0686975494, -0.0571451373, -0.2389617860, -0.0001860010, 0.0376826450, + -0.0334893614, -0.0493457690, 0.0032638730, -0.0276949946, 0.0366198681, -0.0292772222, -0.0406004563, + 0.0360089242, -0.1218376979, 0.1806843132, 0.1113958284, -0.0405312218, 0.0022432276, -0.1337593943, + 0.0729509220, 0.1634687930, 0.0032948528, 0.0776214898, 0.1600115597, -0.0854228437, -0.1109891087, + -0.0564341992, -0.0124987122, 0.0338483378, 0.0216468368, 0.2892125845, -0.0419363230, 0.0799390525, + 0.0079131620, 0.1280078143, 0.0930886343, 0.0150845889, -0.0122468621, -0.3565736711, 0.3034112155, + 0.1370847970, -0.0515636019, 0.1990947574, -0.6926737428, 0.6633190513, 0.7186511755, -0.0038143450, + -0.0632954985, -0.5240395665, 0.6481059194, -0.1913139373, -0.0223663468, -0.0330061354, -0.0007724538, + 0.0031711236, 0.0164572485, -0.0087732449, -0.0083233602, -0.0083719268, 0.0295558013, -0.0158381946, + 0.0207662024, -0.0032593012, 0.0831812173, -0.0175970923, -0.3239497840, 0.0158007033, -0.0106937513, + -0.0832406804, -0.0439340621, 0.0818050355, -0.0590137169, -0.3678484261, -0.8252559304, 0.2230938077, + 0.3108801544, 0.0021616002, -0.0497470722, -0.6720880866, 0.2066508830, -0.5620029569, -0.0025763733, + 0.0753768012, -0.3516313136, 0.3203991950, 0.3835750520, 0.0187730733, -0.0582833514, -0.4428557158, + 0.4818525016, -0.2054705173, -0.0675888211, 0.2989248335, 0.0312647708, 0.0990447775, 0.1213422418, + -0.0735856369, -0.0349877253, 0.1899046749, 0.1087389141, 0.1551754475, 0.0041319388, -0.5746779442, + 0.0658814609, -0.1868388653, 0.0325599350, -0.0466500595, -0.0395346284, 0.2296674401, 0.0618919656, + 0.1525417417, 0.0100804977, 0.2973885834, 0.0829108581, -0.2141572684, -0.2578293085, -0.0191419479, + -0.0261756163, 0.1556160152, -0.1592844576, 0.1052642092, -0.0549823083, 0.4501740336, 0.2459395975, + -0.1690156311, -0.3005261421, -0.0201924089, -0.0455512740, 0.0550876595, -0.5089792013, 0.3866674900, + -0.0132356742, 0.3193220496, -0.0581676178, 0.1859592199, 0.0603353418, -0.0743811354, -0.0334267654, + -0.0704199299, 0.1037535146, 0.1687176079, -0.0629248247, -0.0154705839}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w3.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w3.h new file mode 100644 index 0000000000000..6dd20986aa269 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w3.h @@ -0,0 +1,26 @@ +//Numpy array shape [10, 10] +//Min -1.066073656082 +//Max 0.681088924408 +//Number of zeros 0 + +#ifndef W3_H_ +#define W3_H_ + +weight_default_t w3[100] = { + -0.1038735062, -0.0083230771, -0.0552374311, -0.5224462748, -0.0573509037, -0.1265300810, -0.0112661421, + -0.5452736616, -0.0644872189, -0.1275455654, 0.1141930372, -0.0077123214, 0.1154981479, 0.3085378408, + -0.0414689742, 0.0115689430, -0.0417736508, 0.1851192564, -0.0965978727, 0.0469020531, -0.0236889981, + -0.0430007130, 0.0516370200, 0.2873915136, -0.0340524092, -0.1160606891, -0.0130381659, 0.1598475724, + 0.0319193080, -0.2202762365, -0.0452292822, -0.0490893982, -0.0062470436, -0.0103780562, -0.0179754607, + 0.0128578581, -0.0021512285, -0.0128093800, -0.0163365994, 0.0363431089, 0.0190900937, 0.0117608421, + -0.0029030738, -0.0137901427, 0.0414321311, 0.0412845612, -0.0302784089, -0.0485344902, -0.0001797759, + -0.0344933569, 0.2524053454, -0.0404473692, 0.4452796578, 0.1888252646, -0.0498852022, 0.6810889244, + -0.0330508612, 0.2906026244, -0.1345981210, 0.5589192510, -0.1634582132, 0.0017064024, -0.0490242988, + 0.1130080819, -0.0318347588, -0.0584588088, -0.0371478200, 0.1148293316, 0.1451935470, -0.1724624336, + 0.0266404785, -0.0216521453, 0.0870701820, -0.4996633530, -0.0126784481, 0.0649333969, -0.0329958349, + -0.1830419898, -0.3936564028, 0.0841621608, -0.0027621964, 0.0302785076, 0.0032740140, 0.0303986724, + 0.0166636966, -0.0340096354, 0.0390744917, -0.0281386729, 0.0063985521, 0.0091940211, -1.0660736561, + -0.0350735374, -0.6366914511, -0.6618690491, -0.0448695309, 0.1518789679, -0.0225193389, -0.6637751460, + -0.4656083286, -0.5459096432}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w4.h b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w4.h new file mode 100644 index 0000000000000..98f4fd3d3607c --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/interface/taus/weights/w4.h @@ -0,0 +1,20 @@ +//Numpy array shape [10, 1] +//Min -0.667848289013 +//Max 0.826535403728 +//Number of zeros 0 + +#ifndef W4_H_ +#define W4_H_ + +weight_default_t w4[10] = {-0.6678482890, + 0.0003038962, + -0.1780688465, + 0.6331779361, + -0.0266840570, + -0.3114789128, + 0.0264124461, + 0.8265354037, + 0.1617123932, + -0.4059850574}; + +#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/BuildFile.xml b/L1Trigger/Phase2L1ParticleFlow/plugins/BuildFile.xml index a5ec2e799f15d..3d1223a3526e1 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/BuildFile.xml +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/BuildFile.xml @@ -2,6 +2,7 @@ + diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/DeregionizerProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/DeregionizerProducer.cc new file mode 100644 index 0000000000000..89fe1bdea54dd --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/DeregionizerProducer.cc @@ -0,0 +1,188 @@ +#include + +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" + +#include "L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_input.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h" + +class DeregionizerProducer : public edm::stream::EDProducer<> { +public: + explicit DeregionizerProducer(const edm::ParameterSet &); + ~DeregionizerProducer() override; + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); + +private: + edm::ParameterSet config_; + edm::EDGetTokenT token_; + l1ct::DeregionizerEmulator emulator_; + + std::unordered_map clusterRefMap_; + std::unordered_map trackRefMap_; + std::unordered_map muonRefMap_; + + void produce(edm::Event &, const edm::EventSetup &) override; + void hwToEdm_(const std::vector &hwOut, std::vector &edmOut) const; + void setRefs_(l1t::PFCandidate &pf, const l1ct::PuppiObjEmu &p) const; +}; + +DeregionizerProducer::DeregionizerProducer(const edm::ParameterSet &iConfig) + : config_(iConfig), + token_(consumes(iConfig.getParameter("RegionalPuppiCands"))), + emulator_(iConfig) { + produces("Puppi"); + produces("TruncatedPuppi"); +} + +DeregionizerProducer::~DeregionizerProducer() {} + +void DeregionizerProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + clusterRefMap_.clear(); + trackRefMap_.clear(); + muonRefMap_.clear(); + + auto deregColl = std::make_unique(); + auto truncColl = std::make_unique(); + + edm::Handle src; + + iEvent.getByToken(token_, src); + + std::vector regionEtas, regionPhis; + std::vector outputRegions; + std::vector hwOut; + std::vector edmOut; + std::vector hwTruncOut; + std::vector edmTruncOut; + + LogDebug("DeregionizerProducer") << "\nRegional Puppi Candidates"; + for (unsigned int iReg = 0, nReg = src->nRegions(); iReg < nReg; ++iReg) { + l1ct::OutputRegion tempOutputRegion; + + auto region = src->region(iReg); + float eta = src->eta(iReg); + float phi = src->phi(iReg); + LogDebug("DeregionizerProducer") << "\nRegion " << iReg << "\n" + << "Eta = " << eta << " and Phi = " << phi << "\n" + << "###########"; + for (int i = 0, n = region.size(); i < n; ++i) { + l1ct::PuppiObjEmu tempPuppi; + const l1t::PFCandidate &cand = region[i]; + clusterRefMap_[&cand] = cand.pfCluster(); + trackRefMap_[&cand] = cand.pfTrack(); + muonRefMap_[&cand] = cand.muon(); + + tempPuppi.initFromBits(cand.encodedPuppi64()); + tempPuppi.srcCand = &cand; + tempOutputRegion.puppi.push_back(tempPuppi); + LogDebug("DeregionizerProducer") << "pt[" << i << "] = " << tempOutputRegion.puppi.back().hwPt << ", eta[" << i + << "] = " << 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); + } + } + + l1ct::DeregionizerInput in = l1ct::DeregionizerInput(regionEtas, regionPhis, outputRegions); + + emulator_.run(in, hwOut, hwTruncOut); + + DeregionizerProducer::hwToEdm_(hwOut, edmOut); + DeregionizerProducer::hwToEdm_(hwTruncOut, edmTruncOut); + + deregColl->swap(edmOut); + truncColl->swap(edmTruncOut); + + iEvent.put(std::move(deregColl), "Puppi"); + iEvent.put(std::move(truncColl), "TruncatedPuppi"); +} + +void DeregionizerProducer::hwToEdm_(const std::vector &hwOut, + std::vector &edmOut) const { + for (const auto &hwPuppi : hwOut) { + l1t::PFCandidate::ParticleType type; + float mass = 0.13f; + if (hwPuppi.hwId.charged()) { + if (hwPuppi.hwId.isMuon()) { + type = l1t::PFCandidate::Muon; + mass = 0.105; + } else if (hwPuppi.hwId.isElectron()) { + type = l1t::PFCandidate::Electron; + mass = 0.005; + } else + type = l1t::PFCandidate::ChargedHadron; + } else { + type = hwPuppi.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron; + mass = hwPuppi.hwId.isPhoton() ? 0.0 : 0.5; + } + reco::Particle::PolarLorentzVector p4(hwPuppi.floatPt(), hwPuppi.floatEta(), hwPuppi.floatPhi(), mass); + edmOut.emplace_back( + type, hwPuppi.intCharge(), p4, hwPuppi.floatPuppiW(), hwPuppi.intPt(), hwPuppi.intEta(), hwPuppi.intPhi()); + if (hwPuppi.hwId.charged()) { + edmOut.back().setZ0(hwPuppi.floatZ0()); + edmOut.back().setDxy(hwPuppi.floatDxy()); + edmOut.back().setHwZ0(hwPuppi.hwZ0()); + edmOut.back().setHwDxy(hwPuppi.hwDxy()); + edmOut.back().setHwTkQuality(hwPuppi.hwTkQuality()); + } else { + edmOut.back().setHwPuppiWeight(hwPuppi.hwPuppiW()); + edmOut.back().setHwEmID(hwPuppi.hwEmID()); + } + edmOut.back().setEncodedPuppi64(hwPuppi.pack().to_uint64()); + setRefs_(edmOut.back(), hwPuppi); + } +} + +void DeregionizerProducer::setRefs_(l1t::PFCandidate &pf, const l1ct::PuppiObjEmu &p) const { + if (p.srcCand) { + auto match = clusterRefMap_.find(p.srcCand); + if (match == clusterRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.intId() << " pt " + << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setPFCluster(match->second); + } + if (p.srcCand) { + auto match = trackRefMap_.find(p.srcCand); + if (match == trackRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid track pointer in PF candidate id " << p.intId() << " pt " + << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setPFTrack(match->second); + } + if (p.srcCand) { + auto match = muonRefMap_.find(p.srcCand); + if (match == muonRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid muon pointer in PF candidate id " << p.intId() << " pt " + << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setMuon(match->second); + } +} + +void DeregionizerProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + // DeregionizerProducer + edm::ParameterSetDescription desc; + desc.add("RegionalPuppiCands", edm::InputTag("l1ctLayer1", "PuppiRegional")); + desc.add("nPuppiFinalBuffer", 128); + desc.add("nPuppiPerClk", 6); + desc.add("nPuppiFirstBuffers", 12); + desc.add("nPuppiSecondBuffers", 32); + desc.add("nPuppiThirdBuffers", 64); + 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" +DEFINE_FWK_MODULE(DeregionizerProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1CTJetFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1CTJetFileWriter.cc new file mode 100644 index 0000000000000..f3d21a7c85e1f --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1CTJetFileWriter.cc @@ -0,0 +1,120 @@ +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.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/Common/interface/View.h" + +#include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h" +#include "L1Trigger/DemonstratorTools/interface/utilities.h" +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" +#include "DataFormats/L1TParticleFlow/interface/gt_datatypes.h" + +// +// class declaration +// + +class L1CTJetFileWriter : public edm::one::EDAnalyzer { +public: + explicit L1CTJetFileWriter(const edm::ParameterSet&); + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + // ----------constants, enums and typedefs --------- + unsigned nJets_; + size_t nFramesPerBX_; + size_t ctl2BoardTMUX_; + size_t gapLengthOutput_; + size_t maxLinesPerFile_; + std::map>> channelSpecsOutputToGT_; + + // ----------member functions ---------------------- + void analyze(const edm::Event&, const edm::EventSetup&) override; + void endJob() override; + std::vector> encodeJets(const std::vector jets); + + edm::EDGetTokenT> jetsToken_; + l1t::demo::BoardDataWriter fileWriterOutputToGT_; +}; + +L1CTJetFileWriter::L1CTJetFileWriter(const edm::ParameterSet& iConfig) + : nJets_(iConfig.getParameter("nJets")), + nFramesPerBX_(iConfig.getParameter("nFramesPerBX")), + ctl2BoardTMUX_(iConfig.getParameter("TMUX")), + gapLengthOutput_(ctl2BoardTMUX_ * nFramesPerBX_ - 2 * nJets_), + maxLinesPerFile_(iConfig.getParameter("maxLinesPerFile")), + channelSpecsOutputToGT_{{{"jets", 0}, {{ctl2BoardTMUX_, gapLengthOutput_}, {0}}}}, + jetsToken_(consumes>(iConfig.getParameter("jets"))), + fileWriterOutputToGT_(l1t::demo::parseFileFormat(iConfig.getParameter("format")), + iConfig.getParameter("outputFilename"), + nFramesPerBX_, + ctl2BoardTMUX_, + maxLinesPerFile_, + channelSpecsOutputToGT_) {} + +void L1CTJetFileWriter::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + + // 1) Encode jet information onto vectors containing link data + // TODO remove the sort here and sort the input collection where it's created + const edm::View& jets = iEvent.get(jetsToken_); + std::vector sortedJets; + sortedJets.reserve(jets.size()); + std::copy(jets.begin(), jets.end(), std::back_inserter(sortedJets)); + + std::stable_sort( + sortedJets.begin(), sortedJets.end(), [](l1t::PFJet i, l1t::PFJet j) { return (i.hwPt() > j.hwPt()); }); + const auto outputJets(encodeJets(sortedJets)); + + // 2) Pack jet information into 'event data' object, and pass that to file writer + l1t::demo::EventData eventDataJets; + eventDataJets.add({"jets", 0}, outputJets); + fileWriterOutputToGT_.addEvent(eventDataJets); +} + +// ------------ method called once each job just after ending the event loop ------------ +void L1CTJetFileWriter::endJob() { + // Writing pending events to file before exiting + fileWriterOutputToGT_.flush(); +} + +std::vector> L1CTJetFileWriter::encodeJets(const std::vector jets) { + std::vector> jet_words; + for (unsigned i = 0; i < nJets_; i++) { + l1t::PFJet j; + if (i < jets.size()) { + j = jets.at(i); + } else { // pad up to nJets_ with null jets + l1t::PFJet j(0, 0, 0, 0, 0, 0); + } + jet_words.push_back(j.encodedJet()[0]); + jet_words.push_back(j.encodedJet()[1]); + } + return jet_words; +} + +// ------------ method fills 'descriptions' with the allowed parameters for the module ------------ +void L1CTJetFileWriter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + //The following says we do not know what parameters are allowed so do no validation + // Please change this to state exactly what you do use, even if it is no parameters + edm::ParameterSetDescription desc; + desc.add("jets"); + desc.add("outputFilename"); + desc.add("nJets", 12); + desc.add("nFramesPerBX", 9); + desc.add("TMUX", 6); + desc.add("maxLinesPerFile", 1024); + desc.add("format", "EMP"); + descriptions.addDefault(desc); +} + +//define this as a plug-in +DEFINE_FWK_MODULE(L1CTJetFileWriter); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1MHtPFProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1MHtPFProducer.cc new file mode 100644 index 0000000000000..06ad0eb1c2d00 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1MHtPFProducer.cc @@ -0,0 +1,98 @@ +#include +#include + +//////////////////// +//// FRAMEWORK HEADERS +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" + +#include "DataFormats/L1Trigger/interface/EtSum.h" +#include "DataFormats/Math/interface/LorentzVector.h" + +// bitwise emulation headers +#include "L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1PFHtEmulator.h" + +class L1MhtPfProducer : public edm::global::EDProducer<> { +public: + explicit L1MhtPfProducer(const edm::ParameterSet&); + ~L1MhtPfProducer() override; + +private: + void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override; + edm::EDGetTokenT> _jetsToken; + float _minJetPt; + float _maxJetEta; + + std::vector convertEDMToHW(std::vector edmJets) const; + std::vector convertHWToEDM(l1ct::Sum hwSums) const; +}; + +L1MhtPfProducer::L1MhtPfProducer(const edm::ParameterSet& cfg) + : _jetsToken(consumes>(cfg.getParameter("jets"))), + _minJetPt(cfg.getParameter("minJetPt")), + _maxJetEta(cfg.getParameter("maxJetEta")) { + produces>(); +} + +void L1MhtPfProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { + // Get the jets from the event + l1t::PFJetCollection edmJets = iEvent.get(_jetsToken); + + // Apply pT and eta selections + l1t::PFJetCollection edmJetsFiltered; + std::copy_if(edmJets.begin(), edmJets.end(), std::back_inserter(edmJetsFiltered), [&](auto jet) { + return jet.pt() > _minJetPt && std::abs(jet.eta()) < _maxJetEta; + }); + + // Run the emulation + std::vector hwJets = convertEDMToHW(edmJetsFiltered); // convert to the emulator format + l1ct::Sum hwSums = htmht(hwJets); // call the emulator + std::vector edmSums = convertHWToEDM(hwSums); // convert back to edm format + + // Put the sums in the event + std::unique_ptr> mhtCollection(new std::vector(0)); + mhtCollection->push_back(edmSums.at(0)); // HT + mhtCollection->push_back(edmSums.at(1)); // MHT + + iEvent.put(std::move(mhtCollection)); +} + +std::vector L1MhtPfProducer::convertEDMToHW(std::vector edmJets) const { + std::vector hwJets; + std::for_each(edmJets.begin(), edmJets.end(), [&](l1t::PFJet jet) { + l1ct::Jet hwJet = l1ct::Jet::unpack(jet.encodedJet()); + hwJets.push_back(hwJet); + }); + return hwJets; +} + +std::vector L1MhtPfProducer::convertHWToEDM(l1ct::Sum hwSums) const { + std::vector edmSums; + + reco::Candidate::PolarLorentzVector htVector; + htVector.SetPt(hwSums.hwSumPt.to_double()); + htVector.SetPhi(0); + htVector.SetEta(0); + + reco::Candidate::PolarLorentzVector mhtVector; + mhtVector.SetPt(hwSums.hwPt.to_double()); + mhtVector.SetPhi(l1ct::Scales::floatPhi(hwSums.hwPhi)); + mhtVector.SetEta(0); + + l1t::EtSum ht(htVector, l1t::EtSum::EtSumType::kTotalHt); + l1t::EtSum mht(mhtVector, l1t::EtSum::EtSumType::kMissingHt); + + edmSums.push_back(ht); + edmSums.push_back(mht); + return edmSums; +} + +L1MhtPfProducer::~L1MhtPfProducer() {} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1MhtPfProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1METPFProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1MetPfProducer.cc similarity index 69% rename from L1Trigger/Phase2L1ParticleFlow/plugins/L1METPFProducer.cc rename to L1Trigger/Phase2L1ParticleFlow/plugins/L1MetPfProducer.cc index 4ccff7bcb6d21..457aea90637c4 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1METPFProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1MetPfProducer.cc @@ -14,12 +14,10 @@ using namespace l1t; -class L1METPFProducer : public edm::global::EDProducer<> { +class L1MetPfProducer : public edm::global::EDProducer<> { public: - explicit L1METPFProducer(const edm::ParameterSet&); - ~L1METPFProducer() override; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + explicit L1MetPfProducer(const edm::ParameterSet&); + ~L1MetPfProducer() override; private: void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override; @@ -52,18 +50,16 @@ class L1METPFProducer : public edm::global::EDProducer<> { void Project(pt_t pt, phi_t phi, pxy_t& pxy, bool isX, bool debug = false) const; void PhiFromXY(pxy_t px, pxy_t py, phi_t& phi, bool debug = false) const; - void CalcMetHLS(const std::vector& pt, - const std::vector& phi, - reco::Candidate::PolarLorentzVector& metVector) const; + void CalcMetHLS(std::vector pt, std::vector phi, reco::Candidate::PolarLorentzVector& metVector) const; }; -L1METPFProducer::L1METPFProducer(const edm::ParameterSet& cfg) +L1MetPfProducer::L1MetPfProducer(const edm::ParameterSet& cfg) : _l1PFToken(consumes>(cfg.getParameter("L1PFObjects"))), maxCands_(cfg.getParameter("maxCands")) { produces>(); } -void L1METPFProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { +void L1MetPfProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { edm::Handle l1PFCandidates; iEvent.getByToken(_l1PFToken, l1PFCandidates); @@ -87,8 +83,8 @@ void L1METPFProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Even iEvent.put(std::move(metCollection)); } -void L1METPFProducer::CalcMetHLS(const std::vector& pt, - const std::vector& phi, +void L1MetPfProducer::CalcMetHLS(std::vector pt, + std::vector phi, reco::Candidate::PolarLorentzVector& metVector) const { pxy_t hw_px = 0; pxy_t hw_py = 0; @@ -117,7 +113,7 @@ void L1METPFProducer::CalcMetHLS(const std::vector& pt, metVector.SetEta(0); } -void L1METPFProducer::Project(pt_t pt, phi_t phi, pxy_t& pxy, bool isX, bool debug) const { +void L1MetPfProducer::Project(pt_t pt, phi_t phi, pxy_t& pxy, bool isX, bool debug) const { /* Convert pt and phi to px (py) 1) Map phi to the first quadrant to reduce LUT size @@ -134,10 +130,10 @@ void L1METPFProducer::Project(pt_t pt, phi_t phi, pxy_t& pxy, bool isX, bool deb phiQ1 = hwPi_ - phiQ1; if (phiQ1 > hwPiOverTwo_) { - edm::LogWarning("L1METPFProducer") << "unexpected phi (high)"; + std::cout << "unexpected phi (high)" << std::endl; phiQ1 = hwPiOverTwo_; } else if (phiQ1 < 0) { - edm::LogWarning("L1METPFProducer") << "unexpected phi (low)"; + std::cout << "unexpected phi (low)" << std::endl; phiQ1 = 0; } if (isX) { @@ -154,7 +150,7 @@ void L1METPFProducer::Project(pt_t pt, phi_t phi, pxy_t& pxy, bool isX, bool deb } } -void L1METPFProducer::PhiFromXY(pxy_t px, pxy_t py, phi_t& phi, bool debug) const { +void L1MetPfProducer::PhiFromXY(pxy_t px, pxy_t py, phi_t& phi, bool debug) const { if (px == 0 && py == 0) { phi = 0; return; @@ -185,25 +181,26 @@ void L1METPFProducer::PhiFromXY(pxy_t px, pxy_t py, phi_t& phi, bool debug) cons inv_t a_over_b = a * inv_b; if (debug) { - LogDebug("L1METPFProducer") << " a, b = \n " << a.to_double() << " , " << b.to_double() - << "; index, inv = " << index << ", " << inv_b.to_double() - << "; ratio= " << a_over_b.to_double() << " \n" - << std::endl; - LogDebug("L1METPFProducer") << "bcheck, 1/bc = " << bcheck << ", " << 1. / bcheck << " -- " << invTableSize_ << " " - << maxPt_ << " " << dropFactor_ << " \n" - << std::endl; + printf(" a, b = %f, %f; index, inv = %d, %f; ratio = %f \n", + a.to_double(), + b.to_double(), + index, + inv_b.to_double(), + a_over_b.to_double()); + printf(" bcheck, 1/bc = %f, %f -- %d %f %d \n", bcheck, 1. / bcheck, invTableSize_, maxPt_, dropFactor_); } - const int atanTableBits_ = 7; - const int atanTableSize_ = (1 << atanTableBits_); + int atanTableBits_ = 7; + int atanTableSize_ = (1 << atanTableBits_); index = round(a_over_b.to_double() * atanTableSize_); phi = atan(float(index) / atanTableSize_) / phiLSB_; if (debug) { - LogDebug("L1METPFProducer") << " atan index, phi = " << index << ", " << phi.to_double() << " (" - << phi.to_double() * (M_PI / hwPi_.to_double()) - << " rad) real atan(a/b)= " << atan(a.to_double() / b.to_double()) << " \n" - << std::endl; + printf(" atan index, phi = %d, %f (%f rad) real atan(a/b)= %f \n", + index, + phi.to_double(), + phi.to_double() * (M_PI / hwPi_.to_double()), + atan(a.to_double() / b.to_double())); } // rotate from (0,pi/4) to full quad1 @@ -218,22 +215,16 @@ void L1METPFProducer::PhiFromXY(pxy_t px, pxy_t py, phi_t& phi, bool debug) cons phi = -(hwPi_ - phi); // Q3 composition of both if (debug) { - LogDebug("L1METPFProducer") << " phi hw, float, real = " << phi.to_double() << ", " - << phi.to_double() * (M_PI / hwPi_.to_double()) << " (" - << atan2(py.to_double(), px.to_double()) << " rad from x,y = " << px.to_double() << ", " - << py.to_double() << ") \n" - << std::endl; + printf(" phi hw, float, real = %f, %f (%f rad from x,y = %f, %f) \n", + phi.to_double(), + phi.to_double() * (M_PI / hwPi_.to_double()), + atan2(py.to_double(), px.to_double()), + px.to_double(), + py.to_double()); } } -void L1METPFProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - edm::ParameterSetDescription desc; - desc.add("maxCandidates", 128); - desc.add("L1PFObjects", edm::InputTag("L1PFProducer", "l1pfCandidates")); - descriptions.add("L1METPFProducer", desc); -} - -L1METPFProducer::~L1METPFProducer() {} +L1MetPfProducer::~L1MetPfProducer() {} #include "FWCore/Framework/interface/MakerMacros.h" -DEFINE_FWK_MODULE(L1METPFProducer); +DEFINE_FWK_MODULE(L1MetPfProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1NNTauProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1NNTauProducer.cc index 474986195d7fc..8e599421cb7dd 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1NNTauProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1NNTauProducer.cc @@ -1,4 +1,5 @@ #include "DataFormats/Math/interface/deltaR.h" +#include #include #include @@ -11,6 +12,10 @@ #include "DataFormats/L1TParticleFlow/interface/PFTau.h" #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/TauNNId.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/TauNNIdHW.h" + +#include "ap_int.h" +#include "ap_fixed.h" using namespace l1t; @@ -25,16 +30,26 @@ class L1NNTauProducer : public edm::stream::EDProducer fTauNNId_; + std::unique_ptr fTauNNIdHW_; + + void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; + void process_SW(const l1t::PFCandidateCollection& parts, std::unique_ptr& iTaus); + void process_HW(const l1t::PFCandidateCollection& parts, std::unique_ptr& iTaus) const; + void makeTau_HW(const l1t::PFCandidate& seed, + l1t::PFCandidateCollection& parts, + std::unique_ptr& iTaus) const; + void addTau(const l1t::PFCandidate& iCand, const l1t::PFCandidateCollection& iParts, std::unique_ptr& outputTaus); - void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; double fSeedPt_; double fConeSize_; double fTauSize_; int fMaxTaus_; int fNParticles_; + bool fHW; + bool fDebug; edm::EDGetTokenT> fL1PFToken_; }; @@ -46,12 +61,21 @@ L1NNTauProducer::L1NNTauProducer(const edm::ParameterSet& cfg, const TauNNTFCach fTauSize_(cfg.getParameter("tausize")), fMaxTaus_(cfg.getParameter("maxtaus")), fNParticles_(cfg.getParameter("nparticles")), + fHW(cfg.getParameter("HW")), + fDebug(cfg.getParameter("debug")), fL1PFToken_(consumes>(cfg.getParameter("L1PFObjects"))) { std::string lNNFile = cfg.getParameter("NNFileName"); //,"L1Trigger/Phase2L1Taus/data/tau_3layer.pb"); - fTauNNId_ = std::make_unique( - lNNFile.find("v0") == std::string::npos ? "input_1:0" : "dense_1_input:0", cache, lNNFile, fNParticles_); + + if (fHW) { + fTauNNIdHW_ = std::make_unique(); + fTauNNIdHW_->initialize("input_1:0", fNParticles_); + } else { + fTauNNId_ = std::make_unique( + lNNFile.find("v0") == std::string::npos ? "input_1:0" : "dense_1_input:0", cache, lNNFile, fNParticles_); + } produces("L1PFTausNN"); } + std::unique_ptr L1NNTauProducer::initializeGlobalCache(const edm::ParameterSet& cfg) { tensorflow::setLogging("3"); std::string lNNFile = cfg.getParameter("NNFileName"); @@ -68,28 +92,38 @@ void L1NNTauProducer::globalEndJob(const TauNNTFCache* cache) { void L1NNTauProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { edm::Handle l1PFCandidates; iEvent.getByToken(fL1PFToken_, l1PFCandidates); + auto lTaus = std::make_unique(); + + if (fHW) { + process_HW(*l1PFCandidates, lTaus); + } else { + process_SW(*l1PFCandidates, lTaus); + } + if (lTaus->empty()) { + PFTau dummy; + lTaus->push_back(dummy); + } + std::sort(lTaus->begin(), lTaus->end(), [](l1t::PFTau i, l1t::PFTau j) { return (i.pt() > j.pt()); }); + iEvent.put(std::move(lTaus), "L1PFTausNN"); +} +void L1NNTauProducer::process_SW(const l1t::PFCandidateCollection& parts, + std::unique_ptr& iTaus) { + std::vector> pfChargedHadrons; std::vector> pfChargedHadrons_sort_v; std::vector> pfChargedHadrons_seeds_v; - for (const auto& l1PFCand : *l1PFCandidates) + for (const auto& l1PFCand : parts) if ((l1PFCand.id() == l1t::PFCandidate::ChargedHadron || l1PFCand.id() == l1t::PFCandidate::Electron) && std::abs(l1PFCand.eta()) < track_trigger_eta_max) pfChargedHadrons_sort_v.push_back(std::make_unique(l1PFCand)); + if (pfChargedHadrons_sort_v.empty()) + return; std::sort( pfChargedHadrons_sort_v.begin(), pfChargedHadrons_sort_v.end(), [](std::unique_ptr& i, std::unique_ptr& j) { return (i->pt() > j->pt()); }); - auto lTaus = std::make_unique(); - if (pfChargedHadrons_sort_v.empty()) { - if (lTaus->empty()) { - PFTau dummy; - lTaus->push_back(dummy); - } - iEvent.put(std::move(lTaus), "L1PFTausNN"); - return; - } pfChargedHadrons_seeds_v.push_back(std::move(pfChargedHadrons_sort_v[0])); for (unsigned int i0 = 1; i0 < pfChargedHadrons_sort_v.size(); i0++) { bool pMatch = false; @@ -104,14 +138,8 @@ void L1NNTauProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) break; } for (unsigned int i0 = 0; i0 < pfChargedHadrons_seeds_v.size(); i0++) { - addTau(*(pfChargedHadrons_seeds_v[i0]), (*l1PFCandidates), lTaus); - } - if (lTaus->empty()) { - PFTau dummy; - lTaus->push_back(dummy); + addTau(*(pfChargedHadrons_seeds_v[i0]), parts, iTaus); } - std::sort(lTaus->begin(), lTaus->end(), [](l1t::PFTau i, l1t::PFTau j) { return (i.pt() > j.pt()); }); - iEvent.put(std::move(lTaus), "L1PFTausNN"); } // create taus based on grid structure @@ -122,6 +150,8 @@ void L1NNTauProducer::addTau(const l1t::PFCandidate& iCand, math::PtEtaPhiMLorentzVector lTot(0, 0, 0, 0); math::PtEtaPhiMLorentzVector lCand(0, 0, 0, 0); int lId = 0; + float z0 = 0; + float dxy = 0; for (const auto& l1PFCand : iParts) { if (reco::deltaR2(iCand, l1PFCand) > fConeSize_ * fConeSize_) continue; @@ -132,6 +162,10 @@ void L1NNTauProducer::addTau(const l1t::PFCandidate& iCand, l1PFCand.id() == l1t::PFCandidate::Photon)) { lId++; lCand += pVec; + if (z0 == 0 && l1PFCand.id() == l1t::PFCandidate::ChargedHadron) { + z0 = l1PFCand.z0(); + dxy = l1PFCand.dxy(); + } } pfTauCands.push_back(l1PFCand); } @@ -140,8 +174,10 @@ void L1NNTauProducer::addTau(const l1t::PFCandidate& iCand, std::sort( pfTauCands.begin(), pfTauCands.end(), [](l1t::PFCandidate i, l1t::PFCandidate j) { return (i.pt() > j.pt()); }); float NN = fTauNNId_->compute(iCand, pfTauCands); - math::PtEtaPhiMLorentzVector tempP4(lCand.Pt(), lCand.Eta(), lCand.Phi(), lCand.M()); + math::PtEtaPhiMLorentzVector tempP4(lCand.Pt(), lCand.Eta(), lCand.Phi(), lCand.M() * lCand.M()); l1t::PFTau l1PFTau(tempP4, NN, 0, lId); + l1PFTau.setZ0(z0); + l1PFTau.setDxy(dxy); outputTaus->push_back(l1PFTau); } void L1NNTauProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { @@ -153,9 +189,127 @@ void L1NNTauProducer::fillDescriptions(edm::ConfigurationDescriptions& descripti desc.add("nparticles", 10); desc.add("conesize", 0.4); desc.add("seedpt", 20); + desc.add("HW", true); + desc.add("debug", false); desc.add("L1PFObjects", edm::InputTag("L1PFProducer", "l1pfCandidates")); descriptions.add("L1NNTauProducer", desc); } + +void L1NNTauProducer::makeTau_HW(const l1t::PFCandidate& seed, + l1t::PFCandidateCollection& parts, + std::unique_ptr& iTaus) const { + // Seed Cone Jet algorithm with ap_fixed types and hardware emulation + L1TauEmu::detaphi_t rCone2 = + L1TauEmu::detaphi_t(fTauSize_ * fTauSize_ * L1TauEmu::etaphi_base * L1TauEmu::etaphi_base); + unsigned lId = 0; + L1TauEmu::pt_t pt_tot = 0; + input2_t p1_tot = 0; + input2_t p1x_tot = 0; + input2_t p1y_tot = 0; + input2_t p1z_tot = 0; + + float p_tot = 0; + float px_tot = 0; + float py_tot = 0; + float pz_tot = 0; + + float eta_1 = seed.eta(); + float phi_1 = seed.phi(); + input_t e1ta_1 = seed.eta(); + input_t p1hi_1 = seed.phi(); + L1TauEmu::pt_t pt = 0; + L1TauEmu::z0_t z0 = 0; + L1TauEmu::dxy_t dxy = 0; + for (unsigned i0 = 0; i0 < parts.size(); i0++) { + pt_tot = pt_tot + L1TauEmu::pt_t(parts[i0].pt()); + if (L1TauEmu::inCone(seed, (parts[i0]), rCone2)) { + if (parts[i0].id() == l1t::PFCandidate::Electron || parts[i0].id() == l1t::PFCandidate::ChargedHadron || + parts[i0].id() == l1t::PFCandidate::Photon) { + lId++; + pt = pt + L1TauEmu::pt_t(parts[i0].pt()); + float deta = parts[i0].eta() - eta_1; + float dphi = parts[i0].phi() - phi_1; + float dr2 = deta * deta + dphi * dphi; + pz_tot = pz_tot + (parts[i0].pt()) * (1 - dr2 * 0.5); + py_tot = py_tot + (parts[i0].pt()) * dphi; //sin(dphi )); + px_tot = px_tot + (parts[i0].pt()) * deta; //sin(deta )); + + input2_t d1eta = input_t(parts[i0].eta()) - e1ta_1; + input2_t d1phi = input_t(parts[i0].phi()) - p1hi_1; + input2_t d1r2 = d1eta * d1eta + d1phi * d1phi; + input2_t tmppt = input_t(parts[i0].pt()); + input2_t half = 0.5; + p1z_tot = p1z_tot + tmppt * (1 - d1r2 * half); + p1y_tot = p1y_tot + tmppt * d1phi; + p1x_tot = p1x_tot + tmppt * d1eta; + p_tot = p_tot + (parts[i0].pt()); + p1_tot = p1_tot + tmppt; + if (z0 == 0 && parts[i0].id() == l1t::PFCandidate::ChargedHadron) { + z0 = parts[i0].hwZ0(); + dxy = parts[i0].hwDxy(); + } + } + } + } + input2_t tmpmass1 = (p1_tot * p1_tot - p1x_tot * p1x_tot - p1y_tot * p1y_tot - p1z_tot * p1z_tot); + if (tmpmass1 < 0) + tmpmass1 = 0; + L1TauEmu::pt_t mass = l1ct::pt_t(tmpmass1); + if (pt < fSeedPt_) + return; + result_t NN = fTauNNIdHW_->compute(seed, parts); + L1TauEmu::etaphi_t eta = etaphi_t(seed.eta() * L1TauEmu::etaphi_base); + L1TauEmu::etaphi_t phi = etaphi_t(seed.phi() * L1TauEmu::etaphi_base); + math::PtEtaPhiMLorentzVector tempP4( + float(pt), float(eta) / L1TauEmu::etaphi_base, float(phi) / L1TauEmu::etaphi_base, float(mass)); + l1t::PFTau l1PFTau(tempP4, NN, 0, lId); + l1PFTau.setZ0(float(z0) * L1TauEmu::z0_base); + l1PFTau.setDxy(float(dxy) * L1TauEmu::dxy_base); + iTaus->push_back(l1PFTau); +} + +void L1NNTauProducer::process_HW(const l1t::PFCandidateCollection& parts, + std::unique_ptr& iTaus) const { + // The fixed point algorithm emulation + using namespace L1TauEmu; + std::vector work; + work.resize(parts.size()); + std::transform(parts.begin(), parts.end(), work.begin(), [](const l1t::PFCandidate& part) { return part; }); + std::sort(work.begin(), work.end(), [](l1t::PFCandidate i, l1t::PFCandidate j) { + return (l1ct::pt_t(i.pt()) > l1ct::pt_t(j.pt())); + }); + std::vector seeds; + std::copy_if(work.begin(), work.end(), std::back_inserter(seeds), [&](const l1t::PFCandidate& part) { + return ((part.id() == l1t::PFCandidate::Electron || part.id() == l1t::PFCandidate::ChargedHadron) && + std::abs(part.eta()) < track_trigger_eta_max); + }); + // It would be nice to transform the inputs to the etaphi_base of the FW here, as in the line below + // However the phi may wrap around if the etaphi_base > 1, so don't do it... + //std::for_each(work.begin(), work.end(), [](l1t::PFCandidate& x){x.setP4(math::PtEtaPhiMLorentzVector(pt_t(x.pt()), etaphi_t(x.eta()*etaphi_base), etaphi_t(x.phi()*etaphi_base), x.mass()));}); + detaphi_t rCone2 = detaphi_t(fConeSize_ * fConeSize_ * etaphi_base * etaphi_base); + + iTaus->reserve(fMaxTaus_); + while (!seeds.empty() && iTaus->size() < unsigned(fMaxTaus_)) { + // Take the first (highest pt) candidate as a seed + l1t::PFCandidate seed = seeds.at(0); + // Get the particles within a _coneSize of the seed + std::vector particlesInCone; + std::copy_if(work.begin(), work.end(), std::back_inserter(particlesInCone), [&](l1t::PFCandidate& part) { + return inCone(seed, part, rCone2); + }); + makeTau_HW(seed, particlesInCone, iTaus); + // remove the clustered particles + work.erase(std::remove_if( + work.begin(), work.end(), [&](const l1t::PFCandidate& part) { return inCone(seed, part, rCone2); }), + work.end()); + + seeds.erase( + std::remove_if( + seeds.begin(), seeds.end(), [&](const l1t::PFCandidate& part) { return inCone(seed, part, rCone2); }), + seeds.end()); + } +} + L1NNTauProducer::~L1NNTauProducer() {} #include "FWCore/Framework/interface/MakerMacros.h" diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc new file mode 100644 index 0000000000000..68577119804bb --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1SeedConePFJetProducer.cc @@ -0,0 +1,196 @@ + +#include +#include + +//////////////////// +// FRAMEWORK HEADERS +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "DataFormats/L1TParticleFlow/interface/PFJet.h" +#include "DataFormats/Math/interface/deltaR.h" + +// bitwise emulation headers +#include "L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h" +#include "DataFormats/L1TParticleFlow/interface/gt_datatypes.h" + +class L1SeedConePFJetProducer : public edm::global::EDProducer<> { +public: + explicit L1SeedConePFJetProducer(const edm::ParameterSet&); + ~L1SeedConePFJetProducer() override; + +private: + /// ///////////////// /// + /// MANDATORY METHODS /// + void produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override; + /// ///////////////// /// + + float _coneSize; + unsigned _nJets; + bool _HW; + bool _debug; + L1SCJetEmu _emulator; + edm::EDGetTokenT> _l1PFToken; + + 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); + + static std::vector convertHWToEDM( + std::vector hwJets, + std::unordered_map> constituentMap); +}; + +L1SeedConePFJetProducer::L1SeedConePFJetProducer(const edm::ParameterSet& cfg) + : _coneSize(cfg.getParameter("coneSize")), + _nJets(cfg.getParameter("nJets")), + _HW(cfg.getParameter("HW")), + _debug(cfg.getParameter("debug")), + _emulator(L1SCJetEmu(_debug, _coneSize, _nJets)), + _l1PFToken(consumes>(cfg.getParameter("L1PFObjects"))) { + produces(); +} + +void L1SeedConePFJetProducer::produce(edm::StreamID /*unused*/, + edm::Event& iEvent, + const edm::EventSetup& iSetup) const { + std::unique_ptr newPFJetCollection(new l1t::PFJetCollection); + + edm::Handle l1PFCandidates; + iEvent.getByToken(_l1PFToken, l1PFCandidates); + + std::vector> particles; + for (unsigned i = 0; i < (*l1PFCandidates).size(); i++) { + particles.push_back(edm::Ptr(l1PFCandidates, i)); + } + + std::vector jets; + if (_HW) { + jets = processEvent_HW(particles); + } else { + jets = processEvent_SW(particles); + } + + std::sort(jets.begin(), jets.end(), [](l1t::PFJet i, l1t::PFJet j) { return (i.pt() > j.pt()); }); + newPFJetCollection->swap(jets); + iEvent.put(std::move(newPFJetCollection)); +} + +///////////// +// DESTRUCTOR +L1SeedConePFJetProducer::~L1SeedConePFJetProducer() {} + +l1t::PFJet L1SeedConePFJetProducer::makeJet_SW(const std::vector>& parts) const { + l1t::PFCandidate seed = *parts.at(0); + + auto sumpt = [](float a, const edm::Ptr& b) { return a + b->pt(); }; + + // Sum the pt + float pt = std::accumulate(parts.begin(), parts.end(), 0., sumpt); + + // pt weighted d eta + std::vector pt_deta; + pt_deta.resize(parts.size()); + std::transform(parts.begin(), parts.end(), pt_deta.begin(), [&seed, &pt](const edm::Ptr& part) { + return (part->pt() / pt) * (part->eta() - seed.eta()); + }); + // Accumulate the pt weighted etas. Init to the seed eta, start accumulating at begin()+1 to skip seed + float eta = std::accumulate(pt_deta.begin() + 1, pt_deta.end(), seed.eta()); + + // pt weighted d phi + std::vector pt_dphi; + pt_dphi.resize(parts.size()); + std::transform(parts.begin(), parts.end(), pt_dphi.begin(), [&seed, &pt](const edm::Ptr& part) { + return (part->pt() / pt) * reco::deltaPhi(part->phi(), seed.phi()); + }); + // Accumulate the pt weighted phis. Init to the seed phi, start accumulating at begin()+1 to skip seed + float phi = std::accumulate(pt_dphi.begin() + 1, pt_dphi.end(), seed.phi()); + + l1t::PFJet jet(pt, eta, phi); + for (auto it = parts.begin(); it != parts.end(); it++) { + jet.addConstituent(*it); + } + + return jet; +} + +std::vector L1SeedConePFJetProducer::processEvent_SW(std::vector>& work) const { + // The floating point algorithm simulation + std::stable_sort(work.begin(), work.end(), [](edm::Ptr i, edm::Ptr j) { + return (i->pt() > j->pt()); + }); + std::vector jets; + jets.reserve(_nJets); + while (!work.empty() && jets.size() < _nJets) { + // Take the first (highest pt) candidate as a seed + edm::Ptr seed = work.at(0); + // 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) { + return reco::deltaR(*seed, *part) <= _coneSize; + }); + jets.push_back(makeJet_SW(particlesInCone)); + // remove the clustered particles + work.erase(std::remove_if(work.begin(), + work.end(), + [&](const edm::Ptr& part) { + return reco::deltaR(*seed, *part) <= _coneSize; + }), + work.end()); + } + return jets; +} + +std::vector L1SeedConePFJetProducer::processEvent_HW(std::vector>& work) const { + // The fixed point emulator + // Convert the EDM format to the hardware format, and call the standalone emulator + std::pair, std::unordered_map>> + particles = convertEDMToHW(work); + std::vector jets = _emulator.emulateEvent(particles.first); + return convertHWToEDM(jets, particles.second); +} + +std::pair, std::unordered_map>> +L1SeedConePFJetProducer::convertEDMToHW(std::vector>& edmParticles) { + std::vector hwParticles; + std::unordered_map> candidateMap; + std::for_each(edmParticles.begin(), edmParticles.end(), [&](edm::Ptr& edmParticle) { + l1ct::PuppiObjEmu particle; + particle.initFromBits(edmParticle->encodedPuppi64()); + particle.srcCand = edmParticle.get(); + candidateMap.insert(std::make_pair(edmParticle.get(), edmParticle)); + hwParticles.push_back(particle); + }); + return std::make_pair(hwParticles, candidateMap); +} + +std::vector L1SeedConePFJetProducer::convertHWToEDM( + std::vector hwJets, + std::unordered_map> constituentMap) { + 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()); + // 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" +DEFINE_FWK_MODULE(L1SeedConePFJetProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc index b642a1bc3f5cb..46b76e20f45a5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrectedPFJetProducer.cc @@ -1,5 +1,8 @@ #include "DataFormats/L1TParticleFlow/interface/PFJet.h" #include "DataFormats/JetReco/interface/Jet.h" +#include "DataFormats/Candidate/interface/Candidate.h" + +#include "DataFormats/Candidate/interface/Candidate.h" #include "FWCore/Framework/interface/global/EDProducer.h" #include "FWCore/Framework/interface/Event.h" @@ -18,22 +21,21 @@ 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_; - bool copyDaughters_; }; L1TCorrectedPFJetProducer::L1TCorrectedPFJetProducer(const edm::ParameterSet& iConfig) - : jets_(consumes>(iConfig.getParameter("jets"))), - corrector_(iConfig.getParameter("correctorFile"), iConfig.getParameter("correctorDir")), - copyDaughters_(iConfig.getParameter("copyDaughters")) { + : jets_(consumes>(iConfig.getParameter("jets"))), + corrector_(iConfig.getParameter("correctorFile"), + iConfig.getParameter("correctorDir")) { 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>(); @@ -42,11 +44,11 @@ void L1TCorrectedPFJetProducer::produce(edm::StreamID, edm::Event& iEvent, const out->emplace_back(srcjet.p4()); auto& jet = out->back(); // copy daughters - if (copyDaughters_) { - for (const auto& dau : srcjet.daughterPtrVector()) { - jet.addConstituent(edm::Ptr(dau)); - } - } + //if (copyDaughters_) { + // for (const auto& dau : srcjet.daughterPtrVector()) { + // jet.addConstituent(edm::Ptr(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 new file mode 100644 index 0000000000000..e173c3c773bdb --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCorrelatorLayer1Producer.cc @@ -0,0 +1,1117 @@ +// system include files +#include +#include +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/FileInPath.h" + +#include "DataFormats/Common/interface/View.h" +#include "DataFormats/Common/interface/RefToPtr.h" +#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" +#include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" + +#include "DataFormats/Math/interface/deltaR.h" + +#include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/muonGmtToL1ct_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h" +#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/L1TCorrelatorLayer1PatternFileWriter.h" + +#include "DataFormats/L1TCorrelator/interface/TkElectron.h" +#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1TCorrelator/interface/TkEm.h" +#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" + +//-------------------------------------------------------------------------------------------------- +class L1TCorrelatorLayer1Producer : public edm::stream::EDProducer<> { +public: + explicit L1TCorrelatorLayer1Producer(const edm::ParameterSet &); + ~L1TCorrelatorLayer1Producer() override; + +private: + edm::ParameterSet config_; + + bool hasTracks_; + edm::EDGetTokenT tkCands_; + float trkPt_; + bool emuTkVtx_; + edm::EDGetTokenT> extTkVtx_; + edm::EDGetTokenT> tkVtxEmu_; + int NVtx_; + + edm::EDGetTokenT muCands_; // standalone muons + + std::vector> emCands_; + std::vector> hadCands_; + + float emPtCut_, hadPtCut_; + + l1ct::Event event_; + std::unique_ptr trackInput_; + std::unique_ptr muonInput_; + std::unique_ptr regionizer_; + std::unique_ptr l1pfalgo_; + std::unique_ptr l1pualgo_; + std::unique_ptr l1tkegalgo_; + std::unique_ptr l1tkegsorter_; + + bool writeEgSta_; + // Region dump + const std::string regionDumpName_; + bool writeRawHgcalCluster_; + std::fstream fRegionDump_; + std::vector patternWriterConfigs_; + std::vector> patternWriters_; + + // region of interest debugging + float debugEta_, debugPhi_, debugR_; + + // these are used to link items back + std::unordered_map clusterRefMap_; + std::unordered_map trackRefMap_; + std::unordered_map muonRefMap_; + + // main methods + void beginStream(edm::StreamID) override; + void endStream() override; + void produce(edm::Event &, const edm::EventSetup &) override; + void addUInt(unsigned int value, std::string iLabel, edm::Event &iEvent); + + void initSectorsAndRegions(const edm::ParameterSet &iConfig); + void initEvent(const edm::Event &e); + // add object, tracking references + void addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref); + void addMuon(const l1t::SAMuon &t, l1t::PFCandidate::MuonRef ref); + void addHadCalo(const l1t::PFCluster &t, l1t::PFClusterRef ref); + void addEmCalo(const l1t::PFCluster &t, l1t::PFClusterRef ref); + // add objects in already-decoded format + void addDecodedTrack(l1ct::DetectorSector &sec, const l1t::PFTrack &t); + void addDecodedMuon(l1ct::DetectorSector &sec, const l1t::SAMuon &t); + void addDecodedHadCalo(l1ct::DetectorSector &sec, const l1t::PFCluster &t); + void addDecodedEmCalo(l1ct::DetectorSector &sec, const l1t::PFCluster &t); + + void addRawHgcalCluster(l1ct::DetectorSector> &sec, const l1t::PFCluster &c); + + // fetching outputs + std::unique_ptr fetchHadCalo() const; + std::unique_ptr fetchEmCalo() const; + std::unique_ptr fetchTracks() const; + std::unique_ptr fetchPF() const; + void putPuppi(edm::Event &iEvent) const; + + void putEgStaObjects(edm::Event &iEvent, + const std::string &egLablel, + std::vector>> &egsta_refs); + void putEgObjects(edm::Event &iEvent, + const bool writeEgSta, + const std::vector>> &egsta_refs, + const std::string &tkEmLabel, + const std::string &tkEmPerBoardLabel, + const std::string &tkEleLabel, + const std::string &tkElePerBoardLabel) const; + + template + void setRefs_(l1t::PFCandidate &pf, const T &p) const; + + void doVertexings(std::vector &pvdz) const; + // for multiplicities + enum InputType { caloType = 0, emcaloType = 1, trackType = 2, l1muType = 3 }; + static constexpr const char *inputTypeName[l1muType + 1] = {"Calo", "EmCalo", "TK", "Mu"}; + std::unique_ptr> vecSecInput(InputType i) const; + std::unique_ptr> vecRegInput(InputType i) const; + typedef l1ct::OutputRegion::ObjType OutputType; + std::unique_ptr> vecOutput(OutputType i, bool usePuppi) const; + std::pair totAndMax(const std::vector &perRegion) const; +}; + +// +// constructors and destructor +// +L1TCorrelatorLayer1Producer::L1TCorrelatorLayer1Producer(const edm::ParameterSet &iConfig) + : config_(iConfig), + hasTracks_(!iConfig.getParameter("tracks").label().empty()), + tkCands_(hasTracks_ ? consumes(iConfig.getParameter("tracks")) + : edm::EDGetTokenT()), + trkPt_(iConfig.getParameter("trkPtCut")), + muCands_(consumes(iConfig.getParameter("muons"))), + emPtCut_(iConfig.getParameter("emPtCut")), + hadPtCut_(iConfig.getParameter("hadPtCut")), + regionizer_(nullptr), + l1pfalgo_(nullptr), + l1pualgo_(nullptr), + l1tkegalgo_(nullptr), + l1tkegsorter_(nullptr), + regionDumpName_(iConfig.getUntrackedParameter("dumpFileName", "")), + writeRawHgcalCluster_(iConfig.getUntrackedParameter("writeRawHgcalCluster", false)), + patternWriterConfigs_(iConfig.getUntrackedParameter>( + "patternWriters", std::vector())), + debugEta_(iConfig.getUntrackedParameter("debugEta", 0)), + debugPhi_(iConfig.getUntrackedParameter("debugPhi", 0)), + debugR_(iConfig.getUntrackedParameter("debugR", -1)) { + produces("PF"); + produces("Puppi"); + produces("PuppiRegional"); + + produces("EmCalo"); + produces("Calo"); + produces("TK"); +#if 0 // LATER + produces("TKVtx"); +#endif + + for (const auto &tag : iConfig.getParameter>("emClusters")) { + emCands_.push_back(consumes(tag)); + } + for (const auto &tag : iConfig.getParameter>("hadClusters")) { + hadCands_.push_back(consumes(tag)); + } + + if (hasTracks_) { + const std::string &tkInAlgo = iConfig.getParameter("trackInputConversionAlgo"); + if (tkInAlgo == "Emulator") { + trackInput_ = std::make_unique( + iConfig.getParameter("trackInputConversionParameters")); + } else if (tkInAlgo != "Ideal") + throw cms::Exception("Configuration", "Unsupported trackInputConversionAlgo"); + } + + const std::string &muInAlgo = iConfig.getParameter("muonInputConversionAlgo"); + if (muInAlgo == "Emulator") { + muonInput_ = std::make_unique( + iConfig.getParameter("muonInputConversionParameters")); + } else if (muInAlgo != "Ideal") + throw cms::Exception("Configuration", "Unsupported muonInputConversionAlgo"); + + const std::string ®algo = iConfig.getParameter("regionizerAlgo"); + if (regalgo == "Ideal") { + regionizer_ = + std::make_unique(iConfig.getParameter("regionizerAlgoParameters")); + } else if (regalgo == "Multififo") { + regionizer_ = std::make_unique( + iConfig.getParameter("regionizerAlgoParameters")); + } else if (regalgo == "TDR") { + regionizer_ = std::make_unique( + iConfig.getParameter("regionizerAlgoParameters")); + } else + throw cms::Exception("Configuration", "Unsupported regionizerAlgo"); + + const std::string &algo = iConfig.getParameter("pfAlgo"); + if (algo == "PFAlgo3") { + l1pfalgo_ = std::make_unique(iConfig.getParameter("pfAlgoParameters")); + } else if (algo == "PFAlgo2HGC") { + l1pfalgo_ = std::make_unique(iConfig.getParameter("pfAlgoParameters")); + } else if (algo == "PFAlgoDummy") { + l1pfalgo_ = + std::make_unique(iConfig.getParameter("pfAlgoParameters")); + } else + throw cms::Exception("Configuration", "Unsupported pfAlgo"); + + const std::string &pualgo = iConfig.getParameter("puAlgo"); + if (pualgo == "LinearizedPuppi") { + l1pualgo_ = std::make_unique(iConfig.getParameter("puAlgoParameters")); + } else + throw cms::Exception("Configuration", "Unsupported puAlgo"); + + l1tkegalgo_ = std::make_unique( + l1ct::PFTkEGAlgoEmuConfig(iConfig.getParameter("tkEgAlgoParameters"))); + + l1tkegsorter_ = + std::make_unique(iConfig.getParameter("tkEgSorterParameters")); + + if (l1tkegalgo_->writeEgSta()) + produces>("L1Eg"); + produces("L1TkEle"); + produces("L1TkElePerBoard"); + produces("L1TkEm"); + produces("L1TkEmPerBoard"); + + emuTkVtx_ = iConfig.getParameter("vtxCollectionEmulation"); + if (emuTkVtx_) { + tkVtxEmu_ = consumes>(iConfig.getParameter("vtxCollection")); + } else { + extTkVtx_ = consumes>(iConfig.getParameter("vtxCollection")); + } + NVtx_ = iConfig.getParameter("nVtx"); + + const char *iprefix[4] = {"totNReg", "maxNReg", "totNSec", "maxNSec"}; + for (int i = 0; i <= l1muType; ++i) { + for (int ip = 0; ip < 4; ++ip) { + produces(std::string(iprefix[ip]) + inputTypeName[i]); + } + produces>(std::string("vecNReg") + inputTypeName[i]); + produces>(std::string("vecNSec") + inputTypeName[i]); + } + const char *oprefix[4] = {"totNPF", "maxNPF", "totNPuppi", "maxNPuppi"}; + for (int i = 0; i < l1ct::OutputRegion::nPFTypes; ++i) { + for (int ip = 0; ip < 4; ++ip) { + produces(std::string(oprefix[ip]) + l1ct::OutputRegion::objTypeName[i]); + } + produces>(std::string("vecNPF") + l1ct::OutputRegion::objTypeName[i]); + produces>(std::string("vecNPuppi") + l1ct::OutputRegion::objTypeName[i]); + } + + initSectorsAndRegions(iConfig); +} + +L1TCorrelatorLayer1Producer::~L1TCorrelatorLayer1Producer() {} + +void L1TCorrelatorLayer1Producer::beginStream(edm::StreamID id) { + if (!regionDumpName_.empty()) { + if (id == 0) { + fRegionDump_.open(regionDumpName_.c_str(), std::ios::out | std::ios::binary); + } else { + edm::LogWarning("L1TCorrelatorLayer1Producer") + << "Job running with multiple streams, but dump file will have only events on stream zero."; + } + } + if (!patternWriterConfigs_.empty()) { + if (id == 0) { + for (const auto &pset : patternWriterConfigs_) { + patternWriters_.emplace_back(std::make_unique(pset, event_)); + } + } else { + edm::LogWarning("L1TCorrelatorLayer1Producer") + << "Job running with multiple streams, but pattern files will be written only on stream zero."; + } + } +} + +void L1TCorrelatorLayer1Producer::endStream() { + for (auto &writer : patternWriters_) { + writer->flush(); + } +} + +// ------------ method called to produce the data ------------ +void L1TCorrelatorLayer1Producer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + // clear the regions also at the beginning, in case one event didn't complete but the job continues on + initEvent(iEvent); + + /// ------ READ TRACKS ---- + if (hasTracks_) { + edm::Handle htracks; + iEvent.getByToken(tkCands_, htracks); + const auto &tracks = *htracks; + for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) { + const auto &tk = tracks[itk]; + // adding objects to PF + if (debugR_ > 0 && deltaR(tk.eta(), tk.phi(), debugEta_, debugPhi_) > debugR_) + continue; + if (tk.pt() > trkPt_) { + addTrack(tk, l1t::PFTrackRef(htracks, itk)); + } + } + } + + /// ------ READ MUONS ---- + edm::Handle muons; + iEvent.getByToken(muCands_, muons); + for (unsigned int i = 0, n = muons->size(); i < n; ++i) { + const l1t::SAMuon &mu = (*muons)[i]; + if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_) + continue; + addMuon(mu, l1t::PFCandidate::MuonRef(muons, i)); + } + // ------ READ CALOS ----- + edm::Handle caloHandle; + for (const auto &tag : emCands_) { + iEvent.getByToken(tag, caloHandle); + const auto &calos = *caloHandle; + for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) { + const auto &calo = calos[ic]; + if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_) + continue; + if (calo.pt() > emPtCut_) + addEmCalo(calo, l1t::PFClusterRef(caloHandle, ic)); + } + } + for (const auto &tag : hadCands_) { + iEvent.getByToken(tag, caloHandle); + const auto &calos = *caloHandle; + for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) { + const auto &calo = calos[ic]; + if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_) + continue; + if (calo.pt() > hadPtCut_) + addHadCalo(calo, l1t::PFClusterRef(caloHandle, ic)); + } + } + + regionizer_->run(event_.decoded, event_.pfinputs); + + // First, get a copy of the discretized and corrected inputs, and write them out + iEvent.put(fetchEmCalo(), "EmCalo"); + iEvent.put(fetchHadCalo(), "Calo"); + iEvent.put(fetchTracks(), "TK"); + + // Then do the vertexing, and save it out + std::vector z0s; + std::vector> ptsums; + float z0 = 0; + double ptsum = 0; + l1t::VertexWord pvwd; + // FIXME: collections seem to be already sorted + if (emuTkVtx_) { + edm::Handle> vtxEmuHandle; + iEvent.getByToken(tkVtxEmu_, vtxEmuHandle); + for (const auto &vtx : *vtxEmuHandle) { + ptsums.push_back(std::pair(vtx.pt(), vtx.z0())); + if (ptsum == 0 || vtx.pt() > ptsum) { + ptsum = vtx.pt(); + z0 = vtx.z0(); + pvwd = vtx; + } + } + } else { + edm::Handle> vtxHandle; + iEvent.getByToken(extTkVtx_, vtxHandle); + for (const auto &vtx : *vtxHandle) { + ptsums.push_back(std::pair(vtx.pt(), vtx.z0())); + if (ptsum == 0 || vtx.pt() > ptsum) { + ptsum = vtx.pt(); + z0 = vtx.z0(); + } + } + pvwd = l1t::VertexWord(1, z0, 1, ptsum, 1, 1, 1); + } + l1ct::PVObjEmu hwpv; + hwpv.hwZ0 = l1ct::Scales::makeZ0(pvwd.z0()); + event_.pvs.push_back(hwpv); + event_.pvs_emu.push_back(pvwd.vertexWord()); + //Do a quick histogram vertexing to get multiple vertices (Hack for the taus) + if (NVtx_ > 1) { + std::stable_sort(ptsums.begin(), ptsums.end(), [](const auto &a, const auto &b) { return a.first > b.first; }); + for (int i0 = 0; i0 < std::min(int(ptsums.size()), int(NVtx_)); i0++) { + z0s.push_back(ptsums[i0].second); + } + for (unsigned int i = 1; i < z0s.size(); ++i) { + l1ct::PVObjEmu hwpv; + hwpv.hwZ0 = l1ct::Scales::makeZ0(z0s[i]); + event_.pvs.push_back(hwpv); //Skip emu + } + } + // Then also save the tracks with a vertex cut +#if 0 + iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/true), "TKVtx"); +#endif + + // Then run PF in each region + event_.out.resize(event_.pfinputs.size()); + for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) { + l1pfalgo_->run(event_.pfinputs[ir], event_.out[ir]); + l1pfalgo_->mergeNeutrals(event_.out[ir]); + l1tkegalgo_->run(event_.pfinputs[ir], event_.out[ir]); + l1tkegalgo_->runIso(event_.pfinputs[ir], event_.pvs, event_.out[ir]); + } + + // Then run puppi (regionally) + for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) { + l1pualgo_->run(event_.pfinputs[ir], event_.pvs, event_.out[ir]); + //l1pualgo_->runNeutralsPU(l1region, z0, -1., puGlobals); + } + + // NOTE: This needs to happen before the EG sorting per board so that the EG objects + // get a global reference to the EGSta before being mixed among differente regions + std::vector>> egsta_refs; + if (l1tkegalgo_->writeEgSta()) { + putEgStaObjects(iEvent, "L1Eg", egsta_refs); + } + + // 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); + } + + // save PF into the event + iEvent.put(fetchPF(), "PF"); + + // and save puppi + putPuppi(iEvent); + + // save the EG objects + putEgObjects(iEvent, l1tkegalgo_->writeEgSta(), egsta_refs, "L1TkEm", "L1TkEmPerBoard", "L1TkEle", "L1TkElePerBoard"); + + // Then go do the multiplicities + for (int i = 0; i <= l1muType; ++i) { + auto vecInputs = vecSecInput(InputType(i)); + auto tm = totAndMax(*vecInputs); + addUInt(tm.first, std::string("totNSec") + inputTypeName[i], iEvent); + addUInt(tm.second, std::string("maxNSec") + inputTypeName[i], iEvent); + iEvent.put(std::move(vecInputs), std::string("vecNSec") + inputTypeName[i]); + } + for (int i = 0; i <= l1muType; ++i) { + auto vecInputs = vecRegInput(InputType(i)); + auto tm = totAndMax(*vecInputs); + addUInt(tm.first, std::string("totNReg") + inputTypeName[i], iEvent); + addUInt(tm.second, std::string("maxNReg") + inputTypeName[i], iEvent); + iEvent.put(std::move(vecInputs), std::string("vecNReg") + inputTypeName[i]); + } + for (int i = 0; i < l1ct::OutputRegion::nPFTypes; ++i) { + auto vecPF = vecOutput(OutputType(i), false); + auto tmPF = totAndMax(*vecPF); + addUInt(tmPF.first, std::string("totNPF") + l1ct::OutputRegion::objTypeName[i], iEvent); + addUInt(tmPF.second, std::string("maxNPF") + l1ct::OutputRegion::objTypeName[i], iEvent); + iEvent.put(std::move(vecPF), std::string("vecNPF") + l1ct::OutputRegion::objTypeName[i]); + auto vecPuppi = vecOutput(OutputType(i), true); + auto tmPuppi = totAndMax(*vecPuppi); + addUInt(tmPuppi.first, std::string("totNPuppi") + l1ct::OutputRegion::objTypeName[i], iEvent); + addUInt(tmPuppi.second, std::string("maxNPuppi") + l1ct::OutputRegion::objTypeName[i], iEvent); + iEvent.put(std::move(vecPuppi), std::string("vecNPuppi") + l1ct::OutputRegion::objTypeName[i]); + } + + if (fRegionDump_.is_open()) { + event_.write(fRegionDump_); + } + for (auto &writer : patternWriters_) { + writer->write(event_); + } + + // finally clear the regions + event_.clear(); +} + +void L1TCorrelatorLayer1Producer::addUInt(unsigned int value, std::string iLabel, edm::Event &iEvent) { + iEvent.put(std::make_unique(value), iLabel); +} + +void L1TCorrelatorLayer1Producer::initSectorsAndRegions(const edm::ParameterSet &iConfig) { + // the track finder geometry is fixed + unsigned int TF_phiSlices = 9; + float TF_phiWidth = 2 * M_PI / TF_phiSlices; + event_.decoded.track.clear(); + for (unsigned int ieta = 0, neta = 2; ieta < neta; ++ieta) { + for (unsigned int iphi = 0; iphi < TF_phiSlices; ++iphi) { + float phiCenter = reco::reduceRange(iphi * TF_phiWidth); + event_.decoded.track.emplace_back((ieta ? 0. : -2.5), (ieta ? 2.5 : 0.0), phiCenter, TF_phiWidth); + event_.raw.track.emplace_back((ieta ? 0. : -2.5), (ieta ? 2.5 : 0.0), phiCenter, TF_phiWidth); + } + } + + event_.decoded.emcalo.clear(); + event_.decoded.hadcalo.clear(); + event_.raw.hgcalcluster.clear(); + + for (const edm::ParameterSet &preg : iConfig.getParameter>("caloSectors")) { + std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); + if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end())) + throw cms::Exception("Configuration", "caloSectors.etaBoundaries not sorted\n"); + unsigned int phiSlices = preg.getParameter("phiSlices"); + float phiWidth = 2 * M_PI / phiSlices; + if (phiWidth > 2 * l1ct::Scales::maxAbsPhi()) + throw cms::Exception("Configuration", "caloSectors phi range too large for phi_t data type"); + double phiZero = preg.getParameter("phiZero"); + for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { + float etaWidth = etaBoundaries[ieta + 1] - etaBoundaries[ieta]; + if (etaWidth > 2 * l1ct::Scales::maxAbsEta()) + throw cms::Exception("Configuration", "caloSectors eta range too large for eta_t data type"); + for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { + float phiCenter = reco::reduceRange(iphi * phiWidth + phiZero); + event_.decoded.hadcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); + event_.decoded.emcalo.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); + event_.raw.hgcalcluster.emplace_back(etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth); + } + } + } + + event_.decoded.muon.region = l1ct::PFRegionEmu(0., 0.); // centered at (0,0) + event_.raw.muon.region = l1ct::PFRegionEmu(0., 0.); // centered at (0,0) + + event_.pfinputs.clear(); + for (const edm::ParameterSet &preg : iConfig.getParameter>("regions")) { + std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); + if (!std::is_sorted(etaBoundaries.begin(), etaBoundaries.end())) + throw cms::Exception("Configuration", "regions.etaBoundaries not sorted\n"); + unsigned int phiSlices = preg.getParameter("phiSlices"); + float etaExtra = preg.getParameter("etaExtra"); + float phiExtra = preg.getParameter("phiExtra"); + float phiWidth = 2 * M_PI / phiSlices; + for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { + for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { + float phiCenter = reco::reduceRange(iphi * phiWidth); //align with L1 TrackFinder phi sector indexing + event_.pfinputs.emplace_back( + etaBoundaries[ieta], etaBoundaries[ieta + 1], phiCenter, phiWidth, etaExtra, phiExtra); + } + } + } + + event_.board_out.clear(); + const std::vector &board_params = iConfig.getParameter>("boards"); + event_.board_out.resize(board_params.size()); + for (unsigned int bidx = 0; bidx < board_params.size(); bidx++) { + event_.board_out[bidx].region_index = board_params[bidx].getParameter>("regions"); + float etaBoard = 0.; + float phiBoard = 0.; + for (auto ridx : event_.board_out[bidx].region_index) { + etaBoard += event_.pfinputs[ridx].region.floatEtaCenter(); + phiBoard += event_.pfinputs[ridx].region.floatPhiCenter(); + } + event_.board_out[bidx].eta = etaBoard / event_.board_out[bidx].region_index.size(); + event_.board_out[bidx].phi = phiBoard / event_.board_out[bidx].region_index.size(); + } +} + +void L1TCorrelatorLayer1Producer::initEvent(const edm::Event &iEvent) { + event_.clear(); + event_.run = iEvent.id().run(); + event_.lumi = iEvent.id().luminosityBlock(); + event_.event = iEvent.id().event(); + clusterRefMap_.clear(); + trackRefMap_.clear(); + muonRefMap_.clear(); +} + +void L1TCorrelatorLayer1Producer::addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref) { + auto &rawsectors = event_.raw.track; + auto §ors = event_.decoded.track; + assert(sectors.size() == 18 && rawsectors.size() == 18); + int isec = t.track()->phiSector() + (t.eta() >= 0 ? 9 : 0); + rawsectors[isec].obj.push_back(t.trackWord().getTrackWord()); + addDecodedTrack(sectors[isec], t); + trackRefMap_[&t] = ref; +} +void L1TCorrelatorLayer1Producer::addMuon(const l1t::SAMuon &mu, l1t::PFCandidate::MuonRef ref) { + event_.raw.muon.obj.emplace_back(mu.word()); + addDecodedMuon(event_.decoded.muon, mu); + muonRefMap_[&mu] = ref; +} +void L1TCorrelatorLayer1Producer::addHadCalo(const l1t::PFCluster &c, l1t::PFClusterRef ref) { + int sidx = 0; + for (auto &sec : event_.decoded.hadcalo) { + if (sec.region.contains(c.eta(), c.phi())) { + addDecodedHadCalo(sec, c); + if (writeRawHgcalCluster_) + addRawHgcalCluster(event_.raw.hgcalcluster[sidx], c); + } + sidx++; + } + clusterRefMap_[&c] = ref; +} +void L1TCorrelatorLayer1Producer::addEmCalo(const l1t::PFCluster &c, l1t::PFClusterRef ref) { + for (auto &sec : event_.decoded.emcalo) { + if (sec.region.contains(c.eta(), c.phi())) { + addDecodedEmCalo(sec, c); + } + } + clusterRefMap_[&c] = ref; +} + +void L1TCorrelatorLayer1Producer::addDecodedTrack(l1ct::DetectorSector &sec, const l1t::PFTrack &t) { + std::pair tkAndSel; + if (trackInput_) { + tkAndSel = trackInput_->decodeTrack(t.trackWord().getTrackWord(), sec.region); + } else { + tkAndSel.first.hwPt = l1ct::Scales::makePtFromFloat(t.pt()); + tkAndSel.first.hwEta = + l1ct::Scales::makeGlbEta(t.caloEta()) - + sec.region.hwEtaCenter; // important to enforce that the region boundary is on a discrete value + tkAndSel.first.hwPhi = l1ct::Scales::makePhi(sec.region.localPhi(t.caloPhi())); + tkAndSel.first.hwCharge = t.charge() > 0; + tkAndSel.first.hwQuality = t.quality(); + tkAndSel.first.hwDEta = l1ct::Scales::makeEta(t.eta() - t.caloEta()); + tkAndSel.first.hwDPhi = l1ct::Scales::makePhi(std::abs(reco::deltaPhi(t.phi(), t.caloPhi()))); + tkAndSel.first.hwZ0 = l1ct::Scales::makeZ0(t.vertex().Z()); + tkAndSel.first.hwDxy = 0; + tkAndSel.second = t.quality() > 0; + } + // CMSSW-only extra info + tkAndSel.first.hwChi2 = round(t.chi2() * 10); + tkAndSel.first.hwStubs = t.nStubs(); + tkAndSel.first.simPt = t.pt(); + tkAndSel.first.simCaloEta = t.caloEta(); + tkAndSel.first.simCaloPhi = t.caloPhi(); + tkAndSel.first.simVtxEta = t.eta(); + tkAndSel.first.simVtxPhi = t.phi(); + tkAndSel.first.simZ0 = t.vertex().Z(); + tkAndSel.first.simD0 = t.vertex().Rho(); + tkAndSel.first.src = &t; + // If the track fails, we set its pT to zero, so that the decoded tracks are still aligned with the raw tracks + // Downstream, the regionizer will just ignore zero-momentum tracks + if (!tkAndSel.second) + tkAndSel.first.hwPt = 0; + sec.obj.push_back(tkAndSel.first); +} + +void L1TCorrelatorLayer1Producer::addDecodedMuon(l1ct::DetectorSector &sec, const l1t::SAMuon &t) { + l1ct::MuObjEmu mu; + if (muonInput_) { + mu = muonInput_->decode(t.word()); + } else { + mu.hwPt = l1ct::Scales::makePtFromFloat(t.pt()); + mu.hwEta = l1ct::Scales::makeGlbEta(t.eta()); // IMPORTANT: input is in global coordinates! + mu.hwPhi = l1ct::Scales::makeGlbPhi(t.phi()); + mu.hwCharge = !t.hwCharge(); + mu.hwQuality = t.hwQual() / 2; + mu.hwDEta = 0; + mu.hwDPhi = 0; + mu.hwZ0 = l1ct::Scales::makeZ0(t.vertex().Z()); + mu.hwDxy = 0; // Dxy not defined yet + } + mu.src = &t; + sec.obj.push_back(mu); +} + +void L1TCorrelatorLayer1Producer::addDecodedHadCalo(l1ct::DetectorSector &sec, + const l1t::PFCluster &c) { + l1ct::HadCaloObjEmu calo; + calo.hwPt = l1ct::Scales::makePtFromFloat(c.pt()); + calo.hwEta = l1ct::Scales::makeGlbEta(c.eta()) - + sec.region.hwEtaCenter; // important to enforce that the region boundary is on a discrete value + calo.hwPhi = l1ct::Scales::makePhi(sec.region.localPhi(c.phi())); + calo.hwEmPt = l1ct::Scales::makePtFromFloat(c.emEt()); + calo.hwEmID = c.hwEmID(); + calo.src = &c; + sec.obj.push_back(calo); +} + +void L1TCorrelatorLayer1Producer::addRawHgcalCluster(l1ct::DetectorSector> &sec, const l1t::PFCluster &c) { + ap_uint<256> cwrd = 0; + ap_uint<14> w_pt = round(c.pt() / 0.25); + ap_uint<14> w_empt = round(c.emEt() / 0.25); + constexpr float ETAPHI_LSB = M_PI / 720; + ap_int<9> w_eta = round(sec.region.localEta(c.eta()) / ETAPHI_LSB); + ap_int<9> w_phi = round(sec.region.localPhi(c.phi()) / ETAPHI_LSB); + ap_uint<10> w_qual = c.hwQual(); + + cwrd(13, 0) = w_pt; + cwrd(27, 14) = w_empt; + cwrd(72, 64) = w_eta; + cwrd(81, 73) = w_phi; + cwrd(115, 106) = w_qual; + + sec.obj.push_back(cwrd); +} + +void L1TCorrelatorLayer1Producer::addDecodedEmCalo(l1ct::DetectorSector &sec, + const l1t::PFCluster &c) { + l1ct::EmCaloObjEmu calo; + calo.hwPt = l1ct::Scales::makePtFromFloat(c.pt()); + calo.hwEta = l1ct::Scales::makeGlbEta(c.eta()) - + sec.region.hwEtaCenter; // important to enforce that the region boundary is on a discrete value + calo.hwPhi = l1ct::Scales::makePhi(sec.region.localPhi(c.phi())); + calo.hwPtErr = l1ct::Scales::makePtFromFloat(c.ptError()); + calo.hwEmID = c.hwEmID(); + calo.src = &c; + sec.obj.push_back(calo); +} + +template +void L1TCorrelatorLayer1Producer::setRefs_(l1t::PFCandidate &pf, const T &p) const { + if (p.srcCluster) { + auto match = clusterRefMap_.find(p.srcCluster); + if (match == clusterRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.intId() << " pt " + << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setPFCluster(match->second); + } + if (p.srcTrack) { + auto match = trackRefMap_.find(p.srcTrack); + if (match == trackRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid track pointer in PF candidate id " << p.intId() << " pt " + << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setPFTrack(match->second); + } + if (p.srcMu) { + auto match = muonRefMap_.find(p.srcMu); + if (match == muonRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid muon pointer in PF candidate id " << p.intId() << " pt " + << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setMuon(match->second); + } +} + +template <> +void L1TCorrelatorLayer1Producer::setRefs_(l1t::PFCandidate &pf, + const l1ct::PFNeutralObjEmu &p) const { + if (p.srcCluster) { + auto match = clusterRefMap_.find(p.srcCluster); + if (match == clusterRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.intId() << " pt " + << p.floatPt() << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setPFCluster(match->second); + } +} + +template <> +void L1TCorrelatorLayer1Producer::setRefs_(l1t::PFCandidate &pf, + const l1ct::HadCaloObjEmu &p) const { + if (p.src) { + auto match = clusterRefMap_.find(p.src); + if (match == clusterRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid cluster pointer in hadcalo candidate pt " << p.floatPt() + << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setPFCluster(match->second); + } +} + +template <> +void L1TCorrelatorLayer1Producer::setRefs_(l1t::PFCandidate &pf, + const l1ct::EmCaloObjEmu &p) const { + if (p.src) { + auto match = clusterRefMap_.find(p.src); + if (match == clusterRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid cluster pointer in emcalo candidate pt " << p.floatPt() + << " eta " << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setPFCluster(match->second); + } +} + +template <> +void L1TCorrelatorLayer1Producer::setRefs_(l1t::PFCandidate &pf, const l1ct::TkObjEmu &p) const { + if (p.src) { + auto match = trackRefMap_.find(p.src); + if (match == trackRefMap_.end()) { + throw cms::Exception("CorruptData") << "Invalid track pointer in track candidate pt " << p.floatPt() << " eta " + << p.floatEta() << " phi " << p.floatPhi(); + } + pf.setPFTrack(match->second); + } +} + +std::unique_ptr L1TCorrelatorLayer1Producer::fetchHadCalo() const { + auto ret = std::make_unique(); + for (const auto &r : event_.pfinputs) { + const auto ® = r.region; + for (const auto &p : r.hadcalo) { + if (p.hwPt == 0 || !reg.isFiducial(p)) + continue; + reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f); + l1t::PFCandidate::ParticleType type = p.hwIsEM() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron; + ret->emplace_back(type, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi()); + ret->back().setHwEmID(p.hwEmID); + setRefs_(ret->back(), p); + } + } + return ret; +} +std::unique_ptr L1TCorrelatorLayer1Producer::fetchEmCalo() const { + auto ret = std::make_unique(); + for (const auto &r : event_.pfinputs) { + const auto ® = r.region; + for (const auto &p : r.emcalo) { + if (p.hwPt == 0 || !reg.isFiducial(p)) + continue; + reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f); + ret->emplace_back(l1t::PFCandidate::Photon, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi()); + ret->back().setHwEmID(p.hwEmID); + setRefs_(ret->back(), p); + } + } + return ret; +} +std::unique_ptr L1TCorrelatorLayer1Producer::fetchTracks() const { + auto ret = std::make_unique(); + for (const auto &r : event_.pfinputs) { + const auto ® = r.region; + for (const auto &p : r.track) { + if (p.hwPt == 0 || !reg.isFiducial(p)) + continue; + reco::Particle::PolarLorentzVector p4( + p.floatPt(), reg.floatGlbEta(p.hwVtxEta()), reg.floatGlbPhi(p.hwVtxPhi()), 0.13f); + ret->emplace_back(l1t::PFCandidate::ChargedHadron, p.intCharge(), p4, 1, p.intPt(), p.intEta(), p.intPhi()); + setRefs_(ret->back(), p); + } + } + return ret; +} + +std::unique_ptr L1TCorrelatorLayer1Producer::fetchPF() const { + auto ret = std::make_unique(); + for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) { + const auto ® = event_.pfinputs[ir].region; + for (const auto &p : event_.out[ir].pfcharged) { + if (p.hwPt == 0 || !reg.isFiducial(p)) + continue; + reco::Particle::PolarLorentzVector p4( + p.floatPt(), reg.floatGlbEta(p.hwVtxEta()), reg.floatGlbPhi(p.hwVtxPhi()), 0.13f); + l1t::PFCandidate::ParticleType type = l1t::PFCandidate::ChargedHadron; + if (p.hwId.isMuon()) + type = l1t::PFCandidate::Muon; + else if (p.hwId.isElectron()) + type = l1t::PFCandidate::Electron; + ret->emplace_back(type, p.intCharge(), p4, 1, p.intPt(), p.intEta(), p.intPhi()); + ret->back().setZ0(p.floatZ0()); + ret->back().setDxy(p.floatDxy()); + ret->back().setHwZ0(p.hwZ0); + ret->back().setHwDxy(p.hwDxy); + ret->back().setHwTkQuality(p.hwTkQuality); + setRefs_(ret->back(), p); + } + for (const auto &p : event_.out[ir].pfneutral) { + if (p.hwPt == 0 || !reg.isFiducial(p)) + continue; + reco::Particle::PolarLorentzVector p4(p.floatPt(), reg.floatGlbEtaOf(p), reg.floatGlbPhiOf(p), 0.13f); + l1t::PFCandidate::ParticleType type = + p.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron; + ret->emplace_back(type, 0, p4, 1, p.intPt(), p.intEta(), p.intPhi()); + ret->back().setHwEmID(p.hwEmID); + setRefs_(ret->back(), p); + } + } + return ret; +} + +void L1TCorrelatorLayer1Producer::putPuppi(edm::Event &iEvent) const { + auto refprod = iEvent.getRefBeforePut("Puppi"); + auto coll = std::make_unique(); + auto reg = std::make_unique(refprod); + std::vector nobj; + for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) { + nobj.clear(); + for (const auto &p : event_.out[ir].puppi) { + if (p.hwPt == 0) + continue; + // note: Puppi candidates are already in global coordinates & fiducial-only! + l1t::PFCandidate::ParticleType type; + float mass = 0.13f; + if (p.hwId.charged()) { + if (p.hwId.isMuon()) { + type = l1t::PFCandidate::Muon; + mass = 0.105; + } else if (p.hwId.isElectron()) { + type = l1t::PFCandidate::Electron; + mass = 0.005; + } else + type = l1t::PFCandidate::ChargedHadron; + } else { + type = p.hwId.isPhoton() ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron; + mass = p.hwId.isPhoton() ? 0.0 : 0.5; + } + reco::Particle::PolarLorentzVector p4(p.floatPt(), p.floatEta(), p.floatPhi(), mass); + coll->emplace_back(type, p.intCharge(), p4, p.floatPuppiW(), p.intPt(), p.intEta(), p.intPhi()); + if (p.hwId.charged()) { + coll->back().setZ0(p.floatZ0()); + coll->back().setDxy(p.floatDxy()); + coll->back().setHwZ0(p.hwZ0()); + coll->back().setHwDxy(p.hwDxy()); + coll->back().setHwTkQuality(p.hwTkQuality()); + } else { + coll->back().setHwPuppiWeight(p.hwPuppiW()); + coll->back().setHwEmID(p.hwEmID()); + } + coll->back().setEncodedPuppi64(p.pack().to_uint64()); + setRefs_(coll->back(), p); + nobj.push_back(coll->size() - 1); + } + reg->addRegion(nobj, event_.pfinputs[ir].region.floatEtaCenter(), event_.pfinputs[ir].region.floatPhiCenter()); + } + iEvent.put(std::move(coll), "Puppi"); + iEvent.put(std::move(reg), "PuppiRegional"); +} + +// NOTE: as a side effect we change the "sta_idx" of TkEle and TkEm objects to an index of the +// vector of refs, for this reason this is not const. We could make this more explicit via arguments +void L1TCorrelatorLayer1Producer::putEgStaObjects(edm::Event &iEvent, + const std::string &egLablel, + std::vector>> &egsta_refs) { + auto egs = std::make_unique>(); + edm::RefProd> ref_egs = iEvent.getRefBeforePut>(egLablel); + + edm::Ref>::key_type idx = 0; + // FIXME: in case more BXes are introduced shuld probably use egs->key(egs->end(bx)); + + for (unsigned int ir = 0, nr = event_.pfinputs.size(); ir < nr; ++ir) { + const auto ® = event_.pfinputs[ir].region; + + std::vector ref_pos(event_.out[ir].egsta.size()); + + // EG standalone objects + for (unsigned int ieg = 0, neg = event_.out[ir].egsta.size(); ieg < neg; ++ieg) { + const auto &p = event_.out[ir].egsta[ieg]; + if (p.hwPt == 0 || !reg.isFiducial(p)) + continue; + l1t::EGamma eg( + reco::Candidate::PolarLorentzVector(p.floatPt(), reg.floatGlbEta(p.hwEta), reg.floatGlbPhi(p.hwPhi), 0.)); + eg.setHwQual(p.hwQual); + egs->push_back(0, eg); + egsta_refs.push_back(edm::Ref>(ref_egs, idx++)); + ref_pos[ieg] = egsta_refs.size() - 1; + } + + for (auto &egiso : event_.out[ir].egphoton) { + if (egiso.hwPt == 0) + continue; + egiso.sta_idx = ref_pos[egiso.sta_idx]; + } + + for (auto &egele : event_.out[ir].egelectron) { + if (egele.hwPt == 0) + continue; + egele.sta_idx = ref_pos[egele.sta_idx]; + } + } + + iEvent.put(std::move(egs), egLablel); +} + +void L1TCorrelatorLayer1Producer::putEgObjects(edm::Event &iEvent, + const bool writeEgSta, + const std::vector>> &egsta_refs, + const std::string &tkEmLabel, + const std::string &tkEmPerBoardLabel, + const std::string &tkEleLabel, + const std::string &tkElePerBoardLabel) const { + auto tkems = std::make_unique(); + auto tkemRefProd = iEvent.getRefBeforePut(tkEmLabel); + auto tkemPerBoard = std::make_unique(tkemRefProd); + auto tkeles = std::make_unique(); + auto tkeleRefProd = iEvent.getRefBeforePut(tkEleLabel); + auto tkelePerBoard = std::make_unique(tkeleRefProd); + + // TkEG objects are written out after the per-board sorting. + // The mapping to each board is saved into the regionalmap for further (stage-2 consumption) + std::vector nele_obj; + std::vector npho_obj; + + for (const auto &board : event_.board_out) { + npho_obj.clear(); + for (const auto &egiso : board.egphoton) { + if (egiso.hwPt == 0) + continue; + + edm::Ref> ref_egsta; + if (writeEgSta) { + ref_egsta = egsta_refs[egiso.sta_idx]; + } else { + auto egptr = egiso.srcCluster->constituentsAndFractions()[0].first; + ref_egsta = + edm::Ref>(egptr.id(), dynamic_cast(egptr.get()), egptr.key()); + } + + reco::Candidate::PolarLorentzVector mom(egiso.floatPt(), egiso.floatEta(), egiso.floatPhi(), 0.); + + l1t::TkEm tkem(reco::Candidate::LorentzVector(mom), + ref_egsta, + egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIso), + egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIsoPV)); + tkem.setHwQual(egiso.hwQual); + tkem.setPFIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIso)); + tkem.setPFIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIsoPV)); + tkem.setEgBinaryWord(egiso.pack()); + tkems->push_back(tkem); + npho_obj.push_back(tkems->size() - 1); + } + tkemPerBoard->addRegion(npho_obj, board.eta, board.phi); + + nele_obj.clear(); + for (const auto &egele : board.egelectron) { + if (egele.hwPt == 0) + continue; + + edm::Ref> ref_egsta; + if (writeEgSta) { + ref_egsta = egsta_refs[egele.sta_idx]; + } else { + auto egptr = egele.srcCluster->constituentsAndFractions()[0].first; + ref_egsta = + edm::Ref>(egptr.id(), dynamic_cast(egptr.get()), egptr.key()); + } + + reco::Candidate::PolarLorentzVector mom(egele.floatPt(), egele.floatEta(), egele.floatPhi(), 0.); + + l1t::TkElectron tkele(reco::Candidate::LorentzVector(mom), + ref_egsta, + edm::refToPtr(egele.srcTrack->track()), + egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::TkIso)); + tkele.setHwQual(egele.hwQual); + tkele.setPFIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PfIso)); + tkele.setEgBinaryWord(egele.pack()); + tkeles->push_back(tkele); + nele_obj.push_back(tkeles->size() - 1); + } + tkelePerBoard->addRegion(nele_obj, board.eta, board.phi); + } + + iEvent.put(std::move(tkems), tkEmLabel); + iEvent.put(std::move(tkemPerBoard), tkEmPerBoardLabel); + iEvent.put(std::move(tkeles), tkEleLabel); + iEvent.put(std::move(tkelePerBoard), tkElePerBoardLabel); +} + +std::unique_ptr> L1TCorrelatorLayer1Producer::vecSecInput(InputType t) const { + auto v = std::make_unique>(); + { + switch (t) { + case caloType: + for (const auto &s : event_.decoded.hadcalo) + v->push_back(s.size()); + break; + case emcaloType: + for (const auto &s : event_.decoded.emcalo) + v->push_back(s.size()); + break; + case trackType: + for (const auto &s : event_.decoded.track) + v->push_back(s.size()); + break; + case l1muType: + v->push_back(event_.decoded.muon.size()); + break; + } + } + return v; +} + +std::unique_ptr> L1TCorrelatorLayer1Producer::vecRegInput(InputType t) const { + auto v = std::make_unique>(); + for (const auto ® : event_.pfinputs) { + switch (t) { + case caloType: + v->push_back(reg.hadcalo.size()); + break; + case emcaloType: + v->push_back(reg.emcalo.size()); + break; + case trackType: + v->push_back(reg.track.size()); + break; + case l1muType: + v->push_back(reg.muon.size()); + break; + } + } + return v; +} + +std::unique_ptr> L1TCorrelatorLayer1Producer::vecOutput(OutputType i, bool usePuppi) const { + auto v = std::make_unique>(); + for (const auto ® : event_.out) { + v->push_back(reg.nObj(i, usePuppi)); + } + return v; +} +std::pair L1TCorrelatorLayer1Producer::totAndMax( + const std::vector &perRegion) const { + unsigned int ntot = 0, nmax = 0; + for (unsigned ni : perRegion) { + ntot += ni; + nmax = std::max(nmax, ni); + } + return std::make_pair(ntot, nmax); +} +//define this as a plug-in +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1TCorrelatorLayer1Producer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc new file mode 100644 index 0000000000000..75265d23765a0 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TCtL2EgProducer.cc @@ -0,0 +1,402 @@ +#include "DataFormats/L1TCorrelator/interface/TkElectron.h" +#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" +#include "DataFormats/L1TCorrelator/interface/TkEm.h" +#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/transform.h" + +#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/DemonstratorTools/interface/BoardDataWriter.h" +#include "L1Trigger/DemonstratorTools/interface/utilities.h" + +#include +#include + +using namespace l1ct; + +class L1TCtL2EgProducer : public edm::global::EDProducer<> { +public: + explicit L1TCtL2EgProducer(const edm::ParameterSet &); + ~L1TCtL2EgProducer() override; + +private: + ap_uint<64> encodeLayer1(const EGIsoObjEmu &egiso) const; + ap_uint<128> encodeLayer1(const EGIsoEleObjEmu &egiso) const; + + std::vector> encodeLayer1(const std::vector &photons) const; + std::vector> encodeLayer1(const std::vector &electrons) const; + + std::vector> encodeLayer1EgObjs(unsigned int nObj, + const std::vector &photons, + const std::vector &electrons) const; + + void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override; + + void endJob() override; + + struct RefRemapper { + typedef TTTrack L1TTTrackType; + + BXVector>> oldRefs; + std::map>, edm::Ref>> old2newRefMap; + std::vector, edm::Ptr>> origRefAndPtr; + }; + + void convertToEmu(const l1t::TkElectron &tkele, RefRemapper &refRemapper, l1ct::OutputBoard &boarOut) const; + void convertToEmu(const l1t::TkEm &tkele, RefRemapper &refRemapper, l1ct::OutputBoard &boarOut) const; + + template + class PFInstanceInputs { + public: + typedef std::vector, std::vector>> InputTokenAndChannels; + PFInstanceInputs(L1TCtL2EgProducer *prod, const std::vector &confs) { + for (const auto &conf : confs) { + const auto &producer_tag = conf.getParameter("pfProducer"); + tokensAndChannels_.push_back(std::make_pair( + prod->consumes(edm::InputTag(producer_tag.label(), producer_tag.instance(), producer_tag.process())), + conf.getParameter>("channels"))); + } + } + + const InputTokenAndChannels &tokensAndChannels() const { return tokensAndChannels_; } + + private: + InputTokenAndChannels tokensAndChannels_; + }; + + class PatternWriter { + public: + PatternWriter(const edm::ParameterSet &conf) : dataWriter_(nullptr) { + unsigned int nFramesPerBX = conf.getParameter("nFramesPerBX"); + + std::map>> channelSpecs; + + for (const auto &channelConf : conf.getParameter>("channels")) { + unsigned int inTMUX = channelConf.getParameter("TMUX"); + unsigned int eventGap = + inTMUX * nFramesPerBX - channelConf.getParameter("nWords"); // assuming 96bit (= 3/2 word) + // words = TMUX*9-2*3/2*words + std::vector chns = channelConf.getParameter>("channels"); + channelSpecs[l1t::demo::LinkId{channelConf.getParameter("interface"), + channelConf.getParameter("id")}] = + std::make_pair(l1t::demo::ChannelSpec{inTMUX, eventGap}, + std::vector(std::begin(chns), std::end(chns))); + } + + dataWriter_ = std::make_unique( + l1t::demo::parseFileFormat(conf.getParameter("format")), + conf.getParameter("outputFilename"), + nFramesPerBX, + conf.getParameter("TMUX"), + conf.getParameter("maxLinesPerFile"), + channelSpecs); + } + + void addEvent(const l1t::demo::EventData &eventData) { dataWriter_->addEvent(eventData); } + + void flush() { dataWriter_->flush(); } + + private: + std::unique_ptr dataWriter_; + }; + + template + void merge(const PFInstanceInputs &instance, + edm::Event &iEvent, + RefRemapper &refRemapper, + std::unique_ptr &out) const { + edm::Handle handle; + for (const auto &tokenAndChannel : instance.tokensAndChannels()) { + iEvent.getByToken(tokenAndChannel.first, handle); + populate(out, handle, tokenAndChannel.second, refRemapper); + } + remapRefs(iEvent, out, refRemapper); + } + + template + void remapRefs(edm::Event &iEvent, std::unique_ptr &out, RefRemapper &refRemapper) const {} + + void remapRefs(edm::Event &iEvent, std::unique_ptr> &out, RefRemapper &refRemapper) const { + edm::RefProd> ref_egs = iEvent.getRefBeforePut>(tkEGInstanceLabel_); + edm::Ref>::key_type idx = 0; + for (std::size_t ix = 0; ix < out->size(); ix++) { + refRemapper.old2newRefMap[refRemapper.oldRefs[ix]] = edm::Ref>(ref_egs, idx++); + } + } + + template + void populate(std::unique_ptr &out, + const edm::Handle &in, + const std::vector &links, + RefRemapper &refRemapper) const { + assert(links.size() == in->nRegions()); + for (unsigned int iBoard = 0, nBoard = in->nRegions(); iBoard < nBoard; ++iBoard) { + auto region = in->region(iBoard); + int linkID = links[iBoard]; + if (linkID < 0) + continue; + // std::cout << "Board eta: " << in->eta(iBoard) << " phi: " << in->phi(iBoard) << " link: " << linkID << std::endl; + for (const auto &obj : region) { + convertToEmu(obj, refRemapper, out->at(linkID)); + } + } + } + + void populate(std::unique_ptr> &out, + const edm::Handle> &in, + const std::vector &links, + RefRemapper &refRemapper) const { + edm::Ref>::key_type idx = 0; + for (int bx = in->getFirstBX(); bx <= in->getLastBX(); bx++) { + for (auto egee_itr = in->begin(bx); egee_itr != in->end(bx); egee_itr++) { + out->push_back(bx, *egee_itr); + // this to ensure that the old ref and the new object have the same + // index in the BXVector collection so that we can still match them no + // matter which BX we will insert next + refRemapper.oldRefs.push_back(bx, edm::Ref>(in, idx++)); + } + } + } + + template + void putEgObjects(edm::Event &iEvent, + const RefRemapper &refRemapper, + const std::string &label, + const std::vector emulated) const { + auto egobjs = std::make_unique(); + for (const auto &emu : emulated) { + if (emu.hwPt == 0) + continue; + auto obj = convertFromEmu(emu, refRemapper); + egobjs->push_back(obj); + } + iEvent.put(std::move(egobjs), label); + } + + l1t::TkEm convertFromEmu(const l1ct::EGIsoObjEmu &emu, const RefRemapper &refRemapper) const; + l1t::TkElectron convertFromEmu(const l1ct::EGIsoEleObjEmu &emu, const RefRemapper &refRemapper) const; + + PFInstanceInputs> tkEGInputs_; + PFInstanceInputs tkEmInputs_; + PFInstanceInputs tkEleInputs_; + std::string tkEGInstanceLabel_; + std::string tkEmInstanceLabel_; + std::string tkEleInstanceLabel_; + l1ct::L2EgSorterEmulator l2egsorter; + l1ct::L2EgEncoderEmulator l2encoder; + bool doInPtrn_; + bool doOutPtrn_; + std::unique_ptr inPtrnWrt_; + std::unique_ptr outPtrnWrt_; +}; + +L1TCtL2EgProducer::L1TCtL2EgProducer(const edm::ParameterSet &conf) + : tkEGInputs_(this, conf.getParameter>("tkEgs")), + tkEmInputs_(this, conf.getParameter>("tkEms")), + tkEleInputs_(this, conf.getParameter>("tkElectrons")), + tkEGInstanceLabel_(conf.getParameter("egStaInstanceLabel")), + tkEmInstanceLabel_(conf.getParameter("tkEmInstanceLabel")), + tkEleInstanceLabel_(conf.getParameter("tkEleInstanceLabel")), + l2egsorter(conf.getParameter("sorter")), + l2encoder(conf.getParameter("encoder")), + doInPtrn_(conf.getParameter("writeInPattern")), + doOutPtrn_(conf.getParameter("writeOutPattern")), + inPtrnWrt_(nullptr), + outPtrnWrt_(nullptr) { + produces>(tkEGInstanceLabel_); + produces(tkEmInstanceLabel_); + produces(tkEleInstanceLabel_); + + if (doInPtrn_) { + inPtrnWrt_ = std::make_unique(conf.getParameter("inPatternFile")); + } + if (doOutPtrn_) { + outPtrnWrt_ = std::make_unique(conf.getParameter("outPatternFile")); + } +} + +L1TCtL2EgProducer::~L1TCtL2EgProducer() {} + +ap_uint<64> L1TCtL2EgProducer::encodeLayer1(const EGIsoObjEmu &egiso) const { + ap_uint<64> ret = 0; + ret(EGIsoObjEmu::BITWIDTH, 0) = egiso.pack(); + return ret; +} + +ap_uint<128> L1TCtL2EgProducer::encodeLayer1(const EGIsoEleObjEmu &egiso) const { + ap_uint<128> ret = 0; + ret(EGIsoEleObjEmu::BITWIDTH, 0) = egiso.pack(); + return ret; +} + +std::vector> L1TCtL2EgProducer::encodeLayer1(const std::vector &photons) const { + std::vector> ret; + ret.reserve(photons.size()); + for (const auto &phot : photons) { + ret.push_back(encodeLayer1(phot)); + } + return ret; +} + +std::vector> L1TCtL2EgProducer::encodeLayer1(const std::vector &electrons) const { + std::vector> ret; + ret.reserve(2 * electrons.size()); + for (const auto &ele : electrons) { + auto eleword = encodeLayer1(ele); + ret.push_back(eleword(63, 0)); + ret.push_back(eleword(127, 64)); + } + return ret; +} + +std::vector> L1TCtL2EgProducer::encodeLayer1EgObjs(unsigned int nObj, + const std::vector &photons, + const std::vector &electrons) const { + std::vector> ret; + auto encoded_photons = encodeLayer1(photons); + encoded_photons.resize(nObj, {0}); + auto encoded_eles = encodeLayer1(electrons); + encoded_eles.resize(2 * nObj, {0}); + + std::copy(encoded_photons.begin(), encoded_photons.end(), std::back_inserter(ret)); + std::copy(encoded_eles.begin(), encoded_eles.end(), std::back_inserter(ret)); + + return ret; +} + +void L1TCtL2EgProducer::produce(edm::StreamID, edm::Event &iEvent, const edm::EventSetup &) const { + RefRemapper refmapper; + + auto outEgs = std::make_unique>(); + merge(tkEGInputs_, iEvent, refmapper, outEgs); + iEvent.put(std::move(outEgs), tkEGInstanceLabel_); + + auto boards = std::make_unique>(l2egsorter.nInputBoards()); + + merge(tkEleInputs_, iEvent, refmapper, boards); + merge(tkEmInputs_, iEvent, refmapper, boards); + + if (doInPtrn_) { + l1t::demo::EventData inData; + for (unsigned int ibrd = 0; ibrd < boards->size(); ibrd++) { + inData.add( + {"eglayer1", ibrd}, + encodeLayer1EgObjs(l2egsorter.nInputObjPerBoard(), (*boards)[ibrd].egphoton, (*boards)[ibrd].egelectron)); + } + inPtrnWrt_->addEvent(inData); + } + + std::vector out_photons_emu; + std::vector out_eles_emu; + l2egsorter.run(*boards, out_photons_emu, out_eles_emu); + + if (doOutPtrn_) { + l1t::demo::EventData outData; + outData.add({"eglayer2", 0}, l2encoder.encodeLayer2EgObjs(out_photons_emu, out_eles_emu)); + outPtrnWrt_->addEvent(outData); + } + + putEgObjects(iEvent, refmapper, tkEmInstanceLabel_, out_photons_emu); + putEgObjects(iEvent, refmapper, tkEleInstanceLabel_, out_eles_emu); +} + +void L1TCtL2EgProducer::endJob() { + // Writing pending events to file before exiting + if (doOutPtrn_) + outPtrnWrt_->flush(); + if (doInPtrn_) + inPtrnWrt_->flush(); +} + +void L1TCtL2EgProducer::convertToEmu(const l1t::TkElectron &tkele, + RefRemapper &refRemapper, + l1ct::OutputBoard &boarOut) const { + EGIsoEleObjEmu emu; + emu.initFromBits(tkele.egBinaryWord()); + emu.srcCluster = nullptr; + emu.srcTrack = nullptr; + auto refEg = tkele.EGRef(); + const auto newref = refRemapper.old2newRefMap.find(refEg); + if (newref != refRemapper.old2newRefMap.end()) { + refEg = newref->second; + } + refRemapper.origRefAndPtr.push_back(std::make_pair(refEg, tkele.trkPtr())); + emu.sta_idx = refRemapper.origRefAndPtr.size() - 1; + // 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())); + // std::cout << "[convertToEmu] TkEle pt: " << emu.hwPt << " eta: " << emu.hwEta << " phi: " << emu.hwPhi << " staidx: " << emu.sta_idx << std::endl; + + boarOut.egelectron.push_back(emu); +} + +void L1TCtL2EgProducer::convertToEmu(const l1t::TkEm &tkem, + RefRemapper &refRemapper, + l1ct::OutputBoard &boarOut) const { + EGIsoObjEmu emu; + emu.initFromBits(tkem.egBinaryWord()); + emu.srcCluster = nullptr; + auto refEg = tkem.EGRef(); + const auto newref = refRemapper.old2newRefMap.find(refEg); + if (newref != refRemapper.old2newRefMap.end()) { + refEg = newref->second; + } + refRemapper.origRefAndPtr.push_back(std::make_pair(refEg, edm::Ptr(nullptr, 0))); + emu.sta_idx = refRemapper.origRefAndPtr.size() - 1; + // 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::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); +} + +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)! + const auto gteg = egiso.toGT(); + reco::Candidate::PolarLorentzVector mom( + l1gt::Scales::floatPt(gteg.v3.pt), l1gt::Scales::floatEta(gteg.v3.eta), l1gt::Scales::floatPhi(gteg.v3.phi), 0.); + // NOTE: The emulator and FW data-format stores absolute iso while the CMSSW object stores relative iso + l1t::TkEm tkem(reco::Candidate::LorentzVector(mom), + refRemapper.origRefAndPtr[egiso.sta_idx].first, + egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIso), + egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::TkIsoPV)); + tkem.setHwQual(gteg.quality); + tkem.setPFIsol(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIso)); + tkem.setPFIsolPV(egiso.floatRelIso(l1ct::EGIsoObjEmu::IsoType::PfIsoPV)); + tkem.setEgBinaryWord(gteg.pack()); + return tkem; +} + +l1t::TkElectron L1TCtL2EgProducer::convertFromEmu(const l1ct::EGIsoEleObjEmu &egele, + const RefRemapper &refRemapper) const { + // std::cout << "[convertFromEmu] TkEle pt: " << egele.hwPt << " eta: " << egele.hwEta << " phi: " << egele.hwPhi << " staidx: " << egele.sta_idx << std::endl; + // NOTE: the TkElectron object is created with the accuracy as in GT object (not the Correlator internal one)! + const auto gteg = egele.toGT(); + reco::Candidate::PolarLorentzVector mom( + l1gt::Scales::floatPt(gteg.v3.pt), l1gt::Scales::floatEta(gteg.v3.eta), l1gt::Scales::floatPhi(gteg.v3.phi), 0.); + // NOTE: The emulator and FW data-format stores absolute iso while the CMSSW object stores relative iso + l1t::TkElectron tkele(reco::Candidate::LorentzVector(mom), + refRemapper.origRefAndPtr[egele.sta_idx].first, + refRemapper.origRefAndPtr[egele.sta_idx].second, + egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::TkIso)); + tkele.setHwQual(gteg.quality); + tkele.setPFIsol(egele.floatRelIso(l1ct::EGIsoEleObjEmu::IsoType::PfIso)); + tkele.setEgBinaryWord(gteg.pack()); + return tkele; +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1TCtL2EgProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TEGMultiMerger.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TEGMultiMerger.cc new file mode 100644 index 0000000000000..44a83bf22db7a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TEGMultiMerger.cc @@ -0,0 +1,124 @@ +#include "DataFormats/L1TCorrelator/interface/TkElectron.h" +#include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1TCorrelator/interface/TkEm.h" +#include "DataFormats/L1TCorrelator/interface/TkEmFwd.h" + +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/transform.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include +#include + +class L1TEGMultiMerger : public edm::global::EDProducer<> { +public: + explicit L1TEGMultiMerger(const edm::ParameterSet&); + ~L1TEGMultiMerger() override; + +private: + void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; + + struct RefRemapper { + BXVector>> oldRefs; + std::map>, edm::Ref>> old2newRefMap; + }; + + template + class InstanceMerger { + public: + InstanceMerger(L1TEGMultiMerger* prod, const edm::ParameterSet& conf) + : instanceLabel_(conf.getParameter("instance")) { + for (const auto& producer_tag : conf.getParameter>("pfProducers")) { + tokens_.push_back( + prod->consumes(edm::InputTag(producer_tag.label(), producer_tag.instance(), producer_tag.process()))); + } + // FIXME: move this outside + prod->produces(instanceLabel_); + } + + void produce(edm::Event& iEvent, RefRemapper& refRemapper) const { + edm::Handle handle; + auto out = std::make_unique(); + for (const auto& token : tokens_) { + iEvent.getByToken(token, handle); + populate(out, handle, refRemapper); + } + remapRefs(iEvent, out, refRemapper); + iEvent.put(std::move(out), instanceLabel_); + } + + private: + template + void remapRefs(edm::Event& iEvent, std::unique_ptr& out, RefRemapper& refRemapper) const { + for (auto& egobj : *out) { + auto newref = refRemapper.old2newRefMap.find(egobj.EGRef()); + if (newref != refRemapper.old2newRefMap.end()) { + egobj.setEGRef(newref->second); + } + } + } + + void remapRefs(edm::Event& iEvent, std::unique_ptr>& out, RefRemapper& refRemapper) const { + edm::RefProd> ref_egs = iEvent.getRefBeforePut>(instanceLabel_); + edm::Ref>::key_type idx = 0; + for (std::size_t ix = 0; ix < out->size(); ix++) { + refRemapper.old2newRefMap[refRemapper.oldRefs[ix]] = edm::Ref>(ref_egs, idx++); + } + } + + template + void populate(std::unique_ptr& out, const edm::Handle& in, RefRemapper& refRemapper) const { + out->insert(out->end(), in->begin(), in->end()); + } + + void populate(std::unique_ptr>& out, + const edm::Handle>& in, + RefRemapper& refRemapper) const { + edm::Ref>::key_type idx = 0; + for (int bx = in->getFirstBX(); bx <= in->getLastBX(); bx++) { + for (auto egee_itr = in->begin(bx); egee_itr != in->end(bx); egee_itr++) { + out->push_back(bx, *egee_itr); + // this to ensure that the old ref and the new object have the same index in the BXVector collection so that we can still match them + // no matter which BX we will insert next + refRemapper.oldRefs.push_back(bx, edm::Ref>(in, idx++)); + } + } + } + + std::vector> tokens_; + std::string instanceLabel_; + }; + + std::vector> tkEleMerger; + std::vector> tkEmMerger; + std::vector>> tkEGMerger; +}; + +L1TEGMultiMerger::L1TEGMultiMerger(const edm::ParameterSet& conf) { + for (const auto& config : conf.getParameter>("tkEgs")) { + tkEGMerger.push_back(InstanceMerger>(this, config)); + } + for (const auto& config : conf.getParameter>("tkElectrons")) { + tkEleMerger.push_back(InstanceMerger(this, config)); + } + for (const auto& config : conf.getParameter>("tkEms")) { + tkEmMerger.push_back(InstanceMerger(this, config)); + } +} + +L1TEGMultiMerger::~L1TEGMultiMerger() {} + +void L1TEGMultiMerger::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const { + RefRemapper refmapper; + for (const auto& egMerger : tkEGMerger) + egMerger.produce(iEvent, refmapper); + for (const auto& eleMerger : tkEleMerger) + eleMerger.produce(iEvent, refmapper); + for (const auto& emMerger : tkEmMerger) + emMerger.produce(iEvent, refmapper); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(L1TEGMultiMerger); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc index 2387893723f67..50c1e7157c740 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCaloProducer.cc @@ -6,7 +6,6 @@ #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/FileInPath.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMultiMerger.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMultiMerger.cc index 96f36c36b794d..61e629b23097e 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMultiMerger.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFCandMultiMerger.cc @@ -16,34 +16,78 @@ class L1TPFCandMultiMerger : public edm::global::EDProducer<> { private: void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override; - std::vector instances_; - std::vector>> tokens_; + std::vector instances_, regionalInstances_; + std::vector alsoRegional_; // aligned with instances_ + std::vector> tokens_; + std::vector> regionalTokens_; }; L1TPFCandMultiMerger::L1TPFCandMultiMerger(const edm::ParameterSet& iConfig) - : instances_(iConfig.getParameter>("labelsToMerge")) { + : instances_(iConfig.getParameter>("labelsToMerge")), + regionalInstances_(iConfig.getParameter>("regionalLabelsToMerge")) { const std::vector& pfProducers = iConfig.getParameter>("pfProducers"); tokens_.reserve(instances_.size() * pfProducers.size()); - for (unsigned int ii = 0, ni = instances_.size(); ii < ni; ++ii) { + for (const std::string& instance : instances_) { for (const edm::InputTag& tag : pfProducers) { - tokens_.push_back( - consumes>(edm::InputTag(tag.label(), instances_[ii], tag.process()))); + tokens_.push_back(consumes(edm::InputTag(tag.label(), instance, tag.process()))); + } + produces(instance); + // check if regional output is needed too + if (std::find(regionalInstances_.begin(), regionalInstances_.end(), instance) != regionalInstances_.end()) { + alsoRegional_.push_back(true); + for (const edm::InputTag& tag : pfProducers) { + regionalTokens_.push_back( + consumes(edm::InputTag(tag.label(), instance + "Regional", tag.process()))); + } + produces(instance + "Regional"); + } else { + alsoRegional_.push_back(false); + } + } + // check that regional output is not requested without the standard one + for (const std::string& instance : regionalInstances_) { + auto match = std::find(instances_.begin(), instances_.end(), instance); + if (match == instances_.end()) { + throw cms::Exception("Configuration", "The regional label '" + instance + "' is not in labelsToMerge\n"); } - produces>(instances_[ii]); } } L1TPFCandMultiMerger::~L1TPFCandMultiMerger() {} void L1TPFCandMultiMerger::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const { - edm::Handle> handle; - for (unsigned int ii = 0, it = 0, ni = instances_.size(), np = tokens_.size() / ni; ii < ni; ++ii) { - auto out = std::make_unique>(); - for (unsigned int ip = 0; ip < np; ++ip, ++it) { + edm::Handle handle; + edm::Handle regionalHandle; + unsigned int ninstances = instances_.size(), nproducers = tokens_.size() / ninstances; + std::vector keys; + for (unsigned int ii = 0, it = 0, irt = 0; ii < ninstances; ++ii) { + auto out = std::make_unique(); + std::unique_ptr regout; + if (alsoRegional_[ii]) { + auto refprod = iEvent.getRefBeforePut(instances_[ii]); + regout = std::make_unique(edm::RefProd(refprod)); + } + for (unsigned int ip = 0; ip < nproducers; ++ip, ++it) { iEvent.getByToken(tokens_[it], handle); + unsigned int offset = out->size(); out->insert(out->end(), handle->begin(), handle->end()); + if (alsoRegional_[ii]) { + iEvent.getByToken(regionalTokens_[irt++], regionalHandle); + const auto& src = *regionalHandle; + for (unsigned int ireg = 0, nreg = src.nRegions(); ireg < nreg; ++ireg) { + auto region = src.region(ireg); + keys.clear(); + for (auto iter = region.begin(), iend = region.end(); iter != iend; ++iter) { + keys.push_back(iter.idx() + offset); + } + regout->addRegion(keys, src.eta(ireg), src.phi(ireg)); + } + } } iEvent.put(std::move(out), instances_[ii]); + if (alsoRegional_[ii]) { + iEvent.put(std::move(regout), instances_[ii] + "Regional"); + } } } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc deleted file mode 100644 index 0f1df6946a646..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/L1TPFProducer.cc +++ /dev/null @@ -1,401 +0,0 @@ -// system include files -#include -#include -#include -#include - -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/ESHandle.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ParameterSet/interface/FileInPath.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" - -#include "DataFormats/Common/interface/View.h" -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" - -#include "DataFormats/Math/interface/deltaR.h" - -#include "L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h" - -#include "DataFormats/L1TCorrelator/interface/TkMuon.h" -#include "DataFormats/L1TCorrelator/interface/TkMuonFwd.h" - -//-------------------------------------------------------------------------------------------------- -class L1TPFProducer : public edm::stream::EDProducer<> { -public: - explicit L1TPFProducer(const edm::ParameterSet&); - ~L1TPFProducer() override; - -private: - edm::ParameterSet config_; - int debug_; - - bool useStandaloneMuons_; - bool useTrackerMuons_; - - bool hasTracks_; - edm::EDGetTokenT tkCands_; - float trkPt_, trkMaxChi2_; - unsigned trkMinStubs_; - l1tpf_impl::PUAlgoBase::VertexAlgo vtxAlgo_; - edm::EDGetTokenT> extTkVtx_; - - edm::EDGetTokenT muCands_; // standalone muons - edm::EDGetTokenT tkMuCands_; // tk muons - - std::vector> emCands_; - std::vector> hadCands_; - - float emPtCut_, hadPtCut_; - - l1tpf_impl::RegionMapper l1regions_; - std::unique_ptr l1pfalgo_; - std::unique_ptr l1pualgo_; - - edm::EDGetTokenT TokGenOrigin_; - - // Region dump/coe - const std::string regionDumpName_, regionCOEName_; - FILE* fRegionDump_; - std::unique_ptr fRegionCOE_; - unsigned int neventscoemax_, neventsproduced_; - - // region of interest debugging - float debugEta_, debugPhi_, debugR_; - - void beginStream(edm::StreamID) override; - void produce(edm::Event&, const edm::EventSetup&) override; - void addUInt(unsigned int value, std::string iLabel, edm::Event& iEvent); -}; - -// -// constructors and destructor -// -L1TPFProducer::L1TPFProducer(const edm::ParameterSet& iConfig) - : config_(iConfig), - debug_(iConfig.getUntrackedParameter("debug", 0)), - useStandaloneMuons_(iConfig.getParameter("useStandaloneMuons")), - useTrackerMuons_(iConfig.getParameter("useTrackerMuons")), - hasTracks_(!iConfig.getParameter("tracks").label().empty()), - tkCands_(hasTracks_ ? consumes(iConfig.getParameter("tracks")) - : edm::EDGetTokenT()), - trkPt_(iConfig.getParameter("trkPtCut")), - trkMaxChi2_(iConfig.getParameter("trkMaxChi2")), - trkMinStubs_(iConfig.getParameter("trkMinStubs")), - muCands_(consumes(iConfig.getParameter("muons"))), - tkMuCands_(consumes(iConfig.getParameter("tkMuons"))), - emPtCut_(iConfig.getParameter("emPtCut")), - hadPtCut_(iConfig.getParameter("hadPtCut")), - l1regions_(iConfig), - l1pfalgo_(nullptr), - l1pualgo_(nullptr), - regionDumpName_(iConfig.getUntrackedParameter("dumpFileName", "")), - regionCOEName_(iConfig.getUntrackedParameter("coeFileName", "")), - fRegionDump_(nullptr), - fRegionCOE_(nullptr), - neventscoemax_(iConfig.getUntrackedParameter("neventscoemax_", 0)), - neventsproduced_(0), - debugEta_(iConfig.getUntrackedParameter("debugEta", 0)), - debugPhi_(iConfig.getUntrackedParameter("debugPhi", 0)), - debugR_(iConfig.getUntrackedParameter("debugR", -1)) { - produces("PF"); - produces("Puppi"); - - produces("EmCalo"); - produces("Calo"); - produces("TK"); - produces("TKVtx"); - - produces("z0"); - - for (const auto& tag : iConfig.getParameter>("emClusters")) { - emCands_.push_back(consumes(tag)); - } - for (const auto& tag : iConfig.getParameter>("hadClusters")) { - hadCands_.push_back(consumes(tag)); - } - - const std::string& algo = iConfig.getParameter("pfAlgo"); - if (algo == "PFAlgo3") { - l1pfalgo_ = std::make_unique(iConfig); - } else if (algo == "PFAlgo2HGC") { - l1pfalgo_ = std::make_unique(iConfig); - } else if (algo == "BitwisePFAlgo") { - l1pfalgo_ = std::make_unique(iConfig); - } else - throw cms::Exception("Configuration", "Unsupported PFAlgo"); - - const std::string& pualgo = iConfig.getParameter("puAlgo"); - if (pualgo == "Puppi") { - l1pualgo_ = std::make_unique(iConfig); - } else if (pualgo == "LinearizedPuppi") { - l1pualgo_ = std::make_unique(iConfig); - } else - throw cms::Exception("Configuration", "Unsupported PUAlgo"); - - std::string vtxAlgo = iConfig.getParameter("vtxAlgo"); - if (vtxAlgo == "TP") - vtxAlgo_ = l1tpf_impl::PUAlgoBase::VertexAlgo::TP; - else if (vtxAlgo == "old") - vtxAlgo_ = l1tpf_impl::PUAlgoBase::VertexAlgo::Old; - else if (vtxAlgo == "external") { - vtxAlgo_ = l1tpf_impl::PUAlgoBase::VertexAlgo::External; - const std::string& vtxFormat = iConfig.getParameter("vtxFormat"); - if (vtxFormat == "TkPrimaryVertex") { - extTkVtx_ = consumes>(iConfig.getParameter("vtxCollection")); - } else - throw cms::Exception("Configuration") << "Unsupported vtxFormat " << vtxFormat << "\n"; - } else - throw cms::Exception("Configuration") << "Unsupported vtxAlgo " << vtxAlgo << "\n"; - - for (const std::string& label : l1pualgo_->puGlobalNames()) { - produces(label); - } - - if (!regionDumpName_.empty()) { - TokGenOrigin_ = consumes(iConfig.getParameter("genOrigin")); - } - for (int tot = 0; tot <= 1; ++tot) { - for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) { - produces(std::string(tot ? "totNL1" : "maxNL1") + l1tpf_impl::Region::inputTypeName(i)); - } - for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) { - produces(std::string(tot ? "totNL1PF" : "maxNL1PF") + l1tpf_impl::Region::outputTypeName(i)); - produces(std::string(tot ? "totNL1Puppi" : "maxNL1Puppi") + l1tpf_impl::Region::outputTypeName(i)); - } - } - for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) { - produces>(std::string("vecNL1") + l1tpf_impl::Region::inputTypeName(i)); - } - for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) { - produces>(std::string("vecNL1PF") + l1tpf_impl::Region::outputTypeName(i)); - produces>(std::string("vecNL1Puppi") + l1tpf_impl::Region::outputTypeName(i)); - } -} - -L1TPFProducer::~L1TPFProducer() { - // do anything here that needs to be done at desctruction time - // (e.g. close files, deallocate resources etc.) - if (fRegionDump_) - fclose(fRegionDump_); - if (fRegionCOE_) - fRegionCOE_->close(); -} - -void L1TPFProducer::beginStream(edm::StreamID id) { - if (!regionDumpName_.empty()) { - if (id == 0) { - fRegionDump_ = fopen(regionDumpName_.c_str(), "wb"); - } else { - edm::LogWarning("L1TPFProducer") - << "Job running with multiple streams, but dump file will have only events on stream zero."; - } - } - if (!regionCOEName_.empty()) { - if (id == 0) { - fRegionCOE_ = std::make_unique(config_); - } else { - edm::LogWarning("L1TPFProducer") - << "Job running with multiple streams, but COE file will dump only events on stream zero."; - } - } -} - -// ------------ method called to produce the data ------------ -void L1TPFProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - // clear the regions also at the beginning, in case one event didn't complete but the job continues on - l1regions_.clear(); - - /// ------ READ TRACKS ---- - if (hasTracks_) { - edm::Handle htracks; - iEvent.getByToken(tkCands_, htracks); - const auto& tracks = *htracks; - for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) { - const auto& tk = tracks[itk]; - // adding objects to PF - if (debugR_ > 0 && deltaR(tk.eta(), tk.phi(), debugEta_, debugPhi_) > debugR_) - continue; - if (tk.pt() > trkPt_ && tk.nStubs() >= trkMinStubs_ && tk.normalizedChi2() < trkMaxChi2_) { - l1regions_.addTrack(tk, l1t::PFTrackRef(htracks, itk)); - } - } - } - - /// ------ READ MUONS ---- - /// ------- first check that not more than one version of muons (standaloneMu or trackerMu) is set to be used in l1pflow - if (useStandaloneMuons_ && useTrackerMuons_) { - throw cms::Exception( - "Configuration", - "setting useStandaloneMuons=True && useTrackerMuons=True is not to be done, as it would duplicate all muons\n"); - } - - if (useStandaloneMuons_) { - edm::Handle muons; - iEvent.getByToken(muCands_, muons); - for (auto it = muons->begin(0), ed = muons->end(0); it != ed; ++it) { - const l1t::Muon& mu = *it; - if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_) - continue; - l1regions_.addMuon(mu, l1t::PFCandidate::MuonRef(muons, muons->key(it))); - } - } - - if (useTrackerMuons_) { - edm::Handle muons; - iEvent.getByToken(tkMuCands_, muons); - for (auto it = muons->begin(), ed = muons->end(); it != ed; ++it) { - const l1t::TkMuon& mu = *it; - if (debugR_ > 0 && deltaR(mu.eta(), mu.phi(), debugEta_, debugPhi_) > debugR_) - continue; - l1regions_.addMuon(mu); // FIXME add a l1t::PFCandidate::MuonRef - } - } - - // ------ READ CALOS ----- - edm::Handle caloHandle; - for (const auto& tag : emCands_) { - iEvent.getByToken(tag, caloHandle); - const auto& calos = *caloHandle; - for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) { - const auto& calo = calos[ic]; - if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_) - continue; - if (calo.pt() > emPtCut_) - l1regions_.addEmCalo(calo, l1t::PFClusterRef(caloHandle, ic)); - } - } - for (const auto& tag : hadCands_) { - iEvent.getByToken(tag, caloHandle); - const auto& calos = *caloHandle; - for (unsigned int ic = 0, nc = calos.size(); ic < nc; ++ic) { - const auto& calo = calos[ic]; - if (debugR_ > 0 && deltaR(calo.eta(), calo.phi(), debugEta_, debugPhi_) > debugR_) - continue; - if (calo.pt() > hadPtCut_) - l1regions_.addCalo(calo, l1t::PFClusterRef(caloHandle, ic)); - } - } - - // First, get a copy of the discretized and corrected inputs, and write them out - iEvent.put(l1regions_.fetchCalo(/*ptmin=*/0.1, /*em=*/true), "EmCalo"); - iEvent.put(l1regions_.fetchCalo(/*ptmin=*/0.1, /*em=*/false), "Calo"); - iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/false), "TK"); - if (fRegionDump_) { - uint32_t run = iEvent.id().run(), lumi = iEvent.id().luminosityBlock(); - uint64_t event = iEvent.id().event(); - fwrite(&run, sizeof(uint32_t), 1, fRegionDump_); - fwrite(&lumi, sizeof(uint32_t), 1, fRegionDump_); - fwrite(&event, sizeof(uint64_t), 1, fRegionDump_); - l1tpf_impl::writeManyToFile(l1regions_.regions(), fRegionDump_); - } - - // Then save the regions to the COE file - // Do it here because there is some sorting going on in a later function - if (fRegionCOE_ && fRegionCOE_->is_open() && neventsproduced_ < neventscoemax_) { - std::vector regions = l1regions_.regions(); - fRegionCOE_->writeTracksToFile(regions, neventsproduced_ == 0); - } - neventsproduced_++; - - // Then do the vertexing, and save it out - float z0; - if (vtxAlgo_ == l1tpf_impl::PUAlgoBase::VertexAlgo::External) { - z0 = 0; - double ptsum = 0; - if (!extTkVtx_.isUninitialized()) { - edm::Handle> vtxHandle; - iEvent.getByToken(extTkVtx_, vtxHandle); - for (const l1t::TkPrimaryVertex& vtx : *vtxHandle) { - if (ptsum == 0 || vtx.sum() > ptsum) { - z0 = vtx.zvertex(); - ptsum = vtx.sum(); - } - } - } else - throw cms::Exception("LogicError", "Inconsistent vertex configuration"); - } - l1pualgo_->doVertexing(l1regions_.regions(), vtxAlgo_, z0); - iEvent.put(std::make_unique(z0), "z0"); - if (fRegionDump_) { - fwrite(&z0, sizeof(float), 1, fRegionDump_); - edm::Handle hGenOrigin; - iEvent.getByToken(TokGenOrigin_, hGenOrigin); - const math::XYZPointF& genOrigin = *hGenOrigin; - float genZ = genOrigin.Z(); - fwrite(&genZ, sizeof(float), 1, fRegionDump_); - } - - // Then also save the tracks with a vertex cut - iEvent.put(l1regions_.fetchTracks(/*ptmin=*/0.0, /*fromPV=*/true), "TKVtx"); - - // Then run PF in each region - for (auto& l1region : l1regions_.regions()) { - l1pfalgo_->runPF(l1region); - l1pualgo_->runChargedPV(l1region, z0); - } - // save PF into the event - iEvent.put(l1regions_.fetch(false), "PF"); - - // Then get our alphas (globally) - std::vector puGlobals; - l1pualgo_->doPUGlobals(l1regions_.regions(), -1., puGlobals); // FIXME we don't have yet an external PU estimate - const std::vector& puGlobalNames = l1pualgo_->puGlobalNames(); - if (puGlobals.size() != puGlobalNames.size()) - throw cms::Exception("LogicError", "Mismatch in the number of global pileup inputs"); - for (unsigned int i = 0, n = puGlobalNames.size(); i < n; ++i) { - iEvent.put(std::make_unique(puGlobals[i]), puGlobalNames[i]); - } - if (fRegionDump_) { - l1tpf_impl::writeManyToFile(puGlobals, fRegionDump_); - } - - // Then run puppi (regionally) - for (auto& l1region : l1regions_.regions()) { - l1pualgo_->runNeutralsPU(l1region, -1., puGlobals); - } - // and save puppi - iEvent.put(l1regions_.fetch(true), "Puppi"); - - // Then go do the multiplicities - - for (int i = 0; i < l1tpf_impl::Region::n_input_types; ++i) { - auto totAndMax = l1regions_.totAndMaxInput(i); - addUInt(totAndMax.first, std::string("totNL1") + l1tpf_impl::Region::inputTypeName(i), iEvent); - addUInt(totAndMax.second, std::string("maxNL1") + l1tpf_impl::Region::inputTypeName(i), iEvent); - iEvent.put(l1regions_.vecInput(i), std::string("vecNL1") + l1tpf_impl::Region::inputTypeName(i)); - } - for (int i = 0; i < l1tpf_impl::Region::n_output_types; ++i) { - auto totAndMaxPF = l1regions_.totAndMaxOutput(i, false); - auto totAndMaxPuppi = l1regions_.totAndMaxOutput(i, true); - addUInt(totAndMaxPF.first, std::string("totNL1PF") + l1tpf_impl::Region::outputTypeName(i), iEvent); - addUInt(totAndMaxPF.second, std::string("maxNL1PF") + l1tpf_impl::Region::outputTypeName(i), iEvent); - addUInt(totAndMaxPuppi.first, std::string("totNL1Puppi") + l1tpf_impl::Region::outputTypeName(i), iEvent); - addUInt(totAndMaxPuppi.second, std::string("maxNL1Puppi") + l1tpf_impl::Region::outputTypeName(i), iEvent); - iEvent.put(l1regions_.vecOutput(i, false), std::string("vecNL1PF") + l1tpf_impl::Region::outputTypeName(i)); - iEvent.put(l1regions_.vecOutput(i, true), std::string("vecNL1Puppi") + l1tpf_impl::Region::outputTypeName(i)); - } - - // finally clear the regions - l1regions_.clear(); -} - -void L1TPFProducer::addUInt(unsigned int value, std::string iLabel, edm::Event& iEvent) { - iEvent.put(std::make_unique(value), iLabel); -} - -//define this as a plug-in -#include "FWCore/Framework/interface/MakerMacros.h" -DEFINE_FWK_MODULE(L1TPFProducer); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc index 5b58c2931096a..8e60240bdb205 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromHGC3DClusters.cc @@ -1,9 +1,9 @@ #include -#include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/MakerMacros.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 "DataFormats/L1TParticleFlow/interface/PFCluster.h" @@ -20,7 +20,10 @@ namespace l1tpf { ~PFClusterProducerFromHGC3DClusters() override {} private: + enum class UseEmInterp { No, EmOnly, AllKeepHad, AllKeepTot }; + edm::EDGetTokenT src_; + UseEmInterp scenario_; bool emOnly_; double etCut_; StringCutObjectSelector preEmId_; @@ -36,6 +39,7 @@ namespace l1tpf { l1tpf::PFClusterProducerFromHGC3DClusters::PFClusterProducerFromHGC3DClusters(const edm::ParameterSet &iConfig) : src_(consumes(iConfig.getParameter("src"))), + scenario_(UseEmInterp::No), emOnly_(iConfig.getParameter("emOnly")), etCut_(iConfig.getParameter("etMin")), preEmId_(iConfig.getParameter("preEmId")), @@ -56,14 +60,33 @@ l1tpf::PFClusterProducerFromHGC3DClusters::PFClusterProducerFromHGC3DClusters(co } produces(); + produces("egamma"); if (hasEmId_) { produces("em"); produces("had"); } + + std::string scenario = iConfig.getParameter("useEMInterpretation"); + if (scenario == "emOnly") { + scenario_ = UseEmInterp::EmOnly; + } else if (scenario == "allKeepHad") { + scenario_ = UseEmInterp::AllKeepHad; + if (emOnly_) { + throw cms::Exception("Configuration", "Unsupported emOnly = True when useEMInterpretation is " + scenario); + } + } else if (scenario == "allKeepTot") { + scenario_ = UseEmInterp::AllKeepTot; + if (emOnly_) { + throw cms::Exception("Configuration", "Unsupported emOnly = True when useEMInterpretation is " + scenario); + } + } else if (scenario != "no") { + throw cms::Exception("Configuration", "Unsupported useEMInterpretation scenario " + scenario); + } } void l1tpf::PFClusterProducerFromHGC3DClusters::produce(edm::Event &iEvent, const edm::EventSetup &) { auto out = std::make_unique(); + auto outEgamma = std::make_unique(); std::unique_ptr outEm, outHad; if (hasEmId_) { outEm = std::make_unique(); @@ -84,15 +107,51 @@ void l1tpf::PFClusterProducerFromHGC3DClusters::produce(edm::Event &iEvent, cons if (pt <= etCut_) continue; - l1t::PFCluster cluster(pt, it->eta(), it->phi(), hoe, /*isEM=*/isEM); + // this block below is to support the older EG emulators, and is not used in newer ones + if (it->hwQual()) { // this is the EG ID shipped with the HGC TPs + // we use the EM interpretation of the cluster energy + l1t::PFCluster egcluster( + it->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM), it->eta(), it->phi(), hoe, false); + egcluster.setHwQual(it->hwQual()); + egcluster.addConstituent(edm::Ptr(multiclusters, multiclusters->key(it))); + outEgamma->push_back(egcluster); + } + + l1t::PFCluster cluster(pt, it->eta(), it->phi(), hoe); + if (scenario_ == UseEmInterp::EmOnly) { // for emID objs, use EM interp as pT and set H = 0 + if (isEM) { + float pt_new = it->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM); + float hoe_new = 0.; + cluster = l1t::PFCluster(pt_new, it->eta(), it->phi(), hoe_new, /*isEM=*/isEM); + } + } else if (scenario_ == UseEmInterp::AllKeepHad) { // for all objs, replace EM part with EM interp, preserve H + float had_old = pt - cluster.emEt(); + //float em_old = cluster.emEt(); + float em_new = it->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM); + float pt_new = had_old + em_new; + float hoe_new = em_new > 0 ? (had_old / em_new) : -1; + cluster = l1t::PFCluster(pt_new, it->eta(), it->phi(), hoe_new, /*isEM=*/isEM); + //printf("Scenario %d: pt %7.2f eta %+5.3f em %7.2f, EMI %7.2f, h/e % 8.3f --> pt %7.2f, em %7.2f, h/e % 8.3f\n", + // 2, pt, it->eta(), em_old, em_new, hoe, cluster.pt(), cluster.emEt(), cluster.hOverE()); + } else if (scenario_ == UseEmInterp::AllKeepTot) { // for all objs, replace EM part with EM interp, preserve pT + //float em_old = cluster.emEt(); + float em_new = it->iPt(l1t::HGCalMulticluster::EnergyInterpretation::EM); + float hoe_new = em_new > 0 ? (it->pt() / em_new - 1) : -1; + cluster = l1t::PFCluster(it->pt(), it->eta(), it->phi(), hoe_new, /*isEM=*/isEM); + //printf("Scenario %d: pt %7.2f eta %+5.3f em %7.2f, EMI %7.2f, h/e % 8.3f --> pt %7.2f, em %7.2f, h/e % 8.3f\n", + // 3, pt, it->eta(), em_old, em_new, hoe, cluster.pt(), cluster.emEt(), cluster.hOverE()); + } + if (!emVsPUID_.method().empty()) { if (!emVsPUID_.passID(*it, cluster)) { continue; } } - if (!emVsPionID_.method().empty()) { - cluster.setIsEM(emVsPionID_.passID(*it, cluster)); + if (!emOnly_ && !emVsPionID_.method().empty()) { + isEM = emVsPionID_.passID(*it, cluster); } + cluster.setHwQual((isEM ? 1 : 0) + (it->hwQual() << 1)); + if (corrector_.valid()) corrector_.correctPt(cluster); cluster.setPtError(resol_(cluster.pt(), std::abs(cluster.eta()))); @@ -105,6 +164,7 @@ void l1tpf::PFClusterProducerFromHGC3DClusters::produce(edm::Event &iEvent, cons } iEvent.put(std::move(out)); + iEvent.put(std::move(outEgamma), "egamma"); if (hasEmId_) { iEvent.put(std::move(outEm), "em"); iEvent.put(std::move(outHad), "had"); diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc index 085110ff0c2d9..1a54b25340f61 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFClusterProducerFromL1EGClusters.cc @@ -7,7 +7,7 @@ #include "DataFormats/L1TParticleFlow/interface/PFCluster.h" #include "L1Trigger/Phase2L1ParticleFlow/src/corrector.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" -#include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" namespace l1tpf { class PFClusterProducerFromL1EGClusters : public edm::stream::EDProducer<> { @@ -16,7 +16,7 @@ namespace l1tpf { ~PFClusterProducerFromL1EGClusters() override {} private: - edm::EDGetTokenT src_; + edm::EDGetTokenT> src_; double etCut_; l1tpf::corrector corrector_; l1tpf::ParametricResolution resol_; @@ -27,7 +27,7 @@ namespace l1tpf { } // namespace l1tpf l1tpf::PFClusterProducerFromL1EGClusters::PFClusterProducerFromL1EGClusters(const edm::ParameterSet &iConfig) - : src_(consumes(iConfig.getParameter("src"))), + : src_(consumes>(iConfig.getParameter("src"))), etCut_(iConfig.getParameter("etMin")), corrector_(iConfig.getParameter("corrector"), -1), resol_(iConfig.getParameter("resol")) { @@ -36,7 +36,7 @@ l1tpf::PFClusterProducerFromL1EGClusters::PFClusterProducerFromL1EGClusters(cons void l1tpf::PFClusterProducerFromL1EGClusters::produce(edm::Event &iEvent, const edm::EventSetup &) { std::unique_ptr out(new l1t::PFClusterCollection()); - edm::Handle clusters; + edm::Handle> clusters; iEvent.getByToken(src_, clusters); unsigned int index = 0; @@ -49,7 +49,7 @@ void l1tpf::PFClusterProducerFromL1EGClusters::produce(edm::Event &iEvent, const if (corrector_.valid()) corrector_.correctPt(cluster); cluster.setPtError(resol_(cluster.pt(), std::abs(cluster.eta()))); - + cluster.setHwQual(it->hwQual()); out->push_back(cluster); out->back().addConstituent(edm::Ptr(clusters, index)); } diff --git a/L1Trigger/Phase2L1ParticleFlow/plugins/PFTrackProducerFromL1Tracks.cc b/L1Trigger/Phase2L1ParticleFlow/plugins/PFTrackProducerFromL1Tracks.cc index aee20808fbb8a..1cae299a73208 100644 --- a/L1Trigger/Phase2L1ParticleFlow/plugins/PFTrackProducerFromL1Tracks.cc +++ b/L1Trigger/Phase2L1ParticleFlow/plugins/PFTrackProducerFromL1Tracks.cc @@ -4,7 +4,6 @@ #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "MagneticField/Engine/interface/MagneticField.h" #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" #include "FWCore/Framework/interface/ESWatcher.h" @@ -13,6 +12,8 @@ #include "L1Trigger/Phase2L1ParticleFlow/interface/L1TPFUtils.h" #include "L1Trigger/Phase2L1ParticleFlow/interface/ParametricResolution.h" +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" + namespace l1tpf { class PFTrackProducerFromL1Tracks : public edm::stream::EDProducer<> { public: @@ -26,6 +27,8 @@ namespace l1tpf { int nParam_; float fBz_; l1tpf::ParametricResolution resolCalo_, resolTrk_; + std::vector> qualityBitSetters_; + bool redigitizeTrackWord_; void produce(edm::Event &, const edm::EventSetup &) override; @@ -37,7 +40,11 @@ l1tpf::PFTrackProducerFromL1Tracks::PFTrackProducerFromL1Tracks(const edm::Param BFieldTag_{esConsumes()}, nParam_(iConfig.getParameter("nParam")), resolCalo_(iConfig.getParameter("resolCalo")), - resolTrk_(iConfig.getParameter("resolTrack")) { + resolTrk_(iConfig.getParameter("resolTrack")), + redigitizeTrackWord_(iConfig.getParameter("redigitizeTrackWord")) { + for (const auto &cut : iConfig.getParameter>("qualityBits")) { + qualityBitSetters_.emplace_back(cut); + } produces(); } @@ -64,13 +71,17 @@ void l1tpf::PFTrackProducerFromL1Tracks::produce(edm::Event &iEvent, const edm:: reco::Candidate::PolarLorentzVector p4p(pt, eta, phi, 0.137); // pion mass reco::Particle::LorentzVector p4(p4p.X(), p4p.Y(), p4p.Z(), p4p.E()); - reco::Particle::Point vtx(0., 0., z0); + reco::Particle::Point vtx(tk.POCA().x(), tk.POCA().y(), z0); auto caloetaphi = l1tpf::propagateToCalo(p4, math::XYZTLorentzVector(0., 0., z0, 0.), charge, fBz_); float trkErr = resolTrk_(pt, std::abs(eta)); float caloErr = resolCalo_(pt, std::abs(eta)); - int quality = 1; + int quality = 0; + for (int i = 0, n = qualityBitSetters_.size(), bit = 1; i < n; ++i, bit <<= 1) { + if (qualityBitSetters_[i](tk)) + quality += bit; + } out->emplace_back(charge, p4, vtx, @@ -81,6 +92,25 @@ void l1tpf::PFTrackProducerFromL1Tracks::produce(edm::Event &iEvent, const edm:: trkErr, caloErr, quality); + + if (redigitizeTrackWord_) { + // Force re-digitization if an old TTrack object is read from an EDM file, and update the quaility bit for now + l1t::PFTrack::L1TTTrackType trackCopy = tk; + trackCopy.setTrackWordBits(); // important + TTTrack_TrackWord &tw = out->back().trackWord(); + tw.setTrackWord(trackCopy.getValidWord(), + trackCopy.getRinvWord(), + trackCopy.getPhiWord(), + trackCopy.getTanlWord(), + trackCopy.getZ0Word(), + trackCopy.getD0Word(), + trackCopy.getChi2RPhiWord(), + trackCopy.getChi2RZWord(), + trackCopy.getBendChi2Word(), + trackCopy.getHitPatternWord(), + trackCopy.getMVAQualityWord(), + ap_uint(quality)); + } } iEvent.put(std::move(out)); } diff --git a/L1Trigger/Phase2L1ParticleFlow/python/DeregionizerProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/DeregionizerProducer_cfi.py new file mode 100644 index 0000000000000..d010a5cd6de33 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/DeregionizerProducer_cfi.py @@ -0,0 +1,10 @@ +import FWCore.ParameterSet.Config as cms + +DeregionizerProducer = cms.EDProducer("DeregionizerProducer", + RegionalPuppiCands = cms.InputTag("l1ctLayer1","PuppiRegional"), + nPuppiFinalBuffer = cms.uint32(128), + nPuppiPerClk = cms.uint32(6), + nPuppiFirstBuffers = cms.uint32(12), + nPuppiSecondBuffers = cms.uint32(32), + nPuppiThirdBuffers = cms.uint32(64) + ) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/L1MetPfProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/L1MetPfProducer_cfi.py new file mode 100644 index 0000000000000..7687521ed327a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/L1MetPfProducer_cfi.py @@ -0,0 +1,6 @@ +import FWCore.ParameterSet.Config as cms + +L1MetPfProducer = cms.EDProducer("L1MetPfProducer", + L1PFObjects = cms.InputTag("l1ctLayer1","Puppi"), + maxCands = cms.int32(128), +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/L1MhtPfProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/L1MhtPfProducer_cfi.py new file mode 100644 index 0000000000000..d6799b3adbb24 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/L1MhtPfProducer_cfi.py @@ -0,0 +1,7 @@ +import FWCore.ParameterSet.Config as cms + +L1MhtPfProducer = cms.EDProducer("L1MhtPfProducer", + jets = cms.InputTag("scPFL1PuppiEmulator"), + minJetPt = cms.double(30.0), + maxJetEta = cms.double(2.4) +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/L1NNTauProducer_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/L1NNTauProducer_cff.py index c1ffa1b4d2f1f..b2715838facf5 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/L1NNTauProducer_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/L1NNTauProducer_cff.py @@ -1,7 +1,57 @@ import FWCore.ParameterSet.Config as cms -from L1Trigger.Phase2L1ParticleFlow.L1NNTauProducer_cfi import * +from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_cff import l1ctLayer1Barrel,l1ctLayer1HGCal,l1ctLayer1 -L1NNTauProducerPuppi = L1NNTauProducer.clone( - NNFileName = cms.string("L1Trigger/Phase2L1ParticleFlow/data/tau_3layer_puppi.pb") - ) +#from L1Trigger.Phase2L1ParticleFlow.L1NNTauProducer_cfi import * + +#L1NNTauProducerPuppi = L1NNTauProducer.clone( +# NNFileName = cms.string("L1Trigger/Phase2L1ParticleFlow/data/tau_3layer_puppi.pb") +# ) + + +L1NNTauProducerPuppi = cms.EDProducer("L1NNTauProducer", + seedpt = cms.double(10), + conesize = cms.double(0.4), + tausize = cms.double(0.1), + maxtaus = cms.int32(5), + nparticles = cms.int32(10), + HW = cms.bool(True), + debug = cms.bool(False), + L1PFObjects = cms.InputTag("l1ctLayer1:Puppi"), #1pfCandidates:Puppi"),#l1pfCandidates + NNFileName = cms.string("L1Trigger/Phase2L1ParticleFlow/data/tau_3layer_puppi.pb") +) + +L1NNTauProducerPF = cms.EDProducer("L1NNTauProducer", + seedpt = cms.double(10), + conesize = cms.double(0.4), + tausize = cms.double(0.1), + maxtaus = cms.int32(5), + nparticles = cms.int32(10), + HW = cms.bool(True), + debug = cms.bool(False), + L1PFObjects = cms.InputTag("l1ctLayer1:PF"),#l1pfCandidates + NNFileName = cms.string("L1Trigger/Phase2L1ParticleFlow/data/tau_3layer.pb") +) + + +l1ctLayer1Barrel2Vtx = l1ctLayer1Barrel.clone() +l1ctLayer1Barrel2Vtx.nVtx = 2 +l1ctLayer1Barrel2Vtx.puAlgoParameters.nVtx = 2 +l1ctLayer1HGCal2Vtx = l1ctLayer1HGCal.clone() +l1ctLayer1HGCal2Vtx.nVtx = 2 +l1ctLayer1HGCal2Vtx.puAlgoParameters.nVtx = 2 +l1ctLayer12Vtx = l1ctLayer1.clone() +l1ctLayer12Vtx.pfProducers = cms.VInputTag( + cms.InputTag("l1ctLayer1Barrel2Vtx"), + cms.InputTag("l1ctLayer1HGCal2Vtx"), + cms.InputTag("l1ctLayer1HGCalNoTK"), + cms.InputTag("l1ctLayer1HF") +) +L1NNTauProducerPuppi2Vtx = L1NNTauProducerPuppi.clone() +L1NNTauProducerPuppi2Vtx.L1PFObjects = cms.InputTag("l1ctLayer12Vtx:Puppi") +tau2VtxTaskHW = cms.Task( + l1ctLayer1Barrel2Vtx, + l1ctLayer1HGCal2Vtx, + l1ctLayer12Vtx, + L1NNTauProducerPuppi2Vtx +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/L1SeedConePFJetProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/L1SeedConePFJetProducer_cfi.py new file mode 100644 index 0000000000000..7b3c7b81486b4 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/L1SeedConePFJetProducer_cfi.py @@ -0,0 +1,17 @@ +import FWCore.ParameterSet.Config as cms + +L1SeedConePFJetProducer = cms.EDProducer("L1SeedConePFJetProducer", + L1PFObjects = cms.InputTag("l1ctLayer1","Puppi"), + nJets = cms.uint32(10), + coneSize = cms.double(0.4), + HW = cms.bool(False), + debug = cms.bool(False) + ) + +L1SeedConePFJetEmulatorProducer = cms.EDProducer("L1SeedConePFJetProducer", + L1PFObjects = cms.InputTag("l1ctLayer1","Puppi"), + nJets = cms.uint32(10), + coneSize = cms.double(0.4), + HW = cms.bool(True), + debug = cms.bool(False) + ) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py deleted file mode 100644 index c43e85c93f71d..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1ParticleFlow_cff.py +++ /dev/null @@ -1,316 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from L1Trigger.Phase2L1ParticleFlow.pfTracksFromL1Tracks_cfi import pfTracksFromL1Tracks -from L1Trigger.Phase2L1ParticleFlow.pfClustersFromL1EGClusters_cfi import pfClustersFromL1EGClusters -from L1Trigger.Phase2L1ParticleFlow.pfClustersFromCombinedCalo_cfi import pfClustersFromCombinedCalo -from L1Trigger.Phase2L1ParticleFlow.l1pfProducer_cfi import l1pfProducer - -# 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 -from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 - -# Calorimeter part: ecal + hcal + hf only -pfClustersFromCombinedCaloHCal = pfClustersFromCombinedCalo.clone( - hcalHGCTowers = [], hcalDigis = [], - hcalDigisBarrel = True, hcalDigisHF = False, - hadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root"), - resol = cms.PSet( - etaBins = cms.vdouble( 0.700, 1.200, 1.600), - offset = cms.vdouble( 2.582, 2.191, -0.077), - scale = cms.vdouble( 0.122, 0.143, 0.465), - kind = cms.string('calo'), - )) -phase2_hgcalV10.toModify(pfClustersFromCombinedCaloHCal, - hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel_106X.root", - resol = cms.PSet( - etaBins = cms.vdouble( 0.700, 1.200, 1.600), - offset = cms.vdouble( 3.084, 2.715, 0.107), - scale = cms.vdouble( 0.118, 0.130, 0.442), - kind = cms.string('calo'), - ) -) -phase2_hgcalV11.toModify(pfClustersFromCombinedCaloHCal, - hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel_110X.root", - resol = cms.PSet( - etaBins = cms.vdouble( 0.700, 1.200, 1.600), - offset = cms.vdouble( 2.909, 2.864, 0.294), - scale = cms.vdouble( 0.119, 0.127, 0.442), - kind = cms.string('calo'), - ) -) - -pfTracksFromL1TracksBarrel = pfTracksFromL1Tracks.clone( - resolCalo = pfClustersFromCombinedCaloHCal.resol.clone(), -) - -pfClustersFromCombinedCaloHF = pfClustersFromCombinedCalo.clone( - ecalCandidates = [], hcalHGCTowers = [], - phase2barrelCaloTowers = [], - hadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hfcorr.root"), - resol = cms.PSet( - etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), - offset = cms.vdouble( 1.099, 0.930, 1.009, 1.369), - scale = cms.vdouble( 0.152, 0.151, 0.144, 0.179), - kind = cms.string('calo'), - )) -phase2_hgcalV10.toModify(pfClustersFromCombinedCaloHF, - hcalCandidates = cms.VInputTag(cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering")), - hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hfcorr_106X.root", - resol = cms.PSet( - etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), - offset = cms.vdouble(-0.846, 0.696, 1.313, 1.044), - scale = cms.vdouble( 0.815, 0.164, 0.146, 0.192), - kind = cms.string('calo'), - ) -) -phase2_hgcalV11.toModify(pfClustersFromCombinedCaloHF, - hcalCandidates = cms.VInputTag(cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering")), - hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hfcorr_110X.root", - resol = cms.PSet( - etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), - offset = cms.vdouble(-1.125, 1.220, 1.514, 1.414), - scale = cms.vdouble( 0.868, 0.159, 0.148, 0.194), - kind = cms.string('calo'), - ) -) - -# Calorimeter part: hgcal -from L1Trigger.Phase2L1ParticleFlow.pfClustersFromHGC3DClusters_cfi import pfClustersFromHGC3DClusters - -l1ParticleFlow_calo_Task = cms.Task( - pfClustersFromL1EGClusters , - pfClustersFromCombinedCaloHCal , - pfClustersFromCombinedCaloHF , - pfClustersFromHGC3DClusters -) -l1ParticleFlow_calo = cms.Sequence(l1ParticleFlow_calo_Task) - - -# PF in the barrel -l1pfProducerBarrel = l1pfProducer.clone( - # inputs - tracks = cms.InputTag('pfTracksFromL1TracksBarrel'), - emClusters = [ cms.InputTag('pfClustersFromL1EGClusters') ], - hadClusters = [ cms.InputTag('pfClustersFromCombinedCaloHCal:calibrated') ], - # track-based PUPPI - puppiUsingBareTracks = True, - puppiDrMin = 0.07, - puppiPtMax = 50., - vtxAlgo = "external", - vtxFormat = cms.string("TkPrimaryVertex"), - vtxCollection = cms.InputTag("L1TkPrimaryVertex",""), - # puppi tuning - puAlgo = "LinearizedPuppi", - puppiEtaCuts = cms.vdouble( 1.6 ), # just one bin - puppiPtCuts = cms.vdouble( 1.0 ), - puppiPtCutsPhotons = cms.vdouble( 1.0 ), - puppiPtSlopes = cms.vdouble( 0.3 ), # coefficient for pT - puppiPtSlopesPhotons = cms.vdouble( 0.3 ), - puppiPtZeros = cms.vdouble( 4.0 ), # ballpark pT from PU - puppiPtZerosPhotons = cms.vdouble( 2.5 ), - puppiAlphaSlopes = cms.vdouble( 0.7 ), # coefficient for alpha - puppiAlphaSlopesPhotons = cms.vdouble( 0.7 ), - puppiAlphaZeros = cms.vdouble( 6.0 ), # ballpark alpha from PU - puppiAlphaZerosPhotons = cms.vdouble( 6.0 ), - puppiAlphaCrops = cms.vdouble( 4 ), # max. absolute value for alpha term - puppiAlphaCropsPhotons = cms.vdouble( 4 ), - puppiPriors = cms.vdouble( 5.0 ), - puppiPriorsPhotons = cms.vdouble( 1.0 ), - # regionalize - useRelativeRegionalCoordinates = cms.bool(False), - trackRegionMode = cms.string("atCalo"), - regions = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-1.5,1.5), - phiSlices = cms.uint32(1), - etaExtra = cms.double(0.3), - phiExtra = cms.double(0.0) - ), - ), -) -l1ParticleFlow_pf_barrel_Task = cms.Task( - pfTracksFromL1TracksBarrel , - l1pfProducerBarrel -) -l1ParticleFlow_pf_barrel = cms.Sequence(l1ParticleFlow_pf_barrel_Task) - - - -# PF in HGCal -pfTracksFromL1TracksHGCal = pfTracksFromL1Tracks.clone( - resolCalo = pfClustersFromHGC3DClusters.resol.clone(), -) -l1pfProducerHGCal = l1pfProducer.clone( - # algo - pfAlgo = "PFAlgo2HGC", - # inputs - tracks = cms.InputTag('pfTracksFromL1TracksHGCal'), - emClusters = [ ], # EM clusters are not used (only added to NTuple for calibration/monitoring) - hadClusters = [ cms.InputTag("pfClustersFromHGC3DClusters") ], - # track-based PUPPI - puppiDrMin = 0.04, - puppiPtMax = 50., - puppiUsingBareTracks = True, - vtxAlgo = "external", - vtxFormat = cms.string("TkPrimaryVertex"), - vtxCollection = cms.InputTag("L1TkPrimaryVertex",""), - # puppi tuning - puAlgo = "LinearizedPuppi", - puppiEtaCuts = cms.vdouble( 2.0, 2.4, 3.1 ), # two bins in the tracker (different pT), one outside - puppiPtCuts = cms.vdouble( 1.0, 2.0, 4.0 ), - puppiPtCutsPhotons = cms.vdouble( 1.0, 2.0, 4.0 ), - puppiPtSlopes = cms.vdouble( 0.3, 0.3, 0.3 ), # coefficient for pT - puppiPtSlopesPhotons = cms.vdouble( 0.4, 0.4, 0.4 ), #When e/g ID not applied, use: cms.vdouble( 0.3, 0.3, 0.3 ), - puppiPtZeros = cms.vdouble( 5.0, 7.0, 9.0 ), # ballpark pT from PU - puppiPtZerosPhotons = cms.vdouble( 3.0, 4.0, 5.0 ), - puppiAlphaSlopes = cms.vdouble( 1.5, 1.5, 2.2 ), - puppiAlphaSlopesPhotons = cms.vdouble( 1.5, 1.5, 2.2 ), - puppiAlphaZeros = cms.vdouble( 6.0, 6.0, 9.0 ), - puppiAlphaZerosPhotons = cms.vdouble( 6.0, 6.0, 9.0 ), - puppiAlphaCrops = cms.vdouble( 3 , 3 , 4 ), # max. absolute value for alpha term - puppiAlphaCropsPhotons = cms.vdouble( 3 , 3 , 4 ), - puppiPriors = cms.vdouble( 5.0, 5.0, 7.0 ), - puppiPriorsPhotons = cms.vdouble( 1.5, 1.5, 5.0 ), #When e/g ID not applied, use: cms.vdouble( 3.5, 3.5, 7.0 ), - # regionalize - useRelativeRegionalCoordinates = cms.bool(False), - trackRegionMode = cms.string("atCalo"), - regions = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-2.5,-1.5), - phiSlices = cms.uint32(1), - etaExtra = cms.double(0.3), - phiExtra = cms.double(0.0) - ), - cms.PSet( - etaBoundaries = cms.vdouble(1.5,2.5), - phiSlices = cms.uint32(1), - etaExtra = cms.double(0.3), - phiExtra = cms.double(0.0) - ), - ), -) -l1pfProducerHGCal.linking.trackCaloDR = 0.1 # more precise cluster positions -l1pfProducerHGCal.linking.ecalPriority = False -l1pfProducerHGCalNoTK = l1pfProducerHGCal.clone(regions = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-3,-2.5), - phiSlices = cms.uint32(1), - etaExtra = cms.double(0.3), - phiExtra = cms.double(0.0) - ), - cms.PSet( - etaBoundaries = cms.vdouble(2.5,3), - phiSlices = cms.uint32(1), - etaExtra = cms.double(0.3), - phiExtra = cms.double(0.0) - ), -)) - -l1ParticleFlow_pf_hgcal_Task = cms.Task( - pfTracksFromL1TracksHGCal , - l1pfProducerHGCal , - l1pfProducerHGCalNoTK -) -l1ParticleFlow_pf_hgcal = cms.Sequence(l1ParticleFlow_pf_hgcal_Task) - - - -# PF in HF -l1pfProducerHF = l1pfProducer.clone( - # inputs - tracks = cms.InputTag(''), # no tracks - emClusters = [ ], - hadClusters = [ cms.InputTag('pfClustersFromCombinedCaloHF:calibrated') ], - hadPtCut = 15, - # not really useful, but for consistency - puppiDrMin = 0.1, - puppiPtMax = 100., - vtxAlgo = "external", - vtxFormat = cms.string("TkPrimaryVertex"), - vtxCollection = cms.InputTag("L1TkPrimaryVertex",""), - # puppi tuning - puAlgo = "LinearizedPuppi", - puppiEtaCuts = cms.vdouble( 5.5 ), # one bin - puppiPtCuts = cms.vdouble( 10. ), - puppiPtCutsPhotons = cms.vdouble( 10. ), # not used (no photons in HF) - puppiPtSlopes = cms.vdouble( 0.25), - puppiPtSlopesPhotons = cms.vdouble( 0.25), # not used (no photons in HF) - puppiPtZeros = cms.vdouble( 14. ), # ballpark pT from PU - puppiPtZerosPhotons = cms.vdouble( 14. ), # not used (no photons in HF) - puppiAlphaSlopes = cms.vdouble( 0.6 ), - puppiAlphaSlopesPhotons = cms.vdouble( 0.6 ), # not used (no photons in HF) - puppiAlphaZeros = cms.vdouble( 9.0 ), - puppiAlphaZerosPhotons = cms.vdouble( 9.0 ), # not used (no photons in HF) - puppiAlphaCrops = cms.vdouble( 4 ), - puppiAlphaCropsPhotons = cms.vdouble( 4 ), # not used (no photons in HF) - puppiPriors = cms.vdouble( 6.0 ), - puppiPriorsPhotons = cms.vdouble( 6.0 ), # not used (no photons in HF) - # regionalize - useRelativeRegionalCoordinates = cms.bool(False), - trackRegionMode = cms.string("atCalo"), - regions = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-5.5,-3), - phiSlices = cms.uint32(1), - etaExtra = cms.double(0.0), - phiExtra = cms.double(0.0) - ), - cms.PSet( - etaBoundaries = cms.vdouble(3,5.5), - phiSlices = cms.uint32(1), - etaExtra = cms.double(0.0), - phiExtra = cms.double(0.0) - ), - ) -) -l1ParticleFlow_pf_hf_Task = cms.Task( - l1pfProducerHF -) -l1ParticleFlow_pf_hf = cms.Sequence(l1ParticleFlow_pf_hf_Task) - - -# PF in the TSA Region -l1pfProducerTSA = l1pfProducerBarrel.clone( - trackRegionMode = cms.string("atVertex"), - regions = cms.VPSet( - cms.PSet( - etaBoundaries = cms.vdouble(-3,3), - phiSlices = cms.uint32(18), - etaExtra = cms.double(0.0), - phiExtra = cms.double(0.0) - ), - ), -) -l1ParticleFlow_pf_tsa = cms.Sequence( - pfTracksFromL1TracksBarrel + - l1pfProducerTSA -) - -# Merging all outputs -l1pfCandidates = cms.EDProducer("L1TPFCandMultiMerger", - pfProducers = cms.VInputTag( - cms.InputTag("l1pfProducerBarrel"), - cms.InputTag("l1pfProducerHGCal"), - cms.InputTag("l1pfProducerHGCalNoTK"), - cms.InputTag("l1pfProducerHF") - ), - labelsToMerge = cms.vstring("Calo", "TK", "TKVtx", "PF", "Puppi"), -) - -l1ParticleFlow_proper = cms.Sequence( - l1ParticleFlow_calo + - l1ParticleFlow_pf_barrel + - l1ParticleFlow_pf_hgcal + - l1ParticleFlow_pf_hf + - l1pfCandidates -) - -l1ParticleFlow = cms.Sequence(l1ParticleFlow_proper) - -l1ParticleFlowTask = cms.Task( - l1ParticleFlow_calo_Task, - l1ParticleFlow_pf_barrel_Task, - l1ParticleFlow_pf_hgcal_Task, - l1ParticleFlow_pf_hf_Task, - cms.Task(l1pfCandidates) -) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py new file mode 100644 index 0000000000000..3d1621b655d56 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgoEmulator_cfi.py @@ -0,0 +1,59 @@ +import FWCore.ParameterSet.Config as cms + + +tkEgAlgoParameters = cms.PSet( + nTRACK=cms.uint32(50), # very large numbers for first test + nTRACK_EGIN=cms.uint32(50), # very large numbers for first test + nEMCALO_EGIN=cms.uint32(50), # very large numbers for first test + nEM_EGOUT=cms.uint32(50), # very large numbers for first test + doBremRecovery=cms.bool(False), + writeBeforeBremRecovery=cms.bool(True), + filterHwQuality=cms.bool(False), + caloHwQual=cms.int32(4), + doEndcapHwQual=cms.bool(False), + dEtaMaxBrem=cms.double(0.02), + dPhiMaxBrem=cms.double(0.1), + absEtaBoundaries=cms.vdouble(0.0, 0.9, 1.5), + dEtaValues=cms.vdouble(0.025, 0.015, 0.01), # last was 0.0075 in TDR + dPhiValues=cms.vdouble(0.07, 0.07, 0.07), + caloEtMin=cms.double(0.0), + trkQualityPtMin=cms.double(10.0), + writeEGSta=cms.bool(False), + tkIsoParametersTkEm=cms.PSet( + tkQualityPtMin=cms.double(2.), + dZ=cms.double(0.6), + dRMin=cms.double(0.07), + dRMax=cms.double(0.30), + tkQualityChi2Max=cms.double(100), + ), + tkIsoParametersTkEle=cms.PSet( + tkQualityPtMin=cms.double(2.), + dZ=cms.double(0.6), + dRMin=cms.double(0.03), + dRMax=cms.double(0.20), + tkQualityChi2Max=cms.double(1e10), + ), + pfIsoParametersTkEm=cms.PSet( + tkQualityPtMin=cms.double(1.), + dZ=cms.double(0.6), + dRMin=cms.double(0.07), + dRMax=cms.double(0.30), + tkQualityChi2Max=cms.double(100), + ), + pfIsoParametersTkEle=cms.PSet( + tkQualityPtMin=cms.double(1.), + dZ=cms.double(0.6), + dRMin=cms.double(0.03), + dRMax=cms.double(0.20), + tkQualityChi2Max=cms.double(1e10), + ), + doTkIso=cms.bool(True), + doPfIso=cms.bool(True), + hwIsoTypeTkEle=cms.uint32(0), + hwIsoTypeTkEm=cms.uint32(2) +) + +tkEgSorterParameters = cms.PSet( + nObjToSort=cms.uint32(6), + nObjSorted=cms.uint32(16), +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgo_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgo_cfi.py new file mode 100644 index 0000000000000..500121131a360 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1TkEgAlgo_cfi.py @@ -0,0 +1,47 @@ +import FWCore.ParameterSet.Config as cms + +tkEgConfig = cms.PSet( + debug=cms.untracked.int32(0), + doBremRecovery=cms.bool(True), + doTkIsolation=cms.bool(True), + filterHwQuality=cms.bool(True), + caloHwQual=cms.int32(4), + dEtaMaxBrem=cms.double(0.02), + dPhiMaxBrem=cms.double(0.1), + absEtaBoundaries=cms.vdouble(0.0, 0.9, 1.5), + dEtaValues=cms.vdouble(0.025, 0.015, 0.01), # last was 0.0075 in TDR + dPhiValues=cms.vdouble(0.07, 0.07, 0.07), + caloEtMin=cms.double(0.0), + trkQualityPtMin=cms.double(10.0), + trkQualityChi2=cms.double(1e10), + writeEgSta=cms.bool(True), + tkIsoParametersTkEm=cms.PSet( + tkQualityPtMin=cms.double(2.), + dZ=cms.double(0.6), + dRMin=cms.double(0.07), + dRMax=cms.double(0.30), + tkQualityChi2Max=cms.double(100), + ), + tkIsoParametersTkEle=cms.PSet( + tkQualityPtMin=cms.double(2.), + dZ=cms.double(0.6), + dRMin=cms.double(0.03), + dRMax=cms.double(0.20), + tkQualityChi2Max=cms.double(1e10), + ), + pfIsoParametersTkEm=cms.PSet( + tkQualityPtMin=cms.double(1.), + dZ=cms.double(0.6), + dRMin=cms.double(0.07), + dRMax=cms.double(0.30), + tkQualityChi2Max=cms.double(100), + ), + pfIsoParametersTkEle=cms.PSet( + tkQualityPtMin=cms.double(1.), + dZ=cms.double(0.6), + dRMin=cms.double(0.03), + dRMax=cms.double(0.20), + tkQualityChi2Max=cms.double(1e10), + ) + +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctJetFileWriter_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctJetFileWriter_cfi.py new file mode 100644 index 0000000000000..226bc381ac4d8 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctJetFileWriter_cfi.py @@ -0,0 +1,11 @@ +import FWCore.ParameterSet.Config as cms + +l1ctSeededConeJetFileWriter = cms.EDAnalyzer('L1CTJetFileWriter', + jets = cms.InputTag("scPFL1PuppiEmulator"), + nJets = cms.uint32(12), + nFramesPerBX = cms.uint32(9), # 360 MHz clock or 25 Gb/s link + TMUX = cms.uint32(6), + maxLinesPerFile = cms.uint32(1024), + outputFilename = cms.string("L1CTSCJetsPatterns"), + format = cms.string("EMP") +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py new file mode 100644 index 0000000000000..22a3f9b4ec8eb --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_cff.py @@ -0,0 +1,529 @@ +import FWCore.ParameterSet.Config as cms + +import math + +from L1Trigger.Phase2L1ParticleFlow.pfTracksFromL1Tracks_cfi import pfTracksFromL1Tracks +from L1Trigger.Phase2L1ParticleFlow.pfClustersFromL1EGClusters_cfi import pfClustersFromL1EGClusters +from L1Trigger.Phase2L1ParticleFlow.pfClustersFromCombinedCalo_cff import pfClustersFromCombinedCaloHCal, pfClustersFromCombinedCaloHF +from L1Trigger.Phase2L1ParticleFlow.pfClustersFromHGC3DClusters_cfi import pfClustersFromHGC3DClusters + +from L1Trigger.Phase2L1ParticleFlow.l1TkEgAlgoEmulator_cfi import tkEgAlgoParameters,tkEgSorterParameters + +muonInputConversionParameters = cms.PSet( + z0Scale = cms.double(1.875), + dxyScale = cms.double(3.85) +) + +l1ctLayer1Barrel = cms.EDProducer("L1TCorrelatorLayer1Producer", + tracks = cms.InputTag('pfTracksFromL1Tracks'), + muons = cms.InputTag('L1SAMuonsGmt','promptSAMuons'), + emClusters = cms.VInputTag(cms.InputTag('pfClustersFromL1EGClusters')), + hadClusters = cms.VInputTag(cms.InputTag('pfClustersFromCombinedCaloHCal:calibrated')), + vtxCollection = cms.InputTag("L1VertexFinderEmulator","l1verticesEmulation"), + vtxCollectionEmulation = cms.bool(True), + emPtCut = cms.double(0.5), + hadPtCut = cms.double(1.0), + trkPtCut = cms.double(2.0), + trackInputConversionAlgo = cms.string("Emulator"), + trackInputConversionParameters = cms.PSet( + region = cms.string("barrel"), + trackWordEncoding = cms.string("biased"), + bitwiseAccurate = cms.bool(True), + ptLUTBits = cms.uint32(11), + etaLUTBits = cms.uint32(10), + etaPreOffs = cms.int32(0), + etaShift = cms.uint32(15-10), + etaPostOffs = cms.int32(0), + etaSigned = cms.bool(True), + phiBits = cms.uint32(10), + z0Bits = cms.uint32(12), + dEtaBarrelBits = cms.uint32(8), + dEtaBarrelZ0PreShift = cms.uint32(2), + dEtaBarrelZ0PostShift = cms.uint32(2), + dEtaBarrelFloatOffs = cms.double(0.0), + dPhiBarrelBits = cms.uint32(4), + dPhiBarrelRInvPreShift = cms.uint32(4), + dPhiBarrelRInvPostShift = cms.uint32(4), + dPhiBarrelFloatOffs = cms.double(0.0) + ), + muonInputConversionAlgo = cms.string("Emulator"), + muonInputConversionParameters = muonInputConversionParameters.clone(), + regionizerAlgo = cms.string("Ideal"), + pfAlgo = cms.string("PFAlgo3"), + puAlgo = cms.string("LinearizedPuppi"), + nVtx = cms.int32(1), + regionizerAlgoParameters = cms.PSet( + useAlsoVtxCoords = cms.bool(True), + ), + pfAlgoParameters = cms.PSet( + nTrack = cms.uint32(25), + nCalo = cms.uint32(18), + nMu = cms.uint32(2), + nSelCalo = cms.uint32(18), + nEmCalo = cms.uint32(12), + nPhoton = cms.uint32(12), + nAllNeutral = cms.uint32(25), + trackMuDR = cms.double(0.2), # accounts for poor resolution of standalone, and missing propagations + trackEmDR = cms.double(0.04), # 1 Ecal crystal size is 0.02, and ~2 cm in HGCal is ~0.007 + emCaloDR = cms.double(0.10), # 1 Hcal tower size is ~0.09 + trackCaloDR = cms.double(0.15), + maxInvisiblePt = cms.double(10.0), # max allowed pt of a track with no calo energy + tightTrackMaxInvisiblePt = cms.double(20), + caloResolution = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 2.909, 2.864, 0.294), + scale = cms.vdouble( 0.119, 0.127, 0.442), + ), + debug = cms.untracked.bool(False) + ), + puAlgoParameters = cms.PSet( + nTrack = cms.uint32(22), + nIn = cms.uint32(25), + nOut = cms.uint32(25), + nVtx = cms.uint32(1), + nFinalSort = cms.uint32(18), + finalSortAlgo = cms.string("Insertion"), + dZ = cms.double(0.5), + dr = cms.double(0.3), + drMin = cms.double(0.07), + ptMax = cms.double(50.), + absEtaCuts = cms.vdouble( ), # just one bin, so no edge needd + ptCut = cms.vdouble( 1.0 ), + ptSlopes = cms.vdouble( 0.3 ), # coefficient for pT + ptSlopesPhoton = cms.vdouble( 0.3 ), + ptZeros = cms.vdouble( 4.0 ), # ballpark pT from PU + ptZerosPhoton = cms.vdouble( 2.5 ), + alphaSlopes = cms.vdouble( 0.7 ), # coefficient for alpha + alphaZeros = cms.vdouble( 6.0 ), # ballpark alpha from PU + alphaCrop = cms.vdouble( 4 ), # max. absolute value for alpha term + priors = cms.vdouble( 5.0 ), + priorsPhoton = cms.vdouble( 1.0 ), + debug = cms.untracked.bool(False) + ), + tkEgAlgoParameters=tkEgAlgoParameters.clone( + nTRACK = 25, + nTRACK_EGIN = 13, + nEMCALO_EGIN = 10, + nEM_EGOUT = 10, + ), + tkEgSorterParameters=tkEgSorterParameters.clone( + nObjToSort = 10 + ), + caloSectors = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-1.5, 1.5), + phiSlices = cms.uint32(3), + phiZero = cms.double(0), + ) + ), + regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5), + phiSlices = cms.uint32(9), + etaExtra = cms.double(0.25), + phiExtra = cms.double(0.25), + ), + ), + boards=cms.VPSet( + cms.PSet( + regions=cms.vuint32(*[0+9*ie+i for ie in range(6) for i in range(3)])), # phi splitting + # regions=cms.vuint32(range(0, 18))), # eta splitting + cms.PSet( + regions=cms.vuint32(*[3+9*ie+i for ie in range(6) for i in range(3)])), # phi splitting + # regions=cms.vuint32(range(18, 36))), # eta splitting + cms.PSet( + regions=cms.vuint32(*[6+9*ie+i for ie in range(6) for i in range(3)])), # phi splitting + # regions=cms.vuint32(range(36, 54))), # eta splitting + ) +) + +_hgcalSectors = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-3.0, -1.5), + phiSlices = cms.uint32(3), + phiZero = cms.double(math.pi/2) # The edge of the 0th HGCal sectors is at 30 deg, the center at 30+120/2=90 = pi/2 + ), + cms.PSet( + etaBoundaries = cms.vdouble(+1.5, +3.0), + phiSlices = cms.uint32(3), + phiZero = cms.double(math.pi/2) # As above + ) + +) + +l1ctLayer1HGCal = cms.EDProducer("L1TCorrelatorLayer1Producer", + tracks = cms.InputTag('pfTracksFromL1Tracks'), + muons = cms.InputTag('L1SAMuonsGmt','promptSAMuons'), + emClusters = cms.VInputTag(cms.InputTag('pfClustersFromHGC3DClusters:egamma')), # used only for E/gamma + hadClusters = cms.VInputTag(cms.InputTag('pfClustersFromHGC3DClusters')), + vtxCollection = cms.InputTag("L1VertexFinderEmulator","l1verticesEmulation"), + vtxCollectionEmulation = cms.bool(True), + nVtx = cms.int32(1), + emPtCut = cms.double(0.5), + hadPtCut = cms.double(1.0), + trkPtCut = cms.double(2.0), + trackInputConversionAlgo = cms.string("Emulator"), + trackInputConversionParameters = cms.PSet( + region = cms.string("endcap"), + trackWordEncoding = cms.string("biased"), + bitwiseAccurate = cms.bool(True), + ptLUTBits = cms.uint32(11), + etaLUTBits = cms.uint32(11), + etaPreOffs = cms.int32(0), + etaShift = cms.uint32(15-11), + etaPostOffs = cms.int32(150), + etaSigned = cms.bool(True), + phiBits = cms.uint32(10), + z0Bits = cms.uint32(12), + dEtaHGCalBits = cms.uint32(10), + dEtaHGCalZ0PreShift = cms.uint32(2), + dEtaHGCalRInvPreShift = cms.uint32(6), + dEtaHGCalLUTBits = cms.uint32(10), + dEtaHGCalLUTShift = cms.uint32(2), + dEtaHGCalFloatOffs = cms.double(0.0), + dPhiHGCalBits = cms.uint32(4), + dPhiHGCalZ0PreShift = cms.uint32(4), + dPhiHGCalZ0PostShift = cms.uint32(6), + dPhiHGCalRInvShift = cms.uint32(4), + dPhiHGCalTanlInvShift = cms.uint32(22), + dPhiHGCalTanlLUTBits = cms.uint32(10), + dPhiHGCalFloatOffs = cms.double(0.0) + ), + muonInputConversionAlgo = cms.string("Emulator"), + muonInputConversionParameters = muonInputConversionParameters.clone(), + regionizerAlgo = cms.string("Multififo"), + regionizerAlgoParameters = cms.PSet( + useAlsoVtxCoords = cms.bool(True), + nEndcaps = cms.uint32(2), + nClocks = cms.uint32(54), + nTrack = cms.uint32(30), + nCalo = cms.uint32(20), + nEmCalo = cms.uint32(10), + nMu = cms.uint32(4), + egInterceptMode = cms.PSet( + afterFifo = cms.bool(True), + emIDMask = cms.uint32(0x1E), + nHADCALO_IN = cms.uint32(20), + nEMCALO_OUT = cms.uint32(10), + ) + ), + pfAlgo = cms.string("PFAlgo2HGC"), + pfAlgoParameters = cms.PSet( + nTrack = cms.uint32(30), + nCalo = cms.uint32(20), + nMu = cms.uint32(4), + nSelCalo = cms.uint32(20), + trackMuDR = cms.double(0.2), # accounts for poor resolution of standalone, and missing propagations + trackCaloDR = cms.double(0.1), + maxInvisiblePt = cms.double(10.0), # max allowed pt of a track with no calo energy + tightTrackMaxInvisiblePt = cms.double(20), + caloResolution = cms.PSet( + etaBins = cms.vdouble( 1.700, 1.900, 2.200, 2.500, 2.800, 2.900), + offset = cms.vdouble( 1.793, 1.827, 2.363, 2.538, 2.812, 2.642), + scale = cms.vdouble( 0.138, 0.137, 0.124, 0.115, 0.106, 0.121), + ), + debug = cms.untracked.bool(False) + ), + puAlgo = cms.string("LinearizedPuppi"), + puAlgoParameters = cms.PSet( + nTrack = cms.uint32(30), + nIn = cms.uint32(20), + nOut = cms.uint32(20), + nVtx = cms.uint32(1), + nFinalSort = cms.uint32(18), + finalSortAlgo = cms.string("FoldedHybrid"), + dZ = cms.double(1.33), + dr = cms.double(0.3), + drMin = cms.double(0.04), + ptMax = cms.double(50.), + absEtaCuts = cms.vdouble( 2.0 ), # two bins in the tracker (different eta); give only the one boundary between them + ptCut = cms.vdouble( 1.0, 2.0 ), + ptSlopes = cms.vdouble( 0.3, 0.3 ), # coefficient for pT + ptSlopesPhoton = cms.vdouble( 0.4, 0.4 ), #When e/g ID not applied, use: cms.vdouble( 0.3, 0.3, 0.3 ), + ptZeros = cms.vdouble( 5.0, 7.0 ), # ballpark pT from PU + ptZerosPhoton = cms.vdouble( 3.0, 4.0 ), + alphaSlopes = cms.vdouble( 1.5, 1.5 ), + alphaZeros = cms.vdouble( 6.0, 6.0 ), + alphaCrop = cms.vdouble( 3 , 3 ), # max. absolute value for alpha term + priors = cms.vdouble( 5.0, 5.0 ), + priorsPhoton = cms.vdouble( 1.5, 1.5 ), #When e/g ID not applied, use: cms.vdouble( 3.5, 3.5, 7.0 ), + debug = cms.untracked.bool(False) + ), + tkEgAlgoParameters=tkEgAlgoParameters.clone( + nTRACK = 30, + nTRACK_EGIN = 10, + nEMCALO_EGIN = 10, + nEM_EGOUT = 5, + doBremRecovery=True, + doEndcapHwQual=True, + writeBeforeBremRecovery=False, + writeEGSta=True), + tkEgSorterParameters=tkEgSorterParameters.clone( + nObjToSort = 5 + ), + caloSectors = _hgcalSectors, + regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-2.5, -1.5), + phiSlices = cms.uint32(9), + etaExtra = cms.double(0.25), + phiExtra = cms.double(0.25), + ), + cms.PSet( + etaBoundaries = cms.vdouble(+1.5, +2.5), + phiSlices = cms.uint32(9), + etaExtra = cms.double(0.25), + phiExtra = cms.double(0.25), + ) + + ), + boards=cms.VPSet( + cms.PSet( + regions=cms.vuint32(range(0, 9))), + cms.PSet( + regions=cms.vuint32(range(9, 18))), + ), + writeRawHgcalCluster = cms.untracked.bool(True) +) + + +l1ctLayer1HGCalNoTK = cms.EDProducer("L1TCorrelatorLayer1Producer", + tracks = cms.InputTag(''), + muons = cms.InputTag('L1SAMuonsGmt','promptSAMuons'), + emClusters = cms.VInputTag(cms.InputTag('pfClustersFromHGC3DClusters:egamma')), # used only for E/gamma + hadClusters = cms.VInputTag(cms.InputTag('pfClustersFromHGC3DClusters')), + vtxCollection = cms.InputTag("L1VertexFinderEmulator","l1verticesEmulation"), + vtxCollectionEmulation = cms.bool(True), + nVtx = cms.int32(1), + emPtCut = cms.double(0.5), + hadPtCut = cms.double(1.0), + trkPtCut = cms.double(2.0), + muonInputConversionAlgo = cms.string("Emulator"), + muonInputConversionParameters = muonInputConversionParameters.clone(), + regionizerAlgo = cms.string("Ideal"), + pfAlgo = cms.string("PFAlgoDummy"), + puAlgo = cms.string("LinearizedPuppi"), + regionizerAlgoParameters = cms.PSet( + useAlsoVtxCoords = cms.bool(True), + ), + pfAlgoParameters = cms.PSet( + nCalo = cms.uint32(12), + nMu = cms.uint32(4), # unused + debug = cms.untracked.bool(False) + ), + puAlgoParameters = cms.PSet( + nTrack = cms.uint32(0), # unused + nIn = cms.uint32(12), + nOut = cms.uint32(12), + nFinalSort = cms.uint32(12), # to be tuned + finalSortAlgo = cms.string("Hybrid"), + nVtx = cms.uint32(1), + dZ = cms.double(1.33), + dr = cms.double(0.3), + drMin = cms.double(0.04), + ptMax = cms.double(50.), + absEtaCuts = cms.vdouble( ), # just one bin + ptCut = cms.vdouble( 4.0 ), + ptSlopes = cms.vdouble( 0.3 ), # coefficient for pT + ptSlopesPhoton = cms.vdouble( 0.4 ), #When e/g ID not applied, use: cms.vdouble( 0.3, 0.3, 0.3 ), + ptZeros = cms.vdouble( 9.0 ), # ballpark pT from PU + ptZerosPhoton = cms.vdouble( 5.0 ), + alphaSlopes = cms.vdouble( 2.2 ), + alphaZeros = cms.vdouble( 9.0 ), + alphaCrop = cms.vdouble( 4 ), # max. absolute value for alpha term + priors = cms.vdouble( 7.0 ), + priorsPhoton = cms.vdouble( 5.0 ), #When e/g ID not applied, use: cms.vdouble( 3.5, 3.5, 7.0 ), + debug = cms.untracked.bool(False) + ), + tkEgAlgoParameters=tkEgAlgoParameters.clone( + nTRACK = 30, + nTRACK_EGIN = 10, + nEMCALO_EGIN = 10, + nEM_EGOUT = 5, + doBremRecovery=True, + doEndcapHwQual=True, + writeBeforeBremRecovery=False, + writeEGSta=True), + tkEgSorterParameters=tkEgSorterParameters.clone( + nObjToSort=5 + ), + caloSectors = _hgcalSectors, + regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-3.0, -2.5), + phiSlices = cms.uint32(9), + etaExtra = cms.double(0.25), + phiExtra = cms.double(0.25), + ), + cms.PSet( + etaBoundaries = cms.vdouble(+2.5, +3.0), + phiSlices = cms.uint32(9), + etaExtra = cms.double(0.25), + phiExtra = cms.double(0.25), + ) + + ), + boards=cms.VPSet( + cms.PSet( + regions=cms.vuint32(range(0,18))), + ), + writeRawHgcalCluster = cms.untracked.bool(True) +) + +l1ctLayer1HF = cms.EDProducer("L1TCorrelatorLayer1Producer", + tracks = cms.InputTag(''), + muons = cms.InputTag('L1SAMuonsGmt','promptSAMuons'), + useStandaloneMuons = cms.bool(False), + useTrackerMuons = cms.bool(False), + emClusters = cms.VInputTag(), + hadClusters = cms.VInputTag(cms.InputTag('pfClustersFromCombinedCaloHF:calibrated')), + vtxCollection = cms.InputTag("L1VertexFinderEmulator","l1verticesEmulation"), + vtxCollectionEmulation = cms.bool(True), + nVtx = cms.int32(1), + emPtCut = cms.double(0.5), + hadPtCut = cms.double(15.0), + trkPtCut = cms.double(2.0), + muonInputConversionAlgo = cms.string("Ideal"), + muonInputConversionParameters = muonInputConversionParameters.clone(), + regionizerAlgo = cms.string("Ideal"), + pfAlgo = cms.string("PFAlgoDummy"), + puAlgo = cms.string("LinearizedPuppi"), + regionizerAlgoParameters = cms.PSet( + useAlsoVtxCoords = cms.bool(True), + ), + pfAlgoParameters = cms.PSet( + nCalo = cms.uint32(18), + nMu = cms.uint32(4), # unused + debug = cms.untracked.bool(False) + ), + puAlgoParameters = cms.PSet( + nTrack = cms.uint32(0), # unused + nIn = cms.uint32(18), + nOut = cms.uint32(18), + nVtx = cms.uint32(1), + nFinalSort = cms.uint32(10), # to be tuned + finalSortAlgo = cms.string("Insertion"), + dZ = cms.double(1.33), + dr = cms.double(0.3), + drMin = cms.double(0.1), + ptMax = cms.double(100.), + absEtaCuts = cms.vdouble( ), # just one bin + ptCut = cms.vdouble( 10.0 ), + ptSlopes = cms.vdouble( 0.25 ), + ptSlopesPhoton = cms.vdouble( 0.25 ), + ptZeros = cms.vdouble( 14.0 ), + ptZerosPhoton = cms.vdouble( 14.0 ), + alphaSlopes = cms.vdouble( 0.6 ), + alphaZeros = cms.vdouble( 9.0 ), + alphaCrop = cms.vdouble( 4 ), + priors = cms.vdouble( 6.0 ), + priorsPhoton = cms.vdouble( 6.0 ), + debug = cms.untracked.bool(False) + ), + tkEgAlgoParameters=tkEgAlgoParameters.clone( + nTRACK = 5, # to be defined + nTRACK_EGIN = 5, # to be defined + nEMCALO_EGIN = 5, # to be defined + nEM_EGOUT = 5, # to be defined + doBremRecovery=True, + writeEGSta=True), + tkEgSorterParameters=tkEgSorterParameters.clone(), + caloSectors = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-5.5, -3.0), + phiSlices = cms.uint32(9), + phiZero = cms.double(0), + ), + cms.PSet( + etaBoundaries = cms.vdouble(+3.0, +5.5), + phiSlices = cms.uint32(9), + phiZero = cms.double(0), + ) + ), + regions = cms.VPSet( + cms.PSet( + etaBoundaries = cms.vdouble(-5.5, -3.0), + phiSlices = cms.uint32(9), + etaExtra = cms.double(0.25), + phiExtra = cms.double(0.25), + ), + cms.PSet( + etaBoundaries = cms.vdouble(+3.0, +5.5), + phiSlices = cms.uint32(9), + etaExtra = cms.double(0.25), + phiExtra = cms.double(0.25), + ) + ), + boards=cms.VPSet(), +) + + +l1ctLayer1 = cms.EDProducer("L1TPFCandMultiMerger", + pfProducers = cms.VInputTag( + cms.InputTag("l1ctLayer1Barrel"), + cms.InputTag("l1ctLayer1HGCal"), + cms.InputTag("l1ctLayer1HGCalNoTK"), + cms.InputTag("l1ctLayer1HF") + ), + labelsToMerge = cms.vstring("PF", "Puppi", "Calo", "TK"), + regionalLabelsToMerge = cms.vstring("Puppi"), +) + +l1ctLayer1EG = cms.EDProducer( + "L1TEGMultiMerger", + tkElectrons=cms.VPSet( + cms.PSet( + instance=cms.string("L1TkEleEE"), + pfProducers=cms.VInputTag( + cms.InputTag("l1ctLayer1HGCal", 'L1TkEle') + ) + ), + cms.PSet( + instance=cms.string("L1TkEleEB"), + pfProducers=cms.VInputTag( + cms.InputTag("l1ctLayer1Barrel", 'L1TkEle') + ) + ) + ), + tkEms=cms.VPSet( + cms.PSet( + instance=cms.string("L1TkEmEE"), + pfProducers=cms.VInputTag( + cms.InputTag("l1ctLayer1HGCal", 'L1TkEm'), + cms.InputTag("l1ctLayer1HGCalNoTK", 'L1TkEm') + ) + ), + cms.PSet( + instance=cms.string("L1TkEmEB"), + pfProducers=cms.VInputTag( + cms.InputTag("l1ctLayer1Barrel", 'L1TkEm') + ) + ) + ), + tkEgs=cms.VPSet( + cms.PSet( + instance=cms.string("L1EgEE"), + pfProducers=cms.VInputTag( + cms.InputTag("l1ctLayer1HGCal", 'L1Eg'), + cms.InputTag("l1ctLayer1HGCalNoTK", 'L1Eg') + ) + ) + ) +) + +l1ctLayer1TaskInputsTask = cms.Task( + pfClustersFromL1EGClusters, + pfClustersFromCombinedCaloHCal, + pfClustersFromCombinedCaloHF, + pfClustersFromHGC3DClusters, + pfTracksFromL1Tracks +) + +l1ctLayer1Task = cms.Task( + l1ctLayer1Barrel, + l1ctLayer1HGCal, + l1ctLayer1HGCalNoTK, + l1ctLayer1HF, + l1ctLayer1, + l1ctLayer1EG +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py new file mode 100644 index 0000000000000..6a856e48db502 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer1_patternWriters_cff.py @@ -0,0 +1,165 @@ +import FWCore.ParameterSet.Config as cms + +eventsPerFile_ = 12 +gttLatency_ = 156+120 +gttNumberOfPVs_ = 10 + +##################################################################################################################### +## Barrel configurations: 54 regions, 6 puppi output links, only write out the layer 1 outputs for now +barrelWriterOutputOnly_ = cms.PSet( + partition = cms.string("Barrel"), + outputLinksPuppi = cms.vuint32(*range(6)), + outputLinkEgamma = cms.int32(6), + nEgammaObjectsOut = cms.uint32(16), + nOutputFramesPerBX = cms.uint32(9), + fileFormat = cms.string("EMP"), + maxLinesPerOutputFile = cms.uint32(1024), + eventsPerFile = cms.uint32(eventsPerFile_), +) +## Barrel (54) split in 3 eta slices +barrelWriterOutputOnlyEtaConfigs = [ + barrelWriterOutputOnly_.clone( + outputRegions = cms.vuint32(*[18*ie+i for i in range(18)]), + outputFileName = cms.string("l1BarrelEta%d-outputs-ideal" % (ie+1)), + outputBoard = cms.int32(-1), ## can't output e/gamma in eta split regions + outputLinkEgamma = cms.int32(-1), ## since the boards are defined in phi regions + ) for ie in range(3) +] +## Barrel (54) split in 3 phi slices +barrelWriterOutputOnlyPhiConfigs = [ + barrelWriterOutputOnly_.clone( + outputRegions = cms.vuint32(*[3*ip+9*ie+i for ie in range(6) for i in range(3) ]), + outputBoard = cms.int32(ip), + outputFileName = cms.string("l1BarrelPhi%d-outputs-ideal" % (ip+1)) + ) for ip in range(3) +] +## Barrel9 (27) split in phi eta slices +barrel9WriterOutputOnlyPhiConfigs = [ + barrelWriterOutputOnly_.clone( + outputRegions = cms.vuint32(*[3*ip+9*ie+i for ie in range(3) for i in range(3) ]), + outputBoard = cms.int32(ip), + outputFileName = cms.string("l1Barrel9Phi%d-outputs-ideal" % (ip+1)) + ) for ip in range(3) +] + +barrelWriterConfigs = barrelWriterOutputOnlyPhiConfigs # + barrelWriterOutputOnlyEtaConfigs +barrel9WriterConfigs = [] #barrel9WriterOutputOnlyPhiConfigs + + +##################################################################################################################### +## HGcal configuration: write out both inputs and outputs +hgcalWriterConfig_ = cms.PSet( + partition = cms.string("HGCal"), + outputRegions = cms.vuint32(*[i+9 for i in range(9)]), + outputBoard = cms.int32(1), + nEgammaObjectsOut = cms.uint32(16), + nInputFramesPerBX = cms.uint32(9), + nOutputFramesPerBX = cms.uint32(9), + fileFormat = cms.string("EMP"), + maxLinesPerInputFile = cms.uint32(1024), + maxLinesPerOutputFile = cms.uint32(1024), + eventsPerFile = cms.uint32(eventsPerFile_), + tfTimeSlices = cms.VPSet(*[cms.PSet(tfSectors = cms.VPSet()) for i in range(3)]), + hgcTimeSlices = cms.VPSet(*[cms.PSet(hgcSectors = cms.VPSet()) for i in range(3)]), + gmtTimeSlices = cms.VPSet(cms.PSet(),cms.PSet(),cms.PSet()), + gmtNumberOfMuons = cms.uint32(12), + gttLink = cms.int32(-1), + gttLatency = cms.uint32(gttLatency_), + gttNumberOfPVs = cms.uint32(gttNumberOfPVs_) +) +## Ideal configuration: 27 input links from tf, 36 from hgc, 3 from gmt, 1 from gtt, in this order; output 3 puppi + 1 e/gamma +hgcalPosIdealWriterConfig = hgcalWriterConfig_.clone() +for t in range(3): + hgcalPosIdealWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # neg + hgcalPosIdealWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t)) for i in range(9) ] # pos + hgcalPosIdealWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # neg + hgcalPosIdealWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[27+12*i+4*t+j for j in range(4)])) for i in range(3) ] # pos + hgcalPosIdealWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(27+36+t) +hgcalPosIdealWriterConfig.gttLink = 27+36+3 +hgcalPosIdealWriterConfig.outputLinksPuppi = cms.vuint32(0,1,2) +hgcalPosIdealWriterConfig.outputLinkEgamma = cms.int32(5) +hgcalPosIdealWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-ideal") +hgcalPosIdealWriterConfig.outputFileName = cms.string("l1HGCalPos-outputs-ideal") +hgcalNegIdealWriterConfig = hgcalPosIdealWriterConfig.clone( + inputFileName = "", + outputFileName = "l1HGCalNeg-outputs-ideal", + outputRegions = [i for i in range(9)], + outputBoard = 0, +) +## Current configuration for VU9P at B904 for layer1 - layer2 tests with puppi and e/gamma outputs on links 56-59 +hgcalPosVU9PB904egWriterConfig = hgcalWriterConfig_.clone() +for t in range(3): + hgcalPosVU9PB904egWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # neg + hgcalPosVU9PB904egWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*2)) for i in range(4) ] # pos, left quads + hgcalPosVU9PB904egWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*25)) for i in range(5) ] # pos, right quads + hgcalPosVU9PB904egWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # neg + hgcalPosVU9PB904egWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[4*11+12*i+4*t+j for j in range(4)])) for i in range(3) ] # pos + hgcalPosVU9PB904egWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4+t) +hgcalPosVU9PB904egWriterConfig.gttLink = 4+3 +hgcalPosVU9PB904egWriterConfig.outputLinksPuppi = cms.vuint32(56,57,58) +hgcalPosVU9PB904egWriterConfig.outputLinkEgamma = cms.int32(59) +hgcalPosVU9PB904egWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-vu9p_B904eg") +hgcalPosVU9PB904egWriterConfig.outputFileName = cms.string("l1HGCalPos-outputs-vu9p_B904eg") +## Current configuration for VU13P +hgcalPosVU13PWriterConfig = hgcalWriterConfig_.clone() +for t in range(3): + hgcalPosVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(-1)) for i in range(9) ] # neg + hgcalPosVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*0)) for i in range(5) ] # pos, left quads + hgcalPosVU13PWriterConfig.tfTimeSlices[t].tfSectors += [ cms.PSet(tfLink = cms.int32(3*i+t+4*28)) for i in range(4) ] # pos, right quads + hgcalPosVU13PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(-1,-1,-1,-1)) for i in range(3) ] # neg + for isec,q0 in (0,12),(1,17),(2,20): + hgcalPosVU13PWriterConfig.hgcTimeSlices[t].hgcSectors += [ cms.PSet(hgcLinks = cms.vint32(*[4*q0+4*t+j for j in range(4)])) ] # pos + hgcalPosVU13PWriterConfig.gmtTimeSlices[t].gmtLink = cms.int32(4*27+t) +hgcalPosVU13PWriterConfig.gttLink = 4*27+3 +hgcalPosVU13PWriterConfig.outputLinksPuppi = cms.vuint32(0,1,2) +hgcalPosVU13PWriterConfig.outputLinkEgamma = cms.int32(3) +hgcalPosVU13PWriterConfig.inputFileName = cms.string("l1HGCalPos-inputs-vu13p") +hgcalPosVU13PWriterConfig.outputFileName = cms.string("l1HGCalPos-outputs-vu13p") +## Enable both + +## Enable both + +hgcalWriterConfigs = [ + hgcalPosIdealWriterConfig, + hgcalNegIdealWriterConfig, + hgcalPosVU9PB904egWriterConfig, + hgcalPosVU13PWriterConfig +] + +##################################################################################################################### +## Forward HGCal configuration: only outputs for now, 18 regions, 12 candidates x region, 4 output fibers +hgcalNoTKWriterOutputOnlyConfig = cms.PSet( + partition = cms.string("HGCalNoTk"), + outputRegions = cms.vuint32(*range(18)), + nOutputFramesPerBX = cms.uint32(9), + fileFormat = cms.string("EMP"), + maxLinesPerOutputFile = cms.uint32(1024), + eventsPerFile = cms.uint32(eventsPerFile_), + outputLinksPuppi = cms.vuint32(0,1,2,4), + outputFileName = cms.string("l1HGCalNoTk-outputs-ideal") +) + +hgcalNoTKWriterConfigs = [ + hgcalNoTKWriterOutputOnlyConfig +] + +##################################################################################################################### +## HF configuration: not enabled for the moment +##################################################################################################################### +## HF configuration not realistic, 3 links per endcap, write out the layer 1 outputs for now +hfWriterOutputOnly_ = cms.PSet( + partition = cms.string("HF"), + outputLinksPuppi = cms.vuint32(*range(3)), + nOutputFramesPerBX = cms.uint32(9), + fileFormat = cms.string("EMP"), + maxLinesPerOutputFile = cms.uint32(1024), + eventsPerFile = cms.uint32(eventsPerFile_), +) +hfWriterConfigs = [ + hfWriterOutputOnly_.clone( + outputRegions = cms.vuint32(*[9*ie+i for i in range(9)]), + outputFileName = cms.string("l1HF%s-outputs-ideal" % ("Pos" if ie else "Neg")), + ) for ie in range(2) +] + + diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py new file mode 100644 index 0000000000000..af063d32cce49 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1ctLayer2EG_cff.py @@ -0,0 +1,137 @@ +import FWCore.ParameterSet.Config as cms + +l1ctLayer2EG = cms.EDProducer( + "L1TCtL2EgProducer", + tkElectrons=cms.VPSet( + cms.PSet( + pfProducer=cms.InputTag("l1ctLayer1HGCal", 'L1TkElePerBoard'), + channels=cms.vint32(3, 4) + ), + cms.PSet( + pfProducer=cms.InputTag("l1ctLayer1Barrel", 'L1TkElePerBoard'), + channels=cms.vint32(0, 1, 2) + ), + ), + tkEms=cms.VPSet( + cms.PSet( + pfProducer=cms.InputTag("l1ctLayer1HGCal", 'L1TkEmPerBoard'), + channels=cms.vint32(3, 4) + ), + cms.PSet( + pfProducer=cms.InputTag("l1ctLayer1HGCalNoTK", 'L1TkEmPerBoard'), + channels=cms.vint32(-1) + ), + cms.PSet( + pfProducer=cms.InputTag("l1ctLayer1Barrel", 'L1TkEmPerBoard'), + channels=cms.vint32(0, 1, 2) + ), + ), + tkEgs=cms.VPSet( + cms.PSet( + pfProducer=cms.InputTag("l1ctLayer1HGCal", 'L1Eg'), + channels=cms.vint32(-1) + ), + cms.PSet( + pfProducer=cms.InputTag("l1ctLayer1HGCalNoTK", 'L1Eg'), + channels=cms.vint32(-1) + ), + ), + egStaInstanceLabel=cms.string("L1CtEgEE"), + tkEmInstanceLabel=cms.string("L1CtTkEm"), + tkEleInstanceLabel=cms.string("L1CtTkElectron"), + sorter=cms.PSet( + nBOARDS=cms.uint32(5), + nEGPerBoard=cms.uint32(16), + nEGOut=cms.uint32(12), + debug=cms.untracked.uint32(0), + ), + encoder=cms.PSet( + nTKELE_OUT=cms.uint32(12), + nTKPHO_OUT=cms.uint32(12), + ), + writeInPattern=cms.bool(False), + writeOutPattern=cms.bool(False), + inPatternFile=cms.PSet( + nFramesPerBX=cms.uint32(9), # 360 MHz clock or 25 Gb/s link + format=cms.string("EMP"), + outputFilename=cms.string("L1TCTL2EG_InPattern"), + TMUX=cms.uint32(6), + maxLinesPerFile=cms.uint32(1024), + channels=cms.VPSet( + cms.PSet( + TMUX=cms.uint32(6), + nWords=cms.uint32(48), # = 16*2words ele + 16words photons + interface=cms.string("eglayer1"), + id=cms.uint32(0), + channels=cms.vuint32(0) + ), + cms.PSet( + TMUX=cms.uint32(6), + nWords=cms.uint32(48), + interface=cms.string("eglayer1"), + id=cms.uint32(1), + channels=cms.vuint32(1) + ), + cms.PSet( + TMUX=cms.uint32(6), + nWords=cms.uint32(48), + interface=cms.string("eglayer1"), + id=cms.uint32(2), + channels=cms.vuint32(2) + ), + cms.PSet( + TMUX=cms.uint32(6), + nWords=cms.uint32(48), + interface=cms.string("eglayer1"), + id=cms.uint32(3), + channels=cms.vuint32(3) + ), + cms.PSet( + TMUX=cms.uint32(6), + nWords=cms.uint32(48), + interface=cms.string("eglayer1"), + id=cms.uint32(4), + channels=cms.vuint32(4) + ), + + ) + ), + outPatternFile=cms.PSet( + nFramesPerBX=cms.uint32(9), # 360 MHz clock or 25 Gb/s link + format=cms.string("EMP"), + outputFilename=cms.string("L1TCTL2EG_OuPattern"), + TMUX=cms.uint32(6), + maxLinesPerFile=cms.uint32(1024), + channels=cms.VPSet( + cms.PSet( + TMUX=cms.uint32(6), + nWords=cms.uint32(36), # 36 = 12*3/2words ele + 12*3/2words phhotons + interface=cms.string("eglayer2"), + id=cms.uint32(0), + channels=cms.vuint32(0) + ) + ) + ), + # NOTE: to write out the GT input from 6TS + # outPatternFile=cms.PSet( + # nFramesPerBX=cms.uint32(9), # 360 MHz clock or 25 Gb/s link + # format=cms.string("EMP"), + # outputFilename=cms.string("L1TCTL2EG_ToGTPattern"), + # TMUX=cms.uint32(1), + # maxLinesPerFile=cms.uint32(1024), + # channels=cms.VPSet( + # cms.PSet( + # TMUX=cms.uint32(6), + # nWords=cms.uint32(36), # 36 = 12*3/2words ele + 12*3/2words phhotons + # interface=cms.string("eglayer2"), + # id=cms.uint32(0), + # channels=cms.vuint32(0, 1, 2, 3, 4, 5) + # ) + # ) + # ) +) + + +l1ctLayer2EGTask = cms.Task( + l1ctLayer2EG +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py index 05d040b0088c9..f30988264bdbf 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/l1pfJetMet_cff.py @@ -1,38 +1,30 @@ import FWCore.ParameterSet.Config as cms -from RecoMET.METProducers.pfMet_cfi import pfMet -_pfMet = pfMet.clone(calculateSignificance = False) -l1PFMetCalo = _pfMet.clone(src = "l1pfCandidates:Calo") -l1PFMetPF = _pfMet.clone(src = "l1pfCandidates:PF") -l1PFMetPuppi = _pfMet.clone(src = "l1pfCandidates:Puppi") - -l1PFMets = cms.Sequence(l1PFMetCalo + l1PFMetPF + l1PFMetPuppi) - -from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets -_ak4PFJets = ak4PFJets.clone(doAreaFastjet = False) -ak4PFL1Calo = _ak4PFJets.clone(src = 'l1pfCandidates:Calo') -ak4PFL1PF = _ak4PFJets.clone(src = 'l1pfCandidates:PF') -ak4PFL1Puppi = _ak4PFJets.clone(src = 'l1pfCandidates:Puppi') +from L1Trigger.Phase2L1ParticleFlow.L1SeedConePFJetProducer_cfi import L1SeedConePFJetProducer, L1SeedConePFJetEmulatorProducer +from L1Trigger.Phase2L1ParticleFlow.DeregionizerProducer_cfi import DeregionizerProducer as l1ctLayer2Deregionizer +scPFL1PF = L1SeedConePFJetProducer.clone(L1PFObjects = 'l1ctLayer1:PF') +scPFL1Puppi = L1SeedConePFJetProducer.clone() +scPFL1PuppiEmulator = L1SeedConePFJetEmulatorProducer.clone(L1PFObject = cms.InputTag('l1ctLayer2Deregionizer', 'Puppi')) _correctedJets = cms.EDProducer("L1TCorrectedPFJetProducer", jets = cms.InputTag("_tag_"), - correctorFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200.root"), - correctorDir = cms.string("_dir_"), - copyDaughters = cms.bool(False) + correctorFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/jecs/jecs.PU200_110X.root"), + correctorDir = cms.string("_dir_") ) # 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") - -ak4PFL1CaloCorrected = _correctedJets.clone(jets = 'ak4PFL1Calo', correctorDir = 'L1CaloJets') -ak4PFL1PFCorrected = _correctedJets.clone(jets = 'ak4PFL1PF', correctorDir = 'L1PFJets') -ak4PFL1PuppiCorrected = _correctedJets.clone(jets = 'ak4PFL1Puppi', correctorDir = 'L1PuppiJets') - -l1PFJets = cms.Sequence( - ak4PFL1Calo + ak4PFL1PF + ak4PFL1Puppi + - ak4PFL1CaloCorrected + ak4PFL1PFCorrected + ak4PFL1PuppiCorrected + +scPFL1PuppiCorrectedEmulator = _correctedJets.clone(jets = 'scPFL1PuppiEmulator', correctorDir = 'L1PuppiSC4EmuDeregJets') + +from L1Trigger.Phase2L1ParticleFlow.L1MhtPfProducer_cfi import L1MhtPfProducer +scPFL1PuppiCorrectedEmulatorMHT = L1MhtPfProducer.clone() #(jets = cms.InputTag("scPFL1PuppiCorrectedEmulator")) + + +l1PFJetsTask = cms.Task( + l1ctLayer2Deregionizer, scPFL1PF, scPFL1Puppi, scPFL1PuppiEmulator, scPFL1PuppiCorrectedEmulator, scPFL1PuppiCorrectedEmulatorMHT ) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/l1pfProducer_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/l1pfProducer_cfi.py deleted file mode 100644 index 08941eb2bc018..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/python/l1pfProducer_cfi.py +++ /dev/null @@ -1,72 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -from math import sqrt - -l1pfProducer = cms.EDProducer("L1TPFProducer", - tracks = cms.InputTag('pfTracksFromL1Tracks'), - muons = cms.InputTag('simGmtStage2Digis',), - tkMuons = cms.InputTag('L1TkMuons'), - # type of muons to be used in PF (enable only one at a time) - useStandaloneMuons = cms.bool(True), - useTrackerMuons = cms.bool(False), - emClusters = cms.VInputTag(cms.InputTag('pfClustersFromHGC3DClustersEM'), cms.InputTag('pfClustersFromL1EGClusters')), - hadClusters = cms.VInputTag(cms.InputTag('pfClustersFromCombinedCalo:calibrated')), - emPtCut = cms.double(0.5), - hadPtCut = cms.double(1.0), - trkPtCut = cms.double(2.0), - trkMinStubs = cms.uint32(4), - trkMaxChi2 = cms.double(15), - etaCharged = cms.double(2.5), - puppiDr = cms.double(0.3), - puppiDrMin = cms.double(0.1), - puppiPtMax = cms.double(999), - puppiEtaCuts = cms.vdouble(1.5, 2.5, 3.0, 5.5), - puppiPtCuts = cms.vdouble(0.0, 3.0, 6.0, 8.0), - puppiPtCutsPhotons = cms.vdouble(0.0, 3.0, 6.0, 8.0), - puppiUsingBareTracks = cms.bool(False), # use PF - vtxRes = cms.double(0.333), - vtxAlgo = cms.string("TP"), - vtxAdaptiveCut = cms.bool(True), - pfAlgo = cms.string("PFAlgo3"), - puAlgo = cms.string("Puppi"), - linking = cms.PSet( - # track -> mu linking configurables - trackMuDR = cms.double(0.2), # accounts for poor resolution of standalone, and missing propagations - trackMuMatch = cms.string("boxBestByPtRatio"), # also drBestByPtRatio - # track -> em linking configurables - trackEmDR = cms.double(0.04), # 1 Ecal crystal size is 0.02, and ~2 cm in HGCal is ~0.007 - trackEmUseAlsoTrackSigma = cms.bool(True), # also use the track uncertainty for electron linking - trackEmMayUseCaloMomenta = cms.bool(True), # use calo momenta for 1 emcalo to 1 track match electrons - # em -> calo linking configurables - emCaloDR = cms.double(0.10), # 1 Hcal tower size is ~0.09 - caloEmPtMinFrac = cms.double(0.5), # Calo object must have an EM Et at least half of that of the EM cluster to allow linking - emCaloUseAlsoCaloSigma = cms.bool(True), # also use the track uncertainty for electron linking - emCaloSubtractionPtSlope = cms.double(1.2), # e/pi ratio of HCal - # track -> calo linking configurables - trackCaloLinkMetric = cms.string("bestByDRPt"), - #trackCaloLinkMetric = cms.string("bestByDR"), - trackCaloDR = cms.double(0.15), - trackCaloNSigmaLow = cms.double(2.0), - trackCaloNSigmaHigh = cms.double(sqrt(1.0)), # sqrt(x) since in the hardware we use sigma squared - useTrackCaloSigma = cms.bool(True), # take the uncertainty on the calo cluster from the track, for linking purposes - sumTkCaloErr2 = cms.bool(True), # add up track calo errors in quadrature instead of linearly - rescaleTracks = cms.bool(False), # if tracks exceed the calo, rescale the track momenta - useCaloTrkWeightedAverage = cms.bool(False), # do the weighted average of track & calo pTs if it's a 1-1 link - # how to deal with unlinked tracks - maxInvisiblePt = cms.double(10.0), # max allowed pt of a track with no calo energy - tightTrackMinStubs = cms.uint32(6), - tightTrackMaxChi2 = cms.double(50), - tightTrackMaxInvisiblePt = cms.double(20), - # how to deal with neutrals - ecalPriority = cms.bool(True), # take first ecal energy when making neutrals - # other features not turned on: reliniking of neutrals to track-matched calo clusters with track excess - caloReLink = cms.bool(False), - caloReLinkDR = cms.double(0.3), - caloReLinkThreshold = cms.double(0.5), - # other features not turned on: matching too high pt tracks to calo but rescaling track pt (not implemented in PFAlgo3) - rescaleUnmatchedTrack = cms.bool(False), - ), - debug = cms.untracked.int32(0), -) - - diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromCombinedCalo_cff.py b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromCombinedCalo_cff.py new file mode 100644 index 0000000000000..96698e77bd2f6 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromCombinedCalo_cff.py @@ -0,0 +1,68 @@ +import FWCore.ParameterSet.Config as cms + +from L1Trigger.Phase2L1ParticleFlow.pfClustersFromCombinedCalo_cfi import pfClustersFromCombinedCalo + +# 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 +from Configuration.Eras.Modifier_phase2_hgcalV11_cff import phase2_hgcalV11 + +# Calorimeter part: ecal + hcal + hf only +pfClustersFromCombinedCaloHCal = pfClustersFromCombinedCalo.clone( + hcalHGCTowers = [], hcalDigis = [], + hcalDigisBarrel = True, hcalDigisHF = False, + hadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel.root"), + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 2.582, 2.191, -0.077), + scale = cms.vdouble( 0.122, 0.143, 0.465), + kind = cms.string('calo'), + )) +phase2_hgcalV10.toModify(pfClustersFromCombinedCaloHCal, + hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel_106X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 3.084, 2.715, 0.107), + scale = cms.vdouble( 0.118, 0.130, 0.442), + kind = cms.string('calo'), + ) +) +phase2_hgcalV11.toModify(pfClustersFromCombinedCaloHCal, + hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hadcorr_barrel_110X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 0.700, 1.200, 1.600), + offset = cms.vdouble( 2.909, 2.864, 0.294), + scale = cms.vdouble( 0.119, 0.127, 0.442), + kind = cms.string('calo'), + ) +) + +pfClustersFromCombinedCaloHF = pfClustersFromCombinedCalo.clone( + ecalCandidates = [], hcalHGCTowers = [], + phase2barrelCaloTowers = [], + hadCorrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hfcorr.root"), + resol = cms.PSet( + etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), + offset = cms.vdouble( 1.099, 0.930, 1.009, 1.369), + scale = cms.vdouble( 0.152, 0.151, 0.144, 0.179), + kind = cms.string('calo'), + )) +phase2_hgcalV10.toModify(pfClustersFromCombinedCaloHF, + hcalCandidates = cms.VInputTag(cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering")), + hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hfcorr_106X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), + offset = cms.vdouble(-0.846, 0.696, 1.313, 1.044), + scale = cms.vdouble( 0.815, 0.164, 0.146, 0.192), + kind = cms.string('calo'), + ) +) +phase2_hgcalV11.toModify(pfClustersFromCombinedCaloHF, + hcalCandidates = cms.VInputTag(cms.InputTag("hgcalBackEndLayer2Producer","HGCalBackendLayer2Processor3DClustering")), + hadCorrector = "L1Trigger/Phase2L1ParticleFlow/data/hfcorr_110X.root", + resol = cms.PSet( + etaBins = cms.vdouble( 3.500, 4.000, 4.500, 5.000), + offset = cms.vdouble(-1.125, 1.220, 1.514, 1.414), + scale = cms.vdouble( 0.868, 0.159, 0.148, 0.194), + kind = cms.string('calo'), + ) +) diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClustersEM_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClustersEM_cfi.py index aa13bd5ee3453..1d30550aab519 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClustersEM_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClustersEM_cfi.py @@ -4,6 +4,7 @@ pfClustersFromHGC3DClustersEM = L1Trigger.Phase2L1ParticleFlow.pfClustersFromHGC3DClusters_cfi.pfClustersFromHGC3DClusters.clone( emOnly = cms.bool(True), + useEMInterpretation = cms.string("emOnly"), # use EM intepretation to redefine the energy etMin = cms.double(0.0), corrector = cms.string("L1Trigger/Phase2L1ParticleFlow/data/emcorr_hgc.root"), preEmId = cms.string(""), diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClusters_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClusters_cfi.py index 536835d095d03..85a4f844e044f 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClusters_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfClustersFromHGC3DClusters_cfi.py @@ -11,27 +11,30 @@ method = cms.string("BDT"), # "" to be disabled, "BDT" to be enabled variables = cms.VPSet( cms.PSet(name = cms.string("fabs(eta)"), value = cms.string("abs(eta())")), - cms.PSet(name = cms.string("coreShowerLength"), value = cms.string("coreShowerLength()")), - cms.PSet(name = cms.string("maxLayer"), value = cms.string("maxLayer()")), - cms.PSet(name = cms.string("hOverE"), value = cms.string("hOverE()")), + cms.PSet(name = cms.string("eMax"), value = cms.string("eMax()")), + cms.PSet(name = cms.string("sigmaPhiPhiTot"), value = cms.string("sigmaPhiPhiTot()")), cms.PSet(name = cms.string("sigmaZZ"), value = cms.string("sigmaZZ()")), + cms.PSet(name = cms.string("layer50percent"), value = cms.string("layer50percent()")), + cms.PSet(name = cms.string("triggerCells67percent"), value = cms.string("triggerCells67percent()")), ), - weightsFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_vs_Pion_BDTweights.xml.gz"), - wp = cms.string("0.01") + weightsFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_vs_Pion_BDTweights_1116.xml.gz"), + wp = cms.string("0.05") ), emVsPUID = cms.PSet( isPUFilter = cms.bool(True), preselection = cms.string(""), method = cms.string("BDT"), # "" to be disabled, "BDT" to be enabled variables = cms.VPSet( - cms.PSet(name = cms.string("fabs(eta)"), value = cms.string("abs(eta())")), - cms.PSet(name = cms.string("coreShowerLength"), value = cms.string("coreShowerLength()")), - cms.PSet(name = cms.string("maxLayer"), value = cms.string("maxLayer()")), + cms.PSet(name = cms.string("eMax"), value = cms.string("eMax()")), + cms.PSet(name = cms.string("eMaxOverE"), value = cms.string("eMax()/energy()")), cms.PSet(name = cms.string("sigmaPhiPhiTot"), value = cms.string("sigmaPhiPhiTot()")), + cms.PSet(name = cms.string("sigmaRRTot"), value = cms.string("sigmaRRTot()")), + cms.PSet(name = cms.string("triggerCells90percent"), value = cms.string("triggerCells90percent()")), ), - weightsFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_Pion_vs_Neutrino_BDTweights.xml.gz"), - wp = cms.string("-0.02") + weightsFile = cms.string("L1Trigger/Phase2L1ParticleFlow/data/hgcal_egID/Photon_Pion_vs_Neutrino_BDTweights_1116.xml.gz"), + wp = cms.string("0.15") ), + useEMInterpretation = cms.string("allKeepHad"), # for all clusters, use EM intepretation to redefine the EM part of the energy emOnly = cms.bool(False), etMin = cms.double(1.0), resol = cms.PSet( diff --git a/L1Trigger/Phase2L1ParticleFlow/python/pfTracksFromL1Tracks_cfi.py b/L1Trigger/Phase2L1ParticleFlow/python/pfTracksFromL1Tracks_cfi.py index 93f8ddb758aed..e37ab47123b00 100644 --- a/L1Trigger/Phase2L1ParticleFlow/python/pfTracksFromL1Tracks_cfi.py +++ b/L1Trigger/Phase2L1ParticleFlow/python/pfTracksFromL1Tracks_cfi.py @@ -16,7 +16,12 @@ offset = cms.vdouble( 0.007, 0.009, 0.011, 0.015, 0.025), scale = cms.vdouble( 0.275, 0.404, 0.512, 0.480, 1.132), kind = cms.string('track'), - ) - + ), + qualityBits = cms.vstring( + "momentum.perp > 2 && getStubRefs.size >= 4 && chi2Red < 15", + "momentum.perp > 2 && getStubRefs.size >= 6 && chi2Red < 15 && chi2 < 50", # historical reasons + "momentum.perp > 5 && getStubRefs.size >= 4" + ), + redigitizeTrackWord = cms.bool(True), ) diff --git a/L1Trigger/Phase2L1ParticleFlow/src/BitwisePFAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/BitwisePFAlgo.cc deleted file mode 100644 index cf937b3c0acdd..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/BitwisePFAlgo.cc +++ /dev/null @@ -1,195 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/BitwisePFAlgo.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" - -//#define REG_HGCal -#include "ref/pfalgo2hgc_ref.h" -#include "ref/pfalgo3_ref.h" -#include "utils/DiscretePF2Firmware.h" -#include "utils/Firmware2DiscretePF.h" - -using namespace l1tpf_impl; - -BitwisePFAlgo::BitwisePFAlgo(const edm::ParameterSet &iConfig) : PFAlgoBase(iConfig), config_(nullptr) { - const edm::ParameterSet &bitwiseConfig = iConfig.getParameter("bitwiseConfig"); - const std::string &algo = iConfig.getParameter("bitwiseAlgo"); - debug_ = iConfig.getUntrackedParameter("debugBitwisePFAlgo", iConfig.getUntrackedParameter("debug", 0)); - if (algo == "pfalgo3") { - algo_ = AlgoChoice::algo3; - config_ = std::make_shared(bitwiseConfig.getParameter("NTRACK"), - bitwiseConfig.getParameter("NEMCALO"), - bitwiseConfig.getParameter("NCALO"), - bitwiseConfig.getParameter("NMU"), - bitwiseConfig.getParameter("NPHOTON"), - bitwiseConfig.getParameter("NSELCALO"), - bitwiseConfig.getParameter("NALLNEUTRAL"), - bitwiseConfig.getParameter("DR2MAX_TK_MU"), - bitwiseConfig.getParameter("DR2MAX_TK_EM"), - bitwiseConfig.getParameter("DR2MAX_EM_CALO"), - bitwiseConfig.getParameter("DR2MAX_TK_CALO"), - bitwiseConfig.getParameter("TK_MAXINVPT_LOOSE"), - bitwiseConfig.getParameter("TK_MAXINVPT_TIGHT")); - } else if (algo == "pfalgo2hgc") { - algo_ = AlgoChoice::algo2hgc; - config_ = std::make_shared(bitwiseConfig.getParameter("NTRACK"), - bitwiseConfig.getParameter("NCALO"), - bitwiseConfig.getParameter("NMU"), - bitwiseConfig.getParameter("NSELCALO"), - bitwiseConfig.getParameter("DR2MAX_TK_MU"), - bitwiseConfig.getParameter("DR2MAX_TK_CALO"), - bitwiseConfig.getParameter("TK_MAXINVPT_LOOSE"), - bitwiseConfig.getParameter("TK_MAXINVPT_TIGHT")); - } else { - throw cms::Exception("Configuration", "Unsupported bitwiseAlgo " + algo); - } -} - -BitwisePFAlgo::~BitwisePFAlgo() {} - -void BitwisePFAlgo::runPF(Region &r) const { - initRegion(r); - - std::unique_ptr calo(new HadCaloObj[config_->nCALO]); - std::unique_ptr track(new TkObj[config_->nTRACK]); - std::unique_ptr mu(new MuObj[config_->nMU]); - std::unique_ptr outch(new PFChargedObj[config_->nTRACK]); - std::unique_ptr outne(new PFNeutralObj[config_->nSELCALO]); - std::unique_ptr outmu(new PFChargedObj[config_->nMU]); - - dpf2fw::convert(config_->nTRACK, r.track, track.get()); - dpf2fw::convert(config_->nCALO, r.calo, calo.get()); - dpf2fw::convert(config_->nMU, r.muon, mu.get()); - - if (debug_) { - dbgPrintf( - "BitwisePF\nBitwisePF region eta [ %+5.2f , %+5.2f ], phi [ %+5.2f , %+5.2f ], fiducial eta [ %+5.2f , %+5.2f " - "], phi [ %+5.2f , %+5.2f ], algo = %d\n", - r.etaMin - r.etaExtra, - r.etaMax + r.etaExtra, - r.phiCenter - r.phiHalfWidth - r.phiExtra, - r.phiCenter + r.phiHalfWidth + r.phiExtra, - r.etaMin, - r.etaMax, - r.phiCenter - r.phiHalfWidth, - r.phiCenter + r.phiHalfWidth, - static_cast(algo_)); - dbgPrintf("BitwisePF \t N(track) %3lu N(em) %3lu N(calo) %3lu N(mu) %3lu\n", - r.track.size(), - r.emcalo.size(), - r.calo.size(), - r.muon.size()); - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - const auto &tk = r.track[itk]; - dbgPrintf( - "BitwisePF \t track %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - " fid %1d calo ptErr %7.2f stubs %2d chi2 %7.1f\n", - itk, - tk.floatPt(), - tk.floatPtErr(), - tk.floatVtxEta(), - tk.floatVtxPhi(), - tk.floatEta(), - tk.floatPhi(), - int(r.fiducialLocal(tk.floatEta(), tk.floatPhi())), - tk.floatCaloPtErr(), - int(tk.hwStubs), - tk.hwChi2 * 0.1f); - } - for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { - const auto &em = r.emcalo[iem]; - dbgPrintf( - "BitwisePF \t EM %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - " fid %1d calo ptErr %7.2f\n", - iem, - em.floatPt(), - em.floatPtErr(), - em.floatEta(), - em.floatPhi(), - em.floatEta(), - em.floatPhi(), - int(r.fiducialLocal(em.floatEta(), em.floatPhi())), - em.floatPtErr()); - } - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - dbgPrintf( - "BitwisePF \t calo %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - " fid %1d calo ptErr %7.2f em pt %7.2f \n", - ic, - calo.floatPt(), - calo.floatPtErr(), - calo.floatEta(), - calo.floatPhi(), - calo.floatEta(), - calo.floatPhi(), - int(r.fiducialLocal(calo.floatEta(), calo.floatPhi())), - calo.floatPtErr(), - calo.floatEmPt()); - } - for (int im = 0, nm = r.muon.size(); im < nm; ++im) { - auto &mu = r.muon[im]; - dbgPrintf( - "BitwisePF \t muon %3d: pt %7.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - " fid %1d \n", - im, - mu.floatPt(), - mu.floatEta(), - mu.floatPhi(), - mu.floatEta(), - mu.floatPhi(), - int(r.fiducialLocal(mu.floatEta(), mu.floatPhi()))); - } - } - switch (algo_) { - case AlgoChoice::algo3: { - pfalgo3_config *config3 = static_cast(config_.get()); - std::unique_ptr emcalo(new EmCaloObj[config3->nEMCALO]); - std::unique_ptr outpho(new PFNeutralObj[config3->nPHOTON]); - - dpf2fw::convert(config3->nEMCALO, r.emcalo, emcalo.get()); - pfalgo3_ref(*config3, - emcalo.get(), - calo.get(), - track.get(), - mu.get(), - outch.get(), - outpho.get(), - outne.get(), - outmu.get(), - debug_); - - fw2dpf::convert(config3->nTRACK, outch.get(), r.track, r.pf); // FIXME works only with a 1-1 mapping - fw2dpf::convert(config3->nPHOTON, outpho.get(), r.pf); - fw2dpf::convert(config3->nSELCALO, outne.get(), r.pf); - } break; - case AlgoChoice::algo2hgc: { - pfalgo2hgc_ref(*config_, calo.get(), track.get(), mu.get(), outch.get(), outne.get(), outmu.get(), debug_); - fw2dpf::convert(config_->nTRACK, outch.get(), r.track, r.pf); // FIXME works only with a 1-1 mapping - fw2dpf::convert(config_->nSELCALO, outne.get(), r.pf); - } break; - }; - - if (debug_) { - dbgPrintf("BitwisePF \t Output N(ch) %3u/%3u N(nh) %3u/%3u N(ph) %3u/%u [all/fiducial]\n", - r.nOutput(l1tpf_impl::Region::charged_type, false, false), - r.nOutput(l1tpf_impl::Region::charged_type, false, true), - r.nOutput(l1tpf_impl::Region::neutral_hadron_type, false, false), - r.nOutput(l1tpf_impl::Region::neutral_hadron_type, false, true), - r.nOutput(l1tpf_impl::Region::photon_type, false, false), - r.nOutput(l1tpf_impl::Region::photon_type, false, true)); - for (int ipf = 0, npf = r.pf.size(); ipf < npf; ++ipf) { - const auto &pf = r.pf[ipf]; - dbgPrintf( - "BitwisePF \t pf %3d: pt %7.2f pid %d vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - "fid %1d\n", - ipf, - pf.floatPt(), - int(pf.hwId), - pf.floatVtxEta(), - pf.floatVtxPhi(), - pf.floatEta(), - pf.floatPhi(), - int(r.fiducialLocal(pf.floatEta(), pf.floatPhi()))); - } - } -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc b/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc deleted file mode 100644 index b0b2c8364803e..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/COEFile.cc +++ /dev/null @@ -1,130 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/COEFile.h" - -using namespace l1tpf_impl; - -COEFile::COEFile(const edm::ParameterSet& iConfig) - : file(nullptr), - coeFileName(iConfig.getUntrackedParameter("coeFileName", "")), - bset_string_(""), - ntracksmax(iConfig.getUntrackedParameter("ntracksmax")), - phiSlices(iConfig.getParameter>("regions")[0].getParameter("phiSlices")), - debug_(iConfig.getUntrackedParameter("debug", 0)) { - file = fopen(coeFileName.c_str(), "w"); - writeHeaderToFile(); - bset_.resize(tracksize); -} - -COEFile::~COEFile() {} - -void COEFile::writeHeaderToFile() { - char depth_width[256]; - snprintf(depth_width, - 255, - "; of depth=%i, and width=%i. In this case, values are specified\n", - ntracksmax, - tracksize * phiSlices); - std::vector vheader = {"; Sample memory initialization file for Dual Port Block Memory,\n", - "; v3.0 or later.\n", - "; Board: VCU118\n", - "; tmux: 1\n", - ";\n", - "; This .COE file specifies the contents for a block memory\n", - std::string(depth_width), - "; in binary format.\n", - "memory_initialization_radix=2;\n", - "memory_initialization_vector=\n"}; - for (uint32_t i = 0; i < vheader.size(); ++i) - fprintf(file, "%s", vheader[i].c_str()); -} - -void COEFile::writeTracksToFile(const std::vector& regions, bool print) { - PropagatedTrack current_track; - bool has_track = false; - for (unsigned int irow = 0; irow < ntracksmax; irow++) { - for (unsigned int icol = 0; icol < regions.size(); icol++) { - if (regions[icol].track.size() <= irow) - has_track = false; - else - has_track = true; - - if (has_track) { - // select the track that will be converted to a bit string - current_track = regions[icol].track[irow]; - - // convert the values in a PropogatedTrack to a 96-bit track word - for (unsigned int iblock = 0; iblock < track_word_block_sizes.size(); iblock++) { - for (unsigned int ibit = 0; ibit < track_word_block_sizes[iblock]; ibit++) { - int offset = std::accumulate(track_word_block_sizes.begin(), track_word_block_sizes.begin() + iblock, 0); - switch (iblock) { - case 0: - bset_.set(ibit + offset, getBit(current_track.hwPt, ibit)); - break; - case 1: - bset_.set(ibit + offset, current_track.hwCharge); - break; - case 2: - bset_.set(ibit + offset, getBit(current_track.hwVtxPhi, ibit)); - break; - case 3: - bset_.set(ibit + offset, getBit(current_track.hwVtxEta, ibit)); - break; - case 4: - bset_.set(ibit + offset, getBit(current_track.hwZ0, ibit)); - break; - case 5: - bset_.set(ibit + offset, false); - break; - case 6: - bset_.set(ibit + offset, getBit(current_track.hwChi2, ibit)); - break; - case 7: - bset_.set(ibit + offset, false); - break; - case 8: - bset_.set(ibit + offset, getBit(current_track.hwStubs, ibit)); - break; - case 9: - bset_.set(ibit + offset, false); - break; - } - } - } - - // print the track word to the COE file - boost::to_string(bset_, bset_string_); - fprintf(file, "%s", bset_string_.c_str()); - - // print some debugging information - if (debug_ && print && irow == 0 && icol == 0) { - printf("region: eta=[%f,%f] phi=%f+/-%f\n", - regions[icol].etaMin, - regions[icol].etaMax, - regions[icol].phiCenter, - regions[icol].phiHalfWidth); - printf("l1t::PFTrack (pT,eta,phi) [float] = (%f,%f,%f)\n", - current_track.src->p4().Pt(), - current_track.src->p4().Eta(), - current_track.src->p4().Phi()); - printf("l1t::PFTrack (pT,eta,phi) [int] = (%i,%i,%i)\n", - current_track.src->hwPt(), - current_track.src->hwEta(), - current_track.src->hwPhi()); - printf("l1tpf_impl::PropagatedTrack (1/pT,eta,phi) [int,10] = (%i,%i,%i)\n", - current_track.hwPt, - current_track.hwVtxEta, - current_track.hwVtxPhi); - printf("l1tpf_impl::PropagatedTrack (1/pT,eta,phi) [int,2] = (%s,%s,%s)\n", - std::bitset<16>(current_track.hwPt).to_string().c_str(), - std::bitset<32>(current_track.hwVtxEta).to_string().c_str(), - std::bitset<32>(current_track.hwVtxPhi).to_string().c_str()); - printf("bitset = %s\n", bset_string_.c_str()); - } - } else { - bset_.reset(); - boost::to_string(bset_, bset_string_); - fprintf(file, "%s", bset_string_.c_str()); - } - } - fprintf(file, (irow == ntracksmax - 1) ? ";\n" : ",\n"); - } -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/DiscretePFInputsIO.cc b/L1Trigger/Phase2L1ParticleFlow/src/DiscretePFInputsIO.cc deleted file mode 100644 index 67cc12e16a383..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/DiscretePFInputsIO.cc +++ /dev/null @@ -1 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h" diff --git a/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc new file mode 100644 index 0000000000000..727be3578576f --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/L1TCorrelatorLayer1PatternFileWriter.cc @@ -0,0 +1,355 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h" +#include "FWCore/Utilities/interface/Exception.h" +#include + +L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const edm::ParameterSet& iConfig, + const l1ct::Event& eventTemplate) + : partition_(parsePartition(iConfig.getParameter("partition"))), + writeInputs_(iConfig.existsAs("inputFileName") && + !iConfig.getParameter("inputFileName").empty()), + writeOutputs_(iConfig.existsAs("outputFileName") && + !iConfig.getParameter("outputFileName").empty()), + outputBoard_(-1), + outputLinkEgamma_(-1), + fileFormat_(iConfig.getParameter("fileFormat")), + eventsPerFile_(iConfig.getParameter("eventsPerFile")), + eventIndex_(0) { + if (writeInputs_) { + nInputFramesPerBX_ = iConfig.getParameter("nInputFramesPerBX"); + + if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) { + configTimeSlices(iConfig, "tf", eventTemplate.raw.track.size(), tfTimeslices_, tfLinksFactor_); + channelSpecsInput_["tf"] = {tmuxFactor_ * tfTimeslices_, tfTimeslices_}; + } + if (partition_ == Partition::Barrel) { + auto sectorConfig = iConfig.getParameter>("gctSectors"); + if (sectorConfig.size() != gctSectors_) + throw cms::Exception("Configuration", "Bad number of GCT sectors"); + for (unsigned int iS = 0; iS < gctSectors_; ++iS) { + auto linksEcal = sectorConfig[iS].getParameter>("gctLinksEcal"); + auto linksHad = sectorConfig[iS].getParameter>("gctLinksHad"); + if (linksEcal.size() != gctLinksEcal_ || linksHad.size() != gctLinksHad_) + throw cms::Exception("Configuration", "Bad number of GCT links"); + unsigned int iLink = 0; + for (unsigned int i = 0; i < gctLinksHad_; ++i, ++iLink) { + if (linksHad[i] != -1) + channelIdsInput_[l1t::demo::LinkId{"gct", iLink + 10 * iS}].push_back(linksHad[i]); + } + for (unsigned int i = 0; i < gctLinksEcal_; ++i) { + if (linksEcal[i] != -1) + channelIdsInput_[l1t::demo::LinkId{"gct", iLink + 10 * iS}].push_back(linksEcal[i]); + } + channelSpecsInput_["gct"] = {tmuxFactor_ * gctTimeslices_, 0}; + } + } + if (partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) { + configTimeSlices(iConfig, "hgc", eventTemplate.raw.hgcalcluster.size(), hgcTimeslices_, hgcLinksFactor_); + channelSpecsInput_["hgc"] = {tmuxFactor_ * hgcTimeslices_, hgcTimeslices_}; + } + if (partition_ == Partition::Barrel || partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) { + configTimeSlices(iConfig, "gmt", 1, gmtTimeslices_, gmtLinksFactor_); + gmtNumberOfMuons_ = iConfig.getParameter("gmtNumberOfMuons"); + channelSpecsInput_["gmt"] = {tmuxFactor_ * gmtTimeslices_, + gmtTimeslices_ * nInputFramesPerBX_ * tmuxFactor_ - gmtNumberOfMuons_}; + } + if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) { + configTimeSlices(iConfig, "gtt", 1, gttTimeslices_, gttLinksFactor_); + gttLatency_ = iConfig.getParameter("gttLatency"); + gttNumberOfPVs_ = iConfig.getParameter("gttNumberOfPVs"); + channelSpecsInput_["gtt"] = l1t::demo::ChannelSpec{tmuxFactor_, gttTimeslices_, gttLatency_}; + } + inputFileWriter_ = + std::make_unique(l1t::demo::parseFileFormat(fileFormat_), + iConfig.getParameter("inputFileName"), + nInputFramesPerBX_, + tmuxFactor_, + iConfig.getParameter("maxLinesPerInputFile"), + channelIdsInput_, + channelSpecsInput_); + } + + if (writeOutputs_) { + nOutputFramesPerBX_ = iConfig.getParameter("nOutputFramesPerBX"); + + outputRegions_ = iConfig.getParameter>("outputRegions"); + outputLinksPuppi_ = iConfig.getParameter>("outputLinksPuppi"); + for (unsigned int i = 0; i < outputLinksPuppi_.size(); ++i) { + channelIdsOutput_[l1t::demo::LinkId{"puppi", i}].push_back(outputLinksPuppi_[i]); + } + channelSpecsOutput_["puppi"] = {tmuxFactor_, 0}; + nPuppiFramesPerRegion_ = (nOutputFramesPerBX_ * tmuxFactor_) / outputRegions_.size(); + if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) { + outputBoard_ = iConfig.getParameter("outputBoard"); + outputLinkEgamma_ = iConfig.getParameter("outputLinkEgamma"); + nEgammaObjectsOut_ = iConfig.getParameter("nEgammaObjectsOut"); + if (outputLinkEgamma_ != -1) { + channelIdsOutput_[l1t::demo::LinkId{"egamma", 0}].push_back(outputLinkEgamma_); + channelSpecsOutput_["egamma"] = {tmuxFactor_, nOutputFramesPerBX_ * tmuxFactor_ - 3 * nEgammaObjectsOut_}; + } + } + if ((outputBoard_ == -1) != (outputLinkEgamma_ == -1)) { + throw cms::Exception("Configuration", "Inconsistent configuration of outputLinkEgamma, outputBoard"); + } + outputFileWriter_ = + std::make_unique(l1t::demo::parseFileFormat(fileFormat_), + iConfig.getParameter("outputFileName"), + nOutputFramesPerBX_, + tmuxFactor_, + iConfig.getParameter("maxLinesPerOutputFile"), + channelIdsOutput_, + channelSpecsOutput_); + } +} + +L1TCorrelatorLayer1PatternFileWriter::~L1TCorrelatorLayer1PatternFileWriter() {} + +void L1TCorrelatorLayer1PatternFileWriter::write(const l1ct::Event& event) { + if (writeInputs_) { + l1t::demo::EventData inputs; + if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) { + writeTF(event, inputs); + } + if (partition_ == Partition::Barrel) { + writeBarrelGCT(event, inputs); + } + if (partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) { + writeHGC(event, inputs); + } + if (partition_ == Partition::Barrel || partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) { + writeGMT(event, inputs); + } + if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) { + writeGTT(event, inputs); + } + inputFileWriter_->addEvent(inputs); + } + + if (writeOutputs_) { + l1t::demo::EventData outputs; + writePuppi(event, outputs); + if (outputLinkEgamma_ != -1) + writeEgamma(event, outputs); + outputFileWriter_->addEvent(outputs); + } + + eventIndex_++; + if (eventIndex_ % eventsPerFile_ == 0) { + if (writeInputs_) + inputFileWriter_->flush(); + if (writeOutputs_) + outputFileWriter_->flush(); + } +} + +L1TCorrelatorLayer1PatternFileWriter::Partition L1TCorrelatorLayer1PatternFileWriter::parsePartition( + const std::string& partition) { + if (partition == "Barrel") + return Partition::Barrel; + if (partition == "HGCal") + return Partition::HGCal; + if (partition == "HGCalNoTk") + return Partition::HGCalNoTk; + if (partition == "HF") + return Partition::HF; + throw cms::Exception("Configuration", "Unsupported partition_ '" + partition + "'\n"); +} + +void L1TCorrelatorLayer1PatternFileWriter::configTimeSlices(const edm::ParameterSet& iConfig, + const std::string& prefix, + unsigned int nSectors, + unsigned int nTimeSlices, + unsigned int linksFactor) { + if (nTimeSlices > 1) { + auto timeSliceConfig = iConfig.getParameter>(prefix + "TimeSlices"); + if (timeSliceConfig.size() != nTimeSlices) + throw cms::Exception("Configuration") + << "Mismatched number of " << prefix << "TimeSlices, expected " << nTimeSlices << std::endl; + for (unsigned int iT = 0; iT < nTimeSlices; ++iT) { + configSectors(timeSliceConfig[iT], prefix, nSectors, linksFactor); + } + } else { + configSectors(iConfig, prefix, nSectors, linksFactor); + } +} + +void L1TCorrelatorLayer1PatternFileWriter::configSectors(const edm::ParameterSet& iConfig, + const std::string& prefix, + unsigned int nSectors, + unsigned int linksFactor) { + if (nSectors > 1) { + auto sectorConfig = iConfig.getParameter>(prefix + "Sectors"); + if (sectorConfig.size() != nSectors) + throw cms::Exception("Configuration") + << "Mismatched number of " << prefix << "Sectors, expected " << nSectors << std::endl; + for (unsigned int iS = 0; iS < nSectors; ++iS) { + configLinks(sectorConfig[iS], prefix, linksFactor, linksFactor > 1 ? iS * 10 : iS); + } + } else { + configLinks(iConfig, prefix, linksFactor, 0); + } +} +void L1TCorrelatorLayer1PatternFileWriter::configLinks(const edm::ParameterSet& iConfig, + const std::string& prefix, + unsigned int linksFactor, + unsigned int offset) { + if (linksFactor > 1) { + auto links = iConfig.getParameter>(prefix + "Links"); + if (links.size() != linksFactor) + throw cms::Exception("Configuration") + << "Mismatched number of " << prefix << "Links, expected " << linksFactor << std::endl; + for (unsigned int i = 0; i < linksFactor; ++i) { + if (links[i] != -1) { + channelIdsInput_[l1t::demo::LinkId{prefix, i + offset}].push_back(links[i]); + } + } + } else { + auto link = iConfig.getParameter(prefix + "Link"); + if (link != -1) { + channelIdsInput_[l1t::demo::LinkId{prefix, offset}].push_back(link); + } + } +} + +void L1TCorrelatorLayer1PatternFileWriter::writeTF(const l1ct::Event& event, l1t::demo::EventData& out) { + for (unsigned int iS = 0, nS = event.raw.track.size(); iS < nS; ++iS) { + l1t::demo::LinkId key{"tf", iS}; + if (channelIdsInput_.count(key) == 0) + continue; + std::vector> ret; + std::vector> tracks = event.raw.track[iS].obj; + if (tracks.empty()) + tracks.emplace_back(0); + for (unsigned int i = 0, n = tracks.size(); i < n; ++i) { + const ap_uint<96>& packedtk = tracks[i]; + if (i % 2 == 0) { + ret.emplace_back(packedtk(63, 0)); + ret.emplace_back(0); + ret.back()(31, 0) = packedtk(95, 64); + } else { + ret.back()(63, 32) = packedtk(31, 0); + ret.emplace_back(packedtk(95, 32)); + } + } + out.add(key, ret); + } +} + +void L1TCorrelatorLayer1PatternFileWriter::writeHGC(const l1ct::Event& event, l1t::demo::EventData& out) { + assert(hgcLinksFactor_ == 4); // this piece of code won't really work otherwise + std::vector> ret[hgcLinksFactor_]; + for (unsigned int iS = 0, nS = event.raw.hgcalcluster.size(); iS < nS; ++iS) { + l1t::demo::LinkId key0{"hgc", iS * 10}; + if (channelIdsInput_.count(key0) == 0) + continue; + for (unsigned int il = 0; il < hgcLinksFactor_; ++il) { + // put header word and (dummy) towers + ret[il].resize(31); + ap_uint<64>& head64 = ret[il][0]; + head64(63, 48) = 0xABC0; // Magic + head64(47, 38) = 0; // Opaque + head64(39, 32) = (eventIndex_ % 3) * 6; // TM slice + head64(31, 24) = iS; // Sector + head64(23, 16) = il; // link + head64(15, 0) = eventIndex_ % 3564; // BX + for (unsigned int j = 0; j < 30; ++j) { + ret[il][j + 1] = 4 * j + il; + } + } + for (auto clust : event.raw.hgcalcluster[iS].obj) { + for (unsigned int il = 0; il < hgcLinksFactor_; ++il) { + ret[il].push_back(clust(64 * il + 63, 64 * il)); + } + } + for (unsigned int il = 0; il < hgcLinksFactor_; ++il) { + out.add(l1t::demo::LinkId{"hgc", iS * 10 + il}, ret[il]); + } + } +} + +void L1TCorrelatorLayer1PatternFileWriter::writeBarrelGCT(const l1ct::Event& event, l1t::demo::EventData& out) { + std::vector> ret; + for (unsigned int iS = 0; iS < gctSectors_; ++iS) { + l1t::demo::LinkId key0{"gct", iS * 10}; + if (channelIdsInput_.count(key0) == 0) + continue; + const auto& had = event.decoded.hadcalo[iS]; + const auto& ecal = event.decoded.emcalo[iS]; + unsigned int iLink = 0, nHad = had.size(), nEcal = ecal.size(); + for (unsigned int i = 0; i < gctLinksHad_; ++i, ++iLink) { + ret.clear(); + for (unsigned int iHad = i; i < nHad; iHad += gctLinksHad_) { + ret.emplace_back(had[iHad].pack()); + } + if (ret.empty()) + ret.emplace_back(0); + out.add(l1t::demo::LinkId{"gct", iS * 10 + iLink}, ret); + } + for (unsigned int i = 0; i < gctLinksEcal_; ++i, ++iLink) { + ret.clear(); + for (unsigned int iEcal = i; i < nEcal; iEcal += gctLinksEcal_) { + ret.emplace_back(ecal[iEcal].pack()); + } + if (ret.empty()) + ret.emplace_back(0); + out.add(l1t::demo::LinkId{"gct", iS * 10 + iLink}, ret); + } + } +} + +void L1TCorrelatorLayer1PatternFileWriter::writeGMT(const l1ct::Event& event, l1t::demo::EventData& out) { + l1t::demo::LinkId key{"gmt", 0}; + if (channelIdsInput_.count(key) == 0) + return; + std::vector> muons = event.raw.muon.obj; + muons.resize(gmtNumberOfMuons_, ap_uint<64>(0)); + out.add(key, muons); +} + +void L1TCorrelatorLayer1PatternFileWriter::writeGTT(const l1ct::Event& event, l1t::demo::EventData& out) { + l1t::demo::LinkId key{"gtt", 0}; + if (channelIdsInput_.count(key) == 0) + return; + std::vector> pvs = event.pvs_emu; + pvs.resize(gttNumberOfPVs_, ap_uint<64>(0)); + out.add(key, pvs); +} + +void L1TCorrelatorLayer1PatternFileWriter::writePuppi(const l1ct::Event& event, l1t::demo::EventData& out) { + unsigned int n = outputLinksPuppi_.size(); + std::vector>> links(n); + for (auto ir : outputRegions_) { + auto puppi = event.out[ir].puppi; + unsigned int npuppi = puppi.size(); + for (unsigned int i = 0; i < n * nPuppiFramesPerRegion_; ++i) { + links[i / nPuppiFramesPerRegion_].push_back(i < npuppi ? puppi[i].pack() : ap_uint(0)); + } + } + for (unsigned int i = 0; i < n; ++i) { + out.add(l1t::demo::LinkId{"puppi", i}, links[i]); + } +} + +void L1TCorrelatorLayer1PatternFileWriter::writeEgamma(const l1ct::Event& event, l1t::demo::EventData& out) { + std::vector> ret; + const auto& pho = event.board_out[outputBoard_].egphoton; + const auto& ele = event.board_out[outputBoard_].egelectron; + ret.reserve(3 * nEgammaObjectsOut_); + for (const auto& p : pho) { + ret.emplace_back(p.pack()); + } + ret.resize(nEgammaObjectsOut_, ap_uint<64>(0)); + for (const auto& p : ele) { + ap_uint<128> dword = p.pack(); + ret.push_back(dword(63, 0)); + ret.push_back(dword(127, 64)); + } + ret.resize(3 * nEgammaObjectsOut_, ap_uint<64>(0)); + out.add(l1t::demo::LinkId{"egamma", 0}, ret); +} + +void L1TCorrelatorLayer1PatternFileWriter::flush() { + if (inputFileWriter_) + inputFileWriter_->flush(); + if (outputFileWriter_) + outputFileWriter_->flush(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/LinearizedPuppiAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/LinearizedPuppiAlgo.cc deleted file mode 100644 index 463a114b53f6e..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/LinearizedPuppiAlgo.cc +++ /dev/null @@ -1,142 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/LinearizedPuppiAlgo.h" -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "DataFormats/Math/interface/deltaR.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" - -#include "Math/ProbFunc.h" - -namespace { - std::vector vd2vf(const std::vector &vd) { - std::vector ret; - ret.insert(ret.end(), vd.begin(), vd.end()); - return ret; - } -} // namespace - -using namespace l1tpf_impl; - -LinearizedPuppiAlgo::LinearizedPuppiAlgo(const edm::ParameterSet &iConfig) - : PuppiAlgo(iConfig), - puppiPriors_(vd2vf(iConfig.getParameter>("puppiPriors"))), - puppiPriorsPhotons_(vd2vf(iConfig.getParameter>("puppiPriorsPhotons"))), - puppiPtSlopes_(vd2vf(iConfig.getParameter>("puppiPtSlopes"))), - puppiPtSlopesPhotons_(vd2vf(iConfig.getParameter>("puppiPtSlopesPhotons"))), - puppiPtZeros_(vd2vf(iConfig.getParameter>("puppiPtZeros"))), - puppiPtZerosPhotons_(vd2vf(iConfig.getParameter>("puppiPtZerosPhotons"))), - puppiAlphaSlopes_(vd2vf(iConfig.getParameter>("puppiAlphaSlopes"))), - puppiAlphaSlopesPhotons_(vd2vf(iConfig.getParameter>("puppiAlphaSlopesPhotons"))), - puppiAlphaZeros_(vd2vf(iConfig.getParameter>("puppiAlphaZeros"))), - puppiAlphaZerosPhotons_(vd2vf(iConfig.getParameter>("puppiAlphaZerosPhotons"))), - puppiAlphaCrops_(vd2vf(iConfig.getParameter>("puppiAlphaCrops"))), - puppiAlphaCropsPhotons_(vd2vf(iConfig.getParameter>("puppiAlphaCropsPhotons"))) { - if (puppiPriors_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiPriors\n"); - if (puppiPtSlopes_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiPtSlopes\n"); - if (puppiPtZeros_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiPtZeros\n"); - if (puppiAlphaSlopes_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaSlopes\n"); - if (puppiAlphaZeros_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaZeros\n"); - if (puppiAlphaCrops_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaCrops\n"); - if (puppiPriorsPhotons_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiPriorsPhotons\n"); - if (puppiPtSlopesPhotons_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiPtSlopesPhotons\n"); - if (puppiPtZerosPhotons_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiPtZerosPhotons\n"); - if (puppiAlphaSlopesPhotons_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaSlopesPhotons\n"); - if (puppiAlphaZerosPhotons_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaZerosPhotons\n"); - if (puppiAlphaCropsPhotons_.size() != puppiEtaCuts_.size()) - throw cms::Exception("Configuration", "Mismatched lenght for puppiAlphaCropsPhotons\n"); -} - -LinearizedPuppiAlgo::~LinearizedPuppiAlgo() {} - -const std::vector &LinearizedPuppiAlgo::puGlobalNames() const { - static const std::vector names_{}; - return names_; -} -void LinearizedPuppiAlgo::doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const { - globals.clear(); -} -void LinearizedPuppiAlgo::runNeutralsPU(Region &r, float npu, const std::vector &globals) const { - std::vector alphaC, alphaF; - PuppiAlgo::computePuppiAlphas(r, alphaC, alphaF); - computePuppiWeights(r, npu, alphaC, alphaF); - PuppiAlgo::fillPuppi(r); -} - -void LinearizedPuppiAlgo::computePuppiWeights(Region &r, - float npu, - const std::vector &alphaC, - const std::vector &alphaF) const { - if (debug_ && npu > 0) - dbgPrintf("LinPup\t npu estimate %7.2f --> log(npu/200) = %+6.2f \n", npu, std::log(npu / 200.f)); - for (unsigned int ip = 0, np = r.pf.size(); ip < np; ++ip) { - PFParticle &p = r.pf[ip]; - // charged - if (p.hwId == l1t::PFCandidate::ChargedHadron || p.hwId == l1t::PFCandidate::Electron || - p.hwId == l1t::PFCandidate::Muon) { - p.setPuppiW(p.chargedPV || p.hwId == l1t::PFCandidate::Muon ? 1.0 : 0); - if (debug_ == 2) - dbgPrintf( - "LinPup\t charged id %1d pt %7.2f eta %+5.2f phi %+5.2f fromPV %1d " - " --> puppi weight %.3f puppi pt %7.2f \n", - p.hwId, - p.floatPt(), - p.floatEta(), - p.floatPhi(), - p.chargedPV, - p.floatPuppiW(), - p.floatPt() * p.floatPuppiW()); - continue; - } - // neutral - float absEta = r.relativeCoordinates ? r.globalAbsEta(p.floatEta()) : std::abs(p.floatEta()); - bool central = absEta < etaCharged_; // FIXME could make a better integer implementation - bool photon = (p.hwId == l1t::PFCandidate::Photon); - // get alpha - float alpha = central ? alphaC[ip] : alphaF[ip]; - alpha = (alpha > 0 ? std::log(alpha) : 0); - // get eta bin - unsigned int ietaBin = 0, lastBin = puppiEtaCuts_.size() - 1; - while (ietaBin < lastBin && absEta > puppiEtaCuts_[ietaBin]) { - ietaBin++; - } - float alphaZero = (photon ? puppiAlphaZerosPhotons_ : puppiAlphaZeros_)[ietaBin]; - float alphaSlope = (photon ? puppiAlphaSlopesPhotons_ : puppiAlphaSlopes_)[ietaBin]; - float alphaCrop = (photon ? puppiAlphaCropsPhotons_ : puppiAlphaCrops_)[ietaBin]; - float x2a = std::clamp(alphaSlope * (alpha - alphaZero), -alphaCrop, alphaCrop); - // weight by pT - float ptZero = (photon ? puppiPtZerosPhotons_ : puppiPtZeros_)[ietaBin]; - float ptSlope = (photon ? puppiPtSlopesPhotons_ : puppiPtSlopes_)[ietaBin]; - float x2pt = ptSlope * (p.floatPt() - ptZero); - // weight by prior - float prior = (photon ? puppiPriorsPhotons_ : puppiPriors_)[ietaBin]; - float x2prior = (npu > 0 ? std::log(npu / 200.f) : 0) + prior; - // total - float x2 = x2a + x2pt - x2prior; - p.setPuppiW(1.0 / (1.0 + std::exp(-x2))); - if (debug_ == 1 || debug_ == 2 || debug_ == int(10 + ietaBin)) - dbgPrintf( - "LinPup\t neutral id %1d pt %7.2f eta %+5.2f phi %+5.2f alpha %+6.2f x2a %+5.2f x2pt %+6.2f x2prior " - "%+6.2f --> x2 %+6.2f --> puppi weight %.3f puppi pt %7.2f \n", - p.hwId, - p.floatPt(), - p.floatEta(), - p.floatPhi(), - alpha, - x2a, - x2pt, - -x2prior, - x2, - p.floatPuppiW(), - p.floatPt() * p.floatPuppiW()); - } -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo2HGC.cc b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo2HGC.cc deleted file mode 100644 index e5984288e9c4a..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo2HGC.cc +++ /dev/null @@ -1,650 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo2HGC.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" - -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" - -#include "FWCore/Utilities/interface/Exception.h" - -#include "DataFormats/Math/interface/deltaR.h" - -namespace { - template - float floatDR(const T1 &t1, const T2 &t2) { - return deltaR(t1.floatEta(), t1.floatPhi(), t2.floatEta(), t2.floatPhi()); - } -} // namespace - -using namespace l1tpf_impl; - -PFAlgo2HGC::PFAlgo2HGC(const edm::ParameterSet &iConfig) : PFAlgoBase(iConfig) { - debug_ = iConfig.getUntrackedParameter("debugPFAlgo2HGC", iConfig.getUntrackedParameter("debug", 0)); - edm::ParameterSet linkcfg = iConfig.getParameter("linking"); - drMatchMu_ = linkcfg.getParameter("trackMuDR"); - - std::string muMatchMode = linkcfg.getParameter("trackMuMatch"); - if (muMatchMode == "boxBestByPtRatio") - muMatchMode_ = MuMatchMode::BoxBestByPtRatio; - else if (muMatchMode == "drBestByPtRatio") - muMatchMode_ = MuMatchMode::DrBestByPtRatio; - else if (muMatchMode == "drBestByPtDiff") - muMatchMode_ = MuMatchMode::DrBestByPtDiff; - else - throw cms::Exception("Configuration", "bad value for trackMuMatch configurable"); - - std::string tkCaloLinkMetric = linkcfg.getParameter("trackCaloLinkMetric"); - if (tkCaloLinkMetric == "bestByDR") - tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDR; - else if (tkCaloLinkMetric == "bestByDRPt") - tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDRPt; - else if (tkCaloLinkMetric == "bestByDR2Pt2") - tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDR2Pt2; - else - throw cms::Exception("Configuration", "bad value for tkCaloLinkMetric configurable"); - - drMatch_ = linkcfg.getParameter("trackCaloDR"); - ptMatchLow_ = linkcfg.getParameter("trackCaloNSigmaLow"); - ptMatchHigh_ = linkcfg.getParameter("trackCaloNSigmaHigh"); - useTrackCaloSigma_ = linkcfg.getParameter("useTrackCaloSigma"); - maxInvisiblePt_ = linkcfg.getParameter("maxInvisiblePt"); - - caloReLinkStep_ = linkcfg.getParameter("caloReLink"); - caloReLinkDr_ = linkcfg.getParameter("caloReLinkDR"); - caloReLinkThreshold_ = linkcfg.getParameter("caloReLinkThreshold"); - rescaleTracks_ = linkcfg.getParameter("rescaleTracks"); - caloTrkWeightedAverage_ = linkcfg.getParameter("useCaloTrkWeightedAverage"); - sumTkCaloErr2_ = linkcfg.getParameter("sumTkCaloErr2"); - ecalPriority_ = linkcfg.getParameter("ecalPriority"); - tightTrackMinStubs_ = linkcfg.getParameter("tightTrackMinStubs"); - tightTrackMaxChi2_ = linkcfg.getParameter("tightTrackMaxChi2"); - tightTrackMaxInvisiblePt_ = linkcfg.getParameter("tightTrackMaxInvisiblePt"); -} - -void PFAlgo2HGC::runPF(Region &r) const { - initRegion(r); - - /// ------------- first step (can all go in parallel) ---------------- - - if (debug_) { - dbgPrintf( - "PFAlgo2HGC\nPFAlgo2HGC region eta [ %+5.2f , %+5.2f ], phi [ %+5.2f , %+5.2f ], fiducial eta [ %+5.2f , " - "%+5.2f ], phi [ %+5.2f , %+5.2f ]\n", - r.etaMin - r.etaExtra, - r.etaMax + r.etaExtra, - r.phiCenter - r.phiHalfWidth - r.phiExtra, - r.phiCenter + r.phiHalfWidth + r.phiExtra, - r.etaMin, - r.etaMax, - r.phiCenter - r.phiHalfWidth, - r.phiCenter + r.phiHalfWidth); - dbgPrintf( - "PFAlgo2HGC \t N(track) %3lu N(calo) %3lu N(mu) %3lu\n", r.track.size(), r.calo.size(), r.muon.size()); - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - const auto &tk = r.track[itk]; - dbgPrintf( - "PFAlgo2HGC \t track %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi " - "%+5.2f fid %1d calo ptErr %7.2f stubs %2d chi2 %7.1f\n", - itk, - tk.floatPt(), - tk.floatPtErr(), - tk.floatVtxEta(), - tk.floatVtxPhi(), - tk.floatEta(), - tk.floatPhi(), - int(r.fiducialLocal(tk.floatEta(), tk.floatPhi())), - tk.floatCaloPtErr(), - int(tk.hwStubs), - tk.hwChi2 * 0.1f); - } - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - dbgPrintf( - "PFAlgo2HGC \t calo %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi " - "%+5.2f fid %1d calo ptErr %7.2f em pt %7.2f isEM %1d \n", - ic, - calo.floatPt(), - calo.floatPtErr(), - calo.floatEta(), - calo.floatPhi(), - calo.floatEta(), - calo.floatPhi(), - int(r.fiducialLocal(calo.floatEta(), calo.floatPhi())), - calo.floatPtErr(), - calo.floatEmPt(), - calo.isEM); - } - for (int im = 0, nm = r.muon.size(); im < nm; ++im) { - auto &mu = r.muon[im]; - dbgPrintf( - "PFAlgo2HGC \t muon %3d: pt %7.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi " - "%+5.2f fid %1d\n", - im, - mu.floatPt(), - mu.floatEta(), - mu.floatPhi(), - mu.floatEta(), - mu.floatPhi(), - int(r.fiducialLocal(mu.floatEta(), mu.floatPhi()))); - } - } - - std::vector tk2mu(r.track.size(), -1), mu2tk(r.muon.size(), -1); - link_tk2mu(r, tk2mu, mu2tk); - - // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later) - std::vector tk2calo(r.track.size(), -1); - link_tk2calo(r, tk2calo); - - /// ------------- next step (needs the previous) ---------------- - // for each calo, compute the sum of the track pt - std::vector calo2ntk(r.calo.size(), 0); - std::vector calo2sumtkpt(r.calo.size(), 0); - std::vector calo2sumtkpterr(r.calo.size(), 0); - sum_tk2calo(r, tk2calo, calo2ntk, calo2sumtkpt, calo2sumtkpterr); - - // in the meantime, promote unlinked low pt tracks to hadrons - unlinkedtk_algo(r, tk2calo); - - /// ------------- next step (needs the previous) ---------------- - /// OPTIONAL STEP: try to recover split hadron showers (v1.0): - // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events - if (caloReLinkStep_) - calo_relink(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr); - - /// ------------- next step (needs the previous) ---------------- - // process matched calo clusters, compare energy to sum track pt - std::vector calo2alpha(r.calo.size(), 1); - linkedcalo_algo(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr, calo2alpha); - - /// ------------- next step (needs the previous) ---------------- - /// process matched tracks, if necessary rescale or average - linkedtk_algo(r, tk2calo, calo2ntk, calo2alpha); - // process unmatched calo clusters - unlinkedcalo_algo(r); - // finally do muons - save_muons(r, tk2mu); -} - -void PFAlgo2HGC::link_tk2mu(Region &r, std::vector &tk2mu, std::vector &mu2tk) const { - // do a rectangular match for the moment; make a box of the same are as a 0.2 cone - int intDrMuonMatchBox = std::ceil(drMatchMu_ * CaloCluster::ETAPHI_SCALE * std::sqrt(M_PI / 4)); - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - tk2mu[itk] = false; - } - for (int imu = 0, nmu = r.muon.size(); imu < nmu; ++imu) { - const auto &mu = r.muon[imu]; - if (debug_) - dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f, eta %+5.2f, phi %+5.2f) \n", - imu, - mu.floatPt(), - mu.floatEta(), - mu.floatPhi()); - float minDistance = 9e9; - switch (muMatchMode_) { - case MuMatchMode::BoxBestByPtRatio: - minDistance = 4.; - break; - case MuMatchMode::DrBestByPtRatio: - minDistance = 4.; - break; - case MuMatchMode::DrBestByPtDiff: - minDistance = 0.5 * mu.floatPt(); - break; - } - int imatch = -1; - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - const auto &tk = r.track[itk]; - int deta = std::abs(mu.hwEta - tk.hwEta); - int dphi = std::abs((mu.hwPhi - tk.hwPhi) % CaloCluster::PHI_WRAP); - float dr = floatDR(mu, tk); - float dpt = std::abs(mu.floatPt() - tk.floatPt()); - float dptr = (mu.hwPt > tk.hwPt ? mu.floatPt() / tk.floatPt() : tk.floatPt() / mu.floatPt()); - bool ok = false; - float distance = 9e9; - switch (muMatchMode_) { - case MuMatchMode::BoxBestByPtRatio: - ok = (deta < intDrMuonMatchBox) && (dphi < intDrMuonMatchBox); - distance = dptr; - break; - case MuMatchMode::DrBestByPtRatio: - ok = (dr < drMatchMu_); - distance = dptr; - break; - case MuMatchMode::DrBestByPtDiff: - ok = (dr < drMatchMu_); - distance = dpt; - break; - } - if (debug_ && dr < 0.4) { - dbgPrintf( - "PFAlgo2HGC \t\t possible match with track %3d (pt %7.2f, caloeta %+5.2f, calophi %+5.2f, dr %.2f, eta " - "%+5.2f, phi %+5.2f, dr %.2f): angular %1d, distance %.3f (vs %.3f)\n", - itk, - tk.floatPt(), - tk.floatEta(), - tk.floatPhi(), - dr, - tk.floatVtxEta(), - tk.floatVtxPhi(), - deltaR(mu.floatEta(), mu.floatPhi(), tk.floatVtxEta(), tk.floatVtxPhi()), - (ok ? 1 : 0), - distance, - minDistance); - } - if (!ok) - continue; - // FIXME for the moment, we do the floating point matching in pt - if (distance < minDistance) { - minDistance = distance; - imatch = itk; - } - } - if (debug_ && imatch > -1) - dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f) linked to track %3d (pt %7.2f)\n", - imu, - mu.floatPt(), - imatch, - r.track[imatch].floatPt()); - if (debug_ && imatch == -1) - dbgPrintf("PFAlgo2HGC \t muon %3d (pt %7.2f) not linked to any track\n", imu, mu.floatPt()); - mu2tk[imu] = imatch; - if (imatch > -1) { - tk2mu[imatch] = imu; - r.track[imatch].muonLink = true; - } - } -} - -void PFAlgo2HGC::link_tk2calo(Region &r, std::vector &tk2calo) const { - // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later) - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - const auto &tk = r.track[itk]; - if (tk.muonLink || tk.used) - continue; // not necessary but just a waste of CPU otherwise - float drbest = drMatch_, dptscale = 0; - switch (tkCaloLinkMetric_) { - case TkCaloLinkMetric::BestByDR: - drbest = drMatch_; - break; - case TkCaloLinkMetric::BestByDRPt: - drbest = 1.0; - dptscale = drMatch_ / tk.floatCaloPtErr(); - break; - case TkCaloLinkMetric::BestByDR2Pt2: - drbest = 1.0; - dptscale = drMatch_ / tk.floatCaloPtErr(); - break; - } - float minCaloPt = tk.floatPt() - ptMatchLow_ * tk.floatCaloPtErr(); - if (debug_) - dbgPrintf( - "PFAlgo2HGC \t track %3d (pt %7.2f) to be matched to calo, min pT %7.2f\n", itk, tk.floatPt(), minCaloPt); - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - if (calo.used || calo.floatPt() <= minCaloPt) - continue; - float dr = floatDR(tk, calo), dq; - switch (tkCaloLinkMetric_) { - case TkCaloLinkMetric::BestByDR: - if (dr < drbest) { - tk2calo[itk] = ic; - drbest = dr; - } - break; - case TkCaloLinkMetric::BestByDRPt: - dq = dr + std::max(tk.floatPt() - calo.floatPt(), 0.) * dptscale; - if (debug_ > 2 && dr < 0.3) - dbgPrintf("PFAlgo2HGC \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n", - itk, - tk.floatPt(), - ic, - calo.floatPt(), - dr, - dq); - if (dr < drMatch_ && dq < drbest) { - tk2calo[itk] = ic; - drbest = dq; - } - break; - case TkCaloLinkMetric::BestByDR2Pt2: - dq = hypot(dr, std::max(tk.floatPt() - calo.floatPt(), 0.) * dptscale); - if (debug_ > 2 && dr < 0.3) - dbgPrintf("PFAlgo2HGC \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n", - itk, - tk.floatPt(), - ic, - calo.floatPt(), - dr, - dq); - if (dr < drMatch_ && dq < drbest) { - tk2calo[itk] = ic; - drbest = dq; - } - break; - } - } - if (debug_ && tk2calo[itk] != -1) - dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) matches to calo %3d (pt %7.2f) with dist %.3f (dr %.3f)\n", - itk, - tk.floatPt(), - tk2calo[itk], - r.calo[tk2calo[itk]].floatPt(), - drbest, - floatDR(tk, r.calo[tk2calo[itk]])); - // now we re-do this for debugging sake, it may be done for real later - if (debug_ && tk2calo[itk] == -1) { - int ibest = -1; - drbest = 0.3; - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - if (calo.used) - continue; - float dr = floatDR(tk, calo); - if (dr < drbest) { - ibest = ic; - drbest = dr; - } - } - if (ibest != -1) - dbgPrintf( - "PFAlgo2HGC \t track %3d (pt %7.2f) would match to calo %3d (pt %7.2f) with dr %.3f if the pt min and dr " - "requirement had been relaxed\n", - itk, - tk.floatPt(), - ibest, - r.calo[ibest].floatPt(), - drbest); - } - } -} - -void PFAlgo2HGC::sum_tk2calo(Region &r, - const std::vector &tk2calo, - std::vector &calo2ntk, - std::vector &calo2sumtkpt, - std::vector &calo2sumtkpterr) const { - // for each calo, compute the sum of the track pt - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - const auto &calo = r.calo[ic]; - if (r.globalAbsEta(calo.floatEta()) > 2.5) - continue; - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - if (tk2calo[itk] == ic) { - const auto &tk = r.track[itk]; - if (tk.muonLink || tk.used) - continue; - calo2ntk[ic]++; - calo2sumtkpt[ic] += tk.floatPt(); - calo2sumtkpterr[ic] += std::pow(tk.floatCaloPtErr(), sumTkCaloErr2_ ? 2 : 1); - } - } - if (sumTkCaloErr2_ && calo2sumtkpterr[ic] > 0) - calo2sumtkpterr[ic] = std::sqrt(calo2sumtkpterr[ic]); - } -} - -void PFAlgo2HGC::unlinkedtk_algo(Region &r, const std::vector &tk2calo) const { - // in the meantime, promote unlinked low pt tracks to hadrons - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - auto &tk = r.track[itk]; - if (tk2calo[itk] != -1 || tk.muonLink || tk.used) - continue; - float maxPt = (tk.hwStubs >= tightTrackMinStubs_ && tk.hwChi2 < 10. * tightTrackMaxChi2_) - ? tightTrackMaxInvisiblePt_ - : maxInvisiblePt_; - if (tk.floatPt() < maxPt) { - if (debug_) - dbgPrintf( - "PFAlgo2HGC \t track %3d (pt %7.2f) not matched to calo, kept as charged hadron\n", itk, tk.floatPt()); - auto &p = addTrackToPF(r, tk); - p.hwStatus = GoodTK_NoCalo; - tk.used = true; - } else { - if (debug_) - dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) not matched to calo, dropped\n", itk, tk.floatPt()); - } - } -} - -void PFAlgo2HGC::calo_relink(Region &r, - const std::vector &calo2ntk, - const std::vector &calo2sumtkpt, - const std::vector &calo2sumtkpterr) const { - /// OPTIONAL STEP: try to recover split hadron showers (v1.0): - // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt - // add this pt to the calo pt of the other cluster - // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events - std::vector addtopt(r.calo.size(), 0); - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - if (calo2ntk[ic] != 0 || calo.used || r.globalAbsEta(calo.floatEta()) > 2.5) - continue; - int i2best = -1; - float drbest = caloReLinkDr_; - for (int ic2 = 0; ic2 < nc; ++ic2) { - const auto &calo2 = r.calo[ic2]; - if (calo2ntk[ic2] == 0 || calo2.used || r.globalAbsEta(calo2.floatEta()) > 2.5) - continue; - float dr = floatDR(calo, calo2); - //// uncomment below for more verbose debugging - //if (debug_ && dr < 0.5) dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) with no tracks is at dr %.3f from calo %3d with pt %7.2f (sum tk pt %7.2f), track excess %7.2f +- %7.2f\n", ic, calo.floatPt(), dr, ic2, calo2.floatPt(), calo2sumtkpt[ic2], calo2sumtkpt[ic2] - calo2.floatPt(), useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr()); - if (dr < drbest) { - float ptdiff = - calo2sumtkpt[ic2] - calo2.floatPt() + (useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr()); - if (ptdiff >= caloReLinkThreshold_ * calo.floatPt()) { - i2best = ic2; - drbest = dr; - } - } - } - if (i2best != -1) { - const auto &calo2 = r.calo[i2best]; - if (debug_) - dbgPrintf( - "PFAlgo2HGC \t calo %3d (pt %7.2f) with no tracks matched within dr %.3f with calo %3d with pt %7.2f (sum " - "tk pt %7.2f), track excess %7.2f +- %7.2f\n", - ic, - calo.floatPt(), - drbest, - i2best, - calo2.floatPt(), - calo2sumtkpt[i2best], - calo2sumtkpt[i2best] - calo2.floatPt(), - useTrackCaloSigma_ ? calo2sumtkpterr[i2best] : calo2.floatPtErr()); - calo.used = true; - addtopt[i2best] += calo.floatPt(); - } - } - // we do this at the end, so that the above loop is parallelizable - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - if (addtopt[ic]) { - auto &calo = r.calo[ic]; - if (debug_) - dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f, sum tk pt %7.2f) is increased to pt %7.2f after merging\n", - ic, - calo.floatPt(), - calo2sumtkpt[ic], - calo.floatPt() + addtopt[ic]); - calo.setFloatPt(calo.floatPt() + addtopt[ic]); - } - } -} - -void PFAlgo2HGC::linkedcalo_algo(Region &r, - const std::vector &calo2ntk, - const std::vector &calo2sumtkpt, - const std::vector &calo2sumtkpterr, - std::vector &calo2alpha) const { - /// ------------- next step (needs the previous) ---------------- - // process matched calo clusters, compare energy to sum track pt - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - if (calo2ntk[ic] == 0 || calo.used) - continue; - float ptdiff = calo.floatPt() - calo2sumtkpt[ic]; - float pterr = useTrackCaloSigma_ ? calo2sumtkpterr[ic] : calo.floatPtErr(); - if (debug_) - dbgPrintf( - "PFAlgo2HGC \t calo %3d (pt %7.2f +- %7.2f, empt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif " - "%7.2f +- %7.2f\n", - ic, - calo.floatPt(), - calo.floatPtErr(), - calo.floatEmPt(), - calo2ntk[ic], - calo2sumtkpt[ic], - calo2sumtkpterr[ic], - ptdiff, - pterr); - if (ptdiff > +ptMatchHigh_ * pterr) { - if (ecalPriority_) { - if (calo.floatEmPt() > 1) { - float emptdiff = std::min(ptdiff, calo.floatEmPt()); - if (debug_) - dbgPrintf( - "PFAlgo2HGC \t calo %3d (pt %7.2f, empt %7.2f) ---> make photon with pt %7.2f, reduce ptdiff to " - "%7.2f +- %7.2f\n", - ic, - calo.floatPt(), - calo.floatEmPt(), - emptdiff, - ptdiff - emptdiff, - pterr); - auto &p = addCaloToPF(r, calo); - p.setFloatPt(emptdiff); - p.hwId = l1t::PFCandidate::Photon; - ptdiff -= emptdiff; - } - if (ptdiff > 2) { - if (debug_) - dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f, empt %7.2f) ---> make also neutral hadron with pt %7.2f\n", - ic, - calo.floatPt(), - calo.floatEmPt(), - ptdiff); - auto &p = addCaloToPF(r, calo); - p.setFloatPt(ptdiff); - p.hwId = l1t::PFCandidate::NeutralHadron; - } - } else { - if (debug_) - dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> promoted to neutral with pt %7.2f\n", - ic, - calo.floatPt(), - ptdiff); - auto &p = addCaloToPF(r, calo); - p.setFloatPt(ptdiff); - calo.hwFlags = 0; - } - } else if (ptdiff > -ptMatchLow_ * pterr) { - // nothing to do (weighted average happens when we process the tracks) - calo.hwFlags = 1; - if (debug_) - dbgPrintf( - "PFAlgo2HGC \t calo %3d (pt %7.2f) ---> to be deleted, will use tracks instead\n", ic, calo.floatPt()); - } else { - // tracks overshoot, rescale to tracks to calo - calo2alpha[ic] = rescaleTracks_ ? calo.floatPt() / calo2sumtkpt[ic] : 1.0; - calo.hwFlags = 2; - if (debug_ && rescaleTracks_) - dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> tracks overshoot and will be scaled down by %.4f\n", - ic, - calo.floatPt(), - calo2alpha[ic]); - if (debug_ && !rescaleTracks_) - dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) ---> tracks overshoot by %.4f\n", - ic, - calo.floatPt(), - calo2sumtkpt[ic] / calo.floatPt()); - } - calo.used = true; - } -} - -void PFAlgo2HGC::linkedtk_algo(Region &r, - const std::vector &tk2calo, - const std::vector &calo2ntk, - const std::vector &calo2alpha) const { - // process matched tracks, if necessary rescale or average - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - auto &tk = r.track[itk]; - if (tk2calo[itk] == -1 || tk.muonLink || tk.used) - continue; - auto &p = addTrackToPF(r, tk); - tk.used = true; - const auto &calo = r.calo[tk2calo[itk]]; - if (calo.isEM) - p.hwId = l1t::PFCandidate::Electron; - p.cluster.src = calo.src; - if (calo.hwFlags == 1) { - // can do weighted average if there's just one track - if (calo2ntk[tk2calo[itk]] == 1 && caloTrkWeightedAverage_) { - p.hwStatus = GoodTK_Calo_TkPt; - float ptavg = tk.floatPt(); - if (tk.floatPtErr() > 0) { - float wcalo = 1.0 / std::pow(tk.floatCaloPtErr(), 2); - float wtk = 1.0 / std::pow(tk.floatPtErr(), 2); - ptavg = (calo.floatPt() * wcalo + tk.floatPt() * wtk) / (wcalo + wtk); - p.hwStatus = GoodTK_Calo_TkCaloPt; - } - p.setFloatPt(ptavg); - if (debug_) - dbgPrintf( - "PFAlgo2HGC \t track %3d (pt %7.2f +- %7.2f) combined with calo %3d (pt %7.2f +- %7.2f (from tk) " - "yielding candidate of pt %7.2f\n", - itk, - tk.floatPt(), - tk.floatPtErr(), - tk2calo[itk], - calo.floatPt(), - tk.floatCaloPtErr(), - ptavg); - } else { - p.hwStatus = GoodTK_Calo_TkPt; - if (debug_) - dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) linked to calo %3d promoted to %s\n", - itk, - tk.floatPt(), - tk2calo[itk], - (p.hwId == l1t::PFCandidate::Electron ? "electron" : "charged hadron")); - } - } else if (calo.hwFlags == 2) { - // must rescale - p.setFloatPt(tk.floatPt() * calo2alpha[tk2calo[itk]]); - p.hwStatus = GoodTk_Calo_CaloPt; - if (debug_) - dbgPrintf( - "PFAlgo2HGC \t track %3d (pt %7.2f, stubs %2d chi2 %7.1f) linked to calo %3d promoted to %s with pt %7.2f " - "after maybe rescaling\n", - itk, - tk.floatPt(), - int(tk.hwStubs), - tk.hwChi2 * 0.1f, - tk2calo[itk], - (p.hwId == l1t::PFCandidate::Electron ? "electron" : "charged hadron"), - p.floatPt()); - } - } -} - -void PFAlgo2HGC::unlinkedcalo_algo(Region &r) const { - // process unmatched calo clusters - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - if (!r.calo[ic].used) { - addCaloToPF(r, r.calo[ic]); - if (debug_) - dbgPrintf("PFAlgo2HGC \t calo %3d (pt %7.2f) not linked, promoted to neutral\n", ic, r.calo[ic].floatPt()); - } - } -} - -void PFAlgo2HGC::save_muons(Region &r, const std::vector &tk2mu) const { - // finally do muons - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - if (r.track[itk].muonLink) { - auto &p = addTrackToPF(r, r.track[itk]); - p.muonsrc = r.muon[tk2mu[itk]].src; - if (debug_) - dbgPrintf("PFAlgo2HGC \t track %3d (pt %7.2f) promoted to muon.\n", itk, r.track[itk].floatPt()); - } - } -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo3.cc b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo3.cc deleted file mode 100644 index 41402a431eb6e..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgo3.cc +++ /dev/null @@ -1,911 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgo3.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" - -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" - -#include "FWCore/Utilities/interface/Exception.h" - -#include "DataFormats/Math/interface/deltaR.h" - -namespace { - template - float floatDR(const T1 &t1, const T2 &t2) { - return deltaR(t1.floatEta(), t1.floatPhi(), t2.floatEta(), t2.floatPhi()); - } -} // namespace - -using namespace l1tpf_impl; - -PFAlgo3::PFAlgo3(const edm::ParameterSet &iConfig) : PFAlgoBase(iConfig) { - debug_ = iConfig.getUntrackedParameter("debugPFAlgo3", iConfig.getUntrackedParameter("debug", 0)); - edm::ParameterSet linkcfg = iConfig.getParameter("linking"); - drMatchMu_ = linkcfg.getParameter("trackMuDR"); - - std::string muMatchMode = linkcfg.getParameter("trackMuMatch"); - if (muMatchMode == "boxBestByPtRatio") - muMatchMode_ = MuMatchMode::BoxBestByPtRatio; - else if (muMatchMode == "drBestByPtRatio") - muMatchMode_ = MuMatchMode::DrBestByPtRatio; - else if (muMatchMode == "drBestByPtDiff") - muMatchMode_ = MuMatchMode::DrBestByPtDiff; - else - throw cms::Exception("Configuration", "bad value for trackMuMatch configurable"); - - std::string tkCaloLinkMetric = linkcfg.getParameter("trackCaloLinkMetric"); - if (tkCaloLinkMetric == "bestByDR") - tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDR; - else if (tkCaloLinkMetric == "bestByDRPt") - tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDRPt; - else if (tkCaloLinkMetric == "bestByDR2Pt2") - tkCaloLinkMetric_ = TkCaloLinkMetric::BestByDR2Pt2; - else - throw cms::Exception("Configuration", "bad value for tkCaloLinkMetric configurable"); - - drMatch_ = linkcfg.getParameter("trackCaloDR"); - ptMatchLow_ = linkcfg.getParameter("trackCaloNSigmaLow"); - ptMatchHigh_ = linkcfg.getParameter("trackCaloNSigmaHigh"); - useTrackCaloSigma_ = linkcfg.getParameter("useTrackCaloSigma"); - maxInvisiblePt_ = linkcfg.getParameter("maxInvisiblePt"); - - drMatchEm_ = linkcfg.getParameter("trackEmDR"); - trackEmUseAlsoTrackSigma_ = linkcfg.getParameter("trackEmUseAlsoTrackSigma"); - trackEmMayUseCaloMomenta_ = linkcfg.getParameter("trackEmMayUseCaloMomenta"); - emCaloUseAlsoCaloSigma_ = linkcfg.getParameter("emCaloUseAlsoCaloSigma"); - ptMinFracMatchEm_ = linkcfg.getParameter("caloEmPtMinFrac"); - drMatchEmHad_ = linkcfg.getParameter("emCaloDR"); - emHadSubtractionPtSlope_ = linkcfg.getParameter("emCaloSubtractionPtSlope"); - caloReLinkStep_ = linkcfg.getParameter("caloReLink"); - caloReLinkDr_ = linkcfg.getParameter("caloReLinkDR"); - caloReLinkThreshold_ = linkcfg.getParameter("caloReLinkThreshold"); - rescaleTracks_ = linkcfg.getParameter("rescaleTracks"); - caloTrkWeightedAverage_ = linkcfg.getParameter("useCaloTrkWeightedAverage"); - sumTkCaloErr2_ = linkcfg.getParameter("sumTkCaloErr2"); - ecalPriority_ = linkcfg.getParameter("ecalPriority"); - tightTrackMinStubs_ = linkcfg.getParameter("tightTrackMinStubs"); - tightTrackMaxChi2_ = linkcfg.getParameter("tightTrackMaxChi2"); - tightTrackMaxInvisiblePt_ = linkcfg.getParameter("tightTrackMaxInvisiblePt"); -} - -void PFAlgo3::runPF(Region &r) const { - initRegion(r); - - /// ------------- first step (can all go in parallel) ---------------- - - if (debug_) { - dbgPrintf( - "PFAlgo3\nPFAlgo3 region eta [ %+5.2f , %+5.2f ], phi [ %+5.2f , %+5.2f ], fiducial eta [ %+5.2f , %+5.2f ], " - "phi [ %+5.2f , %+5.2f ]\n", - r.etaMin - r.etaExtra, - r.etaMax + r.etaExtra, - r.phiCenter - r.phiHalfWidth - r.phiExtra, - r.phiCenter + r.phiHalfWidth + r.phiExtra, - r.etaMin, - r.etaMax, - r.phiCenter - r.phiHalfWidth, - r.phiCenter + r.phiHalfWidth); - dbgPrintf("PFAlgo3 \t N(track) %3lu N(em) %3lu N(calo) %3lu N(mu) %3lu\n", - r.track.size(), - r.emcalo.size(), - r.calo.size(), - r.muon.size()); - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - const auto &tk = r.track[itk]; - dbgPrintf( - "PFAlgo3 \t track %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - "fid %1d calo ptErr %7.2f stubs %2d chi2 %7.1f\n", - itk, - tk.floatPt(), - tk.floatPtErr(), - tk.floatVtxEta(), - tk.floatVtxPhi(), - tk.floatEta(), - tk.floatPhi(), - int(r.fiducialLocal(tk.floatEta(), tk.floatPhi())), - tk.floatCaloPtErr(), - int(tk.hwStubs), - tk.hwChi2 * 0.1f); - } - for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { - const auto &em = r.emcalo[iem]; - dbgPrintf( - "PFAlgo3 \t EM %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - "fid %1d calo ptErr %7.2f\n", - iem, - em.floatPt(), - em.floatPtErr(), - em.floatEta(), - em.floatPhi(), - em.floatEta(), - em.floatPhi(), - int(r.fiducialLocal(em.floatEta(), em.floatPhi())), - em.floatPtErr()); - } - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - dbgPrintf( - "PFAlgo3 \t calo %3d: pt %7.2f +- %5.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - "fid %1d calo ptErr %7.2f em pt %7.2f \n", - ic, - calo.floatPt(), - calo.floatPtErr(), - calo.floatEta(), - calo.floatPhi(), - calo.floatEta(), - calo.floatPhi(), - int(r.fiducialLocal(calo.floatEta(), calo.floatPhi())), - calo.floatPtErr(), - calo.floatEmPt()); - } - for (int im = 0, nm = r.muon.size(); im < nm; ++im) { - auto &mu = r.muon[im]; - dbgPrintf( - "PFAlgo3 \t muon %3d: pt %7.2f vtx eta %+5.2f vtx phi %+5.2f calo eta %+5.2f calo phi %+5.2f " - "fid %1d \n", - im, - mu.floatPt(), - mu.floatEta(), - mu.floatPhi(), - mu.floatEta(), - mu.floatPhi(), - int(r.fiducialLocal(mu.floatEta(), mu.floatPhi()))); - } - } - - std::vector tk2mu(r.track.size(), -1), mu2tk(r.muon.size(), -1); - link_tk2mu(r, tk2mu, mu2tk); - - // match all tracks to the closest EM cluster - std::vector tk2em(r.track.size(), -1); - link_tk2em(r, tk2em); - - // match all em to the closest had (can happen in parallel to the above) - std::vector em2calo(r.emcalo.size(), -1); - link_em2calo(r, em2calo); - - /// ------------- next step (needs the previous) ---------------- - // for each EM cluster, count and add up the pt of all the corresponding tracks (skipping muons) - std::vector em2ntk(r.emcalo.size(), 0); - std::vector em2sumtkpt(r.emcalo.size(), 0); - std::vector em2sumtkpterr(r.emcalo.size(), 0); - sum_tk2em(r, tk2em, em2ntk, em2sumtkpt, em2sumtkpterr); - - /// ------------- next step (needs the previous) ---------------- - // process ecal clusters after linking - emcalo_algo(r, em2ntk, em2sumtkpt, em2sumtkpterr); - - /// ------------- next step (needs the previous) ---------------- - // promote all flagged tracks to electrons - emtk_algo(r, tk2em, em2ntk, em2sumtkpterr); - sub_em2calo(r, em2calo); - - /// ------------- next step (needs the previous) ---------------- - // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later) - std::vector tk2calo(r.track.size(), -1); - link_tk2calo(r, tk2calo); - - /// ------------- next step (needs the previous) ---------------- - // for each calo, compute the sum of the track pt - std::vector calo2ntk(r.calo.size(), 0); - std::vector calo2sumtkpt(r.calo.size(), 0); - std::vector calo2sumtkpterr(r.calo.size(), 0); - sum_tk2calo(r, tk2calo, calo2ntk, calo2sumtkpt, calo2sumtkpterr); - - // in the meantime, promote unlinked low pt tracks to hadrons - unlinkedtk_algo(r, tk2calo); - - /// ------------- next step (needs the previous) ---------------- - /// OPTIONAL STEP: try to recover split hadron showers (v1.0): - // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events - if (caloReLinkStep_) - calo_relink(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr); - - /// ------------- next step (needs the previous) ---------------- - // process matched calo clusters, compare energy to sum track pt - std::vector calo2alpha(r.calo.size(), 1); - linkedcalo_algo(r, calo2ntk, calo2sumtkpt, calo2sumtkpterr, calo2alpha); - - /// ------------- next step (needs the previous) ---------------- - /// process matched tracks, if necessary rescale or average - linkedtk_algo(r, tk2calo, calo2ntk, calo2alpha); - // process unmatched calo clusters - unlinkedcalo_algo(r); - // finally do muons - save_muons(r, tk2mu); -} - -void PFAlgo3::link_tk2mu(Region &r, std::vector &tk2mu, std::vector &mu2tk) const { - // do a rectangular match for the moment; make a box of the same are as a 0.2 cone - int intDrMuonMatchBox = std::ceil(drMatchMu_ * CaloCluster::ETAPHI_SCALE * std::sqrt(M_PI / 4)); - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - tk2mu[itk] = false; - } - for (int imu = 0, nmu = r.muon.size(); imu < nmu; ++imu) { - const auto &mu = r.muon[imu]; - if (debug_) - dbgPrintf( - "PFAlgo3 \t muon %3d (pt %7.2f, eta %+5.2f, phi %+5.2f) \n", imu, mu.floatPt(), mu.floatEta(), mu.floatPhi()); - float minDistance = 9e9; - switch (muMatchMode_) { - case MuMatchMode::BoxBestByPtRatio: - minDistance = 4.; - break; - case MuMatchMode::DrBestByPtRatio: - minDistance = 4.; - break; - case MuMatchMode::DrBestByPtDiff: - minDistance = 0.5 * mu.floatPt(); - break; - } - int imatch = -1; - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - const auto &tk = r.track[itk]; - int deta = std::abs(mu.hwEta - tk.hwEta); - int dphi = std::abs((mu.hwPhi - tk.hwPhi) % CaloCluster::PHI_WRAP); - float dr = floatDR(mu, tk); - float dpt = std::abs(mu.floatPt() - tk.floatPt()); - float dptr = (mu.hwPt > tk.hwPt ? mu.floatPt() / tk.floatPt() : tk.floatPt() / mu.floatPt()); - bool ok = false; - float distance = 9e9; - switch (muMatchMode_) { - case MuMatchMode::BoxBestByPtRatio: - ok = (deta < intDrMuonMatchBox) && (dphi < intDrMuonMatchBox); - distance = dptr; - break; - case MuMatchMode::DrBestByPtRatio: - ok = (dr < drMatchMu_); - distance = dptr; - break; - case MuMatchMode::DrBestByPtDiff: - ok = (dr < drMatchMu_); - distance = dpt; - break; - } - if (debug_ && dr < 0.4) { - dbgPrintf( - "PFAlgo3 \t\t possible match with track %3d (pt %7.2f, caloeta %+5.2f, calophi %+5.2f, dr %.2f, eta " - "%+5.2f, phi %+5.2f, dr %.2f): angular %1d, distance %.3f (vs %.3f)\n", - itk, - tk.floatPt(), - tk.floatEta(), - tk.floatPhi(), - dr, - tk.floatVtxEta(), - tk.floatVtxPhi(), - deltaR(mu.floatEta(), mu.floatPhi(), tk.floatVtxEta(), tk.floatVtxPhi()), - (ok ? 1 : 0), - distance, - minDistance); - } - if (!ok) - continue; - // FIXME for the moment, we do the floating point matching in pt - if (distance < minDistance) { - minDistance = distance; - imatch = itk; - } - } - if (debug_ && imatch > -1) - dbgPrintf("PFAlgo3 \t muon %3d (pt %7.2f) linked to track %3d (pt %7.2f)\n", - imu, - mu.floatPt(), - imatch, - r.track[imatch].floatPt()); - if (debug_ && imatch == -1) - dbgPrintf("PFAlgo3 \t muon %3d (pt %7.2f) not linked to any track\n", imu, mu.floatPt()); - mu2tk[imu] = imatch; - if (imatch > -1) { - tk2mu[imatch] = imu; - r.track[imatch].muonLink = true; - } - } -} - -void PFAlgo3::link_tk2em(Region &r, std::vector &tk2em) const { - // match all tracks to the closest EM cluster - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - const auto &tk = r.track[itk]; - //if (tk.muonLink) continue; // not necessary I think - float drbest = drMatchEm_; - for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { - const auto &em = r.emcalo[iem]; - float dr = floatDR(tk, em); - if (dr < drbest) { - tk2em[itk] = iem; - drbest = dr; - } - } - if (debug_ && tk2em[itk] != -1) - dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) matches to EM %3d (pt %7.2f) with dr %.3f\n", - itk, - tk.floatPt(), - tk2em[itk], - tk2em[itk] == -1 ? 0.0 : r.emcalo[tk2em[itk]].floatPt(), - drbest); - } -} - -void PFAlgo3::link_em2calo(Region &r, std::vector &em2calo) const { - // match all em to the closest had (can happen in parallel to the above) - for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { - const auto &em = r.emcalo[iem]; - float drbest = drMatchEmHad_; - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - const auto &calo = r.calo[ic]; - if (calo.floatEmPt() < ptMinFracMatchEm_ * em.floatPt()) - continue; - float dr = floatDR(calo, em); - if (dr < drbest) { - em2calo[iem] = ic; - drbest = dr; - } - } - if (debug_ && em2calo[iem] != -1) - dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) matches to calo %3d (pt %7.2f, empt %7.2f) with dr %.3f\n", - iem, - em.floatPt(), - em2calo[iem], - em2calo[iem] == -1 ? 0.0 : r.calo[em2calo[iem]].floatPt(), - em2calo[iem] == -1 ? 0.0 : r.calo[em2calo[iem]].floatEmPt(), - drbest); - } -} - -void PFAlgo3::sum_tk2em(Region &r, - const std::vector &tk2em, - std::vector &em2ntk, - std::vector &em2sumtkpt, - std::vector &em2sumtkpterr) const { - // for each EM cluster, count and add up the pt of all the corresponding tracks (skipping muons) - for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { - const auto &em = r.emcalo[iem]; - if (r.globalAbsEta(em.floatEta()) > 2.5) - continue; - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - if (tk2em[itk] == iem) { - const auto &tk = r.track[itk]; - if (tk.muonLink) - continue; - em2ntk[iem]++; - em2sumtkpt[iem] += tk.floatPt(); - em2sumtkpterr[iem] += tk.floatPtErr(); - } - } - } -} - -void PFAlgo3::emcalo_algo(Region &r, - const std::vector &em2ntk, - const std::vector &em2sumtkpt, - const std::vector &em2sumtkpterr) const { - // process ecal clusters after linking - for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { - auto &em = r.emcalo[iem]; - em.isEM = false; - em.used = false; - em.hwFlags = 0; - if (r.globalAbsEta(em.floatEta()) > 2.5) - continue; - if (debug_) - dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif %7.2f +- %7.2f\n", - iem, - em.floatPt(), - em2ntk[iem], - em2sumtkpt[iem], - em2sumtkpterr[iem], - em.floatPt() - em2sumtkpt[iem], - std::max(em2sumtkpterr[iem], em.floatPtErr())); - if (em2ntk[iem] == 0) { // Photon - em.isEM = true; - addCaloToPF(r, em); - em.used = true; - if (debug_) - dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to photon\n", iem, em.floatPt()); - continue; - } - float ptdiff = em.floatPt() - em2sumtkpt[iem]; - float pterr = trackEmUseAlsoTrackSigma_ ? std::max(em2sumtkpterr[iem], em.floatPtErr()) : em.floatPtErr(); - // avoid "pt = inf +- inf" track to become an electron. - if (pterr > 2 * em.floatPt()) { - pterr = 2 * em.floatPt(); - if (debug_) - dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) ---> clamp pterr ---> new ptdiff %7.2f +- %7.2f\n", - iem, - em.floatPt(), - ptdiff, - pterr); - } - - if (ptdiff > -ptMatchLow_ * pterr) { - em.isEM = true; - em.used = true; - // convert leftover to a photon if significant - if (ptdiff > +ptMatchHigh_ * pterr) { - auto &p = addCaloToPF(r, em); - p.setFloatPt(ptdiff); - if (debug_) - dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to electron(s) + photon (pt %7.2f)\n", - iem, - em.floatPt(), - ptdiff); - } else { - em.hwFlags = 1; // may use calo momentum - if (debug_) - dbgPrintf("PFAlgo3 \t EM %3d (pt %7.2f) ---> promoted to electron(s)\n", iem, em.floatPt()); - } - } else { - em.isEM = false; - em.used = false; - em.hwFlags = 0; - //discardCalo(r, em, 2); - } - } -} - -void PFAlgo3::emtk_algo(Region &r, - const std::vector &tk2em, - const std::vector &em2ntk, - const std::vector &em2sumtkpterr) const { - // promote all flagged tracks to electrons - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - auto &tk = r.track[itk]; - if (tk2em[itk] == -1 || tk.muonLink) - continue; - const auto &em = r.emcalo[tk2em[itk]]; - if (em.isEM) { - auto &p = addTrackToPF(r, tk); - p.cluster.src = em.src; - // FIXME to check if this is useful - if (trackEmMayUseCaloMomenta_ && em2ntk[tk2em[itk]] == 1 && em.hwFlags == 1) { - if (em.floatPtErr() < em2sumtkpterr[tk2em[itk]]) { - p.setFloatPt(em.floatPt()); - } - } - if (debug_) - dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) matched to EM %3d (pt %7.2f) promoted to electron with pt %7.2f\n", - itk, - tk.floatPt(), - tk2em[itk], - em.floatPt(), - p.floatPt()); - p.hwId = l1t::PFCandidate::Electron; - tk.used = true; - } - } -} - -void PFAlgo3::sub_em2calo(Region &r, const std::vector &em2calo) const { - // subtract EM component from Calo clusters for all photons and electrons (within tracker coverage) - // kill clusters that end up below their own uncertainty, or that loose 90% of the energy, - // unless they still have live EM clusters pointing to them - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - float pt0 = calo.floatPt(), ept0 = calo.floatEmPt(), pt = pt0, ept = ept0; - bool keepme = false; - for (int iem = 0, nem = r.emcalo.size(); iem < nem; ++iem) { - if (em2calo[iem] == ic) { - const auto &em = r.emcalo[iem]; - if (em.isEM) { - if (debug_) - dbgPrintf( - "PFAlgo3 \t EM %3d (pt %7.2f) is subtracted from calo %3d (pt %7.2f) scaled by %.3f (deltaPt = " - "%7.2f)\n", - iem, - em.floatPt(), - ic, - calo.floatPt(), - emHadSubtractionPtSlope_, - emHadSubtractionPtSlope_ * em.floatPt()); - pt -= emHadSubtractionPtSlope_ * em.floatPt(); - ept -= em.floatPt(); - } else { - keepme = true; - if (debug_) - dbgPrintf( - "PFAlgo3 \t EM %3d (pt %7.2f) not subtracted from calo %3d (pt %7.2f), and calo marked to be kept " - "after EM subtraction\n", - iem, - em.floatPt(), - ic, - calo.floatPt()); - } - } - } - if (pt < pt0) { - if (debug_) - dbgPrintf( - "PFAlgo3 \t calo %3d (pt %7.2f +- %7.2f) has a subtracted pt of %7.2f, empt %7.2f -> %7.2f, isem %d\n", - ic, - calo.floatPt(), - calo.floatPtErr(), - pt, - ept0, - ept, - calo.isEM); - calo.setFloatPt(pt); - calo.setFloatEmPt(ept); - if (!keepme && - ((emCaloUseAlsoCaloSigma_ ? pt < calo.floatPtErr() : false) || pt <= 0.125 * pt0 || - (calo.isEM && ept <= 0.125 * ept0))) { // the <= is important since in firmware the pt0/8 can be zero - if (debug_) - dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) ----> discarded\n", ic, calo.floatPt()); - calo.used = true; - calo.setFloatPt(pt0); //discardCalo(r, calo, 1); // log this as discarded, for debugging - } - } - } -} - -void PFAlgo3::link_tk2calo(Region &r, std::vector &tk2calo) const { - // track to calo matching (first iteration, with a lower bound on the calo pt; there may be another one later) - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - const auto &tk = r.track[itk]; - if (tk.muonLink || tk.used) - continue; // not necessary but just a waste of CPU otherwise - float drbest = drMatch_, dptscale = 0; - switch (tkCaloLinkMetric_) { - case TkCaloLinkMetric::BestByDR: - drbest = drMatch_; - break; - case TkCaloLinkMetric::BestByDRPt: - drbest = 1.0; - dptscale = drMatch_ / tk.floatCaloPtErr(); - break; - case TkCaloLinkMetric::BestByDR2Pt2: - drbest = 1.0; - dptscale = drMatch_ / tk.floatCaloPtErr(); - break; - } - float minCaloPt = tk.floatPt() - ptMatchLow_ * tk.floatCaloPtErr(); - if (debug_) - dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) to be matched to calo, min pT %7.2f\n", itk, tk.floatPt(), minCaloPt); - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - if (calo.used || calo.floatPt() <= minCaloPt) - continue; - float dr = floatDR(tk, calo), dq; - switch (tkCaloLinkMetric_) { - case TkCaloLinkMetric::BestByDR: - if (dr < drbest) { - tk2calo[itk] = ic; - drbest = dr; - } - break; - case TkCaloLinkMetric::BestByDRPt: - dq = dr + std::max(tk.floatPt() - calo.floatPt(), 0.) * dptscale; - //if (debug_ && dr < 0.2) dbgPrintf("PFAlgo3 \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n", itk, tk.floatPt(), ic, calo.floatPt(), dr, dq); - if (dr < drMatch_ && dq < drbest) { - tk2calo[itk] = ic; - drbest = dq; - } - break; - case TkCaloLinkMetric::BestByDR2Pt2: - dq = hypot(dr, std::max(tk.floatPt() - calo.floatPt(), 0.) * dptscale); - //if (debug_ && dr < 0.2) dbgPrintf("PFAlgo3 \t\t\t track %3d (pt %7.2f) vs calo %3d (pt %7.2f): dr %.3f, dq %.3f\n", itk, tk.floatPt(), ic, calo.floatPt(), dr, dq); - if (dr < drMatch_ && dq < drbest) { - tk2calo[itk] = ic; - drbest = dq; - } - break; - } - } - if (debug_ && tk2calo[itk] != -1) - dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) matches to calo %3d (pt %7.2f) with dist %.3f\n", - itk, - tk.floatPt(), - tk2calo[itk], - tk2calo[itk] == -1 ? 0.0 : r.calo[tk2calo[itk]].floatPt(), - drbest); - // now we re-do this for debugging sake, it may be done for real later - if (debug_ && tk2calo[itk] == -1) { - int ibest = -1; - drbest = 0.3; - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - if (calo.used) - continue; - float dr = floatDR(tk, calo); - if (dr < drbest) { - ibest = ic; - drbest = dr; - } - } - if (ibest != -1) - dbgPrintf( - "PFAlgo3 \t track %3d (pt %7.2f) would match to calo %3d (pt %7.2f) with dr %.3f if the pt min and dr " - "requirement had been relaxed\n", - itk, - tk.floatPt(), - ibest, - r.calo[ibest].floatPt(), - drbest); - } - } -} - -void PFAlgo3::sum_tk2calo(Region &r, - const std::vector &tk2calo, - std::vector &calo2ntk, - std::vector &calo2sumtkpt, - std::vector &calo2sumtkpterr) const { - // for each calo, compute the sum of the track pt - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - const auto &calo = r.calo[ic]; - if (r.globalAbsEta(calo.floatEta()) > 2.5) - continue; - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - if (tk2calo[itk] == ic) { - const auto &tk = r.track[itk]; - if (tk.muonLink || tk.used) - continue; - calo2ntk[ic]++; - calo2sumtkpt[ic] += tk.floatPt(); - calo2sumtkpterr[ic] += std::pow(tk.floatCaloPtErr(), sumTkCaloErr2_ ? 2 : 1); - } - } - if (sumTkCaloErr2_ && calo2sumtkpterr[ic] > 0) - calo2sumtkpterr[ic] = std::sqrt(calo2sumtkpterr[ic]); - } -} - -void PFAlgo3::unlinkedtk_algo(Region &r, const std::vector &tk2calo) const { - // in the meantime, promote unlinked low pt tracks to hadrons - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - auto &tk = r.track[itk]; - if (tk2calo[itk] != -1 || tk.muonLink || tk.used) - continue; - float maxPt = (tk.hwStubs >= tightTrackMinStubs_ && tk.hwChi2 < 10 * tightTrackMaxChi2_) ? tightTrackMaxInvisiblePt_ - : maxInvisiblePt_; - if (tk.floatPt() < maxPt) { - if (debug_) - dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) not matched to calo, kept as charged hadron\n", itk, tk.floatPt()); - auto &p = addTrackToPF(r, tk); - p.hwStatus = GoodTK_NoCalo; - tk.used = true; - } else { - if (debug_) - dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) not matched to calo, dropped\n", itk, tk.floatPt()); - //discardTrack(r, tk, BadTK_NoCalo); // log this as discarded, for debugging - } - } -} - -void PFAlgo3::calo_relink(Region &r, - const std::vector &calo2ntk, - const std::vector &calo2sumtkpt, - const std::vector &calo2sumtkpterr) const { - /// OPTIONAL STEP: try to recover split hadron showers (v1.0): - // take hadrons that are not track matched, close by a hadron which has an excess of track pt vs calo pt - // add this pt to the calo pt of the other cluster - // off by default, as it seems to not do much in jets even if it helps remove tails in single-pion events - std::vector addtopt(r.calo.size(), 0); - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - if (calo2ntk[ic] != 0 || calo.used || r.globalAbsEta(calo.floatEta()) > 2.5) - continue; - int i2best = -1; - float drbest = caloReLinkDr_; - for (int ic2 = 0; ic2 < nc; ++ic2) { - const auto &calo2 = r.calo[ic2]; - if (calo2ntk[ic2] == 0 || calo2.used || r.globalAbsEta(calo2.floatEta()) > 2.5) - continue; - float dr = floatDR(calo, calo2); - //// uncomment below for more verbose debugging - //if (debug_ && dr < 0.5) dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) with no tracks is at dr %.3f from calo %3d with pt %7.2f (sum tk pt %7.2f), track excess %7.2f +- %7.2f\n", ic, calo.floatPt(), dr, ic2, calo2.floatPt(), calo2sumtkpt[ic2], calo2sumtkpt[ic2] - calo2.floatPt(), useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr()); - if (dr < drbest) { - float ptdiff = - calo2sumtkpt[ic2] - calo2.floatPt() + (useTrackCaloSigma_ ? calo2sumtkpterr[ic2] : calo2.floatPtErr()); - if (ptdiff >= caloReLinkThreshold_ * calo.floatPt()) { - i2best = ic2; - drbest = dr; - } - } - } - if (i2best != -1) { - const auto &calo2 = r.calo[i2best]; - if (debug_) - dbgPrintf( - "PFAlgo3 \t calo %3d (pt %7.2f) with no tracks matched within dr %.3f with calo %3d with pt %7.2f (sum tk " - "pt %7.2f), track excess %7.2f +- %7.2f\n", - ic, - calo.floatPt(), - drbest, - i2best, - calo2.floatPt(), - calo2sumtkpt[i2best], - calo2sumtkpt[i2best] - calo2.floatPt(), - useTrackCaloSigma_ ? calo2sumtkpterr[i2best] : calo2.floatPtErr()); - calo.used = true; - addtopt[i2best] += calo.floatPt(); - } - } - // we do this at the end, so that the above loop is parallelizable - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - if (addtopt[ic]) { - auto &calo = r.calo[ic]; - if (debug_) - dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f, sum tk pt %7.2f) is increased to pt %7.2f after merging\n", - ic, - calo.floatPt(), - calo2sumtkpt[ic], - calo.floatPt() + addtopt[ic]); - calo.setFloatPt(calo.floatPt() + addtopt[ic]); - } - } -} - -void PFAlgo3::linkedcalo_algo(Region &r, - const std::vector &calo2ntk, - const std::vector &calo2sumtkpt, - const std::vector &calo2sumtkpterr, - std::vector &calo2alpha) const { - /// ------------- next step (needs the previous) ---------------- - // process matched calo clusters, compare energy to sum track pt - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - auto &calo = r.calo[ic]; - if (calo2ntk[ic] == 0 || calo.used) - continue; - float ptdiff = calo.floatPt() - calo2sumtkpt[ic]; - float pterr = useTrackCaloSigma_ ? calo2sumtkpterr[ic] : calo.floatPtErr(); - if (debug_) - dbgPrintf( - "PFAlgo3 \t calo %3d (pt %7.2f +- %7.2f, empt %7.2f) has %2d tracks (sumpt %7.2f, sumpterr %7.2f), ptdif " - "%7.2f +- %7.2f\n", - ic, - calo.floatPt(), - calo.floatPtErr(), - calo.floatEmPt(), - calo2ntk[ic], - calo2sumtkpt[ic], - calo2sumtkpterr[ic], - ptdiff, - pterr); - if (ptdiff > +ptMatchHigh_ * pterr) { - if (ecalPriority_) { - if (calo.floatEmPt() > 1) { - float emptdiff = std::min(ptdiff, calo.floatEmPt()); - if (debug_) - dbgPrintf( - "PFAlgo3 \t calo %3d (pt %7.2f, empt %7.2f) ---> make photon with pt %7.2f, reduce ptdiff to %7.2f " - "+- %7.2f\n", - ic, - calo.floatPt(), - calo.floatEmPt(), - emptdiff, - ptdiff - emptdiff, - pterr); - auto &p = addCaloToPF(r, calo); - p.setFloatPt(emptdiff); - p.hwId = l1t::PFCandidate::Photon; - ptdiff -= emptdiff; - } - if (ptdiff > 2) { - if (debug_) - dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f, empt %7.2f) ---> make also neutral hadron with pt %7.2f\n", - ic, - calo.floatPt(), - calo.floatEmPt(), - ptdiff); - auto &p = addCaloToPF(r, calo); - p.setFloatPt(ptdiff); - p.hwId = l1t::PFCandidate::NeutralHadron; - } - } else { - if (debug_) - dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) ---> promoted to neutral with pt %7.2f\n", - ic, - calo.floatPt(), - ptdiff); - auto &p = addCaloToPF(r, calo); - p.setFloatPt(ptdiff); - calo.hwFlags = 0; - } - } else if (ptdiff > -ptMatchLow_ * pterr) { - // nothing to do (weighted average happens when we process the tracks) - calo.hwFlags = 1; - if (debug_) - dbgPrintf( - "PFAlgo3 \t calo %3d (pt %7.2f) ---> to be deleted, will use tracks instead\n", ic, calo.floatPt()); - //discardCalo(r, calo, 0); // log this as discarded, for debugging - } else { - // tracks overshoot, rescale to tracks to calo - calo2alpha[ic] = rescaleTracks_ ? calo.floatPt() / calo2sumtkpt[ic] : 1.0; - calo.hwFlags = 2; - if (debug_ && rescaleTracks_) - dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) ---> tracks overshoot and will be scaled down by %.4f\n", - ic, - calo.floatPt(), - calo2alpha[ic]); - if (debug_ && !rescaleTracks_) - dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) ---> tracks overshoot by %.4f\n", - ic, - calo.floatPt(), - calo2sumtkpt[ic] / calo.floatPt()); - } - calo.used = true; - } -} - -void PFAlgo3::linkedtk_algo(Region &r, - const std::vector &tk2calo, - const std::vector &calo2ntk, - const std::vector &calo2alpha) const { - // process matched tracks, if necessary rescale or average - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - auto &tk = r.track[itk]; - if (tk2calo[itk] == -1 || tk.muonLink || tk.used) - continue; - auto &p = addTrackToPF(r, tk); - tk.used = true; - const auto &calo = r.calo[tk2calo[itk]]; - p.cluster.src = calo.src; - if (calo.hwFlags == 1) { - // can do weighted average if there's just one track - if (calo2ntk[tk2calo[itk]] == 1 && caloTrkWeightedAverage_) { - p.hwStatus = GoodTK_Calo_TkPt; - float ptavg = tk.floatPt(); - if (tk.floatPtErr() > 0) { - float wcalo = 1.0 / std::pow(tk.floatCaloPtErr(), 2); - float wtk = 1.0 / std::pow(tk.floatPtErr(), 2); - ptavg = (calo.floatPt() * wcalo + tk.floatPt() * wtk) / (wcalo + wtk); - p.hwStatus = GoodTK_Calo_TkCaloPt; - } - p.setFloatPt(ptavg); - if (debug_) - dbgPrintf( - "PFAlgo3 \t track %3d (pt %7.2f +- %7.2f) combined with calo %3d (pt %7.2f +- %7.2f (from tk) yielding " - "candidate of pt %7.2f\n", - itk, - tk.floatPt(), - tk.floatPtErr(), - tk2calo[itk], - calo.floatPt(), - tk.floatCaloPtErr(), - ptavg); - } else { - p.hwStatus = GoodTK_Calo_TkPt; - if (debug_) - dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) linked to calo %3d promoted to charged hadron\n", - itk, - tk.floatPt(), - tk2calo[itk]); - } - } else if (calo.hwFlags == 2) { - // must rescale - p.setFloatPt(tk.floatPt() * calo2alpha[tk2calo[itk]]); - p.hwStatus = GoodTk_Calo_CaloPt; - if (debug_) - dbgPrintf( - "PFAlgo3 \t track %3d (pt %7.2f, stubs %2d chi2 %7.1f) linked to calo %3d promoted to charged hadron with " - "pt %7.2f after maybe rescaling\n", - itk, - tk.floatPt(), - int(tk.hwStubs), - tk.hwChi2 * 0.1f, - tk2calo[itk], - p.floatPt()); - } - } -} - -void PFAlgo3::unlinkedcalo_algo(Region &r) const { - // process unmatched calo clusters - for (int ic = 0, nc = r.calo.size(); ic < nc; ++ic) { - if (!r.calo[ic].used) { - addCaloToPF(r, r.calo[ic]); - if (debug_) - dbgPrintf("PFAlgo3 \t calo %3d (pt %7.2f) not linked, promoted to neutral\n", ic, r.calo[ic].floatPt()); - } - } -} - -void PFAlgo3::save_muons(Region &r, const std::vector &tk2mu) const { - // finally do muons - for (int itk = 0, ntk = r.track.size(); itk < ntk; ++itk) { - if (r.track[itk].muonLink) { - auto &p = addTrackToPF(r, r.track[itk]); - p.muonsrc = r.muon[tk2mu[itk]].src; - if (debug_) - dbgPrintf("PFAlgo3 \t track %3d (pt %7.2f) promoted to muon.\n", itk, r.track[itk].floatPt()); - } - } -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgoBase.cc b/L1Trigger/Phase2L1ParticleFlow/src/PFAlgoBase.cc deleted file mode 100644 index f3b5f3d83652b..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/PFAlgoBase.cc +++ /dev/null @@ -1,57 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/PFAlgoBase.h" - -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" - -using namespace l1tpf_impl; - -PFAlgoBase::PFAlgoBase(const edm::ParameterSet &iConfig) : debug_(iConfig.getUntrackedParameter("debug", 0)) {} - -PFAlgoBase::~PFAlgoBase() {} - -void PFAlgoBase::initRegion(Region &r) const { - r.inputSort(); - r.pf.clear(); - r.puppi.clear(); - for (auto &c : r.calo) - c.used = false; - for (auto &c : r.emcalo) - c.used = false; - for (auto &t : r.track) { - t.used = false; - t.muonLink = false; - } -} - -PFParticle &PFAlgoBase::addTrackToPF(std::vector &pfs, const PropagatedTrack &tk) const { - PFParticle pf; - pf.hwPt = tk.hwPt; - pf.hwEta = tk.hwEta; - pf.hwPhi = tk.hwPhi; - pf.hwVtxEta = tk.hwEta; // FIXME: get from the track - pf.hwVtxPhi = tk.hwPhi; // before propagation - pf.track = tk; - pf.cluster.hwPt = 0; - pf.cluster.src = nullptr; - pf.muonsrc = nullptr; - pf.hwId = (tk.muonLink ? l1t::PFCandidate::Muon : l1t::PFCandidate::ChargedHadron); - pf.hwStatus = 0; - pfs.push_back(pf); - return pfs.back(); -} - -PFParticle &PFAlgoBase::addCaloToPF(std::vector &pfs, const CaloCluster &calo) const { - PFParticle pf; - pf.hwPt = calo.hwPt; - pf.hwEta = calo.hwEta; - pf.hwPhi = calo.hwPhi; - pf.hwVtxEta = calo.hwEta; - pf.hwVtxPhi = calo.hwPhi; - pf.track.hwPt = 0; - pf.track.src = nullptr; - pf.cluster = calo; - pf.muonsrc = nullptr; - pf.hwId = (calo.isEM ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron); - pf.hwStatus = 0; - pfs.push_back(pf); - return pfs.back(); -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PUAlgoBase.cc b/L1Trigger/Phase2L1ParticleFlow/src/PUAlgoBase.cc deleted file mode 100644 index b1c55079b0aa2..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/PUAlgoBase.cc +++ /dev/null @@ -1,81 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/PUAlgoBase.h" - -#include - -using namespace l1tpf_impl; - -PUAlgoBase::PUAlgoBase(const edm::ParameterSet &iConfig) - : debug_(iConfig.getUntrackedParameter("debug", 0)), - etaCharged_(iConfig.getParameter("etaCharged")), - vtxRes_(iConfig.getParameter("vtxRes")), - vtxAdaptiveCut_(iConfig.getParameter("vtxAdaptiveCut")) {} - -PUAlgoBase::~PUAlgoBase() {} - -void PUAlgoBase::runChargedPV(Region &r, float z0) const { - int16_t iZ0 = round(z0 * InputTrack::Z0_SCALE); - int16_t iDZ = round(1.5 * vtxRes_ * InputTrack::Z0_SCALE); - int16_t iDZ2 = vtxAdaptiveCut_ ? round(4.0 * vtxRes_ * InputTrack::Z0_SCALE) : iDZ; - for (PFParticle &p : r.pf) { - bool barrel = std::abs(p.track.hwVtxEta) < InputTrack::VTX_ETA_1p3; - if (r.relativeCoordinates) - barrel = - (std::abs(r.globalAbsEta(p.track.floatVtxEta())) < 1.3); // FIXME could make a better integer implementation - p.chargedPV = (p.hwId <= 1 && std::abs(p.track.hwZ0 - iZ0) < (barrel ? iDZ : iDZ2)); - } -} - -void PUAlgoBase::doVertexing(std::vector &rs, VertexAlgo algo, float &pvdz) const { - int lNBins = int(40. / vtxRes_); - if (algo == VertexAlgo::TP) - lNBins *= 3; - std::unique_ptr h_dz(new TH1F("h_dz", "h_dz", lNBins, -20, 20)); - if (algo != VertexAlgo::External) { - for (const Region &r : rs) { - for (const PropagatedTrack &p : r.track) { - if (rs.size() > 1) { - if (!r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi())) - continue; // skip duplicates - } - h_dz->Fill(p.floatDZ(), std::min(p.floatPt(), 50.f)); - } - } - } - switch (algo) { - case VertexAlgo::External: - break; - case VertexAlgo::Old: { - int imaxbin = h_dz->GetMaximumBin(); - pvdz = h_dz->GetXaxis()->GetBinCenter(imaxbin); - }; break; - case VertexAlgo::TP: { - float max = 0; - int bmax = -1; - for (int b = 1; b <= lNBins; ++b) { - float sum3 = h_dz->GetBinContent(b) + h_dz->GetBinContent(b + 1) + h_dz->GetBinContent(b - 1); - if (bmax == -1 || sum3 > max) { - max = sum3; - bmax = b; - } - } - pvdz = h_dz->GetXaxis()->GetBinCenter(bmax); - }; break; - } - int16_t iZ0 = round(pvdz * InputTrack::Z0_SCALE); - int16_t iDZ = round(1.5 * vtxRes_ * InputTrack::Z0_SCALE); - int16_t iDZ2 = vtxAdaptiveCut_ ? round(4.0 * vtxRes_ * InputTrack::Z0_SCALE) : iDZ; - for (Region &r : rs) { - for (PropagatedTrack &p : r.track) { - bool central = std::abs(p.hwVtxEta) < InputTrack::VTX_ETA_1p3; - if (r.relativeCoordinates) - central = - (std::abs(r.globalAbsEta(p.floatVtxEta())) < 1.3); // FIXME could make a better integer implementation - p.fromPV = (std::abs(p.hwZ0 - iZ0) < (central ? iDZ : iDZ2)); - } - } -} - -const std::vector &PUAlgoBase::puGlobalNames() const { - static const std::vector empty_; - return empty_; -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/PuppiAlgo.cc b/L1Trigger/Phase2L1ParticleFlow/src/PuppiAlgo.cc deleted file mode 100644 index 8f93b627902ef..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/PuppiAlgo.cc +++ /dev/null @@ -1,266 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/PuppiAlgo.h" -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" -#include "FWCore/Utilities/interface/Exception.h" -#include "DataFormats/Math/interface/deltaR.h" -#include "L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h" - -#include "Math/ProbFunc.h" - -namespace { - std::vector vd2vf(const std::vector &vd) { - std::vector ret; - ret.insert(ret.end(), vd.begin(), vd.end()); - return ret; - } -} // namespace - -using namespace l1tpf_impl; - -PuppiAlgo::PuppiAlgo(const edm::ParameterSet &iConfig) - : PUAlgoBase(iConfig), - puppiDr_(iConfig.getParameter("puppiDr")), - puppiDrMin_(iConfig.getParameter("puppiDrMin")), - puppiPtMax_(iConfig.getParameter("puppiPtMax")), - puppiEtaCuts_(vd2vf(iConfig.getParameter>("puppiEtaCuts"))), - puppiPtCuts_(vd2vf(iConfig.getParameter>("puppiPtCuts"))), - puppiPtCutsPhotons_(vd2vf(iConfig.getParameter>("puppiPtCutsPhotons"))), - puppiUsingBareTracks_(iConfig.getParameter("puppiUsingBareTracks")) { - debug_ = iConfig.getUntrackedParameter("puppiDebug", debug_); - if (puppiEtaCuts_.size() != puppiPtCuts_.size() || puppiPtCuts_.size() != puppiPtCutsPhotons_.size()) { - throw cms::Exception("Configuration", "Bad PUPPI config"); - } - for (unsigned int i = 0, n = puppiEtaCuts_.size(); i < n; ++i) { - intPuppiEtaCuts_.push_back(std::round(puppiEtaCuts_[i] * CaloCluster::ETAPHI_SCALE)); - intPuppiPtCuts_.push_back(std::round(puppiPtCuts_[i] * CaloCluster::PT_SCALE)); - intPuppiPtCutsPhotons_.push_back(std::round(puppiPtCutsPhotons_[i] * CaloCluster::PT_SCALE)); - } -} - -PuppiAlgo::~PuppiAlgo() {} - -const std::vector &PuppiAlgo::puGlobalNames() const { - static const std::vector names_{"alphaCMed", "alphaCRms", "alphaFMed", "alphaFRms"}; - return names_; -} -void PuppiAlgo::doPUGlobals(const std::vector &rs, float npu, std::vector &globals) const { - globals.resize(4); - computePuppiMedRMS(rs, globals[0], globals[1], globals[2], globals[3]); -} - -void PuppiAlgo::runNeutralsPU(Region &r, float npu, const std::vector &globals) const { - std::vector alphaC, alphaF; - computePuppiAlphas(r, alphaC, alphaF); - computePuppiWeights(r, alphaC, alphaF, globals[0], globals[1], globals[2], globals[3]); - fillPuppi(r); -} - -void PuppiAlgo::computePuppiAlphas(const Region &r, std::vector &alphaC, std::vector &alphaF) const { - alphaC.resize(r.pf.size()); - alphaF.resize(r.pf.size()); - float puppiDr2 = std::pow(puppiDr_, 2), puppiDr2min = std::pow(puppiDrMin_, 2); - for (unsigned int ip = 0, np = r.pf.size(); ip < np; ++ip) { - const PFParticle &p = r.pf[ip]; - if (p.hwId <= 1) - continue; - // neutral - alphaC[ip] = 0; - alphaF[ip] = 0; - for (const PFParticle &p2 : r.pf) { - float dr2 = ::deltaR2(p.floatEta(), p.floatPhi(), p2.floatEta(), p2.floatPhi()); - if (dr2 > 0 && dr2 < puppiDr2) { - float w = std::pow(std::min(p2.floatPt(), puppiPtMax_), 2) / std::max(puppiDr2min, dr2); - alphaF[ip] += w; - if (p2.chargedPV) - alphaC[ip] += w; - } - } - if (puppiUsingBareTracks_) { - alphaC[ip] = 0; - for (const PropagatedTrack &p2 : r.track) { - if (!p2.fromPV) - continue; - float dr2 = ::deltaR2(p.floatEta(), p.floatPhi(), p2.floatEta(), p2.floatPhi()); - if (dr2 > 0 && dr2 < puppiDr2) { - alphaC[ip] += std::pow(std::min(p2.floatPt(), puppiPtMax_), 2) / std::max(puppiDr2min, dr2); - } - } - } - } -} - -void PuppiAlgo::computePuppiWeights(Region &r, - const std::vector &alphaC, - const std::vector &alphaF, - float alphaCMed, - float alphaCRms, - float alphaFMed, - float alphaFRms) const { - int16_t ietacut = std::round(etaCharged_ * CaloCluster::ETAPHI_SCALE); - for (unsigned int ip = 0, np = r.pf.size(); ip < np; ++ip) { - PFParticle &p = r.pf[ip]; - // charged - if (p.hwId == l1t::PFCandidate::ChargedHadron || p.hwId == l1t::PFCandidate::Electron || - p.hwId == l1t::PFCandidate::Muon) { - p.setPuppiW(p.chargedPV || p.hwId == l1t::PFCandidate::Muon ? 1.0 : 0); - if (debug_) - dbgPrintf( - "PUPPI \t charged id %1d pt %7.2f eta %+5.2f phi %+5.2f alpha %+7.2f x2 %+7.2f --> puppi weight %.3f " - "puppi pt %7.2f \n", - p.hwId, - p.floatPt(), - p.floatEta(), - p.floatPhi(), - 0., - 0., - p.floatPuppiW(), - p.floatPt() * p.floatPuppiW()); - continue; - } - // neutral - float alpha = -99, x2 = -99; - bool central = std::abs(p.hwEta) < ietacut; - if (r.relativeCoordinates) - central = - (std::abs(r.globalAbsEta(p.floatEta())) < etaCharged_); // FIXME could make a better integer implementation - if (central) { - if (alphaC[ip] > 0) { - alpha = std::log(alphaC[ip]); - x2 = (alpha - alphaCMed) * std::abs(alpha - alphaCMed) / std::pow(alphaCRms, 2); - p.setPuppiW(ROOT::Math::chisquared_cdf(x2, 1)); - } else { - p.setPuppiW(0); - } - } else { - if (alphaF[ip] > 0) { - alpha = std::log(alphaF[ip]); - x2 = (alpha - alphaFMed) * std::abs(alpha - alphaFMed) / std::pow(alphaFRms, 2); - p.setPuppiW(ROOT::Math::chisquared_cdf(x2, 1)); - } else { - p.setPuppiW(0); - } - } - if (debug_) - dbgPrintf( - "PUPPI \t neutral id %1d pt %7.2f eta %+5.2f phi %+5.2f alpha %+7.2f x2 %+7.2f --> puppi weight %.3f " - "puppi pt %7.2f \n", - p.hwId, - p.floatPt(), - p.floatEta(), - p.floatPhi(), - alpha, - x2, - p.floatPuppiW(), - p.floatPt() * p.floatPuppiW()); - } -} - -void PuppiAlgo::computePuppiMedRMS( - const std::vector &rs, float &alphaCMed, float &alphaCRms, float &alphaFMed, float &alphaFRms) const { - std::vector alphaFs; - std::vector alphaCs; - int16_t ietacut = std::round(etaCharged_ * CaloCluster::ETAPHI_SCALE); - float puppiDr2 = std::pow(puppiDr_, 2), puppiDr2min = std::pow(puppiDrMin_, 2); - for (const Region &r : rs) { - for (const PFParticle &p : r.pf) { - bool central = std::abs(p.hwEta) < ietacut; - if (r.relativeCoordinates) - central = (r.globalAbsEta(p.floatEta()) < etaCharged_); // FIXME could make a better integer implementation - if (central) { - if (p.hwId > 1 || p.chargedPV) - continue; - } - float alphaC = 0, alphaF = 0; - for (const PFParticle &p2 : r.pf) { - float dr2 = ::deltaR2(p.floatEta(), p.floatPhi(), p2.floatEta(), p2.floatPhi()); - if (dr2 > 0 && dr2 < puppiDr2) { - float w = std::pow(std::min(p2.floatPt(), puppiPtMax_), 2) / std::max(puppiDr2min, dr2); - alphaF += w; - if (p2.chargedPV) - alphaC += w; - } - } - if (puppiUsingBareTracks_) { - alphaC = 0; - for (const PropagatedTrack &p2 : r.track) { - if (!p2.fromPV) - continue; - float dr2 = ::deltaR2(p.floatEta(), p.floatPhi(), p2.floatEta(), p2.floatPhi()); - if (dr2 > 0 && dr2 < puppiDr2) { - alphaC += std::pow(std::min(p2.floatPt(), puppiPtMax_), 2) / std::max(puppiDr2min, dr2); - } - } - } - if (central) { - if (alphaC > 0) - alphaCs.push_back(std::log(alphaC)); - } else { - if (alphaF > 0) - alphaFs.push_back(std::log(alphaF)); - } - } - } - std::sort(alphaCs.begin(), alphaCs.end()); - std::sort(alphaFs.begin(), alphaFs.end()); - - if (alphaCs.size() > 1) { - alphaCMed = alphaCs[alphaCs.size() / 2 + 1]; - double sum = 0.0; - for (float alpha : alphaCs) - sum += std::pow(alpha - alphaCMed, 2); - alphaCRms = std::sqrt(float(sum) / alphaCs.size()); - } else { - alphaCMed = 8.; - alphaCRms = 8.; - } - - if (alphaFs.size() > 1) { - alphaFMed = alphaFs[alphaFs.size() / 2 + 1]; - double sum = 0.0; - for (float alpha : alphaFs) - sum += std::pow(alpha - alphaFMed, 2); - alphaFRms = std::sqrt(float(sum) / alphaFs.size()); - } else { - alphaFMed = 6.; - alphaFRms = 6.; - } - if (debug_) - dbgPrintf("PUPPI \t alphaC = %+6.2f +- %6.2f (%4lu), alphaF = %+6.2f +- %6.2f (%4lu)\n", - alphaCMed, - alphaCRms, - alphaCs.size(), - alphaFMed, - alphaFRms, - alphaFs.size()); -} - -void PuppiAlgo::fillPuppi(Region &r) const { - uint16_t PUPPIW_0p01 = std::round(0.01 * PFParticle::PUPPI_SCALE); - r.puppi.clear(); - for (PFParticle &p : r.pf) { - if (p.hwId == l1t::PFCandidate::ChargedHadron || p.hwId == l1t::PFCandidate::Electron || - p.hwId == l1t::PFCandidate::Muon) { // charged - if (p.hwPuppiWeight > 0) { - r.puppi.push_back(p); - } - } else { // neutral - if (p.hwPuppiWeight > PUPPIW_0p01) { - // FIXME would work better with PUPPI_SCALE being a power of two, to do the shift - // FIXME done with floats - int16_t hwPt = (float(p.hwPt) * float(p.hwPuppiWeight) / float(PFParticle::PUPPI_SCALE)); - int16_t hwPtCut = 0, hwAbsEta = r.relativeCoordinates - ? round(r.globalAbsEta(p.floatEta()) * CaloCluster::ETAPHI_SCALE) - : std::abs(p.hwEta); - for (unsigned int ietaBin = 0, nBins = intPuppiEtaCuts_.size(); ietaBin < nBins; ++ietaBin) { - if (hwAbsEta < intPuppiEtaCuts_[ietaBin]) { - hwPtCut = (p.hwId == l1t::PFCandidate::Photon ? intPuppiPtCutsPhotons_[ietaBin] : intPuppiPtCuts_[ietaBin]); - break; - } - } - if (hwPt > hwPtCut) { - r.puppi.push_back(p); - r.puppi.back().hwPt = hwPt; - } - } - } - } -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/Region.cc b/L1Trigger/Phase2L1ParticleFlow/src/Region.cc deleted file mode 100644 index 116b95410c94d..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/Region.cc +++ /dev/null @@ -1,130 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" -#include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" -#include -#include - -const char *l1tpf_impl::Region::inputTypeName(int type) { - switch (InputType(type)) { - case calo_type: - return "Calo"; - case emcalo_type: - return "EmCalo"; - case track_type: - return "TK"; - case l1mu_type: - return "Mu"; - case n_input_types: - throw cms::Exception( - "LogicError", "n_input_types is not a type to be used, but only a compile-time const for iterating on types"); - } - return "NO_SUCH_INPUT_TYPE"; -} -const char *l1tpf_impl::Region::outputTypeName(int type) { - switch (OutputType(type)) { - case any_type: - return ""; - case charged_type: - return "Charged"; - case neutral_type: - return "Neutral"; - case electron_type: - return "Electron"; - case pfmuon_type: - return "Muon"; - case charged_hadron_type: - return "ChargedHadron"; - case neutral_hadron_type: - return "NeutralHadron"; - case photon_type: - return "Photon"; - case n_output_types: - throw cms::Exception( - "LogicError", - "n_output_types is not a type to be used, but only a compile-time const for iterating on types"); - } - return "NO_SUCH_OUTPUT_TYPE"; -} - -unsigned int l1tpf_impl::Region::nInput(InputType type) const { - switch (type) { - case calo_type: - return calo.size(); - case emcalo_type: - return emcalo.size(); - case track_type: - return track.size(); - case l1mu_type: - return muon.size(); - case n_input_types: - throw cms::Exception( - "LogicError", "n_input_types is not a type to be used, but only a compile-time const for iterating on types"); - } - return 9999; -} - -unsigned int l1tpf_impl::Region::nOutput(OutputType type, bool usePuppi, bool fiducial) const { - unsigned int ret = 0; - for (const auto &p : (usePuppi ? puppi : pf)) { - if (p.hwPt <= 0) - continue; - if (fiducial && !fiducialLocal(p.floatEta(), p.floatPhi())) - continue; - switch (type) { - case any_type: - ret++; - break; - case charged_type: - if (p.intCharge() != 0) - ret++; - break; - case neutral_type: - if (p.intCharge() == 0) - ret++; - break; - case electron_type: - if (p.hwId == l1t::PFCandidate::Electron) - ret++; - break; - case pfmuon_type: - if (p.hwId == l1t::PFCandidate::Muon) - ret++; - break; - case charged_hadron_type: - if (p.hwId == l1t::PFCandidate::ChargedHadron) - ret++; - break; - case neutral_hadron_type: - if (p.hwId == l1t::PFCandidate::NeutralHadron) - ret++; - break; - case photon_type: - if (p.hwId == l1t::PFCandidate::Photon) - ret++; - break; - case n_output_types: - throw cms::Exception( - "LogicError", - "n_output_types is not a type to be used, but only a compile-time const for iterating on types"); - } - } - return ret; -} - -void l1tpf_impl::Region::inputSort() { - std::sort(calo.begin(), calo.end()); - std::sort(emcalo.begin(), emcalo.end()); - std::sort(track.begin(), track.end()); - std::sort(muon.begin(), muon.end()); - if (ncaloMax > 0 && calo.size() > ncaloMax) { - caloOverflow = calo.size() - ncaloMax; - calo.resize(ncaloMax); - } - if (nemcaloMax > 0 && emcalo.size() > nemcaloMax) { - emcaloOverflow = emcalo.size() - nemcaloMax; - emcalo.resize(nemcaloMax); - } - if (ntrackMax > 0 && track.size() > ntrackMax) { - trackOverflow = track.size() - ntrackMax; - track.resize(ntrackMax); - } -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/RegionMapper.cc b/L1Trigger/Phase2L1ParticleFlow/src/RegionMapper.cc deleted file mode 100644 index cb422493dc3a1..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/RegionMapper.cc +++ /dev/null @@ -1,340 +0,0 @@ -#include "L1Trigger/Phase2L1ParticleFlow/interface/RegionMapper.h" - -using namespace l1tpf_impl; - -RegionMapper::RegionMapper(const edm::ParameterSet &iConfig) : useRelativeRegionalCoordinates_(false) { - if (iConfig.existsAs>("regions")) { - useRelativeRegionalCoordinates_ = iConfig.getParameter("useRelativeRegionalCoordinates"); - for (const edm::ParameterSet &preg : iConfig.getParameter>("regions")) { - std::vector etaBoundaries = preg.getParameter>("etaBoundaries"); - unsigned int phiSlices = preg.getParameter("phiSlices"); - float etaExtra = preg.getParameter("etaExtra"); - float phiExtra = preg.getParameter("phiExtra"); - float phiWidth = 2 * M_PI / phiSlices; - unsigned int ncalomax = 0, nemcalomax = 0, ntrackmax = 0, nmuonmax = 0, npfmax = 0, npuppimax = 0; - if (preg.existsAs("caloNMax")) - ncalomax = preg.getParameter("caloNMax"); - if (preg.existsAs("emcaloNMax")) - nemcalomax = preg.getParameter("emcaloNMax"); - if (preg.existsAs("trackNMax")) - ntrackmax = preg.getParameter("trackNMax"); - if (preg.existsAs("muonNMax")) - nmuonmax = preg.getParameter("muonNMax"); - if (preg.existsAs("pfNMax")) - npfmax = preg.getParameter("pfNMax"); - if (preg.existsAs("puppiNMax")) - npuppimax = preg.getParameter("puppiNMax"); - for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { - for (unsigned int iphi = 0; iphi < phiSlices; ++iphi) { - float phiCenter = (iphi + 0.5) * phiWidth - M_PI; - regions_.push_back(Region(etaBoundaries[ieta], - etaBoundaries[ieta + 1], - phiCenter, - phiWidth, - etaExtra, - phiExtra, - useRelativeRegionalCoordinates_, - ncalomax, - nemcalomax, - ntrackmax, - nmuonmax, - npfmax, - npuppimax)); - } - } - } - std::string trackRegionMode = "TrackAssoMode::any"; - if (iConfig.existsAs("trackRegionMode")) - trackRegionMode = iConfig.getParameter("trackRegionMode"); - if (trackRegionMode == "atVertex") - trackRegionMode_ = TrackAssoMode::atVertex; - else if (trackRegionMode == "atCalo") - trackRegionMode_ = TrackAssoMode::atCalo; - else if (trackRegionMode == "any") - trackRegionMode_ = TrackAssoMode::any; - else - throw cms::Exception( - "Configuration", - "Unsupported value for trackRegionMode: " + trackRegionMode + " (allowed are 'atVertex', 'atCalo', 'any')"); - } else { - // start off with a dummy region - unsigned int ncalomax = 0, nemcalomax = 0, ntrackmax = 0, nmuonmax = 0, npfmax = 0, npuppimax = 0; - regions_.emplace_back(-5.5, - 5.5, - 0, - 2 * M_PI, - 0.5, - 0.5, - useRelativeRegionalCoordinates_, - ncalomax, - nemcalomax, - ntrackmax, - nmuonmax, - npfmax, - npuppimax); - } -} - -void RegionMapper::clear() { - for (Region &r : regions_) - r.zero(); - clusterRefMap_.clear(); - trackRefMap_.clear(); - muonRefMap_.clear(); -} - -void RegionMapper::addTrack(const l1t::PFTrack &t) { - // now let's be optimistic and make things very simple - // we propagate in floating point the track to the calo - // we add the track to the region corresponding to its vertex (eta,phi) coordinates AND its (eta,phi) calo coordinates - for (Region &r : regions_) { - bool inside = true; - switch (trackRegionMode_) { - case TrackAssoMode::atVertex: - inside = r.contains(t.eta(), t.phi()); - break; - case TrackAssoMode::atCalo: - inside = r.contains(t.caloEta(), t.caloPhi()); - break; - case TrackAssoMode::any: - inside = r.contains(t.eta(), t.phi()) || r.contains(t.caloEta(), t.caloPhi()); - break; - } - if (inside) { - PropagatedTrack prop; - prop.fillInput(t.pt(), r.localEta(t.eta()), r.localPhi(t.phi()), t.charge(), t.vertex().Z(), t.quality(), &t); - prop.fillPropagated(t.pt(), - t.trkPtError(), - t.caloPtError(), - r.localEta(t.caloEta()), - r.localPhi(t.caloPhi()), - t.quality(), - t.isMuon()); - prop.hwStubs = t.nStubs(); - prop.hwChi2 = round(t.chi2() * 10); - r.track.push_back(prop); - } - } -} -void RegionMapper::addTrack(const l1t::PFTrack &t, l1t::PFTrackRef ref) { - addTrack(t); - trackRefMap_[&t] = ref; -} - -void RegionMapper::addMuon(const l1t::Muon &mu) { - // now let's be optimistic and make things very simple - // we don't propagate anything - for (Region &r : regions_) { - if (r.contains(mu.eta(), mu.phi())) { - Muon prop; - prop.fill(mu.pt(), r.localEta(mu.eta()), r.localPhi(mu.phi()), mu.charge(), mu.hwQual(), &mu); - r.muon.push_back(prop); - } - } -} - -void RegionMapper::addMuon(const l1t::TkMuon &mu) { - // now let's be optimistic and make things very simple - // we don't propagate anything - for (Region &r : regions_) { - if (r.contains(mu.eta(), mu.phi())) { - Muon prop; - prop.fill(mu.pt(), r.localEta(mu.eta()), r.localPhi(mu.phi()), mu.charge(), mu.hwQual()); - r.muon.push_back(prop); - } - } -} - -void RegionMapper::addMuon(const l1t::Muon &mu, l1t::PFCandidate::MuonRef ref) { - addMuon(mu); - muonRefMap_[&mu] = ref; -} - -void RegionMapper::addCalo(const l1t::PFCluster &p) { - if (p.pt() == 0) - return; - for (Region &r : regions_) { - if (r.contains(p.eta(), p.phi())) { - CaloCluster calo; - calo.fill(p.pt(), p.emEt(), p.ptError(), r.localEta(p.eta()), r.localPhi(p.phi()), p.isEM(), 0, &p); - r.calo.push_back(calo); - } - } -} -void RegionMapper::addCalo(const l1t::PFCluster &p, l1t::PFClusterRef ref) { - addCalo(p); - clusterRefMap_[&p] = ref; -} - -void RegionMapper::addEmCalo(const l1t::PFCluster &p) { - if (p.pt() == 0) - return; - for (Region &r : regions_) { - if (r.contains(p.eta(), p.phi())) { - CaloCluster calo; - calo.fill(p.pt(), p.emEt(), p.ptError(), r.localEta(p.eta()), r.localPhi(p.phi()), p.isEM(), 0, &p); - r.emcalo.push_back(calo); - } - } -} -void RegionMapper::addEmCalo(const l1t::PFCluster &p, l1t::PFClusterRef ref) { - addEmCalo(p); - clusterRefMap_[&p] = ref; -} - -std::unique_ptr RegionMapper::fetch(bool puppi, float ptMin) const { - auto ret = std::make_unique(); - for (const Region &r : regions_) { - for (const PFParticle &p : (puppi ? r.puppi : r.pf)) { - bool inside = true; - switch (trackRegionMode_) { - case TrackAssoMode::atVertex: - inside = r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi()); - break; - case TrackAssoMode::atCalo: - inside = r.fiducialLocal(p.floatEta(), p.floatPhi()); - break; - case TrackAssoMode::any: - inside = r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi()); - break; // WARNING: this may not be the best choice - } - if (!inside) - continue; - if (p.floatPt() > ptMin) { - reco::Particle::PolarLorentzVector p4( - p.floatPt(), r.globalEta(p.floatVtxEta()), r.globalPhi(p.floatVtxPhi()), 0.13f); - ret->emplace_back(l1t::PFCandidate::ParticleType(p.hwId), p.intCharge(), p4, p.floatPuppiW()); - ret->back().setVertex(reco::Particle::Point(0, 0, p.floatDZ())); - ret->back().setStatus(p.hwStatus); - if (p.cluster.src) { - auto match = clusterRefMap_.find(p.cluster.src); - if (match == clusterRefMap_.end()) { - throw cms::Exception("CorruptData") << "Invalid cluster pointer in PF candidate id " << p.hwId << " pt " - << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); - } - ret->back().setPFCluster(match->second); - } - if (p.track.src) { - auto match = trackRefMap_.find(p.track.src); - if (match == trackRefMap_.end()) { - throw cms::Exception("CorruptData") << "Invalid track pointer in PF candidate id " << p.hwId << " pt " - << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); - } - ret->back().setPFTrack(match->second); - } - if (p.muonsrc) { - auto match = muonRefMap_.find(p.muonsrc); - if (match == muonRefMap_.end()) { - throw cms::Exception("CorruptData") << "Invalid muon pointer in PF candidate id " << p.hwId << " pt " - << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); - } - ret->back().setMuon(match->second); - } - } - } - } - return ret; -} - -std::unique_ptr RegionMapper::fetchCalo(float ptMin, bool emcalo) const { - auto ret = std::make_unique(); - for (const Region &r : regions_) { - for (const CaloCluster &p : (emcalo ? r.emcalo : r.calo)) { - if (!r.fiducialLocal(p.floatEta(), p.floatPhi())) - continue; - if (p.floatPt() > ptMin) { - reco::Particle::PolarLorentzVector p4(p.floatPt(), r.globalEta(p.floatEta()), r.globalPhi(p.floatPhi()), 0.13f); - l1t::PFCandidate::ParticleType kind = - (p.isEM || emcalo) ? l1t::PFCandidate::Photon : l1t::PFCandidate::NeutralHadron; - ret->emplace_back(kind, 0, p4); - if (p.src) { - auto match = clusterRefMap_.find(p.src); - if (match == clusterRefMap_.end()) { - throw cms::Exception("CorruptData") - << "Invalid cluster pointer in cluster pt " << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); - } - ret->back().setPFCluster(match->second); - } - } - } - } - return ret; -} - -std::unique_ptr RegionMapper::fetchTracks(float ptMin, bool fromPV) const { - auto ret = std::make_unique(); - for (const Region &r : regions_) { - for (const PropagatedTrack &p : r.track) { - if (fromPV && !p.fromPV) - continue; - bool inside = true; - switch (trackRegionMode_) { - case TrackAssoMode::atVertex: - inside = r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi()); - break; - case TrackAssoMode::atCalo: - inside = r.fiducialLocal(p.floatEta(), p.floatPhi()); - break; - case TrackAssoMode::any: - inside = r.fiducialLocal(p.floatVtxEta(), p.floatVtxPhi()); - break; // WARNING: this may not be the best choice - } - if (!inside) - continue; - if (p.floatPt() > ptMin) { - reco::Particle::PolarLorentzVector p4( - p.floatVtxPt(), r.globalEta(p.floatVtxEta()), r.globalPhi(p.floatVtxPhi()), 0.13f); - l1t::PFCandidate::ParticleType kind = p.muonLink ? l1t::PFCandidate::Muon : l1t::PFCandidate::ChargedHadron; - ret->emplace_back(kind, p.intCharge(), p4); - ret->back().setVertex(reco::Particle::Point(0, 0, p.floatDZ())); - if (p.src) { - auto match = trackRefMap_.find(p.src); - if (match == trackRefMap_.end()) { - throw cms::Exception("CorruptData") - << "Invalid track pointer in PF track pt " << p4.pt() << " eta " << p4.eta() << " phi " << p4.phi(); - } - ret->back().setPFTrack(match->second); - } - } - } - } - return ret; -} - -std::pair RegionMapper::totAndMaxInput(int type) const { - unsigned ntot = 0, nmax = 0; - for (const auto &r : regions_) { - unsigned int ni = r.nInput(Region::InputType(type)); - ntot += ni; - nmax = std::max(nmax, ni); - } - return std::make_pair(ntot, nmax); -} - -std::unique_ptr> RegionMapper::vecInput(int type) const { - auto v = std::make_unique>(); - for (const auto &r : regions_) { - unsigned ni = r.nInput(Region::InputType(type)); - v->push_back(ni); - } - return v; -} - -std::pair RegionMapper::totAndMaxOutput(int type, bool puppi) const { - unsigned ntot = 0, nmax = 0; - for (const auto &r : regions_) { - unsigned int ni = r.nOutput(Region::OutputType(type), puppi); - ntot += ni; - nmax = std::max(nmax, ni); - } - return std::make_pair(ntot, nmax); -} - -std::unique_ptr> RegionMapper::vecOutput(int type, bool puppi) const { - auto v = std::make_unique>(); - for (const auto &r : regions_) { - unsigned ni = r.nOutput(Region::OutputType(type), puppi); - v->push_back(ni); - } - return v; -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h b/L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h deleted file mode 100644 index 2946be4e5455d..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/dbgPrintf.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_dbgPrintf_h -#define L1Trigger_Phase2L1ParticleFlow_dbgPrintf_h - -template -inline void dbgPrintf(const char *formatString, Args &&...args) { -#ifdef L1PF_DEBUG - printf(formatString, std::forward(args)...); -#endif -} - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_input.cpp b/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_input.cpp new file mode 100644 index 0000000000000..1c0c8ef939cdc --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_input.cpp @@ -0,0 +1,87 @@ +#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; +} + +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 + } + /*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 + } +} + +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"; + } + } + dbgCout() << " ----------------- " + << "\n"; + } + dbgCout() << "Regions ordered!" + << "\n"; + dbgCout() << "\n"; + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_ref.cpp new file mode 100644 index 0000000000000..7b900c4b0b2ea --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/deregionizer/deregionizer_ref.cpp @@ -0,0 +1,155 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/deregionizer/deregionizer_ref.h" + +#include +#include + +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::DeregionizerEmulator::DeregionizerEmulator(const edm::ParameterSet &iConfig) + : DeregionizerEmulator(iConfig.getParameter("nPuppiFinalBuffer"), + iConfig.getParameter("nPuppiPerClk"), + iConfig.getParameter("nPuppiFirstBuffers"), + iConfig.getParameter("nPuppiSecondBuffers"), + iConfig.getParameter("nPuppiThirdBuffers")) { + debug_ = iConfig.getUntrackedParameter("debug", false); +} +#endif + +l1ct::DeregionizerEmulator::DeregionizerEmulator(const unsigned int nPuppiFinalBuffer /*=128*/, + const unsigned int nPuppiPerClk /*=6*/, + const unsigned int nPuppiFirstBuffers /*=12*/, + const unsigned int nPuppiSecondBuffers /*=32*/, + const unsigned int nPuppiThirdBuffers /*=64*/) + : nPuppiFinalBuffer_(nPuppiFinalBuffer), + nPuppiPerClk_(nPuppiPerClk), + nPuppiFirstBuffers_(nPuppiFirstBuffers), + nPuppiSecondBuffers_(nPuppiSecondBuffers), + nPuppiThirdBuffers_(nPuppiThirdBuffers), + debug_(false) { + assert(nPuppiPerClk < nPuppiFirstBuffers && nPuppiFirstBuffers < nPuppiSecondBuffers && + 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) { + std::vector out; + + out.insert(out.end(), inLeft.begin(), std::min(inLeft.end(), inLeft.begin() + X)); + out.insert(out.end(), inRight.begin(), std::min(inRight.end(), inRight.begin() + Y - X)); + + return out; +} + +void l1ct::DeregionizerEmulator::accumulateToY(const unsigned int Y, + const std::vector &in, + std::vector &out, + std::vector &truncated) { + unsigned int initialOutSize = out.size(); + assert(initialOutSize <= Y); + if (initialOutSize == Y) { + truncated.insert(truncated.end(), in.begin(), in.end()); + return; + } + out.insert(out.end(), in.begin(), std::min(in.end(), in.begin() + Y - initialOutSize)); + if (out.size() == Y) + truncated.insert(truncated.end(), in.begin() + Y - initialOutSize, in.end()); + return; +} + +static void debugPrint(const std::string &header, const std::vector &pup) { + dbgCout() << " --> " << header << "\n"; + for (unsigned int iPup = 0, nPup = pup.size(); iPup < nPup; ++iPup) + dbgCout() << " > puppi[" << iPup << "] pT = " << pup[iPup].hwPt << "\n"; +} + +void l1ct::DeregionizerEmulator::run(const l1ct::DeregionizerInput 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); + } + } + } + + if (debug_) { + dbgCout() << "\n"; + debugPrint("FINAL ARRAY", out); + dbgCout() << "\n"; + dbgCout() << "Ran successfully!" + << "\n"; + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egencoder_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egencoder_ref.cpp new file mode 100644 index 0000000000000..64ffeb9f13e24 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egencoder_ref.cpp @@ -0,0 +1,18 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egencoder_ref.h" + +using namespace l1ct; + +#ifdef CMSSW_GIT_HASH + +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::L2EgEncoderEmulator::L2EgEncoderEmulator(const edm::ParameterSet& pset) + : L2EgEncoderEmulator(pset.getParameter("nTKELE_OUT"), pset.getParameter("nTKPHO_OUT")) {} + +#endif + +void L2EgEncoderEmulator::toFirmware(const std::vector>& encoded_in, ap_uint<64> encoded_fw[]) const { + for (unsigned int i = 0; i < nEncodedWords_; i++) { + encoded_fw[i] = (i < encoded_in.size()) ? encoded_in[i] : ap_uint<64>(0); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egsorter_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egsorter_ref.cpp new file mode 100644 index 0000000000000..751d75e467235 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/l2egsorter_ref.cpp @@ -0,0 +1,75 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/l2egsorter_ref.h" + +#include +#include +#include +#include +#include + +using namespace l1ct; + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::L2EgSorterEmulator::L2EgSorterEmulator(const edm::ParameterSet &pset) + : L2EgSorterEmulator(pset.getParameter("nBOARDS"), + pset.getParameter("nEGPerBoard"), + pset.getParameter("nEGOut"), + pset.getUntrackedParameter("debug", 0)) {} +#endif + +void L2EgSorterEmulator::toFirmware(const std::vector &out_photons, + const std::vector &out_eles, + EGIsoObj out_egphs[/*nObjOut*/], + EGIsoEleObj out_egeles[/*nObjOut*/]) const { + for (unsigned int io = 0; io < nEGOut; io++) { + EGIsoObj pho; + EGIsoEleObj ele; + if (io < out_photons.size()) + pho = out_photons[io]; + else + pho.clear(); + if (io < out_eles.size()) + ele = out_eles[io]; + else + ele.clear(); + + out_egphs[io] = pho; + out_egeles[io] = ele; + } +} + +void L2EgSorterEmulator::run(const std::vector &in, + std::vector &out_photons, + std::vector &out_eles) const { + if (debug_) { + unsigned int board_n = 0; + for (const auto &board : in) { + dbgCout() << "BOARD " << board_n++ << std::endl; + print_objects(board.egphoton, "photon_in"); + print_objects(board.egelectron, "electron_in"); + } + } + + // we copy to be able to resize them + std::vector> photons_in; + std::vector> eles_in; + photons_in.reserve(in.size()); + eles_in.reserve(in.size()); + for (const auto &board : in) { + std::vector photons = board.egphoton; + std::vector eles = board.egelectron; + resize_input(photons); + resize_input(eles); + + photons_in.push_back(photons); + eles_in.push_back(eles); + } + merge(photons_in, out_photons); + merge(eles_in, out_eles); + + if (debug_) { + print_objects(out_photons, "photon_out"); + print_objects(out_eles, "electron_out"); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pfeginput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pfeginput_ref.cpp new file mode 100644 index 0000000000000..71716e7f542c2 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pfeginput_ref.cpp @@ -0,0 +1,64 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pfeginput_ref.h" + +using namespace l1ct; + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::EGInputSelectorEmuConfig::EGInputSelectorEmuConfig(const edm::ParameterSet &pset) + : idMask(pset.getParameter("emIDMask")), + nHADCALO_IN(pset.getParameter("nHADCALO_IN")), + nEMCALO_OUT(pset.getParameter("nEMCALO_OUT")), + debug(pset.getUntrackedParameter("debug", 0)) {} + +#endif + +void EGInputSelectorEmulator::toFirmware(const PFInputRegion &in, HadCaloObj hadcalo[/*nCALO*/]) const { + l1ct::toFirmware(in.hadcalo, cfg.nHADCALO_IN, hadcalo); +} + +void EGInputSelectorEmulator::toFirmware(const std::vector &emcalo_sel, EmCaloObj emcalo[]) const { + l1ct::toFirmware(emcalo_sel, cfg.nEMCALO_OUT, emcalo); +} + +void EGInputSelectorEmulator::select_eginput(const l1ct::HadCaloObjEmu &in, + l1ct::EmCaloObjEmu &out, + bool &valid_out) const { + out.src = in.src; + out.hwPt = in.hwEmPt; + out.hwEta = in.hwEta; + out.hwPhi = in.hwPhi; + out.hwPtErr = 0; + // shift to get rid of PFEM ID bit (more usable final EG quality) + out.hwEmID = (in.hwEmID >> 1); + valid_out = (in.hwEmID & cfg.idMask) != 0; +} + +void EGInputSelectorEmulator::select_eginputs(const std::vector &hadcalo_in, + std::vector &emcalo_sel) const { + for (int ic = 0, nc = hadcalo_in.size(); ic < nc; ++ic) { + if (emcalo_sel.size() == cfg.nEMCALO_OUT) + break; + bool valid = false; + EmCaloObjEmu out; + select_eginput(hadcalo_in[ic], out, valid); + if (valid) { + emcalo_sel.push_back(out); + } + } +} + +void EGInputSelectorEmulator::select_or_clear(const HadCaloObjEmu &hadcalo_in, EmCaloObjEmu &emcalo_out) const { + bool valid = false; + select_eginput(hadcalo_in, emcalo_out, valid); + if (!valid) + emcalo_out.clear(); +} + +void EGInputSelectorEmulator::select_or_clear(const std::vector &hadcalo_in, + std::vector &emcalo_out) const { + emcalo_out.resize(hadcalo_in.size()); + for (int ic = 0, nc = hadcalo_in.size(); ic < nc; ++ic) { + select_or_clear(hadcalo_in[ic], emcalo_out[ic]); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp new file mode 100644 index 0000000000000..2fc881879455d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/egamma/pftkegalgo_ref.cpp @@ -0,0 +1,439 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pftkegalgo_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#include +#include +#include +#include +#include +#include + +using namespace l1ct; + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::PFTkEGAlgoEmuConfig::PFTkEGAlgoEmuConfig(const edm::ParameterSet &pset) + : nTRACK(pset.getParameter("nTRACK")), + nTRACK_EGIN(pset.getParameter("nTRACK_EGIN")), + nEMCALO_EGIN(pset.getParameter("nEMCALO_EGIN")), + nEM_EGOUT(pset.getParameter("nEM_EGOUT")), + filterHwQuality(pset.getParameter("filterHwQuality")), + doBremRecovery(pset.getParameter("doBremRecovery")), + writeBeforeBremRecovery(pset.getParameter("writeBeforeBremRecovery")), + caloHwQual(pset.getParameter("caloHwQual")), + doEndcapHwQual(pset.getParameter("doEndcapHwQual")), + emClusterPtMin(pset.getParameter("caloEtMin")), + dEtaMaxBrem(pset.getParameter("dEtaMaxBrem")), + dPhiMaxBrem(pset.getParameter("dPhiMaxBrem")), + absEtaBoundaries(pset.getParameter>("absEtaBoundaries")), + dEtaValues(pset.getParameter>("dEtaValues")), + dPhiValues(pset.getParameter>("dPhiValues")), + trkQualityPtMin(pset.getParameter("trkQualityPtMin")), + writeEgSta(pset.getParameter("writeEGSta")), + tkIsoParams_tkEle(pset.getParameter("tkIsoParametersTkEle")), + tkIsoParams_tkEm(pset.getParameter("tkIsoParametersTkEm")), + pfIsoParams_tkEle(pset.getParameter("pfIsoParametersTkEle")), + pfIsoParams_tkEm(pset.getParameter("pfIsoParametersTkEm")), + doTkIso(pset.getParameter("doTkIso")), + doPfIso(pset.getParameter("doPfIso")), + hwIsoTypeTkEle(static_cast(pset.getParameter("hwIsoTypeTkEle"))), + hwIsoTypeTkEm(static_cast(pset.getParameter("hwIsoTypeTkEm"))), + debug(pset.getUntrackedParameter("debug", 0)) {} + +l1ct::PFTkEGAlgoEmuConfig::IsoParameters::IsoParameters(const edm::ParameterSet &pset) + : IsoParameters(pset.getParameter("tkQualityPtMin"), + pset.getParameter("dZ"), + pset.getParameter("dRMin"), + pset.getParameter("dRMax")) {} + +#endif + +void PFTkEGAlgoEmulator::toFirmware(const PFInputRegion &in, + PFRegion ®ion, + EmCaloObj emcalo[/*nCALO*/], + TkObj track[/*nTRACK*/]) const { + region = in.region; + l1ct::toFirmware(in.track, cfg.nTRACK_EGIN, track); + l1ct::toFirmware(in.emcalo, cfg.nEMCALO_EGIN, emcalo); + if (debug_ > 0) + dbgCout() << "# of inpput tracks: " << in.track.size() << " (max: " << cfg.nTRACK_EGIN << ")" + << " emcalo: " << in.emcalo.size() << "(" << cfg.nEMCALO_EGIN << ")" << std::endl; +} + +void PFTkEGAlgoEmulator::toFirmware(const OutputRegion &out, EGIsoObj out_egphs[], EGIsoEleObj out_egeles[]) const { + l1ct::toFirmware(out.egphoton, cfg.nEM_EGOUT, out_egphs); + l1ct::toFirmware(out.egelectron, cfg.nEM_EGOUT, out_egeles); + if (debug_ > 0) + dbgCout() << "# output photons: " << out.egphoton.size() << " electrons: " << out.egelectron.size() << std::endl; +} + +void PFTkEGAlgoEmulator::toFirmware( + const PFInputRegion &in, const l1ct::PVObjEmu &pvin, PFRegion ®ion, TkObj track[/*nTRACK*/], PVObj &pv) const { + region = in.region; + l1ct::toFirmware(in.track, cfg.nTRACK, track); + pv = pvin; + if (debug_ > 0) + dbgCout() << "# of inpput tracks: " << in.track.size() << " (max: " << cfg.nTRACK << ")" << std::endl; +} + +float PFTkEGAlgoEmulator::deltaPhi(float phi1, float phi2) const { + // reduce to [-pi,pi] + float x = phi1 - phi2; + float o2pi = 1. / (2. * M_PI); + if (std::abs(x) <= float(M_PI)) + return x; + float n = std::round(x * o2pi); + return x - n * float(2. * M_PI); +} + +void PFTkEGAlgoEmulator::link_emCalo2emCalo(const std::vector &emcalo, + std::vector &emCalo2emCalo) const { + // NOTE: we assume the input to be sorted!!! + for (int ic = 0, nc = emcalo.size(); ic < nc; ++ic) { + auto &calo = emcalo[ic]; + if (emCalo2emCalo[ic] != -1) + continue; + + for (int jc = ic + 1; jc < nc; ++jc) { + if (emCalo2emCalo[jc] != -1) + continue; + + auto &otherCalo = emcalo[jc]; + + if (fabs(otherCalo.floatEta() - calo.floatEta()) < cfg.dEtaMaxBrem && + fabs(deltaPhi(otherCalo.floatPhi(), calo.floatPhi())) < cfg.dPhiMaxBrem) { + emCalo2emCalo[jc] = ic; + } + } + } +} + +void PFTkEGAlgoEmulator::link_emCalo2tk(const PFRegionEmu &r, + const std::vector &emcalo, + const std::vector &track, + std::vector &emCalo2tk) const { + unsigned int nTrackMax = std::min(track.size(), cfg.nTRACK_EGIN); + for (int ic = 0, nc = emcalo.size(); ic < nc; ++ic) { + auto &calo = emcalo[ic]; + + float dPtMin = 999; + for (unsigned int itk = 0; itk < nTrackMax; ++itk) { + const auto &tk = track[itk]; + if (tk.floatPt() < cfg.trkQualityPtMin) + continue; + + float d_phi = deltaPhi(tk.floatPhi(), calo.floatPhi()); + float d_eta = tk.floatEta() - calo.floatEta(); // We only use it squared + + auto eta_index = + std::distance(cfg.absEtaBoundaries.begin(), + std::lower_bound( + cfg.absEtaBoundaries.begin(), cfg.absEtaBoundaries.end(), abs(r.floatGlbEta(calo.hwEta)))) - + 1; + + float dEtaMax = cfg.dEtaValues[eta_index]; + float dPhiMax = cfg.dPhiValues[eta_index]; + + 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) { + emCalo2tk[ic] = itk; + dPtMin = fabs(tk.floatPt() - calo.floatPt()); + } + } + } + } +} + +void PFTkEGAlgoEmulator::sel_emCalo(unsigned int nmax_sel, + const std::vector &emcalo, + std::vector &emcalo_sel) const { + for (int ic = 0, nc = emcalo.size(); ic < nc; ++ic) { + const auto &calo = emcalo[ic]; + if ((calo.hwPt == 0) || (cfg.filterHwQuality && calo.hwEmID != cfg.caloHwQual) || + (calo.floatPt() < cfg.emClusterPtMin)) + continue; + emcalo_sel.push_back(calo); + if (emcalo_sel.size() >= nmax_sel) + break; + } +} + +void PFTkEGAlgoEmulator::run(const PFInputRegion &in, OutputRegion &out) const { + if (debug_ > 1) { + for (int ic = 0, nc = in.emcalo.size(); ic < nc; ++ic) { + const auto &calo = in.emcalo[ic]; + if (calo.hwPt > 0) + dbgCout() << "[REF] IN calo[" << ic << "] pt: " << calo.hwPt << " eta: " << calo.hwEta + << " (glb eta: " << in.region.floatGlbEta(calo.hwEta) << ") phi: " << calo.hwPhi + << "(glb phi: " << in.region.floatGlbPhi(calo.hwPhi) << ") qual: " << std::bitset<4>(calo.hwEmID) + << std::endl; + } + } + + // FIXME: can be removed in the endcap since now running with the "interceptor". + // Might still be needed in barrel + // filter and select first N elements of input clusters + std::vector emcalo_sel; + sel_emCalo(cfg.nEMCALO_EGIN, in.emcalo, emcalo_sel); + + std::vector emCalo2emCalo(emcalo_sel.size(), -1); + if (cfg.doBremRecovery) + link_emCalo2emCalo(emcalo_sel, emCalo2emCalo); + + std::vector emCalo2tk(emcalo_sel.size(), -1); + link_emCalo2tk(in.region, emcalo_sel, in.track, emCalo2tk); + + out.egsta.clear(); + std::vector egobjs; + std::vector egeleobjs; + eg_algo(in.region, emcalo_sel, in.track, emCalo2emCalo, emCalo2tk, out.egsta, egobjs, egeleobjs); + + unsigned int nEGOut = std::min(cfg.nEM_EGOUT, egobjs.size()); + unsigned int nEGEleOut = std::min(cfg.nEM_EGOUT, egeleobjs.size()); + + // init output containers + out.egphoton.clear(); + out.egelectron.clear(); + ptsort_ref(egobjs.size(), nEGOut, egobjs, out.egphoton); + ptsort_ref(egeleobjs.size(), nEGEleOut, egeleobjs, out.egelectron); +} + +void PFTkEGAlgoEmulator::eg_algo(const PFRegionEmu ®ion, + const std::vector &emcalo, + const std::vector &track, + const std::vector &emCalo2emCalo, + const std::vector &emCalo2tk, + std::vector &egstas, + std::vector &egobjs, + std::vector &egeleobjs) const { + for (int ic = 0, nc = emcalo.size(); ic < nc; ++ic) { + auto &calo = emcalo[ic]; + + // discard immediately EG objects that would not fall in the fiducial eta-phi region + if (!region.isFiducial(calo)) + continue; + + if (debug_ > 3) + dbgCout() << "[REF] SEL emcalo with pt: " << calo.hwPt << " qual: " << calo.hwEmID << " eta: " << calo.hwEta + << " phi " << calo.hwPhi << std::endl; + + int itk = emCalo2tk[ic]; + + // check if brem recovery is on + if (!cfg.doBremRecovery || cfg.writeBeforeBremRecovery) { + // 1. create EG objects before brem recovery + unsigned int egQual = calo.hwEmID; + // If we write both objects with and without brem-recovery + // bit 3 is used for the brem-recovery bit: if set = no recovery + // (for consistency with the barrel hwQual where by default the brem recovery is done upstream) + if (cfg.writeBeforeBremRecovery && cfg.doBremRecovery) { + egQual = calo.hwEmID | 0x8; + } + + addEgObjsToPF(egstas, egobjs, egeleobjs, emcalo, track, ic, egQual, calo.hwPt, itk); + } + + if (!cfg.doBremRecovery) + continue; + + // check if the cluster has already been used in a brem reclustering + if (emCalo2emCalo[ic] != -1) + continue; + + pt_t ptBremReco = calo.hwPt; + std::vector components; + + for (int jc = ic; jc < nc; ++jc) { + if (emCalo2emCalo[jc] == ic) { + auto &otherCalo = emcalo[jc]; + ptBremReco += otherCalo.hwPt; + components.push_back(jc); + } + } + + // 2. create EG objects with brem recovery + // NOTE: duplicating the object is suboptimal but this is done for keeping things as in TDR code... + addEgObjsToPF(egstas, egobjs, egeleobjs, emcalo, track, ic, calo.hwEmID, ptBremReco, itk, components); + } +} + +EGObjEmu &PFTkEGAlgoEmulator::addEGStaToPF(std::vector &egobjs, + const EmCaloObjEmu &calo, + const unsigned int hwQual, + const pt_t ptCorr, + const std::vector &components) const { + EGObjEmu egsta; + egsta.clear(); + egsta.hwPt = ptCorr; + egsta.hwEta = calo.hwEta; + egsta.hwPhi = calo.hwPhi; + egsta.hwQual = hwQual; + egobjs.push_back(egsta); + + if (debug_ > 2) + dbgCout() << "[REF] EGSta pt: " << egsta.hwPt << " eta: " << egsta.hwEta << " phi: " << egsta.hwPhi + << " qual: " << std::bitset<4>(egsta.hwQual) << " packed: " << egsta.pack().to_string(16) << std::endl; + + return egobjs.back(); +} + +EGIsoObjEmu &PFTkEGAlgoEmulator::addEGIsoToPF(std::vector &egobjs, + const EmCaloObjEmu &calo, + const unsigned int hwQual, + const pt_t ptCorr) const { + EGIsoObjEmu egiso; + egiso.clear(); + egiso.hwPt = ptCorr; + egiso.hwEta = calo.hwEta; + egiso.hwPhi = calo.hwPhi; + unsigned int egHwQual = hwQual; + if (cfg.doEndcapHwQual) { + // 1. zero-suppress the loose EG-ID (bit 1) + // 2. for now use the standalone tight definition (bit 0) to set the tight point for photons (bit 2) + egHwQual = (hwQual & 0x9) | ((hwQual & 0x1) << 2); + } + egiso.hwQual = egHwQual; + egiso.srcCluster = calo.src; + egobjs.push_back(egiso); + + if (debug_ > 2) + dbgCout() << "[REF] EGIsoObjEmu pt: " << egiso.hwPt << " eta: " << egiso.hwEta << " phi: " << egiso.hwPhi + << " qual: " << std::bitset<4>(egiso.hwQual) << " packed: " << egiso.pack().to_string(16) << std::endl; + + return egobjs.back(); +} + +EGIsoEleObjEmu &PFTkEGAlgoEmulator::addEGIsoEleToPF(std::vector &egobjs, + const EmCaloObjEmu &calo, + const TkObjEmu &track, + const unsigned int hwQual, + const pt_t ptCorr) const { + EGIsoEleObjEmu egiso; + egiso.clear(); + egiso.hwPt = ptCorr; + egiso.hwEta = calo.hwEta; + egiso.hwPhi = calo.hwPhi; + unsigned int egHwQual = hwQual; + if (cfg.doEndcapHwQual) { + // 1. zero-suppress the loose EG-ID (bit 1) + // 2. for now use the standalone tight definition (bit 0) to set the tight point for eles (bit 1) + egHwQual = (hwQual & 0x9) | ((hwQual & 0x1) << 1); + } + egiso.hwQual = egHwQual; + egiso.hwDEta = track.hwVtxEta() - egiso.hwEta; + egiso.hwDPhi = abs(track.hwVtxPhi() - egiso.hwPhi); + egiso.hwZ0 = track.hwZ0; + egiso.hwCharge = track.hwCharge; + egiso.srcCluster = calo.src; + egiso.srcTrack = track.src; + egobjs.push_back(egiso); + + if (debug_ > 2) + dbgCout() << "[REF] EGIsoEleObjEmu pt: " << egiso.hwPt << " eta: " << egiso.hwEta << " phi: " << egiso.hwPhi + << " qual: " << std::bitset<4>(egiso.hwQual) << " packed: " << egiso.pack().to_string(16) << std::endl; + + return egobjs.back(); +} + +void PFTkEGAlgoEmulator::addEgObjsToPF(std::vector &egstas, + std::vector &egobjs, + std::vector &egeleobjs, + const std::vector &emcalo, + const std::vector &track, + const int calo_idx, + const unsigned int hwQual, + const pt_t ptCorr, + const int tk_idx, + const std::vector &components) const { + int sta_idx = -1; + if (writeEgSta()) { + addEGStaToPF(egstas, emcalo[calo_idx], hwQual, ptCorr, components); + sta_idx = egstas.size() - 1; + } + EGIsoObjEmu &egobj = addEGIsoToPF(egobjs, emcalo[calo_idx], hwQual, ptCorr); + egobj.sta_idx = sta_idx; + if (tk_idx != -1) { + EGIsoEleObjEmu &eleobj = addEGIsoEleToPF(egeleobjs, emcalo[calo_idx], track[tk_idx], hwQual, ptCorr); + eleobj.sta_idx = sta_idx; + } +} + +void PFTkEGAlgoEmulator::runIso(const PFInputRegion &in, + const std::vector &pvs, + OutputRegion &out) const { + if (cfg.doTkIso) { + compute_isolation(out.egelectron, in.track, cfg.tkIsoParams_tkEle, pvs[0].hwZ0); + compute_isolation(out.egphoton, in.track, cfg.tkIsoParams_tkEm, pvs[0].hwZ0); + } + if (cfg.doPfIso) { + compute_isolation(out.egelectron, out.pfcharged, out.pfneutral, cfg.pfIsoParams_tkEle, pvs[0].hwZ0); + compute_isolation(out.egphoton, out.pfcharged, out.pfneutral, cfg.pfIsoParams_tkEm, pvs[0].hwZ0); + } + + std::for_each(out.egelectron.begin(), out.egelectron.end(), [&](EGIsoEleObjEmu &obj) { + obj.hwIso = obj.hwIsoVar(cfg.hwIsoTypeTkEle); + }); + std::for_each( + out.egphoton.begin(), out.egphoton.end(), [&](EGIsoObjEmu &obj) { obj.hwIso = obj.hwIsoVar(cfg.hwIsoTypeTkEm); }); +} + +void PFTkEGAlgoEmulator::compute_isolation(std::vector &egobjs, + const std::vector &objects, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const { + for (int ic = 0, nc = egobjs.size(); ic < nc; ++ic) { + auto &egphoton = egobjs[ic]; + iso_t sumPt = 0.; + iso_t sumPtPV = 0.; + compute_sumPt(sumPt, sumPtPV, objects, cfg.nTRACK, egphoton, params, z0); + egphoton.setHwIso(EGIsoObjEmu::IsoType::TkIso, sumPt); + egphoton.setHwIso(EGIsoObjEmu::IsoType::TkIsoPV, sumPtPV); + } +} + +void PFTkEGAlgoEmulator::compute_isolation(std::vector &egobjs, + const std::vector &objects, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const { + for (int ic = 0, nc = egobjs.size(); ic < nc; ++ic) { + auto &egele = egobjs[ic]; + iso_t sumPt = 0.; + iso_t sumPtPV = 0.; + compute_sumPt(sumPt, sumPtPV, objects, cfg.nTRACK, egele, params, z0); + egele.setHwIso(EGIsoEleObjEmu::IsoType::TkIso, sumPtPV); + } +} + +void PFTkEGAlgoEmulator::compute_isolation(std::vector &egobjs, + const std::vector &charged, + const std::vector &neutrals, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const { + for (int ic = 0, nc = egobjs.size(); ic < nc; ++ic) { + auto &egphoton = egobjs[ic]; + iso_t sumPt = 0.; + iso_t sumPtPV = 0.; + // FIXME: set max # of PF objects for iso + compute_sumPt(sumPt, sumPtPV, charged, charged.size(), egphoton, params, z0); + compute_sumPt(sumPt, sumPtPV, neutrals, neutrals.size(), egphoton, params, z0); + egphoton.setHwIso(EGIsoObjEmu::IsoType::PfIso, sumPt); + egphoton.setHwIso(EGIsoObjEmu::IsoType::PfIsoPV, sumPtPV); + } +} + +void PFTkEGAlgoEmulator::compute_isolation(std::vector &egobjs, + const std::vector &charged, + const std::vector &neutrals, + const PFTkEGAlgoEmuConfig::IsoParameters ¶ms, + z0_t z0) const { + for (int ic = 0, nc = egobjs.size(); ic < nc; ++ic) { + auto &egele = egobjs[ic]; + iso_t sumPt = 0.; + iso_t sumPtPV = 0.; + compute_sumPt(sumPt, sumPtPV, charged, charged.size(), egele, params, z0); + compute_sumPt(sumPt, sumPtPV, neutrals, neutrals.size(), egele, params, z0); + egele.setHwIso(EGIsoEleObjEmu::IsoType::PfIso, sumPtPV); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/firmware/data.h b/L1Trigger/Phase2L1ParticleFlow/src/firmware/data.h deleted file mode 100644 index c1ccd93ac5812..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/firmware/data.h +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE_DATA_H -#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE_DATA_H - -#include - -typedef ap_int<16> pt_t; -typedef ap_int<10> etaphi_t; -typedef ap_int<5> vtx_t; -typedef ap_uint<3> particleid_t; -typedef ap_int<10> z0_t; // 40cm / 0.1 -typedef ap_uint<14> tk2em_dr_t; -typedef ap_uint<14> tk2calo_dr_t; -typedef ap_uint<10> em2calo_dr_t; -typedef ap_uint<13> tk2calo_dq_t; - -enum PID { PID_Charged = 0, PID_Neutral = 1, PID_Photon = 2, PID_Electron = 3, PID_Muon = 4 }; - -// DEFINE MULTIPLICITIES -#if defined(REG_HGCal) -#define NTRACK 25 -#define NCALO 20 -#define NMU 4 -#define NSELCALO 15 -#define NALLNEUTRALS NSELCALO -// dummy -#define NEMCALO 1 -#define NPHOTON NEMCALO -// not used but must be there because used in header files -#define NNEUTRALS 1 -//-------------------------------- -#elif defined(REG_HGCalNoTK) -#define NCALO 12 -#define NNEUTRALS 8 -#define NALLNEUTRALS NCALO -// dummy -#define NMU 1 -#define NTRACK 1 -#define NEMCALO 1 -#define NPHOTON NEMCALO -#define NSELCALO 1 -//-------------------------------- -#elif defined(REG_HF) -#define NCALO 18 -#define NNEUTRALS 10 -#define NALLNEUTRALS NCALO -// dummy -#define NMU 1 -#define NTRACK 1 -#define NEMCALO 1 -#define NPHOTON NEMCALO -#define NSELCALO 1 -//-------------------------------- -#else // BARREL -#ifndef REG_Barrel -#ifndef CMSSW_GIT_HASH -#warning "No region defined, assuming it's barrel (#define REG_Barrel to suppress this)" -#endif -#endif -#if defined(BOARD_MP7) -#warning "MP7 NOT SUPPORTED ANYMORE" -#define NTRACK 14 -#define NCALO 10 -#define NMU 2 -#define NEMCALO 10 -#define NPHOTON NEMCALO -#define NSELCALO 10 -#define NALLNEUTRALS (NPHOTON + NSELCALO) -#define NNEUTRALS 15 -#elif defined(BOARD_CTP7) -#error "NOT SUPPORTED ANYMORE" -#elif defined(BOARD_KU15P) -#define NTRACK 14 -#define NCALO 10 -#define NMU 2 -#define NEMCALO 10 -#define NPHOTON NEMCALO -#define NSELCALO 10 -#define NALLNEUTRALS (NPHOTON + NSELCALO) -#define NNEUTRALS 15 -#elif defined(BOARD_VCU118) -#define NTRACK 22 -#define NCALO 15 -#define NEMCALO 13 -#define NMU 2 -#define NPHOTON NEMCALO -#define NSELCALO 10 -#define NALLNEUTRALS (NPHOTON + NSELCALO) -#define NNEUTRALS 25 -#else -#define NTRACK 22 -#define NCALO 15 -#define NEMCALO 13 -#define NMU 2 -#define NPHOTON NEMCALO -#define NSELCALO 10 -#define NALLNEUTRALS (NPHOTON + NSELCALO) -#define NNEUTRALS 25 -#endif - -#endif // region - -#if defined(BOARD_MP7) -#define PACKING_DATA_SIZE 32 -#define PACKING_NCHANN 72 -#elif defined(BOARD_KU15P) -#define PACKING_DATA_SIZE 64 -#define PACKING_NCHANN 42 -#elif defined(BOARD_VCU118) -#define PACKING_DATA_SIZE 64 -#define PACKING_NCHANN 96 -#elif defined(BOARD_APD1) -#define PACKING_DATA_SIZE 64 -#define PACKING_NCHANN 96 -#endif - -struct CaloObj { - pt_t hwPt; - etaphi_t hwEta, hwPhi; // relative to the region center, at calo -}; -struct HadCaloObj : public CaloObj { - pt_t hwEmPt; - bool hwIsEM; -}; -inline void clear(HadCaloObj& c) { - c.hwPt = 0; - c.hwEta = 0; - c.hwPhi = 0; - c.hwEmPt = 0; - c.hwIsEM = false; -} - -struct EmCaloObj { - pt_t hwPt, hwPtErr; - etaphi_t hwEta, hwPhi; // relative to the region center, at calo -}; -inline void clear(EmCaloObj& c) { - c.hwPt = 0; - c.hwPtErr = 0; - c.hwEta = 0; - c.hwPhi = 0; -} - -struct TkObj { - pt_t hwPt, hwPtErr; - etaphi_t hwEta, hwPhi; // relative to the region center, at calo - z0_t hwZ0; - bool hwTightQuality; -}; -inline void clear(TkObj& c) { - c.hwPt = 0; - c.hwPtErr = 0; - c.hwEta = 0; - c.hwPhi = 0; - c.hwZ0 = 0; - c.hwTightQuality = false; -} - -struct MuObj { - pt_t hwPt, hwPtErr; - etaphi_t hwEta, hwPhi; // relative to the region center, at vtx(?) -}; -inline void clear(MuObj& c) { - c.hwPt = 0; - c.hwPtErr = 0; - c.hwEta = 0; - c.hwPhi = 0; -} - -struct PFChargedObj { - pt_t hwPt; - etaphi_t hwEta, hwPhi; // relative to the region center, at calo - particleid_t hwId; - z0_t hwZ0; -}; -inline void clear(PFChargedObj& c) { - c.hwPt = 0; - c.hwEta = 0; - c.hwPhi = 0; - c.hwId = 0; - c.hwZ0 = 0; -} - -struct PFNeutralObj { - pt_t hwPt; - etaphi_t hwEta, hwPhi; // relative to the region center, at calo - particleid_t hwId; - pt_t hwPtPuppi; -}; -inline void clear(PFNeutralObj& c) { - c.hwPt = 0; - c.hwEta = 0; - c.hwPhi = 0; - c.hwId = 0; - c.hwPtPuppi = 0; -} - -//TMUX -#define NETA_TMUX 2 -#define NPHI_TMUX 1 -/* #define TMUX_IN 36 */ -/* #define TMUX_OUT 18 */ -#define TMUX_IN 18 -#define TMUX_OUT 6 -#define NTRACK_TMUX (NTRACK * TMUX_OUT * NETA_TMUX * NPHI_TMUX) -#define NCALO_TMUX (NCALO * TMUX_OUT * NETA_TMUX * NPHI_TMUX) -#define NEMCALO_TMUX (NEMCALO * TMUX_OUT * NETA_TMUX * NPHI_TMUX) -#define NMU_TMUX (NMU * TMUX_OUT * NETA_TMUX * NPHI_TMUX) - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo2hgc.h b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo2hgc.h deleted file mode 100644 index 3d36fa37c2b0c..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo2hgc.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO2HGC_H -#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO2HGC_H - -#include "pfalgo_common.h" - -void pfalgo2hgc(const HadCaloObj calo[NCALO], - const TkObj track[NTRACK], - const MuObj mu[NMU], - PFChargedObj outch[NTRACK], - PFNeutralObj outne[NSELCALO], - PFChargedObj outmu[NMU]); - -#if defined(PACKING_DATA_SIZE) && defined(PACKING_NCHANN) -void packed_pfalgo2hgc(const ap_uint input[PACKING_NCHANN], - ap_uint output[PACKING_NCHANN]); -void pfalgo2hgc_pack_in(const HadCaloObj calo[NCALO], - const TkObj track[NTRACK], - const MuObj mu[NMU], - ap_uint input[PACKING_NCHANN]); -void pfalgo2hgc_unpack_in(const ap_uint input[PACKING_NCHANN], - HadCaloObj calo[NCALO], - TkObj track[NTRACK], - MuObj mu[NMU]); -void pfalgo2hgc_pack_out(const PFChargedObj outch[NTRACK], - const PFNeutralObj outne[NSELCALO], - const PFChargedObj outmu[NMU], - ap_uint output[PACKING_NCHANN]); -void pfalgo2hgc_unpack_out(const ap_uint output[PACKING_NCHANN], - PFChargedObj outch[NTRACK], - PFNeutralObj outne[NSELCALO], - PFChargedObj outmu[NMU]); -#endif - -#ifndef CMSSW_GIT_HASH -#define PFALGO_DR2MAX_TK_CALO 525 -#define PFALGO_TK_MAXINVPT_LOOSE 40 -#define PFALGO_TK_MAXINVPT_TIGHT 80 -#endif - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo3.h b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo3.h deleted file mode 100644 index cc7c48bff14d4..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo3.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO3_H -#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO3_H - -#include "pfalgo_common.h" - -void pfalgo3(const EmCaloObj emcalo[NEMCALO], - const HadCaloObj hadcalo[NCALO], - const TkObj track[NTRACK], - const MuObj mu[NMU], - PFChargedObj outch[NTRACK], - PFNeutralObj outpho[NPHOTON], - PFNeutralObj outne[NSELCALO], - PFChargedObj outmu[NMU]); - -#if defined(PACKING_DATA_SIZE) && defined(PACKING_NCHANN) -void packed_pfalgo3(const ap_uint input[PACKING_NCHANN], - ap_uint output[PACKING_NCHANN]); -void pfalgo3_pack_in(const EmCaloObj emcalo[NEMCALO], - const HadCaloObj hadcalo[NCALO], - const TkObj track[NTRACK], - const MuObj mu[NMU], - ap_uint input[PACKING_NCHANN]); -void pfalgo3_unpack_in(const ap_uint input[PACKING_NCHANN], - EmCaloObj emcalo[NEMCALO], - HadCaloObj hadcalo[NCALO], - TkObj track[NTRACK], - MuObj mu[NMU]); -void pfalgo3_pack_out(const PFChargedObj outch[NTRACK], - const PFNeutralObj outpho[NPHOTON], - const PFNeutralObj outne[NSELCALO], - const PFChargedObj outmu[NMU], - ap_uint output[PACKING_NCHANN]); -void pfalgo3_unpack_out(const ap_uint output[PACKING_NCHANN], - PFChargedObj outch[NTRACK], - PFNeutralObj outpho[NPHOTON], - PFNeutralObj outne[NSELCALO], - PFChargedObj outmu[NMU]); -#endif - -void pfalgo3_set_debug(bool debug); - -#ifndef CMSSW_GIT_HASH -#define PFALGO_DR2MAX_TK_CALO 1182 -#define PFALGO_DR2MAX_EM_CALO 525 -#define PFALGO_DR2MAX_TK_EM 84 -#define PFALGO_TK_MAXINVPT_LOOSE 40 -#define PFALGO_TK_MAXINVPT_TIGHT 80 -#endif - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo_common.h b/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo_common.h deleted file mode 100644 index 5fe4e1181b9db..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/firmware/pfalgo_common.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO_COMMON_H -#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE_PFALGO_COMMON_H - -#include "data.h" - -inline int dr2_int(etaphi_t eta1, etaphi_t phi1, etaphi_t eta2, etaphi_t phi2) { - ap_int deta = (eta1 - eta2); - ap_int dphi = (phi1 - phi2); - return deta * deta + dphi * dphi; -} - -#ifndef CMSSW_GIT_HASH -#define PFALGO_DR2MAX_TK_MU 2101 -#endif - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/jetmet/L1SeedConePFJetEmulator.cc b/L1Trigger/Phase2L1ParticleFlow/src/jetmet/L1SeedConePFJetEmulator.cc new file mode 100644 index 0000000000000..cf54c77a59f13 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/jetmet/L1SeedConePFJetEmulator.cc @@ -0,0 +1,124 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/jetmet/L1SeedConePFJetEmulator.h" + +L1SCJetEmu::L1SCJetEmu(bool debug, float coneSize, unsigned nJets) + : debug_(debug), + coneSize_(coneSize), + nJets_(nJets), + rCone2_(coneSize * coneSize / l1ct::Scales::ETAPHI_LSB / l1ct::Scales::ETAPHI_LSB) { + init_invert_table(inv_pt_table_); +} + +L1SCJetEmu::detaphi_t L1SCJetEmu::deltaPhi(L1SCJetEmu::Particle a, L1SCJetEmu::Particle b) { + detaphi_t dphi = detaphi_t(a.hwPhi) - detaphi_t(b.hwPhi); + // phi wrap + detaphi_t dphi0 = + dphi > detaphi_t(l1ct::Scales::INTPHI_PI) ? detaphi_t(l1ct::Scales::INTPHI_TWOPI - dphi) : detaphi_t(dphi); + detaphi_t dphi1 = + dphi < detaphi_t(-l1ct::Scales::INTPHI_PI) ? detaphi_t(l1ct::Scales::INTPHI_TWOPI + dphi) : detaphi_t(dphi); + detaphi_t dphiw = dphi > detaphi_t(0) ? dphi0 : dphi1; + return dphiw; +} + +bool L1SCJetEmu::inCone(L1SCJetEmu::Particle seed, L1SCJetEmu::Particle part) const { + // scale the particle eta, phi to hardware units + detaphi_t deta = detaphi_t(seed.hwEta) - detaphi_t(part.hwEta); + detaphi_t dphi = deltaPhi(seed, part); + bool ret = deta * deta + dphi * dphi < rCone2_; + //bool ret = r2 < cone2; + if (debug_) { + detaphi2_t r2 = detaphi2_t(deta) * detaphi2_t(deta) + detaphi2_t(dphi) * detaphi2_t(dphi); + dbgCout() << " part eta, seed eta: " << part.hwEta << ", " << seed.hwEta << std::endl; + dbgCout() << " part phi, seed phi: " << part.hwPhi << ", " << seed.hwPhi << std::endl; + dbgCout() << " pt, deta, dphi, r2, cone2, lt: " << part.hwPt << ", " << deta << ", " << dphi << ", " + << deta * deta + dphi * dphi << ", " << rCone2_ << ", " << ret << std::endl; + } + return ret; +} + +L1SCJetEmu::Jet L1SCJetEmu::makeJet_HW(const std::vector& parts) const { + // Seed Cone Jet algorithm with ap_fixed types and hardware emulation + Particle seed = reduce(parts, op_max); + + // Event with saturation, order of terms doesn't matter since they're all positive + auto sumpt = [](pt_t(a), const Particle& b) { return a + b.hwPt; }; + + // Sum the pt + pt_t pt = std::accumulate(parts.begin(), parts.end(), pt_t(0), sumpt); + inv_pt_t inv_pt = invert_with_shift(pt, inv_pt_table_, false); + + // pt weighted d eta + std::vector pt_deta; + pt_deta.resize(parts.size()); + std::transform(parts.begin(), parts.end(), pt_deta.begin(), [&seed, &pt](const Particle& part) { + // In the firmware we calculate the per-particle pt-weighted deta + return pt_etaphi_t(part.hwPt * detaphi_t(part.hwEta - seed.hwEta)); + }); + // Accumulate the pt-weighted etas. Init to 0, include seed in accumulation + pt_etaphi_t sum_pt_eta = std::accumulate(pt_deta.begin(), pt_deta.end(), pt_etaphi_t(0)); + etaphi_t eta = seed.hwEta + etaphi_t(sum_pt_eta * inv_pt); + + // pt weighted d phi + std::vector pt_dphi; + pt_dphi.resize(parts.size()); + std::transform(parts.begin(), parts.end(), pt_dphi.begin(), [&seed, &pt](const Particle& part) { + // In the firmware we calculate the per-particle pt-weighted dphi + return pt_etaphi_t(part.hwPt * deltaPhi(part, seed)); + }); + // Accumulate the pt-weighted phis. Init to 0, include seed in accumulation + pt_etaphi_t sum_pt_phi = std::accumulate(pt_dphi.begin(), pt_dphi.end(), pt_etaphi_t(0)); + etaphi_t phi = seed.hwPhi + etaphi_t(sum_pt_phi * inv_pt); + + Jet jet; + jet.hwPt = pt; + jet.hwEta = eta; + jet.hwPhi = phi; + jet.constituents = parts; + + if (debug_) { + std::for_each(pt_dphi.begin(), pt_dphi.end(), [](pt_etaphi_t& x) { dbgCout() << "pt_dphi: " << x << std::endl; }); + std::for_each(pt_deta.begin(), pt_deta.end(), [](pt_etaphi_t& x) { dbgCout() << "pt_deta: " << x << std::endl; }); + dbgCout() << " sum_pt_eta: " << sum_pt_eta << ", 1/pt: " << inv_pt + << ", sum_pt_eta * 1/pt: " << etaphi_t(sum_pt_eta * inv_pt) << std::endl; + dbgCout() << " sum_pt_phi: " << sum_pt_phi << ", 1/pt: " << inv_pt + << ", sum_pt_phi * 1/pt: " << etaphi_t(sum_pt_phi * inv_pt) << std::endl; + dbgCout() << " uncorr eta: " << seed.hwEta << ", phi: " << seed.hwPhi << std::endl; + dbgCout() << " corr eta: " << eta << ", phi: " << phi << std::endl; + dbgCout() << " pt: " << pt << std::endl; + } + + return jet; +} + +std::vector L1SCJetEmu::emulateEvent(std::vector& parts) const { + // The fixed point algorithm emulation + std::vector work; + work.resize(parts.size()); + std::transform(parts.begin(), parts.end(), work.begin(), [](const Particle& part) { return part; }); + + std::vector jets; + jets.reserve(nJets_); + while (!work.empty() && jets.size() < nJets_) { + // Take the highest pt candidate as a seed + // Use the firmware reduce function to find the same seed as the firmware + // in case there are multiple seeds with the same pT + Particle seed = reduce(work, op_max); + + // Get the particles within a coneSize_ of the seed + std::vector particlesInCone; + std::copy_if(work.begin(), work.end(), std::back_inserter(particlesInCone), [&](const Particle& part) { + return inCone(seed, part); + }); + if (debug_) { + dbgCout() << "Seed: " << seed.hwPt << ", " << seed.hwEta << ", " << seed.hwPhi << std::endl; + std::for_each(particlesInCone.begin(), particlesInCone.end(), [&](Particle& part) { + dbgCout() << " Part: " << part.hwPt << ", " << part.hwEta << ", " << part.hwPhi << std::endl; + inCone(seed, part); + }); + } + jets.push_back(makeJet_HW(particlesInCone)); + // remove the clustered particles + work.erase(std::remove_if(work.begin(), work.end(), [&](const Particle& part) { return inCone(seed, part); }), + work.end()); + } + return jets; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/hgcalinputt_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/hgcalinputt_ref.cpp new file mode 100644 index 0000000000000..d1777586ca753 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/hgcalinputt_ref.cpp @@ -0,0 +1,21 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/hgcalinput_ref.h" + +l1ct::HgcalClusterDecoderEmulator::~HgcalClusterDecoderEmulator() {} + +l1ct::HadCaloObjEmu l1ct::HgcalClusterDecoderEmulator::decode(const ap_uint<256> &in) const { + ap_uint<14> w_pt = in(13, 0); + ap_uint<14> w_empt = in(27, 14); + ap_int<9> w_eta = in(72, 64); + ap_int<9> w_phi = in(81, 73); + ap_uint<10> w_qual = in(115, 106); + + l1ct::HadCaloObjEmu out; + out.clear(); + out.hwPt = w_pt * l1ct::pt_t(l1ct::Scales::INTPT_LSB); + out.hwEta = w_eta; + out.hwPhi = w_phi; // relative to the region center, at calo + out.hwEmPt = w_empt * l1ct::pt_t(l1ct::Scales::INTPT_LSB); + out.hwEmID = w_qual; + + return out; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/muonGmtToL1ct_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/muonGmtToL1ct_ref.cpp new file mode 100644 index 0000000000000..0c3ddda6a1c43 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/muonGmtToL1ct_ref.cpp @@ -0,0 +1,57 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/muonGmtToL1ct_ref.h" + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::GMTMuonDecoderEmulator::GMTMuonDecoderEmulator(const edm::ParameterSet &iConfig) + : z0Scale_(iConfig.getParameter("z0Scale")), dxyScale_(iConfig.getParameter("dxyScale")) {} + +#endif + +l1ct::GMTMuonDecoderEmulator::GMTMuonDecoderEmulator(float z0Scale, float dxyScale) + : z0Scale_(z0Scale), dxyScale_(dxyScale) {} + +l1ct::GMTMuonDecoderEmulator::~GMTMuonDecoderEmulator() {} + +l1ct::MuObjEmu l1ct::GMTMuonDecoderEmulator::decode(const ap_uint<64> &in) const { + typedef ap_ufixed<13, 8, AP_TRN, AP_SAT> gmt_pt_t; + + const int etaPhi_common_bits = 4, etaPhi_extra_bits = 12 - etaPhi_common_bits; + const int etaPhi_scale = l1ct::Scales::INTPHI_PI >> etaPhi_common_bits; + const int etaPhi_offs = 1 << (etaPhi_extra_bits - 1); + + const int z0_scale = std::round(z0Scale_ / l1ct::Scales::Z0_LSB); + const int dxy_scale = std::round(dxyScale_ / l1ct::Scales::DXY_LSB); + + bool gmt_valid = in[0], gmt_chg = in[56]; + ap_uint<13> gmt_ipt = in(16, 1); + ap_int<13> gmt_phi = in(29, 17); + ap_int<14> gmt_eta = in(43, 30); + ap_int<5> gmt_z0 = in(48, 44); + ap_int<7> gmt_d0 = in(55, 49); + ap_uint<4> gmt_qual = in(60, 57); + + gmt_pt_t gmt_pt; + gmt_pt(gmt_pt_t::width - 1, 0) = gmt_ipt(gmt_pt_t::width - 1, 0); // copy the bits + + l1ct::MuObjEmu out; + out.clear(); + if (gmt_valid && gmt_pt != 0) { + // add a shift in order to get the proper rounding + out.hwPt = gmt_pt + gmt_pt_t(l1ct::Scales::INTPT_LSB / 2); + + out.hwEta = (gmt_eta * etaPhi_scale + etaPhi_offs) >> etaPhi_extra_bits; + out.hwPhi = (gmt_phi * etaPhi_scale + etaPhi_offs) >> etaPhi_extra_bits; + out.hwDEta = 0; + out.hwDPhi = 0; + + out.hwCharge = !gmt_chg; + + out.hwZ0 = gmt_z0 * z0_scale; + out.hwDxy = gmt_d0 * dxy_scale; + + out.hwQuality = gmt_qual(3, 1); // drop lowest bit + } + + return out; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/tkinput_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/tkinput_ref.cpp new file mode 100644 index 0000000000000..4f707e49cc3cc --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/l1-converters/tkinput_ref.cpp @@ -0,0 +1,676 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/l1-converters/tkinput_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#include +#include +#include + +#ifdef CMSSW_GIT_HASH +#include +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +namespace { + l1ct::TrackInputEmulator::Region parseRegion(const std::string &str) { + if (str == "barrel") + return l1ct::TrackInputEmulator::Region::Barrel; + else if (str == "endcap") + return l1ct::TrackInputEmulator::Region::Endcap; + else if (str == "any") + return l1ct::TrackInputEmulator::Region::Any; + else + throw cms::Exception("Configuration", "TrackInputEmulator: Unsupported region '" + str + "'\n"); + } + l1ct::TrackInputEmulator::Encoding parseEncoding(const std::string &str) { + if (str == "stepping") + return l1ct::TrackInputEmulator::Encoding::Stepping; + else if (str == "biased") + return l1ct::TrackInputEmulator::Encoding::Biased; + else if (str == "unbised") + return l1ct::TrackInputEmulator::Encoding::Unbiased; + else + throw cms::Exception("Configuration", "TrackInputEmulator: Unsupported track word encoding '" + str + "'\n"); + } +} // namespace + +l1ct::TrackInputEmulator::TrackInputEmulator(const edm::ParameterSet &iConfig) + : TrackInputEmulator(parseRegion(iConfig.getParameter("region")), + parseEncoding(iConfig.getParameter("trackWordEncoding")), + iConfig.getParameter("bitwiseAccurate")) { + if (region_ != Region::Endcap && region_ != Region::Barrel) { + edm::LogError("TrackInputEmulator") << "region '" << iConfig.getParameter("region") + << "' is not yet supported"; + } + debug_ = iConfig.getUntrackedParameter("debug", false); + configPt(iConfig.getParameter("ptLUTBits")); + configEta(iConfig.getParameter("etaLUTBits"), + iConfig.getParameter("etaPreOffs"), + iConfig.getParameter("etaShift"), + iConfig.getParameter("etaPostOffs"), + iConfig.getParameter("etaSigned"), + region_ == Region::Endcap); + configPhi(iConfig.getParameter("phiBits")); + configZ0(iConfig.getParameter("z0Bits")); + if (region_ == Region::Barrel) { + configDEtaBarrel(iConfig.getParameter("dEtaBarrelBits"), + iConfig.getParameter("dEtaBarrelZ0PreShift"), + iConfig.getParameter("dEtaBarrelZ0PostShift"), + iConfig.getParameter("dEtaBarrelFloatOffs")); + configDPhiBarrel(iConfig.getParameter("dPhiBarrelBits"), + iConfig.getParameter("dPhiBarrelRInvPreShift"), + iConfig.getParameter("dPhiBarrelRInvPostShift"), + iConfig.getParameter("dPhiBarrelFloatOffs")); + } + if (region_ == Region::Endcap) { + configDEtaHGCal(iConfig.getParameter("dEtaHGCalBits"), + iConfig.getParameter("dEtaHGCalZ0PreShift"), + iConfig.getParameter("dEtaHGCalRInvPreShift"), + iConfig.getParameter("dEtaHGCalLUTBits"), + iConfig.getParameter("dEtaHGCalLUTShift"), + iConfig.getParameter("dEtaHGCalFloatOffs")); + configDPhiHGCal(iConfig.getParameter("dPhiHGCalBits"), + iConfig.getParameter("dPhiHGCalZ0PreShift"), + iConfig.getParameter("dPhiHGCalZ0PostShift"), + iConfig.getParameter("dPhiHGCalRInvShift"), + iConfig.getParameter("dPhiHGCalTanlInvShift"), + iConfig.getParameter("dPhiHGCalTanlLUTBits"), + iConfig.getParameter("dPhiHGCalFloatOffs")); + } +} + +#endif + +l1ct::TrackInputEmulator::TrackInputEmulator(Region region, Encoding encoding, bool bitwise) + : region_(region), + encoding_(encoding), + bitwise_(bitwise), + rInvToPt_(31199.5), + phiScale_(0.00038349520), + z0Scale_(0.00999469), + dEtaBarrelParamZ0_(0.31735), + dPhiBarrelParamC_(0.0056535), + dEtaHGCalParamZ0_(-0.00655), + dEtaHGCalParamRInv2C_(+0.66), + dEtaHGCalParamRInv2ITanl1_(-0.72), + dEtaHGCalParamRInv2ITanl2_(-0.38), + dPhiHGCalParamZ0_(0.00171908), + dPhiHGCalParamC_(56.5354), + debug_(false) {} + +std::pair l1ct::TrackInputEmulator::decodeTrack(ap_uint<96> tkword, + const l1ct::PFRegionEmu §or, + bool bitwise) const { + l1ct::TkObjEmu ret; + ret.clear(); + auto z0 = signedZ0(tkword); + auto tanl = signedTanl(tkword); + auto Rinv = signedRinv(tkword); + auto phi = signedPhi(tkword); + + bool okprop = false, oksel = false; + switch (region_) { + case Region::Barrel: + okprop = withinBarrel(tanl); + break; + case Region::Endcap: + okprop = mayReachHGCal(tanl) && withinTracker(tanl); + break; + case Region::Any: + okprop = withinTracker(tanl); + break; + } + + if (valid(tkword) && okprop) { + ret.hwQuality = tkword(2, 0); + ret.hwCharge = charge(tkword); + + if (bitwise) { + ret.hwPt = convPt(Rinv); + + l1ct::glbeta_t vtxEta = convEta(tanl); + l1ct::phi_t vtxPhi = convPhi(phi); + + // track propagation + if (region_ == Region::Barrel) { + ret.hwDEta = calcDEtaBarrel(z0, Rinv, tanl); + ret.hwDPhi = calcDPhiBarrel(z0, Rinv, tanl); + } + + if (region_ == Region::Endcap) { + ret.hwDEta = calcDEtaHGCal(z0, Rinv, tanl); + ret.hwDPhi = calcDPhiHGCal(z0, Rinv, tanl); + } + + ret.hwEta = vtxEta - ret.hwDEta; + ret.hwPhi = vtxPhi - ret.hwDPhi * ret.intCharge(); + ret.hwZ0 = convZ0(z0); + } else { + ret.hwPt = l1ct::Scales::makePtFromFloat(floatPt(Rinv)); + + float fvtxEta = floatEta(tanl) / l1ct::Scales::ETAPHI_LSB; + float fvtxPhi = floatPhi(phi) / l1ct::Scales::ETAPHI_LSB; + + // track propagation + float fDEta = 0, fDPhi = 0; // already in layer-1 units + if (region_ == Region::Barrel) { + fDEta = floatDEtaBarrel(z0, Rinv, tanl); + fDPhi = floatDPhiBarrel(z0, Rinv, tanl); + } + + if (region_ == Region::Endcap) { + fDEta = floatDEtaHGCal(z0, Rinv, tanl); + fDPhi = floatDPhiHGCal(z0, Rinv, tanl); + } + + ret.hwDPhi = std::round(fDPhi); + ret.hwDEta = std::round(fDEta); + ret.hwPhi = std::round(fvtxPhi - fDPhi * ret.intCharge()); + ret.hwEta = glbeta_t(std::round(fvtxEta)) - ret.hwDEta - sector.hwEtaCenter; + + ret.hwZ0 = l1ct::Scales::makeZ0(floatZ0(z0)); + } + + oksel = ret.hwQuality != 0; + } + return std::make_pair(ret, oksel); +} + +float l1ct::TrackInputEmulator::floatPt(ap_int<15> Rinv) const { return rInvToPt_ / std::abs(toFloat_(Rinv)); } + +l1ct::pt_t l1ct::TrackInputEmulator::convPt(ap_int<15> Rinv) const { + ap_uint<14> absRinv = (Rinv >= 0 ? ap_uint<14>(Rinv) : ap_uint<14>(-Rinv)); + unsigned int index = absRinv.to_int() >> ptLUTShift_; + if (index >= ptLUT_.size()) { + dbgPrintf("WARN: Rinv %d, absRinv %d, index %d, size %lu, shift %d\n", + Rinv.to_int(), + absRinv.to_int(), + index, + ptLUT_.size(), + ptLUTShift_); + index = ptLUT_.size() - 1; + } + return ptLUT_[index]; +} + +void l1ct::TrackInputEmulator::configPt(int lutBits) { + ptLUTShift_ = 14 - lutBits; + ptLUT_.resize(1 << lutBits); + for (unsigned int u = 0, n = ptLUT_.size(); u < n; ++u) { + int iRinv = std::round((u + 0.5) * (1 << ptLUTShift_)); + ptLUT_[u] = l1ct::Scales::makePtFromFloat(floatPt(iRinv)); + } +} + +float l1ct::TrackInputEmulator::floatEta(ap_int<16> tanl) const { + float lam = std::atan(floatTanl(tanl)); + float theta = M_PI / 2 - lam; + return -std::log(std::tan(0.5 * theta)); +} + +l1ct::glbeta_t l1ct::TrackInputEmulator::convEta(ap_int<16> tanl) const { + unsigned int index; + if (tanlLUTSigned_) { + index = std::max(0, std::abs(tanl.to_int()) - tanlLUTPreOffs_) >> tanlLUTShift_; + } else { + ap_uint<16> unsTanl = tanl(15, 0); + index = unsTanl.to_int() >> tanlLUTShift_; + } + if (index >= tanlLUT_.size()) { + dbgPrintf( + "WARN: tanl %d, index %d, size %lu (signed %d)\n", tanl.to_int(), index, tanlLUT_.size(), int(tanlLUTSigned_)); + index = tanlLUT_.size() - 1; + } + int ret = tanlLUT_[index] + tanlLUTPostOffs_; + if (tanlLUTSigned_ && tanl < 0) + ret = -ret; + if (debug_) + dbgPrintf("convEta: itanl = %+8d -> index %8d, LUT %8d, ret %+8d\n", tanl.to_int(), index, tanlLUT_[index], ret); + return ret; +} + +void l1ct::TrackInputEmulator::configEta( + int lutBits, int preOffs, int shift, int postOffs, bool lutSigned, bool endcap) { + tanlLUTSigned_ = lutSigned; + tanlLUTPreOffs_ = preOffs; + tanlLUTPostOffs_ = postOffs; + tanlLUTShift_ = shift; + tanlLUT_.resize(1 << lutBits); + int etaCenter = lutSigned ? l1ct::Scales::makeGlbEtaRoundEven(2.5).to_int() / 2 : 0; + int etamin = 1, etamax = -1; + for (unsigned int u = 0, n = tanlLUT_.size(), h = n / 2; u < n; ++u) { + int i = (tanlLUTSigned_ || (u < h)) ? int(u) : int(u) - int(n); + ap_int<16> tanl = std::min(i * (1 << shift) + preOffs, (1 << 16) - 1); + int eta = l1ct::Scales::makeGlbEta(floatEta(tanl)).to_int() - etaCenter - tanlLUTPostOffs_; + bool valid = endcap ? (mayReachHGCal(tanl) && withinTracker(tanl)) : withinBarrel(tanl); + if (valid) { + tanlLUT_[u] = eta; + if (etamin > etamax) { + etamin = eta; + etamax = eta; + } else { + etamin = std::min(etamin, eta); + etamax = std::max(etamax, eta); + } + } else { + tanlLUT_[u] = 0; + } + } + if (debug_) + dbgPrintf( + "Configured with glbEtaCenter = %d, bits %d, preOffs %d, shift %d, postOffs %d, lutmin = %d, lutmax = %d\n", + etaCenter, + lutBits, + preOffs, + shift, + postOffs, + etamin, + etamax); +} + +float l1ct::TrackInputEmulator::floatPhi(ap_int<12> phi) const { return phiScale_ * toFloat_(phi); } + +l1ct::phi_t l1ct::TrackInputEmulator::convPhi(ap_int<12> phi) const { + int offs = phi >= 0 ? vtxPhiOffsPos_ : vtxPhiOffsNeg_; + return (phi.to_int() * vtxPhiMult_ + offs) >> vtxPhiBitShift_; +} + +void l1ct::TrackInputEmulator::configPhi(int bits) { + float scale = phiScale_ / l1ct::Scales::ETAPHI_LSB; + vtxPhiBitShift_ = bits; + vtxPhiMult_ = std::round(scale * (1 << bits)); + switch (encoding_) { + case Encoding::Stepping: + vtxPhiOffsPos_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); + vtxPhiOffsNeg_ = std::round(-scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); + break; + case Encoding::Biased: + vtxPhiOffsPos_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); + vtxPhiOffsNeg_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); + break; + case Encoding::Unbiased: + vtxPhiOffsPos_ = (1 << (bits - 1)); + vtxPhiOffsNeg_ = (1 << (bits - 1)); + break; + } + if (debug_) + dbgPrintf("Configured vtxPhi with scale %d [to_cmssw %.8f, to_l1ct %.8f, %d bits], offsets %+d (pos), %+d (neg)\n", + vtxPhiMult_, + phiScale_, + scale, + bits, + vtxPhiOffsPos_, + vtxPhiOffsNeg_); +} + +float l1ct::TrackInputEmulator::floatZ0(ap_int<12> z0) const { return z0Scale_ * toFloat_(z0); } + +l1ct::z0_t l1ct::TrackInputEmulator::convZ0(ap_int<12> z0) const { + int offs = z0 >= 0 ? z0OffsPos_ : z0OffsNeg_; + return (z0.to_int() * z0Mult_ + offs) >> z0BitShift_; +} + +void l1ct::TrackInputEmulator::configZ0(int bits) { + float scale = z0Scale_ / l1ct::Scales::Z0_LSB; + z0BitShift_ = bits; + z0Mult_ = std::round(scale * (1 << bits)); + switch (encoding_) { + case Encoding::Stepping: + z0OffsPos_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); + z0OffsNeg_ = std::round(-scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); + break; + case Encoding::Biased: + z0OffsPos_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); + z0OffsNeg_ = std::round(+scale * 0.5 * (1 << bits) + 0.5 * (1 << bits)); + break; + case Encoding::Unbiased: + z0OffsPos_ = (1 << (bits - 1)); + z0OffsNeg_ = (1 << (bits - 1)); + break; + } + + if (debug_) + dbgPrintf("Configured z0 with scale %d [to_cmssw %.8f, to_l1ct %.8f, %d bits], offsets %+d (pos), %+d (neg)\n", + z0Mult_, + z0Scale_, + scale, + bits, + z0OffsPos_, + z0OffsNeg_); +} + +float l1ct::TrackInputEmulator::floatDEtaBarrel(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const { + float ret = floatEta(tanl) - floatEta(tanl + z0.to_float() * dEtaBarrelParamZ0_); + if (debug_) { + dbgPrintf( + "flt deta for z0 %+6d Rinv %+6d tanl %+6d: eta(calo) %+8.2f eta(vtx) %+8.3f ret " + "%+8.2f\n", + z0.to_int(), + Rinv.to_int(), + tanl.to_int(), + floatEta(tanl + z0.to_float() * dEtaBarrelParamZ0_), + floatEta(tanl), + ret); + } + return ret / l1ct::Scales::ETAPHI_LSB; +} + +l1ct::tkdeta_t l1ct::TrackInputEmulator::calcDEtaBarrel(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const { + int vtxEta = convEta(tanl); + + ap_uint<14> absZ0 = z0 >= 0 ? ap_uint<14>(z0) : ap_uint<14>(-z0); + int preSum = ((absZ0 >> dEtaBarrelZ0PreShift_) * dEtaBarrelZ0_) >> dEtaBarrelZ0PostShift_; + + int caloEta = convEta(tanl + (z0 > 0 ? 1 : -1) * ((preSum + dEtaBarrelOffs_) >> dEtaBarrelBits_)); + + int ret = vtxEta - caloEta; + if (debug_) { + dbgPrintf( + "int deta for z0 %+6d Rinv %+6d tanl %+6d: preSum %+8.2f eta(calo) %+8.2f eta(vtx) %+8.3f ret " + "%+8.2f\n", + z0.to_int(), + Rinv.to_int(), + tanl.to_int(), + preSum, + caloEta, + vtxEta, + ret); + } + return ret; +} + +//use eta LUTs +void l1ct::TrackInputEmulator::configDEtaBarrel(int dEtaBarrelBits, + int dEtaBarrelZ0PreShift, + int dEtaBarrelZ0PostShift, + float offs) { + dEtaBarrelBits_ = dEtaBarrelBits; + + dEtaBarrelZ0PreShift_ = dEtaBarrelZ0PreShift; + dEtaBarrelZ0PostShift_ = dEtaBarrelZ0PostShift; + dEtaBarrelZ0_ = + std::round(dEtaBarrelParamZ0_ * (1 << (dEtaBarrelZ0PreShift + dEtaBarrelZ0PostShift + dEtaBarrelBits))); + + int finalShift = dEtaBarrelBits_; + dEtaBarrelOffs_ = std::round((1 << finalShift) * (0.5 + offs)); + + if (debug_) + dbgPrintf("Configured deta with %d bits: preshift %8d postshift %8d, offset %8d\n", + dEtaBarrelBits, + dEtaBarrelZ0PreShift_, + dEtaBarrelZ0PostShift_, + offs); + + assert(finalShift >= 0); +} + +float l1ct::TrackInputEmulator::floatDPhiBarrel(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const { + float ret = dPhiBarrelParamC_ * std::abs(Rinv.to_int()); + //ret = atan(ret / sqrt(1-ret*ret)); //use linear approx for now + if (debug_) { + dbgPrintf("flt dphi for z0 %+6d Rinv %+6d tanl %+6d: Rinv/1k %8.2f ret %8.2f\n", + z0.to_int(), + Rinv.to_int(), + tanl.to_int(), + std::abs(Rinv.to_int()) / 1024.0, + ret); + } + return ret; +} + +l1ct::tkdphi_t l1ct::TrackInputEmulator::calcDPhiBarrel(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const { + ap_uint<14> absRinv = Rinv >= 0 ? ap_uint<14>(Rinv) : ap_uint<14>(-Rinv); + int preSum = ((absRinv >> dPhiBarrelRInvPreShift_) * dPhiBarrelC_) >> dPhiBarrelRInvPostShift_; + + if (debug_) { + dbgPrintf("int dphi for z0 %+6d Rinv %+6d tanl %+6d: ret %8.2f\n", + z0.to_int(), + Rinv.to_int(), + tanl.to_int(), + (preSum + dPhiBarrelOffs_) >> dPhiBarrelBits_); + } + + return (preSum + dPhiBarrelOffs_) >> dPhiBarrelBits_; +} + +//using DSPs +void l1ct::TrackInputEmulator::configDPhiBarrel(int dPhiBarrelBits, + int dPhiBarrelRInvPreShift, + int dPhiBarrelRInvPostShift, + float offs) { + dPhiBarrelBits_ = dPhiBarrelBits; + + dPhiBarrelRInvPreShift_ = dPhiBarrelRInvPreShift; + dPhiBarrelRInvPostShift_ = dPhiBarrelRInvPostShift; + dPhiBarrelC_ = + std::round(dPhiBarrelParamC_ * (1 << (dPhiBarrelRInvPreShift + dPhiBarrelRInvPostShift + dPhiBarrelBits))); + + int finalShift = dPhiBarrelBits_; + dPhiBarrelOffs_ = std::round((1 << finalShift) * (0.5 + offs)); + + if (debug_) + dbgPrintf("Configured dphi with %d bits: preshift %8d postshift %8d, offset %8d\n", + dPhiBarrelBits, + dPhiBarrelRInvPreShift_, + dPhiBarrelRInvPostShift_, + offs); + + assert(finalShift >= 0); +} + +float l1ct::TrackInputEmulator::floatDEtaHGCal(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const { + float RinvScaled = Rinv.to_float() / (16 * 1024.0), RinvScaled2 = RinvScaled * RinvScaled; + float invtanlScaled = (32 * 1024.0) / std::abs(tanl.to_float()), invtanlScaled2 = invtanlScaled * invtanlScaled; + float tanlTerm = (tanl > 0 ? 1 : -1) * (dEtaHGCalParamRInv2C_ + dEtaHGCalParamRInv2ITanl1_ * invtanlScaled + + dEtaHGCalParamRInv2ITanl2_ * invtanlScaled2); + float ret = dEtaHGCalParamZ0_ * z0.to_float() + tanlTerm * RinvScaled2; + if (debug_) { + dbgPrintf( + "flt deta for z0 %+6d Rinv %+6d tanl %+6d: z0term %+8.2f rinv2u %.4f tanlterm %+8.3f (pre: %+8.2f) ret " + "%+8.2f\n", + z0.to_int(), + Rinv.to_int(), + tanl.to_int(), + dEtaHGCalParamZ0_ * z0.to_float(), + RinvScaled2, + tanlTerm * RinvScaled2, + tanlTerm, + ret); + } + return ret; +} + +l1ct::tkdeta_t l1ct::TrackInputEmulator::calcDEtaHGCal(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const { + int z0Term = dEtaHGCalZ0_ * (z0 >> dEtaHGCalZ0PreShift_); + + int rinvShift = Rinv.to_int() >> dEtaHGCalRInvPreShift_, rinvShift2 = rinvShift * rinvShift; + + ap_uint<16> unsTanl = tanl(15, 0); + unsigned int tanlIdx = (unsTanl.to_int()) >> dEtaHGCalTanlShift_; + assert(tanlIdx < dEtaHGCalLUT_.size()); + int tanlTerm = (rinvShift2 * dEtaHGCalLUT_[tanlIdx] + dEtaHGCalTanlTermOffs_) >> dEtaHGCalTanlTermShift_; + + int ret0 = z0Term + tanlTerm + dEtaHGCalOffs_; + if (debug_) { + dbgPrintf( + "int deta for z0 %+6d Rinv %+6d tanl %+6d: z0term %+8.2f rinv2u %.4f tanlterm %+8.2f (pre: %+8.2f) ret " + "%+8.2f\n", + z0.to_int(), + Rinv.to_int(), + tanl.to_int(), + float(z0Term) / (1 << dEtaHGCalBits_), + float(rinvShift2) / (1 << (28 - 2 * dEtaHGCalRInvPreShift_)), + float(tanlTerm) / (1 << dEtaHGCalBits_), + float(dEtaHGCalLUT_[tanlIdx]) / (1 << (dEtaHGCalBits_ - dEtaHGCalLUTShift_)), + float(ret0) / (1 << dEtaHGCalBits_)); + } + return (ret0 + (1 << (dEtaHGCalBits_ - 1))) >> dEtaHGCalBits_; +} + +void l1ct::TrackInputEmulator::configDEtaHGCal(int dEtaHGCalBits, + int dEtaHGCalZ0PreShift, + int dEtaHGCalRInvPreShift, + int dEtaHGCalLUTBits, + int dEtaHGCalLUTShift, + float offs) { + dEtaHGCalBits_ = dEtaHGCalBits; + float scale = (1 << dEtaHGCalBits); + + dEtaHGCalZ0PreShift_ = dEtaHGCalZ0PreShift; + dEtaHGCalZ0_ = std::round(dEtaHGCalParamZ0_ * scale * (1 << dEtaHGCalZ0PreShift)); + + dEtaHGCalRInvPreShift_ = dEtaHGCalRInvPreShift; + + dEtaHGCalTanlShift_ = 16 - dEtaHGCalLUTBits; + dEtaHGCalLUT_.resize((1 << dEtaHGCalLUTBits)); + dEtaHGCalLUTShift_ = dEtaHGCalLUTShift; + + dEtaHGCalTanlTermShift_ = 28 - 2 * dEtaHGCalRInvPreShift_ - dEtaHGCalLUTShift_; + dEtaHGCalTanlTermOffs_ = std::round(0.5 * (1 << dEtaHGCalTanlTermShift_)); + int lutmin = 1, lutmax = -1; + float lutScale = scale / (1 << dEtaHGCalLUTShift); + for (unsigned int u = 0, n = dEtaHGCalLUT_.size(), h = n / 2; u < n; ++u) { + int i = (u < h) ? int(u) : int(u) - int(n); + float tanl = (i + 0.5) * (1 << dEtaHGCalTanlShift_); + float sign = tanl >= 0 ? 1 : -1; + float invtanlScaled = 32 * 1024.0 / std::abs(tanl), invtanlScaled2 = invtanlScaled * invtanlScaled; + float term = sign * (dEtaHGCalParamRInv2C_ + dEtaHGCalParamRInv2ITanl1_ * invtanlScaled + + dEtaHGCalParamRInv2ITanl2_ * invtanlScaled2); + int iterm = std::round(lutScale * term); + bool valid = mayReachHGCal(tanl); + if (valid) { + dEtaHGCalLUT_[u] = iterm; + if (lutmin > lutmax) { + lutmin = iterm; + lutmax = iterm; + } else { + lutmin = std::min(lutmin, iterm); + lutmax = std::max(lutmax, iterm); + } + } else { + dEtaHGCalLUT_[u] = 0; + } + } + + dEtaHGCalOffs_ = std::round(scale * offs); + + if (debug_) + dbgPrintf( + "Configured deta with %d bits: z0 %8d [%8.2f], lutmin = %d, lutmax = %d, lutshift %d, rinvShift %d, " + "tanlTermShift %d\n", + dEtaHGCalBits, + dEtaHGCalZ0_, + dEtaHGCalZ0_ / float(scale), + lutmin, + lutmax, + dEtaHGCalLUTShift, + dEtaHGCalRInvPreShift_, + dEtaHGCalTanlTermShift_); +} + +float l1ct::TrackInputEmulator::floatDPhiHGCal(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const { + int dzsign = tanl >= 0 ? +1 : -1; + float ret = + (dPhiHGCalParamC_ - dPhiHGCalParamZ0_ * z0 * dzsign) * std::abs(Rinv.to_int()) / std::abs(tanl.to_float()); + if (debug_) { + dbgPrintf( + "flt dphi for z0 %+6d Rinv %+6d tanl %+6d: preSum %+9.4f Rinv/1k %8.2f 1k/tanl %8.5f ret %8.2f\n", + z0.to_int(), + Rinv.to_int(), + tanl.to_int(), + dPhiHGCalParamC_ - dPhiHGCalParamZ0_ * z0 * dzsign, + std::abs(Rinv.to_int()) / 1024.0, + 1024.0 / std::abs(tanl.to_float()), + ret); + } + return ret; +} + +l1ct::tkdphi_t l1ct::TrackInputEmulator::calcDPhiHGCal(ap_int<12> z0, ap_int<15> Rinv, ap_int<16> tanl) const { + int dzsign = tanl >= 0 ? +1 : -1; + int preSum = (((z0 >> dPhiHGCalZ0PreShift_) * dPhiHGCalZ0_) >> dPhiHGCalZ0PostShift_) * dzsign + dPhiHGCalPreOffs_; + + ap_uint<14> absRinv = Rinv >= 0 ? ap_uint<14>(Rinv) : ap_uint<14>(-Rinv); + int rinvShifted = absRinv.to_int() >> dPhiHGCalRInvShift_; + + ap_uint<15> absTanl = tanl >= 0 ? ap_uint<15>(tanl) : ap_uint<15>(-tanl); + unsigned int tanlIdx = absTanl.to_int() >> dPhiHGCalTanlShift_; + assert(tanlIdx < dPhiHGCalTanlLUT_.size()); + int tanlTerm = dPhiHGCalTanlLUT_[tanlIdx]; + + int finalShift = dPhiHGCalBits_ + dPhiHGCalTanlInvShift_ - dPhiHGCalRInvShift_; + if (debug_) { + dbgPrintf( + "int dphi for z0 %+6d Rinv %+6d tanl %+6d: preSum %+9.4f Rinv/1k %8.2f 1k/tanl %8.5f ret %8.2f: int " + "preSum %8d rivShift %8d tanlTerm %8d\n", + z0.to_int(), + Rinv.to_int(), + tanl.to_int(), + float(preSum) / (1 << dPhiHGCalBits_), + (rinvShifted << dPhiHGCalRInvShift_) / 1024.0, + tanlTerm * 1024.0 / (1 << dPhiHGCalTanlInvShift_), + float(preSum * rinvShifted * tanlTerm) / (1 << finalShift), + preSum, + rinvShifted, + tanlTerm); + } + + return (preSum * rinvShifted * tanlTerm + dPhiHGCalOffs_) >> finalShift; +} + +void l1ct::TrackInputEmulator::configDPhiHGCal(int dPhiHGCalBits, + int dPhiHGCalZ0PreShift, + int dPhiHGCalZ0PostShift, + int dPhiHGCalRInvShift, + int dPhiHGCalTanlInvShift, + int dPhiHGCalTanlLUTBits, + float offs) { + dPhiHGCalBits_ = dPhiHGCalBits; + + dPhiHGCalZ0PreShift_ = dPhiHGCalZ0PreShift; + dPhiHGCalZ0PostShift_ = dPhiHGCalZ0PostShift; + dPhiHGCalZ0_ = -std::round(dPhiHGCalParamZ0_ * (1 << (dPhiHGCalZ0PreShift + dPhiHGCalZ0PostShift + dPhiHGCalBits))); + + dPhiHGCalPreOffs_ = std::round(dPhiHGCalParamC_ * (1 << dPhiHGCalBits)); + + dPhiHGCalRInvShift_ = dPhiHGCalRInvShift; + + dPhiHGCalTanlInvShift_ = dPhiHGCalTanlInvShift; + dPhiHGCalTanlShift_ = 15 - dPhiHGCalTanlLUTBits; + dPhiHGCalTanlLUT_.resize((1 << dPhiHGCalTanlLUTBits)); + int lutmin = 1, lutmax = -1; + for (unsigned int u = 0, n = dPhiHGCalTanlLUT_.size(); u < n; ++u) { + float tanl = (u + 0.5) * (1 << dPhiHGCalTanlShift_); + int iterm = std::round((1 << dPhiHGCalTanlInvShift_) / tanl); + bool valid = mayReachHGCal(tanl); + if (valid) { + dPhiHGCalTanlLUT_[u] = iterm; + if (lutmin > lutmax) { + lutmin = iterm; + lutmax = iterm; + } else { + lutmin = std::min(lutmin, iterm); + lutmax = std::max(lutmax, iterm); + } + } else { + dPhiHGCalTanlLUT_[u] = 0; + } + } + + int finalShift = dPhiHGCalBits_ + dPhiHGCalTanlInvShift_ - dPhiHGCalRInvShift_; + dPhiHGCalOffs_ = std::round((1 << finalShift) * (0.5 + offs)); + + if (debug_) + dbgPrintf( + "Configured dphi with %d bits: z0 %8d [%8.2f], preoffs %8d [%8.2f], final shift %d, lutmin = %d, lutmax = %d\n", + dPhiHGCalBits, + dPhiHGCalZ0_, + dPhiHGCalZ0_ / float(1 << (dPhiHGCalZ0PostShift + dPhiHGCalBits)), + dPhiHGCalPreOffs_, + dPhiHGCalPreOffs_ / float(1 << dPhiHGCalBits), + finalShift, + lutmin, + lutmax); + + assert(finalShift >= 0); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo2hgc_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo2hgc_ref.cpp new file mode 100644 index 0000000000000..ff7fe8b05be2d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo2hgc_ref.cpp @@ -0,0 +1,282 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo2hgc_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#include +#include +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::PFAlgo2HGCEmulator::PFAlgo2HGCEmulator(const edm::ParameterSet& iConfig) + : PFAlgoEmulatorBase(iConfig.getParameter("nTrack"), + iConfig.getParameter("nCalo"), + iConfig.getParameter("nMu"), + iConfig.getParameter("nSelCalo"), + l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter("trackMuDR")), + l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter("trackCaloDR")), + l1ct::Scales::makePtFromFloat(iConfig.getParameter("maxInvisiblePt")), + l1ct::Scales::makePtFromFloat(iConfig.getParameter("tightTrackMaxInvisiblePt"))) { + debug_ = iConfig.getUntrackedParameter("debug", false); + loadPtErrBins(iConfig); +} + +#endif + +void l1ct::PFAlgo2HGCEmulator::toFirmware(const PFInputRegion& in, + PFRegion& region, + HadCaloObj calo[/*nCALO*/], + TkObj track[/*nTRACK*/], + MuObj mu[/*nMU*/]) const { + region = in.region; + l1ct::toFirmware(in.track, nTRACK_, track); + l1ct::toFirmware(in.hadcalo, nCALO_, calo); + l1ct::toFirmware(in.muon, nMU_, mu); +} + +void l1ct::PFAlgo2HGCEmulator::toFirmware(const OutputRegion& out, + PFChargedObj outch[/*nTRACK*/], + PFNeutralObj outne[/*nSELCALO*/], + PFChargedObj outmu[/*nMU*/]) const { + l1ct::toFirmware(out.pfcharged, nTRACK_, outch); + l1ct::toFirmware(out.pfneutral, nSELCALO_, outne); + l1ct::toFirmware(out.pfmuon, nMU_, outmu); +} + +void l1ct::PFAlgo2HGCEmulator::run(const PFInputRegion& in, OutputRegion& out) const { + unsigned int nTRACK = std::min(nTRACK_, in.track.size()); + unsigned int nCALO = std::min(nCALO_, in.hadcalo.size()); + unsigned int nSELCALO = std::min(nSELCALO_, in.hadcalo.size()); + unsigned int nMU = std::min(nMU_, in.muon.size()); + + if (debug_) { + dbgPrintf("FW\nFW \t region eta %+5.2f [ %+5.2f , %+5.2f ], phi %+5.2f [ %+5.2f , %+5.2f ] packed %s\n", + in.region.floatEtaCenter(), + in.region.floatEtaMinExtra(), + in.region.floatEtaMaxExtra(), + in.region.floatPhiCenter(), + in.region.floatPhiCenter() - in.region.floatPhiHalfWidthExtra(), + in.region.floatPhiCenter() + in.region.floatPhiHalfWidthExtra(), + in.region.pack().to_string(16).c_str()); + + dbgPrintf("FW \t N(track) %3lu N(calo) %3lu N(mu) %3lu\n", in.track.size(), in.hadcalo.size(), in.muon.size()); + + for (unsigned int i = 0; i < nTRACK; ++i) { + if (in.track[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t track %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] vtx eta %+5.2f " + "vtx phi %+5.2f charge %+2d qual %d fid %d glb eta %+5.2f phi %+5.2f packed %s\n", + i, + in.track[i].floatPt(), + in.track[i].intPt(), + in.track[i].floatEta(), + in.track[i].intEta(), + in.track[i].floatPhi(), + in.track[i].intPhi(), + in.track[i].floatVtxEta(), + in.track[i].floatVtxPhi(), + in.track[i].intCharge(), + int(in.track[i].hwQuality), + int(in.region.isFiducial(in.track[i].hwEta, in.track[i].hwPhi)), + in.region.floatGlbEta(in.track[i].hwVtxEta()), + in.region.floatGlbPhi(in.track[i].hwVtxPhi()), + in.track[i].pack().to_string(16).c_str()); + } + for (unsigned int i = 0; i < nCALO; ++i) { + if (in.hadcalo[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t calo %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] calo emPt %8.2f [ " + "%6d ] emID %2d fid %d glb eta %+5.2f phi %+5.2f packed %s \n", + i, + in.hadcalo[i].floatPt(), + in.hadcalo[i].intPt(), + in.hadcalo[i].floatEta(), + in.hadcalo[i].intEta(), + in.hadcalo[i].floatPhi(), + in.hadcalo[i].intPhi(), + in.hadcalo[i].floatEmPt(), + in.hadcalo[i].intEmPt(), + in.hadcalo[i].hwEmID.to_int(), + int(in.region.isFiducial(in.hadcalo[i].hwEta, in.hadcalo[i].hwPhi)), + in.region.floatGlbEtaOf(in.hadcalo[i]), + in.region.floatGlbPhiOf(in.hadcalo[i]), + in.hadcalo[i].pack().to_string(16).c_str()); + } + for (unsigned int i = 0; i < nMU; ++i) { + if (in.muon[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t muon %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] " + "vtx eta %+5.2f vtx phi %+5.2f charge %+2d qual %2d glb eta %+5.2f phi %+5.2f packed %s \n", + i, + in.muon[i].floatPt(), + in.muon[i].intPt(), + in.muon[i].floatEta(), + in.muon[i].intEta(), + in.muon[i].floatPhi(), + in.muon[i].intPhi(), + in.muon[i].floatVtxEta(), + in.muon[i].floatVtxPhi(), + in.muon[i].intCharge(), + int(in.muon[i].hwQuality), + in.region.floatGlbEta(in.muon[i].hwVtxEta()), + in.region.floatGlbPhi(in.muon[i].hwVtxPhi()), + in.muon[i].pack().to_string(16).c_str()); + } + } + + //////////////////////////////////////////////////// + // TK-MU Linking + std::vector iMu; + pfalgo_mu_ref(in, out, iMu); + + //////////////////////////////////////////////////// + // TK-HAD Linking + + // initialize sum track pt + std::vector calo_sumtk(nCALO), calo_subpt(nCALO); + std::vector calo_sumtkErr2(nCALO); + for (unsigned int ic = 0; ic < nCALO; ++ic) { + calo_sumtk[ic] = 0; + calo_sumtkErr2[ic] = 0; + } + + // initialize good track bit + std::vector track_good(nTRACK, false); + std::vector isEle(nTRACK, false); + for (unsigned int it = 0; it < nTRACK; ++it) { + if (!in.track[it].isPFLoose()) + continue; + pt_t ptInv = in.track[it].isPFTight() ? tk_MAXINVPT_TIGHT_ : tk_MAXINVPT_LOOSE_; + track_good[it] = (in.track[it].hwPt < ptInv) || (iMu[it] != -1); + isEle[it] = false; + } + + // initialize output + out.pfcharged.resize(nTRACK); + out.pfneutral.resize(nSELCALO); + for (unsigned int ipf = 0; ipf < nTRACK; ++ipf) + out.pfcharged[ipf].clear(); + for (unsigned int ipf = 0; ipf < nSELCALO; ++ipf) + out.pfneutral[ipf].clear(); + + // for each track, find the closest calo + std::vector tk2calo(nTRACK, -1); + for (unsigned int it = 0; it < nTRACK; ++it) { + if (in.track[it].hwPt > 0 && in.track[it].isPFLoose() && iMu[it] == -1) { + pt_t tkCaloPtErr = ptErr_ref(in.region, in.track[it]); + int ibest = best_match_with_pt_ref(dR2MAX_TK_CALO_, in.hadcalo, in.track[it], tkCaloPtErr); + if (ibest != -1) { + if (debug_) + dbgPrintf("FW \t track %3d pt %8.2f caloPtErr %6.2f matched to calo %3d pt %8.2f\n", + it, + in.track[it].floatPt(), + Scales::floatPt(tkCaloPtErr), + ibest, + in.hadcalo[ibest].floatPt()); + track_good[it] = true; + isEle[it] = in.hadcalo[ibest].hwIsEM(); + calo_sumtk[ibest] += in.track[it].hwPt; + calo_sumtkErr2[ibest] += tkCaloPtErr * tkCaloPtErr; + } + tk2calo[it] = ibest; // for emulator info + } + } + + for (unsigned int ic = 0; ic < nCALO; ++ic) { + if (calo_sumtk[ic] > 0) { + pt_t ptdiff = in.hadcalo[ic].hwPt - calo_sumtk[ic]; + pt2_t sigmamult = + calo_sumtkErr2[ic]; // + (calo_sumtkErr2[ic] >> 1)); // this multiplies by 1.5 = sqrt(1.5)^2 ~ (1.2)^2 + if (debug_ && (in.hadcalo[ic].hwPt > 0)) { + dbgPrintf( + "FW \t calo %3d pt %8.2f [ %7d ] eta %+5.2f [ %+5d ] has a sum track pt %8.2f, difference %7.2f +- %.2f " + "\n", + ic, + in.hadcalo[ic].floatPt(), + in.hadcalo[ic].intPt(), + in.hadcalo[ic].floatEta(), + in.hadcalo[ic].intEta(), + Scales::floatPt(calo_sumtk[ic]), + Scales::floatPt(ptdiff), + std::sqrt(Scales::floatPt(calo_sumtkErr2[ic]))); + } + if (ptdiff > 0 && ptdiff * ptdiff > sigmamult) { + calo_subpt[ic] = ptdiff; + } else { + calo_subpt[ic] = 0; + } + } else { + calo_subpt[ic] = in.hadcalo[ic].hwPt; + } + if (debug_ && (in.hadcalo[ic].hwPt > 0)) + dbgPrintf( + "FW \t calo' %3d pt %8.2f ---> %8.2f \n", ic, in.hadcalo[ic].floatPt(), Scales::floatPt(calo_subpt[ic])); + } + + // copy out charged hadrons + for (unsigned int it = 0; it < nTRACK; ++it) { + if (in.track[it].hwPt > 0 && track_good[it]) { + fillPFCand(in.track[it], out.pfcharged[it], /*isMu=*/(iMu[it] != -1), isEle[it]); + // extra emulator information + if (tk2calo[it] != -1) + out.pfcharged[it].srcCluster = in.hadcalo[tk2calo[it]].src; + if (iMu[it] != -1) + out.pfcharged[it].srcMu = in.muon[iMu[it]].src; + } + } + + // copy out neutral hadrons with sorting and cropping + std::vector outne_all(nCALO); + for (unsigned int ipf = 0; ipf < nCALO; ++ipf) + outne_all[ipf].clear(); + for (unsigned int ic = 0; ic < nCALO; ++ic) { + if (calo_subpt[ic] > 0) { + fillPFCand(in.hadcalo[ic], outne_all[ic], in.hadcalo[ic].hwIsEM()); + outne_all[ic].hwPt = calo_subpt[ic]; + outne_all[ic].hwEmPt = in.hadcalo[ic].hwIsEM() ? calo_subpt[ic] : pt_t(0); // FIXME + } + } + + if (nCALO_ == nSELCALO_) { + std::swap(outne_all, out.pfneutral); + } else { + ptsort_ref(nCALO, nSELCALO, outne_all, out.pfneutral); + } + + if (debug_) { + for (unsigned int i = 0; i < nTRACK; ++i) { + if (out.pfcharged[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t outch %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] pid %d packed %s\n", + i, + out.pfcharged[i].floatPt(), + out.pfcharged[i].intPt(), + out.pfcharged[i].floatEta(), + out.pfcharged[i].intEta(), + out.pfcharged[i].floatPhi(), + out.pfcharged[i].intPhi(), + out.pfcharged[i].intId(), + out.pfcharged[i].pack().to_string(16).c_str()); + } + for (unsigned int i = 0; i < nSELCALO; ++i) { + if (out.pfneutral[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t outne %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] pid %d packed %s\n", + i, + out.pfneutral[i].floatPt(), + out.pfneutral[i].intPt(), + out.pfneutral[i].floatEta(), + out.pfneutral[i].intEta(), + out.pfneutral[i].floatPhi(), + out.pfneutral[i].intPhi(), + out.pfneutral[i].intId(), + out.pfneutral[i].pack().to_string(16).c_str()); + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp new file mode 100644 index 0000000000000..fe0e3e0bd5ae6 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo3_ref.cpp @@ -0,0 +1,556 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo3_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#include +#include +#include +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::PFAlgo3Emulator::PFAlgo3Emulator(const edm::ParameterSet& iConfig) + : PFAlgoEmulatorBase(iConfig.getParameter("nTrack"), + iConfig.getParameter("nCalo"), + iConfig.getParameter("nMu"), + iConfig.getParameter("nSelCalo"), + l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter("trackMuDR")), + l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter("trackCaloDR")), + l1ct::Scales::makePtFromFloat(iConfig.getParameter("maxInvisiblePt")), + l1ct::Scales::makePtFromFloat(iConfig.getParameter("tightTrackMaxInvisiblePt"))), + nEMCALO_(iConfig.getParameter("nEmCalo")), + nPHOTON_(iConfig.getParameter("nPhoton")), + nALLNEUTRAL_(iConfig.getParameter("nAllNeutral")), + dR2MAX_TK_EM_(l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter("trackEmDR"))), + dR2MAX_EM_CALO_(l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter("emCaloDR"))) { + debug_ = iConfig.getUntrackedParameter("debug", false); + loadPtErrBins(iConfig); +} +#endif + +void l1ct::PFAlgo3Emulator::toFirmware(const PFInputRegion& in, + PFRegion& region, + HadCaloObj calo[/*nCALO*/], + EmCaloObj emcalo[/*nEMCALO*/], + TkObj track[/*nTRACK*/], + MuObj mu[/*nMU*/]) const { + region = in.region; + l1ct::toFirmware(in.track, nTRACK_, track); + l1ct::toFirmware(in.emcalo, nEMCALO_, emcalo); + l1ct::toFirmware(in.hadcalo, nCALO_, calo); + l1ct::toFirmware(in.muon, nMU_, mu); +} + +void l1ct::PFAlgo3Emulator::toFirmware(const OutputRegion& out, + PFChargedObj outch[/*nTRACK*/], + PFNeutralObj outpho[/*nPHOTON*/], + PFNeutralObj outne[/*nSELCALO*/], + PFChargedObj outmu[/*nMU*/]) const { + l1ct::toFirmware(out.pfcharged, nTRACK_, outch); + l1ct::toFirmware(out.pfphoton, nPHOTON_, outpho); + l1ct::toFirmware(out.pfneutral, nSELCALO_, outne); + l1ct::toFirmware(out.pfmuon, nMU_, outmu); +} + +int l1ct::PFAlgo3Emulator::tk_best_match_ref(unsigned int dR2MAX, + const std::vector& calo, + const l1ct::TkObjEmu& track) const { + int drmin = dR2MAX, ibest = -1; + for (unsigned int ic = 0, nCAL = std::min(nEMCALO_, calo.size()); ic < nCAL; ++ic) { + if (calo[ic].hwPt <= 0) + continue; + int dr = dr2_int(track.hwEta, track.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); + if (dr < drmin) { + drmin = dr; + ibest = ic; + } + } + return ibest; +} +int l1ct::PFAlgo3Emulator::em_best_match_ref(unsigned int dR2MAX, + const std::vector& calo, + const l1ct::EmCaloObjEmu& em) const { + pt_t emPtMin = em.hwPt >> 1; + int drmin = dR2MAX, ibest = -1; + for (unsigned int ic = 0, nCAL = calo.size(); ic < nCAL; ++ic) { + if (calo[ic].hwEmPt <= emPtMin) + continue; + int dr = dr2_int(em.hwEta, em.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); + if (dr < drmin) { + drmin = dr; + ibest = ic; + } + } + return ibest; +} + +void l1ct::PFAlgo3Emulator::pfalgo3_em_ref(const PFInputRegion& in, + const std::vector& iMu /*[nTRACK]*/, + std::vector& iEle /*[nTRACK]*/, + OutputRegion& out, + std::vector& hadcalo_out /*[nCALO]*/) const { + // constants + unsigned int nTRACK = std::min(nTRACK_, in.track.size()); + unsigned int nEMCALO = std::min(nEMCALO_, in.emcalo.size()); + unsigned int nPHOTON = std::min(nPHOTON_, in.emcalo.size()); + unsigned int nCALO = std::min(nCALO_, in.hadcalo.size()); + + // initialize sum track pt + std::vector calo_sumtk(nEMCALO); + for (unsigned int ic = 0; ic < nEMCALO; ++ic) { + calo_sumtk[ic] = 0; + } + std::vector tk2em(nTRACK); + std::vector isEM(nEMCALO); + // for each track, find the closest calo + for (unsigned int it = 0; it < nTRACK; ++it) { + if (in.track[it].hwPt > 0 && in.track[it].isPFLoose() && iMu[it] == -1) { + tk2em[it] = tk_best_match_ref(dR2MAX_TK_EM_, in.emcalo, in.track[it]); + if (tk2em[it] != -1) { + if (debug_) + dbgPrintf( + "FW \t track %3d pt %8.2f matched to em calo %3d pt %8.2f (int deltaR2 %d)\n", + it, + in.track[it].floatPt(), + tk2em[it], + in.emcalo[tk2em[it]].floatPt(), + dr2_int(in.track[it].hwEta, in.track[it].hwPhi, in.emcalo[tk2em[it]].hwEta, in.emcalo[tk2em[it]].hwPhi)); + calo_sumtk[tk2em[it]] += in.track[it].hwPt; + } + } else { + tk2em[it] = -1; + } + } + + if (debug_) { + for (unsigned int ic = 0; ic < nEMCALO; ++ic) { + if (in.emcalo[ic].hwPt > 0) + dbgPrintf("FW \t emcalo %3d pt %8.2f has sumtk %8.2f\n", + ic, + in.emcalo[ic].floatPt(), + Scales::floatPt(calo_sumtk[ic])); + } + } + + assert(nEMCALO == nPHOTON); // code doesn't work otherwise + out.pfphoton.resize(nPHOTON); + for (unsigned int ic = 0; ic < nEMCALO; ++ic) { + pt_t photonPt; + if (calo_sumtk[ic] > 0) { + dpt_t ptdiff = dpt_t(in.emcalo[ic].hwPt) - dpt_t(calo_sumtk[ic]); + pt2_t sigma2 = in.emcalo[ic].hwPtErr * in.emcalo[ic].hwPtErr; + pt2_t sigma2Lo = 4 * sigma2; + const pt2_t& sigma2Hi = sigma2; // + (sigma2>>1); // cut at 1 sigma instead of old cut at sqrt(1.5) sigma's + pt2_t ptdiff2 = ptdiff * ptdiff; + if ((ptdiff >= 0 && ptdiff2 <= sigma2Hi) || (ptdiff < 0 && ptdiff2 < sigma2Lo)) { + // electron + photonPt = 0; + isEM[ic] = true; + if (debug_) + dbgPrintf("FW \t emcalo %3d pt %8.2f ptdiff %8.2f [match window: -%.2f / +%.2f] flagged as electron\n", + ic, + in.emcalo[ic].floatPt(), + Scales::floatPt(ptdiff), + std::sqrt(Scales::floatPt(sigma2Lo)), + std::sqrt(float(sigma2Hi))); + } else if (ptdiff > 0) { + // electron + photon + photonPt = ptdiff; + isEM[ic] = true; + if (debug_) + dbgPrintf( + "FW \t emcalo %3d pt %8.2f ptdiff %8.2f [match window: -%.2f / +%.2f] flagged as electron + photon of " + "pt %8.2f\n", + ic, + in.emcalo[ic].floatPt(), + Scales::floatPt(ptdiff), + std::sqrt(Scales::floatPt(sigma2Lo)), + std::sqrt(float(sigma2Hi)), + Scales::floatPt(photonPt)); + } else { + // pion + photonPt = 0; + isEM[ic] = false; + if (debug_) + dbgPrintf("FW \t emcalo %3d pt %8.2f ptdiff %8.2f [match window: -%.2f / +%.2f] flagged as pion\n", + ic, + in.emcalo[ic].floatPt(), + Scales::floatPt(ptdiff), + std::sqrt(Scales::floatPt(sigma2Lo)), + std::sqrt(Scales::floatPt(sigma2Hi))); + } + } else { + // photon + isEM[ic] = true; + photonPt = in.emcalo[ic].hwPt; + if (debug_ && in.emcalo[ic].hwPt > 0) + dbgPrintf("FW \t emcalo %3d pt %8.2f flagged as photon\n", ic, in.emcalo[ic].floatPt()); + } + if (photonPt) { + fillPFCand(in.emcalo[ic], out.pfphoton[ic]); + out.pfphoton[ic].hwPt = photonPt; + out.pfphoton[ic].hwEmPt = photonPt; + } else { + out.pfphoton[ic].clear(); + } + } + + iEle.resize(nTRACK); + for (unsigned int it = 0; it < nTRACK; ++it) { + iEle[it] = ((tk2em[it] != -1) && isEM[tk2em[it]]) ? tk2em[it] : -1; + if (debug_ && (iEle[it] != -1)) + dbgPrintf( + "FW \t track %3d pt %8.2f flagged as electron (emcluster %d).\n", it, in.track[it].floatPt(), iEle[it]); + } + + std::vector em2calo(nEMCALO); + for (unsigned int ic = 0; ic < nEMCALO; ++ic) { + em2calo[ic] = em_best_match_ref(dR2MAX_EM_CALO_, in.hadcalo, in.emcalo[ic]); + if (debug_ && (in.emcalo[ic].hwPt > 0)) { + dbgPrintf("FW \t emcalo %3d pt %8.2f isEM %d matched to hadcalo %3d pt %8.2f emPt %8.2f isEM %d\n", + ic, + in.emcalo[ic].floatPt(), + int(isEM[ic]), + em2calo[ic], + (em2calo[ic] >= 0 ? in.hadcalo[em2calo[ic]].floatPt() : -1), + (em2calo[ic] >= 0 ? in.hadcalo[em2calo[ic]].floatEmPt() : -1), + (em2calo[ic] >= 0 ? int(in.hadcalo[em2calo[ic]].hwIsEM()) : 0)); + } + } + + hadcalo_out.resize(nCALO); + for (unsigned int ih = 0; ih < nCALO; ++ih) { + hadcalo_out[ih] = in.hadcalo[ih]; + dpt_t sub = 0; + bool keep = false; + for (unsigned int ic = 0; ic < nEMCALO; ++ic) { + if (em2calo[ic] == int(ih)) { + if (isEM[ic]) + sub += in.emcalo[ic].hwPt; + else + keep = true; + } + } + dpt_t emdiff = dpt_t(in.hadcalo[ih].hwEmPt) - sub; // ok to saturate at zero here + dpt_t alldiff = dpt_t(in.hadcalo[ih].hwPt) - sub; + if (debug_ && (in.hadcalo[ih].hwPt > 0)) { + dbgPrintf("FW \t calo %3d pt %8.2f has a subtracted pt of %8.2f, empt %8.2f -> %8.2f isem %d mustkeep %d \n", + ih, + in.hadcalo[ih].floatPt(), + Scales::floatPt(alldiff), + in.hadcalo[ih].floatEmPt(), + Scales::floatPt(emdiff), + int(in.hadcalo[ih].hwIsEM()), + keep); + } + if (alldiff <= (in.hadcalo[ih].hwPt >> 4)) { + hadcalo_out[ih].hwPt = 0; // kill + hadcalo_out[ih].hwEmPt = 0; // kill + if (debug_ && (in.hadcalo[ih].hwPt > 0)) + dbgPrintf("FW \t calo %3d pt %8.2f --> discarded (zero pt)\n", ih, in.hadcalo[ih].floatPt()); + } else if ((in.hadcalo[ih].hwIsEM() && emdiff <= (in.hadcalo[ih].hwEmPt >> 3)) && !keep) { + hadcalo_out[ih].hwPt = 0; // kill + hadcalo_out[ih].hwEmPt = 0; // kill + if (debug_ && (in.hadcalo[ih].hwPt > 0)) + dbgPrintf("FW \t calo %3d pt %8.2f --> discarded (zero em)\n", ih, in.hadcalo[ih].floatPt()); + } else { + hadcalo_out[ih].hwPt = alldiff; + hadcalo_out[ih].hwEmPt = (emdiff > 0 ? pt_t(emdiff) : pt_t(0)); + } + } +} + +void l1ct::PFAlgo3Emulator::run(const PFInputRegion& in, OutputRegion& out) const { + // constants + unsigned int nTRACK = std::min(nTRACK_, in.track.size()); + unsigned int nEMCALO = std::min(nEMCALO_, in.emcalo.size()); + unsigned int nPHOTON = std::min(nPHOTON_, in.emcalo.size()); + unsigned int nCALO = std::min(nCALO_, in.hadcalo.size()); + unsigned int nSELCALO = std::min(nSELCALO_, in.hadcalo.size()); + unsigned int nMU = std::min(nMU_, in.muon.size()); + + if (debug_) { + dbgPrintf("FW\nFW \t region eta %+5.2f [ %+5.2f , %+5.2f ], phi %+5.2f [ %+5.2f , %+5.2f ] packed %s\n", + in.region.floatEtaCenter(), + in.region.floatEtaMinExtra(), + in.region.floatEtaMaxExtra(), + in.region.floatPhiCenter(), + in.region.floatPhiCenter() - in.region.floatPhiHalfWidthExtra(), + in.region.floatPhiCenter() + in.region.floatPhiHalfWidthExtra(), + in.region.pack().to_string(16).c_str()); + + dbgPrintf("FW \t N(track) %3lu N(em) %3lu N(calo) %3lu N(mu) %3lu\n", + in.track.size(), + in.emcalo.size(), + in.hadcalo.size(), + in.muon.size()); + + for (unsigned int i = 0; i < nTRACK; ++i) { + if (in.track[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t track %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] vtx eta %+5.2f " + "vtx phi %+5.2f charge %+2d qual %2d fid %d glb eta %+5.2f phi %+5.2f packed %s\n", + i, + in.track[i].floatPt(), + in.track[i].intPt(), + in.track[i].floatEta(), + in.track[i].intEta(), + in.track[i].floatPhi(), + in.track[i].intPhi(), + in.track[i].floatVtxEta(), + in.track[i].floatVtxPhi(), + in.track[i].intCharge(), + int(in.track[i].hwQuality), + int(in.region.isFiducial(in.track[i].hwEta, in.track[i].hwPhi)), + in.region.floatGlbEta(in.track[i].hwVtxEta()), + in.region.floatGlbPhi(in.track[i].hwVtxPhi()), + in.track[i].pack().to_string(16).c_str()); + } + for (unsigned int i = 0; i < nEMCALO; ++i) { + if (in.emcalo[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t EM %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] calo ptErr %8.2f [ " + "%6d ] emID %2d fid %d glb eta %+5.2f phi %+5.2f packed %s \n", + i, + in.emcalo[i].floatPt(), + in.emcalo[i].intPt(), + in.emcalo[i].floatEta(), + in.emcalo[i].intEta(), + in.emcalo[i].floatPhi(), + in.emcalo[i].intPhi(), + in.emcalo[i].floatPtErr(), + in.emcalo[i].intPtErr(), + in.emcalo[i].hwEmID.to_int(), + int(in.region.isFiducial(in.emcalo[i].hwEta, in.emcalo[i].hwPhi)), + in.region.floatGlbEtaOf(in.emcalo[i]), + in.region.floatGlbPhiOf(in.emcalo[i]), + in.emcalo[i].pack().to_string(16).c_str()); + } + for (unsigned int i = 0; i < nCALO; ++i) { + if (in.hadcalo[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t calo %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] calo emPt %8.2f [ " + "%6d ] emID %2d fid %d glb eta %+5.2f phi %+5.2f packed %s \n", + i, + in.hadcalo[i].floatPt(), + in.hadcalo[i].intPt(), + in.hadcalo[i].floatEta(), + in.hadcalo[i].intEta(), + in.hadcalo[i].floatPhi(), + in.hadcalo[i].intPhi(), + in.hadcalo[i].floatEmPt(), + in.hadcalo[i].intEmPt(), + in.hadcalo[i].hwEmID.to_int(), + int(in.region.isFiducial(in.hadcalo[i].hwEta, in.hadcalo[i].hwPhi)), + in.region.floatGlbEtaOf(in.hadcalo[i]), + in.region.floatGlbPhiOf(in.hadcalo[i]), + in.hadcalo[i].pack().to_string(16).c_str()); + } + for (unsigned int i = 0; i < nMU; ++i) { + if (in.muon[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t muon %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] " + "vtx eta %+5.2f vtx phi %+5.2f charge %+2d qual %2d glb eta %+5.2f phi %+5.2f packed %s \n", + i, + in.muon[i].floatPt(), + in.muon[i].intPt(), + in.muon[i].floatEta(), + in.muon[i].intEta(), + in.muon[i].floatPhi(), + in.muon[i].intPhi(), + in.muon[i].floatVtxEta(), + in.muon[i].floatVtxPhi(), + in.muon[i].intCharge(), + int(in.muon[i].hwQuality), + in.region.floatGlbEta(in.muon[i].hwVtxEta()), + in.region.floatGlbPhi(in.muon[i].hwVtxPhi()), + in.muon[i].pack().to_string(16).c_str()); + } + dbgPrintf("%s", "FW\n"); + } + + //////////////////////////////////////////////////// + // TK-MU Linking + std::vector iMu; + pfalgo_mu_ref(in, out, iMu); + + //////////////////////////////////////////////////// + // TK-EM Linking + std::vector iEle; + std::vector hadcalo_subem(nCALO); + pfalgo3_em_ref(in, iMu, iEle, out, hadcalo_subem); + + //////////////////////////////////////////////////// + // TK-HAD Linking + + // initialize sum track pt + std::vector calo_sumtk(nCALO), calo_subpt(nCALO); + std::vector calo_sumtkErr2(nCALO); + for (unsigned int ic = 0; ic < nCALO; ++ic) { + calo_sumtk[ic] = 0; + calo_sumtkErr2[ic] = 0; + } + + // initialize good track bit + std::vector track_good(nTRACK, false); + for (unsigned int it = 0; it < nTRACK; ++it) { + if (!in.track[it].isPFLoose()) + continue; + pt_t ptInv = in.track[it].isPFTight() ? tk_MAXINVPT_TIGHT_ : tk_MAXINVPT_LOOSE_; + track_good[it] = (in.track[it].hwPt < ptInv) || (iEle[it] != -1) || (iMu[it] != -1); + } + + // initialize output + out.pfcharged.resize(nTRACK); + out.pfneutral.resize(nSELCALO); + for (unsigned int ipf = 0; ipf < nTRACK; ++ipf) + out.pfcharged[ipf].clear(); + for (unsigned int ipf = 0; ipf < nSELCALO; ++ipf) + out.pfneutral[ipf].clear(); + + // for each track, find the closest calo + std::vector tk2calo(nTRACK, -1); + for (unsigned int it = 0; it < nTRACK; ++it) { + if (in.track[it].hwPt > 0 && in.track[it].isPFLoose() && (iEle[it] == -1) && (iMu[it] == -1)) { + pt_t tkCaloPtErr = ptErr_ref(in.region, in.track[it]); + int ibest = best_match_with_pt_ref(dR2MAX_TK_CALO_, hadcalo_subem, in.track[it], tkCaloPtErr); + if (ibest != -1) { + if (debug_) + dbgPrintf( + "FW \t track %3d pt %8.2f matched to calo %3d pt %8.2f (int deltaR2 %d)\n", + it, + in.track[it].floatPt(), + ibest, + hadcalo_subem[ibest].floatPt(), + dr2_int(in.track[it].hwEta, in.track[it].hwPhi, hadcalo_subem[ibest].hwEta, hadcalo_subem[ibest].hwPhi)); + track_good[it] = true; + calo_sumtk[ibest] += in.track[it].hwPt; + calo_sumtkErr2[ibest] += tkCaloPtErr * tkCaloPtErr; + } + tk2calo[it] = ibest; // for emulator info + } + } + + for (unsigned int ic = 0; ic < nCALO; ++ic) { + if (calo_sumtk[ic] > 0) { + dpt_t ptdiff = dpt_t(hadcalo_subem[ic].hwPt) - dpt_t(calo_sumtk[ic]); + pt2_t sigmamult = calo_sumtkErr2 + [ic]; // before we did (calo_sumtkErr2[ic] + (calo_sumtkErr2[ic] >> 1)); to multiply by 1.5 = sqrt(1.5)^2 ~ (1.2)^2 + if (debug_ && (hadcalo_subem[ic].hwPt > 0)) { + dbgPrintf( + "FW \t calo %3d pt %8.2f [ %7d ] eta %+5.2f [ %+5d ] has a sum track pt %8.2f, difference %7.2f +- %.2f " + "\n", + ic, + hadcalo_subem[ic].floatPt(), + hadcalo_subem[ic].intPt(), + hadcalo_subem[ic].floatEta(), + hadcalo_subem[ic].intEta(), + Scales::floatPt(calo_sumtk[ic]), + Scales::floatPt(ptdiff), + std::sqrt(Scales::floatPt(calo_sumtkErr2[ic]))); + } + if (ptdiff > 0 && ptdiff * ptdiff > sigmamult) { + calo_subpt[ic] = pt_t(ptdiff); + } else { + calo_subpt[ic] = 0; + } + } else { + calo_subpt[ic] = hadcalo_subem[ic].hwPt; + } + if (debug_ && (hadcalo_subem[ic].hwPt > 0)) + dbgPrintf( + "FW \t calo %3d pt %8.2f ---> %8.2f \n", ic, hadcalo_subem[ic].floatPt(), Scales::floatPt(calo_subpt[ic])); + } + + // copy out charged hadrons + for (unsigned int it = 0; it < nTRACK; ++it) { + if (track_good[it]) { + fillPFCand(in.track[it], out.pfcharged[it], iMu[it] != -1, iEle[it] != -1); + // extra emulator information + if (iEle[it] != -1) + out.pfcharged[it].srcCluster = in.emcalo[iEle[it]].src; + if (iMu[it] != -1) + out.pfcharged[it].srcMu = in.muon[iMu[it]].src; + } + } + + // copy out neutral hadrons + std::vector outne_all(nCALO); + for (unsigned int ipf = 0; ipf < nCALO; ++ipf) + outne_all[ipf].clear(); + for (unsigned int ic = 0; ic < nCALO; ++ic) { + if (calo_subpt[ic] > 0) { + fillPFCand(hadcalo_subem[ic], outne_all[ic]); + outne_all[ic].hwPt = calo_subpt[ic]; + outne_all[ic].hwEmPt = hadcalo_subem[ic].hwIsEM() ? calo_subpt[ic] : pt_t(0); // FIXME + } + } + + if (nCALO_ == nSELCALO_) { + std::swap(outne_all, out.pfneutral); + } else { + ptsort_ref(nCALO, nSELCALO, outne_all, out.pfneutral); + } + + if (debug_) { + dbgPrintf("%s", "FW\n"); + for (unsigned int i = 0; i < nTRACK; ++i) { + if (out.pfcharged[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t outch %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] pid %d packed %s\n", + i, + out.pfcharged[i].floatPt(), + out.pfcharged[i].intPt(), + out.pfcharged[i].floatEta(), + out.pfcharged[i].intEta(), + out.pfcharged[i].floatPhi(), + out.pfcharged[i].intPhi(), + out.pfcharged[i].intId(), + out.pfcharged[i].pack().to_string(16).c_str()); + } + for (unsigned int i = 0; i < nPHOTON; ++i) { + if (out.pfphoton[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t outph %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] pid %d packed %s\n", + i, + out.pfphoton[i].floatPt(), + out.pfphoton[i].intPt(), + out.pfphoton[i].floatEta(), + out.pfphoton[i].intEta(), + out.pfphoton[i].floatPhi(), + out.pfphoton[i].intPhi(), + out.pfphoton[i].intId(), + out.pfphoton[i].pack().to_string(16).c_str()); + } + for (unsigned int i = 0; i < nSELCALO; ++i) { + if (out.pfneutral[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t outne %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+5d ] calo phi %+5.2f [ %+5d ] pid %d packed %s\n", + i, + out.pfneutral[i].floatPt(), + out.pfneutral[i].intPt(), + out.pfneutral[i].floatEta(), + out.pfneutral[i].intEta(), + out.pfneutral[i].floatPhi(), + out.pfneutral[i].intPhi(), + out.pfneutral[i].intId(), + out.pfneutral[i].pack().to_string(16).c_str()); + } + dbgPrintf("%s", "FW\n"); + } +} + +void l1ct::PFAlgo3Emulator::mergeNeutrals(OutputRegion& out) const { + out.pfphoton.reserve(out.pfphoton.size() + out.pfneutral.size()); + out.pfphoton.insert(out.pfphoton.end(), out.pfneutral.begin(), out.pfneutral.end()); + out.pfphoton.swap(out.pfneutral); + out.pfphoton.clear(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo_common_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo_common_ref.cpp new file mode 100644 index 0000000000000..1e7fa983f559a --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo_common_ref.cpp @@ -0,0 +1,157 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_common_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#endif + +l1ct::PFAlgoEmulatorBase::~PFAlgoEmulatorBase() {} + +void l1ct::PFAlgoEmulatorBase::loadPtErrBins( + unsigned int nbins, const float absetas[], const float scales[], const float offs[], bool verbose) { + ptErrBins_.resize(nbins); + for (unsigned int i = 0; i < nbins; ++i) { + ptErrBins_[i].abseta = Scales::makeGlbEta(absetas[i]); + ptErrBins_[i].scale = scales[i]; + ptErrBins_[i].offs = offs[i]; + + if (verbose || debug_) + dbgPrintf("loadPtErrBins: #%d: abseta %5.3f -> %8d, scale %7.4f -> %7.4f, offs %7.3f -> %7.4f\n", + i, + absetas[i], + ptErrBins_[i].abseta.to_int(), + scales[i], + ptErrBins_[i].scale.to_float(), + offs[i], + ptErrBins_[i].offs.to_float()); + } +} + +#ifdef CMSSW_GIT_HASH +void l1ct::PFAlgoEmulatorBase::loadPtErrBins(const edm::ParameterSet &iConfig) { + const edm::ParameterSet &resol = iConfig.getParameter("caloResolution"); + std::vector absetas, scales, offs; + for (auto &v : resol.getParameter>("etaBins")) + absetas.push_back(v); + for (auto &v : resol.getParameter>("scale")) + scales.push_back(v); + for (auto &v : resol.getParameter>("offset")) + offs.push_back(v); + loadPtErrBins(absetas.size(), &absetas[0], &scales[0], &offs[0]); +} + +#endif + +l1ct::pt_t l1ct::PFAlgoEmulatorBase::ptErr_ref(const l1ct::PFRegionEmu ®ion, const l1ct::TkObjEmu &track) const { + glbeta_t abseta = region.hwGlbEta(track.hwEta); + if (abseta < 0) + abseta = -abseta; + + ptErrScale_t scale = 0.3125; + ptErrOffs_t offs = 7.0; + for (const auto &bin : ptErrBins_) { + if (abseta < bin.abseta) { + scale = bin.scale; + offs = bin.offs; + break; + } + } + + pt_t ptErr = track.hwPt * scale + offs; + if (ptErr > track.hwPt) + ptErr = track.hwPt; + return ptErr; +} + +void l1ct::PFAlgoEmulatorBase::pfalgo_mu_ref(const PFInputRegion &in, OutputRegion &out, std::vector &iMu) const { + // init + unsigned int nTRACK = std::min(nTRACK_, in.track.size()); + unsigned int nMU = std::min(nMU_, in.muon.size()); + out.pfmuon.resize(nMU); + iMu.resize(nTRACK); + for (unsigned int ipf = 0; ipf < nMU; ++ipf) + out.pfmuon[ipf].clear(); + for (unsigned int it = 0; it < nTRACK; ++it) + iMu[it] = -1; + + // for each muon, find the closest track + for (unsigned int im = 0; im < nMU; ++im) { + if (in.muon[im].hwPt > 0) { + int ibest = -1; + pt_t dptmin = (in.muon[im].hwPt << 1) + in.muon[im].hwPt; + for (unsigned int it = 0; it < nTRACK; ++it) { + if (!in.track[it].isPFLoose()) + continue; + unsigned int dr = dr2_int(in.muon[im].hwEta, in.muon[im].hwPhi, in.track[it].hwEta, in.track[it].hwPhi); + //dbgPrintf("deltaR2(mu %d float pt %5.1f, tk %2d float pt %5.1f) = int %d (float deltaR = %.3f); int cut at %d\n", im, 0.25*int(in.muon[im].hwPt), it, 0.25*int(in.track[it].hwPt), dr, std::sqrt(float(dr))/229.2, dR2MAX_TK_MU_); + if (dr < dR2MAX_TK_MU_) { + dpt_t dpt = (dpt_t(in.track[it].hwPt) - dpt_t(in.muon[im].hwPt)); + pt_t absdpt = dpt >= 0 ? pt_t(dpt) : pt_t(-dpt); + if (absdpt < dptmin) { + dptmin = absdpt; + ibest = it; + } + } + } + if (ibest != -1) { + iMu[ibest] = im; + fillPFCand(in.track[ibest], out.pfmuon[im], /*isMu=*/true, /*isEle=*/false); + // extra emulator info + out.pfmuon[im].srcMu = in.muon[im].src; + if (debug_) + dbgPrintf("FW \t muon %3d linked to track %3d \n", im, ibest); + } else { + if (debug_) + dbgPrintf("FW \t muon %3d not linked to any track\n", im); + } + } + } +} + +void l1ct::PFAlgoEmulatorBase::fillPFCand(const TkObjEmu &track, PFChargedObjEmu &pf, bool isMu, bool isEle) const { + assert(!(isEle && isMu)); + pf.hwPt = track.hwPt; + pf.hwEta = track.hwEta; + pf.hwPhi = track.hwPhi; + pf.hwDEta = track.hwDEta; + pf.hwDPhi = track.hwDPhi; + pf.hwZ0 = track.hwZ0; + pf.hwDxy = track.hwDxy; + pf.hwTkQuality = track.hwQuality; + if (isMu) { + pf.hwId = ParticleID::mkMuon(track.hwCharge); + } else if (isEle) { + pf.hwId = ParticleID::mkElectron(track.hwCharge); + } else { + pf.hwId = ParticleID::mkChHad(track.hwCharge); + } + // extra emulator information + pf.srcTrack = track.src; +} + +void l1ct::PFAlgoEmulatorBase::fillPFCand(const HadCaloObjEmu &calo, PFNeutralObjEmu &pf, bool isPhoton) const { + pf.hwPt = calo.hwPt; + pf.hwEta = calo.hwEta; + pf.hwPhi = calo.hwPhi; + pf.hwId = isPhoton ? ParticleID::PHOTON : ParticleID::HADZERO; + pf.hwEmPt = calo.hwEmPt; // FIXME + pf.hwEmID = calo.hwEmID; + pf.hwPUID = 0; + // extra emulator information + pf.srcCluster = calo.src; +} + +void l1ct::PFAlgoEmulatorBase::fillPFCand(const EmCaloObjEmu &calo, PFNeutralObjEmu &pf, bool isPhoton) const { + pf.hwPt = calo.hwPt; + pf.hwEta = calo.hwEta; + pf.hwPhi = calo.hwPhi; + pf.hwId = isPhoton ? ParticleID::PHOTON : ParticleID::HADZERO; + pf.hwEmPt = calo.hwPt; + pf.hwEmID = calo.hwEmID; + pf.hwPUID = 0; + // more emulator info + pf.srcCluster = calo.src; +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo_dummy_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo_dummy_ref.cpp new file mode 100644 index 0000000000000..0f39904bce93b --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/pf/pfalgo_dummy_ref.cpp @@ -0,0 +1,79 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/pf/pfalgo_dummy_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#include +#include +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::PFAlgoDummyEmulator::PFAlgoDummyEmulator(const edm::ParameterSet& iConfig) + : PFAlgoEmulatorBase( + 0, iConfig.getParameter("nCalo"), iConfig.getParameter("nMu"), 0, 0, 0, 0, 0) { + debug_ = iConfig.getUntrackedParameter("debug", false); +} +#endif + +void l1ct::PFAlgoDummyEmulator::run(const PFInputRegion& in, OutputRegion& out) const { + unsigned int nCALO = std::min(nCALO_, in.hadcalo.size()); + unsigned int nMU = std::min(nMU_, in.muon.size()); + + if (debug_) { + for (unsigned int i = 0; i < nCALO; ++i) { + if (in.hadcalo[i].hwPt == 0) + continue; + dbgPrintf( + "FW \t calo %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+7d ] calo phi %+5.2f [ %+7d ] calo emPt %8.2f [ " + "%6d ] emID %2d \n", + i, + in.hadcalo[i].floatPt(), + in.hadcalo[i].intPt(), + in.hadcalo[i].floatEta(), + in.hadcalo[i].intEta(), + in.hadcalo[i].floatPhi(), + in.hadcalo[i].intPhi(), + in.hadcalo[i].floatEmPt(), + in.hadcalo[i].intEmPt(), + in.hadcalo[i].hwEmID.to_int()); + } + for (unsigned int i = 0; i < nMU; ++i) { + if (in.muon[i].hwPt == 0) + continue; + dbgPrintf("FW \t muon %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+7d ] calo phi %+5.2f [ %+7d ] \n", + i, + in.muon[i].floatPt(), + in.muon[i].intPt(), + in.muon[i].floatEta(), + in.muon[i].intEta(), + in.muon[i].floatPhi(), + in.muon[i].intPhi()); + } + } + + out.pfneutral.resize(nCALO); + for (unsigned int ic = 0; ic < nCALO; ++ic) { + if (in.hadcalo[ic].hwPt > 0) { + fillPFCand(in.hadcalo[ic], out.pfneutral[ic], in.hadcalo[ic].hwIsEM()); + } else { + out.pfneutral[ic].clear(); + } + } + + if (debug_) { + for (unsigned int i = 0; i < nCALO; ++i) { + if (out.pfneutral[i].hwPt == 0) + continue; + dbgPrintf("FW \t outne %3d: pt %8.2f [ %8d ] calo eta %+5.2f [ %+7d ] calo phi %+5.2f [ %+7d ] pid %d\n", + i, + out.pfneutral[i].floatPt(), + out.pfneutral[i].intPt(), + out.pfneutral[i].floatEta(), + out.pfneutral[i].intEta(), + out.pfneutral[i].floatPhi(), + out.pfneutral[i].intPhi(), + out.pfneutral[i].intId()); + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp new file mode 100644 index 0000000000000..8ef2679747d0d --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/puppi/linpuppi_ref.cpp @@ -0,0 +1,642 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/puppi/linpuppi_bits.h" +#include +#include + +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_hybrid_sort_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/common/bitonic_sort_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h" + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/transform.h" +#include "FWCore/Utilities/interface/Exception.h" +#endif + +using namespace l1ct; + +l1ct::LinPuppiEmulator::LinPuppiEmulator(unsigned int nTrack, + unsigned int nIn, + unsigned int nOut, + unsigned int nVtx, + unsigned int dR2Min, + unsigned int dR2Max, + unsigned int iptMax, + unsigned int dzCut, + glbeta_t etaCut, + double ptSlopeNe_0, + double ptSlopeNe_1, + double ptSlopePh_0, + double ptSlopePh_1, + double ptZeroNe_0, + double ptZeroNe_1, + double ptZeroPh_0, + double ptZeroPh_1, + double alphaSlope_0, + double alphaSlope_1, + double alphaZero_0, + double alphaZero_1, + double alphaCrop_0, + double alphaCrop_1, + double priorNe_0, + double priorNe_1, + double priorPh_0, + double priorPh_1, + pt_t ptCut_0, + pt_t ptCut_1, + unsigned int nFinalSort, + SortAlgo finalSortAlgo) + : nTrack_(nTrack), + nIn_(nIn), + nOut_(nOut), + nVtx_(nVtx), + dR2Min_(dR2Min), + dR2Max_(dR2Max), + iptMax_(iptMax), + dzCut_(dzCut), + absEtaBins_(1, etaCut), + ptSlopeNe_(2), + ptSlopePh_(2), + ptZeroNe_(2), + ptZeroPh_(2), + alphaSlope_(2), + alphaZero_(2), + alphaCrop_(2), + priorNe_(2), + priorPh_(2), + ptCut_(2), + nFinalSort_(nFinalSort ? nFinalSort : nOut), + finalSortAlgo_(finalSortAlgo), + debug_(false), + fakePuppi_(false) { + ptSlopeNe_[0] = ptSlopeNe_0; + ptSlopeNe_[1] = ptSlopeNe_1; + ptSlopePh_[0] = ptSlopePh_0; + ptSlopePh_[1] = ptSlopePh_1; + ptZeroNe_[0] = ptZeroNe_0; + ptZeroNe_[1] = ptZeroNe_1; + ptZeroPh_[0] = ptZeroPh_0; + ptZeroPh_[1] = ptZeroPh_1; + alphaSlope_[0] = alphaSlope_0; + alphaSlope_[1] = alphaSlope_1; + alphaZero_[0] = alphaZero_0; + alphaZero_[1] = alphaZero_1; + alphaCrop_[0] = alphaCrop_0; + alphaCrop_[1] = alphaCrop_1; + priorNe_[0] = priorNe_0; + priorNe_[1] = priorNe_1; + priorPh_[0] = priorPh_0; + priorPh_[1] = priorPh_1; + ptCut_[0] = ptCut_0; + ptCut_[1] = ptCut_1; +} + +#ifdef CMSSW_GIT_HASH +l1ct::LinPuppiEmulator::LinPuppiEmulator(const edm::ParameterSet &iConfig) + : nTrack_(iConfig.getParameter("nTrack")), + nIn_(iConfig.getParameter("nIn")), + nOut_(iConfig.getParameter("nOut")), + nVtx_(iConfig.getParameter("nVtx")), + dR2Min_(l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter("drMin"))), + dR2Max_(l1ct::Scales::makeDR2FromFloatDR(iConfig.getParameter("dr"))), + iptMax_(l1ct::Scales::intPt(l1ct::Scales::makePtFromFloat(iConfig.getParameter("ptMax")))), + dzCut_(l1ct::Scales::makeZ0(iConfig.getParameter("dZ"))), + absEtaBins_( + edm::vector_transform(iConfig.getParameter>("absEtaCuts"), l1ct::Scales::makeGlbEta)), + ptSlopeNe_(iConfig.getParameter>("ptSlopes")), + ptSlopePh_(iConfig.getParameter>("ptSlopesPhoton")), + ptZeroNe_(iConfig.getParameter>("ptZeros")), + ptZeroPh_(iConfig.getParameter>("ptZerosPhoton")), + alphaSlope_(iConfig.getParameter>("alphaSlopes")), + alphaZero_(iConfig.getParameter>("alphaZeros")), + alphaCrop_(iConfig.getParameter>("alphaCrop")), + priorNe_(iConfig.getParameter>("priors")), + priorPh_(iConfig.getParameter>("priorsPhoton")), + ptCut_(edm::vector_transform(iConfig.getParameter>("ptCut"), l1ct::Scales::makePtFromFloat)), + nFinalSort_(iConfig.getParameter("nFinalSort")), + debug_(iConfig.getUntrackedParameter("debug", false)), + fakePuppi_(iConfig.existsAs("fakePuppi") ? iConfig.getParameter("fakePuppi") + : false) // it's only for debug, but still better be tracked +{ + if (absEtaBins_.size() + 1 != ptSlopeNe_.size()) + throw cms::Exception("Configuration", "size mismatch for ptSlopes parameter"); + if (absEtaBins_.size() + 1 != ptSlopePh_.size()) + throw cms::Exception("Configuration", "size mismatch for ptSlopesPhoton parameter"); + if (absEtaBins_.size() + 1 != ptZeroPh_.size()) + throw cms::Exception("Configuration", "size mismatch for ptZeros parameter"); + if (absEtaBins_.size() + 1 != ptZeroNe_.size()) + throw cms::Exception("Configuration", "size mismatch for ptZerosPhotons parameter"); + if (absEtaBins_.size() + 1 != priorPh_.size()) + throw cms::Exception("Configuration", "size mismatch for priors parameter"); + if (absEtaBins_.size() + 1 != priorNe_.size()) + throw cms::Exception("Configuration", "size mismatch for priorsPhotons parameter"); + if (absEtaBins_.size() + 1 != alphaSlope_.size()) + throw cms::Exception("Configuration", "size mismatch for alphaSlope parameter"); + if (absEtaBins_.size() + 1 != alphaZero_.size()) + throw cms::Exception("Configuration", "size mismatch for alphaZero parameter"); + if (absEtaBins_.size() + 1 != alphaCrop_.size()) + throw cms::Exception("Configuration", "size mismatch for alphaCrop parameter"); + if (absEtaBins_.size() + 1 != ptCut_.size()) + throw cms::Exception("Configuration", "size mismatch for ptCut parameter"); + const std::string &sortAlgo = iConfig.getParameter("finalSortAlgo"); + if (sortAlgo == "Insertion") + finalSortAlgo_ = SortAlgo::Insertion; + else if (sortAlgo == "BitonicRUFL") + finalSortAlgo_ = SortAlgo::BitonicRUFL; + else if (sortAlgo == "BitonicHLS") + finalSortAlgo_ = SortAlgo::BitonicHLS; + else if (sortAlgo == "Hybrid") + finalSortAlgo_ = SortAlgo::Hybrid; + else if (sortAlgo == "FoldedHybrid") + finalSortAlgo_ = SortAlgo::FoldedHybrid; + else + throw cms::Exception("Configuration", "unsupported finalSortAlgo '" + sortAlgo + "'"); +} +#endif + +void l1ct::LinPuppiEmulator::puppisort_and_crop_ref(unsigned int nOutMax, + const std::vector &in, + std::vector &out, + SortAlgo sortAlgo) { + const unsigned int nOut = std::min(nOutMax, in.size()); + out.resize(nOut); + for (unsigned int iout = 0; iout < nOut; ++iout) { + out[iout].clear(); + } + + if (sortAlgo == SortAlgo::Insertion) { + for (unsigned int it = 0, nIn = in.size(); it < nIn; ++it) { + for (int iout = int(nOut) - 1; iout >= 0; --iout) { + if (out[iout].hwPt <= in[it].hwPt) { + if (iout == 0 || out[iout - 1].hwPt > in[it].hwPt) { + out[iout] = in[it]; + } else { + out[iout] = out[iout - 1]; + } + } + } + } + } else if (sortAlgo == SortAlgo::BitonicRUFL) { + bitonic_sort_and_crop_ref(in.size(), nOut, &in[0], &out[0]); + } else if (sortAlgo == SortAlgo::BitonicHLS || sortAlgo == SortAlgo::Hybrid) { + hybrid_bitonic_sort_and_crop_ref(in.size(), nOut, &in[0], &out[0], sortAlgo == SortAlgo::Hybrid); + } else if (sortAlgo == SortAlgo::FoldedHybrid) { + folded_hybrid_bitonic_sort_and_crop_ref(in.size(), nOut, &in[0], &out[0], true); + } +} + +void l1ct::LinPuppiEmulator::linpuppi_chs_ref(const PFRegionEmu ®ion, + const std::vector &pv, + const std::vector &pfch /*[nTrack]*/, + std::vector &outallch /*[nTrack]*/) const { + const unsigned int nTrack = std::min(nTrack_, pfch.size()); + outallch.resize(nTrack); + for (unsigned int i = 0; i < nTrack; ++i) { + int pZ0 = pfch[i].hwZ0; + int z0diff = -99999; + for (unsigned int j = 0; j < nVtx_; ++j) { + if (j < pv.size()) { + int pZ0Diff = pZ0 - pv[j].hwZ0; + if (std::abs(z0diff) > std::abs(pZ0Diff)) + z0diff = pZ0Diff; + } + } + bool accept = pfch[i].hwPt != 0; + if (!fakePuppi_) + accept = accept && region.isFiducial(pfch[i]) && (std::abs(z0diff) <= int(dzCut_) || pfch[i].hwId.isMuon()); + if (accept) { + outallch[i].fill(region, pfch[i]); + if (fakePuppi_) { // overwrite Dxy & TkQuality with debug information + outallch[i].setHwDxy(dxy_t(pv[0].hwZ0)); ///hack to get this to work + outallch[i].setHwTkQuality(region.isFiducial(pfch[i]) ? 1 : 0); + } + if (debug_ && pfch[i].hwPt > 0) + dbgPrintf("ref candidate %02u pt %7.2f pid %1d vz %+6d dz %+6d (cut %5d), fid %1d -> pass, packed %s\n", + i, + pfch[i].floatPt(), + pfch[i].intId(), + int(pfch[i].hwZ0), + z0diff, + dzCut_, + region.isFiducial(pfch[i]), + outallch[i].pack().to_string(16).c_str()); + } else { + outallch[i].clear(); + if (debug_ && pfch[i].hwPt > 0) + dbgPrintf("ref candidate %02u pt %7.2f pid %1d vz %+6d dz %+6d (cut %5d), fid %1d -> fail\n", + i, + pfch[i].floatPt(), + pfch[i].intId(), + int(pfch[i].hwZ0), + z0diff, + dzCut_, + region.isFiducial(pfch[i])); + } + } +} + +unsigned int l1ct::LinPuppiEmulator::find_ieta(const PFRegionEmu ®ion, eta_t eta) const { + int n = absEtaBins_.size(); + glbeta_t abseta = region.hwGlbEta(eta); + if (abseta < 0) + abseta = -abseta; + for (int i = 0; i < n; ++i) { + if (abseta <= absEtaBins_[i]) + return i; + } + return n; +} + +std::pair l1ct::LinPuppiEmulator::sum2puppiPt_ref( + uint64_t sum, pt_t pt, unsigned int ieta, bool isEM, int icand) const { + const int sum_bitShift = LINPUPPI_sum_bitShift; + const int x2_bits = LINPUPPI_x2_bits; // decimal bits the discriminator values + const int alpha_bits = LINPUPPI_alpha_bits; // decimal bits of the alpha values + const int alphaSlope_bits = LINPUPPI_alphaSlope_bits; // decimal bits of the alphaSlope values + const int ptSlope_bits = LINPUPPI_ptSlope_bits; // decimal bits of the ptSlope values + const int weight_bits = LINPUPPI_weight_bits; + + const int ptSlopeNe = ptSlopeNe_[ieta] * (1 << ptSlope_bits); + const int ptSlopePh = ptSlopePh_[ieta] * (1 << ptSlope_bits); + const int ptZeroNe = ptZeroNe_[ieta] / LINPUPPI_ptLSB; // in pt scale + const int ptZeroPh = ptZeroPh_[ieta] / LINPUPPI_ptLSB; // in pt scale + const int alphaCrop = alphaCrop_[ieta] * (1 << x2_bits); + const int alphaSlopeNe = + alphaSlope_[ieta] * std::log(2.) * + (1 << alphaSlope_bits); // we put a log(2) here since we compute alpha as log2(sum) instead of ln(sum) + const int alphaSlopePh = alphaSlope_[ieta] * std::log(2.) * (1 << alphaSlope_bits); + const int alphaZeroNe = alphaZero_[ieta] / std::log(2.) * (1 << alpha_bits); + const int alphaZeroPh = alphaZero_[ieta] / std::log(2.) * (1 << alpha_bits); + const int priorNe = priorNe_[ieta] * (1 << x2_bits); + const int priorPh = priorPh_[ieta] * (1 << x2_bits); + + // -- simplest version + //int alpha = sum > 0 ? int(std::log2(float(sum) * LINPUPPI_pt2DR2_scale / (1< 0 ? int(std::log2(float(sum))*(1 << alpha_bits) + (std::log2(LINPUPPI_pt2DR2_scale) - sum_bitShift)*(1 << alpha_bits) + 0.5 ) : 0; + // -- re-written for a LUT implementation of the log2 + const int log2lut_bits = 10; + int alpha = 0; + uint64_t logarg = sum; + if (logarg > 0) { + alpha = int((std::log2(LINPUPPI_pt2DR2_scale) - sum_bitShift) * (1 << alpha_bits) + 0.5); + while (logarg >= (1 << log2lut_bits)) { + logarg = logarg >> 1; + alpha += (1 << alpha_bits); + } + alpha += int( + std::log2(float(logarg)) * + (1 + << alpha_bits)); // the maximum value of this term is log2lut_bits * (1 << alpha_bits) ~ 10*16 = 160 => fits in ap_uint<4+alpha_bits> + } + int alphaZero = (isEM ? alphaZeroPh : alphaZeroNe); + int alphaSlope = (isEM ? alphaSlopePh : alphaSlopeNe); + int x2a = std::min(std::max(alphaSlope * (alpha - alphaZero) >> (alphaSlope_bits + alpha_bits - x2_bits), -alphaCrop), + alphaCrop); + + // -- re-written to fit in a single LUT + int x2a_lut = -alphaSlope * alphaZero; + logarg = sum; + if (logarg > 0) { + x2a_lut += alphaSlope * int((std::log2(LINPUPPI_pt2DR2_scale) - sum_bitShift) * (1 << alpha_bits) + 0.5); + while (logarg >= (1 << log2lut_bits)) { + logarg = logarg >> 1; + x2a_lut += alphaSlope * (1 << alpha_bits); + } + x2a_lut += alphaSlope * int(std::log2(float(logarg)) * (1 << alpha_bits)); + /*if (in <= 3) dbgPrintf("ref [%d]: x2a(sum = %9lu): logarg = %9lu, sumterm = %9d, table[logarg] = %9d, ret pre-crop = %9d\n", + in, sum, logarg, + alphaSlope * int((std::log2(LINPUPPI_pt2DR2_scale) - sum_bitShift)*(1 << alpha_bits) + 0.5) - alphaSlope * alphaZero, + alphaSlope * int(std::log2(float(logarg))*(1 << alpha_bits)), + x2a_lut); */ + } else { + //if (in <= 3) dbgPrintf("ref [%d]: x2a(sum = %9lu): logarg = %9lu, ret pre-crop = %9d\n", + // in, sum, logarg, x2a_lut); + } + x2a_lut = std::min(std::max(x2a_lut >> (alphaSlope_bits + alpha_bits - x2_bits), -alphaCrop), alphaCrop); + assert(x2a_lut == x2a); + + int ptZero = (isEM ? ptZeroPh : ptZeroNe); + int ptSlope = (isEM ? ptSlopePh : ptSlopeNe); + int x2pt = ptSlope * (Scales::ptToInt(pt) - ptZero) >> (ptSlope_bits + 2 - x2_bits); + + int prior = (isEM ? priorPh : priorNe); + + int x2 = x2a + x2pt - prior; + + int weight = + std::min(1.0 / (1.0 + std::exp(-float(x2) / (1 << x2_bits))) * (1 << weight_bits) + 0.5, (1 << weight_bits)); + + pt_t ptPuppi = Scales::makePt((Scales::ptToInt(pt) * weight) >> weight_bits); + + if (debug_) + dbgPrintf( + "ref candidate %02d pt %7.2f em %1d ieta %1d: alpha %+7.2f x2a %+5d = %+7.3f x2pt %+5d = %+7.3f x2 %+5d " + "= %+7.3f --> weight %4d = %.4f puppi pt %7.2f\n", + icand, + Scales::floatPt(pt), + int(isEM), + ieta, + std::max(alpha / float(1 << alpha_bits) * std::log(2.), -99.99f), + x2a, + x2a / float(1 << x2_bits), + x2pt, + x2pt / float(1 << x2_bits), + x2, + x2 / float(1 << x2_bits), + weight, + weight / float(1 << weight_bits), + Scales::floatPt(ptPuppi)); + + return std::make_pair(ptPuppi, puppiWgt_t(weight)); +} + +void l1ct::LinPuppiEmulator::fwdlinpuppi_ref(const PFRegionEmu ®ion, + const std::vector &caloin /*[nIn]*/, + std::vector &outallne_nocut /*[nIn]*/, + std::vector &outallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const { + const unsigned int nIn = std::min(nIn_, caloin.size()); + const int PTMAX2 = (iptMax_ * iptMax_); + + const int sum_bitShift = LINPUPPI_sum_bitShift; + + outallne_nocut.resize(nIn); + outallne.resize(nIn); + for (unsigned int in = 0; in < nIn; ++in) { + outallne_nocut[in].clear(); + outallne[in].clear(); + if (caloin[in].hwPt == 0) + continue; + uint64_t sum = 0; // 2 ^ sum_bitShift times (int pt^2)/(int dr2) + for (unsigned int it = 0; it < nIn; ++it) { + if (it == in || caloin[it].hwPt == 0) + continue; + unsigned int dr2 = dr2_int( + caloin[it].hwEta, caloin[it].hwPhi, caloin[in].hwEta, caloin[in].hwPhi); // if dr is inside puppi cone + if (dr2 <= dR2Max_) { + ap_uint<9> dr2short = (dr2 >= dR2Min_ ? dr2 : dR2Min_) >> 5; // reduce precision to make divide LUT cheaper + uint64_t pt2 = Scales::ptToInt(caloin[it].hwPt) * Scales::ptToInt(caloin[it].hwPt); + uint64_t term = std::min(pt2 >> 5, PTMAX2 >> 5) * ((1 << sum_bitShift) / int(dr2short)); + // dr2short >= (dR2Min_ >> 5) = 2 + // num <= (PTMAX2 >> 5) << sum_bitShift = (2^11) << 15 = 2^26 + // ==> term <= 2^25 + //dbgPrintf("ref term [%2d,%2d]: dr = %8d pt2_shift = %8lu term = %12lu\n", in, it, dr2, std::min(pt2 >> 5, PTMAX2 >> 5), term); + assert(uint64_t(PTMAX2 << (sum_bitShift - 5)) / (dR2Min_ >> 5) <= (1 << 25)); + assert(term < (1 << 25)); + sum += term; + //dbgPrintf(" pT cand %5.1f pT item %5.1f dR = %.3f term = %.1f [dbl] = %lu [int]\n", + // caloin[in].floatPt(), caloin[it].floatPt(), std::sqrt(dr2*LINPUPPI_DR2LSB), + // double(std::min(pt2 >> 5, 131071)<<15)/double(std::max(dr2,dR2Min_) >> 5), + // term); + } + } + unsigned int ieta = find_ieta(region, caloin[in].hwEta); + std::pair ptAndW = sum2puppiPt_ref(sum, caloin[in].hwPt, ieta, caloin[in].hwIsEM(), in); + + outallne_nocut[in].fill(region, caloin[in], ptAndW.first, ptAndW.second); + if (region.isFiducial(caloin[in]) && outallne_nocut[in].hwPt >= ptCut_[ieta]) { + outallne[in] = outallne_nocut[in]; + } + } + puppisort_and_crop_ref(nOut_, outallne, outselne); +} + +void l1ct::LinPuppiEmulator::linpuppi_ref(const PFRegionEmu ®ion, + const std::vector &track /*[nTrack]*/, + const std::vector &pv, /*[nVtx]*/ + const std::vector &pfallne /*[nIn]*/, + std::vector &outallne_nocut /*[nIn]*/, + std::vector &outallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const { + const unsigned int nIn = std::min(nIn_, pfallne.size()); + const unsigned int nTrack = std::min(nTrack_, track.size()); + const int PTMAX2 = (iptMax_ * iptMax_); + + const int sum_bitShift = LINPUPPI_sum_bitShift; + + outallne_nocut.resize(nIn); + outallne.resize(nIn); + for (unsigned int in = 0; in < nIn; ++in) { + outallne_nocut[in].clear(); + outallne[in].clear(); + if (pfallne[in].hwPt == 0) + continue; + uint64_t sum = 0; // 2 ^ sum_bitShift times (int pt^2)/(int dr2) + for (unsigned int it = 0; it < nTrack; ++it) { + if (track[it].hwPt == 0) + continue; + + int pZMin = 99999; + for (unsigned int v = 0; v < nVtx_; ++v) { + if (v < pv.size()) { + int ppZMin = std::abs(int(track[it].hwZ0 - pv[v].hwZ0)); + if (pZMin > ppZMin) + pZMin = ppZMin; + } + } + if (std::abs(pZMin) > int(dzCut_)) + continue; + unsigned int dr2 = dr2_int( + pfallne[in].hwEta, pfallne[in].hwPhi, track[it].hwEta, track[it].hwPhi); // if dr is inside puppi cone + if (dr2 <= dR2Max_) { + ap_uint<9> dr2short = (dr2 >= dR2Min_ ? dr2 : dR2Min_) >> 5; // reduce precision to make divide LUT cheaper + uint64_t pt2 = Scales::ptToInt(track[it].hwPt) * Scales::ptToInt(track[it].hwPt); + uint64_t term = std::min(pt2 >> 5, PTMAX2 >> 5) * ((1 << sum_bitShift) / int(dr2short)); + // dr2short >= (dR2Min_ >> 5) = 2 + // num <= (PTMAX2 >> 5) << sum_bitShift = (2^11) << 15 = 2^26 + // ==> term <= 2^25 + //dbgPrintf("ref term [%2d,%2d]: dr = %8d pt2_shift = %8lu term = %12lu\n", in, it, dr2, std::min(pt2 >> 5, PTMAX2 >> 5), term); + assert(uint64_t(PTMAX2 << (sum_bitShift - 5)) / (dR2Min_ >> 5) <= (1 << 25)); + assert(term < (1 << 25)); + sum += term; + //dbgPrintf(" pT cand %5.1f pT item %5.1f dR = %.3f term = %.1f [dbl] = %lu [int]\n", + // pfallne[in].floatPt(), track[it].floatPt(), std::sqrt(dr2*LINPUPPI_DR2LSB), + // double(std::min(pt2 >> 5, 131071)<<15)/double(std::max(dr2,dR2Min_) >> 5), + // term); + } + } + + unsigned int ieta = find_ieta(region, pfallne[in].hwEta); + bool isEM = (pfallne[in].hwId.isPhoton()); + std::pair ptAndW = sum2puppiPt_ref(sum, pfallne[in].hwPt, ieta, isEM, in); + if (!fakePuppi_) { + outallne_nocut[in].fill(region, pfallne[in], ptAndW.first, ptAndW.second); + if (region.isFiducial(pfallne[in]) && outallne_nocut[in].hwPt >= ptCut_[ieta]) { + outallne[in] = outallne_nocut[in]; + } + } else { // fakePuppi: keep the full candidate, but set the Puppi weight and some debug info into it + outallne_nocut[in].fill(region, pfallne[in], pfallne[in].hwPt, ptAndW.second); + outallne_nocut[in].hwData[9] = region.isFiducial(pfallne[in]); + outallne_nocut[in].hwData(20, 10) = ptAndW.first(10, 0); + outallne[in] = outallne_nocut[in]; + } + if (debug_ && pfallne[in].hwPt > 0 && outallne_nocut[in].hwPt > 0) { + dbgPrintf("ref candidate %02u pt %7.2f -> puppi pt %7.2f, fiducial %1d, packed %s\n", + in, + pfallne[in].floatPt(), + outallne_nocut[in].floatPt(), + int(region.isFiducial(pfallne[in])), + outallne_nocut[in].pack().to_string(16).c_str()); + } + } + puppisort_and_crop_ref(nOut_, outallne, outselne); +} + +std::pair l1ct::LinPuppiEmulator::sum2puppiPt_flt( + float sum, float pt, unsigned int ieta, bool isEM, int icand) const { + float alphaZero = alphaZero_[ieta], alphaSlope = alphaSlope_[ieta], alphaCrop = alphaCrop_[ieta]; + float alpha = sum > 0 ? std::log(sum) : -9e9; + float x2a = std::min(std::max(alphaSlope * (alpha - alphaZero), -alphaCrop), alphaCrop); + + float ptZero = (isEM ? ptZeroPh_[ieta] : ptZeroNe_[ieta]); + float ptSlope = (isEM ? ptSlopePh_[ieta] : ptSlopeNe_[ieta]); + float x2pt = ptSlope * (pt - ptZero); + + float prior = (isEM ? priorPh_[ieta] : priorNe_[ieta]); + + float x2 = x2a + x2pt - prior; + + float weight = 1.0 / (1.0 + std::exp(-x2)); + + float puppiPt = pt * weight; + if (debug_) + dbgPrintf( + "flt candidate %02d pt %7.2f em %1d ieta %1d: alpha %+7.2f x2a %+7.3f x2pt %+7.3f x2 " + " %+7.3f --> weight %.4f puppi pt %7.2f\n", + icand, + pt, + int(isEM), + ieta, + std::max(alpha, -99.99f), + x2a, + x2pt, + x2, + weight, + puppiPt); + + return std::make_pair(puppiPt, weight); +} + +void l1ct::LinPuppiEmulator::fwdlinpuppi_flt(const PFRegionEmu ®ion, + const std::vector &caloin /*[nIn]*/, + std::vector &outallne_nocut /*[nIn]*/, + std::vector &outallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const { + const unsigned int nIn = std::min(nIn_, caloin.size()); + const float f_ptMax = Scales::floatPt(Scales::makePt(iptMax_)); + + outallne_nocut.resize(nIn); + outallne.resize(nIn); + for (unsigned int in = 0; in < nIn; ++in) { + outallne_nocut[in].clear(); + outallne[in].clear(); + if (caloin[in].hwPt == 0) + continue; + float sum = 0; + for (unsigned int it = 0; it < nIn; ++it) { + if (it == in || caloin[it].hwPt == 0) + continue; + unsigned int dr2 = dr2_int( + caloin[it].hwEta, caloin[it].hwPhi, caloin[in].hwEta, caloin[in].hwPhi); // if dr is inside puppi cone + if (dr2 <= dR2Max_) { + sum += std::pow(std::min(caloin[it].floatPt(), f_ptMax), 2) / + (std::max(dr2, dR2Min_) * LINPUPPI_DR2LSB); + } + } + + unsigned int ieta = find_ieta(region, caloin[in].hwEta); + std::pair ptAndW = sum2puppiPt_flt(sum, caloin[in].floatPt(), ieta, caloin[in].hwIsEM(), in); + outallne_nocut[in].fill(region, caloin[in], Scales::makePtFromFloat(ptAndW.first), int(ptAndW.second * 256)); + if (region.isFiducial(caloin[in]) && outallne_nocut[in].hwPt >= ptCut_[ieta]) { + outallne[in] = outallne_nocut[in]; + } + } + + puppisort_and_crop_ref(nOut_, outallne, outselne); +} + +void l1ct::LinPuppiEmulator::linpuppi_flt(const PFRegionEmu ®ion, + const std::vector &track /*[nTrack]*/, + const std::vector &pv, + const std::vector &pfallne /*[nIn]*/, + std::vector &outallne_nocut /*[nIn]*/, + std::vector &outallne /*[nIn]*/, + std::vector &outselne /*[nOut]*/) const { + const unsigned int nIn = std::min(nIn_, pfallne.size()); + const unsigned int nTrack = std::min(nTrack_, track.size()); + const float f_ptMax = Scales::floatPt(Scales::makePt(iptMax_)); + + outallne_nocut.resize(nIn); + outallne.resize(nIn); + for (unsigned int in = 0; in < nIn; ++in) { + outallne_nocut[in].clear(); + outallne[in].clear(); + if (pfallne[in].hwPt == 0) + continue; + float sum = 0; + for (unsigned int it = 0; it < nTrack; ++it) { + if (track[it].hwPt == 0) + continue; + + int pZMin = 99999; + for (unsigned int v = 0; v < nVtx_; ++v) { + if (v < pv.size()) { + int ppZMin = std::abs(int(track[it].hwZ0 - pv[v].hwZ0)); + if (pZMin > ppZMin) + pZMin = ppZMin; + } + } + if (std::abs(pZMin) > int(dzCut_)) + continue; + unsigned int dr2 = dr2_int( + pfallne[in].hwEta, pfallne[in].hwPhi, track[it].hwEta, track[it].hwPhi); // if dr is inside puppi cone + if (dr2 <= dR2Max_) { + sum += std::pow(std::min(track[it].floatPt(), f_ptMax), 2) / + (std::max(dr2, dR2Min_) * LINPUPPI_DR2LSB); + } + } + unsigned int ieta = find_ieta(region, pfallne[in].hwEta); + bool isEM = pfallne[in].hwId.isPhoton(); + std::pair ptAndW = sum2puppiPt_flt(sum, pfallne[in].floatPt(), ieta, isEM, in); + outallne_nocut[in].fill(region, pfallne[in], Scales::makePtFromFloat(ptAndW.first), int(ptAndW.second * 256)); + if (region.isFiducial(pfallne[in]) && outallne_nocut[in].hwPt >= ptCut_[ieta]) { + outallne[in] = outallne_nocut[in]; + } + } + puppisort_and_crop_ref(nOut_, outallne, outselne); +} + +void l1ct::LinPuppiEmulator::run(const PFInputRegion &in, + const std::vector &pvs, + OutputRegion &out) const { + if (debug_) { + dbgPrintf("\nWill run LinPuppi in region eta %+5.2f, phi %+5.2f, pv0 int Z %+d\n", + in.region.floatEtaCenter(), + in.region.floatPhiCenter(), + pvs.front().hwZ0.to_int()); + } + if (std::abs(in.region.floatEtaCenter()) < 2.5) { // within tracker + std::vector outallch, outallne_nocut, outallne, outselne; + linpuppi_chs_ref(in.region, pvs, out.pfcharged, outallch); + linpuppi_ref(in.region, in.track, pvs, out.pfneutral, outallne_nocut, outallne, outselne); + // ensure proper sizes of the vectors, to get accurate sorting wrt firmware + const std::vector &ne = (nOut_ == nIn_ ? outallne : outselne); + unsigned int nch = outallch.size(), nne = ne.size(), i; + outallch.resize(nTrack_ + nOut_); + for (i = nch; i < nTrack_; ++i) + outallch[i].clear(); + for (unsigned int j = 0; j < nne; ++i, ++j) + outallch[i] = ne[j]; + for (; i < nTrack_ + nOut_; ++i) + outallch[i].clear(); + puppisort_and_crop_ref(nFinalSort_, outallch, out.puppi, finalSortAlgo_); + // trim if needed + while (!out.puppi.empty() && out.puppi.back().hwPt == 0) + out.puppi.pop_back(); + out.puppi.shrink_to_fit(); + } else { // forward + std::vector outallne_nocut, outallne; + fwdlinpuppi_ref(in.region, in.hadcalo, outallne_nocut, outallne, out.puppi); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.cpp deleted file mode 100644 index 5954b906ad51d..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include "pfalgo2hgc_ref.h" - -#ifndef CMSSW_GIT_HASH -#include "../DiscretePFInputs.h" -#else -#include "../../interface/DiscretePFInputs.h" -#endif - -#include "../utils/Firmware2DiscretePF.h" -#include -#include -#include -#include - -void pfalgo2hgc_ref(const pfalgo_config &cfg, - const HadCaloObj calo[/*cfg.nCALO*/], - const TkObj track[/*cfg.nTRACK*/], - const MuObj mu[/*cfg.nMU*/], - PFChargedObj outch[/*cfg.nTRACK*/], - PFNeutralObj outne[/*cfg.nSELCALO*/], - PFChargedObj outmu[/*cfg.nMU*/], - bool debug) { - if (debug) { -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - for (unsigned int i = 0; i < cfg.nTRACK; ++i) { - if (track[i].hwPt == 0) - continue; - l1tpf_impl::PropagatedTrack tk; - fw2dpf::convert(track[i], tk); - printf( - "FW \t track %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo ptErr %6d [ " - "%7.2f ] tight %d\n", - i, - tk.hwPt, - tk.floatPt(), - tk.hwEta, - tk.floatEta(), - tk.hwPhi, - tk.floatPhi(), - tk.hwCaloPtErr, - tk.floatCaloPtErr(), - int(track[i].hwTightQuality)); - } - for (unsigned int i = 0; i < cfg.nCALO; ++i) { - if (calo[i].hwPt == 0) - continue; - l1tpf_impl::CaloCluster c; - fw2dpf::convert(calo[i], c); - printf( - "FW \t calo %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo emPt %7d [ " - "%7.2f ] isEM %d \n", - i, - c.hwPt, - c.floatPt(), - c.hwEta, - c.floatEta(), - c.hwPhi, - c.floatPhi(), - c.hwEmPt, - c.floatEmPt(), - c.isEM); - } - for (unsigned int i = 0; i < cfg.nMU; ++i) { - if (mu[i].hwPt == 0) - continue; - l1tpf_impl::Muon muon; - fw2dpf::convert(mu[i], muon); - printf("FW \t muon %3d: pt %8d [ %7.2f ] muon eta %+7d [ %+5.2f ] muon phi %+7d [ %+5.2f ] \n", - i, - muon.hwPt, - muon.floatPt(), - muon.hwEta, - muon.floatEta(), - muon.hwPhi, - muon.floatPhi()); - } -#endif - } - - // constants - const pt_t TKPT_MAX_LOOSE = cfg.tk_MAXINVPT_LOOSE; - const pt_t TKPT_MAX_TIGHT = cfg.tk_MAXINVPT_TIGHT; - const int DR2MAX = cfg.dR2MAX_TK_CALO; - - //////////////////////////////////////////////////// - // TK-MU Linking - std::unique_ptr isMu(new bool[cfg.nTRACK]); - pfalgo_mu_ref(cfg, track, mu, &isMu[0], outmu, debug); - - //////////////////////////////////////////////////// - // TK-HAD Linking - - // initialize sum track pt - std::vector calo_sumtk(cfg.nCALO), calo_subpt(cfg.nCALO); - std::vector calo_sumtkErr2(cfg.nCALO); - for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { - calo_sumtk[ic] = 0; - calo_sumtkErr2[ic] = 0; - } - - // initialize good track bit - std::unique_ptr track_good(new bool[cfg.nTRACK]); - std::unique_ptr isEle(new bool[cfg.nTRACK]); - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - track_good[it] = (track[it].hwPt < (track[it].hwTightQuality ? TKPT_MAX_TIGHT : TKPT_MAX_LOOSE) || isMu[it]); - isEle[it] = false; - } - - // initialize output - for (unsigned int ipf = 0; ipf < cfg.nTRACK; ++ipf) - clear(outch[ipf]); - for (unsigned int ipf = 0; ipf < cfg.nSELCALO; ++ipf) - clear(outne[ipf]); - - // for each track, find the closest calo - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - if (track[it].hwPt > 0 && !isMu[it]) { - int ibest = best_match_with_pt_ref(cfg.nCALO, DR2MAX, calo, track[it]); - if (ibest != -1) { - if (debug) - printf("FW \t track %3d pt %7d matched to calo' %3d pt %7d\n", - it, - int(track[it].hwPt), - ibest, - int(calo[ibest].hwPt)); - track_good[it] = true; - isEle[it] = calo[ibest].hwIsEM; - calo_sumtk[ibest] += track[it].hwPt; - calo_sumtkErr2[ibest] += sqr(track[it].hwPtErr); - } - } - } - - for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { - if (calo_sumtk[ic] > 0) { - pt_t ptdiff = calo[ic].hwPt - calo_sumtk[ic]; - int sigmamult = - calo_sumtkErr2[ic]; // + (calo_sumtkErr2[ic] >> 1)); // this multiplies by 1.5 = sqrt(1.5)^2 ~ (1.2)^2 - if (debug && (calo[ic].hwPt > 0)) { -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - l1tpf_impl::CaloCluster floatcalo; - fw2dpf::convert(calo[ic], floatcalo); - printf( - "FW \t calo' %3d pt %7d [ %7.2f ] eta %+7d [ %+5.2f ] has a sum track pt %7d, difference %7d +- %.2f \n", - ic, - int(calo[ic].hwPt), - floatcalo.floatPt(), - int(calo[ic].hwEta), - floatcalo.floatEta(), - int(calo_sumtk[ic]), - int(ptdiff), - std::sqrt(float(int(calo_sumtkErr2[ic])))); -#endif - } - if (ptdiff > 0 && ptdiff * ptdiff > sigmamult) { - calo_subpt[ic] = ptdiff; - } else { - calo_subpt[ic] = 0; - } - } else { - calo_subpt[ic] = calo[ic].hwPt; - } - if (debug && (calo[ic].hwPt > 0)) - printf("FW \t calo' %3d pt %7d ---> %7d \n", ic, int(calo[ic].hwPt), int(calo_subpt[ic])); - } - - // copy out charged hadrons - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - if (track_good[it]) { - assert(!(isEle[it] && isMu[it])); - outch[it].hwPt = track[it].hwPt; - outch[it].hwEta = track[it].hwEta; - outch[it].hwPhi = track[it].hwPhi; - outch[it].hwZ0 = track[it].hwZ0; - outch[it].hwId = isEle[it] ? PID_Electron : (isMu[it] ? PID_Muon : PID_Charged); - } - } - - // copy out neutral hadrons with sorting and cropping - std::vector outne_all(cfg.nCALO); - for (unsigned int ipf = 0; ipf < cfg.nCALO; ++ipf) - clear(outne_all[ipf]); - for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { - if (calo_subpt[ic] > 0) { - outne_all[ic].hwPt = calo_subpt[ic]; - outne_all[ic].hwEta = calo[ic].hwEta; - outne_all[ic].hwPhi = calo[ic].hwPhi; - outne_all[ic].hwId = calo[ic].hwIsEM ? PID_Photon : PID_Neutral; - } - } - - ptsort_ref(cfg.nCALO, cfg.nSELCALO, outne_all, outne); -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.h b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.h deleted file mode 100644 index e33f611f768ac..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo2hgc_ref.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_PFALGO2HGC_REF_H -#define L1Trigger_Phase2L1ParticleFlow_PFALGO2HGC_REF_H - -#include "../firmware/pfalgo2hgc.h" -#include "pfalgo_common_ref.h" - -void pfalgo2hgc_ref(const pfalgo_config &cfg, - const HadCaloObj calo[/*cfg.nCALO*/], - const TkObj track[/*cfg.nTRACK*/], - const MuObj mu[/*cfg.nMU*/], - PFChargedObj outch[/*cfg.nTRACK*/], - PFNeutralObj outne[/*cfg.nSELCALO*/], - PFChargedObj outmu[/*cfg.nMU*/], - bool debug); - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.cpp deleted file mode 100644 index 5021b4bbd0d83..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.cpp +++ /dev/null @@ -1,483 +0,0 @@ -#include "pfalgo3_ref.h" - -#ifndef CMSSW_GIT_HASH -#include "../DiscretePFInputs.h" -#else -#include "../../interface/DiscretePFInputs.h" -#endif - -#include "../utils/Firmware2DiscretePF.h" -#include -#include -#include -#include -#include - -template -int tk_best_match_ref(unsigned int nCAL, unsigned int dR2MAX, const CO_t calo[/*nCAL*/], const TkObj &track) { - pt_t caloPtMin = track.hwPt - 2 * (track.hwPtErr); - if (caloPtMin < 0) - caloPtMin = 0; - int drmin = dR2MAX, ibest = -1; - for (unsigned int ic = 0; ic < nCAL; ++ic) { - if (calo[ic].hwPt <= 0) - continue; - if (doPtMin && calo[ic].hwPt <= caloPtMin) - continue; - int dr = dr2_int(track.hwEta, track.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); - if (dr < drmin) { - drmin = dr; - ibest = ic; - } - } - return ibest; -} -int em_best_match_ref(unsigned int nCAL, unsigned int dR2MAX, const HadCaloObj calo[/*nCAL*/], const EmCaloObj &em) { - pt_t emPtMin = em.hwPt >> 1; - int drmin = dR2MAX, ibest = -1; - for (unsigned int ic = 0; ic < nCAL; ++ic) { - if (calo[ic].hwEmPt <= emPtMin) - continue; - int dr = dr2_int(em.hwEta, em.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); - if (dr < drmin) { - drmin = dr; - ibest = ic; - } - } - return ibest; -} - -void pfalgo3_em_ref(const pfalgo3_config &cfg, - const EmCaloObj emcalo[/*cfg.nEMCALO*/], - const HadCaloObj hadcalo[/*cfg.nCALO*/], - const TkObj track[/*cfg.nTRACK*/], - const bool isMu[/*cfg.nTRACK*/], - bool isEle[/*cfg.nTRACK*/], - PFNeutralObj outpho[/*cfg.nPHOTON*/], - HadCaloObj hadcalo_out[/*cfg.nCALO*/], - bool debug) { - // constants - const int DR2MAX_TE = cfg.dR2MAX_TK_EM; - const int DR2MAX_EH = cfg.dR2MAX_EM_CALO; - - // initialize sum track pt - std::vector calo_sumtk(cfg.nEMCALO); - for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { - calo_sumtk[ic] = 0; - } - std::vector tk2em(cfg.nTRACK); - std::vector isEM(cfg.nEMCALO); - // for each track, find the closest calo - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - if (track[it].hwPt > 0 && !isMu[it]) { - tk2em[it] = tk_best_match_ref(cfg.nEMCALO, DR2MAX_TE, emcalo, track[it]); - if (tk2em[it] != -1) { - if (debug) - printf("FW \t track %3d pt %7d matched to em calo %3d pt %7d\n", - it, - int(track[it].hwPt), - tk2em[it], - int(emcalo[tk2em[it]].hwPt)); - calo_sumtk[tk2em[it]] += track[it].hwPt; - } - } else { - tk2em[it] = -1; - } - } - - if (debug) { - for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { - if (emcalo[ic].hwPt > 0) - printf("FW \t emcalo %3d pt %7d has sumtk %7d\n", ic, int(emcalo[ic].hwPt), int(calo_sumtk[ic])); - } - } - - for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { - pt_t photonPt; - if (calo_sumtk[ic] > 0) { - pt_t ptdiff = emcalo[ic].hwPt - calo_sumtk[ic]; - int sigma2 = sqr(emcalo[ic].hwPtErr); - int sigma2Lo = 4 * sigma2, - sigma2Hi = sigma2; // + (sigma2>>1); // cut at 1 sigma instead of old cut at sqrt(1.5) sigma's - int ptdiff2 = ptdiff * ptdiff; - if ((ptdiff >= 0 && ptdiff2 <= sigma2Hi) || (ptdiff < 0 && ptdiff2 < sigma2Lo)) { - // electron - photonPt = 0; - isEM[ic] = true; - if (debug) - printf("FW \t emcalo %3d pt %7d ptdiff %7d [match window: -%.2f / +%.2f] flagged as electron\n", - ic, - int(emcalo[ic].hwPt), - int(ptdiff), - std::sqrt(float(sigma2Lo)), - std::sqrt(float(sigma2Hi))); - } else if (ptdiff > 0) { - // electron + photon - photonPt = ptdiff; - isEM[ic] = true; - if (debug) - printf( - "FW \t emcalo %3d pt %7d ptdiff %7d [match window: -%.2f / +%.2f] flagged as electron + photon of pt " - "%7d\n", - ic, - int(emcalo[ic].hwPt), - int(ptdiff), - std::sqrt(float(sigma2Lo)), - std::sqrt(float(sigma2Hi)), - int(photonPt)); - } else { - // pion - photonPt = 0; - isEM[ic] = false; - if (debug) - printf("FW \t emcalo %3d pt %7d ptdiff %7d [match window: -%.2f / +%.2f] flagged as pion\n", - ic, - int(emcalo[ic].hwPt), - int(ptdiff), - std::sqrt(float(sigma2Lo)), - std::sqrt(float(sigma2Hi))); - } - } else { - // photon - isEM[ic] = true; - photonPt = emcalo[ic].hwPt; - if (debug && emcalo[ic].hwPt > 0) - printf("FW \t emcalo %3d pt %7d flagged as photon\n", ic, int(emcalo[ic].hwPt)); - } - outpho[ic].hwPt = photonPt; - outpho[ic].hwEta = photonPt ? emcalo[ic].hwEta : etaphi_t(0); - outpho[ic].hwPhi = photonPt ? emcalo[ic].hwPhi : etaphi_t(0); - outpho[ic].hwId = photonPt ? PID_Photon : particleid_t(0); - } - - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - isEle[it] = (tk2em[it] != -1) && isEM[tk2em[it]]; - if (debug && isEle[it]) - printf("FW \t track %3d pt %7d flagged as electron.\n", it, int(track[it].hwPt)); - } - - std::vector em2calo(cfg.nEMCALO); - for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { - em2calo[ic] = em_best_match_ref(cfg.nCALO, DR2MAX_EH, hadcalo, emcalo[ic]); - if (debug && (emcalo[ic].hwPt > 0)) { - printf("FW \t emcalo %3d pt %7d isEM %d matched to hadcalo %7d pt %7d emPt %7d isEM %d\n", - ic, - int(emcalo[ic].hwPt), - int(isEM[ic]), - em2calo[ic], - (em2calo[ic] >= 0 ? int(hadcalo[em2calo[ic]].hwPt) : -1), - (em2calo[ic] >= 0 ? int(hadcalo[em2calo[ic]].hwEmPt) : -1), - (em2calo[ic] >= 0 ? int(hadcalo[em2calo[ic]].hwIsEM) : 0)); - } - } - - for (unsigned int ih = 0; ih < cfg.nCALO; ++ih) { - hadcalo_out[ih] = hadcalo[ih]; - pt_t sub = 0; - bool keep = false; - for (unsigned int ic = 0; ic < cfg.nEMCALO; ++ic) { - if (em2calo[ic] == int(ih)) { - if (isEM[ic]) - sub += emcalo[ic].hwPt; - else - keep = true; - } - } - pt_t emdiff = hadcalo[ih].hwEmPt - sub; - pt_t alldiff = hadcalo[ih].hwPt - sub; - if (debug && (hadcalo[ih].hwPt > 0)) { - printf("FW \t calo %3d pt %7d has a subtracted pt of %7d, empt %7d -> %7d isem %d mustkeep %d \n", - ih, - int(hadcalo[ih].hwPt), - int(alldiff), - int(hadcalo[ih].hwEmPt), - int(emdiff), - int(hadcalo[ih].hwIsEM), - keep); - } - if (alldiff <= (hadcalo[ih].hwPt >> 4)) { - hadcalo_out[ih].hwPt = 0; // kill - hadcalo_out[ih].hwEmPt = 0; // kill - if (debug && (hadcalo[ih].hwPt > 0)) - printf("FW \t calo %3d pt %7d --> discarded (zero pt)\n", ih, int(hadcalo[ih].hwPt)); - } else if ((hadcalo[ih].hwIsEM && emdiff <= (hadcalo[ih].hwEmPt >> 3)) && !keep) { - hadcalo_out[ih].hwPt = 0; // kill - hadcalo_out[ih].hwEmPt = 0; // kill - if (debug && (hadcalo[ih].hwPt > 0)) - printf("FW \t calo %3d pt %7d --> discarded (zero em)\n", ih, int(hadcalo[ih].hwPt)); - } else { - hadcalo_out[ih].hwPt = alldiff; - hadcalo_out[ih].hwEmPt = (emdiff > 0 ? emdiff : pt_t(0)); - } - } -} - -void pfalgo3_ref(const pfalgo3_config &cfg, - const EmCaloObj emcalo[/*cfg.nEMCALO*/], - const HadCaloObj hadcalo[/*cfg.nCALO*/], - const TkObj track[/*cfg.nTRACK*/], - const MuObj mu[/*cfg.nMU*/], - PFChargedObj outch[/*cfg.nTRACK*/], - PFNeutralObj outpho[/*cfg.nPHOTON*/], - PFNeutralObj outne[/*cfg.nSELCALO*/], - PFChargedObj outmu[/*cfg.nMU*/], - bool debug) { - if (debug) { -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - for (unsigned int i = 0; i < cfg.nTRACK; ++i) { - if (track[i].hwPt == 0) - continue; - l1tpf_impl::PropagatedTrack tk; - fw2dpf::convert(track[i], tk); - printf( - "FW \t track %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo ptErr %6d [ " - "%7.2f ] tight %d\n", - i, - tk.hwPt, - tk.floatPt(), - tk.hwEta, - tk.floatEta(), - tk.hwPhi, - tk.floatPhi(), - tk.hwCaloPtErr, - tk.floatCaloPtErr(), - int(track[i].hwTightQuality)); - } - for (unsigned int i = 0; i < cfg.nEMCALO; ++i) { - if (emcalo[i].hwPt == 0) - continue; - l1tpf_impl::CaloCluster em; - fw2dpf::convert(emcalo[i], em); - printf( - "FW \t EM %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo ptErr %6d [ " - "%7.2f ] \n", - i, - em.hwPt, - em.floatPt(), - em.hwEta, - em.floatEta(), - em.hwPhi, - em.floatPhi(), - em.hwPtErr, - em.floatPtErr()); - } - for (unsigned int i = 0; i < cfg.nCALO; ++i) { - if (hadcalo[i].hwPt == 0) - continue; - l1tpf_impl::CaloCluster calo; - fw2dpf::convert(hadcalo[i], calo); - printf( - "FW \t calo %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] calo emPt %7d [ " - "%7.2f ] isEM %d \n", - i, - calo.hwPt, - calo.floatPt(), - calo.hwEta, - calo.floatEta(), - calo.hwPhi, - calo.floatPhi(), - calo.hwEmPt, - calo.floatEmPt(), - calo.isEM); - } - for (unsigned int i = 0; i < cfg.nMU; ++i) { - if (mu[i].hwPt == 0) - continue; - l1tpf_impl::Muon muon; - fw2dpf::convert(mu[i], muon); - printf("FW \t muon %3d: pt %8d [ %7.2f ] muon eta %+7d [ %+5.2f ] muon phi %+7d [ %+5.2f ] \n", - i, - muon.hwPt, - muon.floatPt(), - muon.hwEta, - muon.floatEta(), - muon.hwPhi, - muon.floatPhi()); - } -#endif - } - - // constants - const pt_t TKPT_MAX_LOOSE = cfg.tk_MAXINVPT_LOOSE; - const pt_t TKPT_MAX_TIGHT = cfg.tk_MAXINVPT_TIGHT; - const int DR2MAX = cfg.dR2MAX_TK_CALO; - - //////////////////////////////////////////////////// - // TK-MU Linking - // // we can't use std::vector here because it's specialized - std::unique_ptr isMu(new bool[cfg.nTRACK]); - pfalgo_mu_ref(cfg, track, mu, &isMu[0], outmu, debug); - - //////////////////////////////////////////////////// - // TK-EM Linking - std::unique_ptr isEle(new bool[cfg.nTRACK]); - std::vector hadcalo_subem(cfg.nCALO); - pfalgo3_em_ref(cfg, emcalo, hadcalo, track, &isMu[0], &isEle[0], outpho, &hadcalo_subem[0], debug); - - //////////////////////////////////////////////////// - // TK-HAD Linking - - // initialize sum track pt - std::vector calo_sumtk(cfg.nCALO), calo_subpt(cfg.nCALO); - std::vector calo_sumtkErr2(cfg.nCALO); - for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { - calo_sumtk[ic] = 0; - calo_sumtkErr2[ic] = 0; - } - - // initialize good track bit - std::unique_ptr track_good(new bool[cfg.nTRACK]); - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - track_good[it] = - (track[it].hwPt < (track[it].hwTightQuality ? TKPT_MAX_TIGHT : TKPT_MAX_LOOSE) || isEle[it] || isMu[it]); - } - - // initialize output - for (unsigned int ipf = 0; ipf < cfg.nTRACK; ++ipf) { - clear(outch[ipf]); - } - for (unsigned int ipf = 0; ipf < cfg.nSELCALO; ++ipf) { - clear(outne[ipf]); - } - - // for each track, find the closest calo - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - if (track[it].hwPt > 0 && !isEle[it] && !isMu[it]) { - int ibest = best_match_with_pt_ref(cfg.nCALO, DR2MAX, &hadcalo_subem[0], track[it]); - //int ibest = tk_best_match_ref(cfg.nCALO, DR2MAX, &hadcalo_subem[0], track[it]); - if (ibest != -1) { - if (debug) - printf("FW \t track %3d pt %7d matched to calo %3d pt %7d\n", - it, - int(track[it].hwPt), - ibest, - int(hadcalo_subem[ibest].hwPt)); - track_good[it] = true; - calo_sumtk[ibest] += track[it].hwPt; - calo_sumtkErr2[ibest] += sqr(track[it].hwPtErr); - } - } - } - - for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { - if (calo_sumtk[ic] > 0) { - pt_t ptdiff = hadcalo_subem[ic].hwPt - calo_sumtk[ic]; - int sigmamult = calo_sumtkErr2 - [ic]; // before we did (calo_sumtkErr2[ic] + (calo_sumtkErr2[ic] >> 1)); to multiply by 1.5 = sqrt(1.5)^2 ~ (1.2)^2 - if (debug && (hadcalo_subem[ic].hwPt > 0)) { -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - l1tpf_impl::CaloCluster floatcalo; - fw2dpf::convert(hadcalo_subem[ic], floatcalo); - printf( - "FW \t calo %3d pt %7d [ %7.2f ] eta %+7d [ %+5.2f ] has a sum track pt %7d, difference %7d +- %.2f \n", - ic, - int(hadcalo_subem[ic].hwPt), - floatcalo.floatPt(), - int(hadcalo_subem[ic].hwEta), - floatcalo.floatEta(), - int(calo_sumtk[ic]), - int(ptdiff), - std::sqrt(float(int(calo_sumtkErr2[ic])))); -#endif - } - if (ptdiff > 0 && ptdiff * ptdiff > sigmamult) { - calo_subpt[ic] = ptdiff; - } else { - calo_subpt[ic] = 0; - } - } else { - calo_subpt[ic] = hadcalo_subem[ic].hwPt; - } - if (debug && (hadcalo_subem[ic].hwPt > 0)) - printf("FW \t calo %3d pt %7d ---> %7d \n", ic, int(hadcalo_subem[ic].hwPt), int(calo_subpt[ic])); - } - - // copy out charged hadrons - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - if (track_good[it]) { - outch[it].hwPt = track[it].hwPt; - outch[it].hwEta = track[it].hwEta; - outch[it].hwPhi = track[it].hwPhi; - outch[it].hwZ0 = track[it].hwZ0; - outch[it].hwId = isEle[it] ? PID_Electron : (isMu[it] ? PID_Muon : PID_Charged); - } - } - - // copy out neutral hadrons - std::vector outne_all(cfg.nCALO); - for (unsigned int ipf = 0; ipf < cfg.nCALO; ++ipf) { - clear(outne_all[ipf]); - } - for (unsigned int ic = 0; ic < cfg.nCALO; ++ic) { - if (calo_subpt[ic] > 0) { - outne_all[ic].hwPt = calo_subpt[ic]; - outne_all[ic].hwEta = hadcalo_subem[ic].hwEta; - outne_all[ic].hwPhi = hadcalo_subem[ic].hwPhi; - outne_all[ic].hwId = PID_Neutral; - } - } - - ptsort_ref(cfg.nCALO, cfg.nSELCALO, outne_all, outne); - - if (debug) { -#ifdef L1Trigger_Phase2L1ParticleFlow_DiscretePFInputs_MORE - std::vector tmp; - for (unsigned int i = 0; i < cfg.nTRACK; ++i) { - if (outch[i].hwPt == 0) - continue; - fw2dpf::convert(outch[i], track[i], tmp); - auto &pf = tmp.back(); - printf("FW \t outch %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] pid %d\n", - i, - pf.hwPt, - pf.floatPt(), - pf.hwEta, - pf.floatEta(), - pf.hwPhi, - pf.floatPhi(), - pf.hwId); - } - for (unsigned int i = 0; i < cfg.nPHOTON; ++i) { - if (outpho[i].hwPt == 0) - continue; - fw2dpf::convert(outpho[i], tmp); - auto &pf = tmp.back(); - printf("FW \t outph %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] pid %d\n", - i, - pf.hwPt, - pf.floatPt(), - pf.hwEta, - pf.floatEta(), - pf.hwPhi, - pf.floatPhi(), - pf.hwId); - } - for (unsigned int i = 0; i < cfg.nSELCALO; ++i) { - if (outne[i].hwPt == 0) - continue; - fw2dpf::convert(outne[i], tmp); - auto &pf = tmp.back(); - printf("FW \t outne %3d: pt %8d [ %7.2f ] calo eta %+7d [ %+5.2f ] calo phi %+7d [ %+5.2f ] pid %d\n", - i, - pf.hwPt, - pf.floatPt(), - pf.hwEta, - pf.floatEta(), - pf.hwPhi, - pf.floatPhi(), - pf.hwId); - } -#endif - } -} - -void pfalgo3_merge_neutrals_ref(const pfalgo3_config &cfg, - const PFNeutralObj pho[/*cfg.nPHOTON*/], - const PFNeutralObj ne[/*cfg.nSELCALO*/], - PFNeutralObj allne[/*cfg.nALLNEUTRALS*/]) { - int j = 0; - for (unsigned int i = 0; i < cfg.nPHOTON; ++i, ++j) - allne[j] = pho[i]; - for (unsigned int i = 0; i < cfg.nSELCALO; ++i, ++j) - allne[j] = ne[i]; -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.h b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.h deleted file mode 100644 index be1b82bbbce3a..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo3_ref.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_PFALGO3_REF_H -#define L1Trigger_Phase2L1ParticleFlow_PFALGO3_REF_H - -#include "../firmware/pfalgo3.h" -#include "pfalgo_common_ref.h" - -struct pfalgo3_config : public pfalgo_config { - unsigned int nEMCALO, nPHOTON, nALLNEUTRAL; - unsigned int dR2MAX_TK_EM; - unsigned int dR2MAX_EM_CALO; - - pfalgo3_config(unsigned int nTrack, - unsigned int nEmCalo, - unsigned int nCalo, - unsigned int nMu, - unsigned int nPhoton, - unsigned int nSelCalo, - unsigned int nAllNeutral, - unsigned int dR2Max_Tk_Mu, - unsigned int dR2Max_Tk_Em, - unsigned int dR2Max_Em_Calo, - unsigned int dR2Max_Tk_Calo, - unsigned int tk_MaxInvPt_Loose, - unsigned int tk_MaxInvPt_Tight) - : pfalgo_config(nTrack, nCalo, nMu, nSelCalo, dR2Max_Tk_Mu, dR2Max_Tk_Calo, tk_MaxInvPt_Loose, tk_MaxInvPt_Tight), - nEMCALO(nEmCalo), - nPHOTON(nPhoton), - nALLNEUTRAL(nAllNeutral), - dR2MAX_TK_EM(dR2Max_Tk_Em), - dR2MAX_EM_CALO(dR2Max_Em_Calo) {} - ~pfalgo3_config() override {} -}; - -void pfalgo3_em_ref(const pfalgo3_config &cfg, - const EmCaloObj emcalo[/*cfg.nEMCALO*/], - const HadCaloObj hadcalo[/*cfg.nCALO*/], - const TkObj track[/*cfg.nTRACK*/], - const bool isMu[/*cfg.nTRACK*/], - bool isEle[/*cfg.nTRACK*/], - PFNeutralObj outpho[/*cfg.nPHOTON*/], - HadCaloObj hadcalo_out[/*cfg.nCALO*/], - bool debug); -void pfalgo3_ref(const pfalgo3_config &cfg, - const EmCaloObj emcalo[/*cfg.nEMCALO*/], - const HadCaloObj hadcalo[/*cfg.nCALO*/], - const TkObj track[/*cfg.nTRACK*/], - const MuObj mu[/*cfg.nMU*/], - PFChargedObj outch[/*cfg.nTRACK*/], - PFNeutralObj outpho[/*cfg.nPHOTON*/], - PFNeutralObj outne[/*cfg.nSELCALO*/], - PFChargedObj outmu[/*cfg.nMU*/], - bool debug); - -void pfalgo3_merge_neutrals_ref(const pfalgo3_config &cfg, - const PFNeutralObj pho[/*cfg.nPHOTON*/], - const PFNeutralObj ne[/*cfg.nSELCALO*/], - PFNeutralObj allne[/*cfg.nALLNEUTRALS*/]); -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.cpp deleted file mode 100644 index 8844c0617149b..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "pfalgo_common_ref.h" - -#include -#include - -void pfalgo_mu_ref(const pfalgo_config &cfg, - const TkObj track[/*cfg.nTRACK*/], - const MuObj mu[/*cfg.nMU*/], - bool isMu[/*cfg.nTRACK*/], - PFChargedObj outmu[/*cfg.nMU*/], - bool debug) { - // init - for (unsigned int ipf = 0; ipf < cfg.nMU; ++ipf) - clear(outmu[ipf]); - for (unsigned int it = 0; it < cfg.nTRACK; ++it) - isMu[it] = false; - - // for each muon, find the closest track - for (unsigned int im = 0; im < cfg.nMU; ++im) { - if (mu[im].hwPt > 0) { - int ibest = -1; - int dptmin = mu[im].hwPt >> 1; - for (unsigned int it = 0; it < cfg.nTRACK; ++it) { - unsigned int dr = dr2_int(mu[im].hwEta, mu[im].hwPhi, track[it].hwEta, track[it].hwPhi); - //printf("deltaR2(mu %d float pt %5.1f, tk %2d float pt %5.1f) = int %d (float deltaR = %.3f); int cut at %d\n", im, 0.25*int(mu[im].hwPt), it, 0.25*int(track[it].hwPt), dr, std::sqrt(float(dr))/229.2, cfg.dR2MAX_TK_MU); - if (dr < cfg.dR2MAX_TK_MU) { - int dpt = std::abs(int(track[it].hwPt - mu[im].hwPt)); - if (dpt < dptmin) { - dptmin = dpt; - ibest = it; - } - } - } - if (ibest != -1) { - outmu[im].hwPt = track[ibest].hwPt; - outmu[im].hwEta = track[ibest].hwEta; - outmu[im].hwPhi = track[ibest].hwPhi; - outmu[im].hwId = PID_Muon; - outmu[im].hwZ0 = track[ibest].hwZ0; - isMu[ibest] = true; - if (debug) - printf("FW \t muon %3d linked to track %3d \n", im, ibest); - } else { - if (debug) - printf("FW \t muon %3d not linked to any track\n", im); - } - } - } -} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.h b/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.h deleted file mode 100644 index 87b2b7194697c..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/ref/pfalgo_common_ref.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_PFALGO_COMMON_REF_H -#define L1Trigger_Phase2L1ParticleFlow_PFALGO_COMMON_REF_H - -#include "../firmware/data.h" -#include "../firmware/pfalgo_common.h" -#include - -template -inline int sqr(const T &t) { - return t * t; -} - -template -int best_match_with_pt_ref(int nCAL, int dR2MAX, const CO_t calo[/*nCAL*/], const TkObj &track); - -template -void ptsort_ref(int nIn, int nOut, const T in[/*nIn*/], T out[/*nOut*/]); - -struct pfalgo_config { - unsigned int nTRACK, nCALO, nMU; - unsigned int nSELCALO; - unsigned int dR2MAX_TK_MU; - unsigned int dR2MAX_TK_CALO; - unsigned int tk_MAXINVPT_LOOSE, tk_MAXINVPT_TIGHT; - - pfalgo_config(unsigned int nTrack, - unsigned int nCalo, - unsigned int nMu, - unsigned int nSelCalo, - unsigned int dR2Max_Tk_Mu, - unsigned int dR2Max_Tk_Calo, - unsigned int tk_MaxInvPt_Loose, - unsigned int tk_MaxInvPt_Tight) - : nTRACK(nTrack), - nCALO(nCalo), - nMU(nMu), - nSELCALO(nSelCalo), - dR2MAX_TK_MU(dR2Max_Tk_Mu), - dR2MAX_TK_CALO(dR2Max_Tk_Calo), - tk_MAXINVPT_LOOSE(tk_MaxInvPt_Loose), - tk_MAXINVPT_TIGHT(tk_MaxInvPt_Tight) {} - - virtual ~pfalgo_config() {} -}; - -void pfalgo_mu_ref(const pfalgo_config &cfg, - const TkObj track[/*cfg.nTRACK*/], - const MuObj mu[/*cfg.nMU*/], - bool isMu[/*cfg.nTRACK*/], - PFChargedObj outmu[/*cfg.nMU*/], - bool debug); - -//=== begin implementation part - -template -int best_match_with_pt_ref(int nCAL, int dR2MAX, const CO_t calo[/*nCAL*/], const TkObj &track) { - pt_t caloPtMin = track.hwPt - 2 * (track.hwPtErr); - if (caloPtMin < 0) - caloPtMin = 0; - int dptscale = (dR2MAX << 8) / std::max(1, sqr(track.hwPtErr)); - int drmin = 0, ibest = -1; - for (int ic = 0; ic < nCAL; ++ic) { - if (calo[ic].hwPt <= caloPtMin) - continue; - int dr = dr2_int(track.hwEta, track.hwPhi, calo[ic].hwEta, calo[ic].hwPhi); - if (dr >= dR2MAX) - continue; - dr += ((sqr(std::max(track.hwPt - calo[ic].hwPt, 0)) * dptscale) >> 8); - if (ibest == -1 || dr < drmin) { - drmin = dr; - ibest = ic; - } - } - return ibest; -} - -template -void ptsort_ref(int nIn, int nOut, const TV &in /*[nIn]*/, T out[/*nOut*/]) { - for (int iout = 0; iout < nOut; ++iout) { - out[iout].hwPt = 0; - } - for (int it = 0; it < nIn; ++it) { - for (int iout = 0; iout < nOut; ++iout) { - if (in[it].hwPt >= out[iout].hwPt) { - for (int i2 = nOut - 1; i2 > iout; --i2) { - out[i2] = out[i2 - 1]; - } - out[iout] = in[it]; - break; - } - } - } -} - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/multififo_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/multififo_regionizer_ref.cpp new file mode 100644 index 0000000000000..feb87ce4b9dfe --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/multififo_regionizer_ref.cpp @@ -0,0 +1,553 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pfeginput_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.icc" + +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(const edm::ParameterSet& iConfig) + : MultififoRegionizerEmulator(iConfig.getParameter("nEndcaps"), + iConfig.getParameter("nClocks"), + iConfig.getParameter("nTrack"), + iConfig.getParameter("nCalo"), + iConfig.getParameter("nEmCalo"), + iConfig.getParameter("nMu"), + /*streaming=*/false, + /*outii=*/1, + iConfig.getParameter("useAlsoVtxCoords")) { + debug_ = iConfig.getUntrackedParameter("debug", false); + if (iConfig.existsAs("egInterceptMode")) { + const auto& emSelCfg = iConfig.getParameter("egInterceptMode"); + setEgInterceptMode(emSelCfg.getParameter("afterFifo"), emSelCfg); + } +} +#endif + +l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(unsigned int nendcaps, + unsigned int nclocks, + unsigned int ntk, + unsigned int ncalo, + unsigned int nem, + unsigned int nmu, + bool streaming, + unsigned int outii, + bool useAlsoVtxCoords) + : RegionizerEmulator(useAlsoVtxCoords), + NTK_SECTORS(9), + NCALO_SECTORS(3), + NTK_LINKS(2), + NCALO_LINKS(3), + HCAL_LINKS(0), + ECAL_LINKS(0), + NMU_LINKS(1), + nendcaps_(nendcaps), + nclocks_(nclocks), + ntk_(ntk), + ncalo_(ncalo), + nem_(nem), + nmu_(nmu), + outii_(outii), + pauseii_(0), + 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) { + // 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); + } + } + } + // hgcal + assert(NCALO_SECTORS == 3 && NTK_SECTORS == 9); // otherwise math below is broken, but it's hard to make it generic + for (unsigned int ie = 0; ie < nendcaps; ++ie) { + for (unsigned int is = 0; is < NCALO_SECTORS; ++is) { // NCALO_SECTORS sectors + for (unsigned int il = 0; il < NCALO_LINKS; ++il) { // max clusters per sector per clock + for (unsigned int j = 0; j < 3; ++j) { // PF REGION + caloRoutes_.emplace_back(is + 3 * ie, il, 3 * is + j + 9 * ie, il); // 4 args are: sector, link, region, fifo + if (j != 2) { // pf regions 0 and 1 take also from previous sector + int isprev = (is > 0 ? is - 1 : NCALO_SECTORS - 1); + caloRoutes_.emplace_back(isprev + 3 * ie, il, 3 * is + j + 9 * ie, il + NCALO_LINKS); + } + } + } + } + } + emCaloRoutes_ = caloRoutes_; // in the endcaps there's only one calo + // mu + for (unsigned int il = 0; il < NMU_LINKS && nmu > 0; ++il) { // max clusters per sector per clock + for (unsigned int j = 0; j < NTK_SECTORS * nendcaps; ++j) { + muRoutes_.emplace_back(0, il, j, il); + } + } +} + +l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(BarrelSetup barrelSetup, + unsigned int nHCalLinks, + unsigned int nECalLinks, + 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) + : RegionizerEmulator(useAlsoVtxCoords), + NTK_SECTORS((barrelSetup == BarrelSetup::Phi18 || barrelSetup == BarrelSetup::Phi9) ? 5 : 9), + NCALO_SECTORS((barrelSetup == BarrelSetup::Phi18 || barrelSetup == BarrelSetup::Phi9) ? 2 : 3), + NTK_LINKS(2), + NCALO_LINKS(2), + HCAL_LINKS(nHCalLinks), + ECAL_LINKS(nECalLinks), + NMU_LINKS(1), + nendcaps_(0), + nclocks_(nclocks), + ntk_(ntk), + ncalo_(ncalo), + nem_(nem), + nmu_(nmu), + outii_(outii), + pauseii_(pauseii), + streaming_(streaming), + emInterceptMode_(noIntercept), + init_(false), + 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) { + unsigned int nendcaps = 2, etaslices = 0; + switch (barrelSetup) { + case BarrelSetup::Full54: + nregions_ = 54; + etaslices = 6; + break; + case BarrelSetup::Full27: + nregions_ = 27; + etaslices = 3; + break; + case BarrelSetup::Central18: + nregions_ = 18; + etaslices = 2; + break; + case BarrelSetup::Central9: + nregions_ = 9; + etaslices = 1; + break; + case BarrelSetup::Phi18: + nregions_ = 18; + etaslices = 6; + break; + case BarrelSetup::Phi9: + nregions_ = 9; + etaslices = 3; + break; + } + unsigned int phisectors = nregions_ / etaslices; + // now we initialize the routes: track finder + for (unsigned int ietaslice = 0; ietaslice < etaslices && ntk > 0; ++ietaslice) { + for (unsigned int ie = 0; ie < nendcaps; ++ie) { // 0 = negative, 1 = positive + unsigned int nTFEtaSlices = 1; + if (etaslices == 3) { + if (ietaslice == 0 && ie == 1) + continue; + if (ietaslice == 2 && ie == 0) + continue; + if (ietaslice == 1) + nTFEtaSlices = 2; + } else if (etaslices == 6) { + if (ietaslice <= 1 && ie == 1) + continue; + if (ietaslice >= 4 && ie == 0) + continue; + if (ietaslice == 2 || ietaslice == 3) + nTFEtaSlices = 2; + } else if (barrelSetup == BarrelSetup::Central18 || barrelSetup == BarrelSetup::Central9) { + nTFEtaSlices = 2; + } + unsigned int ireg0 = phisectors * ietaslice, il0 = 6 * (nTFEtaSlices - 1) * ie; + if (barrelSetup == BarrelSetup::Phi18 || barrelSetup == BarrelSetup::Phi9) { + for (unsigned int iregphi = 0; iregphi < (nregions_ / etaslices); ++iregphi) { + for (unsigned int il = 0; il < NTK_LINKS; ++il) { + tkRoutes_.emplace_back((iregphi + 1) + NTK_SECTORS * ie, il, iregphi + ireg0, il0 + il); + tkRoutes_.emplace_back((iregphi + 0) + NTK_SECTORS * ie, il, iregphi + ireg0, il0 + il + 2); + tkRoutes_.emplace_back((iregphi + 2) + NTK_SECTORS * ie, il, iregphi + ireg0, il0 + il + 4); + } + } + } else { + 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 + ireg0, il0 + il); + tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, isp + ireg0, il0 + il + 2); + tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, ism + ireg0, il0 + il + 4); + } + } + } + } + } + // calo + unsigned int calo_sectors_to_loop = NCALO_SECTORS; + if (barrelSetup == BarrelSetup::Phi18 || barrelSetup == BarrelSetup::Phi9) { + calo_sectors_to_loop = 1; + assert(NCALO_SECTORS == 2 && NTK_SECTORS == 5); // otherwise math below is broken, but it's hard to make it generic + } else { + assert(NCALO_SECTORS == 3 && NTK_SECTORS == 9); // otherwise math below is broken, but it's hard to make it generic + } + for (unsigned int ie = 0; ie < etaslices; ++ie) { + for (unsigned int is = 0; is < calo_sectors_to_loop; ++is) { // NCALO_SECTORS sectors + for (unsigned int j = 0; j < 3; ++j) { // 3 regions x sector + for (unsigned int il = 0; il < HCAL_LINKS; ++il) { + caloRoutes_.emplace_back(is, il, 3 * is + j + phisectors * ie, il); + if (j) { + caloRoutes_.emplace_back((is + 1) % 3, il, 3 * is + j + phisectors * ie, il + HCAL_LINKS); + } + } + for (unsigned int il = 0; il < ECAL_LINKS; ++il) { + emCaloRoutes_.emplace_back(is, il, 3 * is + j + phisectors * ie, il); + if (j) { + emCaloRoutes_.emplace_back((is + 1) % 3, il, 3 * is + j + phisectors * ie, il + ECAL_LINKS); + } + } + } + } + } + // mu + for (unsigned int il = 0; il < NMU_LINKS && nmu > 0; ++il) { + for (unsigned int j = 0; j < nregions_; ++j) { + muRoutes_.emplace_back(0, il, j, il); + } + } +} + +l1ct::MultififoRegionizerEmulator::~MultififoRegionizerEmulator() {} + +void l1ct::MultififoRegionizerEmulator::setEgInterceptMode(bool afterFifo, + const l1ct::EGInputSelectorEmuConfig& interceptorConfig) { + emInterceptMode_ = afterFifo ? interceptPostFifo : interceptPreFifo; + interceptor_ = std::make_unique(interceptorConfig); +} + +void l1ct::MultififoRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedInputs& in, + const std::vector& out) { + assert(!init_); + init_ = true; + if (nendcaps_ > 0) { + assert(out.size() == NTK_SECTORS * nendcaps_); + } else { + assert(out.size() == nregions_); + } + nregions_ = out.size(); + if (ntk_) { + assert(in.track.size() == NTK_SECTORS * (nendcaps_ ? nendcaps_ : 2)); + tkRegionizer_.initSectors(in.track); + tkRegionizer_.initRegions(out); + tkRegionizer_.initRouting(tkRoutes_); + } + if (ncalo_) { + assert(in.hadcalo.size() == NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1)); + hadCaloRegionizer_.initSectors(in.hadcalo); + hadCaloRegionizer_.initRegions(out); + hadCaloRegionizer_.initRouting(caloRoutes_); + } + if (nem_) { + assert(in.emcalo.size() == NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1)); + emCaloRegionizer_.initSectors(in.emcalo); + emCaloRegionizer_.initRegions(out); + emCaloRegionizer_.initRouting(emCaloRoutes_); + } + if (nmu_) { + muRegionizer_.initSectors(in.muon); + muRegionizer_.initRegions(out); + muRegionizer_.initRouting(muRoutes_); + } +} + +// clock-cycle emulation +bool l1ct::MultififoRegionizerEmulator::step(bool newEvent, + const std::vector& links, + std::vector& out, + bool mux) { + return ntk_ ? tkRegionizer_.step(newEvent, links, out, mux) : false; +} + +bool l1ct::MultififoRegionizerEmulator::step(bool newEvent, + const std::vector& links, + std::vector& out, + bool mux) { + assert(emInterceptMode_ == noIntercept); // otherwise the em & had calo can't be stepped independently + return nem_ ? emCaloRegionizer_.step(newEvent, links, out, mux) : false; +} + +bool l1ct::MultififoRegionizerEmulator::step(bool newEvent, + const std::vector& links, + std::vector& out, + bool mux) { + return ncalo_ ? hadCaloRegionizer_.step(newEvent, links, out, mux) : false; +} + +bool l1ct::MultififoRegionizerEmulator::step(bool newEvent, + const std::vector& links, + std::vector& out, + bool mux) { + return nmu_ ? muRegionizer_.step(newEvent, links, out, mux) : false; +} + +bool l1ct::MultififoRegionizerEmulator::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) { + bool ret = false; + if (ntk_) + ret = tkRegionizer_.step(newEvent, links_tk, out_tk, mux); + if (nmu_) + ret = muRegionizer_.step(newEvent, links_mu, out_mu, mux); + switch (emInterceptMode_) { + case noIntercept: + if (ncalo_) + ret = hadCaloRegionizer_.step(newEvent, links_hadCalo, out_hadCalo, mux); + if (nem_) + ret = emCaloRegionizer_.step(newEvent, links_emCalo, out_emCalo, mux); + break; + case interceptPreFifo: + // we actually intercept at the links, in the software it's equivalent and it's easier + assert(nem_ > 0 && ncalo_ > 0 && !links_hadCalo.empty() && links_emCalo.empty()); + assert(interceptor_.get()); + { + std::vector intercepted_links; + interceptor_->select_or_clear(links_hadCalo, intercepted_links); + ret = hadCaloRegionizer_.step(newEvent, links_hadCalo, out_hadCalo, mux); + emCaloRegionizer_.step(newEvent, intercepted_links, out_emCalo, mux); + } + break; + case interceptPostFifo: + assert(nem_ > 0 && ncalo_ > 0 && !links_hadCalo.empty() && links_emCalo.empty()); + assert(interceptor_.get()); + { + if (mux) { + std::vector hadNoMux; + hadCaloRegionizer_.step(newEvent, links_hadCalo, hadNoMux, /*mux=*/false); + std::vector emNoMux(hadNoMux.size()); + interceptor_->select_or_clear(hadNoMux, emNoMux); + ret = hadCaloRegionizer_.muxonly_step(newEvent, /*flush=*/false, hadNoMux, out_hadCalo); + emCaloRegionizer_.muxonly_step(newEvent, /*flush=*/true, emNoMux, out_emCalo); + } else { + ret = hadCaloRegionizer_.step(newEvent, links_hadCalo, out_hadCalo, /*mux=*/false); + interceptor_->select_or_clear(out_hadCalo, out_emCalo); + } + } + break; + } + return ret; +} + +void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock, + const l1ct::RegionizerDecodedInputs& in, + std::vector& links) { + if (ntk_ == 0) + return; + links.resize(NTK_SECTORS * NTK_LINKS * (nendcaps_ ? nendcaps_ : 2)); + 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]; + } else { + links[idx].clear(); + } + } + } +} + +template +void l1ct::MultififoRegionizerEmulator::fillCaloLinks_(unsigned int iclock, + const std::vector>& in, + std::vector& links) { + unsigned int NLINKS = + (nendcaps_ ? NCALO_LINKS : (typeid(T) == typeid(l1ct::HadCaloObjEmu) ? HCAL_LINKS : ECAL_LINKS)); + links.resize(NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1) * NLINKS); + 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]; + } else { + links[idx].clear(); + } + } + } +} + +void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock, + const l1ct::RegionizerDecodedInputs& in, + std::vector& links) { + if (ncalo_ == 0) + return; + fillCaloLinks_(iclock, in.hadcalo, links); +} + +void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock, + const l1ct::RegionizerDecodedInputs& in, + std::vector& links) { + if (nem_ == 0 || emInterceptMode_ != noIntercept) + return; + fillCaloLinks_(iclock, in.emcalo, links); +} + +void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock, + const l1ct::RegionizerDecodedInputs& in, + std::vector& links) { + if (nmu_ == 0) + return; + assert(NMU_LINKS == 1); + links.resize(NMU_LINKS); + if (iclock < in.muon.size() && iclock < nclocks_ - 1) { + links[0] = in.muon[iclock]; + } else { + links[0].clear(); + } +} + +void l1ct::MultififoRegionizerEmulator::toFirmware(const std::vector& emu, + TkObj fw[/*NTK_SECTORS][NTK_LINKS*/]) { + if (ntk_ == 0) + return; + assert(emu.size() == NTK_SECTORS * NTK_LINKS * (nendcaps_ ? nendcaps_ : 2)); + for (unsigned int is = 0, idx = 0; is < NTK_SECTORS * (nendcaps_ ? nendcaps_ : 2); ++is) { // tf sectors + for (unsigned int il = 0; il < NTK_LINKS; ++il, ++idx) { + fw[is * NTK_LINKS + il] = emu[idx]; + } + } +} +void l1ct::MultififoRegionizerEmulator::toFirmware(const std::vector& emu, + HadCaloObj fw[/*NCALO_SECTORS*NCALO_LINKS*/]) { + if (ncalo_ == 0) + return; + unsigned int NLINKS = (nendcaps_ ? NCALO_LINKS * nendcaps_ : HCAL_LINKS); + assert(emu.size() == NCALO_SECTORS * NLINKS); + for (unsigned int is = 0, idx = 0; is < NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1); ++is) { // calo sectors + for (unsigned int il = 0; il < NLINKS; ++il, ++idx) { + fw[is * NLINKS + il] = emu[idx]; + } + } +} + +void l1ct::MultififoRegionizerEmulator::toFirmware(const std::vector& emu, + EmCaloObj fw[/*NCALO_SECTORS*NCALO_LINKS*/]) { + if (nem_ == 0) + return; + unsigned int NLINKS = (nendcaps_ ? NCALO_LINKS * nendcaps_ : ECAL_LINKS); + assert(emu.size() == NCALO_SECTORS * NLINKS); + for (unsigned int is = 0, idx = 0; is < NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1); ++is) { // calo sectors + for (unsigned int il = 0; il < NLINKS; ++il, ++idx) { + fw[is * NLINKS + il] = emu[idx]; + } + } +} + +void l1ct::MultififoRegionizerEmulator::toFirmware(const std::vector& emu, MuObj fw[/*NMU_LINKS*/]) { + if (nmu_ == 0) + return; + assert(emu.size() == NMU_LINKS); + for (unsigned int il = 0, idx = 0; il < NMU_LINKS; ++il, ++idx) { + fw[il] = emu[idx]; + } +} + +void l1ct::MultififoRegionizerEmulator::destream(int iclock, + const std::vector& tk_out, + const std::vector& em_out, + const std::vector& calo_out, + const std::vector& mu_out, + PFInputRegion& out) { + if (ntk_) + tkRegionizer_.destream(iclock, tk_out, out.track); + if (ncalo_) + hadCaloRegionizer_.destream(iclock, calo_out, out.hadcalo); + if (nem_) + emCaloRegionizer_.destream(iclock, em_out, out.emcalo); + if (nmu_) + muRegionizer_.destream(iclock, mu_out, out.muon); +} + +void l1ct::MultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { + if (!init_) + initSectorsAndRegions(in, out); + tkRegionizer_.reset(); + emCaloRegionizer_.reset(); + hadCaloRegionizer_.reset(); + muRegionizer_.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 + for (unsigned int iclock = 0; iclock < nclocks_; ++iclock) { + fillLinks(iclock, in, tk_links_in); + fillLinks(iclock, in, em_links_in); + fillLinks(iclock, in, calo_links_in); + fillLinks(iclock, in, mu_links_in); + + 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_) { + destream(iclock, tk_out, em_out, calo_out, mu_out, out[ireg]); + } else { + if (iclock % outii_ == 0) { + out[ireg].track = tk_out; + out[ireg].emcalo = em_out; + out[ireg].hadcalo = calo_out; + out[ireg].muon = mu_out; + } + } + } + + tkRegionizer_.reset(); + emCaloRegionizer_.reset(); + hadCaloRegionizer_.reset(); + muRegionizer_.reset(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/regionizer_base_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/regionizer_base_ref.cpp new file mode 100644 index 0000000000000..f79f9f6934903 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/regionizer_base_ref.cpp @@ -0,0 +1,96 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/regionizer_base_ref.h" + +#include +#include +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" +l1ct::RegionizerEmulator::RegionizerEmulator(const edm::ParameterSet& iConfig) + : useAlsoVtxCoords_(iConfig.getParameter("useAlsoVtxCoords")), + debug_(iConfig.getUntrackedParameter("debug", false)) {} +#endif + +l1ct::RegionizerEmulator::~RegionizerEmulator() {} + +void l1ct::RegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { + for (const auto& sec : in.track) { + for (const auto& tk : sec) { + if (tk.hwPt == 0) + continue; + float fglbEta = sec.region.floatGlbEtaOf(tk), fglbPhi = sec.region.floatGlbPhiOf(tk); + glbeta_t glbEta = sec.region.hwGlbEtaOf(tk); + glbphi_t glbPhi = sec.region.hwGlbPhiOf(tk); + glbeta_t glbEtaV = sec.region.hwGlbEta(tk.hwVtxEta()); + glbphi_t glbPhiV = sec.region.hwGlbPhi(tk.hwVtxPhi()); + for (auto& r : out) { + if (r.region.containsHw(glbEta, glbPhi) || (useAlsoVtxCoords_ && r.region.containsHw(glbEtaV, glbPhiV))) { + r.track.push_back(tk); + r.track.back().hwEta = l1ct::Scales::makeEta(r.region.localEta(fglbEta)); + r.track.back().hwPhi = l1ct::Scales::makePhi(r.region.localPhi(fglbPhi)); + } + } + } + } + + for (const auto& sec : in.hadcalo) { + for (const auto& c : sec) { + if (c.hwPt == 0) + continue; + float fglbEta = sec.region.floatGlbEtaOf(c), fglbPhi = sec.region.floatGlbPhiOf(c); + glbeta_t glbEta = sec.region.hwGlbEtaOf(c); + glbphi_t glbPhi = sec.region.hwGlbPhiOf(c); + for (auto& r : out) { + if (r.region.containsHw(glbEta, glbPhi)) { + r.hadcalo.push_back(c); + r.hadcalo.back().hwEta = l1ct::Scales::makeEta(r.region.localEta(fglbEta)); + r.hadcalo.back().hwPhi = l1ct::Scales::makePhi(r.region.localPhi(fglbPhi)); + } + } + } + } + + for (const auto& sec : in.emcalo) { + for (const auto& c : sec) { + if (c.hwPt == 0) + continue; + float fglbEta = sec.region.floatGlbEtaOf(c), fglbPhi = sec.region.floatGlbPhiOf(c); + glbeta_t glbEta = sec.region.hwGlbEtaOf(c); + glbphi_t glbPhi = sec.region.hwGlbPhiOf(c); + for (auto& r : out) { + if (r.region.containsHw(glbEta, glbPhi)) { + r.emcalo.push_back(c); + r.emcalo.back().hwEta = l1ct::Scales::makeEta(r.region.localEta(fglbEta)); + r.emcalo.back().hwPhi = l1ct::Scales::makePhi(r.region.localPhi(fglbPhi)); + } + } + } + } + + for (const auto& mu : in.muon.obj) { + if (mu.hwPt == 0) + continue; + float glbEta = mu.floatEta(), glbPhi = mu.floatPhi(); + for (auto& r : out) { + if (r.region.containsHw(mu.hwEta, mu.hwPhi)) { + r.muon.push_back(mu); + r.muon.back().hwEta = l1ct::Scales::makeEta(r.region.localEta(glbEta)); + r.muon.back().hwPhi = l1ct::Scales::makePhi(r.region.localPhi(glbPhi)); + } + } + } + + for (auto& r : out) { + std::sort(r.track.begin(), r.track.end(), [](const l1ct::TkObjEmu& a, const l1ct::TkObjEmu& b) { + return a.hwPt > b.hwPt; + }); + std::sort(r.hadcalo.begin(), r.hadcalo.end(), [](const l1ct::HadCaloObjEmu& a, const l1ct::HadCaloObjEmu& b) { + return a.hwPt > b.hwPt; + }); + std::sort(r.emcalo.begin(), r.emcalo.end(), [](const l1ct::EmCaloObjEmu& a, const l1ct::EmCaloObjEmu& b) { + return a.hwPt > b.hwPt; + }); + std::sort( + r.muon.begin(), r.muon.end(), [](const l1ct::MuObjEmu& a, const l1ct::MuObjEmu& b) { return a.hwPt > b.hwPt; }); + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp new file mode 100644 index 0000000000000..f7f3b86320728 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/regionizer/tdr_regionizer_ref.cpp @@ -0,0 +1,292 @@ +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_ref.h" +#include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.icc" + +#include + +#ifdef CMSSW_GIT_HASH +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +l1ct::TDRRegionizerEmulator::TDRRegionizerEmulator(const edm::ParameterSet& iConfig) + : TDRRegionizerEmulator( + /*netaslices=*/3, + iConfig.getParameter("nTrack"), + iConfig.getParameter("nCalo"), + iConfig.getParameter("nEmCalo"), + iConfig.getParameter("nMu"), + iConfig.getParameter("nClocks"), + iConfig.getParameter("doSort")) { + debug_ = iConfig.getUntrackedParameter("debug", false); +} +#endif + +l1ct::TDRRegionizerEmulator::TDRRegionizerEmulator(unsigned int netaslices, + unsigned int ntk, + unsigned int ncalo, + unsigned int nem, + unsigned int nmu, + int nclocks, + bool dosort) + : RegionizerEmulator(), + netaslices_(netaslices), + ntk_(ntk), + ncalo_(ncalo), + nem_(nem), + nmu_(nmu), + nclocks_(nclocks), + dosort_(dosort), + init_(false) { + assert(netaslices == 3); //the setup here only works for 3 barrel boards + int etaoffsets[3] = {-228, 0, 228}; //this could be made generic perhaps, hardcoding for now + for (unsigned int i = 0; i < netaslices_; i++) { + tkRegionizers_.emplace_back( + (unsigned int)NETA_SMALL, (unsigned int)NUMBER_OF_SMALL_REGIONS, ntk, etaoffsets[i], 115, nclocks); + hadCaloRegionizers_.emplace_back( + (unsigned int)NETA_SMALL, (unsigned int)NUMBER_OF_SMALL_REGIONS, ncalo, etaoffsets[i], 115, nclocks); + emCaloRegionizers_.emplace_back( + (unsigned int)NETA_SMALL, (unsigned int)NUMBER_OF_SMALL_REGIONS, nem, etaoffsets[i], 115, nclocks); + muRegionizers_.emplace_back( + (unsigned int)NETA_SMALL, (unsigned int)NUMBER_OF_SMALL_REGIONS, nmu, etaoffsets[i], 115, nclocks); + } +} + +l1ct::TDRRegionizerEmulator::~TDRRegionizerEmulator() {} + +void l1ct::TDRRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedInputs& in, + const std::vector& out) { + assert(!init_); + init_ = true; + nregions_ = out.size(); + if (ntk_) { + for (unsigned int i = 0; i < netaslices_; i++) { + tkRegionizers_[i].initSectors(in.track); + tkRegionizers_[i].initRegions(out); + } + } + if (ncalo_) { + for (unsigned int i = 0; i < netaslices_; i++) { + hadCaloRegionizers_[i].initSectors(in.hadcalo); + hadCaloRegionizers_[i].initRegions(out); + } + } + if (nem_) { + for (unsigned int i = 0; i < netaslices_; i++) { + emCaloRegionizers_[i].initSectors(in.emcalo); + emCaloRegionizers_[i].initRegions(out); + } + } + if (nmu_) { + for (unsigned int i = 0; i < netaslices_; i++) { + muRegionizers_[i].initSectors(in.muon); + muRegionizers_[i].initRegions(out); + } + } +} + +void l1ct::TDRRegionizerEmulator::fillLinks(const l1ct::RegionizerDecodedInputs& in, + std::vector>& links) { + if (ntk_ == 0) + return; + + links.clear(); + links.resize(in.track.size()); + + //one link per sector + for (unsigned int il = 0; il < in.track.size(); il++) { + const l1ct::DetectorSector& sec = in.track[il]; + for (unsigned int io = 0; io < sec.size(); io++) { + links[il].push_back(sec[io]); + if (links[il].size() == MAX_TK_EVT) { + break; + } + } + } +} + +void l1ct::TDRRegionizerEmulator::fillLinks(const l1ct::RegionizerDecodedInputs& in, + std::vector>& links) { + if (ncalo_ == 0) + return; + + links.clear(); + links.resize(in.hadcalo.size()); + + //one link per sector + for (unsigned int il = 0; il < in.hadcalo.size(); il++) { + const l1ct::DetectorSector& sec = in.hadcalo[il]; + for (unsigned int io = 0; io < sec.size(); io++) { + links[il].push_back(sec[io]); + if (links[il].size() == MAX_CALO_EVT) { + break; + } + } + } +} + +void l1ct::TDRRegionizerEmulator::fillLinks(const l1ct::RegionizerDecodedInputs& in, + std::vector>& links) { + if (nem_ == 0) + return; + + links.clear(); + links.resize(in.emcalo.size()); + + //one link per sector + for (unsigned int il = 0; il < in.emcalo.size(); il++) { + const l1ct::DetectorSector& sec = in.emcalo[il]; + for (unsigned int io = 0; io < sec.size(); io++) { + links[il].push_back(sec[io]); + if (links[il].size() == MAX_EMCALO_EVT) { + break; + } + } + } +} + +void l1ct::TDRRegionizerEmulator::fillLinks(const l1ct::RegionizerDecodedInputs& in, + std::vector>& links) { + if (nmu_ == 0) + return; + + links.clear(); + links.resize(1); //muons are global + + const l1ct::DetectorSector& sec = in.muon; + for (unsigned int io = 0; io < sec.size(); io++) { + links[0].push_back(sec[io]); + if (links[0].size() == MAX_MU_EVT) { + break; + } + } +} + +void l1ct::TDRRegionizerEmulator::toFirmware(const std::vector& emu, TkObj fw[NTK_SECTORS][NTK_LINKS]) { + if (ntk_ == 0) + return; + assert(emu.size() == NTK_SECTORS * NTK_LINKS * netaslices_); + for (unsigned int is = 0, idx = 0; is < NTK_SECTORS * netaslices_; ++is) { // tf sectors + for (unsigned int il = 0; il < NTK_LINKS; ++il, ++idx) { + fw[is][il] = emu[idx]; + } + } +} +void l1ct::TDRRegionizerEmulator::toFirmware(const std::vector& emu, + HadCaloObj fw[NCALO_SECTORS][NCALO_LINKS]) { + if (ncalo_ == 0) + return; + assert(emu.size() == NCALO_SECTORS * NCALO_LINKS * netaslices_); + for (unsigned int is = 0, idx = 0; is < NCALO_SECTORS * netaslices_; ++is) { // tf sectors + for (unsigned int il = 0; il < NCALO_LINKS; ++il, ++idx) { + fw[is][il] = emu[idx]; + } + } +} + +void l1ct::TDRRegionizerEmulator::toFirmware(const std::vector& emu, + EmCaloObj fw[NCALO_SECTORS][NCALO_LINKS]) { + if (nem_ == 0) + return; + assert(emu.size() == NCALO_SECTORS * NCALO_LINKS * netaslices_); + for (unsigned int is = 0, idx = 0; is < NCALO_SECTORS * netaslices_; ++is) { // tf sectors + for (unsigned int il = 0; il < NCALO_LINKS; ++il, ++idx) { + fw[is][il] = emu[idx]; + } + } +} + +void l1ct::TDRRegionizerEmulator::toFirmware(const std::vector& emu, MuObj fw[NMU_LINKS]) { + if (nmu_ == 0) + return; + assert(emu.size() == NMU_LINKS); + for (unsigned int il = 0, idx = 0; il < NMU_LINKS; ++il, ++idx) { + fw[il] = emu[idx]; + } +} + +void l1ct::TDRRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector& out) { + if (!init_) + initSectorsAndRegions(in, out); + + std::vector> tk_links_in; + std::vector> em_links_in; + std::vector> calo_links_in; + std::vector> mu_links_in; + + // read the inputs + fillLinks(in, tk_links_in); + fillLinks(in, em_links_in); + fillLinks(in, calo_links_in); + fillLinks(in, mu_links_in); + //this is overkill and could be improved, for now its ok (the sectors outside each board just wont do anything) + + for (unsigned int ie = 0; ie < netaslices_; ie++) { + //add objects from link + tkRegionizers_[ie].reset(); + tkRegionizers_[ie].setPipes(tk_links_in); + tkRegionizers_[ie].initTimes(); + if (debug_) { + dbgCout() << ie << "SECTORS/LINKS " << ie << std::endl; + for (unsigned int i = 0; i < tk_links_in.size(); i++) { + for (unsigned int j = 0; j < tk_links_in[i].size(); j++) { + dbgCout() << "\t" << i << " " << j << "\t" << tk_links_in[i][j].hwPt.to_int() << "\t" + << tk_links_in[i][j].hwEta.to_int() << "\t" << tk_links_in[i][j].hwPhi.to_int() << std::endl; + } + dbgCout() << "-------------------------------" << std::endl; + } + } + tkRegionizers_[ie].run(debug_); + + emCaloRegionizers_[ie].reset(); + emCaloRegionizers_[ie].setPipes(em_links_in); + emCaloRegionizers_[ie].initTimes(); + emCaloRegionizers_[ie].run(); + + hadCaloRegionizers_[ie].reset(); + hadCaloRegionizers_[ie].setPipes(calo_links_in); + hadCaloRegionizers_[ie].initTimes(); + hadCaloRegionizers_[ie].run(); + + muRegionizers_[ie].reset(); + muRegionizers_[ie].setPipes(mu_links_in); + muRegionizers_[ie].initTimes(); + muRegionizers_[ie].run(); + } + + for (unsigned int ie = 0; ie < netaslices_; ie++) { + for (unsigned int ireg = 0; ireg < nregions_; ireg++) { + std::vector out_tks = tkRegionizers_[ie].getSmallRegion(ireg); + if (!out_tks.empty()) { + if (dosort_) { + std::sort( + out_tks.begin(), out_tks.end(), [](const l1ct::TkObjEmu a, const l1ct::TkObjEmu b) { return a > b; }); + } + out[ireg].track = out_tks; + } + std::vector out_emcalos = emCaloRegionizers_[ie].getSmallRegion(ireg); + if (!out_emcalos.empty()) { + if (dosort_) { + std::sort(out_emcalos.begin(), out_emcalos.end(), [](const l1ct::EmCaloObjEmu a, const l1ct::EmCaloObjEmu b) { + return a > b; + }); + } + out[ireg].emcalo = out_emcalos; + } + std::vector out_hadcalos = hadCaloRegionizers_[ie].getSmallRegion(ireg); + if (!out_hadcalos.empty()) { + if (dosort_) { + std::sort(out_hadcalos.begin(), + out_hadcalos.end(), + [](const l1ct::HadCaloObjEmu a, const l1ct::HadCaloObjEmu b) { return a > b; }); + } + out[ireg].hadcalo = out_hadcalos; + } + std::vector out_mus = muRegionizers_[ie].getSmallRegion(ireg); + if (!out_mus.empty()) { + if (dosort_) { + std::sort( + out_mus.begin(), out_mus.end(), [](const l1ct::MuObjEmu a, const l1ct::MuObjEmu b) { return a > b; }); + } + out[ireg].muon = out_mus; + } + } + } +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/taus/TauNNIdHW.cc b/L1Trigger/Phase2L1ParticleFlow/src/taus/TauNNIdHW.cc new file mode 100644 index 0000000000000..1e6430467d4f5 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/src/taus/TauNNIdHW.cc @@ -0,0 +1,107 @@ +#include +#include "L1Trigger/Phase2L1ParticleFlow/interface/taus/TauNNIdHW.h" + +TauNNIdHW::TauNNIdHW() { NNvectorVar_.clear(); } +TauNNIdHW::~TauNNIdHW() {} + +void TauNNIdHW::initialize(const std::string &iInput, int iNParticles) { + fNParticles_ = iNParticles; + fPt_ = std::make_unique(fNParticles_); + fEta_ = std::make_unique(fNParticles_); + fPhi_ = std::make_unique(fNParticles_); + fId_ = std::make_unique(fNParticles_); + fInput_ = iInput; +} +void TauNNIdHW::SetNNVectorVar() { + NNvectorVar_.clear(); + for (unsigned i0 = 0; i0 < fNParticles_; i0++) { + input_t pPt = input_t(fPt_.get()[i0]); + input_t pEta = input_t(fEta_.get()[i0]); + input_t pPhi = input_t(fPhi_.get()[i0]); + + NNvectorVar_.push_back(pPt); + NNvectorVar_.push_back(pEta); + NNvectorVar_.push_back(pPhi); + if (fPt_.get()[i0] == 0) { + for (unsigned i1 = 0; i1 < 5; i1++) + NNvectorVar_.push_back(0); + continue; + } + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Photon); // Photon + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Electron); // Electron + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::Muon); // Muon + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::NeutralHadron); // Neutral Had + NNvectorVar_.push_back(fId_.get()[i0] == l1t::PFCandidate::ChargedHadron); // Charged Had + } +} + +result_t TauNNIdHW::EvaluateNN() { + input_t data[N_INPUTS]; + for (unsigned int i = 0; i < NNvectorVar_.size(); i++) { + data[i] = input_t(NNvectorVar_[i]); + } + + layer1_t layer1_out[N_LAYER_1]; + layer1_t logits1[N_LAYER_1]; + nnet::compute_layer(data, logits1, w1, b1); + nnet::relu(logits1, layer1_out); + + layer2_t layer2_out[N_LAYER_2]; + layer2_t logits2[N_LAYER_2]; + nnet::compute_layer(layer1_out, logits2, w2, b2); + nnet::relu(logits2, layer2_out); + + layer3_t layer3_out[N_LAYER_3]; + layer3_t logits3[N_LAYER_3]; + nnet::compute_layer(layer2_out, logits3, w3, b3); + nnet::relu(logits3, layer3_out); + + result_t logits4[N_OUTPUTS]; + nnet::compute_layer(layer3_out, logits4, w4, b4); + result_t res[N_OUTPUTS]; + nnet::sigmoid(logits4, res); + + return res[0]; +} +/* +void TauNNIdHW::print() { + for (unsigned i0 = 0; i0 < fNParticles_; i0++) { + input_t pPt = input_t(fPt_.get()[i0]); + input_t pEta = input_t(fEta_.get()[i0]); + input_t pPhi = input_t(fPhi_.get()[i0]); + input_t pId = input_t(fId_.get()[i0]); + fprintf(file_, " %08x", pPt.to_uint()); + fprintf(file_, " %08x", pEta.to_uint()); + fprintf(file_, " %08x", pPhi.to_uint()); + fprintf(file_, " %08x", pId.to_uint()); + } + fprintf(file_, "\n"); +} +*/ +result_t TauNNIdHW::compute(const l1t::PFCandidate &iSeed, std::vector &iParts) { + for (unsigned i0 = 0; i0 < fNParticles_; i0++) { + fPt_.get()[i0] = 0.; + fEta_.get()[i0] = 0.; + fPhi_.get()[i0] = 0.; + fId_.get()[i0] = 0.; + } + std::sort(iParts.begin(), iParts.end(), [](l1t::PFCandidate i, l1t::PFCandidate j) { + return (pt_t(i.pt()) > pt_t(j.pt())); + }); + for (unsigned int i0 = 0; i0 < iParts.size(); i0++) { + if (i0 > fNParticles_) + break; + fPt_.get()[i0] = pt_t(iParts[i0].pt()); + fEta_.get()[i0] = etaphi_t(iSeed.eta() - iParts[i0].eta()); + etaphi_t lDPhi = etaphi_t(iSeed.phi()) - etaphi_t(iParts[i0].phi()); + etaphi_t lMPI = 3.1415; + if (lDPhi > lMPI) + lDPhi = lDPhi - lMPI; + if (lDPhi < -lMPI) + lDPhi = lDPhi + lMPI; + fPhi_.get()[i0] = lDPhi; + fId_.get()[i0] = id_t(iParts[i0].id()); + } + SetNNVectorVar(); + return EvaluateNN(); +} diff --git a/L1Trigger/Phase2L1ParticleFlow/src/utils/DiscretePF2Firmware.h b/L1Trigger/Phase2L1ParticleFlow/src/utils/DiscretePF2Firmware.h deleted file mode 100644 index 4732a3aeaef8a..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/utils/DiscretePF2Firmware.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_DISCRETEPF2FIRMWARE_H -#define L1Trigger_Phase2L1ParticleFlow_DISCRETEPF2FIRMWARE_H - -/// NOTE: this include is not standalone, since the path to DiscretePFInputs is different in CMSSW & Vivado_HLS - -#include "../firmware/data.h" -#include - -namespace dpf2fw { - - // convert inputs from discrete to firmware - inline void convert(const l1tpf_impl::PropagatedTrack &in, TkObj &out) { - out.hwPt = in.hwPt; - out.hwPtErr = in.hwCaloPtErr; - out.hwEta = in.hwEta; // @calo - out.hwPhi = in.hwPhi; // @calo - out.hwZ0 = in.hwZ0; - out.hwTightQuality = (in.hwStubs >= 6 && in.hwChi2 < 500); - } - - inline TkObj transformConvert(const l1tpf_impl::PropagatedTrack &in) { - TkObj out; - convert(in, out); - return out; - } - - inline void convert(const l1tpf_impl::CaloCluster &in, HadCaloObj &out) { - out.hwPt = in.hwPt; - out.hwEmPt = in.hwEmPt; - out.hwEta = in.hwEta; - out.hwPhi = in.hwPhi; - out.hwIsEM = in.isEM; - } - inline void convert(const l1tpf_impl::CaloCluster &in, EmCaloObj &out) { - out.hwPt = in.hwPt; - out.hwPtErr = in.hwPtErr; - out.hwEta = in.hwEta; - out.hwPhi = in.hwPhi; - } - inline void convert(const l1tpf_impl::Muon &in, MuObj &out) { - out.hwPt = in.hwPt; - out.hwPtErr = 0; // does not exist in input - out.hwEta = in.hwEta; // @calo - out.hwPhi = in.hwPhi; // @calo - } - - template - void convert(const std::vector &in, Out out[NMAX]) { - for (unsigned int i = 0, n = std::min(NMAX, in.size()); i < n; ++i) { - convert(in[i], out[i]); - } - for (unsigned int i = in.size(); i < NMAX; ++i) { - clear(out[i]); - } - } - - template - void convert(unsigned int NMAX, const std::vector &in, Out out[]) { - for (unsigned int i = 0, n = std::min(NMAX, in.size()); i < n; ++i) { - convert(in[i], out[i]); - } - for (unsigned int i = in.size(); i < NMAX; ++i) { - clear(out[i]); - } - } - -} // namespace dpf2fw - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/src/utils/Firmware2DiscretePF.h b/L1Trigger/Phase2L1ParticleFlow/src/utils/Firmware2DiscretePF.h deleted file mode 100644 index 7956a7044861d..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/src/utils/Firmware2DiscretePF.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef L1Trigger_Phase2L1ParticleFlow_FIRMWARE2DISCRETEPF_H -#define L1Trigger_Phase2L1ParticleFlow_FIRMWARE2DISCRETEPF_H - -/// NOTE: this include is not standalone, since the path to DiscretePFInputs is different in CMSSW & Vivado_HLS - -#include "../firmware/data.h" -#include -#include - -namespace fw2dpf { - - // convert inputs from discrete to firmware - inline void convert(const PFChargedObj &src, - const l1tpf_impl::PropagatedTrack &track, - std::vector &out) { - l1tpf_impl::PFParticle pf; - pf.hwPt = src.hwPt; - pf.hwEta = src.hwEta; - pf.hwPhi = src.hwPhi; - pf.hwVtxEta = src.hwEta; // FIXME: get from the track - pf.hwVtxPhi = src.hwPhi; // before propagation - pf.track = track; // FIXME: ok only as long as there is a 1-1 mapping - pf.cluster.hwPt = 0; - pf.cluster.src = nullptr; - pf.muonsrc = nullptr; - switch (src.hwId) { - case PID_Electron: - pf.hwId = 1; - break; - case PID_Muon: - pf.hwId = 4; - break; - default: - pf.hwId = 0; - break; - }; - pf.hwStatus = 0; - out.push_back(pf); - } - // convert inputs from discrete to firmware - inline void convert(const TkObj &in, l1tpf_impl::PropagatedTrack &out); - inline void convert(const PFChargedObj &src, const TkObj &track, std::vector &out) { - l1tpf_impl::PFParticle pf; - pf.hwPt = src.hwPt; - pf.hwEta = src.hwEta; - pf.hwPhi = src.hwPhi; - pf.hwVtxEta = src.hwEta; // FIXME: get from the track - pf.hwVtxPhi = src.hwPhi; // before propagation - convert(track, pf.track); // FIXME: ok only as long as there is a 1-1 mapping - pf.cluster.hwPt = 0; - pf.cluster.src = nullptr; - pf.muonsrc = nullptr; - switch (src.hwId) { - case PID_Electron: - pf.hwId = 1; - break; - case PID_Muon: - pf.hwId = 4; - break; - default: - pf.hwId = 0; - break; - }; - pf.hwStatus = 0; - out.push_back(pf); - } - inline void convert(const PFNeutralObj &src, std::vector &out) { - l1tpf_impl::PFParticle pf; - pf.hwPt = src.hwPt; - pf.hwEta = src.hwEta; - pf.hwPhi = src.hwPhi; - pf.hwVtxEta = src.hwEta; - pf.hwVtxPhi = src.hwPhi; - pf.track.hwPt = 0; - pf.track.src = nullptr; - pf.cluster.hwPt = src.hwPt; - pf.cluster.src = nullptr; - pf.muonsrc = nullptr; - switch (src.hwId) { - case PID_Photon: - pf.hwId = 3; - break; - default: - pf.hwId = 2; - break; - } - pf.hwStatus = 0; - out.push_back(pf); - } - - // convert inputs from discrete to firmware - inline void convert(const TkObj &in, l1tpf_impl::PropagatedTrack &out) { - out.hwPt = in.hwPt; - out.hwCaloPtErr = in.hwPtErr; - out.hwEta = in.hwEta; // @calo - out.hwPhi = in.hwPhi; // @calo - out.hwZ0 = in.hwZ0; - out.src = nullptr; - } - inline void convert(const HadCaloObj &in, l1tpf_impl::CaloCluster &out) { - out.hwPt = in.hwPt; - out.hwEmPt = in.hwEmPt; - out.hwEta = in.hwEta; - out.hwPhi = in.hwPhi; - out.isEM = in.hwIsEM; - out.src = nullptr; - } - inline void convert(const EmCaloObj &in, l1tpf_impl::CaloCluster &out) { - out.hwPt = in.hwPt; - out.hwPtErr = in.hwPtErr; - out.hwEta = in.hwEta; - out.hwPhi = in.hwPhi; - out.src = nullptr; - } - inline void convert(const MuObj &in, l1tpf_impl::Muon &out) { - out.hwPt = in.hwPt; - out.hwEta = in.hwEta; // @calo - out.hwPhi = in.hwPhi; // @calo - out.src = nullptr; - } - - template - void convert(const In in[NMAX], std::vector &out) { - for (unsigned int i = 0; i < NMAX; ++i) { - if (in[i].hwPt > 0) - convert(in[i], out); - } - } - template - void convert(unsigned int NMAX, const In in[], std::vector &out) { - for (unsigned int i = 0; i < NMAX; ++i) { - if (in[i].hwPt > 0) - convert(in[i], out); - } - } - template - void convert(const PFChargedObj in[NMAX], - std::vector srctracks, - std::vector &out) { - for (unsigned int i = 0; i < NMAX; ++i) { - if (in[i].hwPt > 0) { - assert(i < srctracks.size()); - convert(in[i], srctracks[i], out); - } - } - } - inline void convert(unsigned int NMAX, - const PFChargedObj in[], - std::vector srctracks, - std::vector &out) { - for (unsigned int i = 0; i < NMAX; ++i) { - if (in[i].hwPt > 0) { - assert(i < srctracks.size()); - convert(in[i], srctracks[i], out); - } - } - } - -} // namespace fw2dpf - -#endif diff --git a/L1Trigger/Phase2L1ParticleFlow/test/.gitignore b/L1Trigger/Phase2L1ParticleFlow/test/.gitignore new file mode 100644 index 0000000000000..26f0a8dafc043 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/.gitignore @@ -0,0 +1,2 @@ +*.txt +*.dump diff --git a/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml b/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml deleted file mode 100644 index 0b22a9c4949f8..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/test/BuildFile.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/L1Trigger/Phase2L1ParticleFlow/test/l1pfJetMetTreeProducer.py b/L1Trigger/Phase2L1ParticleFlow/test/l1pfJetMetTreeProducer.py deleted file mode 100644 index c2ec3df0ffa56..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/test/l1pfJetMetTreeProducer.py +++ /dev/null @@ -1,31 +0,0 @@ -import FWCore.ParameterSet.Config as cms -from Configuration.StandardSequences.Eras import eras - -process = cms.Process("IN", eras.phase2_trigger) -process.load('Configuration.StandardSequences.Services_cff') -process.load("FWCore.MessageLogger.MessageLogger_cfi") -process.load('Configuration.Geometry.GeometryExtended2023D17Reco_cff') -process.load('Configuration.StandardSequences.MagneticField_cff') -process.load('Configuration.StandardSequences.EndOfProcess_cff') -process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') -from Configuration.AlCa.GlobalTag import GlobalTag -process.GlobalTag = GlobalTag(process.GlobalTag, '100X_upgrade2023_realistic_v1', '') - -process.source = cms.Source("PoolSource", - fileNames = cms.untracked.vstring('/store/relval/CMSSW_9_3_7/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/93X_upgrade2023_realistic_v5_2023D17noPU-v2/10000/7EC7DD7F-782C-E811-B469-0CC47A4D76A0.root'), - duplicateCheckMode = cms.untracked.string("noDuplicateCheck"), - inputCommands = cms.untracked.vstring("keep *", - "drop l1tEMTFHit2016Extras_simEmtfDigis_CSC_HLT", - "drop l1tEMTFHit2016Extras_simEmtfDigis_RPC_HLT", - "drop l1tEMTFHit2016s_simEmtfDigis__HLT", - "drop l1tEMTFTrack2016Extras_simEmtfDigis__HLT", - "drop l1tEMTFTrack2016s_simEmtfDigis__HLT") - -) -process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(500)) -process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True) ) - -process.load('L1Trigger.Phase2L1ParticleFlow.l1pfJetMetTreeProducer_cff') - -process.p = cms.Path(process.l1pfJetMetTreeProducer) -process.TFileService = cms.Service("TFileService", fileName = cms.string("jetmetTuple.root")) diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py new file mode 100644 index 0000000000000..902b081492dce --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_cfg.py @@ -0,0 +1,71 @@ +import FWCore.ParameterSet.Config as cms +from Configuration.StandardSequences.Eras import eras + +process = cms.Process("RESP", eras.Phase2C9) + +process.load('Configuration.StandardSequences.Services_cff') +process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi") +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True), allowUnscheduled = cms.untracked.bool(False) ) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(1000)) +process.MessageLogger.cerr.FwkReport.reportEvery = 1 + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring('file:inputs110X.root'), + inputCommands = cms.untracked.vstring("keep *", + "drop l1tPFClusters_*_*_*", + "drop l1tPFTracks_*_*_*", + "drop l1tPFCandidates_*_*_*", + "drop l1tTkPrimaryVertexs_*_*_*") +) + +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') # needed to read HCal TPs +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, '123X_mcRun4_realistic_v3', '') + +process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_cff') +process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer2EG_cff') +process.load('L1Trigger.L1TTrackMatch.L1GTTInputProducer_cfi') +process.load('L1Trigger.VertexFinder.VertexProducer_cff') +process.L1VertexFinderEmulator = process.VertexProducer.clone() +process.L1VertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" +process.L1VertexFinderEmulator.l1TracksInputTag = cms.InputTag("L1GTTInputProducer", "Level1TTTracksConverted") +from L1Trigger.Phase2L1GMT.gmt_cfi import standaloneMuons +process.L1SAMuonsGmt = standaloneMuons.clone() + +process.l1ctLayer1Barrel9 = process.l1ctLayer1Barrel.clone() +process.l1ctLayer1Barrel9.puAlgo.nFinalSort = 32 +process.l1ctLayer1Barrel9.regions[0].etaBoundaries = [ -1.5, -0.5, 0.5, 1.5 ] +process.l1ctLayer1Barrel9.boards=cms.VPSet( + cms.PSet( + regions=cms.vuint32(*[0+9*ie+i for ie in range(3) for i in range(3)])), + cms.PSet( + regions=cms.vuint32(*[3+9*ie+i for ie in range(3) for i in range(3)])), + cms.PSet( + regions=cms.vuint32(*[6+9*ie+i for ie in range(3) for i in range(3)])), + ) + +process.runPF = cms.Path( + process.L1SAMuonsGmt + + process.L1GTTInputProducer + + process.L1VertexFinderEmulator + + process.l1ctLayer1Barrel + + process.l1ctLayer1Barrel9 + + process.l1ctLayer1HGCal + + process.l1ctLayer1HGCalNoTK + + process.l1ctLayer1HF +) +process.runPF.associate(process.l1ctLayer1TaskInputsTask) + + +for det in "Barrel", "Barrel9", "HGCal", "HGCalNoTK", "HF": + l1pf = getattr(process, 'l1ctLayer1'+det) + l1pf.dumpFileName = cms.untracked.string("TTbar_PU200_"+det+".dump") + +process.source.fileNames = [ '/store/cmst3/group/l1tr/gpetrucc/11_1_0/NewInputs110X/110121.done/TTbar_PU200/inputs110X_%d.root' % i for i in (1,3,7,8,9) ] +process.pfClustersFromCombinedCaloHCal.phase2barrelCaloTowers = [cms.InputTag("L1EGammaClusterEmuProducer",)] diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_fromRAW_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_fromRAW_cfg.py new file mode 100644 index 0000000000000..abb2f14b3ccc5 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ctLayer1_dumpFiles_fromRAW_cfg.py @@ -0,0 +1,73 @@ +import FWCore.ParameterSet.Config as cms +from Configuration.StandardSequences.Eras import eras + +process = cms.Process("RESP", eras.Phase2C9) + +process.load('Configuration.StandardSequences.Services_cff') +process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi") +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.options = cms.untracked.PSet( + wantSummary = cms.untracked.bool(True), + numberOfThreads = cms.untracked.uint32(2), + numberOfStreams = cms.untracked.uint32(1), +) +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(100)) +process.MessageLogger.cerr.FwkReport.reportEvery = 1 + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring('/store/mc/Phase2HLTTDRWinter20DIGI/TT_TuneCP5_14TeV-powheg-pythia8/GEN-SIM-DIGI-RAW/PU200_110X_mcRun4_realistic_v3-v2/110000/005E74D6-B50E-674E-89E6-EAA9A617B476.root',) +) + +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('SimGeneral.MixingModule.mixNoPU_cfi') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, '123X_mcRun4_realistic_v3', '') + +process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') # needed to read HCal TPs +process.load('CalibCalorimetry.CaloTPG.CaloTPGTranscoder_cfi') +process.load('Configuration.StandardSequences.SimL1Emulator_cff') +process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') +process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") +process.load("L1Trigger.TrackerDTC.ProducerES_cff") +process.load("L1Trigger.TrackerDTC.ProducerED_cff") +process.load("RecoVertex.BeamSpotProducer.BeamSpot_cfi") + +process.l1ctLayer1Barrel9 = process.l1ctLayer1Barrel.clone() +process.l1ctLayer1Barrel9.puAlgo.nFinalSort = 32 +process.l1ctLayer1Barrel9.regions[0].etaBoundaries = [ -1.5, -0.5, 0.5, 1.5 ] +process.l1ctLayer1Barrel9.boards=cms.VPSet( + cms.PSet( + regions=cms.vuint32(*[0+9*ie+i for ie in range(3) for i in range(3)])), + cms.PSet( + regions=cms.vuint32(*[3+9*ie+i for ie in range(3) for i in range(3)])), + cms.PSet( + regions=cms.vuint32(*[6+9*ie+i for ie in range(3) for i in range(3)])), + ) + +process.pfInputsTask = cms.Task( + process.TTClustersFromPhase2TrackerDigis, + process.TTStubsFromPhase2TrackerDigis, + process.TrackerDTCProducer, + process.offlineBeamSpot, + process.TTTracksFromTrackletEmulation, + process.SimL1EmulatorTask +) +process.runPF = cms.Path( + process.l1ctLayer1Barrel + + process.l1ctLayer1Barrel9 + + process.l1ctLayer1HGCal + + process.l1ctLayer1HGCalNoTK + + process.l1ctLayer1HF +) + +process.runPF.associate(process.pfInputsTask) +process.schedule = cms.Schedule(process.runPF) + +for det in "Barrel", "Barrel9", "HGCal", "HGCalNoTK", "HF": + l1pf = getattr(process, 'l1ctLayer1'+det) + l1pf.dumpFileName = cms.untracked.string("TTbar_PU200_123X_"+det+".dump") diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py new file mode 100644 index 0000000000000..cd82861a8f1bc --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_cfg.py @@ -0,0 +1,98 @@ +import FWCore.ParameterSet.Config as cms +from Configuration.StandardSequences.Eras import eras + +process = cms.Process("RESP", eras.Phase2C9) + +process.load('Configuration.StandardSequences.Services_cff') +process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi") +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True), allowUnscheduled = cms.untracked.bool(False) ) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(1000)) +process.MessageLogger.cerr.FwkReport.reportEvery = 1 + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring('file:inputs110X.root'), + inputCommands = cms.untracked.vstring("keep *", + "drop l1tPFClusters_*_*_*", + "drop l1tPFTracks_*_*_*", + "drop l1tPFCandidates_*_*_*", + "drop l1tTkPrimaryVertexs_*_*_*") +) + +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') # needed to read HCal TPs +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, '123X_mcRun4_realistic_v3', '') + +process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_cff') +process.load('L1Trigger.Phase2L1ParticleFlow.l1ctLayer2EG_cff') +process.load('L1Trigger.L1TTrackMatch.L1GTTInputProducer_cfi') +process.load('L1Trigger.VertexFinder.VertexProducer_cff') +process.L1VertexFinderEmulator = process.VertexProducer.clone() +process.L1VertexFinderEmulator.VertexReconstruction.Algorithm = "fastHistoEmulation" +process.L1VertexFinderEmulator.l1TracksInputTag = cms.InputTag("L1GTTInputProducer", "Level1TTTracksConverted") +from L1Trigger.Phase2L1GMT.gmt_cfi import standaloneMuons +process.L1SAMuonsGmt = standaloneMuons.clone() + +from L1Trigger.Phase2L1ParticleFlow.L1SeedConePFJetProducer_cfi import L1SeedConePFJetEmulatorProducer +from L1Trigger.Phase2L1ParticleFlow.DeregionizerProducer_cfi import DeregionizerProducer +from L1Trigger.Phase2L1ParticleFlow.l1ctJetFileWriter_cfi import l1ctSeededConeJetFileWriter +process.l1ctLayer2Deregionizer = DeregionizerProducer.clone() +process.l1ctLayer2SeedConeJets = L1SeedConePFJetEmulatorProducer.clone(L1PFObject = cms.InputTag('l1ctLayer2Deregionizer', 'Puppi')) +process.l1ctLayer2SeedConeJetWriter = l1ctSeededConeJetFileWriter.clone(jets = "l1ctLayer2SeedConeJets") + +process.l1ctLayer1Barrel9 = process.l1ctLayer1Barrel.clone() +process.l1ctLayer1Barrel9.puAlgo.nFinalSort = 32 +process.l1ctLayer1Barrel9.regions[0].etaBoundaries = [ -1.5, -0.5, 0.5, 1.5 ] +process.l1ctLayer1Barrel9.boards=cms.VPSet( + cms.PSet( + regions=cms.vuint32(*[0+9*ie+i for ie in range(3) for i in range(3)])), + cms.PSet( + regions=cms.vuint32(*[3+9*ie+i for ie in range(3) for i in range(3)])), + cms.PSet( + regions=cms.vuint32(*[6+9*ie+i for ie in range(3) for i in range(3)])), + ) + +from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_patternWriters_cff import * +process.l1ctLayer1Barrel.patternWriters = cms.untracked.VPSet(*barrelWriterConfigs) +#process.l1ctLayer1Barrel9.patternWriters = cms.untracked.VPSet(*barrel9WriterConfigs) # not enabled for now +process.l1ctLayer1HGCal.patternWriters = cms.untracked.VPSet(*hgcalWriterConfigs) +process.l1ctLayer1HGCalNoTK.patternWriters = cms.untracked.VPSet(*hgcalNoTKWriterConfigs) +process.l1ctLayer1HF.patternWriters = cms.untracked.VPSet(*hfWriterConfigs) + +process.runPF = cms.Path( + process.L1SAMuonsGmt + + process.L1GTTInputProducer + + process.L1VertexFinderEmulator + + process.l1ctLayer1Barrel + + #process.l1ctLayer1Barrel9 + + process.l1ctLayer1HGCal + + process.l1ctLayer1HGCalNoTK + + process.l1ctLayer1HF + + process.l1ctLayer1 + + process.l1ctLayer2EG + + process.l1ctLayer2Deregionizer + + process.l1ctLayer2SeedConeJets + + process.l1ctLayer2SeedConeJetWriter + ) +process.runPF.associate(process.l1ctLayer1TaskInputsTask) + + +##################################################################################################################### +## Layer 2 e/gamma + +process.l1ctLayer2EG.writeInPattern = True +process.l1ctLayer2EG.writeOutPattern = True +process.l1ctLayer2EG.inPatternFile.maxLinesPerFile = eventsPerFile_*54 +process.l1ctLayer2EG.outPatternFile.maxLinesPerFile = eventsPerFile_*54 + +##################################################################################################################### +## Layer 2 seeded-cone jets +process.l1ctLayer2SeedConeJetWriter.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("L1EGammaClusterEmuProducer",)] diff --git a/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py new file mode 100644 index 0000000000000..f3b79f0e67227 --- /dev/null +++ b/L1Trigger/Phase2L1ParticleFlow/test/make_l1ct_patternFiles_fromRAW_cfg.py @@ -0,0 +1,100 @@ +import FWCore.ParameterSet.Config as cms +from Configuration.StandardSequences.Eras import eras + +process = cms.Process("RESP", eras.Phase2C9) + +process.load('Configuration.StandardSequences.Services_cff') +process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi") +process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.options = cms.untracked.PSet( + wantSummary = cms.untracked.bool(True), + numberOfThreads = cms.untracked.uint32(2), + numberOfStreams = cms.untracked.uint32(1), +) +process.maxEvents = cms.untracked.PSet(input = cms.untracked.int32(100)) +process.MessageLogger.cerr.FwkReport.reportEvery = 1 + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring('/store/mc/Phase2HLTTDRWinter20DIGI/TT_TuneCP5_14TeV-powheg-pythia8/GEN-SIM-DIGI-RAW/PU200_110X_mcRun4_realistic_v3-v2/110000/005E74D6-B50E-674E-89E6-EAA9A617B476.root',) +) + +process.load('Configuration.Geometry.GeometryExtended2026D49Reco_cff') +process.load('Configuration.Geometry.GeometryExtended2026D49_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('SimGeneral.MixingModule.mixNoPU_cfi') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, '123X_mcRun4_realistic_v3', '') + +process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') # needed to read HCal TPs +process.load('CalibCalorimetry.CaloTPG.CaloTPGTranscoder_cfi') +process.load('Configuration.StandardSequences.SimL1Emulator_cff') +process.load('L1Trigger.TrackTrigger.TrackTrigger_cff') +process.load("L1Trigger.TrackFindingTracklet.L1HybridEmulationTracks_cff") +process.load("L1Trigger.TrackerDTC.ProducerES_cff") +process.load("L1Trigger.TrackerDTC.ProducerED_cff") +process.load("RecoVertex.BeamSpotProducer.BeamSpot_cfi") + +from L1Trigger.Phase2L1ParticleFlow.L1SeedConePFJetProducer_cfi import L1SeedConePFJetEmulatorProducer +from L1Trigger.Phase2L1ParticleFlow.DeregionizerProducer_cfi import DeregionizerProducer +from L1Trigger.Phase2L1ParticleFlow.l1ctJetFileWriter_cfi import l1ctSeededConeJetFileWriter +process.l1ctLayer2Deregionizer = DeregionizerProducer.clone() +process.l1ctLayer2SeedConeJets = L1SeedConePFJetEmulatorProducer.clone(L1PFObject = cms.InputTag('l1ctLayer2Deregionizer', 'Puppi')) +process.l1ctLayer2SeedConeJetWriter = l1ctSeededConeJetFileWriter.clone(jets = "l1ctLayer2SeedConeJets") + +process.l1ctLayer1Barrel9 = process.l1ctLayer1Barrel.clone() +process.l1ctLayer1Barrel9.puAlgo.nFinalSort = 32 +process.l1ctLayer1Barrel9.regions[0].etaBoundaries = [ -1.5, -0.5, 0.5, 1.5 ] +process.l1ctLayer1Barrel9.boards=cms.VPSet( + cms.PSet( + regions=cms.vuint32(*[0+9*ie+i for ie in range(3) for i in range(3)])), + cms.PSet( + regions=cms.vuint32(*[3+9*ie+i for ie in range(3) for i in range(3)])), + cms.PSet( + regions=cms.vuint32(*[6+9*ie+i for ie in range(3) for i in range(3)])), + ) + +from L1Trigger.Phase2L1ParticleFlow.l1ctLayer1_patternWriters_cff import * +process.l1ctLayer1Barrel.patternWriters = cms.untracked.VPSet(*barrelWriterConfigs) +#process.l1ctLayer1Barrel9.patternWriters = cms.untracked.VPSet(*barrel9WriterConfigs) # not enabled for now +process.l1ctLayer1HGCal.patternWriters = cms.untracked.VPSet(*hgcalWriterConfigs) +process.l1ctLayer1HGCalNoTK.patternWriters = cms.untracked.VPSet(*hgcalNoTKWriterConfigs) +process.l1ctLayer1HF.patternWriters = cms.untracked.VPSet(*hfWriterConfigs) + +process.pfInputsTask = cms.Task( + process.TTClustersFromPhase2TrackerDigis, + process.TTStubsFromPhase2TrackerDigis, + process.TrackerDTCProducer, + process.offlineBeamSpot, + process.TTTracksFromTrackletEmulation, + process.SimL1EmulatorTask +) +process.runPF = cms.Path( + process.l1ctLayer1Barrel + + #process.l1ctLayer1Barrel9 + + process.l1ctLayer1HGCal + + process.l1ctLayer1HGCalNoTK + + process.l1ctLayer1HF + + process.l1ctLayer1 + + process.l1ctLayer2EG + + process.l1ctLayer2Deregionizer + + process.l1ctLayer2SeedConeJets + + process.l1ctLayer2SeedConeJetWriter + ) +process.runPF.associate(process.pfInputsTask) +process.schedule = cms.Schedule(process.runPF) + + +##################################################################################################################### +## Layer 2 e/gamma + +process.l1ctLayer2EG.writeInPattern = True +process.l1ctLayer2EG.writeOutPattern = True +process.l1ctLayer2EG.inPatternFile.maxLinesPerFile = eventsPerFile_*54 +process.l1ctLayer2EG.outPatternFile.maxLinesPerFile = eventsPerFile_*54 + +##################################################################################################################### +## Layer 2 seeded-cone jets +process.l1ctLayer2SeedConeJetWriter.maxLinesPerFile = eventsPerFile_*54 diff --git a/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp b/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp deleted file mode 100644 index fbd92c4a82221..0000000000000 --- a/L1Trigger/Phase2L1ParticleFlow/test/testOutputFiles.cpp +++ /dev/null @@ -1,611 +0,0 @@ -// STL includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// ROOT includes -#include "TROOT.h" -#include "TSystem.h" -#include "TFile.h" -#include "TTree.h" -#include "TLorentzVector.h" - -// CMSSW includes -#include "FWCore/FWLite/interface/FWLiteEnabler.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "DataFormats/FWLite/interface/Handle.h" -#include "DataFormats/FWLite/interface/Run.h" -#include "DataFormats/FWLite/interface/LuminosityBlock.h" -#include "DataFormats/FWLite/interface/Event.h" -#include "DataFormats/L1TParticleFlow/interface/PFTrack.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/DiscretePFInputsIO.h" -#include "L1Trigger/Phase2L1ParticleFlow/interface/Region.h" - -#define NTEST 64 -#define REPORT_EVERY_N 50 -#define NTRACKS_PER_SECTOR 110 -#define NBITS_PER_TRACK 96 -static std::vector regions_; - -typedef l1tpf_impl::InputRegion Region; -typedef std::pair SectorTrackIndex; -typedef std::map TrackMap; - -struct Event { - uint32_t run, lumi; - uint64_t event; - float z0, genZ0; - std::vector puGlobals; // [float] alphaCMed, alphaCRms, alphaFMed, alphaFRms - std::vector regions; - - Event() : run(0), lumi(0), event(0), z0(0.), regions() {} - bool readFromFile(FILE *fRegionDump) { - if (!fread(&run, sizeof(uint32_t), 1, fRegionDump)) - return false; - fread(&lumi, sizeof(uint32_t), 1, fRegionDump); - fread(&event, sizeof(uint64_t), 1, fRegionDump); - l1tpf_impl::readManyFromFile(regions, fRegionDump); - fread(&z0, sizeof(float), 1, fRegionDump); - fread(&genZ0, sizeof(float), 1, fRegionDump); - l1tpf_impl::readManyFromFile(puGlobals, fRegionDump); - return true; - } -}; - -TLorentzVector makeTLorentzVectorPtEtaPhiE(float pt, float eta, float phi, float e) { - TLorentzVector v; - v.SetPtEtaPhiE(pt, eta, phi, e); - return v; -} - -/* - * Convert a bitset to a signed int64_t. - * std::bitset has built-ins for ulong and ullong. - */ -template 0 && N < 64)>> -int64_t to_int64_from_bitset(const std::bitset &b) { - int const shift = 64 - N; - return (((int64_t)b.to_ullong() << shift) >> shift); -} - -/* - * Generic implementation to search if a given value exists in a map or not. - * Adds all the keys with given value in the vector - */ -template -bool findAllInRegion(std::vector &vec, std::map mapOfElemen, T value) { - bool bResult = false; - auto it = mapOfElemen.begin(); - // Iterate through the map - while (it != mapOfElemen.end()) { - // Check if value of this entry matches with given value - if (it->first.first == value) { - // Yes found - bResult = true; - // Push the key in given map - vec.push_back(it->first); - } - // Go to next entry in map - it++; - } - return bResult; -} - -TrackMap get_tracks_from_root_file(fwlite::Event &ev, int entry = 0, bool print = false) { - TrackMap tracks_root; - - // clear the tracks currently stored in the regions - for (l1tpf_impl::Region &r : regions_) { - r.track.clear(); - } - - // go to the event under test - if (!ev.to(entry)) { - std::cerr << "ERROR::testDumpFile::get_tracks_from_root_file Unable to load the event at entry " << entry - << std::endl; - assert(ev.to(entry)); - } - if (print) - printf("ROOT::Run %u, lumi %u, event %llu \n", - ev.getRun().id().run(), - ev.getLuminosityBlock().id().luminosityBlock(), - ev.eventAuxiliary().id().event()); - - edm::InputTag trackLabel("pfTracksFromL1TracksBarrel"); - edm::Handle> h_track; - ev.getByLabel(trackLabel, h_track); - assert(h_track.isValid()); - - int ntrackstotal(0); - const auto &tracks = *h_track; - for (unsigned int itk = 0, ntk = tracks.size(); itk < ntk; ++itk) { - const auto &tk = tracks[itk]; - if (tk.pt() <= 2.0 || tk.nStubs() < 4 || tk.normalizedChi2() >= 15.0) - continue; - for (l1tpf_impl::Region &r : regions_) { - bool inside = r.contains(tk.eta(), tk.phi()); - ; - if (inside) { - l1tpf_impl::PropagatedTrack prop; - prop.fillInput( - tk.pt(), r.localEta(tk.eta()), r.localPhi(tk.phi()), tk.charge(), tk.vertex().Z(), tk.quality(), &tk); - prop.fillPropagated(tk.pt(), - tk.trkPtError(), - tk.caloPtError(), - r.localEta(tk.caloEta()), - r.localPhi(tk.caloPhi()), - tk.quality(), - tk.isMuon()); - prop.hwStubs = tk.nStubs(); - prop.hwChi2 = round(tk.chi2() * 10); - r.track.push_back(prop); - } - } - //if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", ntrackstotal, tk.pt(), tk.eta(), tk.phi()); - ntrackstotal++; - } - for (unsigned int iregion = 0; iregion < regions_.size(); ++iregion) { - std::vector tracks_in_region = regions_[iregion].track; - if (print) - printf("\tFound region %u (eta=[%0.4f,%0.4f] phi=[%0.4f,%0.4f]) with %lu tracks\n", - iregion, - regions_[iregion].etaMin, - regions_[iregion].etaMax, - regions_[iregion].phiCenter - regions_[iregion].phiHalfWidth, - regions_[iregion].phiCenter + regions_[iregion].phiHalfWidth, - tracks_in_region.size()); - for (unsigned int it = 0; it < tracks_in_region.size(); it++) { - if (print) - printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", - it, - tracks_in_region[it].src->p4().pt(), - tracks_in_region[it].src->p4().eta(), - tracks_in_region[it].src->p4().phi()); - tracks_root[std::make_pair(iregion, it)] = makeTLorentzVectorPtEtaPhiE(tracks_in_region[it].src->pt(), - tracks_in_region[it].src->eta(), - tracks_in_region[it].src->phi(), - tracks_in_region[it].src->pt()); - } - } - if (print) { - printf("\t================================= \n"); - printf("\tTotal tracks %u \n\n", ntrackstotal); - } - - return tracks_root; -} - -std::map, TLorentzVector> get_tracks_from_dump_file(FILE *dfile_ = nullptr, bool print = false) { - std::map, TLorentzVector> tracks_dump; - Event event_; - - if (feof(dfile_)) { - std::cerr << "ERROR::testDumpFile::get_tracks_from_dump_file We have already reached the end of the dump file" - << std::endl; - assert(!feof(dfile_)); - } - if (!event_.readFromFile(dfile_)) { - std::cerr << "ERROR::testDumpFile::get_tracks_from_dump_file Something went wrong reading from the dump file" - << std::endl; - assert(event_.readFromFile(dfile_)); - } - if (event_.regions.size() != regions_.size()) { - printf("ERROR::testDumpFile::get_tracks_from_dump_file Mismatching number of input regions: %lu\n", - event_.regions.size()); - assert(event_.regions.size() == regions_.size()); - } - if (print) - printf("Dump::Run %u, lumi %u, event %lu, regions %lu \n", - event_.run, - event_.lumi, - event_.event, - event_.regions.size()); - - unsigned int ntrackstotal(0); - float maxabseta(0), maxz(0), minz(0); - - int pv_gen = round(event_.genZ0 * l1tpf_impl::InputTrack::Z0_SCALE); - int pv_cmssw = round(event_.z0 * l1tpf_impl::InputTrack::Z0_SCALE); - - for (unsigned int is = 0; is < regions_.size(); ++is) { - const Region &r = event_.regions[is]; - if (print) - printf("\tRead region %u [%0.2f,%0.2f] with %lu tracks\n", - is, - r.phiCenter - r.phiHalfWidth, - r.phiCenter + r.phiHalfWidth, - r.track.size()); - ntrackstotal += r.track.size(); - for (unsigned int it = 0; it < r.track.size(); it++) { - tracks_dump[std::make_pair(is, it)] = makeTLorentzVectorPtEtaPhiE( - r.track[it].floatVtxPt(), r.track[it].floatVtxEta(), r.track[it].floatVtxPhi(), r.track[it].floatVtxPt()); - if (abs(r.track[it].hwVtxEta) > maxabseta) - maxabseta = abs(r.track[it].hwVtxEta); - if (r.track[it].hwZ0 > maxz) - maxz = r.track[it].hwZ0; - if (r.track[it].hwZ0 < minz) - minz = r.track[it].hwZ0; - if (print) - printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", - it, - r.track[it].floatVtxPt(), - r.track[it].floatVtxEta(), - r.track[it].floatVtxPhi()); - } - } - - if (print) { - printf("\t================================= \n"); - printf("\tTotal tracks %u \n", ntrackstotal); - printf("\tMax abs(eta) %.2f [hw units] \n", maxabseta); - printf("\tMax abs(eta) %.4f \n", maxabseta / l1tpf_impl::InputTrack::VTX_ETA_SCALE); - printf("\t[Min,max] track z0 [%.2f,%.2f] [hw units] \n", minz, maxz); - printf("\t[Min,max] track z0 [%.2f,%.2f] [cm] \n", - minz / l1tpf_impl::InputTrack::Z0_SCALE, - maxz / l1tpf_impl::InputTrack::Z0_SCALE); - printf("\tPV (GEN) %u \n", pv_gen); - printf("\tPV (CMSSW) %u \n\n", pv_cmssw); - } - - return tracks_dump; -} - -std::map, TLorentzVector> get_tracks_from_coe_file(std::ifstream &cfile_, - bool print = false, - bool debug = false) { - std::map, TLorentzVector> tracks_coe; - std::string bset_string_; - int ntrackstotal(0); - bool skip(false); - - // check that we haven't reached the end of the file (i.e. there a more events to be read out) - if (cfile_.eof()) { - std::cerr << "ERROR::testDumpFile::get_tracks_from_coe_file We have already reached the end of the coe file" - << std::endl; - assert(!cfile_.eof()); - } - if (print) - printf("COE::Run \"unknown\", lumi \"unknown\", event \"unknown\", regions %lu? \n", regions_.size()); - - // read the lines one by one - for (unsigned int iline = 0; iline < NTRACKS_PER_SECTOR; iline++) { - bset_string_.resize(NBITS_PER_TRACK); - for (unsigned int isector = 0; isector < regions_.size(); isector++) { - cfile_.read(&bset_string_[0], 96); - std::bitset bset_(bset_string_); - if (bset_.none()) { - skip = true; - continue; - } else { - skip = false; - } - - std::bitset<14> hwPt; - std::bitset<16> hwVtxEta; - std::bitset<12> hwVtxPhi; - for (int i = 14 - 1; i >= 0; i--) { - hwPt.set(i, bset_[i]); - } - for (int i = 12 - 1; i >= 0; i--) { - hwVtxPhi.set(i, bset_[i + 15]); - } - for (int i = 16 - 1; i >= 0; i--) { - hwVtxEta.set(i, bset_[i + 27]); - } - float hwVtxPt_f = (float(hwPt.to_ulong()) / l1tpf_impl::CaloCluster::PT_SCALE); - float hwVtxEta_f = float(to_int64_from_bitset(hwVtxEta)) / l1tpf_impl::InputTrack::VTX_ETA_SCALE; - float hwVtxPhi_f = float(to_int64_from_bitset(hwVtxPhi)) / l1tpf_impl::InputTrack::VTX_PHI_SCALE; - - if (debug) { - std::cout << "bset_string_ = " << bset_string_ << std::endl; - std::cout << "\thwPt (0b) = " << std::flush; - for (int i = 14 - 1; i >= 0; i--) { - std::cout << bset_[i] << std::flush; - } - std::cout << std::endl; - std::cout << "\thwVtxPhi (0b) = " << std::flush; - for (int i = 12 - 1; i >= 0; i--) { - std::cout << bset_[i + 15] << std::flush; - } - std::cout << std::endl; - std::cout << "\thwVtxEta (0b) = " << std::flush; - for (int i = 16 - 1; i >= 0; i--) { - std::cout << bset_[i + 27] << std::flush; - } - std::cout << std::endl; - std::cout << "\thwPt (int) = " << hwPt.to_ulong() << std::endl; - std::cout << "\thwVtxPhi (int) = " << to_int64_from_bitset(hwVtxPhi) << std::endl; - std::cout << "\thwVtxEta (int) = " << to_int64_from_bitset(hwVtxEta) << std::endl; - std::cout << "\thwVtxPt_f (float) = " << hwVtxPt_f << std::endl; - std::cout << "\thwVtxPhi_f (float) = " << hwVtxPhi_f << std::endl; - std::cout << "\thwVtxEta_f (float) = " << hwVtxEta_f << std::endl; - } - - if (bset_.any()) { - ntrackstotal++; - tracks_coe[std::make_pair(isector, iline)] = - makeTLorentzVectorPtEtaPhiE(hwVtxPt_f, hwVtxEta_f, hwVtxPhi_f, hwVtxPt_f); - //if (print) printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", it, hwPt_f, hwVtxEta_f, hwVtxPhi_f); - } - } - - // remove the trailing character - bset_string_.resize(2); - cfile_.read(&bset_string_[0], 2); - if (debug && !skip) - std::cout << "bset_string_ = " << bset_string_ << std::endl; - if (bset_string_ != ",\n" && bset_string_ != ";\n") { - std::cerr << "ERROR::testDumpFile::get_tracks_from_coe_file Something went wrong reading line " << 11 + iline - << " of the COE file" << std::endl - << "\tThe line should have ended with \',\' or \';\', but instead ended with \'" - << bset_string_ << "\'" << std::endl; - assert(bset_string_ != "," || bset_string_ != ";"); - } - } - for (unsigned int is = 0; is < regions_.size(); ++is) { - std::vector tracks_in_sector; - findAllInRegion(tracks_in_sector, tracks_coe, is); - if (print) - printf("\tRead region %u (eta=[%0.4f,%0.4f] phi=[%0.4f,%0.4f]) with %lu tracks\n", - is, - regions_[is].etaMin, - regions_[is].etaMax, - regions_[is].phiCenter - regions_[is].phiHalfWidth, - regions_[is].phiCenter + regions_[is].phiHalfWidth, - tracks_in_sector.size()); - for (unsigned int it = 0; it < tracks_in_sector.size(); it++) { - if (print) - printf("\t\t Track %u (pT,eta,phi): (%.4f,%.4f,%.4f)\n", - it, - tracks_coe[tracks_in_sector[it]].Pt(), - tracks_coe[tracks_in_sector[it]].Eta(), - tracks_coe[tracks_in_sector[it]].Phi()); - } - } - - if (print) { - printf("\t================================= \n"); - printf("\tTotal tracks %u \n\n", ntrackstotal); - } - - return tracks_coe; -} - -std::ifstream &GotoLine(std::ifstream &file, unsigned int num) { - file.seekg(std::ios::beg); - for (unsigned int i = 0; i < num - 1; ++i) { - file.ignore(std::numeric_limits::max(), '\n'); - } - return file; -} - -bool compare_lv_with_tolerance(TLorentzVector a, TLorentzVector b, const std::vector &tolerance = {0, 0, 0, 0}) { - /* - Example (Tolerance = 0.0005): - Track from ROOT file: pt=16.3452797 - InputTrack::INVPT_SCALE = 2E4 - std::numeric_limits::max() = 65535 - hwInvpt = std::min(round(1/pt * InputTrack::INVPT_SCALE), std::numeric_limits::max()) = 1224.0000 - floatVtxPt() = 1/(float(hwInvpt) / InputTrack::INVPT_SCALE) = 16.339869 - So loss of precision comes from rounding - Difference is DeltaPt=0.00541114807 - */ - if (abs(a.Pt() - b.Pt()) > tolerance[0] || abs(a.Eta() - b.Eta()) > tolerance[1] || - abs(a.Phi() - b.Phi()) > tolerance[2] || abs(a.E() - b.E()) > tolerance[3]) { - std::cerr << std::setprecision(9); - std::cerr << std::endl << "\tMismatching " << std::flush; - if (abs(a.Pt() - b.Pt()) > tolerance[0]) - std::cerr << "pT! " << a.Pt() << " vs " << b.Pt() << " where DeltaPt=" << abs(a.Pt() - b.Pt()) - << " and epsilon=" << tolerance[0] << std::endl; - else if (abs(a.Eta() - b.Eta()) > tolerance[1]) - std::cerr << "eta! " << a.Eta() << " vs " << b.Eta() << " where DeltaEta=" << abs(a.Eta() - b.Eta()) - << " and epsilon=" << tolerance[1] << std::endl; - else if (abs(a.Phi() - b.Phi()) > tolerance[2]) - std::cerr << "phi! " << a.Phi() << " vs " << b.Phi() << " where DeltaPhi=" << abs(a.Phi() - b.Phi()) - << " and epsilon=" << tolerance[2] << std::endl; - else if (abs(a.E() - b.E()) > tolerance[3]) - std::cerr << "E! " << a.E() << " vs " << b.E() << " where DeltaE=" << abs(a.E() - b.E()) - << " and epsilon=" << tolerance[3] << std::endl; - return false; - } - return true; -} - -bool compare_maps(TrackMap ref, TrackMap test) { - TLorentzVector tlv; - for (auto it = ref.begin(); it != ref.end(); it++) { - if (test.find(it->first) == test.end()) { - std::cerr << std::endl - << "\tERROR::compare_maps Can't find the test track with (sector,index)=(" << it->first.first << "," - << it->first.second << ")" << std::endl; - return false; - } - tlv = (test.find(it->first)->second); - // The pT tolerance should be 1.0/l1tpf_impl::CaloCluster::PT_SCALE, but because of the rounding this is not true and the actual resolution isn't always as good - // Instead, we will use max(1% of the pT of the reference TLorentzVector,0.25) - // We use the max statement because at low pT, the 1% definition doesn't hold anymore. This wouldn't be a problem if 1/pT were encoded rather than pT. - if (!compare_lv_with_tolerance( - (it->second), - tlv, - {float(std::max(it->second.Pt() * 1E-2, 1.0 / l1tpf_impl::CaloCluster::PT_SCALE)), - 1.0 / l1tpf_impl::InputTrack::VTX_ETA_SCALE, - 1.0 / l1tpf_impl::InputTrack::VTX_PHI_SCALE, - float(std::max(it->second.Pt() * 1E-2, 1.0 / l1tpf_impl::CaloCluster::PT_SCALE))})) { - std::cerr << std::endl - << "\tERROR::compare_maps Can't find the test track with TLorentzVector (" << it->second.Pt() << "," - << it->second.Eta() << "," << it->second.Phi() << "," << it->second.E() << ")" << std::endl - << "\t\tInstead found (" << tlv.Pt() << "," << tlv.Eta() << "," << tlv.Phi() << "," << tlv.E() - << ") at the position (sector,index)=(" << it->first.first << "," << it->first.second << ")" - << std::endl; - return false; - } - } - return true; -} - -int main(int argc, char *argv[]) { - // store some programatic information - std::stringstream usage; - usage << "usage: " << argv[0] - << " .root .dump .coe "; - - // load framework libraries - gSystem->Load("libFWCoreFWLite"); - FWLiteEnabler::enable(); - - // argc should be 5 for correct execution - // We print argv[0] assuming it is the program name - if (argc < 9) { - std::cerr << "ERROR::testDumpFile " << argc << " arguments provided" << std::endl; - for (int i = 0; i < argc; i++) { - std::cerr << "\tArgument " << i << ": " << argv[i] << std::endl; - } - std::cerr << usage.str() << std::endl; - return -1; - } - - // assign the command-line parameters to variables and setup the regions - std::string filename_root = argv[1]; - std::string filename_dump = argv[2]; - std::string filename_coe = argv[3]; - float etaExtra, phiExtra; - unsigned int nRegionsPhi; - std::vector etaBoundaries; - try { - etaExtra = atof(argv[4]); - phiExtra = atof(argv[5]); - nRegionsPhi = atoi(argv[6]); - std::vector etaBoundariesStrings(argv + 7, argv + argc); - std::size_t pos; - for (unsigned int i = 0; i < etaBoundariesStrings.size(); i++) { - etaBoundaries.push_back(std::stoi(etaBoundariesStrings[i], &pos)); - if (pos < etaBoundariesStrings[i].size()) { - std::cerr << "Trailing characters after number: " << etaBoundariesStrings[i] << '\n'; - } - } - float phiWidth = 2 * M_PI / nRegionsPhi; - for (unsigned int ieta = 0, neta = etaBoundaries.size() - 1; ieta < neta; ++ieta) { - for (unsigned int iphi = 0; iphi < nRegionsPhi; ++iphi) { - float phiCenter = (iphi + 0.5) * phiWidth - M_PI; - regions_.push_back(l1tpf_impl::Region(etaBoundaries[ieta], - etaBoundaries[ieta + 1], - phiCenter, - phiWidth, - phiExtra, - etaExtra, - false, - 0, - 0, - 0, - 0, - 0, - 0)); - } - } - } catch (std::invalid_argument const &ex) { - std::cerr << "Invalid number in one of the eta-phi arguments" << std::endl; - return -2; - } catch (std::out_of_range const &ex) { - std::cerr << "Number out of range in one of the eta-phi arguments" << std::endl; - return -3; - } - - // check the filenames - if (filename_root.find(".root") == std::string::npos) { - std::cerr << "ERROR::testDumpFile Filename 1 must be a ROOT (.root) file" << std::endl << usage.str() << std::endl; - return -4; - } else if (filename_dump.find(".dump") == std::string::npos) { - std::cerr << "ERROR::testDumpFile Filename 2 must be a binary (.dump) file" << std::endl - << usage.str() << std::endl; - return -5; - } else if (filename_coe.find(".coe") == std::string::npos) { - std::cerr << "ERROR::testDumpFile Filename 3 must be a COE (.coe) file" << std::endl << usage.str() << std::endl; - return -6; - } - - // report the program configuraion - std::cout << "Configuration:" << std::endl - << "==============" << std::endl - << "Number of tests (events): " << NTEST << std::endl - << "Report every N tests: " << REPORT_EVERY_N << std::endl - << "Number of regions (in eta-phi): " << regions_.size() << std::endl; - for (unsigned int iregion = 0; iregion < regions_.size(); iregion++) { - printf("\t%i : eta=[%0.4f,%0.4f] phi=[%0.4f,%0.4f]\n", - iregion, - regions_[iregion].etaMin, - regions_[iregion].etaMax, - regions_[iregion].phiCenter - regions_[iregion].phiHalfWidth, - regions_[iregion].phiCenter + regions_[iregion].phiHalfWidth); - } - std::cout << "Number of tracks per sector: " << NTRACKS_PER_SECTOR << std::endl - << "Number of bits per track: " << NBITS_PER_TRACK << std::endl - << "==============" << std::endl - << std::endl; - - // open the files for testing - TFile *rfile_ = TFile::Open(filename_root.c_str(), "READ"); - if (!rfile_) { - std::cerr << "ERROR::testDumpFile Cannot open '" << filename_root << "'" << std::endl; - return -7; - } - fwlite::Event rfileentry_(rfile_); - FILE *dfile_(fopen(filename_dump.c_str(), "rb")); - if (!dfile_) { - std::cerr << "ERROR::testDumpFile Cannot read '" << filename_dump << "'" << std::endl; - return -8; - } - std::ifstream cfile_(filename_coe); - if (!cfile_) { - std::cerr << "ERROR::testDumpFile Cannot read '" << filename_coe << "'" << std::endl; - return -9; - } - GotoLine(cfile_, 11); //Skip the header of the COE file - - TrackMap tracks_root, tracks_dump, tracks_coe; - - // run the tests for multiple events - for (int test = 1; test <= NTEST; ++test) { - if (test % REPORT_EVERY_N == 1) - std::cout << "Doing test " << test << " ... " << std::endl; - - tracks_root = get_tracks_from_root_file(rfileentry_, test - 1, test == 1); - tracks_dump = get_tracks_from_dump_file(dfile_, test == 1); - tracks_coe = get_tracks_from_coe_file(cfile_, test == 1); - - if (test % REPORT_EVERY_N == 1) - std::cout << "Comparing the ROOT tracks to the dump tracks in event " << test << " ... " << std::flush; - if (!compare_maps(tracks_root, tracks_dump)) - return -10; - if (test % REPORT_EVERY_N == 1) - std::cout << "DONE" << std::endl; - - if (test % REPORT_EVERY_N == 1) - std::cout << "Comparing the ROOT tracks to the coe tracks in event " << test << " ... " << std::flush; - if (!compare_maps(tracks_root, tracks_coe)) - return -11; - if (test % REPORT_EVERY_N == 1) - std::cout << "DONE" << std::endl << std::endl; - } - - std::cout << std::endl << "The dump and coe outputs match the ROOT outputs for all events!" << std::endl; - return 0; -} - -/* -USE: -g++ -I/uscms_data/d2/aperloff/YOURWORKINGAREA/TSABoard/slc7/CMSSW_10_6_0_pre4/src/L1Trigger/Phase2L1ParticleFlow/interface/ -O0 -g3 -Wall -std=c++0x -c -fmessage-length=0 testDumpFile.cpp -g++ -o testDumpFile testDumpFile.o -./testDumpFile trackerRegion_alltracks_sectors_1x18_TTbar_PU200.dump 18 - -scram b runtests -*/ diff --git a/L1Trigger/Phase2L1Taus/BuildFile.xml b/L1Trigger/Phase2L1Taus/BuildFile.xml index 7ec14fe3e2ff3..035e9410cf0c2 100644 --- a/L1Trigger/Phase2L1Taus/BuildFile.xml +++ b/L1Trigger/Phase2L1Taus/BuildFile.xml @@ -1,4 +1,5 @@ + diff --git a/L1Trigger/Phase2L1Taus/interface/L1HPSPFTauBuilder.h b/L1Trigger/Phase2L1Taus/interface/L1HPSPFTauBuilder.h index 0dca7074803d6..e79fdecb3f83a 100644 --- a/L1Trigger/Phase2L1Taus/interface/L1HPSPFTauBuilder.h +++ b/L1Trigger/Phase2L1Taus/interface/L1HPSPFTauBuilder.h @@ -7,7 +7,7 @@ #include "DataFormats/L1TParticleFlow/interface/HPSPFTau.h" // l1t::HPSPFTau #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" // l1t::PFCandidate, l1t::PFCandidateCollection, l1t::PFCandidateRef #include "DataFormats/JetReco/interface/CaloJet.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" #include "CommonTools/Utils/interface/FormulaEvaluator.h" #include @@ -18,7 +18,7 @@ class L1HPSPFTauBuilder { void reset(); void setL1PFCandProductID(const edm::ProductID& l1PFCandProductID); - void setVertex(const l1t::TkPrimaryVertexRef& primaryVertex); + void setVertex(const l1t::VertexWordRef& primaryVertex); void setL1PFTauSeed(const l1t::PFCandidateRef& l1PFCandSeed); //void setL1PFTauSeed(const reco::CaloJetRef& l1Jet_seed); void setL1PFTauSeed(const reco::CaloJetRef& l1JetSeed, const std::vector& l1PFCands); @@ -62,7 +62,7 @@ class L1HPSPFTauBuilder { double l1PFTauSeedPhi_; double l1PFTauSeedZVtx_; double sumAllL1PFCandidatesPt_; - l1t::TkPrimaryVertexRef primaryVertex_; + l1t::VertexWordRef primaryVertex_; l1t::HPSPFTau l1PFTau_; reco::Particle::LorentzVector stripP4_; diff --git a/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.cc b/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.cc index dd909fe71505e..6af79cbab176f 100644 --- a/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.cc +++ b/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.cc @@ -30,7 +30,7 @@ HPSPFTauProducer::HPSPFTauProducer(const edm::ParameterSet& cfg) } srcL1Vertices_ = cfg.getParameter("srcL1Vertices"); if (!srcL1Vertices_.label().empty()) { - tokenL1Vertices_ = consumes>(srcL1Vertices_); + tokenL1Vertices_ = consumes(srcL1Vertices_); } deltaR2Cleaning_ = deltaRCleaning_ * deltaRCleaning_; @@ -58,14 +58,14 @@ void HPSPFTauProducer::produce(edm::Event& evt, const edm::EventSetup& es) { edm::Handle l1PFCands; evt.getByToken(tokenL1PFCands_, l1PFCands); - l1t::TkPrimaryVertexRef primaryVertex; + l1t::VertexWordRef primaryVertex; float primaryVertex_z = 0.; if (!srcL1Vertices_.label().empty()) { - edm::Handle> vertices; + edm::Handle vertices; evt.getByToken(tokenL1Vertices_, vertices); if (!vertices->empty()) { - primaryVertex = l1t::TkPrimaryVertexRef(vertices, 0); - primaryVertex_z = primaryVertex->zvertex(); + primaryVertex = l1t::VertexWordRef(vertices, 0); + primaryVertex_z = primaryVertex->z0(); } } @@ -154,7 +154,7 @@ void HPSPFTauProducer::produce(edm::Event& evt, const edm::EventSetup& es) { std::fabs(l1PFTau.leadChargedPFCand()->eta()) < maxLeadChargedPFCandEta_ && (srcL1Vertices_.label().empty() || (primaryVertex.isNonnull() && l1PFTau.leadChargedPFCand()->pfTrack().isNonnull() && - std::fabs(l1PFTau.leadChargedPFCand()->pfTrack()->vertex().z() - primaryVertex->zvertex()) < + std::fabs(l1PFTau.leadChargedPFCand()->pfTrack()->vertex().z() - primaryVertex->z0()) < maxLeadChargedPFCandDz_)) && l1PFTau.sumChargedIso() < maxChargedIso_ && l1PFTau.sumChargedIso() < maxChargedRelIso_ * l1PFTau.pt())) continue; @@ -220,7 +220,7 @@ void HPSPFTauProducer::fillDescriptions(edm::ConfigurationDescriptions& descript desc.add("minSeedJetPt", 30.0); desc.add("maxChargedRelIso", 1.0); desc.add("minSeedChargedPFCandPt", 5.0); - desc.add("srcL1PFCands", edm::InputTag("l1pfCandidates", "PF")); + desc.add("srcL1PFCands", edm::InputTag("l1ctLayer1", "PF")); desc.add("stripSizeEta", 0.05); desc.add("maxLeadChargedPFCandEta", 2.4); desc.add("deltaRCleaning", 0.4); @@ -230,7 +230,7 @@ void HPSPFTauProducer::fillDescriptions(edm::ConfigurationDescriptions& descript desc.add("maxSeedChargedPFCandEta", 2.4); desc.add("applyPreselection", false); desc.add("isolationConeSize", 0.4); - desc.add("srcL1Vertices", edm::InputTag("L1TkPrimaryVertex")); + desc.add("srcL1Vertices", edm::InputTag("L1VertexFinderEmulator", "l1verticesEmulation")); desc.add("maxChargedIso", 1000.0); { edm::ParameterSetDescription psd0; diff --git a/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.h b/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.h index c75d41d6b6552..2e7b14e3c2072 100644 --- a/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.h +++ b/L1Trigger/Phase2L1Taus/plugins/HPSPFTauProducer.h @@ -14,7 +14,7 @@ #include "DataFormats/L1TParticleFlow/interface/HPSPFTauFwd.h" // l1t::HPSPFTauCollection #include "DataFormats/L1TParticleFlow/interface/PFCandidate.h" // l1t::PFCandidate, l1t::PFCandidateCollection, l1t::PFCandidateRef #include "DataFormats/JetReco/interface/CaloJet.h" -#include "DataFormats/L1TCorrelator/interface/TkPrimaryVertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" #include #include @@ -38,7 +38,7 @@ class HPSPFTauProducer : public edm::stream::EDProducer<> { edm::InputTag srcL1Jets_; edm::EDGetTokenT> tokenL1Jets_; edm::InputTag srcL1Vertices_; - edm::EDGetTokenT> tokenL1Vertices_; + edm::EDGetTokenT tokenL1Vertices_; std::vector signalQualityCutsDzCutDisabled_; std::vector isolationQualityCutsDzCutDisabled_; diff --git a/L1Trigger/Phase2L1Taus/python/HPSPFTauProducerPF_cfi.py b/L1Trigger/Phase2L1Taus/python/HPSPFTauProducerPF_cfi.py index d1c58ccb4131c..6c2014f36ddbf 100644 --- a/L1Trigger/Phase2L1Taus/python/HPSPFTauProducerPF_cfi.py +++ b/L1Trigger/Phase2L1Taus/python/HPSPFTauProducerPF_cfi.py @@ -2,5 +2,5 @@ from L1Trigger.Phase2L1Taus.hpspfTauProducer_cfi import hpspfTauProducer as _hpspfTauProducer HPSPFTauProducerPF = _hpspfTauProducer.clone( - srcL1PFCands = "l1pfCandidates:PF" + srcL1PFCands = "l1ctLayer1:PF", ) diff --git a/L1Trigger/Phase2L1Taus/python/HPSPFTauProducerPuppi_cfi.py b/L1Trigger/Phase2L1Taus/python/HPSPFTauProducerPuppi_cfi.py index a7ab48a6ce6a2..383a8bd9da523 100644 --- a/L1Trigger/Phase2L1Taus/python/HPSPFTauProducerPuppi_cfi.py +++ b/L1Trigger/Phase2L1Taus/python/HPSPFTauProducerPuppi_cfi.py @@ -2,7 +2,7 @@ from L1Trigger.Phase2L1Taus.hpspfTauProducer_cfi import hpspfTauProducer as _hpspfTauProducer HPSPFTauProducerPuppi = _hpspfTauProducer.clone( - srcL1PFCands = "l1pfCandidates:Puppi", + srcL1PFCands = "l1ctLayer1:Puppi", signalQualityCuts = dict( chargedHadron = dict( maxDz = 1.e+3 diff --git a/L1Trigger/Phase2L1Taus/python/l1emulator_cff.py b/L1Trigger/Phase2L1Taus/python/l1emulator_cff.py index f79f1cf2e177e..836be424a691b 100644 --- a/L1Trigger/Phase2L1Taus/python/l1emulator_cff.py +++ b/L1Trigger/Phase2L1Taus/python/l1emulator_cff.py @@ -24,8 +24,8 @@ TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag( cms.InputTag(L1TRK_NAME, L1TRK_LABEL) ) l1emulator += TrackTriggerAssociatorTracks -from L1Trigger.L1TTrackMatch.L1TkPrimaryVertexProducer_cfi import * -l1emulator += L1TkPrimaryVertex +from L1Trigger.VertexFinder.VertexProducer_cff import * +l1emulator += VertexProducer from Configuration.StandardSequences.SimL1Emulator_cff import * l1emulator += SimL1Emulator diff --git a/L1Trigger/Phase2L1Taus/src/L1HPSPFTauBuilder.cc b/L1Trigger/Phase2L1Taus/src/L1HPSPFTauBuilder.cc index 285ea3fecec33..ea0d516d7c275 100644 --- a/L1Trigger/Phase2L1Taus/src/L1HPSPFTauBuilder.cc +++ b/L1Trigger/Phase2L1Taus/src/L1HPSPFTauBuilder.cc @@ -50,7 +50,7 @@ void L1HPSPFTauBuilder::reset() { l1PFTauSeedPhi_ = 0.; l1PFTauSeedZVtx_ = 0.; sumAllL1PFCandidatesPt_ = 0.; - primaryVertex_ = l1t::TkPrimaryVertexRef(); + primaryVertex_ = l1t::VertexWordRef(); l1PFTau_ = l1t::HPSPFTau(); stripP4_ = reco::Particle::LorentzVector(0., 0., 0., 0.); @@ -87,7 +87,7 @@ void L1HPSPFTauBuilder::setL1PFCandProductID(const edm::ProductID& l1PFCandProdu l1PFCandProductID_ = l1PFCandProductID; } -void L1HPSPFTauBuilder::setVertex(const l1t::TkPrimaryVertexRef& primaryVertex) { primaryVertex_ = primaryVertex; } +void L1HPSPFTauBuilder::setVertex(const l1t::VertexWordRef& primaryVertex) { primaryVertex_ = primaryVertex; } void L1HPSPFTauBuilder::setL1PFTauSeed(const l1t::PFCandidateRef& l1PFCandSeed) { if (debug_) { @@ -348,83 +348,102 @@ void L1HPSPFTauBuilder::buildL1PFTau() { } } } - l1PFTau_.setP4(l1PFTau_p4); - - l1PFTau_.setSeedChargedPFCand(l1PFCandSeed_); - l1PFTau_.setSeedJet(l1JetSeed_); - - l1PFTau_.setSignalAllL1PFCandidates(convertToRefVector(signalAllL1PFCandidates_)); - l1PFTau_.setSignalChargedHadrons(convertToRefVector(signalChargedHadrons_)); - l1PFTau_.setSignalElectrons(convertToRefVector(signalElectrons_)); - l1PFTau_.setSignalNeutralHadrons(convertToRefVector(signalNeutralHadrons_)); - l1PFTau_.setSignalPhotons(convertToRefVector(signalPhotons_)); - l1PFTau_.setSignalMuons(convertToRefVector(signalMuons_)); - - l1PFTau_.setStripAllL1PFCandidates(convertToRefVector(stripAllL1PFCandidates_)); - l1PFTau_.setStripElectrons(convertToRefVector(stripElectrons_)); - l1PFTau_.setStripPhotons(convertToRefVector(stripPhotons_)); - - l1PFTau_.setIsoAllL1PFCandidates(convertToRefVector(isoAllL1PFCandidates_)); - l1PFTau_.setIsoChargedHadrons(convertToRefVector(isoChargedHadrons_)); - l1PFTau_.setIsoElectrons(convertToRefVector(isoElectrons_)); - l1PFTau_.setIsoNeutralHadrons(convertToRefVector(isoNeutralHadrons_)); - l1PFTau_.setIsoPhotons(convertToRefVector(isoPhotons_)); - l1PFTau_.setIsoMuons(convertToRefVector(isoMuons_)); - - l1PFTau_.setSumAllL1PFCandidates(convertToRefVector(sumAllL1PFCandidates_)); - l1PFTau_.setSumChargedHadrons(convertToRefVector(sumChargedHadrons_)); - l1PFTau_.setSumElectrons(convertToRefVector(sumElectrons_)); - l1PFTau_.setSumNeutralHadrons(convertToRefVector(sumNeutralHadrons_)); - l1PFTau_.setSumPhotons(convertToRefVector(sumPhotons_)); - l1PFTau_.setSumMuons(convertToRefVector(sumMuons_)); - - l1PFTau_.setPrimaryVertex(primaryVertex_); - - if (l1PFTau_.signalChargedHadrons().size() > 1) { - if (stripP4_.pt() < 5.) - l1PFTau_.setTauType(l1t::HPSPFTau::kThreeProng0Pi0); - else - l1PFTau_.setTauType(l1t::HPSPFTau::kThreeProng1Pi0); - } else { - if (stripP4_.pt() < 5.) - l1PFTau_.setTauType(l1t::HPSPFTau::kOneProng0Pi0); - else - l1PFTau_.setTauType(l1t::HPSPFTau::kOneProng1Pi0); - } + if (l1PFTau_.leadChargedPFCand().isNonnull() && l1PFTau_.leadChargedPFCand()->pfTrack().isNonnull()) { + l1PFTau_.setZ(l1PFTau_.leadChargedPFCand()->pfTrack()->vertex().z()); + + l1PFTau_.setP4(l1PFTau_p4); + + l1PFTau_.setSeedChargedPFCand(l1PFCandSeed_); + l1PFTau_.setSeedJet(l1JetSeed_); + + l1PFTau_.setSignalAllL1PFCandidates(convertToRefVector(signalAllL1PFCandidates_)); + l1PFTau_.setSignalChargedHadrons(convertToRefVector(signalChargedHadrons_)); + l1PFTau_.setSignalElectrons(convertToRefVector(signalElectrons_)); + l1PFTau_.setSignalNeutralHadrons(convertToRefVector(signalNeutralHadrons_)); + l1PFTau_.setSignalPhotons(convertToRefVector(signalPhotons_)); + l1PFTau_.setSignalMuons(convertToRefVector(signalMuons_)); + + l1PFTau_.setStripAllL1PFCandidates(convertToRefVector(stripAllL1PFCandidates_)); + l1PFTau_.setStripElectrons(convertToRefVector(stripElectrons_)); + l1PFTau_.setStripPhotons(convertToRefVector(stripPhotons_)); + + l1PFTau_.setIsoAllL1PFCandidates(convertToRefVector(isoAllL1PFCandidates_)); + l1PFTau_.setIsoChargedHadrons(convertToRefVector(isoChargedHadrons_)); + l1PFTau_.setIsoElectrons(convertToRefVector(isoElectrons_)); + l1PFTau_.setIsoNeutralHadrons(convertToRefVector(isoNeutralHadrons_)); + l1PFTau_.setIsoPhotons(convertToRefVector(isoPhotons_)); + l1PFTau_.setIsoMuons(convertToRefVector(isoMuons_)); + + l1PFTau_.setSumAllL1PFCandidates(convertToRefVector(sumAllL1PFCandidates_)); + l1PFTau_.setSumChargedHadrons(convertToRefVector(sumChargedHadrons_)); + l1PFTau_.setSumElectrons(convertToRefVector(sumElectrons_)); + l1PFTau_.setSumNeutralHadrons(convertToRefVector(sumNeutralHadrons_)); + l1PFTau_.setSumPhotons(convertToRefVector(sumPhotons_)); + l1PFTau_.setSumMuons(convertToRefVector(sumMuons_)); + + l1PFTau_.setPrimaryVertex(primaryVertex_); + + if (l1PFTau_.signalChargedHadrons().size() > 1) { + if (stripP4_.pt() < 5.) + l1PFTau_.setTauType(l1t::HPSPFTau::kThreeProng0Pi0); + else + l1PFTau_.setTauType(l1t::HPSPFTau::kThreeProng1Pi0); + } else { + if (stripP4_.pt() < 5.) + l1PFTau_.setTauType(l1t::HPSPFTau::kOneProng0Pi0); + else + l1PFTau_.setTauType(l1t::HPSPFTau::kOneProng1Pi0); + } - l1PFTau_.setStripP4(stripP4_); + l1PFTau_.setStripP4(stripP4_); - l1PFTau_.setSumAllL1PFCandidatesPt(sumAllL1PFCandidatesPt_); - l1PFTau_.setSignalConeSize(signalConeSize_); - l1PFTau_.setisolationConeSize(isolationConeSize_); + l1PFTau_.setSumAllL1PFCandidatesPt(sumAllL1PFCandidatesPt_); + l1PFTau_.setSignalConeSize(signalConeSize_); + l1PFTau_.setisolationConeSize(isolationConeSize_); - double sumChargedIso = 0.; - double sumNeutralIso = 0.; - for (const auto& l1PFCand : isoAllL1PFCandidates_) { - if (l1PFCand->charge() != 0) { - sumChargedIso += l1PFCand->pt(); - } else if (l1PFCand->id() == l1t::PFCandidate::Photon) { - sumNeutralIso += l1PFCand->pt(); + double sumChargedIso = 0.; + double sumNeutralIso = 0.; + for (const auto& l1PFCand : isoAllL1PFCandidates_) { + if (l1PFCand->charge() != 0) { + sumChargedIso += l1PFCand->pt(); + } else if (l1PFCand->id() == l1t::PFCandidate::Photon) { + sumNeutralIso += l1PFCand->pt(); + } + } + l1PFTau_.setSumChargedIso(sumChargedIso); + l1PFTau_.setSumNeutralIso(sumNeutralIso); + const double weightNeutralIso = 1.; + const double offsetNeutralIso = 0.; + l1PFTau_.setSumCombinedIso(sumChargedIso + weightNeutralIso * (sumNeutralIso - offsetNeutralIso)); + l1PFTau_.setSumChargedIsoPileup(sumChargedIsoPileup_); + + if (l1PFTau_.sumChargedIso() < 20.0) { + l1PFTau_.setPassVLooseIso(true); + } + if (l1PFTau_.sumChargedIso() < 10.0) { + l1PFTau_.setPassLooseIso(true); + } + if (l1PFTau_.sumChargedIso() < 5.0) { + l1PFTau_.setPassMediumIso(true); + } + if (l1PFTau_.sumChargedIso() < 2.5) { + l1PFTau_.setPassTightIso(true); + } + + if (l1PFTau_p4.pt() != 0) { + if (l1PFTau_.sumChargedIso() / l1PFTau_p4.pt() < 0.40) { + l1PFTau_.setPassVLooseRelIso(true); + } + if (l1PFTau_.sumChargedIso() / l1PFTau_p4.pt() < 0.20) { + l1PFTau_.setPassLooseRelIso(true); + } + if (l1PFTau_.sumChargedIso() / l1PFTau_p4.pt() < 0.10) { + l1PFTau_.setPassMediumRelIso(true); + } + if (l1PFTau_.sumChargedIso() / l1PFTau_p4.pt() < 0.05) { + l1PFTau_.setPassTightRelIso(true); + } } - } - l1PFTau_.setSumChargedIso(sumChargedIso); - l1PFTau_.setSumNeutralIso(sumNeutralIso); - const double weightNeutralIso = 1.; - const double offsetNeutralIso = 0.; - l1PFTau_.setSumCombinedIso(sumChargedIso + weightNeutralIso * (sumNeutralIso - offsetNeutralIso)); - l1PFTau_.setSumChargedIsoPileup(sumChargedIsoPileup_); - - if (l1PFTau_.sumChargedIso() < 20.0) { - l1PFTau_.setPassVLooseIso(true); - } - if (l1PFTau_.sumChargedIso() < 10.0) { - l1PFTau_.setPassLooseIso(true); - } - if (l1PFTau_.sumChargedIso() < 5.0) { - l1PFTau_.setPassMediumIso(true); - } - if (l1PFTau_.sumChargedIso() < 2.5) { - l1PFTau_.setPassTightIso(true); } } diff --git a/L1Trigger/Phase2L1Taus/src/L1HPSPFTauQualityCut.cc b/L1Trigger/Phase2L1Taus/src/L1HPSPFTauQualityCut.cc index e2ba4cbf2cf99..8c9db2552af00 100644 --- a/L1Trigger/Phase2L1Taus/src/L1HPSPFTauQualityCut.cc +++ b/L1Trigger/Phase2L1Taus/src/L1HPSPFTauQualityCut.cc @@ -42,7 +42,7 @@ bool L1HPSPFTauQualityCut::operator()(const l1t::PFCandidate& pfCand, float_t pr if (pfCand.charge() != 0) { if (dzCut_ == kEnabledPrimary || dzCut_ == kEnabledPileup) { const l1t::PFTrackRef& pfCand_track = pfCand.pfTrack(); - double dz = std::fabs(pfCand_track->vertex().z() - primaryVertex_z); + double dz = std::abs(pfCand_track->vertex().z() - primaryVertex_z); if (dzCut_ == kEnabledPrimary && dz > maxDz_) return false; if (dzCut_ == kEnabledPileup && dz <= maxDz_) diff --git a/L1Trigger/Phase2L1Taus/test/produceHPSPFTaus_cfg.py b/L1Trigger/Phase2L1Taus/test/produceHPSPFTaus_cfg.py index e1b28ad03d45d..2b9b572b15d85 100644 --- a/L1Trigger/Phase2L1Taus/test/produceHPSPFTaus_cfg.py +++ b/L1Trigger/Phase2L1Taus/test/produceHPSPFTaus_cfg.py @@ -59,41 +59,9 @@ process.load('SimCalorimetry.HcalTrigPrimProducers.hcaltpdigi_cff') process.load('CalibCalorimetry.CaloTPG.CaloTPGTranscoder_cfi') -process.load('L1Trigger.L1THGCal.hgcalTriggerPrimitives_cff') -process.productionSequence += process.hgcalTriggerPrimitives - -process.load('SimCalorimetry.EcalEBTrigPrimProducers.ecalEBTriggerPrimitiveDigis_cff') -process.productionSequence += process.simEcalEBTriggerPrimitiveDigis - -process.load("L1Trigger.TrackFindingTracklet.Tracklet_cfi") -L1TRK_PROC = process.TTTracksFromTrackletEmulation -L1TRK_NAME = "TTTracksFromTrackletEmulation" -L1TRK_LABEL = "Level1TTTracks" - -process.load("RecoVertex.BeamSpotProducer.BeamSpot_cfi") -process.productionSequence += process.offlineBeamSpot - -process.productionSequence += process.TTTracksFromTrackletEmulation - -process.load("SimTracker.TrackTriggerAssociation.TrackTriggerAssociator_cff") -process.TTTrackAssociatorFromPixelDigis.TTTracks = cms.VInputTag( cms.InputTag(L1TRK_NAME, L1TRK_LABEL) ) -process.productionSequence += process.TrackTriggerAssociatorTracks - -process.load("L1Trigger.L1TTrackMatch.L1TkPrimaryVertexProducer_cfi") -process.productionSequence += process.L1TkPrimaryVertex - process.load('Configuration.StandardSequences.SimL1Emulator_cff') process.productionSequence += process.SimL1Emulator -process.load("L1Trigger.Phase2L1ParticleFlow.pfTracksFromL1Tracks_cfi") -process.productionSequence += process.pfTracksFromL1Tracks - -process.load("L1Trigger.Phase2L1ParticleFlow.l1ParticleFlow_cff") -process.productionSequence += process.l1ParticleFlow - -process.load('L1Trigger.L1CaloTrigger.Phase1L1TJets_cff') -process.productionSequence += process.Phase1L1TJetsSequence - ############################################################ # Generator-level (visible) hadronic taus ############################################################ @@ -156,8 +124,10 @@ ), outputCommands = cms.untracked.vstring( 'drop *_*_*_*', - 'keep *_l1pfCandidates_PF_*', - 'keep *_l1pfCandidates_Puppi_*', + 'keep *_l1ctLayer1_PF_*', + 'keep *_l1ctLayer1_Puppi_*', + #'keep *_l1pfCandidates_PF_*', + #'keep *_l1pfCandidates_Puppi_*', 'keep *_l1pfProducer*_z0_*', 'keep *_pfTracksFromL1Tracks*_*_*', 'keep *_pfClustersFrom*_*_*', diff --git a/L1Trigger/TrackFindingTMTT/test/PlotEtaSectors.C b/L1Trigger/TrackFindingTMTT/test/PlotEtaSectors.C index 8a7303811562a..3643dcf0072cf 100644 --- a/L1Trigger/TrackFindingTMTT/test/PlotEtaSectors.C +++ b/L1Trigger/TrackFindingTMTT/test/PlotEtaSectors.C @@ -121,12 +121,12 @@ float zPeriphNeg = -beamLen + (z + beamLen) * (rPeriphNeg / chosenR); float zPeriphPos = beamLen + (z - beamLen) * (rPeriphNeg / chosenR); // Now check if actual exit through endcap. - if (fabs(zPeriphNeg) > trkLength) { + if (std::abs(zPeriphNeg) > trkLength) { int whichEndcap = (zPeriphNeg + beamLen > 0) ? 1 : -1; zPeriphNeg = whichEndcap * trkLength; rPeriphNeg = chosenR * (zPeriphNeg + beamLen) / (z + beamLen); } - if (fabs(zPeriphPos) > trkLength) { + if (std::abs(zPeriphPos) > trkLength) { int whichEndcap = (zPeriphPos - beamLen > 0) ? 1 : -1; zPeriphPos = whichEndcap * trkLength; rPeriphPos = chosenR * (zPeriphPos - beamLen) / (z - beamLen); diff --git a/L1Trigger/TrackFindingTracklet/src/TrackletConfigBuilder.cc b/L1Trigger/TrackFindingTracklet/src/TrackletConfigBuilder.cc index 0aa1a837f8bdd..2e9d4123eddeb 100644 --- a/L1Trigger/TrackFindingTracklet/src/TrackletConfigBuilder.cc +++ b/L1Trigger/TrackFindingTracklet/src/TrackletConfigBuilder.cc @@ -238,8 +238,8 @@ void TrackletConfigBuilder::buildProjections() { double TrackletConfigBuilder::phi(double r1, double phi1, double r2, double phi2, double r) { double rhoinv = rinv(r1, phi1, r2, phi2); - if (fabs(rhoinv) > rinvmax_) { - rhoinv = rinvmax_ * rhoinv / fabs(rhoinv); + if (std::abs(rhoinv) > rinvmax_) { + rhoinv = rinvmax_ * rhoinv / std::abs(rhoinv); } return phi1 + asin(0.5 * r * rhoinv) - asin(0.5 * r1 * rhoinv); } diff --git a/L1Trigger/TrackFindingTracklet/test/fpga.cc b/L1Trigger/TrackFindingTracklet/test/fpga.cc index 69736de2f3adf..12c39e8cdc8ce 100644 --- a/L1Trigger/TrackFindingTracklet/test/fpga.cc +++ b/L1Trigger/TrackFindingTracklet/test/fpga.cc @@ -226,9 +226,9 @@ int main(const int argc, const char **argv) { L1SimTrack simtrack = ev.simtrack(isimtrack); if (simtrack.pt() < 2.0) continue; - if (fabs(simtrack.eta()) > 2.4) + if (std::abs(simtrack.eta()) > 2.4) continue; - if (fabs(simtrack.vz()) > 15.0) + if (std::abs(simtrack.vz()) > 15.0) continue; if (hypot(simtrack.vx(), simtrack.vy()) > 0.1) continue; diff --git a/L1Trigger/TrackTrigger/src/StubPtConsistency.cc b/L1Trigger/TrackTrigger/src/StubPtConsistency.cc index 7ae8a0af168a4..f7b1c9797436f 100644 --- a/L1Trigger/TrackTrigger/src/StubPtConsistency.cc +++ b/L1Trigger/TrackTrigger/src/StubPtConsistency.cc @@ -58,11 +58,11 @@ namespace StubPtConsistency { float intercept = 0.504148; float correction; if (tiltedBarrel) - correction = gradient * fabs(stub_z) / stub_r + intercept; + correction = gradient * std::abs(stub_z) / stub_r + intercept; else if (isBarrel) correction = 1; else - correction = fabs(stub_z) / stub_r; + correction = std::abs(stub_z) / stub_r; float stubBend = stubRef->bendFE(); if (!isBarrel && stub_z < 0.0) diff --git a/L1Trigger/VertexFinder/BuildFile.xml b/L1Trigger/VertexFinder/BuildFile.xml index 82b4a81c0ce38..2ee9f1b116ce8 100644 --- a/L1Trigger/VertexFinder/BuildFile.xml +++ b/L1Trigger/VertexFinder/BuildFile.xml @@ -1,3 +1,4 @@ + diff --git a/L1Trigger/VertexFinder/interface/AlgoSettings.h b/L1Trigger/VertexFinder/interface/AlgoSettings.h index 5d24dc2ad65dd..b3fb487c2765d 100644 --- a/L1Trigger/VertexFinder/interface/AlgoSettings.h +++ b/L1Trigger/VertexFinder/interface/AlgoSettings.h @@ -10,17 +10,20 @@ namespace l1tVertexFinder { enum class Algorithm { - FastHisto, - FastHistoLooseAssociation, + fastHisto, + fastHistoEmulation, + fastHistoLooseAssociation, GapClustering, - AgglomerativeHierarchical, + agglomerativeHierarchical, DBSCAN, PVR, - AdaptiveVertexReconstruction, + adaptiveVertexReconstruction, HPV, Kmeans }; + enum class Precision { Simulation, Emulation }; + class AlgoSettings { public: AlgoSettings(const edm::ParameterSet& iConfig); @@ -29,7 +32,8 @@ namespace l1tVertexFinder { //=== Vertex Reconstruction configuration // Vertex Reconstruction algo Algorithm vx_algo() const { return vx_algo_; } - /// For Agglomerative cluster algorithm, select a definition of distance between clusters + Precision vx_precision() const { return vx_precision_; } + // For agglomerative cluster algorithm, select a definition of distance between clusters unsigned int vx_distanceType() const { return vx_distanceType_; } // Assumed Vertex Distance float vx_distance() const { return vx_distance_; } @@ -39,21 +43,23 @@ namespace l1tVertexFinder { unsigned int vx_minTracks() const { return vx_minTracks_; } // Compute the z0 position of the vertex with a mean weighted with track momenta unsigned int vx_weightedmean() const { return vx_weightedmean_; } - /// Chi2 cut for the Adaptive Vertex Recostruction Algorithm + // Chi2 cut for the adaptive Vertex Recostruction Algorithm float vx_chi2cut() const { return vx_chi2cut_; } - /// Window size of the sliding window + // Do track quality cuts in emulation algorithms + bool vx_DoQualityCuts() const { return vx_DoQualityCuts_; } + // Window size of the sliding window unsigned int vx_windowSize() const { return vx_windowSize_; } - /// FastHisto histogram parameters (min, max, width) + // fastHisto histogram parameters (min, max, width) std::vector vx_histogram_parameters() const { return vx_histogram_parameters_; } double vx_histogram_min() const { return vx_histogram_parameters_.at(0); } double vx_histogram_max() const { return vx_histogram_parameters_.at(1); } double vx_histogram_binwidth() const { return vx_histogram_parameters_.at(2); } - /// FastHisto assumed vertex width + // fastHisto assumed vertex width float vx_width() const { return vx_width_; } - /// FastHisto track selection control + // fastHisto track selection control bool vx_DoPtComp() const { return vx_DoPtComp_; } bool vx_DoTightChi2() const { return vx_DoTightChi2_; } - /// Number of vertices to return for FastHisto + // Number of vertices to return for fastHisto unsigned int vx_nvtx() const { return vx_nvtx_; } float vx_dbscan_pt() const { return vx_dbscan_pt_; } unsigned int vx_dbscan_mintracks() const { return vx_dbscan_mintracks_; } @@ -82,18 +88,21 @@ namespace l1tVertexFinder { private: static const std::map algoNameMap; + static const std::map algoPrecisionMap; // Parameter sets for differents types of configuration parameter. edm::ParameterSet vertex_; // Vertex Reconstruction configuration Algorithm vx_algo_; + Precision vx_precision_; float vx_distance_; float vx_resolution_; unsigned int vx_distanceType_; unsigned int vx_minTracks_; unsigned int vx_weightedmean_; float vx_chi2cut_; + bool vx_DoQualityCuts_; bool vx_DoPtComp_; bool vx_DoTightChi2_; std::vector vx_histogram_parameters_; diff --git a/L1Trigger/VertexFinder/interface/RecoVertex.h b/L1Trigger/VertexFinder/interface/RecoVertex.h index ca27deb3d5292..801b45124aba0 100644 --- a/L1Trigger/VertexFinder/interface/RecoVertex.h +++ b/L1Trigger/VertexFinder/interface/RecoVertex.h @@ -69,6 +69,8 @@ namespace l1tVertexFinder { unsigned int nHighPt = -999, double highestPt = -999., bool pv = false); + /// Get the equivalent l1t::Vertex + l1t::Vertex vertex() const; /// Vertex z0 position [cm] double z0() const { return z0_; } /// Vertex z0 width [cm] @@ -151,6 +153,16 @@ namespace l1tVertexFinder { pv_ = pv; } + template + l1t::Vertex RecoVertex::vertex() const { + std::vector> tracks; + tracks.reserve(tracks_.size()); + for (const auto& t : tracks_) { + tracks.push_back(t->getTTTrackPtr()); + } + return l1t::Vertex(pT_, z0_, tracks); + } + // Template specializations template <> RecoVertexWithTP& RecoVertexWithTP::operator+=(const RecoVertexWithTP& rhs); diff --git a/L1Trigger/VertexFinder/interface/VertexFinder.h b/L1Trigger/VertexFinder/interface/VertexFinder.h index 7218c2c5ef3fd..58b6de952c627 100644 --- a/L1Trigger/VertexFinder/interface/VertexFinder.h +++ b/L1Trigger/VertexFinder/interface/VertexFinder.h @@ -2,19 +2,24 @@ #define __L1Trigger_VertexFinder_VertexFinder_h__ #include "DataFormats/Common/interface/Ptr.h" +#include "DataFormats/L1TrackTrigger/interface/TTTrack.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" #include "DataFormats/Math/interface/deltaPhi.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "L1Trigger/VertexFinder/interface/AlgoSettings.h" #include "L1Trigger/VertexFinder/interface/RecoVertex.h" #include +#include #include #include namespace l1tVertexFinder { + // Returns the number of bits needed to represent and integer decimal + static constexpr unsigned BitsToRepresent(unsigned x) { return x < 2 ? 1 : 1 + BitsToRepresent(x >> 1); } + typedef std::vector FitTrackCollection; typedef std::vector> RecoVertexCollection; @@ -40,20 +45,27 @@ namespace l1tVertexFinder { /// Accessors + /// Storage for tracks out of the L1 Track finder + const FitTrackCollection& fitTracks() const { return fitTracks_; } /// Number of iterations - unsigned int IterationsPerTrack() const { return double(iterations_) / double(fitTracks_.size()); } + unsigned int iterationsPerTrack() const { return double(iterations_) / double(fitTracks_.size()); } /// Storage for tracks out of the L1 Track finder unsigned int numInputTracks() const { return fitTracks_.size(); } /// Number of iterations - unsigned int NumIterations() const { return iterations_; } + unsigned int numIterations() const { return iterations_; } /// Number of reconstructed vertices unsigned int numVertices() const { return vertices_.size(); } - /// Reconstructed Primary Vertex - RecoVertex<> primaryVertex() const { - if (pv_index_ < vertices_.size()) + /// Number of emulation vertices + unsigned int numVerticesEmulation() const { return verticesEmulation_.size(); } + /// Reconstructed primary vertex + template + T PrimaryVertex() const { + if ((settings_->vx_precision() == Precision::Simulation) && (pv_index_ < vertices_.size())) return vertices_[pv_index_]; + else if ((settings_->vx_precision() == Precision::Emulation) && (pv_index_ < vertices_.size())) + return verticesEmulation_[pv_index_]; else { - edm::LogWarning("VertexFinder") << "PrimaryVertex::No Primary Vertex has been found."; + edm::LogWarning("VertexFinder") << "PrimaryVertex::No primary vertex has been found."; return RecoVertex<>(); } } @@ -61,8 +73,8 @@ namespace l1tVertexFinder { unsigned int primaryVertexId() const { return pv_index_; } /// Returns the z positions of the reconstructed primary vertices const std::vector>& vertices() const { return vertices_; } - /// Storage for tracks out of the L1 Track finder - const FitTrackCollection& fitTracks() const { return fitTracks_; } + /// Returns the emulation primary vertices + const l1t::VertexWordCollection& verticesEmulation() const { return verticesEmulation_; } /// Find the primary vertex void findPrimaryVertex(); @@ -86,22 +98,23 @@ namespace l1tVertexFinder { void fastHistoLooseAssociation(); /// Histogramming algorithm void fastHisto(const TrackerTopology* tTopo); + /// Histogramming algorithm (emulation) + void fastHistoEmulation(); + /// Sort vertices in pT - void SortVerticesInPt() { - std::sort(vertices_.begin(), vertices_.end(), [](const RecoVertex<>& vertex0, const RecoVertex<>& vertex1) { - return (vertex0.pt() > vertex1.pt()); - }); - } + void sortVerticesInPt(); /// Sort vertices in z - void SortVerticesInZ0() { - std::sort(vertices_.begin(), vertices_.end(), [](const RecoVertex<>& vertex0, const RecoVertex<>& vertex1) { - return (vertex0.z0() < vertex1.z0()); - }); - } - /// Number of iterations - unsigned int numIterations() const { return iterations_; } - /// Number of iterations - unsigned int iterationsPerTrack() const { return double(iterations_) / double(fitTracks_.size()); } + void sortVerticesInZ0(); + + /// Print an ASCII histogram + template + void printHistogram(stream_type& stream, + std::vector data, + int width = 80, + int minimum = 0, + int maximum = -1, + std::string title = "", + std::string color = ""); template void strided_iota(ForwardIterator first, ForwardIterator last, T value, T stride) { @@ -113,38 +126,23 @@ namespace l1tVertexFinder { /// Vertexing algorithms - /// Adaptive Vertex Reconstruction algorithm - void AdaptiveVertexReconstruction(); - /// Simple Merge Algorithm - void AgglomerativeHierarchicalClustering(); - /// Find distance between centres of two clusters - float CentralDistance(RecoVertex<> cluster0, RecoVertex<> cluster1); /// Compute the vertex parameters void computeAndSetVertexParameters(RecoVertex<>& vertex, const std::vector& bin_centers, const std::vector& counts); /// DBSCAN algorithm void DBSCAN(); - /// TDR histogramming algorithmn - void FastHistoLooseAssociation(); - /// Histogramming algorithm - void FastHisto(const TrackerTopology* tTopo); /// High pT Vertex Algorithm void HPV(); /// Kmeans Algorithm void Kmeans(); /// Find maximum distance in two clusters of tracks - float MaxDistance(RecoVertex<> cluster0, RecoVertex<> cluster1); - /// Find minimum distance in two clusters of tracks - float MinDistance(RecoVertex<> cluster0, RecoVertex<> cluster1); - /// Find average distance in two clusters of tracks - float MeanDistance(RecoVertex<> cluster0, RecoVertex<> cluster1); - /// Principal Vertex Reconstructor algorithm void PVR(); private: const AlgoSettings* settings_; - std::vector> vertices_; + RecoVertexCollection vertices_; + l1t::VertexWordCollection verticesEmulation_; unsigned int numMatchedVertices_; FitTrackCollection fitTracks_; unsigned int pv_index_; diff --git a/L1Trigger/VertexFinder/interface/VertexProducer.h b/L1Trigger/VertexFinder/interface/VertexProducer.h index 8b9abac9a5fe6..f9d683ff0334a 100644 --- a/L1Trigger/VertexFinder/interface/VertexProducer.h +++ b/L1Trigger/VertexFinder/interface/VertexProducer.h @@ -3,6 +3,8 @@ #include "DataFormats/L1Trigger/interface/Vertex.h" #include "FWCore/Framework/interface/global/EDProducer.h" +#include "DataFormats/L1TrackTrigger/interface/TTTypes.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" #include "FWCore/Framework/interface/global/EDProducer.h" #include "FWCore/Framework/interface/Event.h" @@ -13,6 +15,7 @@ #include "Geometry/Records/interface/TrackerTopologyRcd.h" #include "L1Trigger/VertexFinder/interface/AlgoSettings.h" #include "L1Trigger/VertexFinder/interface/RecoVertex.h" +#include "L1Trigger/VertexFinder/interface/VertexFinder.h" #include #include @@ -36,7 +39,7 @@ class VertexProducer : public edm::global::EDProducer<> { private: const edm::EDGetTokenT l1TracksToken_; - const edm::ESGetToken trackerTopologyToken_; + const edm::ESGetToken tTopoToken; const std::string outputCollectionName_; l1tVertexFinder::AlgoSettings settings_; diff --git a/L1Trigger/VertexFinder/plugins/TPStubValueMapProducer.cc b/L1Trigger/VertexFinder/plugins/TPStubValueMapProducer.cc index e799bd734c16a..408564410affb 100644 --- a/L1Trigger/VertexFinder/plugins/TPStubValueMapProducer.cc +++ b/L1Trigger/VertexFinder/plugins/TPStubValueMapProducer.cc @@ -77,7 +77,6 @@ class TPStubValueMapProducer : public edm::global::EDProducer<> { const edm::EDGetTokenT stubToken_; const edm::EDGetTokenT stubTruthToken_; const edm::EDGetTokenT clusterTruthToken_; - edm::ESGetToken tTopoToken_; edm::ESGetToken tGeomToken_; }; diff --git a/L1Trigger/VertexFinder/plugins/VertexNTupler.cc b/L1Trigger/VertexFinder/plugins/VertexNTupler.cc index 822e2c269fcee..aa9f6ba047b08 100644 --- a/L1Trigger/VertexFinder/plugins/VertexNTupler.cc +++ b/L1Trigger/VertexFinder/plugins/VertexNTupler.cc @@ -5,12 +5,12 @@ #include "DataFormats/HepMCCandidate/interface/GenParticle.h" #include "DataFormats/L1TrackTrigger/interface/TTTypes.h" #include "DataFormats/L1Trigger/interface/Vertex.h" +#include "DataFormats/L1Trigger/interface/VertexWord.h" #include "DataFormats/JetReco/interface/GenJet.h" #include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" -#include "FWCore/Framework/interface/EDAnalyzer.h" +#include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/MakerMacros.h" -#include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -40,12 +40,24 @@ using namespace std; namespace l1tVertexFinder { - class VertexNTupler : public edm::EDAnalyzer { + class VertexNTupler : public edm::one::EDAnalyzer { public: explicit VertexNTupler(const edm::ParameterSet&); ~VertexNTupler() override; private: + struct EmulationVerticesBranchData { + std::vector numTracks; + std::vector z0; + std::vector sumPt; + + void clear() { + numTracks.clear(); + z0.clear(); + sumPt.clear(); + } + }; + struct GenJetsBranchData { std::vector energy; std::vector pt; @@ -78,11 +90,8 @@ namespace l1tVertexFinder { } }; - struct RecoVerticesBranchData { - std::vector numTracks; + struct RecoVerticesBranchData : public EmulationVerticesBranchData { std::vector> trackIdxs; - std::vector z0; - std::vector sumPt; void clear() { numTracks.clear(); @@ -166,7 +175,7 @@ namespace l1tVertexFinder { std::map> l1TracksTokenMap_; std::map>> l1TracksMapTokenMap_; std::map>> l1VerticesTokenMap_; - std::map>> l1VerticesExtraTokenMap_; + std::map>> l1VerticesEmulationTokenMap_; std::vector>> l1VerticesExtraTokens_; TTree* outputTree_; @@ -176,8 +185,6 @@ namespace l1tVertexFinder { // storage class for configuration parameters AnalysisSettings settings_; - //edm::Service fs_; - // Histograms for Vertex Reconstruction float numTrueInteractions_, hepMCVtxZ0_, genVtxZ0_; @@ -191,18 +198,12 @@ namespace l1tVertexFinder { std::map l1TracksBranchData_; std::map l1VerticesBranchData_; std::map l1VerticesInputMap_; - - std::unordered_map> l1Vertices_branchMap_numTracks_; - std::unordered_map> l1Vertices_branchMap_z0_; - std::unordered_map> l1Vertices_branchMap_z0_etaWeighted_; - std::unordered_map> l1Vertices_branchMap_sumPt_; + std::map l1VerticesEmulationBranchData_; std::vector> l1Vertices_extra_numTracks_; std::vector> l1Vertices_extra_z0_; std::vector> l1Vertices_extra_z0_etaWeighted_; std::vector> l1Vertices_extra_sumPt_; - - bool available_; // ROOT file for histograms is open. }; VertexNTupler::VertexNTupler(const edm::ParameterSet& iConfig) @@ -215,7 +216,6 @@ namespace l1tVertexFinder { consumes>(iConfig.getParameter("l1TracksTPInputTags"))), vTPsToken_(consumes>( iConfig.getParameter("l1TracksTPValueMapInputTags"))), - //outputTree_(fs_->make("l1VertexReco", "L1 vertex-related info")), printResults_(iConfig.getParameter("printResults")), settings_(iConfig) { const std::vector trackBranchNames( @@ -225,13 +225,6 @@ namespace l1tVertexFinder { const std::vector trackMapInputTags( iConfig.getParameter>("l1TracksTruthMapInputTags")); - edm::Service fs_; - available_ = fs_.isAvailable(); - if (not available_) - return; // No ROOT file open. - - outputTree_ = fs_->make("l1VertexReco", "L1 vertex-related info"); - if (trackBranchNames.size() != trackInputTags.size()) throw cms::Exception("The number of track branch names (" + std::to_string(trackBranchNames.size()) + ") specified in the config does not match the number of input tags (" + @@ -258,6 +251,32 @@ namespace l1tVertexFinder { ") specified in the config does not match the number of associated input track collection names (" + std::to_string(vertexTrackNames.size()) + ")"); + const std::vector emulationVertexBranchNames( + iConfig.getParameter>("emulationVertexBranchNames")); + const std::vector emulationVertexInputTags( + iConfig.getParameter>("emulationVertexInputTags")); + + const std::vector extraVertexInputTags( + iConfig.getParameter>("extraL1VertexInputTags")); + const std::vector extraVertexDescriptions( + iConfig.getParameter>("extraL1VertexDescriptions")); + + usesResource(TFileService::kSharedResource); + edm::Service fs; + outputTree_ = fs->make("l1VertexReco", "L1 vertex-related info"); + + std::vector::const_iterator branchNameIt = emulationVertexBranchNames.begin(); + std::vector::const_iterator inputTagIt = emulationVertexInputTags.begin(); + for (; branchNameIt != emulationVertexBranchNames.end(); branchNameIt++, inputTagIt++) { + l1VerticesEmulationTokenMap_[*branchNameIt] = consumes>(*inputTagIt); + l1VerticesEmulationBranchData_[*branchNameIt] = EmulationVerticesBranchData(); + EmulationVerticesBranchData& branchData = l1VerticesEmulationBranchData_.at(*branchNameIt); + + outputTree_->Branch(("emulationVertices_" + *branchNameIt + "_numTracks").c_str(), &branchData.numTracks); + outputTree_->Branch(("emulationVertices_" + *branchNameIt + "_z0").c_str(), &branchData.z0); + outputTree_->Branch(("emulationVertices_" + *branchNameIt + "_sumPt").c_str(), &branchData.sumPt); + } + outputTree_->Branch("genJets_energy", &genJetsBranchData_.energy); outputTree_->Branch("genJets_pt", &genJetsBranchData_.pt); outputTree_->Branch("genJets_eta", &genJetsBranchData_.eta); @@ -302,12 +321,11 @@ namespace l1tVertexFinder { &branchData.truthMapIsUnknown); } - std::vector::const_iterator branchNameIt = vertexBranchNames.begin(); - std::vector::const_iterator inputTagIt = vertexInputTags.begin(); + branchNameIt = vertexBranchNames.begin(); + inputTagIt = vertexInputTags.begin(); std::vector::const_iterator l1VertexTrackNameIt = vertexTrackNames.begin(); for (; branchNameIt != vertexBranchNames.end(); branchNameIt++, inputTagIt++, l1VertexTrackNameIt++) { l1VerticesTokenMap_[*branchNameIt] = consumes>(*inputTagIt); - l1VerticesBranchData_[*branchNameIt] = RecoVerticesBranchData(); RecoVerticesBranchData& branchData = l1VerticesBranchData_.at(*branchNameIt); l1VerticesInputMap_[*branchNameIt] = *l1VertexTrackNameIt; @@ -334,10 +352,6 @@ namespace l1tVertexFinder { outputTree_->Branch("trueTracks_useForAlgEff", &trueTracksBranchData_.useForAlgEff); outputTree_->Branch("trueTracks_useForVtxReco", &trueTracksBranchData_.useForVertexReco); - const std::vector extraVertexInputTags( - iConfig.getParameter>("extraL1VertexInputTags")); - const std::vector extraVertexDescriptions( - iConfig.getParameter>("extraL1VertexDescriptions")); for (const auto& inputTag : extraVertexInputTags) l1VerticesExtraTokens_.push_back(consumes>(inputTag)); TObjArray* descriptionArray = new TObjArray(); @@ -581,6 +595,31 @@ namespace l1tVertexFinder { } } + // Emulation vertex branches + for (const auto& tokenMapEntry : l1VerticesEmulationTokenMap_) { + EmulationVerticesBranchData& branchData = l1VerticesEmulationBranchData_.at(tokenMapEntry.first); + branchData.clear(); + + edm::Handle> handle; + iEvent.getByToken(tokenMapEntry.second, handle); + for (const auto& vtx : *handle) { + branchData.numTracks.push_back(vtx.multiplicity()); + branchData.z0.push_back(vtx.z0()); + branchData.sumPt.push_back(vtx.pt()); + } + + if (printResults_) { + edm::LogInfo("VertexNTupler") << "analyze::" << handle->size() << " '" << tokenMapEntry.first + << "' vertices were found ... "; + for (const auto& vtx : *handle) { + edm::LogInfo("VertexNTupler") << "analyze::" + << " * z0 = " << vtx.z0() << "; contains " << vtx.multiplicity() + << " tracks ..."; + } + } + } + + // Extra vertex collections l1Vertices_extra_numTracks_.resize(l1VerticesExtraTokens_.size()); l1Vertices_extra_z0_.resize(l1VerticesExtraTokens_.size()); l1Vertices_extra_z0_etaWeighted_.resize(l1VerticesExtraTokens_.size()); diff --git a/L1Trigger/VertexFinder/plugins/VertexProducer.cc b/L1Trigger/VertexFinder/plugins/VertexProducer.cc index 3499dca617841..3fe3288bf9dd2 100644 --- a/L1Trigger/VertexFinder/plugins/VertexProducer.cc +++ b/L1Trigger/VertexFinder/plugins/VertexProducer.cc @@ -18,23 +18,27 @@ using namespace std; VertexProducer::VertexProducer(const edm::ParameterSet& iConfig) : l1TracksToken_(consumes(iConfig.getParameter("l1TracksInputTag"))), - trackerTopologyToken_(esConsumes()), + tTopoToken(esConsumes()), outputCollectionName_(iConfig.getParameter("l1VertexCollectionName")), settings_(AlgoSettings(iConfig)) { // Get configuration parameters switch (settings_.vx_algo()) { - case Algorithm::FastHisto: - edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using the FastHisto binning algorithm"; + case Algorithm::fastHisto: + edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using the fastHisto binning algorithm"; break; - case Algorithm::FastHistoLooseAssociation: + case Algorithm::fastHistoEmulation: edm::LogInfo("VertexProducer") - << "VertexProducer::Finding vertices using the FastHistoLooseAssociation binning algorithm"; + << "VertexProducer::Finding vertices using the emulation version of the fastHisto binning algorithm"; + break; + case Algorithm::fastHistoLooseAssociation: + edm::LogInfo("VertexProducer") + << "VertexProducer::Finding vertices using the fastHistoLooseAssociation binning algorithm"; break; case Algorithm::GapClustering: edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using a gap clustering algorithm"; break; - case Algorithm::AgglomerativeHierarchical: + case Algorithm::agglomerativeHierarchical: edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using a Simple Merge Clustering algorithm"; break; case Algorithm::DBSCAN: @@ -43,7 +47,7 @@ VertexProducer::VertexProducer(const edm::ParameterSet& iConfig) case Algorithm::PVR: edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using a PVR algorithm"; break; - case Algorithm::AdaptiveVertexReconstruction: + case Algorithm::adaptiveVertexReconstruction: edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using an AdaptiveVertexReconstruction algorithm"; break; @@ -56,7 +60,11 @@ VertexProducer::VertexProducer(const edm::ParameterSet& iConfig) } //--- Define EDM output to be written to file (if required) - produces(outputCollectionName_); + if (settings_.vx_algo() == Algorithm::fastHistoEmulation) { + produces(outputCollectionName_ + "Emulation"); + } else { + produces(outputCollectionName_); + } } void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const { @@ -65,31 +73,46 @@ void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Event std::vector l1Tracks; l1Tracks.reserve(l1TracksHandle->size()); + if (settings_.debug() > 1) { + edm::LogInfo("VertexProducer") << "produce::Processing " << l1TracksHandle->size() << " tracks"; + } for (const auto& track : l1TracksHandle->ptrs()) { auto l1track = L1Track(track); // Check the minimum pT of the tracks // This is left here because it represents the smallest pT to be sent by the track finding boards // This has less to do with the algorithms than the constraints of what will be sent to the vertexing algorithm - if (l1track.pt() > settings_.vx_TrackMinPt()) { + if (l1track.pt() >= settings_.vx_TrackMinPt()) { l1Tracks.push_back(l1track); + } else { + if (settings_.debug() > 2) { + edm::LogInfo("VertexProducer") << "produce::Removing track with too low of a pt (" << l1track.pt() << ")\n" + << " word = " << l1track.getTTTrackPtr()->getTrackWord().to_string(2); + } } } + if (settings_.debug() > 1) { + edm::LogInfo("VertexProducer") << "produce::Processing " << l1Tracks.size() << " tracks after minimum pt cut of" + << settings_.vx_TrackMinPt() << " GeV"; + } VertexFinder vf(l1Tracks, settings_); switch (settings_.vx_algo()) { - case Algorithm::FastHisto: { - edm::ESHandle tTopoHandle = iSetup.getHandle(trackerTopologyToken_); - vf.fastHisto(tTopoHandle.product()); + case Algorithm::fastHisto: { + const TrackerTopology& tTopo = iSetup.getData(tTopoToken); + vf.fastHisto(&tTopo); break; } - case Algorithm::FastHistoLooseAssociation: + case Algorithm::fastHistoEmulation: + vf.fastHistoEmulation(); + break; + case Algorithm::fastHistoLooseAssociation: vf.fastHistoLooseAssociation(); break; case Algorithm::GapClustering: vf.GapClustering(); break; - case Algorithm::AgglomerativeHierarchical: + case Algorithm::agglomerativeHierarchical: vf.agglomerativeHierarchicalClustering(); break; case Algorithm::DBSCAN: @@ -98,7 +121,7 @@ void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Event case Algorithm::PVR: vf.PVR(); break; - case Algorithm::AdaptiveVertexReconstruction: + case Algorithm::adaptiveVertexReconstruction: vf.adaptiveVertexReconstruction(); break; case Algorithm::HPV: @@ -109,20 +132,20 @@ void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Event break; } - vf.SortVerticesInPt(); + vf.sortVerticesInPt(); vf.findPrimaryVertex(); // //=== Store output EDM track and hardware stub collections. - std::unique_ptr lProduct(new std::vector()); - - for (const auto& vtx : vf.vertices()) { - std::vector> lVtxTracks; - lVtxTracks.reserve(vtx.tracks().size()); - for (const auto& t : vtx.tracks()) - lVtxTracks.push_back(t->getTTTrackPtr()); - lProduct->emplace_back(l1t::Vertex(vtx.pt(), vtx.z0(), lVtxTracks)); + if (settings_.vx_algo() == Algorithm::fastHistoEmulation) { + std::unique_ptr product_emulation = + std::make_unique(vf.verticesEmulation().begin(), vf.verticesEmulation().end()); + iEvent.put(std::move(product_emulation), outputCollectionName_ + "Emulation"); + } else { + std::unique_ptr product(new std::vector()); + for (const auto& vtx : vf.vertices()) { + product->emplace_back(vtx.vertex()); + } + iEvent.put(std::move(product), outputCollectionName_); } - iEvent.put(std::move(lProduct), outputCollectionName_); } - DEFINE_FWK_MODULE(VertexProducer); diff --git a/L1Trigger/VertexFinder/python/VertexNTupler_cff.py b/L1Trigger/VertexFinder/python/VertexNTupler_cff.py index 3e2bd18f499f3..185fa67d775d4 100644 --- a/L1Trigger/VertexFinder/python/VertexNTupler_cff.py +++ b/L1Trigger/VertexFinder/python/VertexNTupler_cff.py @@ -11,7 +11,9 @@ l1TracksBranchNames = cms.vstring('hybrid'), l1VertexInputTags = cms.VInputTag( cms.InputTag("VertexProducer", VertexProducer.l1VertexCollectionName.value()) ), l1VertexTrackInputs = cms.vstring('hybrid'), - l1VertexBranchNames = cms.vstring('FastHisto'), + l1VertexBranchNames = cms.vstring('fastHisto'), + emulationVertexInputTags = cms.VInputTag(), + emulationVertexBranchNames = cms.vstring(), extraL1VertexInputTags = cms.VInputTag(), extraL1VertexDescriptions = cms.vstring(), diff --git a/L1Trigger/VertexFinder/python/VertexProducer_cff.py b/L1Trigger/VertexFinder/python/VertexProducer_cff.py index de410f32adb36..4a9e614abf5cc 100644 --- a/L1Trigger/VertexFinder/python/VertexProducer_cff.py +++ b/L1Trigger/VertexFinder/python/VertexProducer_cff.py @@ -9,7 +9,7 @@ # === Vertex Reconstruction configuration VertexReconstruction = cms.PSet( # Vertex Reconstruction Algorithm - Algorithm = cms.string("FastHisto"), + Algorithm = cms.string("fastHisto"), # Vertex distance [cm] VertexDistance = cms.double(.15), # Assumed Vertex Resolution [cm] @@ -25,18 +25,22 @@ WeightedMean = cms.uint32(1), # Chi2 cut for the Adaptive Vertex Reconstruction Algorithm AVR_chi2cut = cms.double(5.), + # Do track quality cuts in emulation algorithms + EM_DoQualityCuts = cms.bool(False), # Track-stubs Pt compatibility cut FH_DoPtComp = cms.bool(True), # chi2dof < 5 for tracks with Pt > 10 FH_DoTightChi2 = cms.bool(False), - # FastHisto algorithm histogram parameters (min,max,width) [cm] + # fastHisto algorithm histogram parameters (min,max,width) [cm] # TDR settings: [-14.95, 15.0, 0.1] # L1TkPrimaryVertexProducer: [-30.0, 30.0, 0.09983361065] - # Firmware: [-14.4, 14.4, 0.4] - FH_HistogramParameters = cms.vdouble(-30.0, 30.0, 0.09983361065), + # HLS Firmware: [-14.4, 14.4, 0.4] + # Track word limits (128 binns): [-20.46921512, 20.46921512, 0.31983148625] + # Track word limits (256 binns): [-20.46921512, 20.46921512, 0.159915743125] + FH_HistogramParameters = cms.vdouble(-20.46921512, 20.46921512, 0.31983148625), # The number of vertixes to return (i.e. N windows with the highest combined pT) FH_NVtx = cms.uint32(10), - # FastHisto algorithm assumed vertex half-width [cm] + # fastHisto algorithm assumed vertex half-width [cm] FH_VertexWidth = cms.double(.15), # Window size of the sliding window FH_WindowSize = cms.uint32(3), @@ -51,13 +55,13 @@ # Minimum pt of tracks used to create vertex [GeV] VxMinTrackPt = cms.double(2.0), # Maximum pt of tracks used to create vertex [GeV] - VxMaxTrackPt = cms.double(50.0), + VxMaxTrackPt = cms.double(127.0), # When the track pt > VxMaxTrackPt, how should the tracks be considered # -1 = tracks are valid # 0 = tracks are mismeasured and ignored/truncated # 1 = tracks are mismeasured and saturate at VxMaxTrackPt # Option '0' was used for the TDR, but '1' is used for the firmware - VxMaxTrackPtBehavior = cms.int32(0), + VxMaxTrackPtBehavior = cms.int32(1), # Maximum chi2 of tracks used to create vertex VxMaxTrackChi2 = cms.double(100.), # Minimum number of stubs associated to a track diff --git a/L1Trigger/VertexFinder/src/AlgoSettings.cc b/L1Trigger/VertexFinder/src/AlgoSettings.cc index 52f5aa461ae79..f111a8bcbb63c 100644 --- a/L1Trigger/VertexFinder/src/AlgoSettings.cc +++ b/L1Trigger/VertexFinder/src/AlgoSettings.cc @@ -12,6 +12,7 @@ namespace l1tVertexFinder { vx_minTracks_(vertex_.getParameter("MinTracks")), vx_weightedmean_(vertex_.getParameter("WeightedMean")), vx_chi2cut_(vertex_.getParameter("AVR_chi2cut")), + vx_DoQualityCuts_(vertex_.getParameter("EM_DoQualityCuts")), vx_DoPtComp_(vertex_.getParameter("FH_DoPtComp")), vx_DoTightChi2_(vertex_.getParameter("FH_DoTightChi2")), vx_histogram_parameters_(vertex_.getParameter >("FH_HistogramParameters")), @@ -44,17 +45,37 @@ namespace l1tVertexFinder { throw cms::Exception("Invalid algo name '" + algoName + "' specified for L1T vertex producer. Valid algo names are: " + validAlgoNames.str()); } + + const auto algoPrecisionMapIt = algoPrecisionMap.find(vx_algo_); + if (algoPrecisionMapIt != algoPrecisionMap.end()) { + vx_precision_ = algoPrecisionMapIt->second; + } else { + throw cms::Exception("Unknown precision {Simulation, Emulation} for algo name " + algoName); + } } const std::map AlgoSettings::algoNameMap = { - {"FastHisto", Algorithm::FastHisto}, - {"FastHistoLooseAssociation", Algorithm::FastHistoLooseAssociation}, + {"fastHisto", Algorithm::fastHisto}, + {"fastHistoEmulation", Algorithm::fastHistoEmulation}, + {"fastHistoLooseAssociation", Algorithm::fastHistoLooseAssociation}, {"GapClustering", Algorithm::GapClustering}, - {"Agglomerative", Algorithm::AgglomerativeHierarchical}, + {"agglomerative", Algorithm::agglomerativeHierarchical}, {"DBSCAN", Algorithm::DBSCAN}, {"PVR", Algorithm::PVR}, - {"Adaptive", Algorithm::AdaptiveVertexReconstruction}, + {"adaptive", Algorithm::adaptiveVertexReconstruction}, {"HPV", Algorithm::HPV}, {"K-means", Algorithm::Kmeans}}; + const std::map AlgoSettings::algoPrecisionMap = { + {Algorithm::fastHisto, Precision::Simulation}, + {Algorithm::fastHistoEmulation, Precision::Emulation}, + {Algorithm::fastHistoLooseAssociation, Precision::Simulation}, + {Algorithm::GapClustering, Precision::Simulation}, + {Algorithm::agglomerativeHierarchical, Precision::Simulation}, + {Algorithm::DBSCAN, Precision::Simulation}, + {Algorithm::PVR, Precision::Simulation}, + {Algorithm::adaptiveVertexReconstruction, Precision::Simulation}, + {Algorithm::HPV, Precision::Simulation}, + {Algorithm::Kmeans, Precision::Simulation}}; + } // end namespace l1tVertexFinder diff --git a/L1Trigger/VertexFinder/src/InputData.cc b/L1Trigger/VertexFinder/src/InputData.cc index 46fd49c203a20..a0413b72b4908 100644 --- a/L1Trigger/VertexFinder/src/InputData.cc +++ b/L1Trigger/VertexFinder/src/InputData.cc @@ -85,7 +85,7 @@ namespace l1tVertexFinder { } else { genPt_PU_ += tp->pt(); } - if (settings.debug() > 0) { + if (settings.debug() > 2) { edm::LogInfo("InputData") << "InputData::genPt in the event " << genPt_; } @@ -113,7 +113,7 @@ namespace l1tVertexFinder { recoVertices_.push_back(vertex); } - if (settings.debug() > 0) + if (settings.debug() > 2) edm::LogInfo("InputData") << "InputData::" << vertices_.size() << " pileup vertices in the event, " << recoVertices_.size() << " reconstructable"; diff --git a/L1Trigger/VertexFinder/src/VertexFinder.cc b/L1Trigger/VertexFinder/src/VertexFinder.cc index 875d175d24219..ec67e766005df 100644 --- a/L1Trigger/VertexFinder/src/VertexFinder.cc +++ b/L1Trigger/VertexFinder/src/VertexFinder.cc @@ -8,7 +8,7 @@ namespace l1tVertexFinder { const std::vector& bin_centers, const std::vector& counts) { double pt = 0.; - double z0 = 0.; + double z0 = -999.; double z0width = 0.; bool highPt = false; double highestPt = 0.; @@ -25,6 +25,11 @@ namespace l1tVertexFinder { for (const L1Track* track : vertex.tracks()) { itrack++; trackPt = track->pt(); + + // Skip the bins with no tracks + while (ibin < counts.size() && counts[ibin] == 0) + ibin++; + if (trackPt > settings_->vx_TrackMaxPt()) { highPt = true; numHighPtTracks++; @@ -126,7 +131,7 @@ namespace l1tVertexFinder { sort(fitTracks_.begin(), fitTracks_.end(), SortTracksByZ0()); - std::vector> vClusters; + RecoVertexCollection vClusters; vClusters.resize(fitTracks_.size()); for (unsigned int i = 0; i < fitTracks_.size(); ++i) { @@ -438,14 +443,155 @@ namespace l1tVertexFinder { } void VertexFinder::findPrimaryVertex() { - double vertexPt = 0; - pv_index_ = 0; + if (settings_->vx_precision() == Precision::Emulation) { + pv_index_ = std::distance(verticesEmulation_.begin(), + std::max_element(verticesEmulation_.begin(), + verticesEmulation_.end(), + [](const l1t::VertexWord& vertex0, const l1t::VertexWord& vertex1) { + return (vertex0.pt() < vertex1.pt()); + })); + } else { + pv_index_ = std::distance( + vertices_.begin(), + std::max_element( + vertices_.begin(), vertices_.end(), [](const RecoVertex<>& vertex0, const RecoVertex<>& vertex1) { + return (vertex0.pt() < vertex1.pt()); + })); + } + } + + // Possible Formatting Codes: https://misc.flogisoft.com/bash/tip_colors_and_formatting + template + void VertexFinder::printHistogram(stream_type& stream, + std::vector data, + int width, + int minimum, + int maximum, + std::string title, + std::string color) { + int tableSize = data.size(); + + if (maximum == -1) { + maximum = float(*std::max_element(std::begin(data), std::end(data))) * 1.05; + } else if (maximum <= minimum) { + maximum = float(*std::max_element(std::begin(data), std::end(data))) * 1.05; + minimum = float(*std::min_element(std::begin(data), std::end(data))); + } + + if (minimum < 0) { + minimum *= 1.05; + } else { + minimum = 0; + } + + std::vector intervals(tableSize, ""); + std::vector values(tableSize, ""); + char buffer[128]; + int intervalswidth = 0, valueswidth = 0, tmpwidth = 0; + for (int i = 0; i < tableSize; i++) { + //Format the bin labels + tmpwidth = sprintf(buffer, "[%-.5g, %-.5g)", float(i), float(i + 1)); + intervals[i] = buffer; + if (i == (tableSize - 1)) { + intervals[i][intervals[i].size() - 1] = ']'; + } + if (tmpwidth > intervalswidth) + intervalswidth = tmpwidth; + + //Format the values + tmpwidth = sprintf(buffer, "%-.5g", float(data[i])); + values[i] = buffer; + if (tmpwidth > valueswidth) + valueswidth = tmpwidth; + } + + sprintf(buffer, "%-.5g", float(minimum)); + std::string minimumtext = buffer; + sprintf(buffer, "%-.5g", float(maximum)); + std::string maximumtext = buffer; + + int plotwidth = + std::max(int(minimumtext.size() + maximumtext.size()), width - (intervalswidth + 1 + valueswidth + 1 + 2)); + std::string scale = + minimumtext + std::string(plotwidth + 2 - minimumtext.size() - maximumtext.size(), ' ') + maximumtext; + + float norm = float(plotwidth) / float(maximum - minimum); + int zero = std::round((0.0 - minimum) * norm); + std::vector line(plotwidth, '-'); + + if ((minimum != 0) && (0 <= zero) && (zero < plotwidth)) { + line[zero] = '+'; + } + std::string capstone = + std::string(intervalswidth + 1 + valueswidth + 1, ' ') + "+" + std::string(line.begin(), line.end()) + "+"; + + std::vector out; + if (!title.empty()) { + out.push_back(title); + out.push_back(std::string(title.size(), '=')); + } + out.push_back(std::string(intervalswidth + valueswidth + 2, ' ') + scale); + out.push_back(capstone); + for (int i = 0; i < tableSize; i++) { + std::string interval = intervals[i]; + std::string value = values[i]; + data_type x = data[i]; + std::fill_n(line.begin(), plotwidth, ' '); + + int pos = std::round((float(x) - minimum) * norm); + if (x < 0) { + std::fill_n(line.begin() + pos, zero - pos, '*'); + } else { + std::fill_n(line.begin() + zero, pos - zero, '*'); + } - for (unsigned int i = 0; i < vertices_.size(); ++i) { - if (vertices_[i].pt() > vertexPt) { - vertexPt = vertices_[i].pt(); - pv_index_ = i; + if ((minimum != 0) && (0 <= zero) && (zero < plotwidth)) { + line[zero] = '|'; } + + sprintf(buffer, + "%-*s %-*s |%s|", + intervalswidth, + interval.c_str(), + valueswidth, + value.c_str(), + std::string(line.begin(), line.end()).c_str()); + out.push_back(buffer); + } + out.push_back(capstone); + if (!color.empty()) + stream << color; + for (const auto& o : out) { + stream << o << "\n"; + } + if (!color.empty()) + stream << "\e[0m"; + stream << "\n"; + } + + void VertexFinder::sortVerticesInPt() { + if (settings_->vx_precision() == Precision::Emulation) { + std::sort( + verticesEmulation_.begin(), + verticesEmulation_.end(), + [](const l1t::VertexWord& vertex0, const l1t::VertexWord& vertex1) { return (vertex0.pt() > vertex1.pt()); }); + } else { + std::sort(vertices_.begin(), vertices_.end(), [](const RecoVertex<>& vertex0, const RecoVertex<>& vertex1) { + return (vertex0.pt() > vertex1.pt()); + }); + } + } + + void VertexFinder::sortVerticesInZ0() { + if (settings_->vx_precision() == Precision::Emulation) { + std::sort( + verticesEmulation_.begin(), + verticesEmulation_.end(), + [](const l1t::VertexWord& vertex0, const l1t::VertexWord& vertex1) { return (vertex0.z0() < vertex1.z0()); }); + } else { + std::sort(vertices_.begin(), vertices_.end(), [](const RecoVertex<>& vertex0, const RecoVertex<>& vertex1) { + return (vertex0.z0() < vertex1.z0()); + }); } } @@ -552,8 +698,13 @@ namespace l1tVertexFinder { } // Assign the track to the correct vertex - auto upper_bound = std::lower_bound(bounds.begin(), bounds.end(), track.z0()); + // The values are ordered with bounds [lower, upper) + // Values below bounds.begin() return 0 as the index (underflow) + // Values above bounds.end() will return the index of the last bin (overflow) + auto upper_bound = std::upper_bound(bounds.begin(), bounds.end(), track.z0()); int index = std::distance(bounds.begin(), upper_bound) - 1; + if (index == -1) + index = 0; hist.at(index).insert(&track); } // end loop over tracks @@ -588,11 +739,335 @@ namespace l1tVertexFinder { imax = i; } } - found.push_back(imax); vertices_.emplace_back(sums.at(imax)); } pv_index_ = 0; + + if (settings_->debug() >= 1) { + edm::LogInfo log("VertexProducer"); + log << "fastHisto::Checking the output parameters ... \n"; + std::vector tmp; + std::transform(std::begin(sums), std::end(sums), std::back_inserter(tmp), [](const RecoVertex<>& v) -> double { + return v.pt(); + }); + printHistogram(log, tmp, 80, 0, -1, "fastHisto::sums", "\e[92m"); + for (unsigned int i = 0; i < found.size(); i++) { + log << "RecoVertex " << i << ": bin index = " << found[i] << "\tsumPt = " << sums.at(imax).pt() + << "\tz0 = " << sums.at(imax).z0(); + } + } } // end of fastHisto + void VertexFinder::fastHistoEmulation() { + // Relevant constants for the track word + enum TrackBitWidths { + kZ0Size = 12, // Width of z-position (40cm / 0.1) + kZ0MagSize = 5, // Width of z-position magnitude (signed) + kPtSize = 14, // Width of pt + kPtMagSize = 9, // Width of pt magnitude (unsigned) + kReducedPrecisionPt = 7, // Width of the reduced precision, integer only, pt + }; + + enum HistogramBitWidths { + kBinSize = 10, // Width of a single bin in z + kBinFixedSize = 7, // Width of a single z0 bin in fixed point representation + kBinFixedMagSize = 4, // Width (magnitude) of a single z0 bin in fixed point representation + kSlidingSumSize = 11, // Width of the sum of a window of bins + kInverseSize = 14, // Width of the inverse sum + kInverseMagSize = 1, // Width of the inverse sum magnitude (unsigned) + kWeightedSlidingSumSize = 20, // Width of the pT weighted sliding sum + kWeightedSlidingSumMagSize = 10, // Width of the pT weighted sliding sum magnitude (signed) + kWindowSize = 3, // Number of bins in the window used to sum histogram bins + kSumPtLinkSize = 9, // Number of bits used to represent the sum of track pts in a single bin from a single link + kSumPtWindowBits = BitsToRepresent(HistogramBitWidths::kWindowSize * (1 << HistogramBitWidths::kSumPtLinkSize)), + }; + + static constexpr unsigned int kTableSize = + ((1 << HistogramBitWidths::kSumPtLinkSize) - 1) * HistogramBitWidths::kWindowSize; + + typedef ap_ufixed pt_t; + // Same size as TTTrack_TrackWord::z0_t, but now taking into account the sign bit (i.e. 2's complement) + typedef ap_int z0_t; + // 7 bits chosen to represent values between [0,127] + // This is the next highest power of 2 value to our chosen track pt saturation value (100) + typedef ap_ufixed + track_pt_fixed_t; + // Histogram bin index + typedef ap_uint histbin_t; + // Histogram bin in fixed point representation, before truncation + typedef ap_ufixed + histbin_fixed_t; + // This value is slightly arbitrary, but small enough that the windows sums aren't too big. + typedef ap_ufixed + link_pt_sum_fixed_t; + // Enough bits to store HistogramBitWidths::kWindowSize * (2**HistogramBitWidths::kSumPtLinkSize) + typedef ap_ufixed + window_pt_sum_fixed_t; + // pt weighted sum of bins in window + typedef ap_fixed + zsliding_t; + // Sum of histogram bins in window + typedef ap_uint slidingsum_t; + // Inverse of sum of bins in a given window + typedef ap_ufixed + inverse_t; + + auto track_quality_check = [&](const track_pt_fixed_t& pt) -> bool { + // Track quality cuts + if (pt.to_double() < settings_->vx_TrackMinPt()) + return false; + return true; + }; + + auto fetch_bin = [&](const z0_t& z0, int nbins) -> std::pair { + // Increase the the number of bits in the word to allow for additional dynamic range + ap_int z0_13 = z0; + // Add a number equal to half of the range in z0, meaning that the range is now [0, 2*z0_max] + ap_int absz0_13 = z0_13 + (1 << (TrackBitWidths::kZ0Size - 1)); + // Shift the bits down to truncate the dynamic range to the most significant HistogramBitWidths::kBinFixedSize bits + ap_int absz0_13_reduced = + absz0_13 >> (TrackBitWidths::kZ0Size - HistogramBitWidths::kBinFixedSize); + // Put the relevant bits into the histbin_t container + histbin_t bin = absz0_13_reduced.range(HistogramBitWidths::kBinFixedSize - 1, 0); + + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") + << "fastHistoEmulation::fetchBin() Checking the mapping from z0 to bin index ... \n" + << "histbin_fixed_t(1.0 / settings_->vx_histogram_binwidth()) = " + << histbin_fixed_t(1.0 / settings_->vx_histogram_binwidth()) << "\n" + << "histbin_t(std::floor(nbins / 2) = " << histbin_t(std::floor(nbins / 2.)) << "\n" + << "z0 = " << z0 << "\n" + << "bin = " << bin; + } + bool valid = true; + if (bin < 0) { + return std::make_pair(0, false); + } else if (bin > (nbins - 1)) { + return std::make_pair(0, false); + } + return std::make_pair(bin, valid); + }; + + // Replace with https://stackoverflow.com/questions/13313980/populate-an-array-using-constexpr-at-compile-time ? + auto init_inversion_table = [&]() -> std::vector { + std::vector table_out(kTableSize, 0.); + for (unsigned int ii = 0; ii < kTableSize; ii++) { + // First, convert from table index to X-value (unsigned 8-bit, range 0 to +1533) + float in_val = 1533.0 * (ii / float(kTableSize)); + // Next, compute lookup table function + table_out.at(ii) = (in_val > 0) ? (1.0 / in_val) : 0.0; + } + return table_out; + }; + + auto inversion = [&](slidingsum_t& data_den) -> inverse_t { + std::vector inversion_table = init_inversion_table(); + + // Index into the lookup table based on data + int index; + if (data_den < 0) + data_den = 0; + if (data_den > (kTableSize - 1)) + data_den = kTableSize - 1; + index = data_den; + return inversion_table.at(index); + }; + + auto bin_center = [&](zsliding_t iz, int nbins) -> l1t::VertexWord::vtxz0_t { + zsliding_t z = iz - histbin_t(std::floor(nbins / 2.)); + std::unique_ptr log; + if (settings_->debug() >= 1) { + log = std::make_unique("VertexProducer"); + *log << "bin_center information ...\n" + << "iz = " << iz << "\n" + << "histbin_t(std::floor(nbins / 2.)) = " << histbin_t(std::floor(nbins / 2.)) << "\n" + << "binwidth = " << zsliding_t(settings_->vx_histogram_binwidth()) << "\n" + << "z = " << z << "\n" + << "zsliding_t(z * zsliding_t(binwidth)) = " << std::setprecision(7) + << l1t::VertexWord::vtxz0_t(z * zsliding_t(settings_->vx_histogram_binwidth())); + } + return l1t::VertexWord::vtxz0_t(z * zsliding_t(settings_->vx_histogram_binwidth())); + }; + + auto weighted_position = [&](histbin_t b_max, + const std::vector& binpt, + slidingsum_t maximums, + int nbins) -> zsliding_t { + zsliding_t zvtx_sliding = 0; + slidingsum_t zvtx_sliding_sum = 0; + inverse_t inv = 0; + + std::unique_ptr log; + if (settings_->debug() >= 1) { + log = std::make_unique("VertexProducer"); + *log << "Progression of weighted_position() ...\n" + << "zvtx_sliding_sum = "; + } + + // Find the weighted position within the window in index space (width = 1) + for (ap_uint w = 0; w < HistogramBitWidths::kWindowSize; ++w) { + zvtx_sliding_sum += (binpt.at(w) * w); + if (settings_->debug() >= 1) { + *log << "(" << w << " * " << binpt.at(w) << ")"; + if (w < HistogramBitWidths::kWindowSize - 1) { + *log << " + "; + } + } + } + + if (settings_->debug() >= 1) { + *log << " = " << zvtx_sliding_sum << "\n"; + } + + if (maximums != 0) { + inv = inversion(maximums); + zvtx_sliding = zvtx_sliding_sum * inv; + } else { + zvtx_sliding = (settings_->vx_windowSize() / 2.0) + (((int(settings_->vx_windowSize()) % 2) != 0) ? 0.5 : 0.0); + } + if (settings_->debug() >= 1) { + *log << "inversion(" << maximums << ") = " << inv << "\nzvtx_sliding = " << zvtx_sliding << "\n"; + } + + // Add the starting index plus half an index to shift the z position to its weighted position (still in inxex space) within all of the bins + zvtx_sliding += b_max; + zvtx_sliding += ap_ufixed<1, 0>(0.5); + if (settings_->debug() >= 1) { + *log << "b_max = " << b_max << "\n"; + *log << "zvtx_sliding + b_max + 0.5 = " << zvtx_sliding << "\n"; + } + + // Shift the z position from index space into z [cm] space + zvtx_sliding = bin_center(zvtx_sliding, nbins); + if (settings_->debug() >= 1) { + *log << "bin_center(zvtx_sliding + b_max + 0.5, nbins) = " << std::setprecision(7) << zvtx_sliding; + log.reset(); + } + return zvtx_sliding; + }; + + // Create the histogram + unsigned int nbins = + std::round((settings_->vx_histogram_max() - settings_->vx_histogram_min()) / settings_->vx_histogram_binwidth()); + unsigned int nsums = nbins - settings_->vx_windowSize(); + std::vector hist(nbins, 0); + + // Loop over the tracks and fill the histogram + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") << "fastHistoEmulation::Processing " << fitTracks_.size() << " tracks"; + } + for (const L1Track& track : fitTracks_) { + // Get the track pt and z0 + // Convert them to an appropriate data format + // Truncation and saturdation taken care of by the data type specification + pt_t tkpt = 0; + tkpt.V = track.getTTTrackPtr()->getTrackWord()(TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, + TTTrack_TrackWord::TrackBitLocations::kRinvLSB); + track_pt_fixed_t pt_tmp = tkpt; + z0_t tkZ0 = track.getTTTrackPtr()->getZ0Word(); + + if ((settings_->vx_DoQualityCuts() && track_quality_check(tkpt)) || (!settings_->vx_DoQualityCuts())) { + // + // Check bin validity of bin found for the current track + // + std::pair bin = fetch_bin(tkZ0, nbins); + assert(bin.first >= 0 && bin.first < nbins); + + // + // If the bin is valid then sum the tracks + // + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") << "fastHistoEmulation::Checking the track word ... \n" + << "track word = " << track.getTTTrackPtr()->getTrackWord().to_string(2) + << "\n" + << "tkZ0 = " << tkZ0.to_double() << "(" << tkZ0.to_string(2) + << ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2) + << ")\tpt_tmp = " << pt_tmp << "\tbin = " << bin.first.to_int() << "\n" + << "pt sum in bin " << bin.first.to_int() + << " BEFORE adding track = " << hist.at(bin.first).to_double(); + } + if (bin.second) { + hist.at(bin.first) = hist.at(bin.first) + pt_tmp; + } + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") << "fastHistoEmulation::\npt sum in bin " << bin.first.to_int() + << " AFTER adding track = " << hist.at(bin.first).to_double(); + } + } else { + if (settings_->debug() > 2) { + edm::LogInfo("VertexProducer") << "fastHistoEmulation::Did not add the following track ... \n" + << "track word = " << track.getTTTrackPtr()->getTrackWord().to_string(2) + << "\n" + << "tkZ0 = " << tkZ0.to_double() << "(" << tkZ0.to_string(2) + << ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2) + << ")\tpt_tmp = " << pt_tmp; + } + } + } // end loop over tracks + + // Loop through all bins, taking into account the fact that the last bin is nbins-window_width+1, + // and compute the sums using sliding windows ... sum_i_i+(w-1) where i in (0,nbins-w) and w is the window size + std::vector hist_window_sums(nsums, 0); + for (unsigned int b = 0; b < nsums; ++b) { + for (unsigned int w = 0; w < HistogramBitWidths::kWindowSize; ++w) { + unsigned int index = b + w; + hist_window_sums.at(b) += hist.at(index); + } + } + + // Find the top N vertices + std::vector found; + found.reserve(settings_->vx_nvtx()); + for (unsigned int ivtx = 0; ivtx < settings_->vx_nvtx(); ivtx++) { + histbin_t b_max = 0; + window_pt_sum_fixed_t max_pt = 0; + zsliding_t zvtx_sliding = -999; + std::vector binpt_max(HistogramBitWidths::kWindowSize, 0); + + // Find the maxima of the sums + for (unsigned int i = 0; i < hist_window_sums.size(); i++) { + // Skip this window if it will already be returned + if (find(found.begin(), found.end(), i) != found.end()) + continue; + if (hist_window_sums.at(i) > max_pt) { + b_max = i; + max_pt = hist_window_sums.at(b_max); + std::copy(std::begin(hist) + b_max, + std::begin(hist) + b_max + HistogramBitWidths::kWindowSize, + std::begin(binpt_max)); + + // Find the weighted position only for the highest sum pt window + zvtx_sliding = weighted_position(b_max, binpt_max, max_pt, nbins); + } + } + if (settings_->debug() >= 1) { + edm::LogInfo log("VertexProducer"); + log << "fastHistoEmulation::Checking the output parameters ... \n"; + if (found.empty()) { + printHistogram(log, hist, 80, 0, -1, "fastHistoEmulation::hist", "\e[92m"); + printHistogram( + log, hist_window_sums, 80, 0, -1, "fastHistoEmulation::hist_window_sums", "\e[92m"); + } + printHistogram( + log, binpt_max, 80, 0, -1, "fastHistoEmulation::binpt_max", "\e[92m"); + log << "bin index (not a VertexWord parameter) = " << b_max << "\n" + << "sumPt = " << max_pt.to_double() << "\n" + << "z0 = " << zvtx_sliding.to_double(); + } + found.push_back(b_max); + verticesEmulation_.emplace_back(l1t::VertexWord::vtxvalid_t(1), + l1t::VertexWord::vtxz0_t(zvtx_sliding), + l1t::VertexWord::vtxmultiplicity_t(0), + l1t::VertexWord::vtxsumpt_t(max_pt), + l1t::VertexWord::vtxquality_t(0), + l1t::VertexWord::vtxinversemult_t(0), + l1t::VertexWord::vtxunassigned_t(0)); + } + pv_index_ = 0; + } // end of fastHistoEmulation + } // namespace l1tVertexFinder diff --git a/L1Trigger/VertexFinder/test/vertexNTupler_cfg.py b/L1Trigger/VertexFinder/test/vertexNTupler_cfg.py index fca514676091d..d2e5bf974395a 100644 --- a/L1Trigger/VertexFinder/test/vertexNTupler_cfg.py +++ b/L1Trigger/VertexFinder/test/vertexNTupler_cfg.py @@ -1,23 +1,56 @@ import FWCore.ParameterSet.Config as cms import FWCore.Utilities.FileUtils as FileUtils import FWCore.ParameterSet.VarParsing as VarParsing +import pkgutil +import sys # PART 1 : PARSE ARGUMENTS options = VarParsing.VarParsing ('analysis') +options.register('redir', 'root://cms-xrd-global.cern.ch/', VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, "The XRootD redirector to use") +options.register('nstart', 0,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "File index to start on") +options.register('nfiles', -1,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "Number of files to process per job") options.register('storeTracks', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.bool, "Store tracks in NTuple") options.register('l1Tracks','TTTracksFromTrackletEmulation:Level1TTTracks', VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.string, 'L1 track collection to use') options.register('runVariations', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.bool, "Run some pre-defined algorithmic variations") -options.register('threads',1,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "Number of threads/streams to run") +options.register('threads', 1,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "Number of threads to run") +options.register('streams', 0,VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.int, "Number of streams to run") +options.register('memoryProfiler', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.bool, "Run the memory profile") +options.register('tmi', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.bool, "Run a simple profiler") +options.register('trace', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.bool, "Dump the paths and consumes") +options.register('dump', False, VarParsing.VarParsing.multiplicity.singleton, VarParsing.VarParsing.varType.bool, "Dump the configuration and exit") options.parseArguments() -inputFiles = [] +# handle site name usage +if options.redir[0]=="T": + options.redir = "root://cms-xrd-global.cern.ch//store/test/xrootd/"+options.redir + +# Load input files +inputFiles = cms.untracked.vstring() + for filePath in options.inputFiles: - if filePath.endswith(".root"): - inputFiles.append(filePath) + if filePath.endswith(".root") : + inputFiles.append( filePath ) + elif filePath.endswith(".txt"): + inputFiles += FileUtils.loadListFromFile( filePath ) + elif filePath.endswith("_cff.py"): + inputFilesImport = getattr(__import__(filePath.strip(".py").strip("python/").replace('/','.'),fromlist=["readFiles"]),"readFiles") + if options.nfiles==-1: + inputFiles.extend( inputFilesImport ) + else: + inputFiles.extend( inputFilesImport[options.nstart:(options.nstart+options.nfiles)] ) + elif pkgutil.find_loader("L1Trigger.VertexFinder."+filePath+"_cff") is not None: + inputFilesImport = getattr(__import__("L1Trigger.VertexFinder."+filePath+"_cff",fromlist=["readFiles"]),"readFiles") + if options.nfiles==-1: + inputFiles.extend( inputFilesImport ) + else: + inputFiles.extend( inputFilesImport[options.nstart:(options.nstart+options.nfiles)] ) else: - inputFiles += FileUtils.loadListFromFile(filePath) + raise RuntimeError("Must specify a list of ROOT files, a list of txt files containing a list of ROOT files, or a list of python input files.") + +if options.redir != "": + inputFiles = [(options.redir if val.startswith("/") else "")+val for val in inputFiles] if options.l1Tracks.count(':') != 1: raise RuntimeError("Value for 'l1Tracks' command-line argument (= '{}') should contain one colon".format(options.l1Tracks)) @@ -36,14 +69,14 @@ process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') from Configuration.AlCa.GlobalTag import GlobalTag process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:upgradePLS3', '') -process.load("FWCore.MessageLogger.MessageLogger_cfi") +process.load("FWCore.MessageService.MessageLogger_cfi") process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring(inputFiles) ) process.TFileService = cms.Service("TFileService", fileName = cms.string(options.outputFile)) process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(options.maxEvents) ) process.options = cms.untracked.PSet( numberOfThreads = cms.untracked.uint32(options.threads), - numberOfStreams = cms.untracked.uint32(options.threads if options.threads>0 else 0) + numberOfStreams = cms.untracked.uint32(options.streams if options.streams>0 else 0) ) process.load('L1Trigger.VertexFinder.VertexProducer_cff') @@ -60,20 +93,30 @@ process.Timing = cms.Service("Timing", summaryOnly = cms.untracked.bool(True)) producerSum = process.VertexProducer -additionalProducerAlgorithms = ["FastHistoLooseAssociation", "DBSCAN"] +additionalProducerAlgorithms = ["fastHistoEmulation", "fastHistoLooseAssociation", "DBSCAN"] for algo in additionalProducerAlgorithms: producerName = 'VertexProducer{0}'.format(algo) producerName = producerName.replace(".","p") # legalize the name producer = process.VertexProducer.clone() producer.VertexReconstruction.Algorithm = cms.string(algo) + + if "Emulation" in algo: + if "L1GTTInputProducer" not in process.producerNames(): + process.load('L1Trigger.L1TTrackMatch.L1GTTInputProducer_cfi') + producer.l1TracksInputTag = cms.InputTag("L1GTTInputProducer","Level1TTTracksConverted") + producerSum = process.L1GTTInputProducer + producerSum + + process.L1TVertexNTupler.emulationVertexInputTags.append( cms.InputTag(producerName, 'l1verticesEmulation') ) + process.L1TVertexNTupler.emulationVertexBranchNames.append(algo) + else: + process.L1TVertexNTupler.l1VertexInputTags.append( cms.InputTag(producerName, 'l1vertices') ) + process.L1TVertexNTupler.l1VertexBranchNames.append(algo) + process.L1TVertexNTupler.l1VertexTrackInputs.append('hybrid') + setattr(process, producerName, producer) producerSum += producer - process.L1TVertexNTupler.l1VertexInputTags.append( cms.InputTag(producerName, 'l1vertices') ) - process.L1TVertexNTupler.l1VertexBranchNames.append(algo) - process.L1TVertexNTupler.l1VertexTrackInputs.append('hybrid') - # PART 3: PERFORM SCAN OVER ALGO PARAMETER SPACE if options.runVariations: for i in range(1, 9): @@ -108,7 +151,31 @@ print "Total number of producers =", len(additionalProducerAlgorithms)+1 print " Producers = [{0}]".format(producerSum.dumpSequenceConfig().replace('&',', ')) -print " Algorithms = [FastHisto, {0}]".format(', '.join(additionalProducerAlgorithms)) - +print " Algorithms = [fastHisto, {0}]".format(', '.join(additionalProducerAlgorithms)) + +# PART 4: UTILITIES + +# MEMORY PROFILING +if options.memoryProfiler: + process.IgProfService = cms.Service("IgProfService", + reportEventInterval = cms.untracked.int32(1), + reportFirstEvent = cms.untracked.int32(1), + reportToFileAtPostEndJob = cms.untracked.string('| gzip -c > '+options.outputFile+'___memory___%I_EndOfJob.gz'), + reportToFileAtPostEvent = cms.untracked.string('| gzip -c > '+options.outputFile+'___memory___%I.gz') + ) + +# SIMPLER PROFILING +if options.tmi: + from Validation.Performance.TimeMemoryInfo import customise + process = customise(process) + +if options.trace: + process.add_(cms.Service("Tracer", dumpPathsAndConsumes = cms.untracked.bool(True))) + +# SETUP THE PATH process.p = cms.Path(producerSum + process.TPStubValueMapProducer + process.InputDataProducer + process.L1TVertexNTupler) +# DUMP AND EXIT +if options.dump: + print process.dumpPython() + sys.exit(0) diff --git a/SimGeneral/TrackingAnalysis/BuildFile.xml b/SimGeneral/TrackingAnalysis/BuildFile.xml index 303b0c7b87042..0e7ab812a7797 100644 --- a/SimGeneral/TrackingAnalysis/BuildFile.xml +++ b/SimGeneral/TrackingAnalysis/BuildFile.xml @@ -1,4 +1,5 @@ +