CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GenPlusSimParticleProducer.cc
Go to the documentation of this file.
1 
27 
32 
35 
36 #include <ext/algorithm>
37 
38 namespace pat {
40 public:
43 
44 private:
45  virtual void produce(edm::Event&, const edm::EventSetup&);
46  virtual void endJob() {}
47 
51  std::set<int> pdgIds_; // these are the ones we really use
52  std::vector<PdtEntry> pdts_; // these are needed before we get the EventSetup
53 
55  std::auto_ptr<StrFilter> filter_;
56 
59 
61 
74  void addGenParticle(const SimTrack &stMom,
75  const SimTrack &stDau,
76  unsigned int momidx,
77  const edm::SimTrackContainer &simtks,
78  const edm::SimVertexContainer &simvtxs,
79  reco::GenParticleCollection &mergedGens,
80  const reco::GenParticleRefProd ref,
81  std::vector<int> &genBarcodes,
82  bool &barcodesAreSorted ) const ;
83  struct LessById {
84  bool operator()(const SimTrack &tk1, const SimTrack &tk2) const { return tk1.trackId() < tk2.trackId(); }
85  bool operator()(const SimTrack &tk1, unsigned int id ) const { return tk1.trackId() < id; }
86  bool operator()(unsigned int id, const SimTrack &tk2) const { return id < tk2.trackId(); }
87  };
88 
89 };
90 }
91 
92 using namespace std;
93 using namespace edm;
94 using namespace reco;
96 
97 GenPlusSimParticleProducer::GenPlusSimParticleProducer(const ParameterSet& cfg) :
98  firstEvent_(true),
99  src_(cfg.getParameter<InputTag>("src")), // source sim tracks & vertices
100  setStatus_(cfg.getParameter<int32_t>("setStatus")), // set status of GenParticle to this code
101  genParticles_(cfg.getParameter<InputTag>("genParticles")) // get the genParticles to add GEANT particles to
102 {
103  // Possibly allow a list of particle types
104  if (cfg.exists("particleTypes")) {
105  pdts_ = cfg.getParameter<vector<PdtEntry> >("particleTypes");
106  }
107 
108  // Possibly allow a string cut
109  if (cfg.existsAs<string>("filter")) {
110  string filter = cfg.getParameter<string>("filter");
111  if (!filter.empty()) {
112  filter_ = auto_ptr<StrFilter>(new StrFilter(filter));
113  }
114  }
115  produces<GenParticleCollection>();
116  produces<vector<int> >();
117 }
118 
120  const SimTrack &stDau,
121  unsigned int momidx,
122  const SimTrackContainer &simtracksSorted,
123  const SimVertexContainer &simvertices,
124  reco::GenParticleCollection &mergedGens,
125  const GenParticleRefProd ref,
126  std::vector<int> &genBarcodes,
127  bool &barcodesAreSorted) const
128 {
129  // Make the genParticle for stDau and add it to the new collection and update the parent-child relationship
130  // Make up a GenParticleCandidate from the GEANT track info.
131  int charge = static_cast<int>(stDau.charge());
133  Particle::Point vtx; // = (0,0,0) by default
134  if (!stDau.noVertex()) vtx = simvertices[stDau.vertIndex()].position();
135  GenParticle genp(charge, p4, vtx, stDau.type(), setStatus_, true);
136 
137  // Maybe apply filter on the particle
138  if (filter_.get() != 0) {
139  if (!(*filter_)(genp)) return;
140  }
141 
142  reco::GenParticleRef parentRef(ref, momidx);
143  genp.addMother(parentRef);
144  mergedGens.push_back(genp);
145  // get the index for the daughter just added
146  unsigned int dauidx = mergedGens.size()-1;
147 
148  // update add daughter relationship
149  reco::GenParticle & cand = mergedGens[ momidx ];
150  cand.addDaughter( GenParticleRef( ref, dauidx) );
151 
152  //look for simtrack daughters of stDau to see if we need to recur further down the chain
153 
154  for (SimTrackContainer::const_iterator isimtrk = simtracksSorted.begin();
155  isimtrk != simtracksSorted.end(); ++isimtrk) {
156  if (!isimtrk->noVertex()) {
157  // Pick the vertex (isimtrk.vertIndex() is really an index)
158  const SimVertex &vtx = simvertices[isimtrk->vertIndex()];
159 
160  // Check if the vertex has a parent track (otherwise, we're lost)
161  if (!vtx.noParent()) {
162 
163  // Now note that vtx.parentIndex() is NOT an index, it's a track id, so I have to search for it
164  unsigned int idx = vtx.parentIndex();
165  SimTrackContainer::const_iterator it = std::lower_bound(simtracksSorted.begin(), simtracksSorted.end(), idx, LessById());
166  if ((it != simtracksSorted.end()) && (it->trackId() == idx)) {
167  if (it->trackId()==stDau.trackId()) {
168  //need the genparticle index of stDau which is dauidx
169  addGenParticle(stDau, *isimtrk, dauidx, simtracksSorted, simvertices, mergedGens, ref, genBarcodes, barcodesAreSorted);
170  }
171  }
172  }
173  }
174  }
175 }
176 
178  const EventSetup& iSetup) {
179  if (firstEvent_){
180  if (!pdts_.empty()) {
181  pdgIds_.clear();
182  for (vector<PdtEntry>::iterator itp = pdts_.begin(), edp = pdts_.end(); itp != edp; ++itp) {
183  itp->setup(iSetup); // decode string->pdgId and vice-versa
184  pdgIds_.insert(std::abs(itp->pdgId()));
185  }
186  pdts_.clear();
187  }
188  firstEvent_ = false;
189  }
190 
191  // Simulated tracks (i.e. GEANT particles).
192  Handle<SimTrackContainer> simtracks;
193  event.getByLabel(src_, simtracks);
194 
195  // Need to check that SimTrackContainer is sorted; otherwise, copy and sort :-(
196  std::auto_ptr<SimTrackContainer> simtracksTmp;
197  const SimTrackContainer * simtracksSorted = &* simtracks;
198  if (!__gnu_cxx::is_sorted(simtracks->begin(), simtracks->end(), LessById())) {
199  simtracksTmp.reset(new SimTrackContainer(*simtracks));
200  std::sort(simtracksTmp->begin(), simtracksTmp->end(), LessById());
201  simtracksSorted = &* simtracksTmp;
202  }
203 
204  // Get the associated vertices
205  Handle<SimVertexContainer> simvertices;
206  event.getByLabel(src_, simvertices);
207 
208  // Get the GenParticles and barcodes, if needed to set mother and daughter links
210  Handle<std::vector<int> > genBarcodes;
211  bool barcodesAreSorted = true;
212  event.getByLabel(genParticles_, gens);
213  event.getByLabel(genParticles_, genBarcodes);
214  if (gens->size() != genBarcodes->size()) throw cms::Exception("Corrupt data") << "Barcodes not of the same size as GenParticles!\n";
215 
216  // make the output collection
217  auto_ptr<GenParticleCollection> candsPtr(new GenParticleCollection);
218  GenParticleCollection & cands = * candsPtr;
219 
220  const GenParticleRefProd ref = event.getRefBeforePut<GenParticleCollection>();
221 
222  // add the original genParticles to the merged output list
223  for( size_t i = 0; i < gens->size(); ++ i ) {
224  reco::GenParticle cand((*gens)[i]);
225  cands.push_back(cand);
226  }
227 
228  // make new barcodes vector and fill it with the original list
229  auto_ptr<vector<int> > newGenBarcodes( new vector<int>() );
230  for (unsigned int i = 0; i < genBarcodes->size(); ++i) {
231  newGenBarcodes->push_back((*genBarcodes)[i]);
232  }
233  barcodesAreSorted = __gnu_cxx::is_sorted(newGenBarcodes->begin(), newGenBarcodes->end());
234 
235  for( size_t i = 0; i < cands.size(); ++ i ) {
236  reco::GenParticle & cand = cands[ i ];
237  size_t nDaus = cand.numberOfDaughters();
239  cand.resetDaughters( ref.id() );
240  for ( size_t d = 0; d < nDaus; ++d) {
241  cand.addDaughter( GenParticleRef( ref, daus[d].key() ) );
242  }
243 
244  size_t nMoms = cand.numberOfMothers();
246  cand.resetMothers( ref.id() );
247  for ( size_t m = 0; m < nMoms; ++m) {
248  cand.addMother( GenParticleRef( ref, moms[m].key() ) );
249  }
250  }
251 
252  for (SimTrackContainer::const_iterator isimtrk = simtracks->begin();
253  isimtrk != simtracks->end(); ++isimtrk) {
254 
255  // Skip PYTHIA tracks.
256  if (isimtrk->genpartIndex() != -1) continue;
257 
258  // Maybe apply the PdgId filter
259  if (!pdgIds_.empty()) { // if we have a filter on pdg ids
260  if (pdgIds_.find(std::abs(isimtrk->type())) == pdgIds_.end()) continue;
261  }
262 
263  // find simtrack that has a genParticle match to its parent
264  // Look at the production vertex. If there is no vertex, I can do nothing...
265  if (!isimtrk->noVertex()) {
266 
267  // Pick the vertex (isimtrk.vertIndex() is really an index)
268  const SimVertex &vtx = (*simvertices)[isimtrk->vertIndex()];
269 
270  // Check if the vertex has a parent track (otherwise, we're lost)
271  if (!vtx.noParent()) {
272 
273  // Now note that vtx.parentIndex() is NOT an index, it's a track id, so I have to search for it
274  unsigned int idx = vtx.parentIndex();
275  SimTrackContainer::const_iterator it = std::lower_bound(simtracksSorted->begin(), simtracksSorted->end(), idx, LessById());
276  if ((it != simtracksSorted->end()) && (it->trackId() == idx)) { //it is the parent sim track
277  if (it->genpartIndex() != -1) {
278  std::vector<int>::const_iterator itIndex;
279  if (barcodesAreSorted) {
280  itIndex = std::lower_bound(genBarcodes->begin(), genBarcodes->end(), it->genpartIndex());
281  } else {
282  itIndex = std::find( genBarcodes->begin(), genBarcodes->end(), it->genpartIndex());
283  }
284 
285  // Check that I found something
286  // I need to check '*itIndex == it->genpartIndex()' because lower_bound just finds the right spot for an item in a sorted list, not the item
287  if ((itIndex != genBarcodes->end()) && (*itIndex == it->genpartIndex())) {
288  // Ok, I'll make the genParticle for st and add it to the new collection updating the map and parent-child relationship
289  // pass the mother and daughter sim tracks and the mother genParticle to method to create the daughter genParticle and recur
290  unsigned int momidx = itIndex - genBarcodes->begin();
291  addGenParticle(*it, *isimtrk, momidx, *simtracksSorted, *simvertices, *candsPtr, ref, *newGenBarcodes, barcodesAreSorted);
292  }
293  }
294  }
295  }
296  }
297  }
298 
299  event.put(candsPtr);
300  event.put(newGenBarcodes);
301 }
302 
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
bool operator()(const SimTrack &tk1, const SimTrack &tk2) const
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:181
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
bool exists(std::string const &parameterName) const
checks if a parameter exists
#define abs(x)
Definition: mlp_lapack.h:159
const daughters & daughterRefVector() const
references to daughtes
edm::Ref< edm::HepMCProduct, HepMC::GenParticle > GenParticleRef
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
float charge() const
charge
Definition: CoreSimTrack.cc:3
double charge(const std::vector< uint8_t > &Ampls)
virtual void produce(edm::Event &, const edm::EventSetup &)
void addDaughter(const typename daughters::value_type &)
add a daughter via a reference
void resetDaughters(const edm::ProductID &id)
set daughters product ID
StringCutObjectSelector< reco::GenParticle > StrFilter
int parentIndex() const
Definition: SimVertex.h:33
const mothers & motherRefVector() const
references to mothers
virtual size_t numberOfMothers() const
number of mothers
double p4[4]
Definition: TauolaWrapper.h:92
virtual size_t numberOfDaughters() const
number of daughters
bool noVertex() const
Definition: SimTrack.h:30
bool operator()(unsigned int id, const SimTrack &tk2) const
GenPlusSimParticleProducer(const edm::ParameterSet &)
Produces reco::GenParticle from SimTracks.
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
tuple genp
produce generated paricles in acceptance #
void addMother(const typename mothers::value_type &)
add a daughter via a reference
edm::InputTag genParticles_
Collection of GenParticles I need to make refs to. It must also have its associated vector&lt;int&gt; of ba...
int vertIndex() const
index of the vertex in the Event container (-1 if no vertex)
Definition: SimTrack.h:29
bool operator()(const SimTrack &tk1, unsigned int id) const
unsigned int trackId() const
Definition: CoreSimTrack.h:49
tuple filter
USE THIS FOR SKIMMED TRACKS process.p = cms.Path(process.hltLevel1GTSeed*process.skimming*process.offlineBeamSpot*process.TrackRefitter2) OTHERWISE USE THIS.
Definition: align_tpl.py:86
std::vector< SimVertex > SimVertexContainer
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:39
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:40
list key
Definition: combine.py:13
const math::XYZTLorentzVectorD & momentum() const
particle info...
Definition: CoreSimTrack.h:36
ProductID id() const
Accessor for product ID.
Definition: RefProd.h:142
void addGenParticle(const SimTrack &stMom, const SimTrack &stDau, unsigned int momidx, const edm::SimTrackContainer &simtks, const edm::SimVertexContainer &simvtxs, reco::GenParticleCollection &mergedGens, const reco::GenParticleRefProd ref, std::vector< int > &genBarcodes, bool &barcodesAreSorted) const
Try to link the GEANT particle to the generator particle it came from.
math::XYZPoint Point
point in the space
Definition: Candidate.h:43
bool noParent() const
Definition: SimVertex.h:34
void resetMothers(const edm::ProductID &id)
set mother product ID
std::vector< SimTrack > SimTrackContainer