diff --git a/NtupleProducer/plugins/BuildFile.xml b/NtupleProducer/plugins/BuildFile.xml
index 5164718..0cef9e5 100644
--- a/NtupleProducer/plugins/BuildFile.xml
+++ b/NtupleProducer/plugins/BuildFile.xml
@@ -17,6 +17,9 @@
+
+
+
diff --git a/NtupleProducer/plugins/L1TrackTableProducer.cc b/NtupleProducer/plugins/L1TrackTableProducer.cc
new file mode 100644
index 0000000..95e0cab
--- /dev/null
+++ b/NtupleProducer/plugins/L1TrackTableProducer.cc
@@ -0,0 +1,159 @@
+////////////////////////////// L1TrackTableProducer ///////////////////////////
+// Original author: G. Karathanasis, CERN gkaratha@cern.ch
+// Saves all L1 tracks in FastPUPPI. Has hardcoded the basic variables and assoc
+// iations with MC particles. Additional variables can be added in runtime like
+// in nano. Same with cuts
+
+
+// user include files
+#include "FWCore/Framework/interface/Frameworkfwd.h"
+#include "FWCore/Framework/interface/global/EDProducer.h"
+
+#include "FWCore/Framework/interface/Event.h"
+#include "DataFormats/Common/interface/Handle.h"
+#include "DataFormats/Common/interface/View.h"
+
+#include "DataFormats/Candidate/interface/Candidate.h"
+
+
+#include "DataFormats/Math/interface/deltaR.h"
+
+#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include "FWCore/Utilities/interface/InputTag.h"
+
+#include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
+#include "DataFormats/L1TrackTrigger/interface/TTTrack.h"
+#include "SimDataFormats/Associations/interface/TTTrackAssociationMap.h"
+#include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h"
+
+#include "DataFormats/NanoAOD/interface/FlatTable.h"
+
+#include "CommonTools/Utils/interface/StringCutObjectSelector.h"
+#include "CommonTools/Utils/interface/StringObjectFunction.h"
+
+#include
+
+
+
+
+class L1TrackTableProducer : public edm::global::EDProducer<> {
+ public:
+ explicit L1TrackTableProducer(const edm::ParameterSet&);
+ ~L1TrackTableProducer();
+
+ private:
+ virtual void produce(edm::StreamID id, edm::Event& iEvent, const edm::EventSetup& iSetup) const override;
+
+ typedef TTTrack l1Track;
+ typedef TTTrackAssociationMap l1TrackingParticleMap;
+ edm::EDGetTokenT< std::vector > l1TrkToken_;
+ edm::EDGetTokenT< l1TrackingParticleMap > l1TrackingPartToken_;
+ StringCutObjectSelector tk_sel_;
+ std::string name_;
+
+ struct ExtraVar {
+ std::string name, expr;
+ StringObjectFunction func;
+ ExtraVar(const std::string & n, const std::string & expr) : name(n), expr(expr), func(expr, true) {}
+ };
+ std::vector extraVars_;
+
+
+};
+
+
+
+L1TrackTableProducer::L1TrackTableProducer(const edm::ParameterSet& iConfig) :
+ l1TrkToken_{ consumes> ( iConfig.getParameter ("tracks") ) },
+ l1TrackingPartToken_{ consumes( iConfig.getParameter ("trackingParticleMap") )},
+ tk_sel_{iConfig.getParameter("selection"), true},
+ name_{iConfig.getParameter("name")}
+{
+ if (iConfig.existsAs("variables")) {
+ edm::ParameterSet vars = iConfig.getParameter("variables");
+ auto morenames = vars.getParameterNamesForType();
+ for (const std::string & name : morenames) {
+ extraVars_.emplace_back(name, vars.getParameter(name));
+ }
+ }
+ produces(name_);
+ }
+
+
+
+L1TrackTableProducer::~L1TrackTableProducer() { }
+
+// ------------ method called for each event ------------
+ void
+L1TrackTableProducer::produce(edm::StreamID id, edm::Event& iEvent, const edm::EventSetup& iSetup) const
+{
+ // get input
+ edm::Handle> l1_tracks;
+ edm::Handle l1_tracking_parts_map;
+ iEvent.getByToken(l1TrkToken_, l1_tracks);
+ iEvent.getByToken(l1TrackingPartToken_, l1_tracking_parts_map);
+ std::vector isLooseGenuineTP,isGenuineTP,isUnknownTP,isCombinatoricTP;
+ std::vector trk_pt,trk_eta,trk_phi,trk_q,tp_pt,tp_eta,tp_phi;
+ std::vector tp_pdgid;
+ std::vector extra_var_values[extraVars_.size()];
+
+
+ for (size_t itrk=0; itrksize(); itrk++) {
+ // get and select
+ edm::Ptr l1trk_ptr(l1_tracks, itrk);
+ if (!tk_sel_(*l1trk_ptr))
+ continue;
+ trk_pt.emplace_back(l1trk_ptr->momentum().perp());
+ trk_eta.emplace_back(l1trk_ptr->momentum().eta());
+ trk_phi.emplace_back(l1trk_ptr->momentum().phi());
+ trk_q.emplace_back(l1trk_ptr->rInv()/fabs(l1trk_ptr->rInv()));
+ for (size_t ivar =0; ivar< extraVars_.size(); ivar++) {
+ extra_var_values[ivar].emplace_back( extraVars_[ivar].func(*l1trk_ptr) );
+ }
+ isLooseGenuineTP.emplace_back(l1_tracking_parts_map->isLooselyGenuine(l1trk_ptr));
+ isGenuineTP.emplace_back(l1_tracking_parts_map->isGenuine(l1trk_ptr));
+ isUnknownTP.emplace_back(l1_tracking_parts_map->isUnknown(l1trk_ptr));
+ isCombinatoricTP.emplace_back(l1_tracking_parts_map->isCombinatoric(l1trk_ptr));
+ if ( l1_tracking_parts_map->isLooselyGenuine(l1trk_ptr) || l1_tracking_parts_map->isGenuine(l1trk_ptr) ){
+ edm::Ptr trackingpart_ptr = l1_tracking_parts_map->findTrackingParticlePtr(l1trk_ptr);
+ tp_pt.emplace_back( trackingpart_ptr.isNull() ? -99 : trackingpart_ptr->p4().pt() );
+ tp_eta.emplace_back( trackingpart_ptr.isNull() ? -99 : trackingpart_ptr->p4().eta());
+ tp_phi.emplace_back( trackingpart_ptr.isNull() ? -99 : trackingpart_ptr->p4().phi());
+ tp_pdgid.emplace_back( trackingpart_ptr.isNull() ? -99 : trackingpart_ptr->pdgId());
+ } else{
+ tp_pt.emplace_back(-99);
+ tp_eta.emplace_back(-99);
+ tp_phi.emplace_back(-99);
+ tp_pdgid.emplace_back(-99);
+ }
+
+ }
+ // create the table
+ unsigned int ncands = isLooseGenuineTP.size();
+ auto out = std::make_unique(ncands, name_, false);
+ out->addColumn("pt", trk_pt, "l1 track pt");
+ out->addColumn("eta", trk_eta, "l1 track eta");
+ out->addColumn("phi", trk_phi, "l1 track phi");
+ out->addColumn("charge", trk_q, "l1 track charge");
+ out->addColumn("isLooseGenuineTP", isLooseGenuineTP, "track loosely matched to TP");
+ out->addColumn("isGenuineTP", isGenuineTP, "track matched to TP");
+ out->addColumn("isUnknownTP", isUnknownTP, "track not matched to TP");
+ out->addColumn("isCombinatoricTP", isCombinatoricTP, "combinatoric track");
+ out->addColumn("tp_pt", tp_pt, "pt of tracking particle");
+ out->addColumn("tp_eta", tp_eta, "eta of tracking particle");
+ out->addColumn("tp_phi", tp_phi, "phi of tracking particle");
+ out->addColumn("tp_pdgid", tp_pdgid, "pdgId of tracking particle");
+
+ // write arbitrary number of variables
+ for (size_t ivar =0; ivar< extraVars_.size(); ivar++) {
+ out->addColumn(extraVars_[ivar].name, extra_var_values[ivar], extraVars_[ivar].expr);
+ }
+
+ iEvent.put(std::move(out), name_);
+}
+
+
+
+//define this as a plug-in
+#include "FWCore/Framework/interface/MakerMacros.h"
+DEFINE_FWK_MODULE(L1TrackTableProducer);
diff --git a/NtupleProducer/python/runPerformanceNTuple.py b/NtupleProducer/python/runPerformanceNTuple.py
index 0168b78..747455a 100644
--- a/NtupleProducer/python/runPerformanceNTuple.py
+++ b/NtupleProducer/python/runPerformanceNTuple.py
@@ -12,16 +12,16 @@ def LazyVar(expr, valtype, doc=None, precision=-1):
process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi")
process.load("FWCore.MessageLogger.MessageLogger_cfi")
process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True), allowUnscheduled = cms.untracked.bool(False) )
-process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1))
+process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(10))
process.MessageLogger.cerr.FwkReport.reportEvery = 1
process.source = cms.Source("PoolSource",
- fileNames = cms.untracked.vstring('file:inputs125X.root'),
- inputCommands = cms.untracked.vstring("keep *",
- "drop l1tPFClusters_*_*_*",
- "drop l1tPFTracks_*_*_*",
- "drop l1tPFCandidates_*_*_*",
- "drop l1tTkPrimaryVertexs_*_*_*")
+ fileNames = cms.untracked.vstring('/store/mc/Phase2Spring23DIGIRECOMiniAOD/DYToLL_M-10To50_TuneCP5_14TeV-pythia8/GEN-SIM-DIGI-RAW-MINIAOD/PU200_Trk1GeV_131X_mcRun4_realistic_v5-v1/30000/0289a719-64c3-4b16-871f-da7db9a8ac88.root'),
+ inputCommands = cms.untracked.vstring("keep *")
+# "drop l1tPFClusters_*_*_*",
+# "drop l1tPFTracks_*_*_*",
+# "drop l1tPFCandidates_*_*_*",
+# "drop l1tTkPrimaryVertexs_*_*_*")
)
process.load('Configuration.Geometry.GeometryExtended2026D110Reco_cff')
@@ -290,6 +290,31 @@ def addAllJets():
addCaloJets()
#addTkJets()
+
+def addL1Tracks():
+ process.l1trackTable = cms.EDProducer("L1TrackTableProducer",
+ tracks = cms.InputTag("l1tTTTracksFromTrackletEmulation", "Level1TTTracks"),
+ trackingParticleMap = cms.InputTag("TTTrackAssociatorFromPixelDigis", "Level1TTTracks"),
+ selection = cms.string("momentum().perp()>0"),
+ name= cms.string("L1Tk"),
+ variables = cms.PSet(
+ chi2 = cms.string("chi2"),
+ chi2Red = cms.string("chi2Red"),
+ #chi2Bend = cms.string("chi2Bend"),
+ #chi2BendRed = cms.string("chi2BendRed"),
+ chi2XYRed = cms.string("chi2XYRed"),
+ chi2ZRed = cms.string("chi2ZRed"),
+ d0 = cms.string("d0"),
+ nFitPars = cms.string("nFitPars"),
+ stubPtConsistency = cms.string("stubPtConsistency"),
+ z0 = cms.string("z0"),
+ nStub = cms.string("getStubRefs.size"),
+ hitPattern = cms.string("hitPattern"),
+ trkMVA1 = cms.string("trkMVA1")
+
+ ),
+ )
+
def addJetConstituents(N):
for i in range(N): # save a max of N daughters (unfortunately 2D arrays are not yet supported in the NanoAOD output module)
for var in "pt", "eta", "phi", "mass", "pdgId":