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 
28 
31 
36 
37 namespace helper {
38  struct SelectCode {
39  enum KeepOrDrop { kKeep, kDrop };
40  enum FlagDepth { kNone, kFirst, kAll };
43  bool all_;
44  };
45 } // namespace helper
46 
48  // a lot of this is copied from GenParticlePruner
49  // refactor common parts in a separate class
50 public:
52 
53  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
54 
55 private:
56  void produce(edm::Event &, const edm::EventSetup &) override;
57  void parse(const std::string &selection, helper::SelectCode &code, std::string &cut) const;
58  void flagDaughters(const reco::GenParticle &, int);
59  void flagMothers(const reco::GenParticle &, int);
60  void recursiveFlagDaughters(size_t, const reco::GenParticleCollection &, int, std::vector<size_t> &);
61  void recursiveFlagMothers(size_t, const reco::GenParticleCollection &, int, std::vector<size_t> &);
62  void getDaughterKeys(std::vector<size_t> &, std::vector<size_t> &, const reco::GenParticleRefVector &) const;
63  void getMotherKeys(std::vector<size_t> &, std::vector<size_t> &, const reco::GenParticleRefVector &) const;
64 
65  // ----------member data ---------------------------
70  std::vector<int> flags_;
71  std::vector<std::string> selection_;
72  std::vector<std::pair<StringCutObjectSelector<reco::GenParticle>, helper::SelectCode>> select_;
73 };
74 
75 using namespace edm;
76 using namespace std;
77 using namespace reco;
78 
79 const int keep = 1, drop = -1;
80 
82  ::helper::SelectCode &code,
83  std::string &cut) const {
84  using namespace ::helper;
85  size_t f = selection.find_first_not_of(' ');
86  size_t n = selection.size();
87  string command;
88  char c;
89  for (; (c = selection[f]) != ' ' && f < n; ++f) {
90  command.push_back(c);
91  }
92  if (command[0] == '+') {
93  command.erase(0, 1);
94  if (command[0] == '+') {
95  command.erase(0, 1);
97  } else {
99  }
100  } else
102 
103  if (command[command.size() - 1] == '+') {
104  command.erase(command.size() - 1);
105  if (command[command.size() - 1] == '+') {
106  command.erase(command.size() - 1);
108  } else {
110  }
111  } else
113 
114  if (command == "keep")
116  else if (command == "drop")
118  else {
119  throw Exception(errors::Configuration) << "invalid selection command: " << command << "\n" << endl;
120  }
121  for (; f < n; ++f) {
122  if (selection[f] != ' ')
123  break;
124  }
125  cut = string(selection, f);
126  if (cut[0] == '*')
127  cut = string(cut, 0, cut.find_first_of(' '));
128  code.all_ = cut == "*";
129 }
130 
132  : tpToken_(consumes<TrackingParticleCollection>(iConfig.getParameter<edm::InputTag>("trackingParticles"))),
133  gpToken_(consumes<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("genParticles"))),
134  firstEvent_(true),
135  keepOrDropAll_(drop),
136  selection_(iConfig.getParameter<vector<string>>("select")) {
137  produces<TrackingParticleCollection>();
138 }
139 
142  for (GenParticleRefVector::const_iterator i = daughters.begin(); i != daughters.end(); ++i)
143  flags_[i->key()] = keepOrDrop;
144 }
145 
147  const GenParticleRefVector &mothers = gen.motherRefVector();
148  for (GenParticleRefVector::const_iterator i = mothers.begin(); i != mothers.end(); ++i)
149  flags_[i->key()] = keepOrDrop;
150 }
151 
154  int keepOrDrop,
155  std::vector<size_t> &allIndices) {
156  GenParticleRefVector daughters = src[index].daughterRefVector();
157  // avoid infinite recursion if the daughters are set to "this" particle.
158  size_t cachedIndex = index;
159  for (GenParticleRefVector::const_iterator i = daughters.begin(); i != daughters.end(); ++i) {
160  index = i->key();
161  // To also avoid infinite recursion if a "loop" is found in the daughter list,
162  // check to make sure the index hasn't already been added.
163  if (find(allIndices.begin(), allIndices.end(), index) == allIndices.end()) {
164  allIndices.push_back(index);
165  if (cachedIndex != index) {
166  flags_[index] = keepOrDrop;
167  recursiveFlagDaughters(index, src, keepOrDrop, allIndices);
168  }
169  }
170  }
171 }
172 
175  int keepOrDrop,
176  std::vector<size_t> &allIndices) {
177  GenParticleRefVector mothers = src[index].motherRefVector();
178  // avoid infinite recursion if the mothers are set to "this" particle.
179  size_t cachedIndex = index;
180  for (GenParticleRefVector::const_iterator i = mothers.begin(); i != mothers.end(); ++i) {
181  index = i->key();
182  // To also avoid infinite recursion if a "loop" is found in the daughter list,
183  // check to make sure the index hasn't already been added.
184  if (find(allIndices.begin(), allIndices.end(), index) == allIndices.end()) {
185  allIndices.push_back(index);
186  if (cachedIndex != index) {
187  flags_[index] = keepOrDrop;
188  recursiveFlagMothers(index, src, keepOrDrop, allIndices);
189  }
190  }
191  }
192 }
193 
195  vector<size_t> &daNewIndxs,
196  const GenParticleRefVector &daughters) const {
197  for (GenParticleRefVector::const_iterator j = daughters.begin(); j != daughters.end(); ++j) {
198  GenParticleRef dau = *j;
199  if (find(daIndxs.begin(), daIndxs.end(), dau.key()) == daIndxs.end()) {
200  daIndxs.push_back(dau.key());
201  int idx = flags_[dau.key()];
202  if (idx > 0) {
203  daNewIndxs.push_back(idx);
204  } else {
205  const GenParticleRefVector &daus = dau->daughterRefVector();
206  if (!daus.empty())
207  getDaughterKeys(daIndxs, daNewIndxs, daus);
208  }
209  }
210  }
211 }
212 
213 void TrackingParticleSelectorByGen::getMotherKeys(vector<size_t> &moIndxs,
214  vector<size_t> &moNewIndxs,
215  const GenParticleRefVector &mothers) const {
216  for (GenParticleRefVector::const_iterator j = mothers.begin(); j != mothers.end(); ++j) {
217  GenParticleRef mom = *j;
218  if (find(moIndxs.begin(), moIndxs.end(), mom.key()) == moIndxs.end()) {
219  moIndxs.push_back(mom.key());
220  int idx = flags_[mom.key()];
221  if (idx >= 0) {
222  moNewIndxs.push_back(idx);
223  } else {
224  const GenParticleRefVector &moms = mom->motherRefVector();
225  if (!moms.empty())
226  getMotherKeys(moIndxs, moNewIndxs, moms);
227  }
228  }
229  }
230 }
231 
233  using namespace edm;
234 
235  if (firstEvent_) {
236  PdgEntryReplacer rep(iSetup);
237  for (vector<string>::const_iterator i = selection_.begin(); i != selection_.end(); ++i) {
238  string cut;
240  parse(*i, code, cut);
241  if (code.all_) {
242  if (i != selection_.begin())
244  << "selections \"keep *\" and \"drop *\" can be used only as first options. Here used in position # "
245  << (i - selection_.begin()) + 1 << "\n"
246  << endl;
247  switch (code.keepOrDrop_) {
248  case ::helper::SelectCode::kDrop:
250  break;
251  case ::helper::SelectCode::kKeep:
253  };
254  } else {
255  cut = rep.replace(cut);
256  select_.push_back(make_pair(StringCutObjectSelector<GenParticle>(cut), code));
257  }
258  }
259  firstEvent_ = false;
260  }
261 
262  const auto &tps = iEvent.get(tpToken_);
263 
264  const auto &gps = iEvent.get(gpToken_);
265 
266  using namespace ::helper;
267  const size_t n = gps.size();
268  flags_.clear();
269  flags_.resize(n, keepOrDropAll_);
270  for (size_t j = 0; j < select_.size(); ++j) {
271  const pair<StringCutObjectSelector<GenParticle>, SelectCode> &sel = select_[j];
272  SelectCode code = sel.second;
273  const StringCutObjectSelector<GenParticle> &cut = sel.first;
274  for (size_t i = 0; i < n; ++i) {
275  const GenParticle &p = gps[i];
276  if (cut(p)) {
277  int keepOrDrop = keep;
278  switch (code.keepOrDrop_) {
279  case SelectCode::kKeep:
280  keepOrDrop = keep;
281  break;
282  case SelectCode::kDrop:
283  keepOrDrop = drop;
284  };
285  flags_[i] = keepOrDrop;
286  std::vector<size_t> allIndicesDa;
287  std::vector<size_t> allIndicesMo;
288  switch (code.daughtersDepth_) {
289  case SelectCode::kAll:
290  recursiveFlagDaughters(i, gps, keepOrDrop, allIndicesDa);
291  break;
292  case SelectCode::kFirst:
293  flagDaughters(p, keepOrDrop);
294  break;
295  case SelectCode::kNone:;
296  };
297  switch (code.mothersDepth_) {
298  case SelectCode::kAll:
299  recursiveFlagMothers(i, gps, keepOrDrop, allIndicesMo);
300  break;
301  case SelectCode::kFirst:
302  flagMothers(p, keepOrDrop);
303  break;
304  case SelectCode::kNone:;
305  };
306  }
307  }
308  }
309 
310  auto out = std::make_unique<TrackingParticleCollection>();
311  out->reserve(n);
312 
313  for (auto &&tp : tps) {
314  auto &associatedGenParticles = tp.genParticles();
315 
316  bool isSelected = false;
317  for (auto &&assocGen : associatedGenParticles) {
318  if (flags_[assocGen.index()] == keep)
319  isSelected = true;
320  }
321 
322  if (isSelected) {
323  out->emplace_back(tp);
324  }
325  }
326  iEvent.put(std::move(out));
327 }
328 
331  desc.add<edm::InputTag>("trackingParticles", edm::InputTag("mix", "MergedTrackTruth"));
332  desc.add<edm::InputTag>("genParticles", edm::InputTag("genParticles"));
333  desc.add<vector<string>>("select");
334 
335  descriptions.add("tpSelectorByGenDefault", desc);
336 }
337 
338 //define this as a plug-in
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
const int keep
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
void produce(edm::Event &, const edm::EventSetup &) override
Definition: helper.py:1
void flagDaughters(const reco::GenParticle &, int)
std::vector< TrackingParticle > TrackingParticleCollection
edm::EDGetTokenT< TrackingParticleCollection > tpToken_
selection
main part
Definition: corrVsCorr.py:100
std::string replace(const std::string &) const
void parse(const std::string &selection, helper::SelectCode &code, std::string &cut) const
void getMotherKeys(std::vector< size_t > &, std::vector< size_t > &, const reco::GenParticleRefVector &) const
void flagMothers(const reco::GenParticle &, int)
const daughters & daughterRefVector() const
references to daughtes
key_type key() const
Accessor for product key.
Definition: Ref.h:263
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:253
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
bool empty() const
Is the RefVector empty.
Definition: RefVector.h:104
void recursiveFlagMothers(size_t, const reco::GenParticleCollection &, int, std::vector< size_t > &)
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:248
void recursiveFlagDaughters(size_t, const reco::GenParticleCollection &, int, std::vector< size_t > &)
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const mothers & motherRefVector() const
references to mothers
void getDaughterKeys(std::vector< size_t > &, std::vector< size_t > &, const reco::GenParticleRefVector &) const
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:326
double f[11][100]
TrackingParticleSelectorByGen(const edm::ParameterSet &)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::vector< std::pair< StringCutObjectSelector< reco::GenParticle >, helper::SelectCode > > select_
rep
Definition: cuy.py:1190
const int drop
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
def parse(path, config)
Definition: dumpparser.py:13
void add(std::string const &label, ParameterSetDescription const &psetDescription)
list command
Definition: mps_check.py:25
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
fixed size matrix
HLT enums.
edm::EDGetTokenT< reco::GenParticleCollection > gpToken_
def move(src, dest)
Definition: eostools.py:511