CMS 3D CMS Logo

RecoTauIsolationMasking.cc
Go to the documentation of this file.
7 
8 namespace reco::tau {
9 
10 namespace {
11 class DRSorter {
12  public:
13  DRSorter(const reco::Candidate::LorentzVector& axis):axis_(axis){}
14  template<typename T>
15  bool operator()(const T& t1, const T& t2) const {
16  return reco::deltaR(t1->p4(), axis_) < reco::deltaR(t2->p4(), axis_);
17  }
18  private:
20 };
21 // Sort by descending pt
22 class PtSorter {
23  public:
24  PtSorter(){}
25  template<typename T>
26  bool operator()(const T& t1, const T& t2) const {
27  return t1->pt() > t2->pt();
28  }
29 };
30 
31 // Check if an object is within DR of a track collection
32 class MultiTrackDRFilter {
33  public:
34  MultiTrackDRFilter(double deltaR, const std::vector<reco::CandidatePtr>& trks)
35  :deltaR_(deltaR),tracks_(trks){}
36  template <typename T>
37  bool operator()(const T& t) const {
38  for(auto const& trk : tracks_) {
39  if (reco::deltaR(trk->p4(), t->p4()) < deltaR_)
40  return true;
41  }
42  return false;
43  }
44  private:
45  double deltaR_;
46  const std::vector<reco::CandidatePtr>& tracks_;
47 };
48 
49 double square(double x) { return x*x; }
50 
51 template<typename T>
52 std::vector<reco::PFCandidatePtr> convertRefCollection(const T& coll) {
53  std::vector<reco::PFCandidatePtr> output;
54  output.reserve(coll.size());
55  for(auto const& cand : coll) {
56  output.push_back(cand);
57  }
58  return output;
59 }
60 }
61 
63  const edm::ParameterSet& pset):resolutions_(new PFEnergyResolution) {
64  ecalCone_ = pset.getParameter<double>("ecalCone");
65  hcalCone_ = pset.getParameter<double>("hcalCone");
66  finalHcalCone_ = pset.getParameter<double>("finalHcalCone");
67  maxSigmas_ = pset.getParameter<double>("maxSigmas");
68 }
69 
70 // Need to explicitly define this in the .cc so we can use auto_ptr + forward
72 
76 
77  typedef std::list<reco::CandidatePtr> CandList;
78  // Copy original iso collections.
79  std::copy(tau.isolationGammaCands().begin(),
80  tau.isolationGammaCands().end(), std::back_inserter(output.gammas));
81  std::copy(tau.isolationNeutrHadrCands().begin(),
82  tau.isolationNeutrHadrCands().end(),
83  std::back_inserter(output.h0s));
84 
85  std::vector<CandList*> courses;
86  courses.push_back(&(output.h0s));
87  courses.push_back(&(output.gammas));
88  // Mask using each one of the tracks
89  for(auto const& track : tau.signalPFChargedHadrCands()) {
90  double trackerEnergy = track->energy();
91  double linkedEcalEnergy = track->ecalEnergy();
92  double linkedHcalEnergy = track->hcalEnergy();
93  math::XYZPointF posAtCalo = track->positionAtECALEntrance();
94  // Get the linked calo energies & their errors
95  double linkedSumErrSquared = 0;
96  linkedSumErrSquared += square(
97  resolutions_->getEnergyResolutionEm(linkedEcalEnergy, posAtCalo.eta()));
98  linkedSumErrSquared += square(
99  resolutions_->getEnergyResolutionHad(
100  linkedHcalEnergy, posAtCalo.eta(), posAtCalo.phi()));
101 
102  // energyDelta is the difference between associated Calo and tracker energy
103  double energyDelta = linkedEcalEnergy + linkedHcalEnergy - trackerEnergy;
104 
105  // Sort the neutral hadrons by DR to the track
106  //DRSorter sorter(track->p4());
107  PtSorter sorter;
108 
109  for(auto* course : courses) {
110  // Sort by deltaR to the current track
111  course->sort(sorter);
112  CandList::iterator toEatIter = course->begin();
113  // While there are still candidates to eat in this course and they are
114  // within the cone.
115  while (toEatIter != course->end()) {
116  const reco::Candidate& toEat = **toEatIter;
117  double toEatEnergy = toEat.energy();
118  double toEatErrorSq = square(resolution(toEat));
119  // Check if we can absorb this candidate into the track.
120  if (inCone(*track, **toEatIter) &&
121  (energyDelta + toEatEnergy)/std::sqrt(
122  linkedSumErrSquared + toEatErrorSq) < maxSigmas_ ) {
123  energyDelta += toEatEnergy;
124  linkedSumErrSquared += toEatErrorSq;
125  toEatIter = course->erase(toEatIter);
126  } else {
127  // otherwise skip to the next one
128  ++toEatIter;
129  }
130  }
131  }
132  }
133  // Filter out any final HCAL objects with in cones about the tracks.
134  // This removes upward fluctuating HCAL objects
135  if (finalHcalCone_ > 0) {
136  MultiTrackDRFilter hcalFinalFilter(finalHcalCone_,
137  tau.signalChargedHadrCands());
138  std::remove_if(output.h0s.begin(), output.h0s.end(), hcalFinalFilter);
139  }
140  return output;
141 }
142 
144  const reco::Candidate& cand) const {
145  if (cand.pdgId() == 130) {
146  // NB for HCAL it returns relative energy
147  return cand.energy()*resolutions_->getEnergyResolutionHad(cand.energy(),
148  cand.eta(), cand.phi());
149  } else if (cand.pdgId() == 22) {
150  return resolutions_->getEnergyResolutionEm(cand.energy(), cand.eta());
151  } else if (std::abs(cand.pdgId()) == 11) {
152  // FIXME what is the electron resolution??
153  return 0.15;
154  } else {
155  edm::LogWarning("IsoMask::res (bad pf id)")
156  << "Unknown PF PDG ID: " << cand.pdgId();
157  }
158  return -1;
159 }
160 
162  const reco::Candidate& cand) const {
163  double openingDR = reco::deltaR(track.positionAtECALEntrance(), cand.p4());
164  if (cand.pdgId() == 130) {
165  return (openingDR < hcalCone_);
166  } else if (cand.pdgId() == 22 ||
167  abs(cand.pdgId()) == 11) {
168  return openingDR < ecalCone_;
169  } else {
170  edm::LogWarning("IsoMask::inCone (bad pf id)")
171  << "Unknown PF PDG ID: " << cand.pdgId();
172  }
173  return -1;
174 }
175 
176 } // end namespace reco::tau
T getParameter(std::string const &) const
def copy(args, dbName)
double deltaR_
const reco::Candidate::LorentzVector axis_
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
const math::XYZPointF & positionAtECALEntrance() const
Definition: PFCandidate.h:368
const std::vector< reco::CandidatePtr > & isolationGammaCands() const
Gamma candidates in isolation region.
Definition: PFTau.cc:93
RecoTauIsolationMasking(const edm::ParameterSet &pset)
virtual double energy() const =0
energy
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
virtual int pdgId() const =0
PDG identifier.
T sqrt(T t)
Definition: SSEVec.h:18
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:28
const std::vector< reco::PFCandidatePtr > & signalPFChargedHadrCands() const
Definition: PFTau.cc:179
virtual double eta() const =0
momentum pseudorapidity
JetCorrectorParametersCollection coll
Definition: classes.h:10
static double square(double x)
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
const std::vector< reco::CandidatePtr > & signalChargedHadrCands() const
Charged hadrons in signal region.
Definition: PFTau.cc:80
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
const std::vector< reco::CandidatePtr > & tracks_
const std::vector< reco::CandidatePtr > & isolationNeutrHadrCands() const
Definition: PFTau.cc:91
bool inCone(const reco::PFCandidate &track, const reco::Candidate &cand) const
long double T
virtual double phi() const =0
momentum azimuthal angle
std::unique_ptr< PFEnergyResolution > resolutions_
double resolution(const reco::Candidate &cand) const
IsoMaskResult mask(const reco::PFTau &) const
Return a new isolation collections with masking applied.