CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GenParticlePruner.cc
Go to the documentation of this file.
10 
11 namespace helper {
12  struct SelectCode {
13  enum KeepOrDrop { kKeep, kDrop };
14  enum FlagDepth { kNone, kFirst, kAll };
17  bool all_;
18  };
19 }
20 
22 public:
24 private:
25  void produce(edm::Event&, const edm::EventSetup&);
29  std::vector<std::string> selection_;
30  std::vector<std::pair<StringCutObjectSelector<reco::GenParticle>, helper::SelectCode> > select_;
31  std::vector<int> flags_;
32  std::vector<size_t> indices_;
33  void parse(const std::string & selection, helper::SelectCode & code, std::string & cut) const;
34  void flagDaughters(const reco::GenParticle &, int);
35  void flagMothers(const reco::GenParticle &, int);
36  void recursiveFlagDaughters(size_t, const reco::GenParticleCollection &, int);
37  void recursiveFlagMothers(size_t, const reco::GenParticleCollection &, int);
40 };
41 
42 using namespace edm;
43 using namespace std;
44 using namespace reco;
45 
46 const int keep = 1, drop = -1;
47 
48 void GenParticlePruner::parse(const std::string & selection, ::helper::SelectCode & code, std::string & cut) const {
49  using namespace ::helper;
50  size_t f = selection.find_first_not_of(' ');
51  size_t n = selection.size();
52  string command;
53  char c;
54  for(; (c = selection[f]) != ' ' && f < n; ++f) {
55  command.push_back(c);
56  }
57  if(command[0] == '+') {
58  command.erase(0, 1);
59  if(command[0] == '+') {
60  command.erase(0, 1);
61  code.mothersDepth_ = SelectCode::kAll;
62  } else {
63  code.mothersDepth_ = SelectCode::kFirst;
64  }
65  } else
67 
68  if(command[command.size() - 1] == '+') {
69  command.erase(command.size() - 1);
70  if(command[command.size()-1] == '+') {
71  command.erase(command.size() - 1);
72  code.daughtersDepth_ = SelectCode::kAll;
73  } else {
74  code.daughtersDepth_ = SelectCode::kFirst;
75  }
76  } else
78 
79  if(command == "keep") code.keepOrDrop_ = SelectCode::kKeep;
80  else if(command == "drop") code.keepOrDrop_ = SelectCode::kDrop;
81  else {
83  << "invalid selection command: " << command << "\n" << endl;
84  }
85  for(; f < n; ++f) {
86  if(selection[f] != ' ') break;
87  }
88  cut = string(selection, f);
89  if(cut[0] == '*')
90  cut = string(cut, 0, cut.find_first_of(' '));
91  code.all_ = cut == "*";
92 }
93 
95  firstEvent_(true),
96  src_(cfg.getParameter<InputTag>("src")), keepOrDropAll_(drop),
97  selection_(cfg.getParameter<vector<string> >("select")) {
98  using namespace ::helper;
99  produces<GenParticleCollection>();
100 }
101 
102 void GenParticlePruner::flagDaughters(const reco::GenParticle & gen, int keepOrDrop) {
103  GenParticleRefVector daughters = gen.daughterRefVector();
104  for(GenParticleRefVector::const_iterator i = daughters.begin(); i != daughters.end(); ++i)
105  flags_[i->key()] = keepOrDrop;
106 }
107 
108 void GenParticlePruner::flagMothers(const reco::GenParticle & gen, int keepOrDrop) {
109  GenParticleRefVector mothers = gen.motherRefVector();
110  for(GenParticleRefVector::const_iterator i = mothers.begin(); i != mothers.end(); ++i)
111  flags_[i->key()] = keepOrDrop;
112 }
113 
115  GenParticleRefVector daughters = src[index].daughterRefVector();
116  for(GenParticleRefVector::const_iterator i = daughters.begin(); i != daughters.end(); ++i) {
117  index = i->key();
118  flags_[index] = keepOrDrop;
119  recursiveFlagDaughters(index, src, keepOrDrop);
120  }
121 }
122 
124  GenParticleRefVector mothers = src[index].motherRefVector();
125  for(GenParticleRefVector::const_iterator i = mothers.begin(); i != mothers.end(); ++i) {
126  index = i->key();
127  flags_[index] = keepOrDrop;
128  recursiveFlagMothers(index, src, keepOrDrop);
129  }
130 }
131 
133  if (firstEvent_) {
134  PdgEntryReplacer rep(es);
135  for(vector<string>::const_iterator i = selection_.begin(); i != selection_.end(); ++i) {
136  string cut;
138  parse(*i, code, cut);
139  if(code.all_) {
140  if(i != selection_.begin())
142  << "selections \"keep *\" and \"drop *\" can be used only as first options. Here used in position # "
143  << (i - selection_.begin()) + 1 << "\n" << endl;
144  switch(code.keepOrDrop_) {
145  case ::helper::SelectCode::kDrop :
146  keepOrDropAll_ = drop; break;
147  case ::helper::SelectCode::kKeep :
149  };
150  } else {
151  cut = rep.replace(cut);
152  select_.push_back(make_pair(StringCutObjectSelector<GenParticle>(cut), code));
153  }
154  }
155  firstEvent_ = false;
156  }
157 
158  using namespace ::helper;
160  evt.getByLabel(src_, src);
161  const size_t n = src->size();
162  flags_.clear();
163  flags_.resize(n, keepOrDropAll_);
164  for(size_t j = 0; j < select_.size(); ++j) {
165  const pair<StringCutObjectSelector<GenParticle>, SelectCode> & sel = select_[j];
166  SelectCode code = sel.second;
167  const StringCutObjectSelector<GenParticle> & cut = sel.first;
168  for(size_t i = 0; i < n; ++i) {
169  const GenParticle & p = (*src)[i];
170  if(cut(p)) {
171  int keepOrDrop = keep;
172  switch(code.keepOrDrop_) {
173  case SelectCode::kKeep:
174  keepOrDrop = keep; break;
175  case SelectCode::kDrop:
176  keepOrDrop = drop;
177  };
178  flags_[i] = keepOrDrop;
179  switch(code.daughtersDepth_) {
180  case SelectCode::kAll :
181  recursiveFlagDaughters(i, *src, keepOrDrop); break;
182  case SelectCode::kFirst :
183  flagDaughters(p, keepOrDrop); break;
184  case SelectCode::kNone:
185  ;
186  };
187  switch(code.mothersDepth_) {
188  case SelectCode::kAll :
189  recursiveFlagMothers(i, *src, keepOrDrop); break;
190  case SelectCode::kFirst :
191  flagMothers(p, keepOrDrop); break;
192  case SelectCode::kNone:
193  ;
194  };
195  }
196  }
197  }
198  indices_.clear();
199  int counter = 0;
200  for(size_t i = 0; i < n; ++i) {
201  if(flags_[i] == keep) {
202  indices_.push_back(i);
203  flags_[i] = counter++;
204  }
205  }
206 
207  auto_ptr<GenParticleCollection> out(new GenParticleCollection);
209  out->reserve(counter);
210  for(vector<size_t>::const_iterator i = indices_.begin(); i != indices_.end(); ++i) {
211  size_t index = *i;
212  const GenParticle & gen = (*src)[index];
213  const LeafCandidate & part = gen;
214  out->push_back(GenParticle(part));
215  GenParticle & newGen = out->back();
216  addDaughterRefs(newGen, outRef, gen.daughterRefVector());
217  addMotherRefs(newGen, outRef, gen.motherRefVector());
218  }
219 
220  evt.put(out);
221 }
222 
223 
225  const GenParticleRefVector& daughters) const {
226  for(GenParticleRefVector::const_iterator j = daughters.begin();
227  j != daughters.end(); ++j) {
228  GenParticleRef dau = *j;
229  int idx = flags_[dau.key()];
230  if(idx > 0) {
231  GenParticleRef newDau(outRef, static_cast<size_t>(idx));
232  newGen.addDaughter(newDau);
233  } else {
234  const GenParticleRefVector daus = dau->daughterRefVector();
235  if(daus.size()>0)
236  addDaughterRefs(newGen, outRef, daus);
237  }
238  }
239 }
240 
242  const GenParticleRefVector& mothers) const {
244  j != mothers.end(); ++j) {
245  GenParticleRef mom = *j;
246  int idx = flags_[mom.key()];
247  if(idx > 0) {
248  GenParticleRef newMom(outRef, static_cast<size_t>(idx));
249  newGen.addMother(newMom);
250  } else {
251  const GenParticleRefVector moms = mom->motherRefVector();
252  if(moms.size()>0)
253  addMotherRefs(newGen, outRef, moms);
254  }
255  }
256 }
257 
259 
std::vector< std::pair< StringCutObjectSelector< reco::GenParticle >, helper::SelectCode > > select_
void flagDaughters(const reco::GenParticle &, int)
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
int i
Definition: DBlmapReader.cc:9
void produce(edm::Event &, const edm::EventSetup &)
std::vector< int > flags_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void flagMothers(const reco::GenParticle &, int)
std::string replace(const std::string &) const
const daughters & daughterRefVector() const
references to daughtes
GenParticlePruner(const edm::ParameterSet &)
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:243
void addDaughterRefs(reco::GenParticle &, reco::GenParticleRefProd, const reco::GenParticleRefVector &) const
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:238
void addDaughter(const typename daughters::value_type &)
add a daughter via a reference
std::vector< size_t > indices_
const int keep
const mothers & motherRefVector() const
references to mothers
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:84
int j
Definition: DBlmapReader.cc:9
double f[11][100]
void addMotherRefs(reco::GenParticle &, reco::GenParticleRefProd, const reco::GenParticleRefVector &) const
void recursiveFlagDaughters(size_t, const reco::GenParticleCollection &, int)
void parse(const std::string &selection, helper::SelectCode &code, std::string &cut) const
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:355
void addMother(const typename mothers::value_type &)
add a daughter via a reference
RefProd< PROD > getRefBeforePut()
Definition: Event.h:96
const int drop
tuple out
Definition: dbtoconf.py:99
tuple cut
Definition: align_tpl.py:88
part
Definition: HCALResponse.h:21
key_type key() const
Accessor for product key.
Definition: Ref.h:265
void recursiveFlagMothers(size_t, const reco::GenParticleCollection &, int)
size_type size() const
Size of the RefVector.
Definition: RefVector.h:84
std::vector< std::string > selection_
tuple src
Definition: align_tpl.py:87