![]() |
![]() |
Public Member Functions | |
PATGenCandsFromSimTracksProducer (const edm::ParameterSet &) | |
~PATGenCandsFromSimTracksProducer () | |
Private Types | |
typedef StringCutObjectSelector < reco::GenParticle > | StrFilter |
Private Member Functions | |
virtual void | beginJob (const edm::EventSetup &) |
virtual void | endJob () |
const SimTrack * | findGeantMother (const SimTrack &tk, const GlobalContext &g) const |
Find the mother of a given GEANT track (or NULL if it can't be found). | |
edm::Ref < reco::GenParticleCollection > | findRef (const SimTrack &tk, GlobalContext &g) const |
Find the GenParticle reference for a given GEANT or PYTHIA track. | |
edm::Ref < reco::GenParticleCollection > | generatorRef_ (const SimTrack &tk, const GlobalContext &g) const |
Used by findRef if the track is a PYTHIA particle. | |
reco::GenParticle | makeGenParticle_ (const SimTrack &tk, const edm::Ref< reco::GenParticleCollection > &mother, const GlobalContext &g) const |
Make a GenParticle for this SimTrack, with a given mother. | |
virtual void | produce (edm::Event &, const edm::EventSetup &) |
Private Attributes | |
std::auto_ptr< StrFilter > | filter_ |
edm::InputTag | genParticles_ |
Collection of GenParticles I need to make refs to. It must also have its associated vector<int> of barcodes, aligned with them. | |
bool | makeMotherLink_ |
If true, I'll try to make a link from the GEANT particle to a GenParticle. | |
double | minRho_ |
Make SimTracks even for original GenParticles, if they are outside this cylinder. | |
double | minZ_ |
std::set< int > | motherPdgIds_ |
std::vector< PdtEntry > | motherPdts_ |
std::set< int > | pdgIds_ |
std::vector< PdtEntry > | pdts_ |
int | setStatus_ |
edm::InputTag | src_ |
bool | writeAncestors_ |
If true, I'll save GenParticles corresponding to the ancestors of this GEANT particle. Common ancestors are only written once. | |
Classes | |
struct | GlobalContext |
Global context for all recursive methods. More... | |
struct | LessById |
The PATGenCandsFromSimTracksProducer produces GenParticles from SimTracks, so they can be used for MC matching.
Definition at line 29 of file PATGenCandsFromSimTracksProducer.cc.
typedef StringCutObjectSelector<reco::GenParticle> pat::PATGenCandsFromSimTracksProducer::StrFilter [private] |
Definition at line 46 of file PATGenCandsFromSimTracksProducer.cc.
PATGenCandsFromSimTracksProducer::PATGenCandsFromSimTracksProducer | ( | const edm::ParameterSet & | cfg | ) | [explicit] |
Definition at line 119 of file PATGenCandsFromSimTracksProducer.cc.
References edm::ParameterSet::exists(), edm::ParameterSet::existsAs(), filter, filter_, edm::ParameterSet::getParameter(), makeMotherLink_, motherPdts_, pdts_, and writeAncestors_.
00119 : 00120 src_(cfg.getParameter<InputTag>("src")), // source sim tracks & vertices 00121 setStatus_(cfg.getParameter<int32_t>("setStatus")), // set status of GenParticle to this code 00122 makeMotherLink_(cfg.existsAs<bool>("makeMotherLink") ? cfg.getParameter<bool>("makeMotherLink") : false), 00123 writeAncestors_(cfg.existsAs<bool>("writeAncestors") ? cfg.getParameter<bool>("writeAncestors") : false), 00124 genParticles_(makeMotherLink_ ? cfg.getParameter<InputTag>("genParticles") : edm::InputTag()), 00125 minRho_(cfg.existsAs<double>("minRho") ? cfg.getParameter<double>("minRho") : -1), 00126 minZ_(cfg.existsAs<double>("minZ") ? cfg.getParameter<double>("minZ") : -1) 00127 { 00128 // Possibly allow a list of particle types 00129 if (cfg.exists("particleTypes")) { 00130 pdts_ = cfg.getParameter<vector<PdtEntry> >("particleTypes"); 00131 } 00132 if (cfg.exists("motherTypes")) { 00133 motherPdts_ = cfg.getParameter<vector<PdtEntry> >("motherTypes"); 00134 } 00135 00136 // Possibly allow a string cut 00137 if (cfg.existsAs<string>("filter")) { 00138 string filter = cfg.getParameter<string>("filter"); 00139 if (!filter.empty()) { 00140 filter_ = auto_ptr<StrFilter>(new StrFilter(filter)); 00141 } 00142 } 00143 00144 if (writeAncestors_ && !makeMotherLink_) { 00145 edm::LogWarning("Configuration") << "PATGenCandsFromSimTracksProducer: " << 00146 "you have set 'writeAncestors' to 'true' and 'makeMotherLink' to false;" << 00147 "GEANT particles with generator level (e.g.PYHIA) mothers won't have mother links.\n"; 00148 } 00149 produces<GenParticleCollection>(); 00150 }
pat::PATGenCandsFromSimTracksProducer::~PATGenCandsFromSimTracksProducer | ( | ) | [inline] |
void PATGenCandsFromSimTracksProducer::beginJob | ( | const edm::EventSetup & | iSetup | ) | [private, virtual] |
Reimplemented from edm::EDProducer.
Definition at line 152 of file PATGenCandsFromSimTracksProducer.cc.
References funct::abs(), motherPdgIds_, motherPdts_, pdgIds_, and pdts_.
00153 { 00154 if (!pdts_.empty()) { 00155 pdgIds_.clear(); 00156 for (vector<PdtEntry>::iterator itp = pdts_.begin(), edp = pdts_.end(); itp != edp; ++itp) { 00157 itp->setup(iSetup); // decode string->pdgId and vice-versa 00158 pdgIds_.insert(abs(itp->pdgId())); 00159 } 00160 pdts_.clear(); 00161 } 00162 if (!motherPdts_.empty()) { 00163 motherPdgIds_.clear(); 00164 for (vector<PdtEntry>::iterator itp = motherPdts_.begin(), edp = motherPdts_.end(); itp != edp; ++itp) { 00165 itp->setup(iSetup); // decode string->pdgId and vice-versa 00166 motherPdgIds_.insert(abs(itp->pdgId())); 00167 } 00168 motherPdts_.clear(); 00169 } 00170 00171 }
Reimplemented from edm::EDProducer.
Definition at line 37 of file PATGenCandsFromSimTracksProducer.cc.
const SimTrack * PATGenCandsFromSimTracksProducer::findGeantMother | ( | const SimTrack & | tk, | |
const GlobalContext & | g | |||
) | const [private] |
Find the mother of a given GEANT track (or NULL if it can't be found).
Definition at line 174 of file PATGenCandsFromSimTracksProducer.cc.
References it, SimVertex::noParent(), SimTrack::noVertex(), SimVertex::parentIndex(), pat::PATGenCandsFromSimTracksProducer::GlobalContext::simtks, pat::PATGenCandsFromSimTracksProducer::GlobalContext::simvtxs, and SimTrack::vertIndex().
Referenced by findRef(), and produce().
00174 { 00175 // assert(tk.genpartIndex() == -1); // MUST NOT be called with a PYTHIA track // why not? 00176 if (!tk.noVertex()) { 00177 const SimVertex &vtx = g.simvtxs[tk.vertIndex()]; 00178 if (!vtx.noParent()) { 00179 unsigned int idx = vtx.parentIndex(); 00180 SimTrackContainer::const_iterator it = std::lower_bound(g.simtks.begin(), g.simtks.end(), idx, LessById()); 00181 if ((it != g.simtks.end()) && (it->trackId() == idx)) { 00182 return &*it; 00183 } 00184 } 00185 } 00186 return 0; 00187 }
edm::Ref< reco::GenParticleCollection > PATGenCandsFromSimTracksProducer::findRef | ( | const SimTrack & | tk, | |
GlobalContext & | g | |||
) | const [private] |
Find the GenParticle reference for a given GEANT or PYTHIA track.
Definition at line 190 of file PATGenCandsFromSimTracksProducer.cc.
References findGeantMother(), generatorRef_(), SimTrack::genpartIndex(), it, makeGenParticle_(), makeMotherLink_, minRho_, minZ_, SimTrack::noVertex(), pat::PATGenCandsFromSimTracksProducer::GlobalContext::output, p, pat::PATGenCandsFromSimTracksProducer::GlobalContext::refprod, pat::PATGenCandsFromSimTracksProducer::GlobalContext::simTksProcessed, pat::PATGenCandsFromSimTracksProducer::GlobalContext::simvtxs, CoreSimTrack::trackId(), SimTrack::vertIndex(), and writeAncestors_.
Referenced by produce().
00190 { 00191 if (tk.genpartIndex() != -1) { 00192 bool stopNow = false; 00193 if (minZ_ <= 0 && minRho_ <= 0) stopNow = true; 00194 if (tk.noVertex()) stopNow = true; 00195 Particle::Point vtx(g.simvtxs[tk.vertIndex()].position()); 00196 if ((vtx.Rho() <= minRho_) && (fabs(vtx.z()) <= minZ_)) stopNow = true; 00197 if (stopNow) return makeMotherLink_ ? generatorRef_(tk, g) : edm::Ref<reco::GenParticleCollection>(); 00198 } 00199 const SimTrack * simMother = findGeantMother(tk, g); 00200 00201 edm::Ref<reco::GenParticleCollection> motherRef; 00202 if (simMother != 0) motherRef = findRef(*simMother,g); 00203 00204 if (writeAncestors_) { 00205 // If writing ancestors, I need to serialize myself, and then to return a ref to me 00206 // But first check if I've already been serialized 00207 std::map<unsigned int,int>::const_iterator it = g.simTksProcessed.find(tk.trackId()); 00208 if (it != g.simTksProcessed.end()) { 00209 // just return a ref to it 00210 assert(it->second > 0); 00211 return edm::Ref<reco::GenParticleCollection>(g.refprod, (it->second) - 1); 00212 } else { 00213 // make genParticle, save, update the map, and return ref to myself 00214 reco::GenParticle p = makeGenParticle_(tk, motherRef, g); 00215 g.output.push_back(p); 00216 g.simTksProcessed[tk.trackId()] = g.output.size(); 00217 return edm::Ref<reco::GenParticleCollection>(g.refprod, g.output.size()-1 ); 00218 } 00219 } else { 00220 // Otherwise, I just return a ref to my mum 00221 return motherRef; 00222 } 00223 }
edm::Ref< reco::GenParticleCollection > PATGenCandsFromSimTracksProducer::generatorRef_ | ( | const SimTrack & | tk, | |
const GlobalContext & | g | |||
) | const [private] |
Used by findRef if the track is a PYTHIA particle.
Definition at line 226 of file PATGenCandsFromSimTracksProducer.cc.
References pat::PATGenCandsFromSimTracksProducer::GlobalContext::barcodesAreSorted, find(), pat::PATGenCandsFromSimTracksProducer::GlobalContext::genBarcodes, SimTrack::genpartIndex(), pat::PATGenCandsFromSimTracksProducer::GlobalContext::gens, and it.
Referenced by findRef().
00226 { 00227 assert(st.genpartIndex() != -1); 00228 // Note that st.genpartIndex() is the barcode, not the index within GenParticleCollection, so I have to search the particle 00229 std::vector<int>::const_iterator it; 00230 if (g.barcodesAreSorted) { 00231 it = std::lower_bound(g.genBarcodes->begin(), g.genBarcodes->end(), st.genpartIndex()); 00232 } else { 00233 it = std::find( g.genBarcodes->begin(), g.genBarcodes->end(), st.genpartIndex()); 00234 } 00235 00236 // Check that I found something 00237 // I need to check '*it == st.genpartIndex()' because lower_bound just finds the right spot for an item in a sorted list, not the item 00238 if ((it != g.genBarcodes->end()) && (*it == st.genpartIndex())) { 00239 return reco::GenParticleRef(g.gens, it - g.genBarcodes->begin()); 00240 } else { 00241 return reco::GenParticleRef(); 00242 } 00243 }
reco::GenParticle PATGenCandsFromSimTracksProducer::makeGenParticle_ | ( | const SimTrack & | tk, | |
const edm::Ref< reco::GenParticleCollection > & | mother, | |||
const GlobalContext & | g | |||
) | const [private] |
Make a GenParticle for this SimTrack, with a given mother.
Definition at line 246 of file PATGenCandsFromSimTracksProducer.cc.
References CoreSimTrack::charge(), edm::Ref< C, T, F >::isNonnull(), CoreSimTrack::momentum(), SimTrack::noVertex(), p4, setStatus_, pat::PATGenCandsFromSimTracksProducer::GlobalContext::simvtxs, CoreSimTrack::type(), and SimTrack::vertIndex().
Referenced by findRef(), and produce().
00246 { 00247 // Make up a GenParticleCandidate from the GEANT track info. 00248 int charge = static_cast<int>(tk.charge()); 00249 Particle::LorentzVector p4 = tk.momentum(); 00250 Particle::Point vtx; // = (0,0,0) by default 00251 if (!tk.noVertex()) vtx = g.simvtxs[tk.vertIndex()].position(); 00252 GenParticle gp(charge, p4, vtx, tk.type(), setStatus_, true); 00253 if (mother.isNonnull()) gp.addMother(mother); 00254 return gp; 00255 }
void PATGenCandsFromSimTracksProducer::produce | ( | edm::Event & | event, | |
const edm::EventSetup & | eSetup | |||
) | [private, virtual] |
Implements edm::EDProducer.
Definition at line 257 of file PATGenCandsFromSimTracksProducer.cc.
References funct::abs(), reco::CompositeRefCandidateT< D >::addMother(), GenMuonPlsPt100GeV_cfg::cout, lat::endl(), Exception, filter_, findGeantMother(), findRef(), EgammaValidation_cff::genp, genParticles_, i, edm::OrphanHandle< T >::id(), edm::Ref< C, T, F >::id(), edm::Ref< C, T, F >::isNonnull(), it, edm::Ref< C, T, F >::key(), makeGenParticle_(), makeMotherLink_, minRho_, minZ_, motherPdgIds_, pdgIds_, python::multivaluedict::sort(), src_, CoreSimTrack::type(), and writeAncestors_.
00258 { 00259 // Simulated tracks (i.e. GEANT particles). 00260 Handle<SimTrackContainer> simtracks; 00261 event.getByLabel(src_, simtracks); 00262 00263 // Need to check that SimTrackContainer is sorted; otherwise, copy and sort :-( 00264 std::auto_ptr<SimTrackContainer> simtracksTmp; 00265 const SimTrackContainer * simtracksSorted = &* simtracks; 00266 if (makeMotherLink_ || writeAncestors_) { 00267 if (!__gnu_cxx::is_sorted(simtracks->begin(), simtracks->end(), LessById())) { 00268 simtracksTmp.reset(new SimTrackContainer(*simtracks)); 00269 std::sort(simtracksTmp->begin(), simtracksTmp->end(), LessById()); 00270 simtracksSorted = &* simtracksTmp; 00271 } 00272 } 00273 00274 // Get the associated vertices 00275 Handle<SimVertexContainer> simvertices; 00276 event.getByLabel(src_, simvertices); 00277 00278 // Get the GenParticles and barcodes, if needed to set mother links 00279 Handle<GenParticleCollection> gens; 00280 Handle<std::vector<int> > genBarcodes; 00281 bool barcodesAreSorted = true; 00282 if (makeMotherLink_) { 00283 event.getByLabel(genParticles_, gens); 00284 event.getByLabel(genParticles_, genBarcodes); 00285 if (gens->size() != genBarcodes->size()) throw cms::Exception("Corrupt data") << "Barcodes not of the same size as GenParticles!\n"; 00286 barcodesAreSorted = __gnu_cxx::is_sorted(genBarcodes->begin(), genBarcodes->end()); 00287 } 00288 00289 // make the output collection 00290 auto_ptr<GenParticleCollection> cands(new GenParticleCollection); 00291 edm::RefProd<GenParticleCollection> refprod = event.getRefBeforePut<GenParticleCollection>(); 00292 00293 GlobalContext globals(*simtracksSorted, *simvertices, gens, genBarcodes, barcodesAreSorted, *cands, refprod); 00294 00295 for (SimTrackContainer::const_iterator isimtrk = simtracks->begin(); 00296 isimtrk != simtracks->end(); ++isimtrk) { 00297 00298 // Skip PYTHIA tracks. 00299 if (isimtrk->genpartIndex() != -1) { 00300 if (minZ_ <= 0 && minRho_ <= 0) continue; 00301 if (isimtrk->noVertex()) continue; 00302 Particle::Point vtx((*simvertices)[isimtrk->vertIndex()].position()); 00303 if ((vtx.Rho() <= minRho_) && (fabs(vtx.z()) <= minZ_)) continue; 00304 } 00305 // Maybe apply the PdgId filter 00306 if (!pdgIds_.empty()) { // if we have a filter on pdg ids 00307 if (pdgIds_.find(abs(isimtrk->type())) == pdgIds_.end()) continue; 00308 } 00309 00310 GenParticle genp = makeGenParticle_(*isimtrk, Ref<GenParticleCollection>(), globals); 00311 00312 // Maybe apply filter on the particle 00313 if (filter_.get() != 0) { 00314 if (!(*filter_)(genp)) continue; 00315 } 00316 00317 // Maybe apply the mother PdgId filter 00318 if (!motherPdgIds_.empty()) { 00319 const SimTrack *motherSimTk = findGeantMother(*isimtrk, globals); 00320 if (motherSimTk == 0) continue; 00321 if (motherPdgIds_.find(abs(motherSimTk->type())) == motherPdgIds_.end()) continue; 00322 } 00323 00324 if (makeMotherLink_ || writeAncestors_) { 00325 Ref<GenParticleCollection> motherRef; 00326 const SimTrack * mother = findGeantMother(*isimtrk, globals); 00327 if (mother != 0) motherRef = findRef(*mother, globals); 00328 if (motherRef.isNonnull()) genp.addMother(motherRef); 00329 } 00330 00331 cands->push_back(genp); 00332 } 00333 00334 // Write to the Event, and get back a handle (which can be useful for debugging) 00335 edm::OrphanHandle<reco::GenParticleCollection> orphans = event.put(cands); 00336 00337 #ifdef DEBUG_PATGenCandsFromSimTracksProducer 00338 std::cout << "Produced a list of " << orphans->size() << " genParticles." << std::endl; 00339 for (GenParticleCollection::const_iterator it = orphans->begin(), ed = orphans->end(); it != ed; ++it) { 00340 std::cout << " "; 00341 std::cout << "GenParticle #" << (it - orphans->begin()) << ": pdgId " << it->pdgId() 00342 << ", pt = " << it->pt() << ", eta = " << it->eta() << ", phi = " << it->phi() 00343 << ", rho = " << it->vertex().Rho() << ", z = " << it->vertex().Z() << std::endl; 00344 edm::Ref<GenParticleCollection> mom = it->motherRef(); 00345 size_t depth = 2; 00346 while (mom.isNonnull()) { 00347 if (mom.id() == orphans.id()) { 00348 // I need to re-make the ref because they are not working until this module returns. 00349 mom = edm::Ref<GenParticleCollection>(orphans, mom.key()); 00350 } 00351 for (size_t i = 0; i < depth; ++i) std::cout << " "; 00352 std::cout << "GenParticleRef [" << mom.id() << "/" << mom.key() << "]: pdgId " << mom->pdgId() << ", status = " << mom->status() 00353 << ", pt = " << mom->pt() << ", eta = " << mom->eta() << ", phi = " << mom->phi() 00354 << ", rho = " << mom->vertex().Rho() << ", z = " << mom->vertex().Z() << std::endl; 00355 if (mom.id() != orphans.id()) break; 00356 if ((mom->motherRef().id() == mom.id()) && (mom->motherRef().key() == mom.key())) { 00357 throw cms::Exception("Corrupt Data") << "A particle is it's own mother.\n"; 00358 } 00359 mom = mom->motherRef(); 00360 depth++; 00361 } 00362 } 00363 std::cout << std::endl; 00364 #endif 00365 00366 }
std::auto_ptr<StrFilter> pat::PATGenCandsFromSimTracksProducer::filter_ [private] |
Definition at line 47 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by PATGenCandsFromSimTracksProducer(), and produce().
Collection of GenParticles I need to make refs to. It must also have its associated vector<int> of barcodes, aligned with them.
Definition at line 55 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by produce().
If true, I'll try to make a link from the GEANT particle to a GenParticle.
Definition at line 50 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by findRef(), PATGenCandsFromSimTracksProducer(), and produce().
double pat::PATGenCandsFromSimTracksProducer::minRho_ [private] |
Make SimTracks even for original GenParticles, if they are outside this cylinder.
Definition at line 58 of file PATGenCandsFromSimTracksProducer.cc.
double pat::PATGenCandsFromSimTracksProducer::minZ_ [private] |
Definition at line 58 of file PATGenCandsFromSimTracksProducer.cc.
std::set<int> pat::PATGenCandsFromSimTracksProducer::motherPdgIds_ [private] |
Definition at line 43 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by beginJob(), and produce().
std::vector<PdtEntry> pat::PATGenCandsFromSimTracksProducer::motherPdts_ [private] |
Definition at line 44 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by beginJob(), and PATGenCandsFromSimTracksProducer().
std::set<int> pat::PATGenCandsFromSimTracksProducer::pdgIds_ [private] |
Definition at line 41 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by beginJob(), and produce().
std::vector<PdtEntry> pat::PATGenCandsFromSimTracksProducer::pdts_ [private] |
Definition at line 42 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by beginJob(), and PATGenCandsFromSimTracksProducer().
Definition at line 40 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by makeGenParticle_().
If true, I'll save GenParticles corresponding to the ancestors of this GEANT particle. Common ancestors are only written once.
Definition at line 52 of file PATGenCandsFromSimTracksProducer.cc.
Referenced by findRef(), PATGenCandsFromSimTracksProducer(), and produce().