CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFRecoTauChargedHadronFromTrackPlugin.cc
Go to the documentation of this file.
1 /*
2  * PFRecoTauChargedHadronFromTrackPlugin
3  *
4  * Build PFRecoTauChargedHadron objects
5  * using charged PFCandidates as input
6  *
7  * Author: Christian Veelken, LLR
8  *
9  */
10 
12 
14 
18 
30 
33 
38 
39 #include <TMath.h>
40 
41 #include <memory>
42 #include <math.h>
43 
44 namespace reco { namespace tau {
45 
47 {
48  public:
51  // Return type is auto_ptr<ChargedHadronVector>
52  return_type operator()(const reco::PFJet&) const;
53  // Hook to update PV information
54  virtual void beginEvent();
55 
56  private:
57  typedef std::vector<reco::PFCandidatePtr> PFCandPtrs;
58 
60 
62 
65  double dRcone_;
67 
70 
72 
73  mutable int numWarnings_;
75 
77 };
78 
80  : PFRecoTauChargedHadronBuilderPlugin(pset,std::move(iC)),
81  vertexAssociator_(pset.getParameter<edm::ParameterSet>("qualityCuts"),std::move(iC)),
82  qcuts_(0)
83 {
84  edm::ParameterSet qcuts_pset = pset.getParameterSet("qualityCuts").getParameterSet("signalQualityCuts");
85  qcuts_ = new RecoTauQualityCuts(qcuts_pset);
86 
87  srcTracks_ = pset.getParameter<edm::InputTag>("srcTracks");
89  dRcone_ = pset.getParameter<double>("dRcone");
90  dRconeLimitedToJetArea_ = pset.getParameter<bool>("dRconeLimitedToJetArea");
91 
92  dRmergeNeutralHadron_ = pset.getParameter<double>("dRmergeNeutralHadron");
93  dRmergePhoton_ = pset.getParameter<double>("dRmergePhoton");
94 
95  numWarnings_ = 0;
96  maxWarnings_ = 3;
97 
98  verbosity_ = ( pset.exists("verbosity") ) ?
99  pset.getParameter<int>("verbosity") : 0;
100 }
101 
103 {
104  delete qcuts_;
105 }
106 
107 // Update the primary vertex
109 {
110  vertexAssociator_.setEvent(*this->evt());
111 
112  edm::ESHandle<MagneticField> magneticField;
113  evtSetup()->get<IdealMagneticFieldRecord>().get(magneticField);
114  magneticFieldStrength_ = magneticField->inTesla(GlobalPoint(0.,0.,0.));
115 }
116 
117 namespace
118 {
119  struct PFCandidate_withDistance
120  {
122  double distance_;
123  };
124 
125  bool isSmallerDistance(const PFCandidate_withDistance& cand1, const PFCandidate_withDistance& cand2)
126  {
127  return (cand1.distance_ < cand2.distance_);
128  }
129 }
130 
132 {
133  //if ( verbosity_ ) {
134  // std::cout << "<PFRecoTauChargedHadronFromTrackPlugin::operator()>:" << std::endl;
135  // std::cout << " pluginName = " << name() << std::endl;
136  //}
137 
139 
140  const edm::Event& evt = (*this->evt());
141 
143  evt.getByToken(Tracks_token, tracks);
144 
146 
147  size_t numTracks = tracks->size();
148  for ( size_t iTrack = 0; iTrack < numTracks; ++iTrack ) {
149  reco::TrackRef track(tracks, iTrack);
150 
151  // consider tracks in vicinity of tau-jet candidate only
152  double dR = deltaR(track->eta(), track->phi(), jet.eta(), jet.phi());
153  double dRmatch = dRcone_;
154  if ( dRconeLimitedToJetArea_ ) {
155  double jetArea = jet.jetArea();
156  if ( jetArea > 0. ) {
157  dRmatch = TMath::Min(dRmatch, TMath::Sqrt(jetArea/TMath::Pi()));
158  } else {
159  if ( numWarnings_ < maxWarnings_ ) {
160  edm::LogWarning("PFRecoTauChargedHadronFromTrackPlugin::operator()")
161  << "Jet: Pt = " << jet.pt() << ", eta = " << jet.eta() << ", phi = " << jet.phi() << " has area = " << jetArea << " !!" << std::endl;
162  ++numWarnings_;
163  }
164  dRmatch = 0.1;
165  }
166  }
167  if ( dR > dRmatch ) continue;
168 
169  // ignore tracks which fail quality cuts
170  if ( !qcuts_->filterTrack(track) ) continue;
171 
172  reco::Candidate::Charge trackCharge_int = 0;
173  if ( track->charge() > 0. ) trackCharge_int = +1;
174  else if ( track->charge() < 0. ) trackCharge_int = -1;
175 
176  const double chargedPionMass = 0.13957; // GeV
177  double chargedPionP = track->p();
178  double chargedPionEn = TMath::Sqrt(chargedPionP*chargedPionP + chargedPionMass*chargedPionMass);
179  reco::Candidate::LorentzVector chargedPionP4(track->px(), track->py(), track->pz(), chargedPionEn);
180 
181  reco::Vertex::Point vtx(0.,0.,0.);
183 
184  std::auto_ptr<PFRecoTauChargedHadron> chargedHadron(new PFRecoTauChargedHadron(trackCharge_int, chargedPionP4, vtx, 0, true, PFRecoTauChargedHadron::kTrack));
185  chargedHadron->track_ = edm::Ptr<reco::Track>(tracks, iTrack);
186 
187  // CV: Take code for propagating track to ECAL entrance
188  // from RecoParticleFlow/PFTracking/src/PFTrackTransformer.cc
189  // to make sure propagation is done in the same way as for charged PFCandidates.
190  //
191  // The following replacements need to be made
192  // outerMomentum -> momentum
193  // outerPosition -> referencePoint
194  // in order to run on AOD input
195  // (outerMomentum and outerPosition require access to reco::TrackExtra objects, which are available in RECO only)
196  //
197  XYZTLorentzVector chargedPionPos(track->referencePoint().x(), track->referencePoint().y(), track->referencePoint().z(), 0.);
198  BaseParticlePropagator trackPropagator(RawParticle(chargedPionP4, chargedPionPos), 0., 0., magneticFieldStrength_.z());
199  trackPropagator.setCharge(track->charge());
200  trackPropagator.propagateToEcalEntrance(false);
201  if ( trackPropagator.getSuccess() != 0 ) {
202  chargedHadron->positionAtECALEntrance_ = trackPropagator.vertex();
203  } else {
204  if ( chargedPionP4.pt() > 2. ) {
205  edm::LogWarning("PFRecoTauChargedHadronFromTrackPlugin::operator()")
206  << "Failed to propagate track: Pt = " << track->pt() << ", eta = " << track->eta() << ", phi = " << track->phi() << " to ECAL entrance !!" << std::endl;
207  }
208  chargedHadron->positionAtECALEntrance_ = math::XYZPointF(0.,0.,0.);
209  }
210 
211  std::vector<PFCandidate_withDistance> neutralJetConstituents_withDistance;
212  std::vector<reco::PFCandidatePtr> jetConstituents = jet.getPFConstituents();
213  for ( std::vector<reco::PFCandidatePtr>::const_iterator jetConstituent = jetConstituents.begin();
214  jetConstituent != jetConstituents.end(); ++jetConstituent ) {
215  reco::PFCandidate::ParticleType jetConstituentType = (*jetConstituent)->particleId();
216  if ( !(jetConstituentType == reco::PFCandidate::h0 || jetConstituentType == reco::PFCandidate::gamma) ) continue;
217  double dR = deltaR((*jetConstituent)->positionAtECALEntrance(), chargedHadron->positionAtECALEntrance_);
218  double dRmerge = -1.;
219  if ( jetConstituentType == reco::PFCandidate::h0 ) dRmerge = dRmergeNeutralHadron_;
220  else if ( jetConstituentType == reco::PFCandidate::gamma ) dRmerge = dRmergePhoton_;
221  if ( dR < dRmerge ) {
222  PFCandidate_withDistance jetConstituent_withDistance;
223  jetConstituent_withDistance.pfCandidate_ = (*jetConstituent);
224  jetConstituent_withDistance.distance_ = dR;
225  neutralJetConstituents_withDistance.push_back(jetConstituent_withDistance);
226  chargedHadron->addDaughter(*jetConstituent);
227  }
228  }
229  std::sort(neutralJetConstituents_withDistance.begin(), neutralJetConstituents_withDistance.end(), isSmallerDistance);
230 
231  const double caloResolutionCoeff = 1.0; // CV: approximate ECAL + HCAL calorimeter resolution for hadrons by 100%*sqrt(E)
232  double resolutionTrackP = track->p()*(track->ptError()/track->pt());
233  double neutralEnSum = 0.;
234  for ( std::vector<PFCandidate_withDistance>::const_iterator nextNeutral = neutralJetConstituents_withDistance.begin();
235  nextNeutral != neutralJetConstituents_withDistance.end(); ++nextNeutral ) {
236  double nextNeutralEn = nextNeutral->pfCandidate_->energy();
237  double resolutionCaloEn = caloResolutionCoeff*sqrt(neutralEnSum + nextNeutralEn);
238  double resolution = sqrt(resolutionTrackP*resolutionTrackP + resolutionCaloEn*resolutionCaloEn);
239  if ( (neutralEnSum + nextNeutralEn) < (track->p() + 2.*resolution) ) {
240  chargedHadron->neutralPFCandidates_.push_back(nextNeutral->pfCandidate_);
241  neutralEnSum += nextNeutralEn;
242  } else {
243  break;
244  }
245  }
246 
247  setChargedHadronP4(*chargedHadron);
248 
249  //if ( verbosity_ ) {
250  // chargedHadron->print(std::cout);
251  //}
252 
253  output.push_back(chargedHadron);
254  }
255 
256  return output.release();
257 }
258 
259 }} // end namespace reco::tau
260 
262 
const double Pi
void setCharge(float q)
set the MEASURED charge
Definition: RawParticle.cc:138
T getParameter(std::string const &) const
reco::VertexRef associatedVertex(const PFJet &tau) const
int Charge
electric charge type
Definition: Candidate.h:39
return_type operator()(const reco::PFJet &) const
Build a collection of chargedHadrons from objects in the input jet.
ParticleType
particle types
Definition: PFCandidate.h:43
PFRecoTauChargedHadronFromTrackPlugin(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
reco::PFCandidatePtr pfCandidate_
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:10
bool exists(std::string const &parameterName) const
checks if a parameter exists
void setEvent(const edm::Event &evt)
Load the vertices from the event.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
virtual void beginEvent()
Hook called at the beginning of the event.
boost::ptr_vector< PFRecoTauChargedHadron > ChargedHadronVector
Jets made from PFObjects.
Definition: PFJet.h:21
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
void setPV(const reco::VertexRef &vtx) const
Update the primary vertex.
T sqrt(T t)
Definition: SSEVec.h:48
auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
math::XYZPoint Point
point in the space
Definition: Vertex.h:39
const edm::EventSetup * evtSetup() const
virtual float eta() const GCC11_FINAL
momentum pseudorapidity
ParameterSet const & getParameterSet(std::string const &) const
tuple tracks
Definition: testEve_cfg.py:39
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
const T & get() const
Definition: EventSetup.h:55
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:41
virtual float jetArea() const
get jet area
Definition: Jet.h:105
virtual std::vector< reco::PFCandidatePtr > getPFConstituents() const
get all constituents
Definition: PFJet.cc:52
#define DEFINE_EDM_PLUGIN(factory, type, name)
virtual float pt() const GCC11_FINAL
transverse momentum
void setChargedHadronP4(reco::PFRecoTauChargedHadron &chargedHadron, double scaleFactor_neutralPFCands=1.0)
bool filterTrack(const reco::TrackBaseRef &track) const
Filter a single Track.