CMS 3D CMS Logo

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:
57  ~RecoTauPiZeroStripPlugin2() override;
58  // Return type is auto_ptr<PiZeroVector>
59  return_type operator()(const reco::PFJet&) const override;
60  // Hook to update PV information
61  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)),
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 namespace
174 {
175  void markCandsInStrip(std::vector<bool>& candFlags, const std::set<size_t>& candIds)
176  {
177  for ( std::set<size_t>::const_iterator candId = candIds.begin();
178  candId != candIds.end(); ++candId ) {
179  candFlags[*candId] = true;
180  }
181  }
182 
183  inline const reco::TrackBaseRef getTrack(const PFCandidate& cand)
184  {
185  if ( cand.trackRef().isNonnull() ) return reco::TrackBaseRef(cand.trackRef());
186  else if ( cand.gsfTrackRef().isNonnull() ) return reco::TrackBaseRef(cand.gsfTrackRef());
187  else return reco::TrackBaseRef();
188  }
189 }
190 
192 {
193  if ( verbosity_ >= 1 ) {
194  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "<RecoTauPiZeroStripPlugin2::operator()>:" ;
195  edm::LogPrint("RecoTauPiZeroStripPlugin2") << " minGammaEtStripSeed = " << minGammaEtStripSeed_ ;
196  edm::LogPrint("RecoTauPiZeroStripPlugin2") << " minGammaEtStripAdd = " << minGammaEtStripAdd_ ;
197  edm::LogPrint("RecoTauPiZeroStripPlugin2") << " minStripEt = " << minStripEt_ ;
198  }
199 
201 
202  // Get the candidates passing our quality cuts
205 
206  // Convert to stl::list to allow fast deletions
207  PFCandPtrs seedCands;
208  PFCandPtrs addCands;
209  int idx = 0;
210  for ( PFCandPtrs::iterator cand = candsVector.begin();
211  cand != candsVector.end(); ++cand ) {
212  if ( verbosity_ >= 1 ) {
213  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "PFGamma #" << idx << " (" << cand->id() << ":" << cand->key() << "): Et = " << (*cand)->et() << ", eta = " << (*cand)->eta() << ", phi = " << (*cand)->phi() ;
214  }
215  if ( (*cand)->et() > minGammaEtStripSeed_ ) {
216  if ( verbosity_ >= 2 ) {
217  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "--> assigning seedCandId = " << seedCands.size() ;
218  const reco::TrackBaseRef candTrack = getTrack(*cand);
219  if ( candTrack.isNonnull() ) {
220  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "track: Pt = " << candTrack->pt() << " eta = " << candTrack->eta() << ", phi = " << candTrack->phi() << ", charge = " << candTrack->charge() ;
221  edm::LogPrint("RecoTauPiZeroStripPlugin2") << " (dZ = " << candTrack->dz(vertexAssociator_.associatedVertex(jet)->position()) << ", dXY = " << candTrack->dxy(vertexAssociator_.associatedVertex(jet)->position()) << ","
222  << " numHits = " << candTrack->hitPattern().numberOfValidTrackerHits() << ", numPxlHits = " << candTrack->hitPattern().numberOfValidPixelHits() << ","
223  << " chi2 = " << candTrack->normalizedChi2() << ", dPt/Pt = " << (candTrack->ptError()/candTrack->pt()) << ")" ;
224  }
225  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "ECAL Et: calibrated = " << (*cand)->ecalEnergy()*sin((*cand)->theta()) << ","
226  << " raw = " << (*cand)->rawEcalEnergy()*sin((*cand)->theta()) ;
227  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "HCAL Et: calibrated = " << (*cand)->hcalEnergy()*sin((*cand)->theta()) << ","
228  << " raw = " << (*cand)->rawHcalEnergy()*sin((*cand)->theta()) ;
229  }
230  seedCands.push_back(*cand);
231  } else if ( (*cand)->et() > minGammaEtStripAdd_ ) {
232  if ( verbosity_ >= 2 ) {
233  edm::LogPrint("RecoTauPiZeroStripPlugin2") << "--> assigning addCandId = " << addCands.size() ;
234  }
235  addCands.push_back(*cand);
236  }
237  ++idx;
238  }
239 
240  std::vector<bool> seedCandFlags(seedCands.size()); // true/false: seedCand is already/not yet included in strip
241  std::vector<bool> addCandFlags(addCands.size()); // true/false: addCand is already/not yet included in strip
242 
243  std::set<size_t> seedCandIdsCurrentStrip;
244  std::set<size_t> addCandIdsCurrentStrip;
245 
246  size_t idxSeed = 0;
247  while ( idxSeed < seedCands.size() ) {
248  if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << "processing seed #" << idxSeed ;
249 
250  seedCandIdsCurrentStrip.clear();
251  addCandIdsCurrentStrip.clear();
252 
253  std::auto_ptr<RecoTauPiZero> strip(new RecoTauPiZero(*seedCands[idxSeed], RecoTauPiZero::kStrips));
254  strip->addDaughter(seedCands[idxSeed]);
255  seedCandIdsCurrentStrip.insert(idxSeed);
256 
257  bool isCandAdded;
258  int stripBuildIteration = 0;
259  do {
260  isCandAdded = false;
261 
262  //if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << " adding seedCands to strip..." ;
263  addCandsToStrip(*strip, seedCands, seedCandFlags, seedCandIdsCurrentStrip, isCandAdded);
264  //if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << " adding addCands to strip..." ;
265  addCandsToStrip(*strip, addCands, addCandFlags, addCandIdsCurrentStrip, isCandAdded);
266 
268 
269  ++stripBuildIteration;
270  } while ( isCandAdded && (stripBuildIteration < maxStripBuildIterations_ || maxStripBuildIterations_ == -1) );
271 
272  if ( strip->et() > minStripEt_ ) { // strip passed Et cuts, add it to the event
273  if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << "Building strip: Et = " << strip->et() << ", eta = " << strip->eta() << ", phi = " << strip->phi() ;
274 
275  // Update the vertex
276  if ( strip->daughterPtr(0).isNonnull() ) strip->setVertex(strip->daughterPtr(0)->vertex());
277  output.push_back(strip);
278 
279  // Mark daughters as being part of this strip
280  markCandsInStrip(seedCandFlags, seedCandIdsCurrentStrip);
281  markCandsInStrip(addCandFlags, addCandIdsCurrentStrip);
282  } else { // strip failed Et cuts, just skip it
283  if ( verbosity_ >= 2 ) edm::LogPrint("RecoTauPiZeroStripPlugin2") << "Discarding strip: Et = " << strip->et() << ", eta = " << strip->eta() << ", phi = " << strip->phi() ;
284  }
285 
286  ++idxSeed;
287  while ( idxSeed < seedCands.size() && seedCandFlags[idxSeed] ) {
288  ++idxSeed; // fast-forward to next seed cand not yet included in any strip
289  }
290  }
291 
292  // Check if we want to combine our strips
293  if ( combineStrips_ && output.size() > 1 ) {
294  PiZeroVector stripCombinations;
295  // Sort the output by descending pt
296  output.sort(output.begin(), output.end(),
297  boost::bind(&RecoTauPiZero::pt, _1) >
298  boost::bind(&RecoTauPiZero::pt, _2));
299  // Get the end of interesting set of strips to try and combine
300  PiZeroVector::const_iterator end_iter = takeNElements(
301  output.begin(), output.end(), maxStrips_);
302 
303  // Look at all the combinations
304  for ( PiZeroVector::const_iterator first = output.begin();
305  first != end_iter-1; ++first ) {
306  for ( PiZeroVector::const_iterator second = first+1;
307  second != end_iter; ++second ) {
308  Candidate::LorentzVector firstP4 = first->p4();
309  Candidate::LorentzVector secondP4 = second->p4();
310  // If we assume a certain mass for each strip apply it here.
311  firstP4 = applyMassConstraint(firstP4, combinatoricStripMassHypo_);
312  secondP4 = applyMassConstraint(secondP4, combinatoricStripMassHypo_);
313  Candidate::LorentzVector totalP4 = firstP4 + secondP4;
314  // Make our new combined strip
315  std::auto_ptr<RecoTauPiZero> combinedStrips(
316  new RecoTauPiZero(0, totalP4,
317  Candidate::Point(0, 0, 0),
318  //111, 10001, true, RecoTauPiZero::kCombinatoricStrips));
319  111, 10001, true, RecoTauPiZero::kUndefined));
320 
321  // Now loop over the strip members
322  BOOST_FOREACH(const RecoTauPiZero::daughters::value_type& gamma,
323  first->daughterPtrVector()) {
324  combinedStrips->addDaughter(gamma);
325  }
326  BOOST_FOREACH(const RecoTauPiZero::daughters::value_type& gamma,
327  second->daughterPtrVector()) {
328  combinedStrips->addDaughter(gamma);
329  }
330  // Update the vertex
331  if ( combinedStrips->daughterPtr(0).isNonnull() )
332  combinedStrips->setVertex(combinedStrips->daughterPtr(0)->vertex());
333  // Add to our collection of combined strips
334  stripCombinations.push_back(combinedStrips);
335  }
336  }
337  // When done doing all the combinations, add the combined strips to the
338  // output.
339  output.transfer(output.end(), stripCombinations);
340  }
341 
342  return output.release();
343 }
344 }} // end namespace reco::tau
345 
348  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:253
double eta() const final
momentum pseudorapidity
return_type operator()(const reco::PFJet &) const override
Build a collection of piZeros from objects in the input jet.
key_type key() const
Definition: Ptr.h:185
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:561
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:645
double pt() const final
transverse momentum
void setEvent(const edm::Event &evt)
Load the vertices from the event.
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:337
#define nullptr
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:442
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:651
edm::RefToBase< reco::Track > TrackBaseRef
persistent reference to a Track, using views
Definition: TrackFwd.h:32
void setPV(const reco::VertexRef &vtx) const
Update the primary vertex.
T sqrt(T t)
Definition: SSEVec.h:18
double pt() const
track transverse momentum
Definition: TrackBase.h:621
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
Definition: TrackBase.h:763
T min(T a, T b)
Definition: MathUtil.h:58
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:609
static const TrackGhostTrackState * getTrack(const BasicGhostTrackState *basic)
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
Definition: TrackBase.h:446
ParameterSet const & getParameterSet(std::string const &) const
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:180
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
int numberOfValidTrackerHits() const
Definition: HitPattern.h:828
std::auto_ptr< PiZeroVector > return_type
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
fixed size matrix
HLT enums.
boost::ptr_vector< RecoTauPiZero > PiZeroVector
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.cc:480
std::vector< reco::PFCandidatePtr > PFCandPtrs
void addDaughter(const CandidatePtr &)
add a daughter via a reference
int numberOfValidPixelHits() const
Definition: HitPattern.h:838
math::XYZPoint Point
point in the space
Definition: Candidate.h:41
int charge() const
track electric charge
Definition: TrackBase.h:567
#define DEFINE_EDM_PLUGIN(factory, type, name)
void set(reco::Candidate &c) const
set up a candidate
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:591
double phi() const final
momentum azimuthal angle
def move(src, dest)
Definition: eostools.py:510
void addCandsToStrip(RecoTauPiZero &, PFCandPtrs &, const std::vector< bool > &, std::set< size_t > &, bool &) const