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 
14 #include <algorithm>
15 #include <memory>
16 
17 #include "boost/bind.hpp"
18 
20 
29 
34 
35 //-------------------------------------------------------------------------------
36 // CV: the following headers are needed only for debug print-out
39 //-------------------------------------------------------------------------------
40 
41 namespace reco { namespace tau {
42 
43 namespace {
44  // Apply a hypothesis on the mass of the strips.
45  math::XYZTLorentzVector applyMassConstraint(
46  const math::XYZTLorentzVector& vec,double mass) {
47  double factor = sqrt(vec.energy()*vec.energy()-mass*mass)/vec.P();
49  vec.px()*factor,vec.py()*factor,vec.pz()*factor,vec.energy());
50  }
51 }
52 
54 {
55  public:
58  // Return type is auto_ptr<PiZeroVector>
59  return_type operator()(const reco::PFJet&) const override;
60  // Hook to update PV information
61  virtual void beginEvent() override;
62 
63  private:
64  typedef std::vector<reco::PFCandidatePtr> PFCandPtrs;
65  void addCandsToStrip(RecoTauPiZero&, PFCandPtrs&, const std::vector<bool>&, std::set<size_t>&, bool&) const;
66 
68 
73 
74  double minStripEt_;
75 
76  std::vector<int> inputPdgIds_; // type of candidates to clusterize
77  double etaAssociationDistance_; // size of strip clustering window in eta direction
78  double phiAssociationDistance_; // size of strip clustering window in phi direction
79 
82 
83  // Parameters for build strip combinations
87 
89 
91 };
92 
94  : RecoTauPiZeroBuilderPlugin(pset, std::move(iC)),
95  vertexAssociator_(pset.getParameter<edm::ParameterSet>("qualityCuts"), std::move(iC)),
96  qcuts_(0)
97 {
98  minGammaEtStripSeed_ = pset.getParameter<double>("minGammaEtStripSeed");
99  minGammaEtStripAdd_ = pset.getParameter<double>("minGammaEtStripAdd");
100 
101  minStripEt_ = pset.getParameter<double>("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.e+9);
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  verbosity_ = ( pset.exists("verbosity") ) ?
135  pset.getParameter<int>("verbosity") : 0;
136 }
137 
139 {
140  delete qcuts_;
141 }
142 
143 // Update the primary vertex
145 {
147 }
148 
149 void RecoTauPiZeroStripPlugin2::addCandsToStrip(RecoTauPiZero& strip, PFCandPtrs& cands, const std::vector<bool>& candFlags,
150  std::set<size_t>& candIdsCurrentStrip, bool& isCandAdded) const
151 {
152  if ( verbosity_ >= 1 ) {
153  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "<RecoTauPiZeroStripPlugin2::addCandsToStrip>:" ;
154  }
155  size_t numCands = cands.size();
156  for ( size_t candId = 0; candId < numCands; ++candId ) {
157  if ( (!candFlags[candId]) && candIdsCurrentStrip.find(candId) == candIdsCurrentStrip.end() ) { // do not include same cand twice
158  reco::PFCandidatePtr cand = cands[candId];
159  if ( fabs(strip.eta() - cand->eta()) < etaAssociationDistance_ && // check if cand is within eta-phi window centered on strip
160  fabs(strip.phi() - cand->phi()) < phiAssociationDistance_ ) {
161  if ( verbosity_ >= 2 ) {
162  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "--> adding PFCand #" << candId << " (" << cand.id() << ":" << cand.key() << "): Et = " << cand->et() << ", eta = " << cand->eta() << ", phi = " << cand->phi() ;
163  }
164  strip.addDaughter(cand);
166  isCandAdded = true;
167  candIdsCurrentStrip.insert(candId);
168  }
169  }
170  }
171 }
172 
173 void markCandsInStrip(std::vector<bool>& candFlags, const std::set<size_t>& candIds)
174 {
175  for ( std::set<size_t>::const_iterator candId = candIds.begin();
176  candId != candIds.end(); ++candId ) {
177  candFlags[*candId] = true;
178  }
179 }
180 
181 namespace {
182  inline const reco::TrackBaseRef getTrack(const PFCandidate& cand)
183  {
184  if ( cand.trackRef().isNonnull() ) return reco::TrackBaseRef(cand.trackRef());
185  else if ( cand.gsfTrackRef().isNonnull() ) return reco::TrackBaseRef(cand.gsfTrackRef());
186  else return reco::TrackBaseRef();
187  }
188 }
189 
191 {
192  if ( verbosity_ >= 1 ) {
193  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "<RecoTauPiZeroStripPlugin2::operator()>:" ;
194  edm::LogPrint("RecoTauPiZeroStripPlugin2") << " minGammaEtStripSeed = " << minGammaEtStripSeed_ ;
195  edm::LogPrint("RecoTauPiZeroStripPlugin2") << " minGammaEtStripAdd = " << minGammaEtStripAdd_ ;
196  edm::LogPrint("RecoTauPiZeroStripPlugin2") << " minStripEt = " << minStripEt_ ;
197  }
198 
200 
201  // Get the candidates passing our quality cuts
204 
205  // Convert to stl::list to allow fast deletions
206  PFCandPtrs seedCands;
207  PFCandPtrs addCands;
208  int idx = 0;
209  for ( PFCandPtrs::iterator cand = candsVector.begin();
210  cand != candsVector.end(); ++cand ) {
211  if ( verbosity_ >= 1 ) {
212  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "PFGamma #" << idx << " (" << cand->id() << ":" << cand->key() << "): Et = " << (*cand)->et() << ", eta = " << (*cand)->eta() << ", phi = " << (*cand)->phi() ;
213  }
214  if ( (*cand)->et() > minGammaEtStripSeed_ ) {
215  if ( verbosity_ >= 2 ) {
216  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "--> assigning seedCandId = " << seedCands.size() ;
217  const reco::TrackBaseRef candTrack = getTrack(*cand);
218  if ( candTrack.isNonnull() ) {
219  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "track: Pt = " << candTrack->pt() << " eta = " << candTrack->eta() << ", phi = " << candTrack->phi() << ", charge = " << candTrack->charge() ;
220  edm::LogPrint("RecoTauPiZeroStripPlugin2") << " (dZ = " << candTrack->dz(vertexAssociator_.associatedVertex(jet)->position()) << ", dXY = " << candTrack->dxy(vertexAssociator_.associatedVertex(jet)->position()) << ","
221  << " numHits = " << candTrack->hitPattern().numberOfValidTrackerHits() << ", numPxlHits = " << candTrack->hitPattern().numberOfValidPixelHits() << ","
222  << " chi2 = " << candTrack->normalizedChi2() << ", dPt/Pt = " << (candTrack->ptError()/candTrack->pt()) << ")" ;
223  }
224  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "ECAL Et: calibrated = " << (*cand)->ecalEnergy()*sin((*cand)->theta()) << ","
225  << " raw = " << (*cand)->rawEcalEnergy()*sin((*cand)->theta()) ;
226  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "HCAL Et: calibrated = " << (*cand)->hcalEnergy()*sin((*cand)->theta()) << ","
227  << " raw = " << (*cand)->rawHcalEnergy()*sin((*cand)->theta()) ;
228  }
229  seedCands.push_back(*cand);
230  } else if ( (*cand)->et() > minGammaEtStripAdd_ ) {
231  if ( verbosity_ >= 2 ) {
232  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "--> assigning addCandId = " << addCands.size() ;
233  }
234  addCands.push_back(*cand);
235  }
236  ++idx;
237  }
238 
239  std::vector<bool> seedCandFlags(seedCands.size()); // true/false: seedCand is already/not yet included in strip
240  std::vector<bool> addCandFlags(addCands.size()); // true/false: addCand is already/not yet included in strip
241 
242  std::set<size_t> seedCandIdsCurrentStrip;
243  std::set<size_t> addCandIdsCurrentStrip;
244 
245  size_t idxSeed = 0;
246  while ( idxSeed < seedCands.size() ) {
247  if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << "processing seed #" << idxSeed ;
248 
249  seedCandIdsCurrentStrip.clear();
250  addCandIdsCurrentStrip.clear();
251 
252  std::auto_ptr<RecoTauPiZero> strip(new RecoTauPiZero(*seedCands[idxSeed], RecoTauPiZero::kStrips));
253  strip->addDaughter(seedCands[idxSeed]);
254  seedCandIdsCurrentStrip.insert(idxSeed);
255 
256  bool isCandAdded;
257  int stripBuildIteration = 0;
258  do {
259  isCandAdded = false;
260 
261  //if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << " adding seedCands to strip..." ;
262  addCandsToStrip(*strip, seedCands, seedCandFlags, seedCandIdsCurrentStrip, isCandAdded);
263  //if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << " adding addCands to strip..." ;
264  addCandsToStrip(*strip, addCands, addCandFlags, addCandIdsCurrentStrip, isCandAdded);
265 
267 
268  ++stripBuildIteration;
269  } while ( isCandAdded && (stripBuildIteration < maxStripBuildIterations_ || maxStripBuildIterations_ == -1) );
270 
271  if ( strip->et() > minStripEt_ ) { // strip passed Et cuts, add it to the event
272  if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << "Building strip: Et = " << strip->et() << ", eta = " << strip->eta() << ", phi = " << strip->phi() ;
273 
274  // Update the vertex
275  if ( strip->daughterPtr(0).isNonnull() ) strip->setVertex(strip->daughterPtr(0)->vertex());
276  output.push_back(strip);
277 
278  // Mark daughters as being part of this strip
279  markCandsInStrip(seedCandFlags, seedCandIdsCurrentStrip);
280  markCandsInStrip(addCandFlags, addCandIdsCurrentStrip);
281  } else { // strip failed Et cuts, just skip it
282  if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << "Discarding strip: Et = " << strip->et() << ", eta = " << strip->eta() << ", phi = " << strip->phi() ;
283  }
284 
285  ++idxSeed;
286  while ( idxSeed < seedCands.size() && seedCandFlags[idxSeed] ) {
287  ++idxSeed; // fast-forward to next seed cand not yet included in any strip
288  }
289  }
290 
291  // Check if we want to combine our strips
292  if ( combineStrips_ && output.size() > 1 ) {
293  PiZeroVector stripCombinations;
294  // Sort the output by descending pt
295  output.sort(output.begin(), output.end(),
296  boost::bind(&RecoTauPiZero::pt, _1) >
297  boost::bind(&RecoTauPiZero::pt, _2));
298  // Get the end of interesting set of strips to try and combine
299  PiZeroVector::const_iterator end_iter = takeNElements(
300  output.begin(), output.end(), maxStrips_);
301 
302  // Look at all the combinations
303  for ( PiZeroVector::const_iterator first = output.begin();
304  first != end_iter-1; ++first ) {
305  for ( PiZeroVector::const_iterator second = first+1;
306  second != end_iter; ++second ) {
307  Candidate::LorentzVector firstP4 = first->p4();
308  Candidate::LorentzVector secondP4 = second->p4();
309  // If we assume a certain mass for each strip apply it here.
310  firstP4 = applyMassConstraint(firstP4, combinatoricStripMassHypo_);
311  secondP4 = applyMassConstraint(secondP4, combinatoricStripMassHypo_);
312  Candidate::LorentzVector totalP4 = firstP4 + secondP4;
313  // Make our new combined strip
314  std::auto_ptr<RecoTauPiZero> combinedStrips(
315  new RecoTauPiZero(0, totalP4,
316  Candidate::Point(0, 0, 0),
317  //111, 10001, true, RecoTauPiZero::kCombinatoricStrips));
318  111, 10001, true, RecoTauPiZero::kUndefined));
319 
320  // Now loop over the strip members
321  BOOST_FOREACH(const RecoTauPiZero::daughters::value_type& gamma,
322  first->daughterPtrVector()) {
323  combinedStrips->addDaughter(gamma);
324  }
325  BOOST_FOREACH(const RecoTauPiZero::daughters::value_type& gamma,
326  second->daughterPtrVector()) {
327  combinedStrips->addDaughter(gamma);
328  }
329  // Update the vertex
330  if ( combinedStrips->daughterPtr(0).isNonnull() )
331  combinedStrips->setVertex(combinedStrips->daughterPtr(0)->vertex());
332  // Add to our collection of combined strips
333  stripCombinations.push_back(combinedStrips);
334  }
335  }
336  // When done doing all the combinations, add the combined strips to the
337  // output.
338  output.transfer(output.end(), stripCombinations);
339  }
340 
341  return output.release();
342 }
343 }} // end namespace reco::tau
344 
347  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)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
key_type key() const
Definition: Ptr.h:186
virtual double et() const
transverse energy
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:514
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.
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
reco::VertexRef associatedVertex(const PFJet &jet) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:598
void setEvent(const edm::Event &evt)
Load the vertices from the event.
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:330
Jets made from PFObjects.
Definition: PFJet.h:21
virtual double eta() const
momentum pseudorapidity
virtual double pt() const
transverse momentum
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:433
U second(std::pair< T, U > const &p)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:604
edm::RefToBase< reco::Track > TrackBaseRef
persistent reference to a Track, using views
Definition: TrackFwd.h:31
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:574
const_iterator end() const
last daughter const_iterator
Definition: Candidate.h:146
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
Definition: TrackBase.h:716
T min(T a, T b)
Definition: MathUtil.h:58
Container::value_type value_type
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:562
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.
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
Definition: TrackBase.h:411
ParameterSet const & getParameterSet(std::string const &) const
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:181
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
int numberOfValidTrackerHits() const
Definition: HitPattern.h:739
std::auto_ptr< PiZeroVector > return_type
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
boost::ptr_vector< RecoTauPiZero > PiZeroVector
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.cc:471
std::vector< reco::PFCandidatePtr > PFCandPtrs
void addDaughter(const CandidatePtr &)
add a daughter via a reference
int numberOfValidPixelHits() const
Definition: HitPattern.h:749
const_iterator begin() const
first daughter const_iterator
Definition: Candidate.h:144
math::XYZPoint Point
point in the space
Definition: Candidate.h:41
int charge() const
track electric charge
Definition: TrackBase.h:520
#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:544
virtual double phi() const
momentum azimuthal angle
void addCandsToStrip(RecoTauPiZero &, PFCandPtrs &, const std::vector< bool > &, std::set< size_t > &, bool &) const