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
133
134
135
136
137
138
139
140
141
142
|
#include "DataFormats/Candidate/interface/CompositeCandidate.h"
#include "FWCore/Utilities/interface/Exception.h"
using namespace reco;
CompositeCandidate::CompositeCandidate(const Candidate& c, const std::string& name) : LeafCandidate(c), name_(name) {
size_t n = c.numberOfDaughters();
for (size_t i = 0; i != n; ++i) {
addDaughter(*c.daughter(i));
}
}
CompositeCandidate::CompositeCandidate(const Candidate& c, const std::string& name, role_collection const& roles)
: LeafCandidate(c), name_(name), roles_(roles) {
size_t n = c.numberOfDaughters();
size_t r = roles_.size();
bool sameSize = (n == r);
for (size_t i = 0; i != n; ++i) {
if (sameSize && r > 0)
addDaughter(*c.daughter(i), roles_[i]);
else
addDaughter(*c.daughter(i));
}
}
CompositeCandidate::~CompositeCandidate() {}
CompositeCandidate* CompositeCandidate::clone() const { return new CompositeCandidate(*this); }
const Candidate* CompositeCandidate::daughter(size_type i) const {
return (i < numberOfDaughters()) ? &dau[i] : nullptr; // i >= 0, since i is unsigned
}
Candidate* CompositeCandidate::daughter(size_type i) {
Candidate* d = (i < numberOfDaughters()) ? &dau[i] : nullptr; // i >= 0, since i is unsigned
return d;
}
const Candidate* CompositeCandidate::mother(size_type i) const { return nullptr; }
size_t CompositeCandidate::numberOfDaughters() const { return dau.size(); }
size_t CompositeCandidate::numberOfMothers() const { return 0; }
bool CompositeCandidate::overlap(const Candidate& c2) const {
throw cms::Exception("Error") << "can't check overlap internally for CompositeCanddate";
}
void CompositeCandidate::applyRoles() {
if (roles_.empty())
return;
// Check if there are the same number of daughters and roles
int N1 = roles_.size();
int N2 = numberOfDaughters();
if (N1 != N2) {
throw cms::Exception("InvalidReference")
<< "CompositeCandidate::applyRoles : Number of roles and daughters differ, this is an error.\n";
}
// Set up the daughter roles
for (int i = 0; i < N1; ++i) {
std::string role = roles_[i];
Candidate* c = CompositeCandidate::daughter(i);
CompositeCandidate* c1 = dynamic_cast<CompositeCandidate*>(c);
if (c1 != nullptr) {
c1->setName(role);
}
}
}
Candidate* CompositeCandidate::daughter(const std::string& s) {
int ret = -1;
int i = 0, N = roles_.size();
bool found = false;
for (; i < N && !found; ++i) {
if (s == roles_[i]) {
found = true;
ret = i;
}
}
if (ret < 0) {
throw cms::Exception("InvalidReference") << "CompositeCandidate::daughter: Cannot find role " << s << "\n";
}
return daughter(ret);
}
const Candidate* CompositeCandidate::daughter(const std::string& s) const {
int ret = -1;
int i = 0, N = roles_.size();
bool found = false;
for (; i < N && !found; ++i) {
if (s == roles_[i]) {
found = true;
ret = i;
}
}
if (ret < 0) {
throw cms::Exception("InvalidReference") << "CompositeCandidate::daughter: Cannot find role " << s << "\n";
}
return daughter(ret);
}
void CompositeCandidate::addDaughter(const Candidate& cand, const std::string& s) {
Candidate* c = cand.clone();
if (!s.empty()) {
role_collection::iterator begin = roles_.begin(), end = roles_.end();
bool isFound = (find(begin, end, s) != end);
if (isFound) {
throw cms::Exception("InvalidReference") << "CompositeCandidate::addDaughter: Already have role with name \"" << s
<< "\", please clearDaughters, or use a new name\n";
}
roles_.push_back(s);
CompositeCandidate* c1 = dynamic_cast<CompositeCandidate*>(&*c);
if (c1 != nullptr) {
c1->setName(s);
}
}
dau.push_back(c);
}
void CompositeCandidate::addDaughter(std::unique_ptr<Candidate> cand, const std::string& s) {
if (!s.empty()) {
role_collection::iterator begin = roles_.begin(), end = roles_.end();
bool isFound = (find(begin, end, s) != end);
if (isFound) {
throw cms::Exception("InvalidReference") << "CompositeCandidate::addDaughter: Already have role with name \"" << s
<< "\", please clearDaughters, or use a new name\n";
}
roles_.push_back(s);
CompositeCandidate* c1 = dynamic_cast<CompositeCandidate*>(&*cand);
if (c1 != nullptr) {
c1->setName(s);
}
}
dau.push_back(std::move(cand));
}
|