CMS 3D CMS Logo

TrackingParticleSelectorByGen.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: SimGeneral/TrackingParticleSelectorByGen
4 // Class: TrackingParticleSelectorByGen
5 //
13 //
14 // Original Author: Enrico Lusiani
15 // Created: Mon, 26 Apr 2021 16:44:34 GMT
16 //
17 //
18 
19 // system include files
20 #include <memory>
21 
22 // user include files
25 
29 
32 
38 
39 namespace helper {
40  struct SelectCode {
41  enum KeepOrDrop { kKeep, kDrop };
42  enum FlagDepth { kNone, kFirst, kAll };
45  bool all_;
46  };
47 } // namespace helper
48 
50  // a lot of this is copied from GenParticlePruner
51  // refactor common parts in a separate class
52 public:
54 
55  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
56 
57 private:
58  void produce(edm::Event &, const edm::EventSetup &) override;
59  void parse(const std::string &selection, helper::SelectCode &code, std::string &cut) const;
60  void flagDaughters(const reco::GenParticle &, int);
61  void flagMothers(const reco::GenParticle &, int);
62  void recursiveFlagDaughters(size_t, const reco::GenParticleCollection &, int, std::vector<size_t> &);
63  void recursiveFlagMothers(size_t, const reco::GenParticleCollection &, int, std::vector<size_t> &);
64  void getDaughterKeys(std::vector<size_t> &, std::vector<size_t> &, const reco::GenParticleRefVector &) const;
65  void getMotherKeys(std::vector<size_t> &, std::vector<size_t> &, const reco::GenParticleRefVector &) const;
66 
67  // ----------member data ---------------------------
73  std::vector<int> flags_;
74  std::vector<std::string> selection_;
75  std::vector<std::pair<StringCutObjectSelector<reco::GenParticle>, helper::SelectCode>> select_;
76 };
77 
78 using namespace edm;
79 using namespace std;
80 using namespace reco;
81 
82 const int keep = 1, drop = -1;
83 
85  ::helper::SelectCode &code,
86  std::string &cut) const {
87  using namespace ::helper;
88  size_t f = selection.find_first_not_of(' ');
89  size_t n = selection.size();
90  string command;
91  char c;
92  for (; (c = selection[f]) != ' ' && f < n; ++f) {
93  command.push_back(c);
94  }
95  if (command[0] == '+') {
96  command.erase(0, 1);
97  if (command[0] == '+') {
98  command.erase(0, 1);
99  code.mothersDepth_ = SelectCode::kAll;
100  } else {
101  code.mothersDepth_ = SelectCode::kFirst;
102  }
103  } else
105 
106  if (command[command.size() - 1] == '+') {
107  command.erase(command.size() - 1);
108  if (command[command.size() - 1] == '+') {
109  command.erase(command.size() - 1);
110  code.daughtersDepth_ = SelectCode::kAll;
111  } else {
112  code.daughtersDepth_ = SelectCode::kFirst;
113  }
114  } else
116 
117  if (command == "keep")
118  code.keepOrDrop_ = SelectCode::kKeep;
119  else if (command == "drop")
120  code.keepOrDrop_ = SelectCode::kDrop;
121  else {
122  throw Exception(errors::Configuration) << "invalid selection command: " << command << "\n" << endl;
123  }
124  for (; f < n; ++f) {
125  if (selection[f] != ' ')
126  break;
127  }
128  cut = string(selection, f);
129  if (cut[0] == '*')
130  cut = string(cut, 0, cut.find_first_of(' '));
131  code.all_ = cut == "*";
132 }
133 
135  : tpToken_(consumes<TrackingParticleCollection>(iConfig.getParameter<edm::InputTag>("trackingParticles"))),
136  gpToken_(consumes<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("genParticles"))),
137  tableToken_(esConsumes()),
138  firstEvent_(true),
139  keepOrDropAll_(drop),
140  selection_(iConfig.getParameter<vector<string>>("select")) {
141  produces<TrackingParticleCollection>();
142 }
143 
145  const GenParticleRefVector &daughters = gen.daughterRefVector();
146  for (GenParticleRefVector::const_iterator i = daughters.begin(); i != daughters.end(); ++i)
147  flags_[i->key()] = keepOrDrop;
148 }
149 
151  const GenParticleRefVector &mothers = gen.motherRefVector();
152  for (GenParticleRefVector::const_iterator i = mothers.begin(); i != mothers.end(); ++i)
153  flags_[i->key()] = keepOrDrop;
154 }
155 
158  int keepOrDrop,
159  std::vector<size_t> &allIndices) {
160  GenParticleRefVector daughters = src[index].daughterRefVector();
161  // avoid infinite recursion if the daughters are set to "this" particle.
162  size_t cachedIndex = index;
163  for (GenParticleRefVector::const_iterator i = daughters.begin(); i != daughters.end(); ++i) {
164  index = i->key();
165  // To also avoid infinite recursion if a "loop" is found in the daughter list,
166  // check to make sure the index hasn't already been added.
167  if (find(allIndices.begin(), allIndices.end(), index) == allIndices.end()) {
168  allIndices.push_back(index);
169  if (cachedIndex != index) {
170  flags_[index] = keepOrDrop;
171  recursiveFlagDaughters(index, src, keepOrDrop, allIndices);
172  }
173  }
174  }
175 }
176 
179  int keepOrDrop,
180  std::vector<size_t> &allIndices) {
181  GenParticleRefVector mothers = src[index].motherRefVector();
182  // avoid infinite recursion if the mothers are set to "this" particle.
183  size_t cachedIndex = index;
184  for (GenParticleRefVector::const_iterator i = mothers.begin(); i != mothers.end(); ++i) {
185  index = i->key();
186  // To also avoid infinite recursion if a "loop" is found in the daughter list,
187  // check to make sure the index hasn't already been added.
188  if (find(allIndices.begin(), allIndices.end(), index) == allIndices.end()) {
189  allIndices.push_back(index);
190  if (cachedIndex != index) {
191  flags_[index] = keepOrDrop;
192  recursiveFlagMothers(index, src, keepOrDrop, allIndices);
193  }
194  }
195  }
196 }
197 
199  vector<size_t> &daNewIndxs,
200  const GenParticleRefVector &daughters) const {
201  for (GenParticleRefVector::const_iterator j = daughters.begin(); j != daughters.end(); ++j) {
202  GenParticleRef dau = *j;
203  if (find(daIndxs.begin(), daIndxs.end(), dau.key()) == daIndxs.end()) {
204  daIndxs.push_back(dau.key());
205  int idx = flags_[dau.key()];
206  if (idx > 0) {
207  daNewIndxs.push_back(idx);
208  } else {
209  const GenParticleRefVector &daus = dau->daughterRefVector();
210  if (!daus.empty())
211  getDaughterKeys(daIndxs, daNewIndxs, daus);
212  }
213  }
214  }
215 }
216 
217 void TrackingParticleSelectorByGen::getMotherKeys(vector<size_t> &moIndxs,
218  vector<size_t> &moNewIndxs,
219  const GenParticleRefVector &mothers) const {
220  for (GenParticleRefVector::const_iterator j = mothers.begin(); j != mothers.end(); ++j) {
221  GenParticleRef mom = *j;
222  if (find(moIndxs.begin(), moIndxs.end(), mom.key()) == moIndxs.end()) {
223  moIndxs.push_back(mom.key());
224  int idx = flags_[mom.key()];
225  if (idx >= 0) {
226  moNewIndxs.push_back(idx);
227  } else {
228  const GenParticleRefVector &moms = mom->motherRefVector();
229  if (!moms.empty())
230  getMotherKeys(moIndxs, moNewIndxs, moms);
231  }
232  }
233  }
234 }
235 
237  using namespace edm;
238 
239  if (firstEvent_) {
240  auto const &pdt = iSetup.getData(tableToken_);
241  for (vector<string>::const_iterator i = selection_.begin(); i != selection_.end(); ++i) {
242  string cut;
243  ::helper::SelectCode code;
244  parse(*i, code, cut);
245  if (code.all_) {
246  if (i != selection_.begin())
248  << "selections \"keep *\" and \"drop *\" can be used only as first options. Here used in position # "
249  << (i - selection_.begin()) + 1 << "\n"
250  << endl;
251  switch (code.keepOrDrop_) {
252  case ::helper::SelectCode::kDrop:
254  break;
255  case ::helper::SelectCode::kKeep:
257  };
258  } else {
259  cut = pdgEntryReplace(cut, pdt);
260  select_.push_back(make_pair(StringCutObjectSelector<GenParticle>(cut), code));
261  }
262  }
263  firstEvent_ = false;
264  }
265 
266  const auto &tps = iEvent.get(tpToken_);
267 
268  const auto &gps = iEvent.get(gpToken_);
269 
270  using namespace ::helper;
271  const size_t n = gps.size();
272  flags_.clear();
273  flags_.resize(n, keepOrDropAll_);
274  for (size_t j = 0; j < select_.size(); ++j) {
275  const pair<StringCutObjectSelector<GenParticle>, SelectCode> &sel = select_[j];
276  SelectCode code = sel.second;
278  for (size_t i = 0; i < n; ++i) {
279  const GenParticle &p = gps[i];
280  if (cut(p)) {
281  int keepOrDrop = keep;
282  switch (code.keepOrDrop_) {
283  case SelectCode::kKeep:
284  keepOrDrop = keep;
285  break;
286  case SelectCode::kDrop:
287  keepOrDrop = drop;
288  };
289  flags_[i] = keepOrDrop;
290  std::vector<size_t> allIndicesDa;
291  std::vector<size_t> allIndicesMo;
292  switch (code.daughtersDepth_) {
293  case SelectCode::kAll:
294  recursiveFlagDaughters(i, gps, keepOrDrop, allIndicesDa);
295  break;
296  case SelectCode::kFirst:
297  flagDaughters(p, keepOrDrop);
298  break;
299  case SelectCode::kNone:;
300  };
301  switch (code.mothersDepth_) {
302  case SelectCode::kAll:
303  recursiveFlagMothers(i, gps, keepOrDrop, allIndicesMo);
304  break;
305  case SelectCode::kFirst:
306  flagMothers(p, keepOrDrop);
307  break;
308  case SelectCode::kNone:;
309  };
310  }
311  }
312  }
313 
314  auto out = std::make_unique<TrackingParticleCollection>();
315  out->reserve(n);
316 
317  for (auto &&tp : tps) {
318  auto &associatedGenParticles = tp.genParticles();
319 
320  bool isSelected = false;
321  for (auto &&assocGen : associatedGenParticles) {
322  if (flags_[assocGen.index()] == keep)
323  isSelected = true;
324  }
325 
326  if (isSelected) {
327  out->emplace_back(tp);
328  }
329  }
330  iEvent.put(std::move(out));
331 }
332 
335  desc.add<edm::InputTag>("trackingParticles", edm::InputTag("mix", "MergedTrackTruth"));
336  desc.add<edm::InputTag>("genParticles", edm::InputTag("genParticles"));
337  desc.add<vector<string>>("select");
338 
339  descriptions.add("tpSelectorByGenDefault", desc);
340 }
341 
342 //define this as a plug-in
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
bool empty() const
Is the RefVector empty.
Definition: RefVector.h:99
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const int keep
void produce(edm::Event &, const edm::EventSetup &) override
Definition: helper.py:1
void flagDaughters(const reco::GenParticle &, int)
edm::EDGetTokenT< TrackingParticleCollection > tpToken_
selection
main part
Definition: corrVsCorr.py:100
std::string pdgEntryReplace(const std::string &, HepPDT::ParticleDataTable const &)
void flagMothers(const reco::GenParticle &, int)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
void recursiveFlagMothers(size_t, const reco::GenParticleCollection &, int, std::vector< size_t > &)
key_type key() const
Accessor for product key.
Definition: Ref.h:250
void recursiveFlagDaughters(size_t, const reco::GenParticleCollection &, int, std::vector< size_t > &)
edm::ESGetToken< HepPDT::ParticleDataTable, edm::DefaultRecord > tableToken_
int iEvent
Definition: GenABIO.cc:224
double f[11][100]
void parse(const std::string &selection, helper::SelectCode &code, std::string &cut) const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
bool getData(T &iHolder) const
Definition: EventSetup.h:122
void getDaughterKeys(std::vector< size_t > &, std::vector< size_t > &, const reco::GenParticleRefVector &) const
TrackingParticleSelectorByGen(const edm::ParameterSet &)
std::vector< std::pair< StringCutObjectSelector< reco::GenParticle >, helper::SelectCode > > select_
const int drop
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:228
void add(std::string const &label, ParameterSetDescription const &psetDescription)
bool isSelected(const std::vector< L1HPSPFTauQualityCut > &qualityCuts, const l1t::PFCandidate &pfCand, float_t primaryVertexZ)
list command
Definition: mps_check.py:25
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
fixed size matrix
HLT enums.
edm::EDGetTokenT< reco::GenParticleCollection > gpToken_
std::vector< TrackingParticle > TrackingParticleCollection
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:223
void getMotherKeys(std::vector< size_t > &, std::vector< size_t > &, const reco::GenParticleRefVector &) const
def move(src, dest)
Definition: eostools.py:511