CMS 3D CMS Logo

GenPlusSimParticleProducer.cc
Go to the documentation of this file.
1 
27 
32 
35 
36 #include <ext/algorithm>
37 #include <memory>
38 
39 namespace pat {
41  public:
44 
45  private:
46  void produce(edm::Event &, const edm::EventSetup &) override;
47  void endJob() override {}
48 
53  std::set<int> pdgIds_; // these are the ones we really use
54  std::vector<PdtEntry> pdts_; // these are needed before we get the EventSetup
55 
57  std::unique_ptr<StrFilter> filter_;
58 
62 
64 
77  void addGenParticle(const SimTrack &stMom,
78  const SimTrack &stDau,
79  unsigned int momidx,
80  const edm::SimTrackContainer &simtks,
81  const edm::SimVertexContainer &simvtxs,
82  reco::GenParticleCollection &mergedGens,
83  const reco::GenParticleRefProd ref,
84  std::vector<int> &genBarcodes,
85  bool &barcodesAreSorted) const;
86  struct LessById {
87  bool operator()(const SimTrack &tk1, const SimTrack &tk2) const { return tk1.trackId() < tk2.trackId(); }
88  bool operator()(const SimTrack &tk1, unsigned int id) const { return tk1.trackId() < id; }
89  bool operator()(unsigned int id, const SimTrack &tk2) const { return id < tk2.trackId(); }
90  };
91  };
92 } // namespace pat
93 
94 using namespace std;
95 using namespace edm;
96 using namespace reco;
98 
99 GenPlusSimParticleProducer::GenPlusSimParticleProducer(const ParameterSet &cfg)
100  : firstEvent_(true),
101  simtracksToken_(consumes<SimTrackContainer>(cfg.getParameter<InputTag>("src"))), // source sim tracks & vertices
102  simverticesToken_(
103  consumes<SimVertexContainer>(cfg.getParameter<InputTag>("src"))), // source sim tracks & vertices
104  setStatus_(cfg.getParameter<int32_t>("setStatus")), // set status of GenParticle to this code
105  gensToken_(consumes<GenParticleCollection>(
106  cfg.getParameter<InputTag>("genParticles"))), // get the genParticles to add GEANT particles to
107  genBarcodesToken_(consumes<std::vector<int>>(
108  cfg.getParameter<InputTag>("genParticles"))) // get the genParticles to add GEANT particles to
109 {
110  // Possibly allow a list of particle types
111  if (cfg.exists("particleTypes")) {
112  pdts_ = cfg.getParameter<vector<PdtEntry>>("particleTypes");
113  }
114 
115  // Possibly allow a string cut
116  if (cfg.existsAs<string>("filter")) {
117  string filter = cfg.getParameter<string>("filter");
118  if (!filter.empty()) {
119  filter_ = std::make_unique<StrFilter>(filter);
120  }
121  }
122  produces<GenParticleCollection>();
123  produces<vector<int>>();
124 }
125 
127  const SimTrack &stDau,
128  unsigned int momidx,
129  const SimTrackContainer &simtracksSorted,
130  const SimVertexContainer &simvertices,
131  reco::GenParticleCollection &mergedGens,
132  const GenParticleRefProd ref,
133  std::vector<int> &genBarcodes,
134  bool &barcodesAreSorted) const {
135  // Make the genParticle for stDau and add it to the new collection and update the parent-child relationship
136  // Make up a GenParticleCandidate from the GEANT track info.
137  int charge = static_cast<int>(stDau.charge());
138  const Particle::LorentzVector &p4 = stDau.momentum();
139  Particle::Point vtx; // = (0,0,0) by default
140  if (!stDau.noVertex())
141  vtx = simvertices[stDau.vertIndex()].position();
142  GenParticle genp(charge, p4, vtx, stDau.type(), setStatus_, true);
143 
144  // Maybe apply filter on the particle
145  if (filter_.get() != nullptr) {
146  if (!(*filter_)(genp))
147  return;
148  }
149 
150  reco::GenParticleRef parentRef(ref, momidx);
151  genp.addMother(parentRef);
152  mergedGens.push_back(genp);
153  // get the index for the daughter just added
154  unsigned int dauidx = mergedGens.size() - 1;
155 
156  // update add daughter relationship
157  reco::GenParticle &cand = mergedGens[momidx];
158  cand.addDaughter(GenParticleRef(ref, dauidx));
159 
160  //look for simtrack daughters of stDau to see if we need to recur further down the chain
161 
162  for (SimTrackContainer::const_iterator isimtrk = simtracksSorted.begin(); isimtrk != simtracksSorted.end();
163  ++isimtrk) {
164  if (!isimtrk->noVertex()) {
165  // Pick the vertex (isimtrk.vertIndex() is really an index)
166  const SimVertex &vtx = simvertices[isimtrk->vertIndex()];
167 
168  // Check if the vertex has a parent track (otherwise, we're lost)
169  if (!vtx.noParent()) {
170  // Now note that vtx.parentIndex() is NOT an index, it's a track id, so I have to search for it
171  unsigned int idx = vtx.parentIndex();
172  SimTrackContainer::const_iterator it =
173  std::lower_bound(simtracksSorted.begin(), simtracksSorted.end(), idx, LessById());
174  if ((it != simtracksSorted.end()) && (it->trackId() == idx)) {
175  if (it->trackId() == stDau.trackId()) {
176  //need the genparticle index of stDau which is dauidx
178  stDau, *isimtrk, dauidx, simtracksSorted, simvertices, mergedGens, ref, genBarcodes, barcodesAreSorted);
179  }
180  }
181  }
182  }
183  }
184 }
185 
187  if (firstEvent_) {
188  if (!pdts_.empty()) {
189  pdgIds_.clear();
190  for (vector<PdtEntry>::iterator itp = pdts_.begin(), edp = pdts_.end(); itp != edp; ++itp) {
191  itp->setup(iSetup); // decode string->pdgId and vice-versa
192  pdgIds_.insert(std::abs(itp->pdgId()));
193  }
194  pdts_.clear();
195  }
196  firstEvent_ = false;
197  }
198 
199  // Simulated tracks (i.e. GEANT particles).
200  Handle<SimTrackContainer> simtracks;
201  event.getByToken(simtracksToken_, simtracks);
202 
203  // Need to check that SimTrackContainer is sorted; otherwise, copy and sort :-(
204  std::unique_ptr<SimTrackContainer> simtracksTmp;
205  const SimTrackContainer *simtracksSorted = &*simtracks;
206  if (!__gnu_cxx::is_sorted(simtracks->begin(), simtracks->end(), LessById())) {
207  simtracksTmp = std::make_unique<SimTrackContainer>(*simtracks);
208  std::sort(simtracksTmp->begin(), simtracksTmp->end(), LessById());
209  simtracksSorted = &*simtracksTmp;
210  }
211 
212  // Get the associated vertices
213  Handle<SimVertexContainer> simvertices;
214  event.getByToken(simverticesToken_, simvertices);
215 
216  // Get the GenParticles and barcodes, if needed to set mother and daughter links
218  Handle<std::vector<int>> genBarcodes;
219  bool barcodesAreSorted = true;
220  event.getByToken(gensToken_, gens);
221  event.getByToken(genBarcodesToken_, genBarcodes);
222  if (gens->size() != genBarcodes->size())
223  throw cms::Exception("Corrupt data") << "Barcodes not of the same size as GenParticles!\n";
224 
225  // make the output collection
226  auto candsPtr = std::make_unique<GenParticleCollection>();
227  GenParticleCollection &cands = *candsPtr;
228 
229  const GenParticleRefProd ref = event.getRefBeforePut<GenParticleCollection>();
230 
231  // add the original genParticles to the merged output list
232  for (size_t i = 0; i < gens->size(); ++i) {
233  reco::GenParticle cand((*gens)[i]);
234  cands.push_back(cand);
235  }
236 
237  // make new barcodes vector and fill it with the original list
238  auto newGenBarcodes = std::make_unique<vector<int>>();
239  for (unsigned int i = 0; i < genBarcodes->size(); ++i) {
240  newGenBarcodes->push_back((*genBarcodes)[i]);
241  }
242  barcodesAreSorted = __gnu_cxx::is_sorted(newGenBarcodes->begin(), newGenBarcodes->end());
243 
244  for (size_t i = 0; i < cands.size(); ++i) {
246  size_t nDaus = cand.numberOfDaughters();
247  GenParticleRefVector daus = cand.daughterRefVector();
248  cand.resetDaughters(ref.id());
249  for (size_t d = 0; d < nDaus; ++d) {
250  cand.addDaughter(GenParticleRef(ref, daus[d].key()));
251  }
252 
253  size_t nMoms = cand.numberOfMothers();
254  GenParticleRefVector moms = cand.motherRefVector();
255  cand.resetMothers(ref.id());
256  for (size_t m = 0; m < nMoms; ++m) {
257  cand.addMother(GenParticleRef(ref, moms[m].key()));
258  }
259  }
260 
261  for (SimTrackContainer::const_iterator isimtrk = simtracks->begin(); isimtrk != simtracks->end(); ++isimtrk) {
262  // Skip PYTHIA tracks.
263  if (isimtrk->genpartIndex() != -1)
264  continue;
265 
266  // Maybe apply the PdgId filter
267  if (!pdgIds_.empty()) { // if we have a filter on pdg ids
268  if (pdgIds_.find(std::abs(isimtrk->type())) == pdgIds_.end())
269  continue;
270  }
271 
272  // find simtrack that has a genParticle match to its parent
273  // Look at the production vertex. If there is no vertex, I can do nothing...
274  if (!isimtrk->noVertex()) {
275  // Pick the vertex (isimtrk.vertIndex() is really an index)
276  const SimVertex &vtx = (*simvertices)[isimtrk->vertIndex()];
277 
278  // Check if the vertex has a parent track (otherwise, we're lost)
279  if (!vtx.noParent()) {
280  // Now note that vtx.parentIndex() is NOT an index, it's a track id, so I have to search for it
281  unsigned int idx = vtx.parentIndex();
282  SimTrackContainer::const_iterator it =
283  std::lower_bound(simtracksSorted->begin(), simtracksSorted->end(), idx, LessById());
284  if ((it != simtracksSorted->end()) && (it->trackId() == idx)) { //it is the parent sim track
285  if (it->genpartIndex() != -1) {
286  std::vector<int>::const_iterator itIndex;
287  if (barcodesAreSorted) {
288  itIndex = std::lower_bound(genBarcodes->begin(), genBarcodes->end(), it->genpartIndex());
289  } else {
290  itIndex = std::find(genBarcodes->begin(), genBarcodes->end(), it->genpartIndex());
291  }
292 
293  // Check that I found something
294  // 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
295  if ((itIndex != genBarcodes->end()) && (*itIndex == it->genpartIndex())) {
296  // Ok, I'll make the genParticle for st and add it to the new collection updating the map and parent-child relationship
297  // pass the mother and daughter sim tracks and the mother genParticle to method to create the daughter genParticle and recur
298  unsigned int momidx = itIndex - genBarcodes->begin();
299  addGenParticle(*it,
300  *isimtrk,
301  momidx,
302  *simtracksSorted,
303  *simvertices,
304  *candsPtr,
305  ref,
306  *newGenBarcodes,
307  barcodesAreSorted);
308  }
309  }
310  }
311  }
312  }
313  }
314 
315  event.put(std::move(candsPtr));
316  event.put(std::move(newGenBarcodes));
317 }
318 
edm::RefProd< GenParticleCollection >
CoreSimTrack::momentum
const math::XYZTLorentzVectorD & momentum() const
Definition: CoreSimTrack.h:19
mps_fire.i
i
Definition: mps_fire.py:428
SimVertex
Definition: SimVertex.h:5
edm::RefProd::id
ProductID id() const
Accessor for product ID.
Definition: RefProd.h:124
EDProducer.h
reco::GenParticle
Definition: GenParticle.h:21
EgammaValidation_cff.genp
genp
produce generated paricles in acceptance #
Definition: EgammaValidation_cff.py:115
edm::EDGetTokenT< edm::SimTrackContainer >
edm
HLT enums.
Definition: AlignableModifier.h:19
pat::GenPlusSimParticleProducer::LessById::operator()
bool operator()(unsigned int id, const SimTrack &tk2) const
Definition: GenPlusSimParticleProducer.cc:89
reco::GenParticleCollection
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
Definition: GenParticleFwd.h:13
GenParticleRef
edm::Ref< edm::HepMCProduct, HepMC::GenParticle > GenParticleRef
Definition: MultiTrackValidator.cc:43
CoreSimTrack::charge
float charge() const
charge
Definition: CoreSimTrack.cc:17
edm::RefVector< GenParticleCollection >
reco
fixed size matrix
Definition: AlignmentAlgorithmBase.h:45
spr::find
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
edm::Handle
Definition: AssociativeIterator.h:50
GenParticle
Definition: GenParticle.py:1
pat::GenPlusSimParticleProducer::~GenPlusSimParticleProducer
~GenPlusSimParticleProducer() override
Definition: GenPlusSimParticleProducer.cc:43
edm::Ref< GenParticleCollection >
heavyIonCSV_trainingSettings.idx
idx
Definition: heavyIonCSV_trainingSettings.py:5
GenParticle.h
SimTrack::noVertex
bool noVertex() const
Definition: SimTrack.h:31
MakerMacros.h
DEFINE_FWK_MODULE
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
pat::GenPlusSimParticleProducer::firstEvent_
bool firstEvent_
Definition: GenPlusSimParticleProducer.cc:49
visualization-live-secondInstance_cfg.m
m
Definition: visualization-live-secondInstance_cfg.py:72
pat::GenPlusSimParticleProducer
Produces reco::GenParticle from SimTracks.
Definition: GenPlusSimParticleProducer.cc:40
GenParticleFwd.h
pat::GenPlusSimParticleProducer::endJob
void endJob() override
Definition: GenPlusSimParticleProducer.cc:47
ALCARECOTkAlBeamHalo_cff.filter
filter
Definition: ALCARECOTkAlBeamHalo_cff.py:27
pat::GenPlusSimParticleProducer::produce
void produce(edm::Event &, const edm::EventSetup &) override
Definition: GenPlusSimParticleProducer.cc:186
ALCARECOTkAlJpsiMuMu_cff.charge
charge
Definition: ALCARECOTkAlJpsiMuMu_cff.py:47
funct::true
true
Definition: Factorize.h:173
HLT_FULL_cff.cands
cands
Definition: HLT_FULL_cff.py:15142
pfDeepBoostedJetPreprocessParams_cfi.lower_bound
lower_bound
Definition: pfDeepBoostedJetPreprocessParams_cfi.py:15
pat::GenPlusSimParticleProducer::pdgIds_
std::set< int > pdgIds_
Definition: GenPlusSimParticleProducer.cc:53
edm::ParameterSet
Definition: ParameterSet.h:47
Event.h
pat::GenPlusSimParticleProducer::LessById::operator()
bool operator()(const SimTrack &tk1, unsigned int id) const
Definition: GenPlusSimParticleProducer.cc:88
PdtEntry.h
cand
Definition: decayParser.h:32
pat::GenPlusSimParticleProducer::LessById::operator()
bool operator()(const SimTrack &tk1, const SimTrack &tk2) const
Definition: GenPlusSimParticleProducer.cc:87
createfilelist.int
int
Definition: createfilelist.py:10
p4
double p4[4]
Definition: TauolaWrapper.h:92
trackerHitRTTI::vector
Definition: trackerHitRTTI.h:21
pat::GenPlusSimParticleProducer::gensToken_
edm::EDGetTokenT< reco::GenParticleCollection > gensToken_
Collection of GenParticles I need to make refs to. It must also have its associated vector<int> of ba...
Definition: GenPlusSimParticleProducer.cc:60
CoreSimTrack::type
int type() const
particle type (HEP PDT convension)
Definition: CoreSimTrack.h:22
edm::EventSetup
Definition: EventSetup.h:57
pat::GenPlusSimParticleProducer::GenPlusSimParticleProducer
GenPlusSimParticleProducer(const edm::ParameterSet &)
Definition: GenPlusSimParticleProducer.cc:99
pat
Definition: HeavyIon.h:7
pat::GenPlusSimParticleProducer::pdts_
std::vector< PdtEntry > pdts_
Definition: GenPlusSimParticleProducer.cc:54
pat::GenPlusSimParticleProducer::setStatus_
int setStatus_
Definition: GenPlusSimParticleProducer.cc:52
looper.cfg
cfg
Definition: looper.py:297
CoreSimTrack::trackId
unsigned int trackId() const
Definition: CoreSimTrack.h:31
pat::GenPlusSimParticleProducer::addGenParticle
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.
Definition: GenPlusSimParticleProducer.cc:126
eostools.move
def move(src, dest)
Definition: eostools.py:511
std
Definition: JetResolutionObject.h:76
StringCutObjectSelector.h
extraflags_cff.vtx
vtx
Definition: extraflags_cff.py:18
edm::SimTrackContainer
std::vector< SimTrack > SimTrackContainer
Definition: SimTrackContainer.h:12
SimTrack
Definition: SimTrack.h:6
Frameworkfwd.h
triggerObjects_cff.id
id
Definition: triggerObjects_cff.py:31
StringCutObjectSelector< reco::GenParticle >
pat::GenPlusSimParticleProducer::LessById
Definition: GenPlusSimParticleProducer.cc:86
SimTrack::vertIndex
int vertIndex() const
index of the vertex in the Event container (-1 if no vertex)
Definition: SimTrack.h:30
edm::EDProducer
Definition: EDProducer.h:35
pat::GenPlusSimParticleProducer::simverticesToken_
edm::EDGetTokenT< edm::SimVertexContainer > simverticesToken_
Definition: GenPlusSimParticleProducer.cc:51
ztail.d
d
Definition: ztail.py:151
cms::Exception
Definition: Exception.h:70
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ParameterSet.h
pat::GenPlusSimParticleProducer::genBarcodesToken_
edm::EDGetTokenT< std::vector< int > > genBarcodesToken_
Definition: GenPlusSimParticleProducer.cc:61
pat::GenPlusSimParticleProducer::StrFilter
StringCutObjectSelector< reco::GenParticle > StrFilter
Definition: GenPlusSimParticleProducer.cc:56
reco::Candidate::LorentzVector
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:36
reco::Candidate::Point
math::XYZPoint Point
point in the space
Definition: Candidate.h:40
event
Definition: event.py:1
edm::Event
Definition: Event.h:73
pat::GenPlusSimParticleProducer::filter_
std::unique_ptr< StrFilter > filter_
Definition: GenPlusSimParticleProducer.cc:57
crabWrapper.key
key
Definition: crabWrapper.py:19
pat::GenPlusSimParticleProducer::simtracksToken_
edm::EDGetTokenT< edm::SimTrackContainer > simtracksToken_
Definition: GenPlusSimParticleProducer.cc:50
SimTrackContainer.h
edm::SimVertexContainer
std::vector< SimVertex > SimVertexContainer
Definition: SimVertexContainer.h:12
edm::InputTag
Definition: InputTag.h:15
SimVertexContainer.h