From 67e69968c1d6297d4239bd2b1c66622256cd102f Mon Sep 17 00:00:00 2001 From: Georgios Karathanasis Date: Wed, 29 Jan 2025 17:48:56 +0100 Subject: [PATCH] L1 track code --- NtupleProducer/plugins/BuildFile.xml | 3 + .../plugins/L1TrackTableProducer.cc | 159 ++++++++++++++++++ NtupleProducer/python/runPerformanceNTuple.py | 39 ++++- 3 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 NtupleProducer/plugins/L1TrackTableProducer.cc 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":