CMS 3D CMS Logo

RecoTauPiZeroStripPlugin.cc
Go to the documentation of this file.
1 /*
2  * RecoTauPiZeroStripPlugin
3  *
4  * Merges PFGammas in a PFJet into Candidate piZeros defined as
5  * strips in eta-phi.
6  *
7  * Author: Michail Bachtis (University of Wisconsin)
8  *
9  * Code modifications: Evan Friis (UC Davis)
10  *
11  */
12 #include <algorithm>
13 #include <functional>
14 #include <memory>
15 
17 
26 
31 
32 namespace reco {
33  namespace tau {
34 
35  namespace {
36  // Apply a hypothesis on the mass of the strips.
37  math::XYZTLorentzVector applyMassConstraint(const math::XYZTLorentzVector& vec, double mass) {
38  double factor = sqrt(vec.energy() * vec.energy() - mass * mass) / vec.P();
39  return math::XYZTLorentzVector(vec.px() * factor, vec.py() * factor, vec.pz() * factor, vec.energy());
40  }
41  } // namespace
42 
44  public:
47  // Return type is unique_ptr<PiZeroVector>
48  return_type operator()(const reco::Jet& jet) const override;
49  // Hook to update PV information
50  void beginEvent() override;
51 
52  private:
53  std::unique_ptr<RecoTauQualityCuts> qcuts_;
55 
56  std::vector<int> inputParticleIds_; //type of candidates to clusterize
57  double etaAssociationDistance_; //eta Clustering Association Distance
58  double phiAssociationDistance_; //phi Clustering Association Distance
59 
60  // Parameters for build strip combinations
64 
66  };
67 
70  qcuts_(std::make_unique<RecoTauQualityCuts>(
71  pset.getParameterSet("qualityCuts").getParameterSet("signalQualityCuts"))),
72  vertexAssociator_(pset.getParameter<edm::ParameterSet>("qualityCuts"), std::move(iC)) {
73  inputParticleIds_ = pset.getParameter<std::vector<int> >("stripCandidatesParticleIds");
74  etaAssociationDistance_ = pset.getParameter<double>("stripEtaAssociationDistance");
75  phiAssociationDistance_ = pset.getParameter<double>("stripPhiAssociationDistance");
76  combineStrips_ = pset.getParameter<bool>("makeCombinatoricStrips");
77  if (combineStrips_) {
78  maxStrips_ = pset.getParameter<int>("maxInputStrips");
79  combinatoricStripMassHypo_ = pset.getParameter<double>("stripMassWhenCombining");
80  }
81  }
82 
83  // Update the primary vertex
85 
87  // Get list of gamma candidates
88  typedef std::vector<reco::CandidatePtr> CandPtrs;
89  typedef CandPtrs::iterator CandIter;
91 
92  // Get the candidates passing our quality cuts
94  CandPtrs candsVector = qcuts_->filterCandRefs(pfCandidates(jet, inputParticleIds_));
95  //PFCandPtrs candsVector = qcuts_->filterCandRefs(pfGammas(jet));
96 
97  // Convert to stl::list to allow fast deletions
98  std::list<reco::CandidatePtr> cands;
99  cands.insert(cands.end(), candsVector.begin(), candsVector.end());
100 
101  while (!cands.empty()) {
102  // Seed this new strip, and delete it from future strips
103  CandidatePtr seed = cands.front();
104  cands.pop_front();
105 
106  // Add a new candidate to our collection using this seed
107  auto strip = std::make_unique<RecoTauPiZero>(*seed, RecoTauPiZero::kStrips);
108  strip->addDaughter(seed);
109 
110  // Find all other objects in the strip
111  auto stripCand = cands.begin();
112  while (stripCand != cands.end()) {
113  if (fabs(strip->eta() - (*stripCand)->eta()) < etaAssociationDistance_ &&
114  fabs(deltaPhi(*strip, **stripCand)) < phiAssociationDistance_) {
115  // Add candidate to strip
116  strip->addDaughter(*stripCand);
117  // Update the strips four momenta
118  p4Builder_.set(*strip);
119  // Delete this candidate from future strips and move on to
120  // the next potential candidate
121  stripCand = cands.erase(stripCand);
122  } else {
123  // This candidate isn't compatabile - just move to the next candidate
124  ++stripCand;
125  }
126  }
127  // Update the vertex
128  if (strip->daughterPtr(0).isNonnull())
129  strip->setVertex(strip->daughterPtr(0)->vertex());
130  output.emplace_back(strip.release());
131  }
132 
133  // Check if we want to combine our strips
134  if (combineStrips_ && output.size() > 1) {
135  PiZeroVector stripCombinations;
136  // Sort the output by descending pt
137  std::sort(output.begin(), output.end(), [&](auto& arg1, auto& arg2) { return arg1->pt() > arg2->pt(); });
138  // Get the end of interesting set of strips to try and combine
139  PiZeroVector::const_iterator end_iter = takeNElements(output.begin(), output.end(), maxStrips_);
140 
141  // Look at all the combinations
142  for (PiZeroVector::const_iterator firstIter = output.begin(); firstIter != end_iter - 1; ++firstIter) {
143  for (PiZeroVector::const_iterator secondIter = firstIter + 1; secondIter != end_iter; ++secondIter) {
144  auto const& first = *firstIter;
145  auto const& second = *secondIter;
146  Candidate::LorentzVector firstP4 = first->p4();
147  Candidate::LorentzVector secondP4 = second->p4();
148  // If we assume a certain mass for each strip apply it here.
149  firstP4 = applyMassConstraint(firstP4, combinatoricStripMassHypo_);
150  secondP4 = applyMassConstraint(secondP4, combinatoricStripMassHypo_);
151  Candidate::LorentzVector totalP4 = firstP4 + secondP4;
152  // Make our new combined strip
153  auto combinedStrips =
154  std::make_unique<RecoTauPiZero>(0,
155  totalP4,
156  Candidate::Point(0, 0, 0),
157  //111, 10001, true, RecoTauPiZero::kCombinatoricStrips));
158  111,
159  10001,
160  true,
162 
163  // Now loop over the strip members
164  for (auto const& gamma : first->daughterPtrVector()) {
165  combinedStrips->addDaughter(gamma);
166  }
167  for (auto const& gamma : second->daughterPtrVector()) {
168  combinedStrips->addDaughter(gamma);
169  }
170  // Update the vertex
171  if (combinedStrips->daughterPtr(0).isNonnull())
172  combinedStrips->setVertex(combinedStrips->daughterPtr(0)->vertex());
173  // Add to our collection of combined strips
174  stripCombinations.emplace_back(combinedStrips.release());
175  }
176  }
177  // When done doing all the combinations, add the combined strips to the output.
178  std::move(stripCombinations.begin(), stripCombinations.end(), std::back_inserter(output));
179  }
180 
181  return output;
182  }
183  } // namespace tau
184 } // namespace reco
185 
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
std::vector< CandidatePtr > pfCandidates(const Jet &jet, int particleId, bool sort=true)
InputIterator takeNElements(const InputIterator &begin, const InputIterator &end, size_t N)
void set(reco::Candidate &c) const
set up a candidate
Base class for all types of Jets.
Definition: Jet.h:20
void setEvent(const edm::Event &evt)
Load the vertices from the event.
RecoTauPiZeroStripPlugin(const edm::ParameterSet &pset, edm::ConsumesCollector &&iC)
void beginEvent() override
Hook called at the beginning of the event.
reco::VertexRef associatedVertex(const Jet &jet) const
U second(std::pair< T, U > const &p)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
std::vector< reco::CandidatePtr > CandPtrs
T sqrt(T t)
Definition: SSEVec.h:23
std::vector< std::unique_ptr< RecoTauPiZero > > PiZeroVector
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:36
ParameterSet const & getParameterSet(ParameterSetID const &id)
fixed size matrix
HLT enums.
math::XYZPoint Point
point in the space
Definition: Candidate.h:40
#define DEFINE_EDM_PLUGIN(factory, type, name)
Definition: output.py:1
std::unique_ptr< RecoTauQualityCuts > qcuts_
return_type operator()(const reco::Jet &jet) const override
Build a collection of piZeros from objects in the input jet.
CandPtrs::iterator CandIter
def move(src, dest)
Definition: eostools.py:511