cmsrel CMSSW_9_2_4
from DataFormats.FWLite import Handle, Events
iEvent.getByToken(muons_, muons);
boh?
CMSSW_9_2_4
release and assume you're working on a SLC6 node (e.g. lxplus.cern.ch
) . To setup the release, you can do
cmsrel CMSSW_9_2_4 cd CMSSW_9_2_4/src cmsenvAs input test files in the examples we will use
/store/relval/CMSSW_8_0_3/RelValTTbarLepton_13/MINIAODSIM/80X_mcRun2_asymptotic_2016_v3_gs7120p2NewGTv3-v1/00000/4E291B64-DCEF-E511-B99D-0025905A60B0.root
which contains 6k 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.FWLiteEnabler.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/relval/CMSSW_8_0_3/RelValTTbarLepton_13/MINIAODSIM/80X_mcRun2_asymptotic_2016_v3_gs7120p2NewGTv3-v1/00000/4E291B64-DCEF-E511-B99D-0025905A60B0.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 tunePMuonBestTrack |
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 decayModeFindingNewDMs id |
All POG-supported tau id discriminators are included. Links to the PF candidates are also provided. Note: different miniAOD version use different tau reconstructions, see below in the Tau entry |
slimmedTausBoosted ![]() |
std::vector<pat::Tau> |
taus from boosted tau reconstruction seeded by subjets (instead of jets) from hpsPFTauProducer with pT > 18 GeV, and passing the basic decayModeFindingNewDMs id |
All id discriminators of standard taus are available also for boosted taus see below in the Tau entry | |
Photons | slimmedPhotons |
std::vector<pat::Photon> |
gedPhotons with pT > 14 GeV and hadTowOverEm() < 0.15 Since 74X In version 2 MiniAOD, keep also pt 10-14 GeV if chargedHadronIso() < 10 |
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() |
oniaPhotonCandidates ![]() |
std::vector<pat::CompositeCandidate> |
Conversions with highPurity or generalTracksOnly quality, rho > 1.5 cm |
Loe energy conversions for reconstruction of radiative decays are store, electron tracks are store as reco::Track |
|
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. |
slimmedJetsPuppi |
std::vector<pat::Jet> |
puppi jets with pT > 20 GeV | L1+L2+L3+residual corrections are applied; b-tagging information is embedded. Links are provided to the constituent PF candidates. | |
slimmedGenJets |
std::vector<reco::GenJet> |
ak4GenJetsNoNu with pT > 8 GeV |
links to constituents (packed gen particles) are available | |
slimmedJetsAK8 |
std::vector<pat::Jet> |
ak8PFJetsPUPPI with pT > 170 GeV (for substructure) |
L1+L2+L3+residual corrections are applied (AK8PFPuppi corrections used); some precomputed substructure info is provided, and also links to the constituent PF candidates. Subjets themselves are also stored. | |
slimmedJetsAK8PFPuppiSoftDropPacked |
std::vector<pat::Jet> |
Subjets of PUPPI soft drop algorithm | L1+L2+L3+residual corrections are applied (AK4PFpuppi corrections used); b-tagging information is embedded. Links are provided to the constituent PF candidates. | |
slimmedGenJetsAK8 |
std::vector<reco::GenJet> |
ak8GenJetsNoNu with pT > 150 GeV |
links to constituents (packed gen particles) are available | |
MET | slimmedMETs |
std::vector<pat::MET> |
the type1 PF MET | MET uncertainties are provided Contains also the calo, raw pf and gen met values. |
slimmedMETsNoHF |
std::vector<pat::MET> |
as above but excluding HF; | ||
slimmedMETsPuppi |
std::vector<pat::MET> |
puppi-corrected MET | MET computed using the PFCandidate 4-vectors weighted with their puppi weights |
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
. DYT and TeV-muon refits are also available for muons with pt > 100 GeV
The ECal energy associated to the PF Muon is also stored, accessible as muon.pfEcalEnergy()
. This has been used in some analyses, e.g. H→ZZ→4l, for collinear FSR recovery.
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()
.
ele.ecalPFClusterIso()
and ele.hcalPFClusterIso()
gedPhotons
, with two levels of selection: hadTowOverEm() < 0.15
; photons with pT 10-14 GeV are also lept, if they satisfy hadTowOverEm() < 0.15 && chargedHadronIso()<10
r9()>0.8
, and an absolute and relative isolation cuts done with charged hadrons only, chargedHadronIso()<20
, chargedHadronIso()<0.3*pt()
UserData<reco::Track>
, quality flags for TkVtxCompatibility, CompatibleInnerHits, Highpurity, pizero_rejected, large_pizero_window, Conversion Algorithm, are packed as single bit for each flag in the word flags
. The quality of the conversion is store in the upper 8 bits, following the list:
generalTracksOnly, arbitratedEcalSeeded, arbitratedMerged, arbitratedMergedEcalGeneral, highPurity, highEfficiency, ecalMatched1Track, and ecalMatched2Track.
decayModeFindingNewDMs
discriminator (which is strictly looser than the decayModeFinding
used up to 72X). Tighter tau ID requirements can be applied using the tauID(name)
method, all POG-supported discriminators are included.
The tau ID discriminators recommended for 13 TeV 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.
slimmedJets
, made from ak4PFJetsCHS
, i.e. using anti-kT clustering out of Particle Flow candidates, after rejecting the charged hadrons that are associated to a pileup primary vertex. These have standard jet energy corrections applied (L1FastJet, L2, L3), and a pT cut at 10 GeV
slimmedJetsPuppi
; they have the same clustering as the slimmedJets
, but pileup mitigation is performed by weighting the particles according to the PUPPI algorithm, i.e. the jet 4-vector is the weighted sum of the particle 4-vectors. slimmedJetsAK8
, made from ak8PFJetsPUPPI
, i.e. the same clustering of the slimmedJetsPuppi
but with a larger distance parameter R=0.8 instead of R=0.4 (R corresponds approximately to the radius of the jet).slimmedJetsAK8
, are provided slimmedJetsAK8PFPuppiSoftDropPacked
. The CMS top tagger subjets and slimmedJetsAK8PFCHSSoftDropPacked found in previous versions of miniAOD have been dropped, although CHS values are stored as user floats.
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.
For the AK8 jet collection, the links to the daughters are stored in an efficient way, but it is not the same way to access the daughters as in the past in pat::Jet
. The jets have (by default) two substructure algorithms run, SoftDrop and PUPPI SoftDrop. The subjets of PUPPI softdrop, available through the subjets
method in pat::Jet
. However, each also point to their respective constituents. To save space, the Soft Drop Subjets are stored in positions 0 and 1 in the constituent list. These subjets contain pointers to their own constituents. The remaining constituents that are groomed away by the soft drop method are stored in the constituent vector in indices 2,3,....N. As such, to access all daughters, you must loop over the constituents of all of the constituents (see code snippet below). As with the AK4 collections, the daughter(idx)
method will be the appropriate one, while getPFConstituent
and getPFConstituents
will also NOT work. This functionality is currently broken for 9x and will be fixed ASAP. The same code snippet below will work to obtain the constituents.
For the AK4 jets (both with and without PUPPI), the following information is provided: bDiscriminator(name)
method, for: pfJetBProbabilityBJetTags
, pfJetProbabilityBJetTags
, pfTrackCountingHighEffBJetTags
, pfSimpleSecondaryVertexHighEffBJetTags
, pfSimpleInclusiveSecondaryVertexHighEffBJetTags
, pfCombinedSecondaryVertexV2BJetTags
, pfCombinedInclusiveSecondaryVertexV2BJetTags
, softPFMuonBJetTags
, softPFElectronBJetTags
, pfCombinedMVAV2BJetTags
, pfCombinedCvsLJetTags
, pfCombinedCvsBJetTags
, pfDeepCSVJetTags:probb
, pfDeepCSVJetTags:probc
, pfDeepCSVJetTags:probudsg
, pfDeepCSVJetTags:probbb
;
userFloat("pileupJetId:fullDiscriminant")
. userFloat("caloJetMap:pt")
and userFloat("caloJetMap:emEnergyFraction")
. userFloat
with label ak8PFJetsPuppiSoftDropMass
. The trimmed and filtered userfloats have been dropped from 80X miniAOD. They are calculable with the jet toolbox.
userFloats
with labels ak8PFJetsCHSValueMap:ak8PFJetsCHSPrunedMass
and ak8PFJetsCHSValueMap:ak8PFJetsCHSSoftDropMass
.
userFloats
with labels NjettinessAK8Puppi:tau1
, NjettinessAK8Puppi:tau2
, and NjettinessAK8Puppi:tau3
userFloats
with labels ak8PFJetsCHSValueMap:NjettinessAK8CHSTau1
, ak8PFJetsCHSValueMap:NjettinessAK8CHSTau2
, and ak8PFJetsCHSValueMap:NjettinessAK8CHSTau3
slimmedJetsAK8.userFloat(" ak8PFJetsCHSValueMap:pt")
. The subjets for the soft drop CHS have been dropped and only soft drop PUPPI subjets are saved. To access them use the subjets
method within pat::Jet
with label SoftDropPuppi
.
userFloats
is highlighted here. A simple snippet to perform a very simple W/Z/H tagging selection would be :
double softdrop_puppi_mass = jet.userFloat("ak8PFJetsPuppiSoftDropMass"); double puppi_tau1 = jet.userFloat("NjettinessAK8Puppi:tau1"); double puppi_tau2 = jet.userFloat("NjettinessAK8Puppi:tau2"); double puppi_tau3 = jet.userFloat("NjettinessAK8Puppi:tau3"); // You can also get the subjets like this: TLorentzVector puppi_softdrop, puppi_softdrop_subjet; auto const & sdSubjetsPuppi = jet.subjets("SoftDropPuppi"); for ( auto const & it : sbSubjetsPuppi ) { puppi_softdrop_subjet.SetPtEtaPhiM(it->correctedP4(0).pt(),it->correctedP4(0).eta(),it->correctedP4(0).phi(),it->correctedP4(0).mass()); puppi_softdrop+=puppi_softdrop_subjet; } bool myPuppiSimpleWTagger = (puppi_tau2/puppi_tau1) < 0.5 && softdrop_puppi_mass > 50.0; double pruned_chs_mass = jet.userFloat("ak8PFJetsCHSValueMap:ak8PFJetsCHSPrunedMass"); // access to pruned mass double chs_tau1 = jet.userFloat("ak8PFJetsCHSValueMap:NjettinessAK8CHSTau1); double chs_tau2 = jet.userFloat("ak8PFJetsCHSValueMap:NjettinessAK8CHSTau2"); double chs_tau3 = jet.userFloat("ak8PFJetsCHSValueMap:NjettinessAK8CHSTau3"); bool myCHSSimpleWTagger = (tau2/tau1) < 0.6 && pruned_mass > 50.0;The PUPPI softdrop mass correction depends on the use case. For W/Z/H tagging follow the instructions here: https://twiki.cern.ch/twiki/bin/viewauth/CMS/JetWtagging https://github.com/cms-jet/PuppiSoftdropMassCorr
slimmedMETs.genMET()
and slimmedMETs.uncorPt()
and slimmedMETs.caloMETPt()
The type1 corrections is computed from ak4PFJetsCHS
jets with pT > 15 GeV, as per the updated prescribed by the JetMET group.
The pat::METcorXyz(level)
methods and shiftedXyz(uncertainty, level)
methods: Xyz
can be any of P2, P3, P4, Px, Py, Pz, Phi, SumEt
uncertainty
can be any of the 19 variations considered (e.g. UnclusteredEnUp
or JetResDown
)
Type1
(default), Raw
, Type1p2
, etc; note that not all uncertainties are filled for levels.
pt()
, phi()
, p4()
etc all return the default type1 corrected MET
slimmedMETsPuppi
collection. The type1 corrections are also computed and available as default for this MET definition.
If the JECs are updated, one would need to re-compute the type-1 MET for both PF and Puppi flavors. To learn about the re-computation recipe please look here
For releases older than 8_0_20, the latest recommended version of slimmedMETsPuppi
requires a standalone recipe to run on top of miniAOD. Similarly, the met-significance is available with a standalone recipe for releases older than 8_0_20 to run on top of miniAOD. You can access this variable with metSignificance()
call.
isolatedTracks
of pat::IsolatedTrackpackedPFCandidates
, lostTracks
, and generalTracks
collections (care is taken to avoid duplicates, so for example if a track is in both the packedPFCandidate and generalTrack collections, it will only be taken from the packedPFCandidate collection). These collections are pruned to the following selection: (absolute iso < 5 GeV || relative iso < 0.2 || mini relative iso < 0.2)
.
(fromPV>1 || dz<0.1)
within the relevant cone (dR=0.3
for regular iso, and dR=min(0.2, max(0.05, 10/pT))
for mini iso).
The pat::IsolatedTrackpfIsolationDR03
, miniPFIsolation
- pat::PFIsolationmatchedCaloJet(Em/Had)Energy
- EM/hadronic energies of the nearest calo-jet within dR=0.3. Serves as a rough proxy for calo-isolation.
dz
, dxy
, dzError
, dxyError
fromPV
- result of fromPV() method of packedPFCandidates/lostTracks. Set to -1 for candidates solely from generalTracks.
trackQuality
- the result of the qualityMask() method of generalTracks.
dEdxStrip
, dEdxPixel
- estimated dE/dx values in the strips/pixels.
hitPattern
- a reco::HitPatterncrossed(Ecal/Hcal)Status
- the status codes of the Ecal/Hcal cells crossed by the extrapolated track.
deltaEta
, deltaPhi
- the difference in eta/phi between the initial track trajectory and the point of intersection with the Ecal. Can be used to identify roughly the calorimeter cells the track should hit.
packedCandRef
- reference to the original packedCandidate object, either in the packedPFCandidates or lostTracks collections. Candidates solely from the generalTracks collection have a NULL value for this.
packedPFCandidates
that have no associated track in the generalTracks
collection (mostly electrons, with some muons too). These are included in this isolatedTracks
collection (so that they may still be used for vetoes), and track-specific quantities above get default values (trackQuality = 0
, dEdx(Pixel/Strip) = -1
, delta(Eta/Phi) = 0
, crossed(Ecal/Hcal)Status
empty).
// 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 vtxToken_; edm::EDGetTokenT muonToken_; edm::EDGetTokenT electronToken_; edm::EDGetTokenT tauToken_; edm::EDGetTokenT photonToken_; edm::EDGetTokenT jetToken_; edm::EDGetTokenT fatjetToken_; edm::EDGetTokenT metToken_; }; MiniAnalyzer::MiniAnalyzer(const edm::ParameterSet& iConfig): vtxToken_(consumes(iConfig.getParameter("vertices"))), muonToken_(consumes(iConfig.getParameter("muons"))), electronToken_(consumes(iConfig.getParameter("electrons"))), tauToken_(consumes(iConfig.getParameter("taus"))), photonToken_(consumes(iConfig.getParameter("photons"))), jetToken_(consumes(iConfig.getParameter("jets"))), fatjetToken_(consumes(iConfig.getParameter("fatjets"))), metToken_(consumes(iConfig.getParameter("mets"))) { } MiniAnalyzer::~MiniAnalyzer() { } void MiniAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { edm::Handle vertices; iEvent.getByToken(vtxToken_, vertices); if (vertices->empty()) return; // skip the event if no PV found const reco::Vertex &PV = vertices->front(); edm::Handle 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 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 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 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 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 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 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 softdrop, %5.1f pruned CHS\n", j.pt(), j.pt()*j.jecFactor("Uncorrected"), j.eta(), j.mass(), j.userFloat("ak8PFJetsPuppiSoftDropMass"), j.userFloat("ak8PFJetsCHSValueMap:ak8PFJetsCHSPrunedMass") ); // To get the constituents of the AK8 jets, you have to loop over all of the // daughters recursively. To save space, the first two constituents are actually // the Soft Drop SUBJETS, which will then point to their daughters. // The remaining constituents are those constituents removed by soft drop but // still in the AK8 jet. std::vector constituents; for ( unsigned ida = 0; ida < j.numberOfDaughters(); ++ida ) { reco::Candidate const * cand = j.daughter(ida); if ( cand->numberOfDaughters() == 0 ) constituents.push_back( cand ) ; else { for ( unsigned jda = 0; jda < cand->numberOfDaughters(); ++jda ) { reco::Candidate const * cand2 = cand->daughter(jda); constituents.push_back( cand2 ); } } } std::sort( constituents.begin(), constituents.end(), [] (reco::Candidate const * ida, reco::Candidate const * jda){return ida->pt() > jda->pt();} ); for ( unsigned int ida = 0; ida < constituents.size(); ++ida ) { const pat::PackedCandidate &cand = dynamic_cast<const pat::PackedCandidate &>(*constituents[ida]); printf(" constituent %3d: pt %6.2f, dz(pv) %+.3f, pdgId %+3d\n", ida,cand.pt(),cand.dz(PV.position()),cand.pdgId()); } auto sdSubjets = j.subjets("SoftDropPuppi"); for ( auto const & isd : sdSubjets ) { printf(" sd subjet with pt %5.1f (raw pt %5.1f), eta %+4.2f, mass %5.1f ungroomed\n", isd->pt(), isd->pt()*isd->jecFactor("Uncorrected"), isd->eta(), isd->mass() ); } } edm::Handle 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.FWLiteEnabler.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" tauLabelb = "slimmedTausBoosted" jets = Handle("std::vector<pat::Jet>") fatjets, fatjetLabel = Handle("std::vector<pat::Jet>"), "slimmedJetsAK8" mets, metLabel = Handle("std::vector<pat::MET>"), "slimmedMETs" vertices, vertexLabel = Handle("std::vector<reco::Vertex>"), "offlineSlimmedPrimaryVertices" verticesScore = Handle("edm::ValueMap<float>") seenIt = {} # list of things we've seen (so that we dump them in full only once) # open file (you can use 'edmFileUtil -d /store/whatever.root' to get the physical file name) events = Events("root://eoscms//eos/cms/store/relval/CMSSW_8_0_3/RelValTTbarLepton_13/MINIAODSIM/80X_mcRun2_asymptotic_2016_v3_gs7120p2NewGTv3-v1/00000/4E291B64-DCEF-E511-B99D-0025905A60B0.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(fatjetLabel, fatjets) event.getByLabel(metLabel, mets) event.getByLabel(vertexLabel, vertices) event.getByLabel(vertexLabel, verticesScore) 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, score: (pt2 of clustered objects) %.1f" % (PV.x(), PV.y(), PV.z(), PV.ndof(),verticesScore.product().get(0)) # 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 (full5x5), non-triggering Spring15 MVA score %+.3f, lost hits %d, pass conv veto %d" % ( i, el.pt(), el.superCluster().eta(), el.full5x5_sigmaIetaIeta(), el.userFloat("ElectronMVAEstimatorRun2Spring15NonTrig25nsV1Values"), el.gsfTrack().hitPattern().numberOfLostHits(ROOT.reco.HitPattern.MISSING_INNER_HITS), el.passConversionVeto()) if 'ele' not in seenIt: for eleid in el.electronIDs(): print "\t%s %s" % (eleid.first, eleid.second) seenIt['ele'] = True # 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 (full5x5 shower shapes)" % ( i, pho.pt(), pho.superCluster().eta(), pho.full5x5_sigmaIetaIeta()) if 'pho' not in seenIt: for phoid in pho.photonIDs(): print "\t%s %s" % (phoid.first, phoid.second) seenIt['pho'] = True # Tau event.getByLabel(tauLabel, taus) 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()) if 'tau' not in seenIt: for tauid in tau.tauIDs(): print "\t%s %s" % (tauid.first, tauid.second) seenIt['tau'] = True # Tau (Boosted) event.getByLabel(tauLabelb, taus) for i,tau in enumerate(taus.product()): if tau.pt() < 20: continue print "boosted 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()) if 'taub' not in seenIt: for tauid in tau.tauIDs(): print "\t%s %s" % (tauid.first, tauid.second) seenIt['taub'] = True # Jets (AK4, CHS and Puppi) for jetLabel, algo in ("slimmedJets", "CHS"), ("slimmedJetsPuppi", "PUPPI"): event.getByLabel(jetLabel, jets) for i,j in enumerate(jets.product()): if j.pt() < 20: continue print "jet %s %3d: pt %5.1f (raw pt %5.1f, matched-calojet pt %5.1f), eta %+4.2f, btag CSVIVFv2 %.3f, CMVAv2 %.3f, pileup mva disc %+.2f" % ( algo, i, j.pt(), j.pt()*j.jecFactor('Uncorrected'), j.userFloat("caloJetMap:pt") if algo == "CHS" else -99.0, j.eta(), max(0,j.bDiscriminator("pfCombinedInclusiveSecondaryVertexV2BJetTags")), max(0,j.bDiscriminator("pfCombinedMVAV2BJetTags")), j.userFloat("pileupJetId:fullDiscriminant") if algo == "CHS" else -99) if 'jetAk4'+algo not in seenIt: 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): if i2 > 12: print " ....." break print " constituent %3d: pt %6.2f, dz(pv) %+.3f, pdgId %+3d, hcal energy fraction %.2f, puppi weight %.3f " % (i2,cand.pt(),cand.dz(PV.position()),cand.pdgId(),cand.hcalFraction(),cand.puppiWeight()) print " btag discriminators:" for btag in j.getPairDiscri(): print "\t%s %s" % (btag.first, btag.second) print " userFloats:" for ufl in j.userFloatNames(): print "\t%s %s" % (ufl, j.userFloat(ufl)) seenIt['jetAk4'+algo] = True # Fat AK8 Jets for i,j in enumerate(fatjets.product()): print "jetAK8 %3d: pt %5.1f (raw pt %5.1f), eta %+4.2f, mass %5.1f ungroomed, %5.1f softdrop, %5.1f pruned CHS. " % ( i, j.pt(), j.pt()*j.jecFactor('Uncorrected'), j.eta(), j.mass(), j.userFloat('ak8PFJetsPuppiSoftDropMass'), j.userFloat('ak8PFJetsCHSValueMap:ak8PFJetsCHSPrunedMass')) # To get the constituents of the AK8 jets, you have to loop over all of the # daughters recursively. To save space, the first two constituents are actually # the Soft Drop SUBJETS, which will then point to their daughters. # The remaining constituents are those constituents removed by soft drop but # still in the AK8 jet. if 'jetAk8' not in seenIt: constituents = [] for ida in xrange( j.numberOfDaughters() ) : cand = j.daughter(ida) if cand.numberOfDaughters() == 0 : constituents.append( cand ) else : for jda in xrange( cand.numberOfDaughters() ) : cand2 = cand.daughter(jda) constituents.append( cand2 ) constituents.sort(key = lambda c:c.pt(), reverse=True) for i2, cand in enumerate(constituents): if i2 >4: print " ....." break print " constituent %3d: pt %6.2f, pdgId %+3d, #dau %+3d" % (i2,cand.pt(),cand.pdgId(), cand.numberOfDaughters()) print " btag discriminators:" for btag in j.getPairDiscri(): print "\t%s %s" % (btag.first, btag.second) print " userFloats:" for ufl in j.userFloatNames(): print "\t%s %s" % (ufl, j.userFloat(ufl)) seenIt['jetAk8'] = True # Print Subjets if 'jetAk8SD' not in seenIt: wSubjets = j.subjets('SoftDropPuppi') for isd,sdsub in enumerate( sdSubjets ) : print " w subjet %3d: pt %5.1f (raw pt %5.1f), eta %+4.2f, mass %5.1f " % ( isd, sdsub.pt(), sdsub.pt()*sdsub.jecFactor('Uncorrected'), sdsub.eta(), sdsub.mass() ) print " \tbtag discriminators:" for btag in sdsub.getPairDiscri(): print "\t\t%s %s" % (btag.first, btag.second) print " \tuserFloats:" for ufl in sdsub.userFloatNames(): print "\t\t%s %s" % (ufl, sdsub.userFloat(ufl)) seenIt['jetAk8SD'] = True # 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.uncorPt(), met.genMET().pt(), met.shiftedPt(ROOT.pat.MET.JetEnUp), met.shiftedPt(ROOT.pat.MET.JetEnDown));
packedPFCandidates
collection, using as dataformat pat::PackedCandidatelostTracks
.
For all packed PF candidates, this information is stored: pt()
, 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.
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::Track
had the highPurity
quality flag set.
puppiWeight()
and puppiWeightNoLep()
functions. puppiWeight
are used to cluster the jets and puppiWeightNoLep
are used to compute the puppi MET.
hcalFraction()
method. vertexRef()
now returns for each packed candidate the associated PV (before 740 it was always the pv[0]
). The association is based on CommonTools /RecoAlgos/python/sortedPFPrimaryVertices_cfi.py
pvAssociationQuality()
method is added and returns the quality of PV-candidate association, in particular (please note that in the following the PV means the associated PV returned by vertexRef()): fromPV()
is still provided and is expected to given in 99.99% of the tracks the same behaviour as in previous versions. In addition fromPV(int i)
provides the same information of fromPV
but computed wrt PV[i], this allow to rerun CHS changing the signal vertex.
The meaning of fromPV()
results are unchanged, fromPV()
returns a number between 3 and 0 to define how tight the association with the PV is: PVUsedInFit
), is if the track is used in the PV fit;
PVTight
) is if the track is not used in the fit of any of the other PVs, and is closest in z to the PV,
PVLoose
) is if the track is closest in z to a PV other then the PV.
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
.
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.
dz()
still returns the ip wrt PV[0]
dz(point)
still return the ip wrt a given 3D point
dz(int i)
returns the ip wrt PV[i]
dzAssociatedPV()
returns the ip wrt the PV associated to this candidate
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, layers 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()
, with the following caveat: slimmedJets
(i.e. default AK4CHS jets) the daughters of the jets are directly the packed candidates
slimmedJetsAK8
(i.e. fat jets used for substructures analysis) the daughter Ptrs are a mixed collection of SubJets and PackedCandidates. In order to have the full list of PackedCandidates you have to add the daughters of the subjets (see example below)
#! /usr/bin/env python import ROOT from DataFormats.FWLite import Events, Handle events = Events (["root://cms-xrd-global.cern.ch//store/relval/CMSSW_7_4_0/RelValTTbar_13/MINIAODSIM/PU25ns_MCRUN2_74_V7_GENSIM_7_1_15-v1/00000/7628ED6B-99DD-E411-B9C8-0025905A60B0.root"]) handleFatJets = Handle ("std::vector") labelFatJets = ("slimmedJetsAK8") c=0 for event in events: event.getByLabel (labelFatJets,handleFatJets) fatjets = handleFatJets.product() for fj in fatjets : if c > 10 : break c+=1 print "FatJet",fj.pt(),fj.eta() allconstituents = [] for constituent in fj.daughterPtrVector() : if constituent.numberOfDaughters() > 0 : allconstituents.extend([x for x in constituent.daughterPtrVector()]) else: allconstituents.append(constituent) print " n. constituents " , len(fj.daughterPtrVector()) print " n. subjets " , len(fj.subjets()) print " n. all constituents " , len(allconstituents)
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 electronToken_; edm::EDGetTokenT muonToken_; edm::EDGetTokenT jetToken_; edm::EDGetTokenT pfToken_; }; PackedCandAnalyzer::PackedCandAnalyzer(const edm::ParameterSet& iConfig): electronToken_(consumes(iConfig.getParameter("electrons"))), muonToken_(consumes(iConfig.getParameter("muons"))), jetToken_(consumes(iConfig.getParameter("jets"))), pfToken_(consumes(iConfig.getParameter("pfCands"))) { } void PackedCandAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { edm::Handle muons; iEvent.getByToken(muonToken_, muons); edm::Handle electrons; iEvent.getByToken(electronToken_, electrons); edm::Handle pfs; iEvent.getByToken(pfToken_, pfs); edm::Handle 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 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"), "slimmedMuons" electrons, electronLabel = Handle("std::vector"), "slimmedElectrons" jets, jetLabel = Handle("std::vector"), "slimmedJets" pfs, pfLabel = Handle("std::vector"), "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
pat::Electron::genParticle() pat::Muon::genParticle() pat::Jet::genParton() pat::Jet::hadronFlavour() 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 as pat::PackedGenParticlemotherRef()
or mother(0)
methods; note that some generator level particles may be motherless, in that case motherRef
will return a null reference, numberOfMothers
will return zero, and mother(0)
will return a null c++ pointer).
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). pat::MET
object)
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") handlePacked = Handle ("std::vector") 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("pruned"))), packedGenToken_(consumes<edm::View<pat::PackedGenParticle> >(iConfig.getParameter("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; isize();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; jsize();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
partonFlavour()
will return a purely parton-based flavor (in version 1 if there was a mismatch between the parton- and hadron-based flavour, the priority was given to the hadron-based flavour). The hadronFlavour()
will return a purely hadron-based flavour, as was the case in version 1
genParton().pdgId()
can be used to obtain the physics definition of the jet flavour
partonFlavour()
because some of the soft partons, which would otherwise be used to set the jet flavor, are dropped from the prunedGenParticles collection
JetFlavourInfo
is embedded into PAT jets by default making it possible to get additional information about the clustered generator-level partons, hadrons, and leptons
slimmedGenJets
, made from ak4GenJets
, i.e. using anti-kT clustering out of stable gen particles.
Starting from 74X neutrinos and other invisible BSM particles are excluded from GenJets, while they were included in CMSSW 70X (CSA14) and 72X (Phys14) campaigns. 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.
Issues with missing daughter references that affected forward jets in CSA14 and Phys14 campaigns should be solved now in 74X, for jets within the detector acceptance.
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
. gmtStage2Digis:Muon
, caloStage2Digis:EGamma
, caloStage2Digis:EtSum
, caloStage2Digis:Jet
, caloStage2Digis:Tau
and the corresponding dataformats can be found under DataFormats/L1TriggergetType()
method can be used determine the type of sum (ET, ETmiss, HT, HTmiss), as they're all dumped in the same BXVector. gtStage2Digis
, but at the moment we don't know a way to translate the bits into names that works in FWLite.BXVector
of GlobalAlgBlk
as bxvec.at(0,0).getPreScColumn()
(This is tested and working on 2016 data, also on PromptReco )
Events contain also the old l1extra
and L1GlobalTriggerReadoutRecord
objects, but they should be ignored since they're not relevant for 2016 data.
// 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 triggerBits_; edm::EDGetTokenT triggerObjects_; edm::EDGetTokenT triggerPrescales_; }; MiniAODTriggerAnalyzer::MiniAODTriggerAnalyzer(const edm::ParameterSet& iConfig): triggerBits_(consumes(iConfig.getParameter("bits"))), triggerObjects_(consumes(iConfig.getParameter("objects"))), triggerPrescales_(consumes(iConfig.getParameter("prescales"))) { } void MiniAODTriggerAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { edm::Handle triggerBits; edm::Handle triggerObjects; edm::Handle 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 pathNamesAll obj.pathNames(false); std::vector 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.FWLiteEnabler.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>"), "slimmedPatTrigger" triggerPrescales, triggerPrescaleLabel = Handle("pat::PackedTriggerPrescales"), "patTrigger" l1Muons, l1MuonLabel = Handle("BXVector"), "gmtStage2Digis:Muon" l1EGammas, l1EGammaLabel = Handle("BXVector"), "caloStage2Digis:EGamma" l1Jets, l1JetLabel = Handle("BXVector"), "caloStage2Digis:Jet" l1EtSums, l1EtSumLabel = Handle("BXVector"), "caloStage2Digis:EtSum" l1Taus, l1TauLabel = Handle("BXVector"), "caloStage2Digis:Tau" events = Events(sys.argv[1]) for iev,event in enumerate(events): event.getByLabel(triggerBitLabel, triggerBits) event.getByLabel(triggerObjectLabel, triggerObjects) event.getByLabel(triggerPrescaleLabel, triggerPrescales) event.getByLabel(l1MuonLabel, l1Muons) event.getByLabel(l1EGammaLabel, l1EGammas) event.getByLabel(l1JetLabel, l1Jets) event.getByLabel(l1EtSumLabel, l1EtSums) event.getByLabel(l1TauLabel, l1Taus) 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.unpackNamesAndLabels(event.object(), triggerBits.product()); 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.pathNames()]) print "\n === BARE L1 OBJECTS ===" for where, what in (l1Muons, l1MuonLabel), (l1EGammas, l1EGammaLabel), (l1Jets, l1JetLabel), (l1Taus, l1TauLabel): shortname = what.split(":")[1] bxvector = where.product() for bx in 0,: # xrange(bxvector.getFirstBX(), bxvector.getLastBX()+1): # typically we want only bx=0 for i in xrange(bxvector.size(bx)): l1obj = bxvector.at(bx,i) if shortname != "Muon" and l1obj.pt() <= 0.01: continue print "%-10s bx %+1d pt %6.2f eta %+5.3f phi %+5.3f " % (shortname, bx, l1obj.pt(), l1obj.eta(), l1obj.phi()) for shortname in ("TotalEt", "TotalHt", "MissingEt", "MissingHt"): bxvector = l1EtSums.product() for bx in 0,: # xrange(bxvector.getFirstBX(), bxvector.getLastBX()+1): # typically we want only bx=0 for i in xrange(bxvector.size(bx)): l1obj = bxvector.at(bx,i) if l1obj.getType() != getattr(l1obj, "k"+shortname): continue print "%-10s bx %+1d pt %6.2f eta %+5.3f phi %+5.3f " % (shortname, bx, l1obj.pt(), l1obj.eta(), l1obj.phi()) 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.
Slimmed primary vertices differ from the AOD collection as follows: floatedmValueMap_offlineSlimmedPrimaryVertices__PAT
.
PileupSummaryInfo
objects for the different bunch crossings:
The collection is slimmedAddPileupInfo
and is slimmed by not saving the detailed information for the out-of-time bunch crossings.
edm::TriggerResults
of the RECO
or PAT
process, depeding on whether MiniAOD was produced simultaneously with RECO or as a separate step). Remember, Trigger bits for each path are stored as edm::TriggerResultshcalnoise
CSCHaloData
, BeamHaloSummary
unsigned int
product bunchSpacingProducer
saying whether the given event has 50ns or 25ns bunch spacing. As all 2016 data and MC is 25ns, this is no longer terribly useful.
fixedGridRhoFastjetAll
: computed from all PF candidates
fixedGridRhoFastjetCentral
: computed from all PF candidates with |η| < 2.5
fixedGridRhoFastjetCentralNeutral
computed from all neutral PF candidates with |η| < 2.5 (neutral hadrons and photons)
fixedGridRhoFastjetCentralChargedPileUp
computed from all PF charged hadrons associated to pileup vertices and with |η| < 2.5
import FWCore.ParameterSet.Config as cms from [[FWCore.ParameterSet.VarParsing]] import VarParsing process = cms.Process("USER") process.load("Configuration.StandardSequences.MagneticField_cff") process.load("Configuration.Geometry.GeometryRecoDB_cff") process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") from [[Configuration.AlCa.GlobalTag]] import GlobalTag process.GlobalTag = GlobalTag (process.GlobalTag, 'auto:run2_mc') ## Events to process process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(10) ) ## Input files process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring( '/store/relval/CMSSW_7_4_1/RelValTTbar_13/MINIAODSIM/PU50ns_MCRUN2_74_V8_gensim_740pre7-v1/00000/7EC72BA9-44EC-E411-9DF3-0025905A60B0.root' ) ) ## Output file from PhysicsTools.PatAlgos.patEventContent_cff import patEventContent process.OUT = cms.OutputModule("PoolOutputModule", fileName = cms.untracked.string('test.root'), outputCommands = cms.untracked.vstring(['drop *','keep patJets_selectedPatJetsAK5PFCHS_*_*']) ) process.endpath= cms.EndPath(process.OUT) ################################################# ## Remake jets ################################################# ## Filter out neutrinos from packed GenParticles process.packedGenParticlesForJetsNoNu = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedGenParticles"), cut = cms.string("abs(pdgId) != 12 && abs(pdgId) != 14 && abs(pdgId) != 16")) ## Define GenJets from RecoJets.JetProducers.ak5GenJets_cfi import ak5GenJets process.ak5GenJetsNoNu = ak5GenJets.clone(src = 'packedGenParticlesForJetsNoNu') ## Select charged hadron subtracted packed PF candidates process.pfCHS = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV")) from RecoJets.JetProducers.ak5PFJets_cfi import ak5PFJets ## Define PFJetsCHS process.ak5PFJetsCHS = ak5PFJets.clone(src = 'pfCHS', doAreaFastjet = True) ################################################# ## Remake PAT jets ################################################# ## b-tag discriminators bTagDiscriminators = [ 'pfCombinedInclusiveSecondaryVertexV2BJetTags' ] from PhysicsTools.PatAlgos.tools.jetTools import * ## Add PAT jet collection based on the above-defined ak5PFJetsCHS addJetCollection( process, labelName = 'AK5PFCHS', jetSource = cms.InputTag('ak5PFJetsCHS'), pvSource = cms.InputTag('offlineSlimmedPrimaryVertices'), pfCandidates = cms.InputTag('packedPFCandidates'), svSource = cms.InputTag('slimmedSecondaryVertices'), btagDiscriminators = bTagDiscriminators, jetCorrections = ('AK5PFchs', ['L1FastJet', 'L2Relative', 'L3Absolute'], 'None'), genJetCollection = cms.InputTag('ak5GenJetsNoNu'), genParticles = cms.InputTag('prunedGenParticles'), algo = 'AK', rParam = 0.5 ) getattr(process,'selectedPatJetsAK5PFCHS').cut = cms.string('pt > 10') process.p = cms.Path(process.selectedPatJetsAK5PFCHS) from PhysicsTools.PatAlgos.tools.pfTools import * ## Adapt primary vertex collection adaptPVs(process, pvCollection=cms.InputTag('offlineSlimmedPrimaryVertices')) 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("EX") # Input source process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring( '/store/relval/CMSSW_7_4_1/RelValTTbar_13/MINIAODSIM/PU50ns_MCRUN2_74_V8_gensim_740pre7-v1/00000/7EC72BA9-44EC-E411-9DF3-0025905A60B0.root' ) ) process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(10) ) #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)10. && (pfIsolationR04().sumChargedHadronPt+ max(0.,pfIsolationR04().sumNeutralHadronEt+ pfIsolationR04().sumPhotonEt- 1 50*pfIsolationR04().sumPUPt))/pt < 0.20 && (isPFMuon && (isGlobalMuon || isTrackerMuon) )''')) process.selectedElectrons = cms.EDFilter("CandPtrSelector", src = cms.InputTag("slimmedElectrons"), cut = cms.string('''abs(eta)20. && gsfTrack.isAvailable() && gsfTrack.hitPattern().numberOfLostHits(\'MISSING_INNER_HITS\') < 2 && (pfIsolationVariables().sumChargedHadronPt+ max(0.,pfIsolationVariables().sumNeutralHadronEt+ pfIsolationVariables().sumPhotonEt- 1 5*pfIsolationVariables().sumPUPt))/pt < 0.15''')) ## Do projections process.pfCHS = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV")) process.pfNoMuonCHS = cms.EDProducer("CandPtrProjector", src = cms.InputTag("pfCHS"), veto = cms.InputTag("selectedMuons")) 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.packedGenParticlesForJetsNoNu = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedGenParticles"), cut = cms.string("abs(pdgId) != 12 && abs(pdgId) != 14 && abs(pdgId) != 16")) process.ak4GenJetsNoNu = ak4GenJets.clone(src = 'packedGenParticlesForJetsNoNu') # The following is make patJets, but EI is done with the above process.load("Configuration.StandardSequences.MagneticField_cff") process.load("Configuration.Geometry.GeometryRecoDB_cff") process.load("Configuration.StandardSequences.FrontierConditions_GlobalTag_cff") from [[Configuration.AlCa.GlobalTag]] import GlobalTag process.GlobalTag = GlobalTag (process.GlobalTag, 'auto:run2_mc') bTagDiscriminators = [ 'pfCombinedInclusiveSecondaryVertexV2BJetTags' ] from PhysicsTools.PatAlgos.tools.jetTools import addJetCollection addJetCollection( process, labelName = 'AK4PFCHS', jetSource = cms.InputTag('ak4PFJetsCHS'), pvSource = cms.InputTag('offlineSlimmedPrimaryVertices'), pfCandidates = cms.InputTag('packedPFCandidates'), svSource = cms.InputTag('slimmedSecondaryVertices'), btagDiscriminators = bTagDiscriminators, jetCorrections = ('AK4PFchs', ['L1FastJet', 'L2Relative', 'L3Absolute'], 'None'), genJetCollection = cms.InputTag('ak4GenJetsNoNu'), genParticles = cms.InputTag('prunedGenParticles'), algo = 'AK', rParam = 0.4 ) #adjust PV used for Jet Corrections process.patJetCorrFactorsAK4PFCHS.primaryVertices = "offlineSlimmedPrimaryVertices" #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 --era era --no_exec(the
--fast
is needed on fast sim to switch off some MET filters)
for example, for 80X MiniAOD v2 MC in CMSSW_8_0_5_patch1
(the patch1
part is important for data, it makes no difference on MC that lacks trigger information)
cmsDriver.py miniAOD-prod -s PAT --eventcontent MINIAODSIM --runUnscheduled --mc --conditions 80X_mcRun2_asymptotic_2016_miniAODv2 --era Run2_2016 --no_exec --filein /store/relval/CMSSW_8_0_3/RelValTTbar_13/GEN-SIM-RECO/80X_mcRun2_asymptotic_2016_v3_gs7120p2NewGTv3-v1/00000/42BE3BF8-A7F0-E511-B6FA-0025905A612A.rootwhile for 80X MiniAOD v1 in
CMSSW_8_0_3_patch1
cmsDriver.py miniAOD-prod -s PAT --eventcontent MINIAODSIM --runUnscheduled --mc --conditions 80X_mcRun2_asymptotic_2016_v3 --era Run2_25ns --no_exec --filein /store/relval/CMSSW_8_0_3/RelValTTbar_13/GEN-SIM-RECO/80X_mcRun2_asymptotic_2016_v3_gs7120p2NewGTv3-v1/00000/42BE3BF8-A7F0-E511-B6FA-0025905A612A.rootIf you have to run on some input file that does not contain any HLT trigger information at all, e.g. from a private production or for the 2017 upgrade scenario, you can disable the HLT in MiniAOD adding to your cmsDriver command the option
--customise_commands 'del process.patTrigger; del process.selectedPatTrigger'
This is not needed on the 80X background MC samples, which contain some dummy HLT information.
The right and most recent global tag for a release can also be obtained with the auto:
syntax in cmsDriver, for example auto:run2_mc
automatically expands to the right GT for run2 MC with 25ns bunch spacing scenario. The full list of available tags is printed by cmsDriver if the --conditions
option is omitted.