CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RecoTauPiZeroStripPlugin2.cc
Go to the documentation of this file.
1 /*
2  * RecoTauPiZeroStripPlugin2
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  * Christian Veelken (LLR)
11  *
12  */
13 #include <algorithm>
14 #include <memory>
15 
17 
26 
31 
32 //-------------------------------------------------------------------------------
33 // CV: the following headers are needed only for debug print-out
36 //-------------------------------------------------------------------------------
37 
38 namespace reco { namespace tau {
39 
40 namespace {
41  // Apply a hypothesis on the mass of the strips.
42  math::XYZTLorentzVector applyMassConstraint(
43  const math::XYZTLorentzVector& vec,double mass) {
44  double factor = sqrt(vec.energy()*vec.energy()-mass*mass)/vec.P();
46  vec.px()*factor,vec.py()*factor,vec.pz()*factor,vec.energy());
47  }
48 }
49 
51 {
52  public:
55  // Return type is auto_ptr<PiZeroVector>
56  return_type operator()(const reco::PFJet&) const override;
57  // Hook to update PV information
58  virtual void beginEvent() override;
59 
60  private:
61  typedef std::vector<reco::PFCandidatePtr> PFCandPtrs;
62  void addCandsToStrip(RecoTauPiZero&, PFCandPtrs&, const std::vector<bool>&, std::set<size_t>&, bool&) const;
63 
65 
70 
71  double minStripEt_;
72 
73  std::vector<int> inputPdgIds_; // type of candidates to clusterize
74  double etaAssociationDistance_; // size of strip clustering window in eta direction
75  double phiAssociationDistance_; // size of strip clustering window in phi direction
76 
79 
80  // Parameters for build strip combinations
84 
86 };
87 
89  : RecoTauPiZeroBuilderPlugin(pset,std::move(iC)),
90  vertexAssociator_(pset.getParameter<edm::ParameterSet>("qualityCuts"),std::move(iC)),
91  qcuts_(0)
92 {
93  LogTrace("RecoTauPiZeroStripPlugin2") << "<RecoTauPiZeroStripPlugin2::RecoTauPiZeroStripPlugin2>:" ;
94 
95  minGammaEtStripSeed_ = pset.getParameter<double>("minGammaEtStripSeed");
96  LogTrace("RecoTauPiZeroStripPlugin2") << " minGammaEtStripSeed = " << minGammaEtStripSeed_ ;
97  minGammaEtStripAdd_ = pset.getParameter<double>("minGammaEtStripAdd");
98  LogTrace("RecoTauPiZeroStripPlugin2") << " minGammaEtStripAdd = " << minGammaEtStripAdd_ ;
99 
100  minStripEt_ = pset.getParameter<double>("minStripEt");
101  LogTrace("RecoTauPiZeroStripPlugin2") << " minStripEt = " << minStripEt_ ;
102 
103  edm::ParameterSet qcuts_pset = pset.getParameterSet("qualityCuts").getParameterSet("signalQualityCuts");
104 //-------------------------------------------------------------------------------
105 // CV: disable track quality cuts for PFElectronsPFElectron
106 // (treat PFElectrons like PFGammas for the purpose of building eta-phi strips)
107  applyElecTrackQcuts_ = pset.getParameter<bool>("applyElecTrackQcuts");
108  if ( !applyElecTrackQcuts_ ) {
109  qcuts_pset.addParameter<double>("minTrackPt", std::min(minGammaEtStripSeed_, minGammaEtStripAdd_));
110  qcuts_pset.addParameter<double>("maxTrackChi2", 1.e+9);
111  qcuts_pset.addParameter<double>("maxTransverseImpactParameter", 1.e+9);
112  qcuts_pset.addParameter<double>("maxDeltaZ", 1.);
113  qcuts_pset.addParameter<double>("minTrackVertexWeight", -1.);
114  qcuts_pset.addParameter<unsigned>("minTrackPixelHits", 0);
115  qcuts_pset.addParameter<unsigned>("minTrackHits", 0);
116  }
117 //-------------------------------------------------------------------------------
118  qcuts_pset.addParameter<double>("minGammaEt", std::min(minGammaEtStripSeed_, minGammaEtStripAdd_));
119  qcuts_ = new RecoTauQualityCuts(qcuts_pset);
120 
121  inputPdgIds_ = pset.getParameter<std::vector<int> >("stripCandidatesParticleIds");
122  etaAssociationDistance_ = pset.getParameter<double>("stripEtaAssociationDistance");
123  phiAssociationDistance_ = pset.getParameter<double>("stripPhiAssociationDistance");
124 
125  updateStripAfterEachDaughter_ = pset.getParameter<bool>("updateStripAfterEachDaughter");
126  maxStripBuildIterations_ = pset.getParameter<int>("maxStripBuildIterations");
127 
128  combineStrips_ = pset.getParameter<bool>("makeCombinatoricStrips");
129  if ( combineStrips_ ) {
130  maxStrips_ = pset.getParameter<int>("maxInputStrips");
131  combinatoricStripMassHypo_ = pset.getParameter<double>("stripMassWhenCombining");
132  }
133 }
134 
136 {
137  delete qcuts_;
138 }
139 
140 // Update the primary vertex
142 {
144 }
145 
146 void RecoTauPiZeroStripPlugin2::addCandsToStrip(RecoTauPiZero& strip, PFCandPtrs& cands, const std::vector<bool>& candFlags,
147  std::set<size_t>& candIdsCurrentStrip, bool& isCandAdded) const
148 {
149  size_t numCands = cands.size();
150  for ( size_t candId = 0; candId < numCands; ++candId ) {
151  if ( (!candFlags[candId]) && candIdsCurrentStrip.find(candId) == candIdsCurrentStrip.end() ) { // do not include same cand twice
152  reco::PFCandidatePtr cand = cands[candId];
153  if ( fabs(strip.eta() - cand->eta()) < etaAssociationDistance_ && // check if cand is within eta-phi window centered on strip
154  fabs(strip.phi() - cand->phi()) < phiAssociationDistance_ ) {
155  LogTrace("RecoTauPiZeroStripPlugin2") << "--> candId = " << candId << " has been added." ;
156  strip.addDaughter(cand);
158  isCandAdded = true;
159  candIdsCurrentStrip.insert(candId);
160  }
161  }
162  }
163 }
164 
165 void markCandsInStrip(std::vector<bool>& candFlags, const std::set<size_t>& candIds)
166 {
167  for ( std::set<size_t>::const_iterator candId = candIds.begin();
168  candId != candIds.end(); ++candId ) {
169  candFlags[*candId] = true;
170  }
171 }
172 
173 namespace {
174  const reco::TrackBaseRef getTrack(const PFCandidate& cand)
175  {
176  if ( cand.trackRef().isNonnull() ) return reco::TrackBaseRef(cand.trackRef());
177  else if ( cand.gsfTrackRef().isNonnull() ) return reco::TrackBaseRef(cand.gsfTrackRef());
178  else return reco::TrackBaseRef();
179  }
180 }
181 
183 {
185 
186  // Get the candidates passing our quality cuts
189 
190  // Convert to stl::list to allow fast deletions
191  PFCandPtrs seedCands;
192  PFCandPtrs addCands;
193  int idx = 0;
194  for ( PFCandPtrs::iterator cand = candsVector.begin();
195  cand != candsVector.end(); ++cand ) {
196  LogTrace("RecoTauPiZeroStripPlugin2") << "PFGamma (" << idx << "): Et = " << (*cand)->et() << ","
197  << " eta = " << (*cand)->eta() << ", phi = " << (*cand)->phi();
198  if ( (*cand)->et() > minGammaEtStripSeed_ ) {
199  LogTrace("RecoTauPiZeroStripPlugin2") << " --> assigning seedCandId = " << seedCands.size() ;
200 #ifdef EDM_ML_DEBUG
201  const reco::TrackBaseRef candTrack = getTrack(*cand);
202  if ( candTrack.isNonnull() ) {
203  LogTrace("RecoTauPiZeroStripPlugin2") << "has Track: pt = " << candTrack->pt() << " +/- " << candTrack->ptError() << ","
204  << " eta = " << candTrack->eta() << ", phi = " << candTrack->phi() << ","
205  << " charge = " << candTrack->charge() ;
206  LogTrace("RecoTauPiZeroStripPlugin2") << " chi2 = " << candTrack->normalizedChi2() ;
207  LogTrace("RecoTauPiZeroStripPlugin2") << " dIP = " << std::abs(candTrack->dxy(vertexAssociator_.associatedVertex(jet)->position())) ;
208  LogTrace("RecoTauPiZeroStripPlugin2") << " dZ = " << std::abs(candTrack->dz(vertexAssociator_.associatedVertex(jet)->position())) ;
209  LogTrace("RecoTauPiZeroStripPlugin2") << " vtxAssocWeight = " << vertexAssociator_.associatedVertex(jet)->trackWeight(candTrack) ;
210  LogTrace("RecoTauPiZeroStripPlugin2") << " numPxlHits = " << candTrack->hitPattern().numberOfValidPixelHits() ;
211  LogTrace("RecoTauPiZeroStripPlugin2") << " numTrkHits = " << candTrack->hitPattern().numberOfValidHits() ;
212  }
213 #endif
214  LogTrace("RecoTauPiZeroStripPlugin2") << "ECAL Et: calibrated = " << (*cand)->ecalEnergy()*sin((*cand)->theta()) << ","
215  << " raw = " << (*cand)->rawEcalEnergy()*sin((*cand)->theta()) ;
216  LogTrace("RecoTauPiZeroStripPlugin2") << "HCAL Et: calibrated = " << (*cand)->hcalEnergy()*sin((*cand)->theta()) << ","
217  << " raw = " << (*cand)->rawHcalEnergy()*sin((*cand)->theta()) ;
218  seedCands.push_back(*cand);
219  } else if ( (*cand)->et() > minGammaEtStripAdd_ ) {
220  LogTrace("RecoTauPiZeroStripPlugin2") << " --> assigning addCandId = " << addCands.size();
221  addCands.push_back(*cand);
222  }
223  LogTrace("RecoTauPiZeroStripPlugin2") ;
224  ++idx;
225  }
226 
227  std::vector<bool> seedCandFlags(seedCands.size()); // true/false: seedCand is already/not yet included in strip
228  std::vector<bool> addCandFlags(addCands.size()); // true/false: addCand is already/not yet included in strip
229 
230  std::set<size_t> seedCandIdsCurrentStrip;
231  std::set<size_t> addCandIdsCurrentStrip;
232 
233  size_t idxSeed = 0;
234  while ( idxSeed < seedCands.size() ) {
235  LogTrace("RecoTauPiZeroStripPlugin2") << "idxSeed = " << idxSeed ;
236 
237  seedCandIdsCurrentStrip.clear();
238  addCandIdsCurrentStrip.clear();
239 
240  std::auto_ptr<RecoTauPiZero> strip(new RecoTauPiZero(*seedCands[idxSeed], RecoTauPiZero::kStrips));
241  strip->addDaughter(seedCands[idxSeed]);
242  seedCandIdsCurrentStrip.insert(idxSeed);
243 
244  bool isCandAdded;
245  int stripBuildIteration = 0;
246  do {
247  isCandAdded = false;
248 
249  LogTrace("RecoTauPiZeroStripPlugin2") << " adding seedCands to strip..." ;
250  addCandsToStrip(*strip, seedCands, seedCandFlags, seedCandIdsCurrentStrip, isCandAdded);
251  LogTrace("RecoTauPiZeroStripPlugin2") << " adding addCands to strip..." ;
252  addCandsToStrip(*strip, addCands, addCandFlags, addCandIdsCurrentStrip, isCandAdded);
253 
255 
256  ++stripBuildIteration;
257  } while ( isCandAdded && (stripBuildIteration < maxStripBuildIterations_ || maxStripBuildIterations_ == -1) );
258 
259  if ( strip->et() > minStripEt_ ) { // strip passed Et cuts, add it to the event
260  LogTrace("RecoTauPiZeroStripPlugin2") << "Strip: Et = " << strip->et() << ","
261  << " eta = " << strip->eta() << ", phi = " << strip->phi()
262  << " --> building it !!" ;
263 
264  // Update the vertex
265  if ( strip->daughterPtr(0).isNonnull() ) strip->setVertex(strip->daughterPtr(0)->vertex());
266  output.push_back(strip);
267 
268  // Mark daughters as being part of this strip
269  markCandsInStrip(seedCandFlags, seedCandIdsCurrentStrip);
270  markCandsInStrip(addCandFlags, addCandIdsCurrentStrip);
271  } else { // strip failed Et cuts, just skip it
272  LogTrace("RecoTauPiZeroStripPlugin2") << "Strip: Et = " << strip->et() << ","
273  << " eta = " << strip->eta() << ", phi = " << strip->phi()
274  << " --> discarding it !!" ;
275  }
276 
277  ++idxSeed;
278  while ( idxSeed < seedCands.size() && seedCandFlags[idxSeed] ) {
279  ++idxSeed; // fast-forward to next seed cand not yet included in any strip
280  }
281  }
282 
283  // Check if we want to combine our strips
284  if ( combineStrips_ && output.size() > 1 ) {
285  PiZeroVector stripCombinations;
286  // Sort the output by descending pt
287  output.sort(output.begin(), output.end(),
288  boost::bind(&RecoTauPiZero::pt, _1) >
289  boost::bind(&RecoTauPiZero::pt, _2));
290  // Get the end of interesting set of strips to try and combine
291  PiZeroVector::const_iterator end_iter = takeNElements(
292  output.begin(), output.end(), maxStrips_);
293 
294  // Look at all the combinations
295  for ( PiZeroVector::const_iterator first = output.begin();
296  first != end_iter-1; ++first ) {
297  for ( PiZeroVector::const_iterator second = first+1;
298  second != end_iter; ++second ) {
299  Candidate::LorentzVector firstP4 = first->p4();
300  Candidate::LorentzVector secondP4 = second->p4();
301  // If we assume a certain mass for each strip apply it here.
302  firstP4 = applyMassConstraint(firstP4, combinatoricStripMassHypo_);
303  secondP4 = applyMassConstraint(secondP4, combinatoricStripMassHypo_);
304  Candidate::LorentzVector totalP4 = firstP4 + secondP4;
305  // Make our new combined strip
306  std::auto_ptr<RecoTauPiZero> combinedStrips(
307  new RecoTauPiZero(0, totalP4,
308  Candidate::Point(0, 0, 0),
309  //111, 10001, true, RecoTauPiZero::kCombinatoricStrips));
310  111, 10001, true, RecoTauPiZero::kUndefined));
311 
312  // Now loop over the strip members
313  BOOST_FOREACH(const RecoTauPiZero::daughters::value_type& gamma,
314  first->daughterPtrVector()) {
315  combinedStrips->addDaughter(gamma);
316  }
317  BOOST_FOREACH(const RecoTauPiZero::daughters::value_type& gamma,
318  second->daughterPtrVector()) {
319  combinedStrips->addDaughter(gamma);
320  }
321  // Update the vertex
322  if ( combinedStrips->daughterPtr(0).isNonnull() )
323  combinedStrips->setVertex(combinedStrips->daughterPtr(0)->vertex());
324  // Add to our collection of combined strips
325  stripCombinations.push_back(combinedStrips);
326  }
327  }
328  // When done doing all the combinations, add the combined strips to the
329  // output.
330  output.transfer(output.end(), stripCombinations);
331  }
332 
333  return output.release();
334 }
335 }} // end namespace reco::tau
336 
339  reco::tau::RecoTauPiZeroStripPlugin2, "RecoTauPiZeroStripPlugin2");
RecoTauPiZeroStripPlugin2(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
T getParameter(std::string const &) const
reco::VertexRef associatedVertex(const PFJet &tau) const
InputIterator takeNElements(const InputIterator &begin, const InputIterator &end, size_t N)
double normalizedChi2() const
chi-squared divided by n.d.o.f. (or chi-squared * 1e6 if n.d.o.f. is zero)
Definition: TrackBase.h:109
void markCandsInStrip(std::vector< bool > &candFlags, const std::set< size_t > &candIds)
Coll filterCandRefs(const Coll &refcoll, bool invert=false) const
Filter a ref vector of PFCandidates.
int numberOfValidHits() const
Definition: HitPattern.h:589
virtual const_iterator end() const
last daughter const_iterator
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:137
void setEvent(const edm::Event &evt)
Load the vertices from the event.
Jets made from PFObjects.
Definition: PFJet.h:21
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:429
U second(std::pair< T, U > const &p)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
virtual float phi() const GCC11_FINAL
momentum azimuthal angle
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:139
edm::RefToBase< reco::Track > TrackBaseRef
persistent reference to a Track, using views
Definition: TrackFwd.h:22
void setPV(const reco::VertexRef &vtx) const
Update the primary vertex.
T sqrt(T t)
Definition: SSEVec.h:48
double pt() const
track transverse momentum
Definition: TrackBase.h:129
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:142
virtual const_iterator begin() const
first daughter const_iterator
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
Definition: TrackBase.h:192
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
Definition: TrackBase.h:221
bool first
Definition: L1TdeRCT.cc:79
Container::value_type value_type
#define LogTrace(id)
virtual float eta() const GCC11_FINAL
momentum pseudorapidity
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:125
static const TrackGhostTrackState * getTrack(const BasicGhostTrackState *basic)
return_type operator()(const reco::PFJet &) const override
Build a collection of piZeros from objects in the input jet.
ParameterSet const & getParameterSet(std::string const &) const
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:41
std::auto_ptr< PiZeroVector > return_type
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:38
boost::ptr_vector< RecoTauPiZero > PiZeroVector
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.cc:467
std::vector< reco::PFCandidatePtr > PFCandPtrs
void addDaughter(const CandidatePtr &)
add a daughter via a reference
int numberOfValidPixelHits() const
Definition: HitPattern.h:601
math::XYZPoint Point
point in the space
Definition: Candidate.h:45
int charge() const
track electric charge
Definition: TrackBase.h:111
#define DEFINE_EDM_PLUGIN(factory, type, name)
void set(reco::Candidate &c) const
set up a candidate
virtual void beginEvent() override
Hook called at the beginning of the event.
virtual float pt() const GCC11_FINAL
transverse momentum
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:119
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:279
void addCandsToStrip(RecoTauPiZero &, PFCandPtrs &, const std::vector< bool > &, std::set< size_t > &, bool &) const