CMS 3D CMS Logo

RecoTauBuilderCombinatoricPlugin.cc
Go to the documentation of this file.
1 #include <vector>
2 
5 
9 
11 
18 
19 #include <algorithm>
20 
21 namespace reco {
22  namespace tau {
23 
24  typedef std::vector<reco::PFRecoTauChargedHadron> ChargedHadronList;
26  typedef std::vector<RecoTauPiZero> PiZeroList;
28 
30  public:
33 
35  const std::vector<reco::PFRecoTauChargedHadron>&,
36  const std::vector<RecoTauPiZero>&,
37  const std::vector<CandidatePtr>&) const override;
38 
39  private:
40  std::unique_ptr<RecoTauQualityCuts> qcuts_;
41 
43 
44  struct decayModeInfo {
45  uint32_t maxPiZeros_;
46  uint32_t maxPFCHs_;
47  uint32_t nCharged_;
48  uint32_t nPiZeros_;
49  };
50  std::vector<decayModeInfo> decayModesToBuild_;
51 
57 
59  };
60 
64  qcuts_(new RecoTauQualityCuts(pset.getParameterSet("qualityCuts").getParameterSet("signalQualityCuts"))),
65  isolationConeSize_(pset.getParameter<double>("isolationConeSize")),
66  signalConeSize_(pset.getParameter<std::string>("signalConeSize")),
67  minAbsPhotonSumPt_insideSignalCone_(pset.getParameter<double>("minAbsPhotonSumPt_insideSignalCone")),
68  minRelPhotonSumPt_insideSignalCone_(pset.getParameter<double>("minRelPhotonSumPt_insideSignalCone")),
69  minAbsPhotonSumPt_outsideSignalCone_(pset.getParameter<double>("minAbsPhotonSumPt_outsideSignalCone")),
70  minRelPhotonSumPt_outsideSignalCone_(pset.getParameter<double>("minRelPhotonSumPt_outsideSignalCone")) {
71  typedef std::vector<edm::ParameterSet> VPSet;
72  const VPSet& decayModes = pset.getParameter<VPSet>("decayModes");
73  for (VPSet::const_iterator decayMode = decayModes.begin(); decayMode != decayModes.end(); ++decayMode) {
75  info.nCharged_ = decayMode->getParameter<uint32_t>("nCharged");
76  info.nPiZeros_ = decayMode->getParameter<uint32_t>("nPiZeros");
77  info.maxPFCHs_ = decayMode->getParameter<uint32_t>("maxTracks");
78  info.maxPiZeros_ = decayMode->getParameter<uint32_t>("maxPiZeros");
79  decayModesToBuild_.push_back(info);
80  }
81 
82  verbosity_ = pset.getParameter<int>("verbosity");
83  }
84 
85  // define template specialization for cross-cleaning
86  namespace xclean {
87  template <>
89  const ChargedHadronCombo::combo_iterator& chargedHadronsBegin,
90  const ChargedHadronCombo::combo_iterator& chargedHadronsEnd) {
91  // Get the list of objects we need to clean
92  for (ChargedHadronCombo::combo_iterator chargedHadron = chargedHadronsBegin; chargedHadron != chargedHadronsEnd;
93  ++chargedHadron) {
94  // CV: Remove PFGammas that are merged into TauChargedHadrons from isolation PiZeros, but not from signal PiZeros.
95  // The overlap between PFGammas contained in signal PiZeros and merged into TauChargedHadrons
96  // is resolved by RecoTauConstructor::addTauChargedHadron,
97  // which gives preference to PFGammas that are within PiZeros and removes those PFGammas from TauChargedHadrons.
98  if (mode_ == kRemoveChargedDaughterOverlaps) {
99  if (chargedHadron->getChargedPFCandidate().isNonnull())
100  toRemove_.insert(reco::CandidatePtr(chargedHadron->getChargedPFCandidate()));
101  } else if (mode_ == kRemoveChargedAndNeutralDaughterOverlaps) {
102  const reco::CompositePtrCandidate::daughters& daughters = chargedHadron->daughterPtrVector();
103  for (reco::CompositePtrCandidate::daughters::const_iterator daughter = daughters.begin();
104  daughter != daughters.end();
105  ++daughter) {
106  toRemove_.insert(reco::CandidatePtr(*daughter));
107  }
108  } else
109  assert(0);
110  }
111  }
112 
113  template <>
114  inline void CrossCleanPtrs<PiZeroList::const_iterator>::initialize(const PiZeroList::const_iterator& piZerosBegin,
115  const PiZeroList::const_iterator& piZerosEnd) {
116  for (auto const& ptr : flattenPiZeros(piZerosBegin, piZerosEnd)) {
117  toRemove_.insert(CandidatePtr(ptr));
118  }
119  }
120 
121  template <>
123  const ChargedHadronCombo::combo_iterator& chargedHadronsBegin,
124  const ChargedHadronCombo::combo_iterator& chargedHadronsEnd) {
125  //std::cout << "<CrossCleanPtrs<ChargedHadronCombo>::initialize>:" << std::endl;
126  for (ChargedHadronCombo::combo_iterator chargedHadron = chargedHadronsBegin; chargedHadron != chargedHadronsEnd;
127  ++chargedHadron) {
128  const reco::CompositePtrCandidate::daughters& daughters = chargedHadron->daughterPtrVector();
129  for (reco::CompositePtrCandidate::daughters::const_iterator daughter = daughters.begin();
130  daughter != daughters.end();
131  ++daughter) {
132  //std::cout << " adding PFCandidate = " << daughter->id() << ":" << daughter->key() << std::endl;
133  toRemove_.insert(reco::CandidatePtr(*daughter));
134  }
135  }
136  }
137 
138  template <>
140  const ChargedHadronList::const_iterator& chargedHadronsBegin,
141  const ChargedHadronList::const_iterator& chargedHadronsEnd) {
142  //std::cout << "<CrossCleanPtrs<ChargedHadronList>::initialize>:" << std::endl;
143  for (ChargedHadronList::const_iterator chargedHadron = chargedHadronsBegin; chargedHadron != chargedHadronsEnd;
144  ++chargedHadron) {
145  const reco::CompositePtrCandidate::daughters& daughters = chargedHadron->daughterPtrVector();
146  for (reco::CompositePtrCandidate::daughters::const_iterator daughter = daughters.begin();
147  daughter != daughters.end();
148  ++daughter) {
149  //std::cout << " adding PFCandidate = " << daughter->id() << ":" << daughter->key() << std::endl;
150  toRemove_.insert(reco::CandidatePtr(*daughter));
151  }
152  }
153  }
154  } // namespace xclean
155 
156  namespace {
157  // auxiliary class for sorting pizeros by descending transverse momentum
158  class SortPi0sDescendingPt {
159  public:
160  bool operator()(const RecoTauPiZero& a, const RecoTauPiZero& b) const { return a.pt() > b.pt(); }
161  };
162 
163  double square(double x) { return x * x; }
164  } // namespace
165 
167  const reco::JetBaseRef& jet,
168  const std::vector<reco::PFRecoTauChargedHadron>& chargedHadrons,
169  const std::vector<RecoTauPiZero>& piZeros,
170  const std::vector<CandidatePtr>& regionalExtras) const {
171  if (verbosity_) {
172  std::cout << "<RecoTauBuilderCombinatoricPlugin::operator()>:" << std::endl;
173  std::cout << " processing jet: Pt = " << jet->pt() << ", eta = " << jet->eta() << ", phi = " << jet->eta()
174  << ","
175  << " mass = " << jet->mass() << ", area = " << jet->jetArea() << std::endl;
176  }
177 
178  // Define output.
180 
181  // Update the primary vertex used by the quality cuts. The PV is supplied by
182  // the base class.
183  qcuts_->setPV(primaryVertex(jet));
184 
185  typedef std::vector<CandidatePtr> CandPtrs;
186 
187  if (verbosity_) {
188  std::cout << "#chargedHadrons = " << chargedHadrons.size() << std::endl;
189  int idx = 0;
190  for (ChargedHadronList::const_iterator chargedHadron = chargedHadrons.begin();
191  chargedHadron != chargedHadrons.end();
192  ++chargedHadron) {
193  std::cout << "chargedHadron #" << idx << ":" << std::endl;
194  chargedHadron->print(std::cout);
195  ++idx;
196  }
197  std::cout << "#piZeros = " << piZeros.size() << std::endl;
198  idx = 0;
199  for (PiZeroList::const_iterator piZero = piZeros.begin(); piZero != piZeros.end(); ++piZero) {
200  std::cout << "piZero #" << idx << ":" << std::endl;
201  piZero->print(std::cout);
202  ++idx;
203  }
204  }
205 
206  CandPtrs pfchs = qcuts_->filterCandRefs(pfChargedCands(*jet));
207  CandPtrs pfnhs = qcuts_->filterCandRefs(pfCandidatesByPdgId(*jet, 130));
208  CandPtrs pfgammas = qcuts_->filterCandRefs(pfCandidatesByPdgId(*jet, 22));
209 
212  CandPtrs regionalJunk = qcuts_->filterCandRefs(regionalExtras);
213 
214  // Loop over the decay modes we want to build
215  for (std::vector<decayModeInfo>::const_iterator decayMode = decayModesToBuild_.begin();
216  decayMode != decayModesToBuild_.end();
217  ++decayMode) {
218  // Find how many piZeros are in this decay mode
219  size_t piZerosToBuild = decayMode->nPiZeros_;
220  // Find how many tracks are in this decay mode
221  size_t tracksToBuild = decayMode->nCharged_;
222  if (verbosity_) {
223  std::cout << "piZerosToBuild = " << piZerosToBuild << std::endl;
224  std::cout << "#piZeros = " << piZeros.size() << std::endl;
225  std::cout << "tracksToBuild = " << tracksToBuild << std::endl;
226  std::cout << "#chargedHadrons = " << chargedHadrons.size() << std::endl;
227  }
228 
229  // Skip decay mode if jet doesn't have the multiplicity to support it
230  if (chargedHadrons.size() < tracksToBuild)
231  continue;
232 
233  // Find the start and end of potential signal tracks
234  ChargedHadronList::const_iterator chargedHadron_begin = chargedHadrons.begin();
235  ChargedHadronList::const_iterator chargedHadron_end = chargedHadrons.end();
236  chargedHadron_end = takeNElements(chargedHadron_begin, chargedHadron_end, decayMode->maxPFCHs_);
237 
238  // Build our track combo generator
239  ChargedHadronCombo trackCombos(chargedHadron_begin, chargedHadron_end, tracksToBuild);
240 
241  CandPtrs::iterator pfch_end = pfchs.end();
242  pfch_end = takeNElements(pfchs.begin(), pfch_end, decayMode->maxPFCHs_);
243 
244  //-------------------------------------------------------
245  // Begin combinatoric loop for this decay mode
246  //-------------------------------------------------------
247 
248  // Loop over the different combinations of tracks
249  for (ChargedHadronCombo::iterator trackCombo = trackCombos.begin(); trackCombo != trackCombos.end();
250  ++trackCombo) {
252  trackCombo->combo_begin(),
253  trackCombo->combo_end(),
255 
256  PiZeroList cleanSignalPiZeros = signalPiZeroXCleaner(piZeros);
257 
258  // CV: sort collection of cross-cleaned pi0s by descending Pt
259  std::sort(cleanSignalPiZeros.begin(), cleanSignalPiZeros.end(), SortPi0sDescendingPt());
260 
261  // Skip decay mode if we don't have enough remaining clean pizeros to
262  // build it.
263  if (cleanSignalPiZeros.size() < piZerosToBuild)
264  continue;
265 
266  // Find the start and end of potential signal tracks
267  PiZeroList::iterator signalPiZero_begin = cleanSignalPiZeros.begin();
268  PiZeroList::iterator signalPiZero_end = cleanSignalPiZeros.end();
269  signalPiZero_end = takeNElements(signalPiZero_begin, signalPiZero_end, decayMode->maxPiZeros_);
270 
271  // Build our piZero combo generator
272  PiZeroCombo piZeroCombos(signalPiZero_begin, signalPiZero_end, piZerosToBuild);
273  // Loop over the different combinations of PiZeros
274  for (PiZeroCombo::iterator piZeroCombo = piZeroCombos.begin(); piZeroCombo != piZeroCombos.end();
275  ++piZeroCombo) {
276  // Output tau
278  getPFCands(),
279  true,
285  // Reserve space in our collections
287  tau.reserve(RecoTauConstructor::kSignal, RecoTauConstructor::kGamma, 2 * piZerosToBuild); // k-factor = 2
288  tau.reservePiZero(RecoTauConstructor::kSignal, piZerosToBuild);
289 
291  trackCombo->combo_begin(),
292  trackCombo->combo_end(),
294 
295  PiZeroList precleanedIsolationPiZeros = isolationPiZeroXCleaner(piZeros);
296  std::set<reco::CandidatePtr> toRemove;
297  for (PiZeroCombo::combo_iterator signalPiZero = piZeroCombo->combo_begin();
298  signalPiZero != piZeroCombo->combo_end();
299  ++signalPiZero) {
300  toRemove.insert(signalPiZero->daughterPtrVector().begin(), signalPiZero->daughterPtrVector().end());
301  }
302  PiZeroList cleanIsolationPiZeros;
303  for (auto const& precleanedPiZero : precleanedIsolationPiZeros) {
304  std::set<reco::CandidatePtr> toCheck(precleanedPiZero.daughterPtrVector().begin(),
305  precleanedPiZero.daughterPtrVector().end());
306  std::vector<reco::CandidatePtr> cleanDaughters;
308  toCheck.begin(), toCheck.end(), toRemove.begin(), toRemove.end(), std::back_inserter(cleanDaughters));
309  // CV: piZero is signal piZero if at least one daughter overlaps
310  if (cleanDaughters.size() == precleanedPiZero.daughterPtrVector().size()) {
311  cleanIsolationPiZeros.push_back(precleanedPiZero);
312  }
313  }
314  if (verbosity_) {
315  std::cout << "#cleanIsolationPiZeros = " << cleanIsolationPiZeros.size() << std::endl;
316  int idx = 0;
317  for (PiZeroList::const_iterator piZero = cleanIsolationPiZeros.begin();
318  piZero != cleanIsolationPiZeros.end();
319  ++piZero) {
320  std::cout << "piZero #" << idx << ":" << std::endl;
321  piZero->print(std::cout);
322  ++idx;
323  }
324  }
325 
326  // FIXME - are all these reserves okay? will they get propagated to the
327  // dataformat size if they are wrong?
330  chargedHadrons.size() - tracksToBuild);
331  tau.reserve(
332  RecoTauConstructor::kIsolation, RecoTauConstructor::kGamma, (piZeros.size() - piZerosToBuild) * 2);
333  tau.reservePiZero(RecoTauConstructor::kIsolation, (piZeros.size() - piZerosToBuild));
334 
335  // Get signal PiZero constituents and add them to the tau.
336  // The sub-gammas are automatically added.
337  tau.addPiZeros(RecoTauConstructor::kSignal, piZeroCombo->combo_begin(), piZeroCombo->combo_end());
338 
339  // Set signal and isolation components for charged hadrons, after
340  // converting them to a PFCandidateRefVector
341  //
342  // NOTE: signal ChargedHadrons need to be added **after** signal PiZeros
343  // to avoid double-counting PFGammas as part of PiZero and merged with ChargedHadron
344  //
345  tau.addTauChargedHadrons(RecoTauConstructor::kSignal, trackCombo->combo_begin(), trackCombo->combo_end());
346 
347  // Now build isolation collections
348  // Load our isolation tools
349  using namespace reco::tau::cone;
350  CandPtrDRFilter isolationConeFilter(tau.p4(), -0.1, isolationConeSize_);
351 
352  // Cross cleaning predicate: Remove any PFCandidatePtrs that are contained within existing ChargedHadrons or PiZeros.
353  // The predicate will return false for any object that overlaps with chargedHadrons or cleanPiZeros.
354  // 1.) to select charged PFCandidates within jet that are not signalPFChargedHadrons
355  typedef xclean::CrossCleanPtrs<ChargedHadronCombo::combo_iterator> pfChargedHadronXCleanerType;
356  pfChargedHadronXCleanerType pfChargedHadronXCleaner_comboChargedHadrons(trackCombo->combo_begin(),
357  trackCombo->combo_end());
358  // And this cleaning filter predicate with our Iso cone filter
360  isolationConeFilter, pfChargedHadronXCleaner_comboChargedHadrons);
361  // 2.) to select neutral PFCandidates within jet
362  xclean::CrossCleanPtrs<ChargedHadronList::const_iterator> pfChargedHadronXCleaner_allChargedHadrons(
363  chargedHadrons.begin(), chargedHadrons.end());
364  xclean::CrossCleanPtrs<PiZeroList::const_iterator> piZeroXCleaner(piZeros.begin(), piZeros.end());
367  pfCandXCleanerType;
368  pfCandXCleanerType pfCandXCleaner_allChargedHadrons(pfChargedHadronXCleaner_allChargedHadrons,
369  piZeroXCleaner);
370  // And this cleaning filter predicate with our Iso cone filter
371  xclean::PredicateAND<CandPtrDRFilter, pfCandXCleanerType> pfCandFilter_allChargedHadrons(
372  isolationConeFilter, pfCandXCleaner_allChargedHadrons);
373 
374  ChargedHadronDRFilter isolationConeFilterChargedHadron(tau.p4(), -0.1, isolationConeSize_);
375  PiZeroDRFilter isolationConeFilterPiZero(tau.p4(), -0.1, isolationConeSize_);
376 
377  // Additionally make predicates to select the different PF object types
378  // of the regional junk objects to add
380 
381  xclean::FilterCandByAbsPdgId pfchCandSelector(211);
382  xclean::FilterCandByAbsPdgId pfgammaCandSelector(22);
383  xclean::FilterCandByAbsPdgId pfnhCandSelector(130);
384 
385  RegionalJunkConeAndIdFilter pfChargedJunk(pfchCandSelector, // select charged stuff from junk
386  isolationConeFilter); // only take those in iso cone
387 
388  RegionalJunkConeAndIdFilter pfGammaJunk(pfgammaCandSelector, // select gammas from junk
389  isolationConeFilter); // only take those in iso cone
390 
391  RegionalJunkConeAndIdFilter pfNeutralJunk(pfnhCandSelector, // select neutral stuff from junk
392  isolationConeFilter); // select stuff in iso cone
393 
395  boost::make_filter_iterator(
396  isolationConeFilterPiZero, cleanIsolationPiZeros.begin(), cleanIsolationPiZeros.end()),
397  boost::make_filter_iterator(
398  isolationConeFilterPiZero, cleanIsolationPiZeros.end(), cleanIsolationPiZeros.end()));
399 
400  // Filter the isolation candidates in a DR cone
401  //
402  // NOTE: isolation ChargedHadrons need to be added **after** signal and isolation PiZeros
403  // to avoid double-counting PFGammas as part of PiZero and merged with ChargedHadron
404  //
405  if (verbosity_ >= 2) {
406  std::cout << "adding isolation PFChargedHadrons from trackCombo:" << std::endl;
407  }
408  tau.addTauChargedHadrons(
410  boost::make_filter_iterator(
411  isolationConeFilterChargedHadron, trackCombo->remainder_begin(), trackCombo->remainder_end()),
412  boost::make_filter_iterator(
413  isolationConeFilterChargedHadron, trackCombo->remainder_end(), trackCombo->remainder_end()));
414 
415  // Add all the candidates that weren't included in the combinatoric
416  // generation
417  if (verbosity_ >= 2) {
418  std::cout << "adding isolation PFChargedHadrons not considered in trackCombo:" << std::endl;
419  }
422  boost::make_filter_iterator(pfCandFilter_comboChargedHadrons, pfch_end, pfchs.end()),
423  boost::make_filter_iterator(pfCandFilter_comboChargedHadrons, pfchs.end(), pfchs.end()));
424  // Add all charged candidates that are in the iso cone but weren't in the
425  // original PFJet
426  if (verbosity_ >= 2) {
427  std::cout << "adding isolation PFChargedHadrons from 'regional junk':" << std::endl;
428  }
431  boost::make_filter_iterator(pfChargedJunk, regionalJunk.begin(), regionalJunk.end()),
432  boost::make_filter_iterator(pfChargedJunk, regionalJunk.end(), regionalJunk.end()));
433 
434  // Add all PFGamma constituents of the jet that are not part of a PiZero
435  if (verbosity_ >= 2) {
436  std::cout << "adding isolation PFGammas not considered in PiZeros:" << std::endl;
437  }
438  tau.addPFCands(
441  boost::make_filter_iterator(pfCandFilter_allChargedHadrons, pfgammas.begin(), pfgammas.end()),
442  boost::make_filter_iterator(pfCandFilter_allChargedHadrons, pfgammas.end(), pfgammas.end()));
443  // Add all gammas that are in the iso cone but weren't in the
444  // orginal PFJet
447  boost::make_filter_iterator(pfGammaJunk, regionalJunk.begin(), regionalJunk.end()),
448  boost::make_filter_iterator(pfGammaJunk, regionalJunk.end(), regionalJunk.end()));
449 
450  // Add all the neutral hadron candidates to the isolation collection
453  boost::make_filter_iterator(pfCandFilter_allChargedHadrons, pfnhs.begin(), pfnhs.end()),
454  boost::make_filter_iterator(pfCandFilter_allChargedHadrons, pfnhs.end(), pfnhs.end()));
455  // Add all the neutral hadrons from the region collection that are in
456  // the iso cone to the tau
459  boost::make_filter_iterator(pfNeutralJunk, regionalJunk.begin(), regionalJunk.end()),
460  boost::make_filter_iterator(pfNeutralJunk, regionalJunk.end(), regionalJunk.end()));
461 
462  std::unique_ptr<reco::PFTau> tauPtr = tau.get(true);
463 
464  // Set event vertex position for tau
465  reco::VertexRef primaryVertexRef = primaryVertex(*tauPtr);
466  if (primaryVertexRef.isNonnull()) {
467  tauPtr->setVertex(primaryVertexRef->position());
468  }
469 
470  double tauEn = tauPtr->energy();
471  double tauPz = tauPtr->pz();
472  const double chargedPionMass = 0.13957; // GeV
473  double tauMass = std::max(tauPtr->mass(), chargedPionMass);
474  double bendCorrMass2 = 0.;
475  const std::vector<RecoTauPiZero>& piZeros = tauPtr->signalPiZeroCandidates();
476  for (auto const& piZero : piZeros) {
477  double piZeroEn = piZero.energy();
478  double piZeroPx = piZero.px();
479  double piZeroPy = piZero.py();
480  double piZeroPz = piZero.pz();
481  double tau_wo_piZeroPx = tauPtr->px() - piZeroPx;
482  double tau_wo_piZeroPy = tauPtr->py() - piZeroPy;
483  // CV: Compute effect of varying strip four-vector by eta and phi correction on tau mass
484  // (derrivative of tau mass by strip eta, phi has been computed using Mathematica)
485  bendCorrMass2 += square(((piZeroPz * tauEn - piZeroEn * tauPz) / tauMass) * piZero.bendCorrEta());
486  bendCorrMass2 +=
487  square(((piZeroPy * tau_wo_piZeroPx - piZeroPx * tau_wo_piZeroPy) / tauMass) * piZero.bendCorrPhi());
488  }
489  //edm::LogPrint("RecoTauBuilderCombinatoricPlugin") << "bendCorrMass2 = " << sqrt(bendCorrMass2) << std::endl;
490  tauPtr->setBendCorrMass(sqrt(bendCorrMass2));
491 
492  output.push_back(std::move(tauPtr));
493  }
494  }
495  }
496 
497  return output;
498  }
499 
500  } // namespace tau
501 } // namespace reco
502 
506  "RecoTauBuilderCombinatoricPlugin");
std::vector< CandidatePtr > pfCandidatesByPdgId(const Jet &jet, int pdgId, bool sort=true)
InputIterator takeNElements(const InputIterator &begin, const InputIterator &end, size_t N)
static const TGPicture * info(bool iBackgroundIsBlack)
std::vector< std::unique_ptr< reco::PFTau > > output_type
CombinatoricIterator< T > end()
std::vector< reco::PFRecoTauChargedHadron > ChargedHadronList
const edm::Handle< edm::View< reco::Candidate > > & getPFCands() const
Hack to be able to convert Ptrs to Refs.
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
RecoTauBuilderCombinatoricPlugin(const edm::ParameterSet &pset, edm::ConsumesCollector &&iC)
assert(be >=bs)
std::vector< CandidatePtr > pfChargedCands(const Jet &jet, bool sort=true)
Extract all non-neutral candidates from a PFJet.
tau::CombinatoricGenerator< PiZeroList > PiZeroCombo
std::vector< CandidatePtr > flattenPiZeros(const std::vector< RecoTauPiZero >::const_iterator &, const std::vector< RecoTauPiZero >::const_iterator &)
Flatten a list of pi zeros into a list of there constituent PFCandidates.
reco::VertexRef primaryVertex(const reco::JetBaseRef &jet) const
Get primary vertex associated to this jet.
return_type operator()(const reco::JetBaseRef &, const std::vector< reco::PFRecoTauChargedHadron > &, const std::vector< RecoTauPiZero > &, const std::vector< CandidatePtr > &) const override
std::vector< reco::CandidatePtr > CandPtrs
T sqrt(T t)
Definition: SSEVec.h:19
void initialize(const PtrIter &chargedHadronsBegin, const PtrIter &chargedHadronsEnd)
tau::CombinatoricGenerator< ChargedHadronList > ChargedHadronCombo
std::vector< CandidatePtr > daughters
collection of references to daughters
edm::Ptr< Candidate > CandidatePtr
persistent reference to an object in a collection of Candidate objects
Definition: CandidateFwd.h:25
double b
Definition: hdecay.h:120
static double square(double x)
ParameterSet const & getParameterSet(ParameterSetID const &id)
fixed size matrix
double a
Definition: hdecay.h:121
float x
#define DEFINE_EDM_PLUGIN(factory, type, name)
void initialize(const PtrIter &particlesBegin, const PtrIter &particlesEnd)
std::vector< std::string > set_difference(std::vector< std::string > const &v1, std::vector< std::string > const &v2)
std::vector< RecoTauPiZero > PiZeroList
def move(src, dest)
Definition: eostools.py:511
iterator::value_type::ValueIter combo_iterator
Transform a pizero to remove given candidates.
CombinatoricIterator< T > begin()