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  inline 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
InputIterator takeNElements(const InputIterator &begin, const InputIterator &end, size_t N)
virtual float pt() const
transverse momentum
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.
virtual float phi() const
momentum azimuthal angle
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
reco::VertexRef associatedVertex(const PFJet &jet) const
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
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.
virtual float eta() const
momentum pseudorapidity
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
T min(T a, T b)
Definition: MathUtil.h:58
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:75
Container::value_type value_type
#define LogTrace(id)
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.
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