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