CMS 3D CMS Logo

pat::PATGenCandsFromSimTracksProducer Class Reference

Produces reco::GenParticle from SimTracks. More...

Inheritance diagram for pat::PATGenCandsFromSimTracksProducer:

edm::EDProducer edm::ProducerBase edm::ProductRegistryHelper

List of all members.

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 SimTrackfindGeantMother (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< StrFilterfilter_
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< intmotherPdgIds_
std::vector< PdtEntrymotherPdts_
std::set< intpdgIds_
std::vector< PdtEntrypdts_
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


Detailed Description

Produces reco::GenParticle from SimTracks.

The PATGenCandsFromSimTracksProducer produces GenParticles from SimTracks, so they can be used for MC matching.

Author:
Jordan Tucker (original module), Giovanni Petrucciani (PAT integration)
Version:
Id
PATGenCandsFromSimTracksProducer.cc,v 1.2.4.5 2009/04/14 08:34:40 gpetrucc Exp

Definition at line 29 of file PATGenCandsFromSimTracksProducer.cc.


Member Typedef Documentation

typedef StringCutObjectSelector<reco::GenParticle> pat::PATGenCandsFromSimTracksProducer::StrFilter [private]

Definition at line 46 of file PATGenCandsFromSimTracksProducer.cc.


Constructor & Destructor Documentation

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]

Definition at line 32 of file PATGenCandsFromSimTracksProducer.cc.

00032 {}


Member Function Documentation

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 }

virtual void pat::PATGenCandsFromSimTracksProducer::endJob ( void   )  [inline, private, virtual]

Reimplemented from edm::EDProducer.

Definition at line 37 of file PATGenCandsFromSimTracksProducer.cc.

00037 {}

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 }


Member Data Documentation

std::auto_ptr<StrFilter> pat::PATGenCandsFromSimTracksProducer::filter_ [private]

Definition at line 47 of file PATGenCandsFromSimTracksProducer.cc.

Referenced by PATGenCandsFromSimTracksProducer(), and produce().

edm::InputTag pat::PATGenCandsFromSimTracksProducer::genParticles_ [private]

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().

bool pat::PATGenCandsFromSimTracksProducer::makeMotherLink_ [private]

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.

Referenced by findRef(), and produce().

double pat::PATGenCandsFromSimTracksProducer::minZ_ [private]

Definition at line 58 of file PATGenCandsFromSimTracksProducer.cc.

Referenced by findRef(), and produce().

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().

int pat::PATGenCandsFromSimTracksProducer::setStatus_ [private]

Definition at line 40 of file PATGenCandsFromSimTracksProducer.cc.

Referenced by makeGenParticle_().

edm::InputTag pat::PATGenCandsFromSimTracksProducer::src_ [private]

Definition at line 39 of file PATGenCandsFromSimTracksProducer.cc.

Referenced by produce().

bool pat::PATGenCandsFromSimTracksProducer::writeAncestors_ [private]

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().


The documentation for this class was generated from the following file:
Generated on Tue Jun 9 18:49:43 2009 for CMSSW by  doxygen 1.5.4