cmsrel CMSSW_7_0_6_patch1
from DataFormats.FWLite import Handle, Events
iEvent.getByToken(muons_, muons);
boh?
CMSSW_7_0_6_patch1
release and assume you're working on a SLC6 node (e.g. lxplus6.cern.ch
). To setup the release, you can do
cmsrel CMSSW_7_0_6_patch1 cd CMSSW_7_0_6_patch1/src cmsenvAs input test files in the examples we will use
/store/cmst3/user/gpetrucc/miniAOD/v1/TT_Tune4C_13TeV-pythia8-tauola_PU_S14_PAT.root
(available at CERN), which contains ~8k events of ttbar production, but any other MINIAODSIM file will work equally well.
mkdir Test cd Test mkedanlzr MiniAnalyzer
New package "MiniAnalyzer" of EDAnalyzer type is successfully generated MiniAnalyzer/ | plugins/ | |-- BuildFile.xml | |-- MiniAnalyzer.cc | python/ | |-- CfiFile_cfi.py | |-- ConfFile_cfg.py | test/ | doc/ Total: 4 directories, 4 filesThen you'll need to edit the
BuildFile.xml
to add a <use name="DataFormats/PatCandidates"/>
# import ROOT in batch mode import sys oldargv = sys.argv[:] sys.argv = [ '-b-' ] import ROOT ROOT.gROOT.SetBatch(True) sys.argv = oldargv # load FWLite C++ libraries ROOT.gSystem.Load("libFWCoreFWLite.so"); ROOT.gSystem.Load("libDataFormatsFWLite.so"); ROOT.AutoLibraryLoader.enable() # load FWlite python libraries from DataFormats.FWLite import Handle, Events # open file (you can use 'edmFileUtil -d /store/whatever.root' to get the physical file name) events = Events("root://eoscms//eos/cms/store/cmst3/user/gpetrucc/miniAOD/v1/TT_Tune4C_13TeV-pythia8-tauola_PU_S14_PAT.root") for i,event in enumerate(events): print "\nEvent", i if i > 10: break
Object | Label | C++ class | Selection | Detailed information |
---|---|---|---|---|
Muons | slimmedMuons |
std::vector<pat::Muon> |
includes muons with pT > 5 GeV or that pass the PF muon ID (see below) |
All standard muon ID and isolations, the associated tracker, outer and global tracks, muonBestTrack and typePMuonBestTrack |
Electrons | slimmedElectrons |
std::vector<pat::Electron> |
all gedGsfElectrons electrons |
For electrons of pT > 5 GeV, full information is saved (supercluster, seed cluster, interesting rechits, isolation and id variables). For electrons below the threshold, only the superCluster and seedCluster are provided, and the id and isolation variables are zeroed out to save space |
Taus | slimmedTaus |
std::vector<pat::Tau> |
taus from hpsPFTauProducer with pT > 18 GeV, and passing the basic decayModeFinding id |
All POG-supported tau id discriminators are included. Links to the PF candidates are also provided. |
Photons | slimmedPhotons |
std::vector<pat::Photon> |
gedPhotons with pT > 14 GeV and hadTowOverEm() < 0.15 |
For photons that pass a minimal r9 or isolation cut, full information is saved (supercluster, seed cluster, interesting rechits, isolation and id variables). The requirement is the logical or of the three conditions r9()>0.8 , chargedHadronIso()<20 , chargedHadronIso()<0.3*pt() |
Jets | slimmedJets |
std::vector<pat::Jet> |
ak4PFJetsCHS with pT > 10 GeV |
L1+L2+L3+residual corrections are applied; b-tagging and pileup jet id information are embedded. Links are provided to the constituent PF candidates. |
slimmedGenJets |
std::vector<reco::GenJet> |
ak4GenJets with pT > 8 GeV |
links to constituents (packed gen particles) are available | |
slimmedJetsAK8 |
std::vector<pat::Jet> |
ak8PFJetsCHS with pT > 100 GeV (for substructure) |
L1+L2+L3+residual corrections are applied (AK7PFchs corrections used); some precomputed substructure info is provided, and also links to the constituent PF candidates. | |
MET | slimmedMETs |
std::vector<pat::MET> |
the type1 PF MET | MET uncertainties are provided note: type1 corrections are computed from non-CHS ak4PFJets , as prescribed by the JetMET group. |
muons
collection are included in MiniAOD if they pass at least one of these three requirements: isLooseMuon
, isTightMuon
, isSoftMuon
, isHighPtMuon
and muonID
methods as provided in the pat::Muon
class.
The following tracks are embedded by value in the pat::Muon
, if available: tracker, outer and global tracks, muonBestTrack
and typePMuonBestTrack
. muonBestTrack
or tunePMuonBestTrack
selects any of those tracks, they'll be available), but they are be available for muons with pt > 100 GeV starting from CMSSW 73X.
known Features in CSA14 and PHYS14 tunePMuonBestTrack
not available (but the muonBestTrack
always is). A fix exists in newer releases (PR #8568)gedGsfElectrons
electrons are saved.
For electrons of pT > 5 GeV, detailed information is saved: reco::GsfElectron
information (though they're stored externally in the reducedEgamma
collections). The final superclusters and clusters are saved, not also the intermediate unrefined "PF" superclusters and clusters.
reducedEGamma:reducedEBRecHits
, reducedEGamma:reducedEERecHits
, reducedEGamma:reducedESRecHits
for barrel, endcap and pre-showers respectively.
reco::GsfElectron
interface, e.g. sigmaIetaIeta()
(the only missing one in AOD is sigmaIetaIphi()
which is added in pat::Electron
interface).pat::Electron
methods, e.g. full5x5_sigmaIetaIeta()
.
gedPhotons
, with two levels of selection: hadTowOverEm() < 0.15
r9()>0.8
, and an absolute and relative isolation cuts done with charged hadrons only, chargedHadronIso()<20
, chargedHadronIso()<0.3*pt()
decayModeFinding
discriminator. Tighter tau ID requirements can be applied using the tauID(name)
method, all POG-supported discriminators are included.
The tau ID discriminators recommended for CSA14 and Phys14 studies are described on this wiki.
Additional information on the taus, e.g. the impact parameter of the reconstructed tau vertex, are saved in the TauPFEssentialleadChargedHadrCand()
, leadNeutralCand()
, leadCand()
, signalCands()
, isolationCands()
, ... PF
inside, like signalPFCands()
, are not usable on MiniAOD since they're not compatible with the packed PF candidate format used in MiniAOD.
ak4PFJetsCHS
), and one for dedicated studies of substructure jets (from ak8PFJetsCHS
). Both are made using anti-kT clustering out of Particle Flow candidates, the only difference is the distance parameter, which approximately corresponds to the radius of the jet cone.
For both jet collections, links to the daughters are available through the daughter(idx)
and numberOfDaughters()
methods, and they will point into the collection of packed PF candidates described below.getPFConstituent
and getPFConstituents
methods instead will NOT work, since they explicitly require the daughter to be a full reco::PFCandidate
and not a packed PF one. One subtle point for AK8 jets is that, to save space, the first two constituents of the AK8 jets are the soft-dropped subjets. The rest of the constituents store the unclustered =pat::PackedCandidate=s.
For the AK4 jets, the following information is provided: bDiscriminator(name)
method, for: jetBProbabilityBJetTags
, jetProbabilityBJetTags
, trackCountingHighPurBJetTags
, trackCountingHighEffBJetTags
, simpleSecondaryVertexHighEffBJetTags
, simpleSecondaryVertexHighPurBJetTags
, combinedSecondaryVertexBJetTags
, combinedInclusiveSecondaryVertexBJetTags
combinedSecondaryVertexBJetTags
is no longer included. The new default is combinedInclusiveSecondaryVertexV2BJetTags
. See https://hypernews.cern.ch/HyperNews/CMS/get/physTools/3265/1.htmluserFloats
: the mass of the vertex (vtxMass
), the number of tracks in it (vtxNtracks
), and the decay length value and significance (vtx3DVal
, vtx3DSig
)
userFloat("pileupJetId:fullDiscriminant")
. It should be noted that the training used is for ak5PFJetsCHS
in CMSSW 5.3.X and Run 1 pileup, so it's probably not optimal for Run 2.
userFloats
with labels ak8PFJetsCHSPrunedLinks
, ak8PFJetsCHSTrimmedLinks
, ak8PFJetsCHSFilteredLinks
userFloats
with labels NjettinessAK8:tau1
, NjettinessAK8:tau2
, and NjettinessAK8:tau3
tagInfo("caTop").properties().topMass
, tagInfo("caTop").properties().minMass
, tagInfo("caTop").properties().nSubJets
userFloats
is highlighted here. A simple snippet to perform a very simple W/Z/H tagging selection would be :
double tau1 = jet.userFloat("NjettinessAK8:tau1"); // double tau2 = jet.userFloat("NjettinessAK8:tau2"); // Access the n-subjettiness variables double tau3 = jet.userFloat("NjettinessAK8:tau3"); // double trimmed_mass = jet.userFloat("ak8PFJetsCHSTrimmedLinks"); // access to trimmed mass double pruned_mass = jet.userFloat("ak8PFJetsCHSPrunedLinks"); // access to pruned mass double filtered_mass = jet.userFloat("ak8PFJetsCHSFilteredLinks"); // access to filtered mass bool mySimpleWTagger = (tau2/tau1) < 0.6 && pruned_mass > 50.0;
TagInfos
is highlighted here. The CMS top tagger utilizes this functionality as well. To implement a simple top tagger, a simple snippet would be :
reco::CATopTag const * tagInfo = dynamic_cast<reco::CATopTagInfo const *>( jet.tagInfo("caTop")); bool topTagged = false; if ( tagInfo != 0 ) { double minMass = tagInfo->properties().minMass; double topMass = tagInfo->properties().topMass; int nSubJets = tagInfo->properties().nSubJets; if ( nSubJets > 2 && minMass > 50.0 && topMass > 150.0 ) topTagged = true; }
std::vector< pat::PackedCandidate const *> constituents; for ( unsigned int i = 0; i < jet.numberOfDaughters(); ++i ) { auto const * subjet = jet.daughter(i); for ( unsigned int j = 0; j < subjet->numberOfDaughters(); ++j ) { constituents.push_back( subjet.daughter(j) ); } }
std::vector< pat::PackedCandidate const *> constituents; // First get the constituents from the subjets for ( unsigned int i = 0; i < 2; ++i ) { auto const & subjet = jet.daughter(i); for ( unsigned int j = 0; j < subjet.numberOfDaughters(); ++j ) { constituents.push_back( subjet.daughter(j) ); } } // Then get the constituents that were groomed away for ( unsigned int i = 2; i < jet.numberOfDaughters(); ++i ) { constituents.push_back( jet.daughter(i) ); }
pat::MET
in 74X)
Note that the type1 corrections are computed from non-CHS ak4PFJets
, as prescribed by the JetMET group.
The more sophisticated algorithm like MVAmet is not available at the moment. The metsignificance stored refers to the algorithm used at the beginning of run1 and the one used at the end of run1 is not available at the moment. Standalone recipes to run on top of miniAOD are needed to recalculate those.
The pat::METshiftedXyz(uncertainty, level)
methods: Xyz
can be any of P2, P3, P4, Px, Py, Pz, Phi, SumEt
uncertainty
can be any of the 12 variations considered (e.g. UnclusteredEnUp
or JetResDown
)
Type1
(default), Raw
, Type1p2
shiftedXyz(uncertainty, level)
methods correct for the scale of ak4PFJets
(not for the ak4PFJetsCHS
).
As example: you can get the raw MET with the slimmetMET.shiftedPt(pat::MET::NoShift, pat::MET::Raw)
(in python slimmetMET.shiftedPt(slimmetMET.NoShift, slimmetMET.Raw)
)
known Features in PHYS14
In the PHYS14 miniAOD there are four know features pat::MET
object is copied by value instead of taking a const pat::MET &
reference to the one in the event, one has errors when using the shiftedP** methods . See HN questionpat::MET
class, it is not possible to undo the type1 corrections to retrieve the raw PF ETmiss; however, that can be recalculated with very good accuracy from the packed PF candidates according to the recipes below (which in the end do nothing more than taking the negative vector sum of all pf candidates, as per the pf met definition).
from RecoMET.METProducers.PFMET_cfi import pfMet process.pfMet = pfMet.clone(src = "packedPFCandidates") process.pfMet.calculateSignificance = False # this can't be easily implemented on packed PF candidates at the moment
process.pfMet
in your path.
from math import atan2, hypot # define the handle pfs = Handle("std::vector<pat::PackedCandidate>") # within the event loop, do event.getByLabel("packedPFCandidates", pfs) mypx,mypy,mysumet = 0,0,0 for pf in pfs.product(): mypx -= pf.px() mypy -= pf.py() mysumet += pf.pt() mymet = hypot(py,px) myphi = atan2(py,px)
// system include files #include <memory> // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DataFormats/VertexReco/interface/VertexFwd.h" #include "DataFormats/VertexReco/interface/Vertex.h" #include "DataFormats/PatCandidates/interface/Muon.h" #include "DataFormats/PatCandidates/interface/Electron.h" #include "DataFormats/PatCandidates/interface/Tau.h" #include "DataFormats/PatCandidates/interface/Photon.h" #include "DataFormats/PatCandidates/interface/Jet.h" #include "DataFormats/PatCandidates/interface/MET.h" #include "DataFormats/PatCandidates/interface/PackedCandidate.h" // // class declaration // class MiniAnalyzer : public edm::EDAnalyzer { public: explicit MiniAnalyzer(const edm::ParameterSet&); ~MiniAnalyzer(); private: virtual void analyze(const edm::Event&, const edm::EventSetup&) override; // ----------member data --------------------------- edm::EDGetTokenT<reco::VertexCollection> vtxToken_; edm::EDGetTokenT<pat::MuonCollection> muonToken_; edm::EDGetTokenT<pat::ElectronCollection> electronToken_; edm::EDGetTokenT<pat::TauCollection> tauToken_; edm::EDGetTokenT<pat::PhotonCollection> photonToken_; edm::EDGetTokenT<pat::JetCollection> jetToken_; edm::EDGetTokenT<pat::JetCollection> fatjetToken_; edm::EDGetTokenT<pat::METCollection> metToken_; }; MiniAnalyzer::MiniAnalyzer(const edm::ParameterSet& iConfig): vtxToken_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))), muonToken_(consumes<pat::MuonCollection>(iConfig.getParameter<edm::InputTag>("muons"))), electronToken_(consumes<pat::ElectronCollection>(iConfig.getParameter<edm::InputTag>("electrons"))), tauToken_(consumes<pat::TauCollection>(iConfig.getParameter<edm::InputTag>("taus"))), photonToken_(consumes<pat::PhotonCollection>(iConfig.getParameter<edm::InputTag>("photons"))), jetToken_(consumes<pat::JetCollection>(iConfig.getParameter<edm::InputTag>("jets"))), fatjetToken_(consumes<pat::JetCollection>(iConfig.getParameter<edm::InputTag>("fatjets"))), metToken_(consumes<pat::METCollection>(iConfig.getParameter<edm::InputTag>("mets"))) { } MiniAnalyzer::~MiniAnalyzer() { } void MiniAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { edm::Handle<reco::VertexCollection> vertices; iEvent.getByToken(vtxToken_, vertices); if (vertices->empty()) return; // skip the event if no PV found const reco::Vertex &PV = vertices->front(); edm::Handle<pat::MuonCollection> muons; iEvent.getByToken(muonToken_, muons); for (const pat::Muon &mu : *muons) { if (mu.pt() < 5 || !mu.isLooseMuon()) continue; printf("muon with pt %4.1f, dz(PV) %+5.3f, POG loose id %d, tight id %d\n", mu.pt(), mu.muonBestTrack()->dz(PV.position()), mu.isLooseMuon(), mu.isTightMuon(PV)); } edm::Handle<pat::ElectronCollection> electrons; iEvent.getByToken(electronToken_, electrons); for (const pat::Electron &el : *electrons) { if (el.pt() < 5) continue; printf("elec with pt %4.1f, supercluster eta %+5.3f, sigmaIetaIeta %.3f (%.3f with full5x5 shower shapes), lost hits %d, pass conv veto %d\n", el.pt(), el.superCluster()->eta(), el.sigmaIetaIeta(), el.full5x5_sigmaIetaIeta(), el.gsfTrack()->trackerExpectedHitsInner().numberOfLostHits(), el.passConversionVeto()); } edm::Handle<pat::PhotonCollection> photons; iEvent.getByToken(photonToken_, photons); for (const pat::Photon &pho : *photons) { if (pho.pt() < 20 or pho.chargedHadronIso()/pho.pt() > 0.3) continue; printf("phot with pt %4.1f, supercluster eta %+5.3f, sigmaIetaIeta %.3f (%.3f with full5x5 shower shapes)\n", pho.pt(), pho.superCluster()->eta(), pho.sigmaIetaIeta(), pho.full5x5_sigmaIetaIeta()); } edm::Handle<pat::TauCollection> taus; iEvent.getByToken(tauToken_, taus); for (const pat::Tau &tau : *taus) { if (tau.pt() < 20) continue; printf("tau with pt %4.1f, dxy signif %.1f, ID(byMediumCombinedIsolationDeltaBetaCorr3Hits) %.1f, lead candidate pt %.1f, pdgId %d \n", tau.pt(), tau.dxy_Sig(), tau.tauID("byMediumCombinedIsolationDeltaBetaCorr3Hits"), tau.leadCand()->pt(), tau.leadCand()->pdgId()); } edm::Handle<pat::JetCollection> jets; iEvent.getByToken(jetToken_, jets); int ijet = 0; for (const pat::Jet &j : *jets) { if (j.pt() < 20) continue; printf("jet with pt %5.1f (raw pt %5.1f), eta %+4.2f, btag CSV %.3f, CISV %.3f, pileup mva disc %+.2f\n", j.pt(), j.pt()*j.jecFactor("Uncorrected"), j.eta(), std::max(0.f,j.bDiscriminator("combinedSecondaryVertexBJetTags")), std::max(0.f,j.bDiscriminator("combinedInclusiveSecondaryVertexBJetTags")), j.userFloat("pileupJetId:fullDiscriminant")); if ((++ijet) == 1) { // for the first jet, let's print the leading constituents std::vector<reco::CandidatePtr> daus(j.daughterPtrVector()); std::sort(daus.begin(), daus.end(), [](const reco::CandidatePtr &p1, const reco::CandidatePtr &p2) { return p1->pt() > p2->pt(); }); // the joys of C++11 for (unsigned int i2 = 0, n = daus.size(); i2 < n && i2 <= 3; ++i2) { const pat::PackedCandidate &cand = dynamic_cast<const pat::PackedCandidate &>(*daus[i2]); printf(" constituent %3d: pt %6.2f, dz(pv) %+.3f, pdgId %+3d\n", i2,cand.pt(),cand.dz(PV.position()),cand.pdgId()); } } } edm::Handle<pat::JetCollection> fatjets; iEvent.getByToken(fatjetToken_, fatjets); for (const pat::Jet &j : *fatjets) { printf("AK8j with pt %5.1f (raw pt %5.1f), eta %+4.2f, mass %5.1f ungroomed, %5.1f pruned, %5.1f trimmed, %5.1f filtered. CMS TopTagger %.1f\n", j.pt(), j.pt()*j.jecFactor("Uncorrected"), j.eta(), j.mass(), j.userFloat("ak8PFJetsCHSPrunedLinks"), j.userFloat("ak8PFJetsCHSTrimmedLinks"), j.userFloat("ak8PFJetsCHSFilteredLinks"), j.userFloat("cmsTopTagPFJetsCHSLinksAK8")); } edm::Handle<pat::METCollection> mets; iEvent.getByToken(metToken_, mets); const pat::MET &met = mets->front(); printf("MET: pt %5.1f, phi %+4.2f, sumEt (%.1f). genMET %.1f. MET with JES up/down: %.1f/%.1f\n", met.pt(), met.phi(), met.sumEt(), met.genMET()->pt(), met.shiftedPt(pat::MET::JetEnUp), met.shiftedPt(pat::MET::JetEnDown)); printf("\n"); } //define this as a plug-in DEFINE_FWK_MODULE(MiniAnalyzer);
import FWCore.ParameterSet.Config as cms process = cms.Process("Demo") process.load("FWCore.MessageService.MessageLogger_cfi") process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(10) ) process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring( '/store/cmst3/user/gpetrucc/miniAOD/v1/TT_Tune4C_13TeV-pythia8-tauola_PU_S14_PAT.root' ) ) process.demo = cms.EDAnalyzer("MiniAnalyzer", vertices = cms.InputTag("offlineSlimmedPrimaryVertices"), muons = cms.InputTag("slimmedMuons"), electrons = cms.InputTag("slimmedElectrons"), taus = cms.InputTag("slimmedTaus"), photons = cms.InputTag("slimmedPhotons"), jets = cms.InputTag("slimmedJets"), fatjets = cms.InputTag("slimmedJetsAK8"), mets = cms.InputTag("slimmedMETs"), ) process.p = cms.Path(process.demo)
# import ROOT in batch mode import sys oldargv = sys.argv[:] sys.argv = [ '-b-' ] import ROOT ROOT.gROOT.SetBatch(True) sys.argv = oldargv # load FWLite C++ libraries ROOT.gSystem.Load("libFWCoreFWLite.so"); ROOT.gSystem.Load("libDataFormatsFWLite.so"); ROOT.AutoLibraryLoader.enable() # load FWlite python libraries from DataFormats.FWLite import Handle, Events muons, muonLabel = Handle("std::vector<pat::Muon>"), "slimmedMuons" electrons, electronLabel = Handle("std::vector<pat::Electron>"), "slimmedElectrons" photons, photonLabel = Handle("std::vector<pat::Photon>"), "slimmedPhotons" taus, tauLabel = Handle("std::vector<pat::Tau>"), "slimmedTaus" jets, jetLabel = Handle("std::vector<pat::Jet>"), "slimmedJets" fatjets, fatjetLabel = Handle("std::vector<pat::Jet>"), "slimmedJetsAK8" mets, metLabel = Handle("std::vector<pat::MET>"), "slimmedMETs" vertices, vertexLabel = Handle("std::vector<reco::Vertex>"), "offlineSlimmedPrimaryVertices" # open file (you can use 'edmFileUtil -d /store/whatever.root' to get the physical file name) events = Events("root://eoscms//eos/cms/store/cmst3/user/gpetrucc/miniAOD/v1/TT_Tune4C_13TeV-pythia8-tauola_PU_S14_PAT.root") for iev,event in enumerate(events): if iev >= 10: break event.getByLabel(muonLabel, muons) event.getByLabel(electronLabel, electrons) event.getByLabel(photonLabel, photons) event.getByLabel(tauLabel, taus) event.getByLabel(jetLabel, jets) event.getByLabel(fatjetLabel, fatjets) event.getByLabel(metLabel, mets) event.getByLabel(vertexLabel, vertices) print "\nEvent %d: run %6d, lumi %4d, event %12d" % (iev,event.eventAuxiliary().run(), event.eventAuxiliary().luminosityBlock(),event.eventAuxiliary().event()) # Vertices if len(vertices.product()) == 0 or vertices.product()[0].ndof() < 4: print "Event has no good primary vertex." continue else: PV = vertices.product()[0] print "PV at x,y,z = %+5.3f, %+5.3f, %+6.3f (ndof %.1f)" % (PV.x(), PV.y(), PV.z(), PV.ndof()) # Muons for i,mu in enumerate(muons.product()): if mu.pt() < 5 or not mu.isLooseMuon(): continue print "muon %2d: pt %4.1f, dz(PV) %+5.3f, POG loose id %d, tight id %d." % ( i, mu.pt(), mu.muonBestTrack().dz(PV.position()), mu.isLooseMuon(), mu.isTightMuon(PV)) # Electrons for i,el in enumerate(electrons.product()): if el.pt() < 5: continue print "elec %2d: pt %4.1f, supercluster eta %+5.3f, sigmaIetaIeta %.3f (%.3f with full5x5 shower shapes), lost hits %d, pass conv veto %d" % ( i, el.pt(), el.superCluster().eta(), el.sigmaIetaIeta(), el.full5x5_sigmaIetaIeta(), el.gsfTrack().trackerExpectedHitsInner().numberOfLostHits(), el.passConversionVeto()) # Photon for i,pho in enumerate(photons.product()): if pho.pt() < 20 or pho.chargedHadronIso()/pho.pt() > 0.3: continue print "phot %2d: pt %4.1f, supercluster eta %+5.3f, sigmaIetaIeta %.3f (%.3f with full5x5 shower shapes)" % ( i, pho.pt(), pho.superCluster().eta(), pho.sigmaIetaIeta(), pho.full5x5_sigmaIetaIeta()) # Tau for i,tau in enumerate(taus.product()): if tau.pt() < 20: continue print "tau %2d: pt %4.1f, dxy signif %.1f, ID(byMediumCombinedIsolationDeltaBetaCorr3Hits) %.1f, lead candidate pt %.1f, pdgId %d " % ( i, tau.pt(), tau.dxy_Sig(), tau.tauID("byMediumCombinedIsolationDeltaBetaCorr3Hits"), tau.leadCand().pt(), tau.leadCand().pdgId()) # Jets (standard AK4) for i,j in enumerate(jets.product()): if j.pt() < 20: continue print "jet %3d: pt %5.1f (raw pt %5.1f), eta %+4.2f, btag CSV %.3f, CISV %.3f, pileup mva disc %+.2f" % ( i, j.pt(), j.pt()*j.jecFactor('Uncorrected'), j.eta(), max(0,j.bDiscriminator("combinedSecondaryVertexBJetTags")), max(0,j.bDiscriminator("combinedInclusiveSecondaryVertexBJetTags")), j.userFloat("pileupJetId:fullDiscriminant")) if i == 0: # for the first jet, let's print the leading constituents constituents = [ j.daughter(i2) for i2 in xrange(j.numberOfDaughters()) ] constituents.sort(key = lambda c:c.pt(), reverse=True) for i2, cand in enumerate(constituents): print " constituent %3d: pt %6.2f, dz(pv) %+.3f, pdgId %+3d" % (i2,cand.pt(),cand.dz(PV.position()),cand.pdgId()) if i2 > 3: break # Fat AK8 Jets for i,j in enumerate(fatjets.product()): print "jet %3d: pt %5.1f (raw pt %5.1f), eta %+4.2f, mass %5.1f ungroomed, %5.1f pruned, %5.1f trimmed, %5.1f filtered. CMS TopTagger %.1f" % ( i, j.pt(), j.pt()*j.jecFactor('Uncorrected'), j.eta(), j.mass(), j.userFloat('ak8PFJetsCHSPrunedLinks'), j.userFloat('ak8PFJetsCHSTrimmedLinks'), j.userFloat('ak8PFJetsCHSFilteredLinks'), j.userFloat("cmsTopTagPFJetsCHSLinksAK8")) # MET: met = mets.product().front() print "MET: pt %5.1f, phi %+4.2f, sumEt (%.1f). rawMET: %.1f, genMET %.1f. MET with JES up/down: %.1f/%.1f" % ( met.pt(), met.phi(), met.sumEt(), met.uncorrectedPt(), #<<?-- seems to return the same as pt(): help needed from JetMET experts! met.genMET().pt(), met.shiftedPt(ROOT.pat.MET.JetEnUp), met.shiftedPt(ROOT.pat.MET.JetEnDown));
packedPFCandidates
collection, using as dataformat pat::PackedCandidatept()
, eta()
, phi()
, mass()
, energy()
, px()
, p4()
, polarP4()
. phiAtVtx()
is provided, returning the phi of the candidate's track at the vertex; this is identical to phi()
for the vast majority of the particles, but the two might differ for some of them if the calorimeters had contributed significantly in defining the 4-vector of the particle.
dxz()
, dz()
. dxz(point)
, dz(point)
). vertex()
method returns the position of the point of closest approach to the PV. This shouldn't be confused with the vertexRef()
method, that returns a reference to the PV itself.
fromPV()
: returns a number between 3 and 0 to define how tight the association with the first PV is: the tighest, 3 (PVUsedInFit
), is if the track is used in the first PV fit; 2 (PVTight
) is if the track is not used in the fit of any of the PVs, and is closest in z to the first PV, while 1 (PVLoose
) is if the track is closest in z to a PV other then the first one. 0 (NoPV
) is returned if the track is used in the fit of another PV.fromPV() > 1
; the definition used for CHS subtraction in jets is fromPV() > 0
.
lostInnerHits()
will return -1 (validHitInFirstPixelBarrelLayer
) if the track has a valid hit in the first pixel barrel layer, 0 (noLostInnerHits
) if it doesn't have such hit because of geometrical or detector inefficiencies (i.e. the hit wasn't expected to be there), 1 (oneLostHit
) if the track extrapolation towards the beamline crosses an active detector but no hit is found there, 2 (moreLostHits
) if there are at least two missing expected inner hits. gsfTrack()
, i.e. the usual cuts electron.gsfTrack()->trackerExpectedHitsInner().numberOfLostHits() <= X
can be implemented as cand.lostInnerHits() <= X
(but only for X equal to 0 or 1)
trackHighPurity()
will return true for charged candidates whose reco::Teack
had the highPurity
quality flag set.
dzError()
, dxyError()
numberOfHits()
, numberOfPixelHits()
)
reco::Track
of the candidate is provided by the pseudoTrack()
method, with: hitPattern()
and trackerExpectedHitsInner()
that yield the correct number of hits, pixel hits and the information returned by lostInnerHits()
highPurity
quality flag set, if the original track had it.
numberOfSourceCandidatePtrs()
and sourceCandidatePtr(index)
methods.
daughter(index)
and numberOfDaughters()
leadChargedHadrCand()
, leadNeutralCand()
, leadCand()
, signalCands()
, isolationCands()
, ... PF
inside, like signalPFCands()
, are not usable on MiniAOD)
originalObjectRef()
also points to that PF candidate.
associatedPackedPFCandidates()
method.
// system include files #include <memory> #include <cmath> // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DataFormats/Math/interface/deltaR.h" #include "DataFormats/PatCandidates/interface/PackedCandidate.h" #include "DataFormats/PatCandidates/interface/Muon.h" #include "DataFormats/PatCandidates/interface/Electron.h" #include "DataFormats/PatCandidates/interface/Jet.h" class PackedCandAnalyzer : public edm::EDAnalyzer { public: explicit PackedCandAnalyzer(const edm::ParameterSet&); ~PackedCandAnalyzer() {} private: virtual void analyze(const edm::Event&, const edm::EventSetup&) override; edm::EDGetTokenT<pat::ElectronCollection> electronToken_; edm::EDGetTokenT<pat::MuonCollection> muonToken_; edm::EDGetTokenT<pat::JetCollection> jetToken_; edm::EDGetTokenT<pat::PackedCandidateCollection> pfToken_; }; PackedCandAnalyzer::PackedCandAnalyzer(const edm::ParameterSet& iConfig): electronToken_(consumes<pat::ElectronCollection>(iConfig.getParameter<edm::InputTag>("electrons"))), muonToken_(consumes<pat::MuonCollection>(iConfig.getParameter<edm::InputTag>("muons"))), jetToken_(consumes<pat::JetCollection>(iConfig.getParameter<edm::InputTag>("jets"))), pfToken_(consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfCands"))) { } void PackedCandAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { edm::Handle<pat::MuonCollection> muons; iEvent.getByToken(muonToken_, muons); edm::Handle<pat::ElectronCollection> electrons; iEvent.getByToken(electronToken_, electrons); edm::Handle<pat::PackedCandidateCollection> pfs; iEvent.getByToken(pfToken_, pfs); edm::Handle<pat::JetCollection> jets; iEvent.getByToken(jetToken_, jets); std::vector<const reco::Candidate *> leptons; for (const pat::Muon &mu : *muons) leptons.push_back(&mu); for (const pat::Electron &el : *electrons) leptons.push_back(&el); for (const reco::Candidate *lep : leptons) { if (lep->pt() < 5) continue; // initialize sums double charged = 0, neutral = 0, pileup = 0; // now get a list of the PF candidates used to build this lepton, so to exclude them std::vector<reco::CandidatePtr> footprint; for (unsigned int i = 0, n = lep->numberOfSourceCandidatePtrs(); i < n; ++i) { footprint.push_back(lep->sourceCandidatePtr(i)); } // now loop on pf candidates for (unsigned int i = 0, n = pfs->size(); i < n; ++i) { const pat::PackedCandidate &pf = (*pfs)[i]; if (deltaR(pf,*lep) < 0.2) { // pfcandidate-based footprint removal if (std::find(footprint.begin(), footprint.end(), reco::CandidatePtr(pfs,i)) != footprint.end()) { continue; } if (pf.charge() == 0) { if (pf.pt() > 0.5) neutral += pf.pt(); } else if (pf.fromPV() >= 2) { charged += pf.pt(); } else { if (pf.pt() > 0.5) pileup += pf.pt(); } } } // do deltaBeta double iso = charged + std::max(0.0, neutral-0.5*pileup); printf("%-8s of pt %6.1f, eta %+4.2f: relIso = %5.2f\n", abs(lep->pdgId())==13 ? "muon" : "electron", lep->pt(), lep->eta(), iso/lep->pt()); } // Let's compute the fraction of charged pt from particles with dz < 0.1 cm for (const pat::Jet &j : *jets) { if (j.pt() < 40 || fabs(j.eta()) > 2.4) continue; double in = 0, out = 0; for (unsigned int id = 0, nd = j.numberOfDaughters(); id < nd; ++id) { const pat::PackedCandidate &dau = dynamic_cast<const pat::PackedCandidate &>(*j.daughter(id)); if (dau.charge() == 0) continue; (fabs(dau.dz())<0.1 ? in : out) += dau.pt(); } double sum = in + out; printf("Jet with pt %6.1f, eta %+4.2f, beta(0.1) = %+5.3f, pileup mva disc %+.2f\n", j.pt(),j.eta(), sum ? in/sum : 0, j.userFloat("pileupJetId:fullDiscriminant")); } } //define this as a plug-in DEFINE_FWK_MODULE(PackedCandAnalyzer);
import FWCore.ParameterSet.Config as cms process = cms.Process("Demo") process.load("FWCore.MessageService.MessageLogger_cfi") process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(10) ) process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring( '/store/cmst3/user/gpetrucc/miniAOD/v1/TT_Tune4C_13TeV-pythia8-tauola_PU_S14_PAT.root' ) ) process.demo = cms.EDAnalyzer("PackedCandAnalyzer", electrons = cms.InputTag("slimmedElectrons"), muons = cms.InputTag("slimmedMuons"), jets = cms.InputTag("slimmedJets"), pfCands = cms.InputTag("packedPFCandidates"), ) process.p = cms.Path(process.demo)
# after loading ROOT and FWlite libraries as described in the introduction # define deltaR from math import hypot, pi def deltaR(a,b): dphi = abs(a.phi()-b.phi()); if dphi > pi: dphi = 2*pi-dphi return hypot(a.eta()-b.eta(),dphi) muons, muonLabel = Handle("std::vector<pat::Muon>"), "slimmedMuons" electrons, electronLabel = Handle("std::vector<pat::Electron>"), "slimmedElectrons" jets, jetLabel = Handle("std::vector<pat::Jet>"), "slimmedJets" pfs, pfLabel = Handle("std::vector<pat::PackedCandidate>"), "packedPFCandidates" # open file (you can use 'edmFileUtil -d /store/whatever.root' to get the physical file name) events = Events("root://eoscms//eos/cms/store/cmst3/user/gpetrucc/miniAOD/v1/TT_Tune4C_13TeV-pythia8-tauola_PU_S14_PAT.root") for iev,event in enumerate(events): event.getByLabel(muonLabel, muons) event.getByLabel(electronLabel, electrons) event.getByLabel(pfLabel, pfs) event.getByLabel(jetLabel, jets) print "\nEvent %d: run %6d, lumi %4d, event %12d" % (iev,event.eventAuxiliary().run(), event.eventAuxiliary().luminosityBlock(),event.eventAuxiliary().event()) # Let's compute lepton PF Isolation with R=0.2, 0.5 GeV threshold on neutrals, and deltaBeta corrections leps = [ p for p in muons.product() ] + [ p for p in electrons.product() ] for lep in leps: # skip those below 5 GeV, which we don't care about if lep.pt() < 5: continue # initialize sums charged = 0 neutral = 0 pileup = 0 # now get a list of the PF candidates used to build this lepton, so to exclude them footprint = set() for i in xrange(lep.numberOfSourceCandidatePtrs()): footprint.add(lep.sourceCandidatePtr(i).key()) # the key is the index in the pf collection # now loop on pf candidates for ipf,pf in enumerate(pfs.product()): if deltaR(pf,lep) < 0.2: # pfcandidate-based footprint removal if ipf in footprint: continue # add up if (pf.charge() == 0): if pf.pt() > 0.5: neutral += pf.pt() elif pf.fromPV() >= 2: charged += pf.pt() else: if pf.pt() > 0.5: pileup += pf.pt() # do deltaBeta iso = charged + max(0, neutral-0.5*pileup) print "%-8s of pt %6.1f, eta %+4.2f: relIso = %5.2f" % ( "muon" if abs(lep.pdgId())==13 else "electron", lep.pt(), lep.eta(), iso/lep.pt()) # Let's compute the fraction of charged pt from particles with dz < 0.1 cm for i,j in enumerate(jets.product()): if j.pt() < 40 or abs(j.eta()) > 2.4: continue sums = [0,0] for id in xrange(j.numberOfDaughters()): dau = j.daughter(id) if (dau.charge() == 0): continue sums[ abs(dau.dz())<0.1 ] += dau.pt() sum = sums[0]+sums[1] print "Jet with pt %6.1f, eta %+4.2f, beta(0.1) = %+5.3f, pileup mva disc %+.2f" % ( j.pt(),j.eta(), sums[1]/sum if sum else 0, j.userFloat("pileupJetId:fullDiscriminant")) if iev > 10: break
charge()
method returns always negative for PF candidates that are electrons or muons (the pdgId is instead correct, +11/+13 for negative leptons, -11/-13 for positive leptons)pat::Electron::genParticle() pat::Muon::genParticle() pat::Jet::partonFlavour()The only important difference wrt normal PAT is that not all gen particles are stored. In fact gen particles are stored in two different collections as explained below. The prunedGenParticles are standard GenParticle selected with the GenParticlePruner, in particular
pat::Electron::genParticle()
)
The packedGenParticles collection contains all status=1 GenParticle in a reduced format similar to the one used for PFCandidates. Besides the 4-vector a link to the first ancestor is saved in the prunedGenParticles collection.
This collection is used to re-cluster the MC truth (e.g. if you want to study a different jet algorithm or some substructure techniques).
Caveat: current imlpementation of the ref to first ancestor is missing a few accessors, the only access is via PackedGenParticle::mother(0) and returns a pointer. This has to be fixed in later version to give full access to the motherRef and a proper implementation of numberOfMothers (currently returning always 0)
The following examples show how to navigate between the two collections: the B mesons (500 < pdg ID < 600) are looked for in the pruned collection (because B are important particles, but they are not stable) and then we search which of the stable (status = 1) particles originated from a B decay. In order to do so we first ask to each packed candidate its "pruned" mother (NB, it is actually the first ancestor that survived the pruning), then we navigate back the pruned collection from such initial mother and see if we find the B meson.
import ROOT import sys from DataFormats.FWLite import Events, Handle from math import * def isAncestor(a,p) : if a == p : return True for i in xrange(0,p.numberOfMothers()) : if isAncestor(a,p.mother(i)) : return True return False events = Events (['root://cms-xrd-global.cern.ch//store/mc/Spring14miniaod/TTJets_MSDecaysCKM_central_Tune4C_13TeV-madgraph-tauola/MINIAODSIM/PU20bx25_POSTLS170_V5-v1/00000/F6EDDC10-8DFC-E311-BC5D-0025905A60D6.root']) handlePruned = Handle ("std::vector<reco::GenParticle>") handlePacked = Handle ("std::vector<pat::PackedGenParticle>") labelPruned = ("prunedGenParticles") labelPacked = ("packedGenParticles") # loop over events count= 0 for event in events: event.getByLabel (labelPacked, handlePacked) event.getByLabel (labelPruned, handlePruned) # get the product packed = handlePacked.product() pruned = handlePruned.product() for p in pruned : if abs(p.pdgId()) > 500 and abs(p.pdgId()) < 600 : print "PdgId : %s pt : %s eta : %s phi : %s" %(p.pdgId(),p.pt(),p.eta(),p.phi()) print " daughters" for pa in packed: mother = pa.mother(0) if mother and isAncestor(p,mother) : print " PdgId : %s pt : %s eta : %s phi : %s" %(pa.pdgId(),pa.pt(),pa.eta(),pa.phi())
// Original Author: Andrea RIZZI // Created: Mon, 07 Jul 2014 07:56:38 GMT // system include files #include <memory> // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DataFormats/PatCandidates/interface/PackedGenParticle.h" #include "DataFormats/Candidate/interface/Candidate.h" #include "DataFormats/HepMCCandidate/interface/GenParticle.h" // // class declaration // class MiniAODGenPartAnalyzer : public edm::EDAnalyzer { public: explicit MiniAODGenPartAnalyzer(const edm::ParameterSet&); ~MiniAODGenPartAnalyzer(); bool isAncestor(const reco::Candidate * ancestor, const reco::Candidate * particle); private: virtual void beginJob() override; virtual void analyze(const edm::Event&, const edm::EventSetup&) override; virtual void endJob() override; edm::EDGetTokenT<edm::View<reco::GenParticle> > prunedGenToken_; edm::EDGetTokenT<edm::View<pat::PackedGenParticle> > packedGenToken_; }; MiniAODGenPartAnalyzer::MiniAODGenPartAnalyzer(const edm::ParameterSet& iConfig): prunedGenToken_(consumes<edm::View<reco::GenParticle> >(iConfig.getParameter<edm::InputTag>("pruned"))), packedGenToken_(consumes<edm::View<pat::PackedGenParticle> >(iConfig.getParameter<edm::InputTag>("packed"))) { } MiniAODGenPartAnalyzer::~MiniAODGenPartAnalyzer() { } //Check recursively if any ancestor of particle is the given one bool MiniAODGenPartAnalyzer::isAncestor(const reco::Candidate* ancestor, const reco::Candidate * particle) { //particle is already the ancestor if(ancestor == particle ) return true; //otherwise loop on mothers, if any and return true if the ancestor is found for(size_t i=0;i< particle->numberOfMothers();i++) { if(isAncestor(ancestor,particle->mother(i))) return true; } //if we did not return yet, then particle and ancestor are not relatives return false; } void MiniAODGenPartAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { using namespace edm; using namespace reco; using namespace pat; // Pruned particles are the one containing "important" stuff Handle<edm::View<reco::GenParticle> > pruned; iEvent.getByToken(prunedGenToken_,pruned); // Packed particles are all the status 1, so usable to remake jets // The navigation from status 1 to pruned is possible (the other direction should be made by hand) Handle<edm::View<pat::PackedGenParticle> > packed; iEvent.getByToken(packedGenToken_,packed); //let's try to find all status1 originating directly from a B meson decay for(size_t i=0; i<pruned->size();i++){ if(abs((*pruned)[i].pdgId()) > 500 && abs((*pruned)[i].pdgId()) <600){ const Candidate * bMeson = &(*pruned)[i]; std::cout << "PdgID: " << bMeson->pdgId() << " pt " << bMeson->pt() << " eta: " << bMeson->eta() << " phi: " << bMeson->phi() << std::endl; std::cout << " found daugthers: " << std::endl; for(size_t j=0; j<packed->size();j++){ //get the pointer to the first survied ancestor of a given packed GenParticle in the prunedCollection const Candidate * motherInPrunedCollection = (*packed)[j].mother(0) ; if(motherInPrunedCollection != nullptr && isAncestor( bMeson , motherInPrunedCollection)){ std::cout << " PdgID: " << (*packed)[j].pdgId() << " pt " << (*packed)[j].pt() << " eta: " << (*packed)[j].eta() << " phi: " << (*packed)[j].phi() << std::endl; } } } } } // ------------ method called once each job just before starting event loop ------------ void MiniAODGenPartAnalyzer::beginJob() { } // ------------ method called once each job just after ending the event loop ------------ void MiniAODGenPartAnalyzer::endJob() { } DEFINE_FWK_MODULE(MiniAODGenPartAnalyzer);
import FWCore.ParameterSet.Config as cms process = cms.Process("Demo") process.load("FWCore.MessageService.MessageLogger_cfi") process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1) ) process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring("root://cms-xrd-global.cern.ch//store/mc/Spring14miniaod/TTJets_MSDecaysCKM_central_Tune4C_13TeV-madgraph-tauola/MINIAODSIM/PU20bx25_POSTLS170_V5-v1/00000/F6EDDC10-8DFC-E311-BC5D-0025905A60D6.root") ) process.demo = cms.EDAnalyzer('MiniAODGenPartAnalyzer', packed = cms.InputTag("packedGenParticles"), pruned = cms.InputTag("prunedGenParticles") ) process.p = cms.Path(process.demo)
DataFormats/PatCandidates DataFormats/HepMCCandidate
slimmedGenJets
, made from ak4GenJets
, i.e. using anti-kT clustering out of stable gen particles.
In CMSSW 70X (CSA14) and 72X (Phys14) campaign, neutrinos are included in the gen jets, while starting from 74X neutrinos and other invisible BSM particles are excluded.
Links to the daughters are available through the daughter(idx)
and numberOfDaughters()
methods, and they will point into the collection of packed gen candidates described below.getGenConstituents
method instead will NOT work, since they explicitly require the daughter to be a full reco::GenParticle
and not a packed one.
known Features in CSA14 and PHYS14 isAvailable
method of the reco::CandidatePtr
returned by daughterPtr(index)
can be used to check if a gen particle is available. parameterSetID()
method of the trigger results object).
Trigger objects associated to filters in the HLT are saved as instances of pat::TriggerObjectStandAloneedm::TriggerNames
instance, as shown in the example code at the bottom of this section.
Trigger prescales are encoded for each path into an pat::PackedTriggerPrescalesedm::TriggerNames
if access by path name is needed, just like for the TriggerResults
.
Some extra trigger-level information copied directly from the AOD could also be available, namely the l1extra
and L1GlobalTriggerReadoutRecord
, though they might be missing in some versions of the miniAODs (CMSSW_7_0_6_patch1
selects them only if they're produced in the HLT
process, which might not be the case in production; this will be addressed in future miniAOD versions)
// system include files #include <memory> #include <cmath> // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "DataFormats/Math/interface/deltaR.h" #include "FWCore/Common/interface/TriggerNames.h" #include "DataFormats/Common/interface/TriggerResults.h" #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h" #include "DataFormats/PatCandidates/interface/PackedTriggerPrescales.h" class MiniAODTriggerAnalyzer : public edm::EDAnalyzer { public: explicit MiniAODTriggerAnalyzer(const edm::ParameterSet&); ~MiniAODTriggerAnalyzer() {} private: virtual void analyze(const edm::Event&, const edm::EventSetup&) override; edm::EDGetTokenT<edm::TriggerResults> triggerBits_; edm::EDGetTokenT<pat::TriggerObjectStandAloneCollection> triggerObjects_; edm::EDGetTokenT<pat::PackedTriggerPrescales> triggerPrescales_; }; MiniAODTriggerAnalyzer::MiniAODTriggerAnalyzer(const edm::ParameterSet& iConfig): triggerBits_(consumes<edm::TriggerResults>(iConfig.getParameter<edm::InputTag>("bits"))), triggerObjects_(consumes<pat::TriggerObjectStandAloneCollection>(iConfig.getParameter<edm::InputTag>("objects"))), triggerPrescales_(consumes<pat::PackedTriggerPrescales>(iConfig.getParameter<edm::InputTag>("prescales"))) { } void MiniAODTriggerAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { edm::Handle<edm::TriggerResults> triggerBits; edm::Handle<pat::TriggerObjectStandAloneCollection> triggerObjects; edm::Handle<pat::PackedTriggerPrescales> triggerPrescales; iEvent.getByToken(triggerBits_, triggerBits); iEvent.getByToken(triggerObjects_, triggerObjects); iEvent.getByToken(triggerPrescales_, triggerPrescales); const edm::TriggerNames &names = iEvent.triggerNames(*triggerBits); std::cout << "\n === TRIGGER PATHS === " << std::endl; for (unsigned int i = 0, n = triggerBits->size(); i < n; ++i) { std::cout << "Trigger " << names.triggerName(i) << ", prescale " << triggerPrescales->getPrescaleForIndex(i) << ": " << (triggerBits->accept(i) ? "PASS" : "fail (or not run)") << std::endl; } std::cout << "\n === TRIGGER OBJECTS === " << std::endl; for (pat::TriggerObjectStandAlone obj : *triggerObjects) { // note: not "const &" since we want to call unpackPathNames obj.unpackPathNames(names); std::cout << "\tTrigger object: pt " << obj.pt() << ", eta " << obj.eta() << ", phi " << obj.phi() << std::endl; // Print trigger object collection and type std::cout << "\t Collection: " << obj.collection() << std::endl; std::cout << "\t Type IDs: "; for (unsigned h = 0; h < obj.filterIds().size(); ++h) std::cout << " " << obj.filterIds()[h] ; std::cout << std::endl; // Print associated trigger filters std::cout << "\t Filters: "; for (unsigned h = 0; h < obj.filterLabels().size(); ++h) std::cout << " " << obj.filterLabels()[h]; std::cout << std::endl; std::vector<std::string> pathNamesAll = obj.pathNames(false); std::vector<std::string> pathNamesLast = obj.pathNames(true); // Print all trigger paths, for each one record also if the object is associated to a 'l3' filter (always true for the // definition used in the PAT trigger producer) and if it's associated to the last filter of a successfull path (which // means that this object did cause this trigger to succeed; however, it doesn't work on some multi-object triggers) std::cout << "\t Paths (" << pathNamesAll.size()<<"/"<<pathNamesLast.size()<<"): "; for (unsigned h = 0, n = pathNamesAll.size(); h < n; ++h) { bool isBoth = obj.hasPathName( pathNamesAll[h], true, true ); bool isL3 = obj.hasPathName( pathNamesAll[h], false, true ); bool isLF = obj.hasPathName( pathNamesAll[h], true, false ); bool isNone = obj.hasPathName( pathNamesAll[h], false, false ); std::cout << " " << pathNamesAll[h]; if (isBoth) std::cout << "(L,3)"; if (isL3 && !isBoth) std::cout << "(*,3)"; if (isLF && !isBoth) std::cout << "(L,*)"; if (isNone && !isBoth && !isL3 && !isLF) std::cout << "(*,*)"; } std::cout << std::endl; } std::cout << std::endl; } //define this as a plug-in DEFINE_FWK_MODULE(MiniAODTriggerAnalyzer);
import FWCore.ParameterSet.Config as cms process = cms.Process("Demo") process.load("FWCore.MessageService.MessageLogger_cfi") process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(10) ) process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring( '/store/cmst3/user/gpetrucc/miniAOD/v1/TT_Tune4C_13TeV-pythia8-tauola_PU_S14_PAT.root' ) ) process.demo = cms.EDAnalyzer("MiniAODTriggerAnalyzer", bits = cms.InputTag("TriggerResults","","HLT"), prescales = cms.InputTag("patTrigger"), objects = cms.InputTag("selectedPatTrigger"), ) process.p = cms.Path(process.demo)
# import ROOT in batch mode import sys oldargv = sys.argv[:] sys.argv = [ '-b-' ] import ROOT ROOT.gROOT.SetBatch(True) sys.argv = oldargv # load FWLite C++ libraries ROOT.gSystem.Load("libFWCoreFWLite.so"); ROOT.gSystem.Load("libDataFormatsFWLite.so"); ROOT.AutoLibraryLoader.enable() # load FWlite python libraries from DataFormats.FWLite import Handle, Events triggerBits, triggerBitLabel = Handle("edm::TriggerResults"), ("TriggerResults","","HLT") triggerObjects, triggerObjectLabel = Handle("std::vector<pat::TriggerObjectStandAlone>"), "selectedPatTrigger" triggerPrescales, triggerPrescaleLabel = Handle("pat::PackedTriggerPrescales"), "patTrigger" # open file (you can use 'edmFileUtil -d /store/whatever.root' to get the physical file name) events = Events("root://eoscms//eos/cms/store/cmst3/user/gpetrucc/miniAOD/v1/TT_Tune4C_13TeV-pythia8-tauola_PU_S14_PAT.root") for iev,event in enumerate(events): event.getByLabel(triggerBitLabel, triggerBits) event.getByLabel(triggerObjectLabel, triggerObjects) event.getByLabel(triggerPrescaleLabel, triggerPrescales) print "\nEvent %d: run %6d, lumi %4d, event %12d" % (iev,event.eventAuxiliary().run(), event.eventAuxiliary().luminosityBlock(),event.eventAuxiliary().event()) print "\n === TRIGGER PATHS ===" names = event.object().triggerNames(triggerBits.product()) for i in xrange(triggerBits.product().size()): print "Trigger ", names.triggerName(i), ", prescale ", triggerPrescales.product().getPrescaleForIndex(i), ": ", ("PASS" if triggerBits.product().accept(i) else "fail (or not run)") print "\n === TRIGGER OBJECTS ===" for j,to in enumerate(triggerObjects.product()): to.unpackPathNames(names); print "Trigger object pt %6.2f eta %+5.3f phi %+5.3f " % (to.pt(),to.eta(),to.phi()) print " collection: ", to.collection() print " type ids: ", ", ".join([str(f) for f in to.filterIds()]) print " filters: ", ", ".join([str(f) for f in to.filterLabels()]) pathslast = set(to.pathNames(True)) print " paths: ", ", ".join([("%s*" if f in pathslast else "%s")%f for f in to.filterLabels()]) if iev > 10: break
offlineBeamSpot
collection.
For the primary vertices, a collection offlineSlimmedPrimaryVertices
is provided, that has the same content as the AOD offlinePrimaryVertices
collection except that vertices don't contain track references anymore (since there's not tracks in MiniAOD anyway).
edm::TriggerResults
of the PAT
process); the individual filters can be accessed with the same code as for the HLT paths, except of course for the process name.
The list of all the paths and filters included and their definitions can be found in PhysicsTools/PatAlgos/python/slimming/metFilterPaths_cff.pyhcalnoise
.
import FWCore.ParameterSet.Config as cms process = cms.Process("EX") process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring("root://cms-xrd-global.cern.ch//store/mc/Spring14miniaod/TTJets_MSDecaysCKM_central_Tune4C_13TeV-madgraph-tauola/MINIAODSIM/PU20bx25_POSTLS170_V5-v1/00000/F6EDDC10-8DFC-E311-BC5D-0025905A60D6.root") ) process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(10) ) process.OUT = cms.OutputModule("PoolOutputModule", fileName = cms.untracked.string('test.root'), outputCommands = cms.untracked.vstring(['drop *','keep *_*_*_PAT']) #keep all input miniAOD content, more stuff added below ) process.endpath= cms.EndPath(process.OUT) from RecoJets.JetProducers.ak5PFJets_cfi import ak5PFJets from RecoJets.JetProducers.ak5GenJets_cfi import ak5GenJets from RecoMET.METProducers.PFMET_cfi import pfMet # Select candidates that would pass CHS requirements process.chs = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV")) #makes chs ak5 jets (instead of ak4 that are default in miniAOD 70X) process.ak5PFJetsCHS = ak5PFJets.clone(src = 'chs') #let's also make non-chs ak5 jets process.ak5PFJets = ak5PFJets.clone(src = 'packedPFCandidates') process.OUT.outputCommands.append("keep *_ak5PFJets_*_EX") process.OUT.outputCommands.append("keep *_ak5PFJetsCHS_*_EX") # if we really want to study the ak5 vs ak4 we may need to remake gen Jets in ak5 too # in order to do so we use the "all status 1" gen particles (packedGenParticles) process.ak5GenJets = ak5GenJets.clone(src = 'packedGenParticles') process.OUT.outputCommands.append("keep *_ak5GenJets_*_EX") # the following part is needed if you want to run b-tagging on the freshly made jets # CAVEAT: it is not 100% the same b-tagging as in RECO, but performance plots are almost identical # As tracks are not stored in miniAOD, and b-tag fwk for CMSSW < 72X does not accept candidates # we need to recreate tracks and pv for btagging in standard reco format: process.load('RecoBTag.Configuration.RecoBTag_cff') process.load('RecoJets.Configuration.RecoJetAssociations_cff') process.load('PhysicsTools.PatAlgos.slimming.unpackedTracksAndVertices_cfi') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') process.load('Configuration.StandardSequences.Geometry_cff') process.load('Configuration.StandardSequences.MagneticField_38T_cff') #process.load('TrackingTools.TransientTrack.TransientTrackBuilder_cfi') process.GlobalTag.globaltag = 'PLS170_V7AN1::All' process.ak5JetTracksAssociatorAtVertexPF.jets = cms.InputTag("ak5PFJetsCHS") process.ak5JetTracksAssociatorAtVertexPF.tracks = cms.InputTag("unpackedTracksAndVertices") process.impactParameterTagInfos.primaryVertex = cms.InputTag("unpackedTracksAndVertices") process.inclusiveSecondaryVertexFinderTagInfos.extSVCollection = cms.InputTag("unpackedTracksAndVertices","secondary","") process.combinedSecondaryVertex.trackMultiplicityMin = 1 process.OUT.outputCommands.append("keep *_*VertexBJetTags_*_EX") #runs all Vertex btaggers process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True), # while the timing of this is not reliable in unscheduled mode, it still helps understanding what was actually run allowUnscheduled = cms.untracked.bool(True) )
import FWCore.ParameterSet.Config as cms process = cms.Process("S2") # Input source process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring("root://cms-xrd-global.cern.ch//store/mc/Spring14miniaod/TTJets_MSDecaysCKM_central_Tune4C_13TeV-madgraph-tauola/MINIAODSIM/PU20bx25_POSTLS170_V5-v1/00000/F6EDDC10-8DFC-E311-BC5D-0025905A60D6.root") ) process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1) ) #select isolated muons and electrons collections #tune the requirements to whatever ID and isolation you prefer process.selectedMuons = cms.EDFilter("CandPtrSelector", src = cms.InputTag("slimmedMuons"), cut = cms.string('''abs(eta)<2.5 && pt>10. && (pfIsolationR04().sumChargedHadronPt+ max(0.,pfIsolationR04().sumNeutralHadronEt+ pfIsolationR04().sumPhotonEt- 0.50*pfIsolationR04().sumPUPt))/pt < 0.20 && (isPFMuon && (isGlobalMuon || isTrackerMuon) )''')) process.selectedElectrons = cms.EDFilter("CandPtrSelector", src = cms.InputTag("slimmedElectrons"), cut = cms.string('''abs(eta)<2.5 && pt>20. && gsfTrack.isAvailable() && gsfTrack.trackerExpectedHitsInner.numberOfLostHits<2 && (pfIsolationVariables().sumChargedHadronPt+ max(0.,pfIsolationVariables().sumNeutralHadronEt+ pfIsolationVariables().sumPhotonEt- 0.5*pfIsolationVariables().sumPUPt))/pt < 0.15''')) ### Do "projections" # first select the packedCandidates passing the loose "fromPV()" requirement (equivalent to CHS definition used for Jets in Run I) process.pfCHS = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV")) # then remove the previously selected muons process.pfNoMuonCHS = cms.EDProducer("CandPtrProjector", src = cms.InputTag("pfCHS"), veto = cms.InputTag("selectedMuons")) # then remove the previously selected electrons process.pfNoElectronsCHS = cms.EDProducer("CandPtrProjector", src = cms.InputTag("pfNoMuonCHS"), veto = cms.InputTag("selectedElectrons")) #Import RECO jet producer for ak4 PF and GEN jet from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets from RecoJets.JetProducers.ak4GenJets_cfi import ak4GenJets process.ak4PFJetsCHS = ak4PFJets.clone(src = 'pfNoElectronsCHS', doAreaFastjet = True) process.ak4GenJets = ak4GenJets.clone(src = 'packedGenParticles') # The following is make patJets, but EI is done with the above process.load("PhysicsTools.PatAlgos.producersLayer1.patCandidates_cff") process.load("Configuration.EventContent.EventContent_cff") process.load('Configuration.StandardSequences.Geometry_cff') process.load('Configuration.StandardSequences.MagneticField_38T_cff') process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') process.GlobalTag.globaltag = 'PLS170_V7AN1::All' from PhysicsTools.PatAlgos.tools.jetTools import addJetCollection addJetCollection( process, postfix = "", labelName = 'AK4PFCHS', jetSource = cms.InputTag('ak4PFJetsCHS'), trackSource = cms.InputTag('unpackedTracksAndVertices'), pvSource = cms.InputTag('unpackedTracksAndVertices'), jetCorrections = ('AK4PFchs', cms.vstring(['L1FastJet', 'L2Relative', 'L3Absolute']), 'Type-2'), btagDiscriminators = [ 'combinedSecondaryVertexBJetTags' ] ,algo= 'AK', rParam = 0.4 ) #adjust MC matching process.patJetGenJetMatchAK4PFCHS.matched = "ak4GenJets" process.patJetPartonMatchAK4PFCHS.matched = "prunedGenParticles" process.patJetPartons.particles = "prunedGenParticles" #adjust PV used for Jet Corrections process.patJetCorrFactorsAK4PFCHS.primaryVertices = "offlineSlimmedPrimaryVertices" # the following part is needed if you want to run b-tagging on the freshly made jets # CAVEAT: it is not 100% the same b-tagging as in RECO, but performance plots are almost identical # As tracks are not stored in miniAOD, and b-tag fwk for CMSSW < 72X does not accept candidates # we need to recreate tracks and pv for btagging in standard reco format: process.load('PhysicsTools.PatAlgos.slimming.unpackedTracksAndVertices_cfi') process.combinedSecondaryVertex.trackMultiplicityMin = 1 #needed for CMSSW < 71X #new PAT default running is "unscheduled" so we just need to say in the outputCommands what we want to store process.options = cms.untracked.PSet( allowUnscheduled = cms.untracked.bool(True) ) process.OUT = cms.OutputModule("PoolOutputModule", fileName = cms.untracked.string('test.root'), outputCommands = cms.untracked.vstring(['drop *','keep patJets_patJetsAK4PFCHS_*_*','keep *_*_*_PAT']) ) process.endpath= cms.EndPath(process.OUT)
cmsDriver.py miniAOD-prod -s PAT --eventcontent [ MINIAOD | MINIAODSIM ] --runUnscheduled [ --data | --mc [ --fast ] ] --filein xxx --conditions yyy --no_exec(the
--fast
is needed on fast sim to switch off some MET filters)
for example, for Phys14 MC production in CMSSW_7_2_0
cmsDriver.py miniAOD-prod -s PAT --eventcontent MINIAODSIM --runUnscheduled --mc --filein /store/mc/Phys14DR/TTJets_MSDecaysCKM_central_Tune4C_13TeV-madgraph-tauola/AODSIM/PU20bx25_PHYS14_25_V1-v1/00000/0008EBB4-2475-E411-9F25-0025907DC9F8.root --conditions PHYS14_25_V1 -n 100 --no_execnote: apparently in 7.2.X and later, the
--conditions
option take global tags without the extra ::All
postifx that was there in older releases
The global tags, from https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideFrontierConditions#miniAOD_production are:
GT name | Comments |
---|---|
PHYS14_25_V2![]() |
Phys14 GT for 25ns in 72X (asymptotic alignment and calibration scenario), with the new Phys14 jet energy |
PHYS14_25_V1![]() |
Phys14 GT for 25ns in 72X (asymptotic alignment and calibration scenario), with CSA14 jet energy corrections as used in the central Phys14 production |
PLS170_V7AN1![]() |
CSA14 GT for 25ns in 70X (asymptotic alignment and calibration scenario), as POSTLS170_V7![]() ![]() |
PLS170_V6AN1![]() |
CSA14 GT for 50ns in 70X (more pessimistic alignment and calibration scenario), as POSTLS170_V6![]() ![]() |
GR_70_V2_AN1![]() |
CSA14 GT for data in 70X, as GR_R_70_V2![]() ![]() |