CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFTauDiscriminantManager.cc
Go to the documentation of this file.
2 
3 namespace PFTauDiscriminants
4 {
5 using namespace std;
6 using namespace reco;
7 
8 typedef std::vector<const reco::Candidate*> candPtrVector;
9 
11 {
12  iAmSignal_ = false;
13  iAmNull_ = false;
14  eventWeight_ = 1.0;
15  currentTauDecayMode_ = NULL;
16  eventData_ = NULL;
17  mainTrack_ = NULL;
18 }
19 
20 void
22 {
23  if (!discriminant)
24  {
25  edm::LogError("PFTauDiscriminantManager") << "Error adding a discriminant, null pointer!";
26  return;
27  }
28  string discriminantName = discriminant->name();
29  myDiscriminants_.insert(make_pair(discriminantName, discriminant));
30 }
31 
32 void
34 {
35  mainTrack_ = NULL;
36  signalObjectsSortedByPt_.clear();
37  signalObjectsSortedByDR_.clear();
38  outlierObjectsSortedByPt_.clear();
39  outlierObjectsSortedByDR_.clear();
40 }
41 
42 bool
43 PFTauDiscriminantManager::setTau(const reco::PFTauDecayMode& theTau, bool prePass, bool preFail)
44 {
45  currentTauDecayMode_ = &theTau;
46  iAmNull_ = false;
47  prePass_ = prePass;
48  preFail_ = preFail;
49  //reset cached collections
50  clearCache();
51 
52  for(discriminantHolder::iterator aDiscriminant = myDiscriminants_.begin();
53  aDiscriminant != myDiscriminants_.end();
54  ++aDiscriminant)
55  {
56  Discriminant* const theAlgo = aDiscriminant->second;
57  if (!theAlgo)
58  {
59  string theName = aDiscriminant->first;
60  edm::LogError("PFTauDiscriminantManager") << "Error filling discriminant " << theName <<", null pointer!";
61  return false;
62  }
63  theAlgo->compute(this);
64  }
65  return true;
66 }
67 
68 void
70 {
71  eventData_ = &iEvent;
72  eventWeight_ = eventWeight;
73 }
74 
75 bool
77 {
78  currentTauDecayMode_ = NULL;
79  iAmNull_ = true;
80  prePass_ = false;
81  preFail_ = false;
82  //reset cached collections
83  clearCache();
84 
85  for(discriminantHolder::iterator aDiscriminant = myDiscriminants_.begin();
86  aDiscriminant != myDiscriminants_.end();
87  ++aDiscriminant)
88  {
89  Discriminant* const theAlgo = aDiscriminant->second;
90  if (!theAlgo)
91  {
92  string theName = aDiscriminant->first;
93  edm::LogError("PFTauDiscriminantManager") << "Error filling discriminant " << theName <<", null pointer!";
94  return false;
95  }
96  theAlgo->setNullResult(this);
97  }
98  return true;
99 }
100 
101 
102 
104 {
105  toFill.clear();
106  if (currentTauDecayMode_ == NULL)
107  {
108  edm::LogError("PFTauDiscriminantManager") << "Trying to get signal objects from null PFTauDecayMode object! Returning empty vector...";
109  return;
110  }
111  candPtrVector tempChargedVector = currentTauDecayMode_->chargedPionCandidates();
112  candPtrVector tempNeutralVector = currentTauDecayMode_->neutralPionCandidates();
113  toFill.insert(toFill.end(), tempChargedVector.begin(), tempChargedVector.end());
114  toFill.insert(toFill.end(), tempNeutralVector.begin(), tempNeutralVector.end());
115 }
116 
118 {
119  toFill.clear();
120  if (currentTauDecayMode_ == NULL)
121  {
122  edm::LogError("PFTauDiscriminantManager") << "Trying to get QCD objects from null PFTauDecayMode object! Returning empty vector...";
123  return;
124  }
125 
126  // add in filtered objects (created in PFRecoTauDecayModeDeterminator) i.e filtered 2-prongs
127  // note that this uses the underlying PFCandidates, to be consistent w/ the rest of the objects
128  PFCandidateRefVector theFilteredObjects = currentTauDecayMode_->filteredPFCandidates();
129 
130  for(PFCandidateRefVector::const_iterator iFilteredCand = theFilteredObjects.begin();
131  iFilteredCand != theFilteredObjects.end();
132  ++iFilteredCand)
133  {
134  const PFCandidate* pfCand = iFilteredCand->get();
135  const Candidate* castedCand = static_cast<const Candidate*>(pfCand);
136  if (castedCand)
137  toFill.push_back(castedCand);
138  }
139 
140  // get associated PFTau from PFTauDecayMode
141  const PFTau* originalTau = currentTauDecayMode_->pfTauRef().get();
142  if(originalTau) //this may be null by design if there is no associated PFTau (e.g. if DecayMode is constructed from MC truth)
143  {
144  const PFCandidateRefVector& theOutliers = originalTau->isolationPFCands();
145  for(PFCandidateRefVector::const_iterator iIsoCand = theOutliers.begin();
146  iIsoCand != theOutliers.end();
147  ++iIsoCand)
148  {
149  const PFCandidate* pfCand = iIsoCand->get();
150  const Candidate* castedCand = static_cast<const Candidate*>(pfCand);
151  if (castedCand)
152  toFill.push_back(castedCand);
153  }
154  }
155 }
156 
157 const reco::Candidate*
159 {
160  if (mainTrack_ == NULL) //otherwise already cached or d.n.e
161  {
162  if (!this->getDecayMode())
163  {
164  edm::LogError("PFTauDiscriminantManager") << "In ::mainTrack(), trying to access a null PFTauDecayMode - returning null pointer for main track";
165  return NULL;
166  }
167 
168  std::vector<const reco::Candidate*> myChargedCandidates = getDecayMode()->chargedPionCandidates();
169  size_t nTracks = myChargedCandidates.size();
170  if (!nTracks)
171  {
172  // ...removing this warning for now, not sure what to do about this case (as it shoudl be permissible to pass a jet->pftau->pfTauDecayMode of all gammas??)
173  //edm::LogError("PFTauDiscriminantManager") << "In ::mainTrack(), associated PFTauDecayMode has no associated tracks, returning null pointer.";
174  return NULL;
175  }
176 
177  //if there are more than three tracks, only take the top three, by Pt
179  sort(myChargedCandidates.begin(), myChargedCandidates.end(), ptSorter);
180  size_t maxTracks = (nTracks > 3) ? 3 : nTracks;
181  int charge = 0;
182 
183  if (maxTracks < 3) //two or one track, returning higher Pt track
184  mainTrack_ = myChargedCandidates[0];
185  else
186  {
187  for(size_t iTrack = 0; iTrack < maxTracks; ++iTrack)
188  charge += myChargedCandidates[iTrack]->charge();
189 
190  for(size_t iTrack = 0; iTrack < maxTracks; ++iTrack)
191  {
192  int currentCharge = myChargedCandidates[iTrack]->charge();
193  if (currentCharge != charge)
194  {
195  mainTrack_ = myChargedCandidates[iTrack];
196  break;
197  }
198  }
199  }
200  }
201  return mainTrack_;
202 }
203 
204 
205 
208 {
210  for(candPtrVector::const_iterator iCandidate = input.begin();
211  iCandidate != input.end();
212  ++iCandidate)
213  {
214  bool chargeType = (*iCandidate)->charge();
215  if( chargeType == isCharged )
216  output.push_back(*iCandidate);
217  }
218  return output;
219 }
220 
221 const std::vector<const reco::Candidate*>&
223 {
224  // return already computed vector if has already been computed or is empty (due to null tau)
225  if(!signalObjectsSortedByPt_.empty() || iAmNull_)
226  {
227  return signalObjectsSortedByPt_;
228  }
229  else
230  {
232  fillSignalObjects(signalObjectsSortedByPt_);
233  sort(signalObjectsSortedByPt_.begin(), signalObjectsSortedByPt_.end(), mySorter);
234  }
235  return signalObjectsSortedByPt_;
236 }
237 
238 const std::vector<const reco::Candidate*>&
240 {
241  // return already computed vector if has already been computed or is empty (due to null tau)
242  if(!signalObjectsSortedByDR_.empty() || iAmNull_)
243  {
244  return signalObjectsSortedByDR_;
245  }
246  else
247  {
248  if (currentTauDecayMode_ == NULL)
249  {
250  edm::LogError("PFTauDiscriminantManager") << "Trying to get signal objects from null PFTauDecayMode object! Returning empty vector...";
251  return signalObjectsSortedByDR_;
252  }
253  math::XYZVector signalAxisVector = currentTauDecayMode_->momentum();
255  fillSignalObjects(signalObjectsSortedByDR_);
256  sort(signalObjectsSortedByDR_.begin(), signalObjectsSortedByDR_.end(), mySorter);
257  }
258  return signalObjectsSortedByDR_;
259 }
260 
261 const std::vector<const reco::Candidate*>&
263 {
264  if(!outlierObjectsSortedByPt_.empty() || iAmNull_)
265  {
266  return outlierObjectsSortedByPt_;
267  }
268  else
269  {
270  fillOutlierObjects(outlierObjectsSortedByPt_);
272  sort(outlierObjectsSortedByPt_.begin(), outlierObjectsSortedByPt_.end(), mySorter);
273  }
274  return outlierObjectsSortedByPt_;
275 }
276 
277 const std::vector<const reco::Candidate*>&
279 {
280  if(!outlierObjectsSortedByDR_.empty() || iAmNull_)
281  {
282  return outlierObjectsSortedByDR_;
283  }
284  else
285  {
286  if (currentTauDecayMode_ == NULL)
287  {
288  edm::LogError("PFTauDiscriminantManager") << "Trying to get outlier objects from null PFTauDecayMode object! Returning empty vector...";
289  return outlierObjectsSortedByDR_;
290  }
291  math::XYZVector signalAxisVector = currentTauDecayMode_->momentum();
292  fillOutlierObjects(outlierObjectsSortedByDR_);
294  sort(outlierObjectsSortedByDR_.begin(), outlierObjectsSortedByDR_.end(), mySorter);
295  }
296  return outlierObjectsSortedByDR_;
297 }
298 
299 
300 bool
301 PFTauDiscriminantManager::branchTree(TTree* treeToBranch, bool addTargetBranch, bool addWeightBranch)
302 {
303  if(!treeToBranch)
304  {
305  edm::LogError("PFTauDiscriminantManager") << "Error: trying to branch ttree - TTree pointer is null!";
306  return false;
307  }
308 
309  //add magic variables _TARGET_ (for sig/bkg) and _WEIGHT_, and ISNULL for non-existence
310  if (addTargetBranch)
311  treeToBranch->Branch("__TARGET__", &iAmSignal_, "__TARGET__/O"); //needs bugfix in MVA framework code..
312  if (addWeightBranch)
313  treeToBranch->Branch("__WEIGHT__", &eventWeight_,"__WEIGHT__/D");
314  // note: Target and Weight are normally added after the fact, in the training code.
315 
316  treeToBranch->Branch("__ISNULL__", &iAmNull_,"__ISNULL__/O");
317  treeToBranch->Branch("__PREPASS__", &prePass_,"__PREPASS__/O");
318  treeToBranch->Branch("__PREFAIL__", &preFail_,"__PREFAIL__/O");
319 
320  //loop over all the variables and make a branch for each one
321  for(discriminantHolder::iterator iVariable = myDiscriminants_.begin();
322  iVariable != myDiscriminants_.end();
323  ++iVariable)
324  {
325  Discriminant * theDiscriminant = iVariable->second;
326  edm::LogInfo("PFTauDiscriminantManager") << "Branching for discriminant w/ name: " << theDiscriminant->name();
327  theDiscriminant->branchTree(treeToBranch);
328  }
329  return true;
330 }
331 
332 void
333 PFTauDiscriminantManager::buildMVAComputerLink(std::vector<PhysicsTools::Variable::Value>& toFill)
334 {
335  for(discriminantHolder::iterator iVariable = myDiscriminants_.begin();
336  iVariable != myDiscriminants_.end();
337  ++iVariable)
338  {
339  Discriminant * theDiscriminant = iVariable->second;
340  theDiscriminant->fillMVA(toFill);
341  }
342 }
343 
344 vector<const reco::Candidate*>
346 {
347  std::vector<const reco::Candidate*> output;
348 
349  //check for validity
350  if(!input)
351  return output;
352 
353  size_t nDaughters = input->numberOfDaughters();
354  if(!nDaughters) //this is a leaf
355  output.push_back(input);
356  else //recurse down this objects daughters
357  {
358  for(size_t iDaughter = 0; iDaughter < nDaughters; ++iDaughter)
359  {
360  std::vector<const reco::Candidate*> leafsOnThisBranch = getLeafDaughters(input->daughter(iDaughter));
361  output.insert(output.end(), leafsOnThisBranch.begin(), leafsOnThisBranch.end());
362  }
363  }
364  return output;
365 }
366 
368 {
369 }
370 
371 
372 
373 } //end namespace
374 
375 
376 
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
const PFCandidateRefVector & isolationPFCands() const
PFCandidates in isolation region.
Definition: PFTau.cc:82
void addDiscriminant(Discriminant *const aDiscriminant)
add a discriminant
bool setTau(const reco::PFTauDecayMode &theTau, bool prePass=false, bool preFail=false)
set objects for this discriminant
#define NULL
Definition: scimark2.h:8
static std::vector< const reco::Candidate * > getLeafDaughters(const reco::Candidate *input)
return the lowest level constituent candidates of a composite candidate
const std::vector< const reco::Candidate * > & outlierObjectsSortedByPt()
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:249
double charge(const std::vector< uint8_t > &Ampls)
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:244
PFTau::hadronicDecayMode getDecayMode(const reco::GenJet *genJet)
const std::vector< const reco::Candidate * > & outlierObjectsSortedByDR()
virtual size_type numberOfDaughters() const =0
number of daughters
int iEvent
Definition: GenABIO.cc:243
void setEvent(const edm::Event &, double eventWeight)
set the current event. Must be called (once per event) before setTau or setNullResult ...
virtual void fillMVA(std::vector< PhysicsTools::Variable::Value > &mvaHolder) const =0
T get() const
get a component
const std::vector< const reco::Candidate * > & signalObjectsSortedByPt()
accessed by Discriminant classes (caches to prevent multiple sorts)
virtual void compute(PFTauDiscriminantManager *input)=0
const reco::Candidate * mainTrack()
get the &#39;main&#39; track (track computed for relevancy to tau decay resonances) (ie pi- in pi+pi+pi-) ...
const std::vector< const reco::Candidate * > & signalObjectsSortedByDR()
double computeDeltaR(const math::XYZVector &vec1, const math::XYZVector &vec2)
Definition: TauTagTools.cc:8
std::vector< const reco::Candidate * > candPtrVector
virtual void branchTree(TTree *theTree)=0
add a branch to a ttree corresponding to this variable
bool branchTree(TTree *const treeToBranch, bool addTargetBranch=false, bool addWeightBranch=false)
add a set of branches ot the TTree
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
std::vector< const reco::Candidate * > candPtrVector
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:33
candPtrVector filterByCharge(const candPtrVector &input, bool isCharged) const
virtual void setNullResult(PFTauDiscriminantManager *input)=0
void buildMVAComputerLink(std::vector< PhysicsTools::Variable::Value > &)
connect to an MVA computer