CMS 3D CMS Logo

FlavorHistoryProducer.cc
Go to the documentation of this file.
1 // This file was removed but it should not have been.
2 // This comment is to restore it.
3 
5 
8 
9 // #include "DataFormats/Common/interface/ValueMap.h"
10 // #include <iterators>
11 
12 // -------------------------------------------------------------
13 // Identify the ancestry of the Quark
14 //
15 //
16 // Matrix Element:
17 // Status 3 parent with precisely 2 "grandparents" that
18 // is outside of the "initial" section (0-5) that has the
19 // same ID as the status 2 parton in question.
20 //
21 // Flavor excitation:
22 // If we find only one outgoing parton.
23 //
24 // Gluon splitting:
25 // Parent is a quark of a different flavor than the parton
26 // in question, or a gluon.
27 // Can come from either ISR or FSR.
28 //
29 // True decay:
30 // Decays from a resonance like top, Higgs, etc.
31 // -------------------------------------------------------------
32 
33 using namespace std;
34 using namespace reco;
35 using namespace edm;
36 
38  : srcToken_(consumes<CandidateView>(p.getParameter<InputTag>("src"))),
39  matchedSrcToken_(consumes<CandidateView>(p.getParameter<InputTag>("matchedSrc"))),
40  matchDR_(p.getParameter<double>("matchDR")),
41  pdgIdToSelect_(p.getParameter<int>("pdgIdToSelect")),
42  ptMinParticle_(p.getParameter<double>("ptMinParticle")),
43  ptMinShower_(p.getParameter<double>("ptMinShower")),
44  etaMaxParticle_(p.getParameter<double>("etaMaxParticle")),
45  etaMaxShower_(p.getParameter<double>("etaMaxShower")),
46  flavorHistoryName_(p.getParameter<string>("flavorHistoryName")),
47  verbose_(p.getUntrackedParameter<bool>("verbose")) {
48  produces<FlavorHistoryEvent>(flavorHistoryName_);
49 }
50 
52 
54  if (verbose_)
55  cout << "---------- Hello from FlavorHistoryProducer! -----" << endl;
56 
57  // Get a handle to the particle collection (OwnVector)
58  Handle<CandidateView> particlesViewH;
59  evt.getByToken(srcToken_, particlesViewH);
60 
61  Handle<CandidateView> matchedView;
62  evt.getByToken(matchedSrcToken_, matchedView);
63 
64  // Copy the View to an vector for easier iterator manipulation convenience
65  vector<const Candidate *> particles;
66  for (CandidateView::const_iterator p = particlesViewH->begin(); p != particlesViewH->end(); ++p) {
67  particles.push_back(&*p);
68  }
69 
70  // List of indices for the partons to add
71  vector<int> partonIndices;
72  // List of progenitors for those partons
73  vector<int> progenitorIndices;
74  // List of sisters for those partons
75  vector<int> sisterIndices;
76  // Flavor sources
77  vector<FlavorHistory::FLAVOR_T> flavorSources;
78 
79  // Make a new flavor history vector
80  auto flavorHistoryEvent = std::make_unique<FlavorHistoryEvent>();
81 
82  // ------------------------------------------------------------
83  // Loop over partons
84  // ------------------------------------------------------------
87  for (j = 0; j < j_max; ++j) {
88  // Get the candidate
89  const Candidate *p = particles[j];
90  // Set up indices that we'll need for the flavor history
92  vector<Candidate const *>::size_type progenitorIndex = j_max;
93  bool foundProgenitor = false;
94  FlavorHistory::FLAVOR_T flavorSource = FlavorHistory::FLAVOR_NULL;
95 
96  int idabs = std::abs((p)->pdgId());
97  int nDa = (p)->numberOfDaughters();
98 
99  // Check if we have a status 2 or 3 particle, which is a parton before the string.
100  // Only consider quarks.
101  if (idabs <= FlavorHistory::tQuarkId && p->status() == 2 && idabs == pdgIdToSelect_) {
102  // Ensure the parton in question has daughters
103  if (nDa > 0) {
104  // Ensure the parton passes some minimum kinematic cuts
105  if ((p)->pt() > ptMinShower_ && fabs((p)->eta()) < etaMaxShower_) {
106  if (verbose_)
107  cout << "--------------------------" << endl;
108  if (verbose_)
109  cout << "Processing particle " << j << ", status = " << p->status() << ", pdg id = " << p->pdgId() << endl;
110 
111  //Main (but simple) workhorse to get all ancestors
112  vector<Candidate const *> allParents;
113  getAncestors(*p, allParents);
114 
115  if (verbose_) {
116  cout << "Parents : " << endl;
117  vector<Candidate const *>::const_iterator iprint = allParents.begin(), iprintend = allParents.end();
118  for (; iprint != iprintend; ++iprint)
119  cout << " status = " << (*iprint)->status() << ", pdg id = " << (*iprint)->pdgId()
120  << ", pt = " << (*iprint)->pt() << endl;
121  }
122 
123  // -------------------------------------------------------------
124  // Identify the ancestry of the Quark
125  //
126  //
127  // Matrix Element:
128  // Status 3 parent with precisely 2 "grandparents" that
129  // is outside of the "initial" section (0-5) that has the
130  // same ID as the status 2 parton in question.
131  //
132  // Flavor excitation:
133  // If we find only one outgoing parton.
134  //
135  // Gluon splitting:
136  // Parent is a quark of a different flavor than the parton
137  // in question, or a gluon.
138  // Can come from either ISR or FSR.
139  //
140  // True decay:
141  // Decays from a resonance like top, Higgs, etc.
142  // -------------------------------------------------------------
143  vector<Candidate const *>::size_type a_size = allParents.size();
144 
145  //
146  // Loop over all the ancestors of this parton and find the progenitor.
147  //
148  for (vector<Candidate const *>::size_type i = 0; i < a_size && !foundProgenitor; ++i) {
149  const Candidate *aParent = allParents[i];
150  vector<Candidate const *>::const_iterator found = find(particles.begin(), particles.end(), aParent);
151 
152  // Get the index of the progenitor candidate
153  progenitorIndex = found - particles.begin();
154 
155  int aParentId = std::abs(aParent->pdgId());
156 
157  // -----------------------------------------------------------------------
158  // Here we examine particles that were produced after the collision
159  // -----------------------------------------------------------------------
160  if (progenitorIndex > 5) {
161  // Here is where we have a matrix element process.
162  // The signature is to have a status 3 parent with precisely 2 parents
163  // that is outside of the "initial" section (0-5) that has the
164  // same ID as the status 2 parton in question.
165  // NOTE: If this parton has no sister, then this will be classified as
166  // a flavor excitation. Often the only difference is that the matrix element
167  // cases have a sister, while the flavor excitation cases do not.
168  // If we do not find a sister below, this will be classified as a flavor
169  // excitation.
170  if (aParent->numberOfMothers() == 2 && aParent->pdgId() == p->pdgId() && aParent->status() == 3) {
171  if (verbose_)
172  cout << "Matrix Element progenitor" << endl;
173  if (flavorSource == FlavorHistory::FLAVOR_NULL)
174  flavorSource = FlavorHistory::FLAVOR_ME;
175  foundProgenitor = true;
176  }
177  // Here we have a true decay. Parent is not a quark or a gluon.
178  else if ((aParentId > pdgIdToSelect_ && aParentId < FlavorHistory::gluonId) ||
179  aParentId > FlavorHistory::gluonId) {
180  if (verbose_)
181  cout << "Flavor decay progenitor" << endl;
182  if (flavorSource == FlavorHistory::FLAVOR_NULL)
183  flavorSource = FlavorHistory::FLAVOR_DECAY;
184  foundProgenitor = true;
185  }
186  } // end if progenitorIndex > 5
187  } // end loop over parents
188 
189  // Otherwise, classify it as gluon splitting. Take the first status 3 parton with 1 parent
190  // that you see as the progenitor
191  if (!foundProgenitor) {
192  if (flavorSource == FlavorHistory::FLAVOR_NULL)
193  flavorSource = FlavorHistory::FLAVOR_GS;
194  // Now get the parton with only one parent (the proton) and that is the progenitor
195  for (vector<Candidate const *>::size_type i = 0; i < a_size && !foundProgenitor; ++i) {
196  const Candidate *aParent = allParents[i];
197  vector<Candidate const *>::const_iterator found = find(particles.begin(), particles.end(), aParent);
198  // Get the index of the progenitor candidate
199  progenitorIndex = found - particles.begin();
200 
201  if (aParent->numberOfMothers() == 1 && aParent->status() == 3) {
202  foundProgenitor = true;
203  }
204  } // end loop over parents
205  } // end if we haven't found a progenitor, and if we haven't found a status 3 parton of the same flavor
206  // (i.e. end if examining gluon splitting)
207  } // End if this parton passes some minimal kinematic cuts
208  } // End if this particle is status 2 (has strings as daughters)
209 
210  // Make sure we've actually found a progenitor
211  if (!foundProgenitor)
212  progenitorIndex = j_max;
213 
214  // We've found the particle, add to the list
215 
216  partonIndices.push_back(partonIndex);
217  progenitorIndices.push_back(progenitorIndex);
218  flavorSources.push_back(flavorSource);
219  sisterIndices.push_back(-1); // set below
220 
221  } // End if this particle was a status==2 parton
222  } // end loop over particles
223 
224  // Now add sisters.
225  // Also if the event is preliminarily classified as "matrix element", check to
226  // make sure that they have a sister. If not, it is flavor excitation.
227 
228  if (verbose_)
229  cout << "Making sisters" << endl;
230  // First make sure nothing went terribly wrong:
231  if (partonIndices.size() == progenitorIndices.size() && !partonIndices.empty()) {
232  // Now loop over the candidates
233  for (unsigned int ii = 0; ii < partonIndices.size(); ++ii) {
234  // Get the iith particle
235  const Candidate *candi = particles[partonIndices[ii]];
236  if (verbose_)
237  cout << " Sister candidate particle 1: " << ii << ", pdgid = " << candi->pdgId()
238  << ", status = " << candi->status() << endl;
239  // Get the iith progenitor
240  // Now loop over the other flavor history candidates and
241  // attempt to find a sister to this one
242  for (unsigned int jj = 0; jj < partonIndices.size(); ++jj) {
243  if (ii != jj) {
244  const Candidate *candj = particles[partonIndices[jj]];
245  if (verbose_)
246  cout << " Sister candidate particle 2: " << jj << ", pdgid = " << candj->pdgId()
247  << ", status = " << candj->status() << endl;
248  // They should be opposite in pdgid and have the same status, and
249  // the same progenitory.
250  if (candi->pdgId() == -1 * candj->pdgId() && candi->status() == candj->status()) {
251  sisterIndices[ii] = partonIndices[jj];
252  if (verbose_)
253  cout << "Parton " << partonIndices[ii] << " has sister " << sisterIndices[ii] << endl;
254  }
255  }
256  }
257 
258  // Here, ensure that there is a sister. Otherwise this is "flavor excitation"
259  if (sisterIndices[ii] < 0) {
260  if (verbose_)
261  cout << "No sister. Classified as flavor excitation" << endl;
262  flavorSources[ii] = FlavorHistory::FLAVOR_EXC;
263  }
264 
265  if (verbose_)
266  cout << "Getting matched jet" << endl;
267  // Get the closest match in the matched object collection
268  CandidateView::const_iterator matched = getClosestJet(matchedView, *candi);
269  CandidateView::const_iterator matchedBegin = matchedView->begin();
270  CandidateView::const_iterator matchedEnd = matchedView->end();
271 
272  if (verbose_)
273  cout << "Getting sister jet" << endl;
274  // Get the closest sister in the matched object collection, if sister is found
276  (sisterIndices[ii] >= 0 && static_cast<unsigned int>(sisterIndices[ii]) < particles.size())
277  ? getClosestJet(matchedView, *particles[sisterIndices[ii]])
278  : matchedEnd;
279 
280  if (verbose_)
281  cout << "Making matched shallow clones : ";
282  ShallowClonePtrCandidate matchedCand;
283  if (matched != matchedEnd) {
284  if (verbose_)
285  cout << " found" << endl;
286  matchedCand = ShallowClonePtrCandidate(CandidatePtr(matchedView, matched - matchedBegin));
287  } else {
288  if (verbose_)
289  cout << " NOT found" << endl;
290  }
291 
292  if (verbose_)
293  cout << "Making sister shallow clones : ";
294  ShallowClonePtrCandidate sisterCand;
295  if (sister != matchedEnd) {
296  if (verbose_)
297  cout << " found" << endl;
298  sisterCand = ShallowClonePtrCandidate(CandidatePtr(matchedView, sister - matchedBegin));
299  } else {
300  if (verbose_)
301  cout << " NOT found" << endl;
302  }
303 
304  if (verbose_)
305  cout << "Making history object" << endl;
306  // Now create the flavor history object
307  FlavorHistory history(flavorSources[ii],
308  particlesViewH,
309  partonIndices[ii],
310  progenitorIndices[ii],
311  sisterIndices[ii],
312  matchedCand,
313  sisterCand);
314  if (verbose_)
315  cout << "Adding flavor history : " << history << endl;
316  flavorHistoryEvent->push_back(history);
317  }
318  }
319 
320  // If we got any partons, cache them and then write them out
321  if (flavorHistoryEvent->size() > 0) {
322  // Calculate some nice variables for FlavorHistoryEvent
323  if (verbose_)
324  cout << "Caching flavor history event" << endl;
325  flavorHistoryEvent->cache();
326 
327  if (verbose_) {
328  cout << "Outputting pdg id = " << pdgIdToSelect_ << " with nelements = " << flavorHistoryEvent->size() << endl;
329  vector<FlavorHistory>::const_iterator i = flavorHistoryEvent->begin(), iend = flavorHistoryEvent->end();
330  for (; i != iend; ++i) {
331  cout << *i << endl;
332  }
333  }
334  }
335 
336  // Now add the flavor history to the event record
337  evt.put(std::move(flavorHistoryEvent), flavorHistoryName_);
338 }
339 
340 // Helper function to get all ancestors of this candidate
341 void FlavorHistoryProducer::getAncestors(const Candidate &c, vector<Candidate const *> &moms) {
342  if (c.numberOfMothers() == 1) {
343  const Candidate *dau = &c;
344  const Candidate *mom = c.mother();
345  while (dau->numberOfMothers() != 0) {
346  moms.push_back(dau);
347  dau = mom;
348  mom = dau->mother();
349  }
350  }
351 }
352 
354  reco::Candidate const &parton) const {
355  double dr = matchDR_;
356  CandidateView::const_iterator j = pJets->begin(), jend = pJets->end();
357  CandidateView::const_iterator bestJet = pJets->end();
358  for (; j != jend; ++j) {
359  double dri = deltaR(parton.p4(), j->p4());
360  if (dri < dr) {
361  dr = dri;
362  bestJet = j;
363  }
364  }
365  return bestJet;
366 }
367 
369 
muonTagProbeFilters_cff.matched
matched
Definition: muonTagProbeFilters_cff.py:62
edm::View::begin
const_iterator begin() const
FlavorHistoryProducer::~FlavorHistoryProducer
~FlavorHistoryProducer() override
destructor
Definition: FlavorHistoryProducer.cc:51
electrons_cff.bool
bool
Definition: electrons_cff.py:372
mps_fire.i
i
Definition: mps_fire.py:355
reco::FlavorHistory
Definition: FlavorHistory.h:45
MessageLogger.h
FlavorHistoryProducer::etaMaxShower_
double etaMaxShower_
Definition: FlavorHistoryProducer.h:80
mps_update.status
status
Definition: mps_update.py:69
edm
HLT enums.
Definition: AlignableModifier.h:19
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
gather_cfg.cout
cout
Definition: gather_cfg.py:144
reco::Candidate::status
virtual int status() const =0
status word
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
reco::Candidate::mother
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
newFWLiteAna.found
found
Definition: newFWLiteAna.py:118
edm::Handle
Definition: AssociativeIterator.h:50
ecalTrigSettings_cff.particles
particles
Definition: ecalTrigSettings_cff.py:11
deltaR.h
MakerMacros.h
reco::Candidate::numberOfMothers
virtual size_type numberOfMothers() const =0
number of mothers (zero or one in most of but not all the cases)
trigger::size_type
uint16_t size_type
Definition: TriggerTypeDefs.h:18
DEFINE_FWK_MODULE
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
PVValHelper::eta
Definition: PVValidationHelpers.h:69
reco::FlavorHistory::FLAVOR_T
FLAVOR_T
Definition: FlavorHistory.h:47
edm::Event::getByToken
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:528
PbPb_ZMuSkimMuonDPG_cff.deltaR
deltaR
Definition: PbPb_ZMuSkimMuonDPG_cff.py:63
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
edm::View
Definition: CaloClusterFwd.h:14
FlavorHistoryProducer::produce
void produce(edm::Event &e, const edm::EventSetup &) override
process one event
Definition: FlavorHistoryProducer.cc:53
edm::ParameterSet
Definition: ParameterSet.h:36
FlavorHistoryProducer::pdgIdToSelect_
int pdgIdToSelect_
Definition: FlavorHistoryProducer.h:76
createfilelist.int
int
Definition: createfilelist.py:10
edm::Event::put
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:132
FlavorHistoryProducer::getAncestors
void getAncestors(const reco::Candidate &c, std::vector< reco::Candidate const * > &moms)
Definition: FlavorHistoryProducer.cc:341
EgammaValidation_cff.pdgId
pdgId
Definition: EgammaValidation_cff.py:118
edm::EventSetup
Definition: EventSetup.h:57
FlavorHistoryProducer::matchDR_
double matchDR_
Definition: FlavorHistoryProducer.h:75
HltBtagPostValidation_cff.c
c
Definition: HltBtagPostValidation_cff.py:31
reco::Candidate::pdgId
virtual int pdgId() const =0
PDG identifier.
reco::Candidate
Definition: Candidate.h:27
eostools.move
def move(src, dest)
Definition: eostools.py:511
std
Definition: JetResolutionObject.h:76
FlavorHistoryProducer::matchedSrcToken_
edm::EDGetTokenT< reco::CandidateView > matchedSrcToken_
Definition: FlavorHistoryProducer.h:74
FlavorHistoryProducer
Definition: FlavorHistoryProducer.h:55
flavorHistoryFilter_cfi.dr
dr
Definition: flavorHistoryFilter_cfi.py:37
FlavorHistoryProducer::FlavorHistoryProducer
FlavorHistoryProducer(const edm::ParameterSet &)
constructor
Definition: FlavorHistoryProducer.cc:37
findQualityFiles.jj
string jj
Definition: findQualityFiles.py:188
FlavorHistoryProducer.h
reco::Candidate::p4
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
FlavorHistoryProducer::ptMinShower_
double ptMinShower_
Definition: FlavorHistoryProducer.h:78
edm::View::const_iterator
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:86
reco::CandidatePtr
edm::Ptr< Candidate > CandidatePtr
persistent reference to an object in a collection of Candidate objects
Definition: CandidateFwd.h:25
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::View::end
const_iterator end() const
reco::ShallowClonePtrCandidate
Definition: ShallowClonePtrCandidate.h:15
dqmiolumiharvest.j
j
Definition: dqmiolumiharvest.py:66
FlavorHistoryProducer::flavorHistoryName_
std::string flavorHistoryName_
Definition: FlavorHistoryProducer.h:81
edm::Event
Definition: Event.h:73
cuy.ii
ii
Definition: cuy.py:590
edm::InputTag
Definition: InputTag.h:15
FlavorHistoryProducer::verbose_
bool verbose_
Definition: FlavorHistoryProducer.h:82
FlavorHistoryProducer::getClosestJet
reco::CandidateView::const_iterator getClosestJet(edm::Handle< reco::CandidateView > const &pJets, reco::Candidate const &parton) const
Definition: FlavorHistoryProducer.cc:353
FlavorHistoryProducer::srcToken_
edm::EDGetTokenT< reco::CandidateView > srcToken_
Definition: FlavorHistoryProducer.h:73