1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#include "DataFormats/TauReco/interface/PFTauDecayMode.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
namespace reco {
PFTauDecayMode::PFTauDecayMode(const VertexCompositeCandidate& chargedPions,
const CompositeCandidate& piZeroes,
const CompositeCandidate& filteredObjects) {
chargedPions_ = chargedPions;
piZeroes_ = piZeroes;
filteredObjects_ = filteredObjects;
// determine decay mode
unsigned int nCharged = chargedPions_.numberOfDaughters();
unsigned int nNeutral = piZeroes_.numberOfDaughters();
hadronicTauDecayModes hadronicTauDecayIndex =
static_cast<hadronicTauDecayModes>(((nCharged - 1) * (maxNumberOfPiZeroCandidatesAllowed + 1) + nNeutral));
if (nNeutral > maxNumberOfPiZeroCandidatesAllowed)
hadronicTauDecayIndex = static_cast<hadronicTauDecayModes>(tauDecayOther);
this->setDecayMode(hadronicTauDecayIndex);
// setup Particle base
for (size_type iCand = 0; iCand < nCharged; ++iCand) {
const Candidate* theCandToAdd = chargedPions_.daughter(iCand);
this->addDaughter(*theCandToAdd);
}
for (size_type iCand = 0; iCand < nNeutral; ++iCand) {
const Candidate* theCandToAdd = piZeroes_.daughter(iCand);
this->addDaughter(*theCandToAdd);
}
this->setCharge(chargedPions_.charge());
this->setP4(chargedPions_.p4() + piZeroes_.p4());
this->setStatus(2); //decayed
this->setPdgId(12); //everyone's favorite lepton!
}
PFTauDecayMode* PFTauDecayMode::clone() const { return new PFTauDecayMode(*this); }
const VertexCompositeCandidate& PFTauDecayMode::chargedPions() const { return chargedPions_; }
const CompositeCandidate& PFTauDecayMode::neutralPions() const { return piZeroes_; }
const CompositeCandidate& PFTauDecayMode::filteredObjects() const { return filteredObjects_; }
std::vector<const Candidate*> PFTauDecayMode::chargedPionCandidates() const {
size_type numberOfChargedPions = chargedPions_.numberOfDaughters();
std::vector<const Candidate*> output;
for (size_type iterCand = 0; iterCand < numberOfChargedPions; ++iterCand)
output.push_back(chargedPions_.daughter(iterCand));
return output;
}
std::vector<const Candidate*> PFTauDecayMode::neutralPionCandidates() const {
size_type numberOfChargedPions = piZeroes_.numberOfDaughters();
std::vector<const Candidate*> output;
for (size_type iterCand = 0; iterCand < numberOfChargedPions; ++iterCand)
output.push_back(piZeroes_.daughter(iterCand));
return output;
}
std::vector<const Candidate*> PFTauDecayMode::decayProductCandidates() const {
std::vector<const Candidate*> output = this->chargedPionCandidates();
std::vector<const Candidate*> neutralObjects = this->neutralPionCandidates();
output.insert(output.end(), neutralObjects.begin(), neutralObjects.end());
return output;
}
std::vector<const Candidate*> PFTauDecayMode::filteredObjectCandidates(int absCharge) const {
size_t numberOfFilteredObjects = filteredObjects_.numberOfDaughters();
std::vector<const Candidate*> output;
for (size_t iFilteredCand = 0; iFilteredCand < numberOfFilteredObjects; ++iFilteredCand) {
const Candidate* myCand = filteredObjects_.daughter(iFilteredCand);
if (absCharge < 0 || abs(myCand->charge()) == absCharge)
output.push_back(myCand);
}
return output;
}
std::vector<const Candidate*> PFTauDecayMode::chargedFilteredObjectCandidates() const {
return filteredObjectCandidates(1);
}
std::vector<const Candidate*> PFTauDecayMode::neutralFilteredObjectCandidates() const {
return filteredObjectCandidates(0);
}
void PFTauDecayMode::pfMasterClones(const Candidate* input, PFCandidateRefVector& toFill) const {
if (input->numberOfDaughters() == 0) //we have reached a leaf
{
if (input->hasMasterClone()) // has a master clone
{
PFCandidateRef theCandRef = input->masterClone().castTo<PFCandidateRef>();
toFill.push_back(theCandRef);
} else
edm::LogError("PFTauDecayMode")
<< "Error in pfMasterClones(...) - found a leaf candidate with no Master clone reference!";
} else // recurse down composite chain
{
size_type numberOfDaughters = input->numberOfDaughters();
for (size_type iCand = 0; iCand < numberOfDaughters; ++iCand) {
const Candidate* currentCand = input->daughter(iCand);
pfMasterClones(currentCand, toFill);
}
}
}
PFCandidateRefVector PFTauDecayMode::associatedChargedPFCandidates() const {
PFCandidateRefVector output;
const Candidate* input = static_cast<const Candidate*>(&chargedPions_);
if (input->numberOfDaughters())
pfMasterClones(input, output);
return output;
}
PFCandidateRefVector PFTauDecayMode::associatedNeutralPFCandidates() const {
PFCandidateRefVector output;
const Candidate* input = static_cast<const Candidate*>(&piZeroes_);
if (input->numberOfDaughters())
pfMasterClones(input, output);
return output;
}
PFCandidateRefVector PFTauDecayMode::filteredPFCandidates() const {
PFCandidateRefVector output;
const Candidate* input = static_cast<const Candidate*>(&filteredObjects_);
if (input->numberOfDaughters())
pfMasterClones(input, output);
return output;
}
} // namespace reco
|