CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
InputGenJetsParticleSelector.cc
Go to the documentation of this file.
1 /* \class GenJetInputParticleSelector
2 *
3 * Selects particles that are used as input for the GenJet collection.
4 * Logic: select all stable particles, except for particles specified in
5 * the config file that come from
6 * W,Z and H decays, and except for a special list, which can be used for
7 * unvisible BSM-particles.
8 * It is also possible to only selected the partonic final state,
9 * which means all particles before the hadronization step.
10 *
11 * The algorithm is based on code of Christophe Saout.
12 *
13 * Usage: [example for no resonance from nu an mu, and deselect invisible BSM
14 * particles ]
15 *
16 * module genJetParticles = InputGenJetsParticleSelector {
17 * InputTag src = "genParticles"
18 * bool partonicFinalState = false
19 * bool excludeResonances = true
20 * vuint32 excludeFromResonancePids = {13,12,14,16}
21 * bool tausAsJets = false
22 * vuint32 ignoreParticleIDs = { 1000022, 2000012, 2000014,
23 * 2000016, 1000039, 5000039,
24 * 4000012, 9900012, 9900014,
25 * 9900016, 39}
26 * }
27 *
28 *
29 * \author: Christophe Saout, Andreas Oehler
30 *
31 * Modifications:
32 *
33 * 04.08.2014: Dinko Ferencek
34 * Added support for Pythia8 (status=22 for intermediate resonances)
35 *
36 */
37 
41 //#include <iostream>
42 #include <memory>
44 
45 using namespace std;
46 
48  inTag(params.getParameter<edm::InputTag>("src")),
49  partonicFinalState(params.getParameter<bool>("partonicFinalState")),
50  excludeResonances(params.getParameter<bool>("excludeResonances")),
51  tausAsJets(params.getParameter<bool>("tausAsJets")),
52  ptMin(0.0){
53  if (params.exists("ignoreParticleIDs"))
54  setIgnoredParticles(params.getParameter<std::vector<unsigned int> >
55  ("ignoreParticleIDs"));
56  setExcludeFromResonancePids(params.getParameter<std::vector<unsigned int> >
57  ("excludeFromResonancePids"));
58 
59  produces <reco::GenParticleRefVector> ();
60 
61 }
62 
64 
65 void InputGenJetsParticleSelector::setIgnoredParticles(const std::vector<unsigned int> &particleIDs)
66 {
67  ignoreParticleIDs = particleIDs;
69 }
70 
71 void InputGenJetsParticleSelector::setExcludeFromResonancePids(const std::vector<unsigned int> &particleIDs)
72 {
73  excludeFromResonancePids = particleIDs;
75 }
76 
78  pdgId = (pdgId > 0 ? pdgId : -pdgId) % 10000;
79  return (pdgId > 0 && pdgId < 6) ||
80  pdgId == 9 || (tausAsJets && pdgId == 15) || pdgId == 21;
81  // tops are not considered "regular" partons
82  // but taus eventually are (since they may hadronize later)
83 }
84 
86 {
87  pdgId = (pdgId > 0 ? pdgId : -pdgId) % 10000;
88  return (pdgId > 100 && pdgId < 900) ||
89  (pdgId > 1000 && pdgId < 9000);
90 }
91 
93 {
94  // gauge bosons and tops
95  pdgId = (pdgId > 0 ? pdgId : -pdgId) % 10000;
96  return (pdgId > 21 && pdgId <= 42) || pdgId == 6 || pdgId == 7 || pdgId == 8 ; //BUG! was 21. 22=gamma..
97 }
98 
100 {
101  pdgId = pdgId > 0 ? pdgId : -pdgId;
102  std::vector<unsigned int>::const_iterator pos =
103  std::lower_bound(ignoreParticleIDs.begin(),
104  ignoreParticleIDs.end(),
105  (unsigned int)pdgId);
106  return pos != ignoreParticleIDs.end() && *pos == (unsigned int)pdgId;
107 }
108 
110 {
111  pdgId = pdgId > 0 ? pdgId : -pdgId;
112  std::vector<unsigned int>::const_iterator pos =
113  std::lower_bound(excludeFromResonancePids.begin(),
115  (unsigned int)pdgId);
116  return pos != excludeFromResonancePids.end() && *pos == (unsigned int)pdgId;
117 
118 }
119 
121  const reco::GenParticle *particle)
122 {
123  InputGenJetsParticleSelector::ParticleVector::const_iterator pos =
124  std::lower_bound(p.begin(), p.end(), particle);
125  if (pos == p.end() || *pos != particle)
126  throw cms::Exception("CorruptedData")
127  << "reco::GenEvent corrupted: Unlisted particles"
128  " in decay tree." << std::endl;
129 
130  return pos - p.begin();
131 }
132 
135  const reco::GenParticle *particle)
136 {
137  unsigned int npart=particle->numberOfDaughters();
138  if (!npart) return;
139 
140  for (unsigned int i=0;i<npart;++i){
141  unsigned int idx=partIdx(p,dynamic_cast<const reco::GenParticle*>(particle->daughter(i)));
142  if (invalid[idx])
143  continue;
144  invalid[idx] = true;
145  //cout<<"Invalidated: ["<<setw(4)<<idx<<"] With pt:"<<particle->daughter(i)->pt()<<endl;
146  invalidateTree(invalid, p, dynamic_cast<const reco::GenParticle*>(particle->daughter(i)));
147  }
148 }
149 
150 
154  const reco::GenParticle *particle) const
155 {
156  unsigned int npart=particle->numberOfDaughters();
157  if (!npart) {return 0;}
158 
159  for (unsigned int i=0;i<npart;++i){
160  unsigned int idx = partIdx(p,dynamic_cast<const reco::GenParticle*>(particle->daughter(i)));
161  if (invalid[idx])
162  continue;
163  if (isParton((particle->daughter(i)->pdgId()))){
164  return 1;
165  }
166  if (isHadron((particle->daughter(i)->pdgId()))){
167  return -1;
168  }
169  int result = testPartonChildren(invalid,p,dynamic_cast<const reco::GenParticle*>(particle->daughter(i)));
170  if (result) return result;
171  }
172  return 0;
173 }
174 
177  const ParticleVector &p,
178  const reco::GenParticle *particle) const
179 {
180  unsigned int idx = partIdx(p, particle);
181  int id = particle->pdgId();
182 
183  if (invalid[idx]) return kIndirect;
184 
185  if (isResonance(id) && (particle->status() == 3 || particle->status() == 22) ){
186  return kDirect;
187  }
188 
189 
190  if (!isIgnored(id) && (isParton(id)))
191  return kNo;
192 
193 
194 
195  unsigned int nMo=particle->numberOfMothers();
196  if (!nMo)
197  return kNo;
198 
199 
200  for(unsigned int i=0;i<nMo;++i){
201  ResonanceState result = fromResonance(invalid,p,dynamic_cast<const reco::GenParticle*>(particle->mother(i)));
202  switch(result) {
203  case kNo:
204  break;
205  case kDirect:
206  if (dynamic_cast<const reco::GenParticle*>(particle->mother(i))->pdgId()==id || isResonance(id))
207  return kDirect;
208  if(!isExcludedFromResonance(id))
209  break;
210  case kIndirect:
211  return kIndirect;
212  }
213  }
214 return kNo;
215 }
216 
217 
219  const ParticleVector &p,
220  const reco::GenParticle *particle) const {
221  return testPartonChildren(invalid, p, particle) > 0;
222 }
223 
224 //######################################################
225 //function NEEDED and called per EVENT by FRAMEWORK:
227 
228 
229  std::auto_ptr<reco::GenParticleRefVector> selected_ (new reco::GenParticleRefVector);
230 
232  evt.getByLabel(inTag, genParticles );
233 
234  std::map<const reco::GenParticle*,size_t> particlePtrIdxMap;
235  ParticleVector particles;
236  for (reco::GenParticleCollection::const_iterator iter=genParticles->begin();iter!=genParticles->end();++iter){
237  particles.push_back(&*iter);
238  particlePtrIdxMap[&*iter] = (iter - genParticles->begin());
239  }
240 
241  std::sort(particles.begin(), particles.end());
242  unsigned int size = particles.size();
243 
244  ParticleBitmap selected(size, false);
245  ParticleBitmap invalid(size, false);
246 
247  for(unsigned int i = 0; i < size; i++) {
248  const reco::GenParticle *particle = particles[i];
249  if (invalid[i])
250  continue;
251  if (particle->status() == 1)
252  selected[i] = true;
253  if (partonicFinalState && isParton(particle->pdgId())) {
254 
255  if (particle->numberOfDaughters()==0 &&
256  particle->status() != 1) {
257  // some brokenness in event...
258  invalid[i] = true;
259  }
260  else if (!hasPartonChildren(invalid, particles,
261  particle)) {
262  selected[i] = true;
263  invalidateTree(invalid, particles,particle); //this?!?
264  }
265  }
266 
267  }
268 
269  for(size_t idx = 0; idx < size; ++idx){
270  const reco::GenParticle *particle = particles[idx];
271  if (!selected[idx] || invalid[idx]){
272  continue;
273  }
274 
275  if (excludeResonances &&
276  fromResonance(invalid, particles, particle)) {
277  invalid[idx] = true;
278  //cout<<"[INPUTSELECTOR] Invalidates FROM RESONANCE!: ["<<setw(4)<<idx<<"] "<<particle->pdgId()<<" "<<particle->pt()<<endl;
279  continue;
280  }
281 
282  if (isIgnored(particle->pdgId())){
283  continue;
284  }
285 
286 
287  if (particle->pt() >= ptMin){
288  edm::Ref<reco::GenParticleCollection> particleRef(genParticles,particlePtrIdxMap[particle]);
289  selected_->push_back(particleRef);
290  //cout<<"Finally we have: ["<<setw(4)<<idx<<"] "<<setw(4)<<particle->pdgId()<<" "<<particle->pt()<<endl;
291  }
292  }
293  evt.put(selected_);
294 }
295 
296 
297 
298 //define this as a plug-in
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
bool hasPartonChildren(ParticleBitmap &invalid, const ParticleVector &p, const reco::GenParticle *particle) const
std::vector< const reco::GenParticle * > ParticleVector
virtual int pdgId() const GCC11_FINAL
PDG identifier.
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
int testPartonChildren(ParticleBitmap &invalid, const ParticleVector &p, const reco::GenParticle *particle) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
double npart
Definition: HydjetWrapper.h:44
std::vector< unsigned int > excludeFromResonancePids
virtual void produce(edm::Event &evt, const edm::EventSetup &evtSetup)
void setIgnoredParticles(const std::vector< unsigned int > &particleIDs)
virtual int status() const GCC11_FINAL
status word
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:116
static void invalidateTree(InputGenJetsParticleSelector::ParticleBitmap &invalid, const InputGenJetsParticleSelector::ParticleVector &p, const reco::GenParticle *particle)
virtual size_t numberOfMothers() const
number of mothers
virtual size_t numberOfDaughters() const
number of daughters
tuple result
Definition: query.py:137
virtual const Candidate * daughter(size_type) const
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:390
static unsigned int partIdx(const InputGenJetsParticleSelector::ParticleVector &p, const reco::GenParticle *particle)
virtual int pdgId() const =0
PDG identifier.
bool isParton(const reco::Candidate &c)
Definition: CandMCTag.cc:48
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
std::vector< unsigned int > ignoreParticleIDs
void setExcludeFromResonancePids(const std::vector< unsigned int > &particleIDs)
virtual float pt() const GCC11_FINAL
transverse momentum
virtual const Candidate * mother(size_type=0) const
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
tuple size
Write out results.
ResonanceState fromResonance(ParticleBitmap &invalid, const ParticleVector &p, const reco::GenParticle *particle) const