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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
|
//
//
#ifndef DataFormats_PatCandidates_GenericParticle_h
#define DataFormats_PatCandidates_GenericParticle_h
/**
\class pat::GenericParticle GenericParticle.h "DataFormats/PatCandidates/interface/GenericParticle.h"
\brief Analysis-level Generic Particle class (e.g. for hadron or muon not fully reconstructed)
GenericParticle implements the analysis-level generic particle class within the 'pat'
namespace.
\author Giovanni Petrucciani
*/
#include "DataFormats/PatCandidates/interface/PATObject.h"
#include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
#include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
#include "DataFormats/EgammaReco/interface/SuperCluster.h"
#include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
#include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
#include "DataFormats/PatCandidates/interface/Isolation.h"
#include "DataFormats/PatCandidates/interface/Vertexing.h"
#include "DataFormats/HepMCCandidate/interface/GenParticle.h"
// Define typedefs for convenience
namespace pat {
class GenericParticle;
typedef std::vector<GenericParticle> GenericParticleCollection;
typedef edm::Ref<GenericParticleCollection> GenericParticleRef;
typedef edm::RefVector<GenericParticleCollection> GenericParticleRefVector;
} // namespace pat
// Class definition
namespace pat {
class GenericParticle : public PATObject<reco::RecoCandidate> {
public:
/// default constructor
GenericParticle();
/// constructor from Candidate
GenericParticle(const reco::Candidate &aGenericParticle);
/// constructor from ref to Candidate
GenericParticle(const edm::RefToBase<reco::Candidate> &aGenericParticleRef);
/// constructor from ref to Candidate
GenericParticle(const edm::Ptr<reco::Candidate> &aGenericParticleRef);
/// destructor
~GenericParticle() override;
/// required reimplementation of the Candidate's clone method
GenericParticle *clone() const override { return new GenericParticle(*this); }
/// Checks for overlap with another candidate.
/// It will return 'true' if the other candidate is a RecoCandidate,
/// and if they reference to at least one same non null track, supercluster or calotower (except for the multiple tracks)
/// NOTE: It won't work with embedded references
bool overlap(const Candidate &) const override;
/// reference to a master track (might be transient refs if Tracks are embedded)
/// returns null ref if there is no master track
reco::TrackRef track() const override { return track_.empty() ? trackRef_ : reco::TrackRef(&track_, 0); }
/// reference to one of a set of multiple tracks (might be transient refs if Tracks are embedded)
/// throws exception if idx >= numberOfTracks()
reco::TrackRef track(size_t idx) const override {
if (idx >= numberOfTracks())
throw cms::Exception("Index out of bounds")
<< "Requested track " << idx << " out of " << numberOfTracks() << ".\n";
return (tracks_.empty() ? trackRefs_[idx] : reco::TrackRef(&tracks_, idx));
}
/// number of multiple tracks (not including the master one)
size_t numberOfTracks() const override { return tracks_.empty() ? trackRefs_.size() : tracks_.size(); }
/// reference to a GsfTrack (might be transient ref if SuperCluster is embedded)
/// returns null ref if there is no gsf track
reco::GsfTrackRef gsfTrack() const override {
return (gsfTrack_.empty() ? gsfTrackRef_ : reco::GsfTrackRef(&gsfTrack_, 0));
}
/// reference to a stand-alone muon Track (might be transient ref if SuperCluster is embedded)
/// returns null ref if there is no stand-alone muon track
reco::TrackRef standAloneMuon() const override {
return (standaloneTrack_.empty() ? standaloneTrackRef_ : reco::TrackRef(&standaloneTrack_, 0));
}
/// reference to a combined muon Track (might be transient ref if SuperCluster is embedded)
/// returns null ref if there is no combined muon track
reco::TrackRef combinedMuon() const override {
return (combinedTrack_.empty() ? combinedTrackRef_ : reco::TrackRef(&combinedTrack_, 0));
}
/// reference to a SuperCluster (might be transient ref if SuperCluster is embedded)
/// returns null ref if there is no supercluster
reco::SuperClusterRef superCluster() const override {
return superCluster_.empty() ? superClusterRef_ : reco::SuperClusterRef(&superCluster_, 0);
}
/// reference to a CaloTower (might be transient ref if CaloTower is embedded)
/// returns null ref if there is no calotower
CaloTowerRef caloTower() const override {
return caloTower_.empty() ? caloTowerRef_ : CaloTowerRef(&caloTower_, 0);
}
/// sets master track reference (or even embed it into the object)
virtual void setTrack(const reco::TrackRef &ref, bool embed = false);
/// sets multiple track references (or even embed the tracks into the object - whatch out for disk size issues!)
virtual void setTracks(const reco::TrackRefVector &refs, bool embed = false);
/// sets stand-alone muon track reference (or even embed it into the object)
virtual void setStandAloneMuon(const reco::TrackRef &ref, bool embed = false);
/// sets combined muon track reference (or even embed it into the object)
virtual void setCombinedMuon(const reco::TrackRef &ref, bool embed = false);
/// sets gsf track reference (or even embed it into the object)
virtual void setGsfTrack(const reco::GsfTrackRef &ref, bool embed = false);
/// sets supercluster reference (or even embed it into the object)
virtual void setSuperCluster(const reco::SuperClusterRef &ref, bool embed = false);
/// sets calotower reference (or even embed it into the object)
virtual void setCaloTower(const CaloTowerRef &ref, bool embed = false);
/// embeds the master track instead of keeping a reference to it
void embedTrack();
/// embeds the other tracks instead of keeping references
void embedTracks();
/// embeds the stand-alone track instead of keeping a reference to it
void embedStandalone();
/// embeds the combined track instead of keeping a reference to it
void embedCombined();
/// embeds the gsf track instead of keeping a reference to it
void embedGsfTrack();
/// embeds the supercluster instead of keeping a reference to it
void embedSuperCluster();
/// embeds the calotower instead of keeping a reference to it
void embedCaloTower();
/// returns a user defined quality value, if set by the user to some meaningful value
float quality() { return quality_; }
/// sets a user defined quality value
void setQuality(float quality) { quality_ = quality; }
//============ BEGIN ISOLATION BLOCK =====
/// Returns the isolation variable for a specifc key (or
/// pseudo-key like CaloIso), or -1.0 if not available
float userIsolation(IsolationKeys key) const {
if (key >= 0) {
//if (key >= isolations_.size()) throw cms::Excepton("Missing Data")
//<< "Isolation corresponding to key "
//<< key << " was not stored for this particle.";
if (size_t(key) >= isolations_.size())
return -1.0;
return isolations_[key];
} else
switch (key) {
case pat::CaloIso:
//if (isolations_.size() <= pat::HcalIso) throw cms::Excepton("Missing Data")
//<< "CalIsoo Isolation was not stored for this particle.";
if (isolations_.size() <= pat::HcalIso)
return -1.0;
return isolations_[pat::EcalIso] + isolations_[pat::HcalIso];
default:
return -1.0;
//throw cms::Excepton("Missing Data") << "Isolation corresponding to key "
//<< key << " was not stored for this particle.";
}
}
/// Returns the isolation variable for string type function arguments
/// (to be used with the cut-string parser);
/// the possible values of the strings are the enums defined in
/// DataFormats/PatCandidates/interface/Isolation.h
float userIsolation(const std::string &key) const {
// remove leading namespace specifier
std::string prunedKey = (key.find("pat::") == 0) ? std::string(key, 5) : key;
if (prunedKey == "TrackIso")
return userIsolation(pat::TrackIso);
if (prunedKey == "EcalIso")
return userIsolation(pat::EcalIso);
if (prunedKey == "HcalIso")
return userIsolation(pat::HcalIso);
if (prunedKey == "PfAllParticleIso")
return userIsolation(pat::PfAllParticleIso);
if (prunedKey == "PfChargedHadronIso")
return userIsolation(pat::PfChargedHadronIso);
if (prunedKey == "PfNeutralHadronIso")
return userIsolation(pat::PfNeutralHadronIso);
if (prunedKey == "PfGammaIso")
return userIsolation(pat::PfGammaIso);
if (prunedKey == "User1Iso")
return userIsolation(pat::User1Iso);
if (prunedKey == "User2Iso")
return userIsolation(pat::User2Iso);
if (prunedKey == "User3Iso")
return userIsolation(pat::User3Iso);
if (prunedKey == "User4Iso")
return userIsolation(pat::User4Iso);
if (prunedKey == "User5Iso")
return userIsolation(pat::User5Iso);
if (prunedKey == "UserBaseIso")
return userIsolation(pat::UserBaseIso);
if (prunedKey == "CaloIso")
return userIsolation(pat::CaloIso);
//throw cms::Excepton("Missing Data")
//<< "Isolation corresponding to key "
//<< key << " was not stored for this particle.";
return -1.0;
}
/// Sets the isolation variable for a specifc key.
/// Note that you can't set isolation for a pseudo-key like CaloIso
void setIsolation(IsolationKeys key, float value) {
if (key >= 0) {
if (size_t(key) >= isolations_.size())
isolations_.resize(key + 1, -1.0);
isolations_[key] = value;
} else {
throw cms::Exception("Illegal Argument")
<< "The key for which you're setting isolation does not correspond "
<< "to an individual isolation but to the sum of more independent isolations "
<< "(e.g. Calo = Ecal + Hcal), so you can't SET the value, just GET it.\n"
<< "Please set up each component independly.\n";
}
}
// ---- specific getters ----
/// Return the tracker isolation variable that was stored in this
/// object when produced, or -1.0 if there is none
float trackIso() const { return userIsolation(pat::TrackIso); }
/// Return the sum of ecal and hcal isolation variable that were
/// stored in this object when produced, or -1.0 if at least one
/// is missing
float caloIso() const { return userIsolation(pat::CaloIso); }
/// Return the ecal isolation variable that was stored in this
/// object when produced, or -1.0 if there is none
float ecalIso() const { return userIsolation(pat::EcalIso); }
/// Return the hcal isolation variable that was stored in this
/// object when produced, or -1.0 if there is none
float hcalIso() const { return userIsolation(pat::HcalIso); }
// ---- specific setters ----
/// Sets tracker isolation variable
void setTrackIso(float trackIso) { setIsolation(pat::TrackIso, trackIso); }
/// Sets ecal isolation variable
void setEcalIso(float caloIso) { setIsolation(pat::EcalIso, caloIso); }
/// Sets hcal isolation variable
void setHcalIso(float caloIso) { setIsolation(pat::HcalIso, caloIso); }
/// Sets user isolation variable #index
void setUserIso(float value, uint8_t index = 0) { setIsolation(IsolationKeys(UserBaseIso + index), value); }
//============ BEGIN ISODEPOSIT BLOCK =====
/// Returns the IsoDeposit associated with some key, or a null pointer if it is not available
const IsoDeposit *isoDeposit(IsolationKeys key) const {
for (IsoDepositPairs::const_iterator it = isoDeposits_.begin(), ed = isoDeposits_.end(); it != ed; ++it) {
if (it->first == key)
return &it->second;
}
return nullptr;
}
/// Sets the IsoDeposit associated with some key; if it is already existent, it is overwritten.
void setIsoDeposit(IsolationKeys key, const IsoDeposit &dep) {
IsoDepositPairs::iterator it = isoDeposits_.begin(), ed = isoDeposits_.end();
for (; it != ed; ++it) {
if (it->first == key) {
it->second = dep;
return;
}
}
isoDeposits_.push_back(std::make_pair(key, dep));
}
// ---- specific getters ----
const IsoDeposit *trackIsoDeposit() const { return isoDeposit(pat::TrackIso); }
const IsoDeposit *ecalIsoDeposit() const { return isoDeposit(pat::EcalIso); }
const IsoDeposit *hcalIsoDeposit() const { return isoDeposit(pat::HcalIso); }
const IsoDeposit *userIsoDeposit(uint8_t index = 0) const { return isoDeposit(IsolationKeys(UserBaseIso + index)); }
// ---- specific setters ----
void trackIsoDeposit(const IsoDeposit &dep) { setIsoDeposit(pat::TrackIso, dep); }
void ecalIsoDeposit(const IsoDeposit &dep) { setIsoDeposit(pat::EcalIso, dep); }
void hcalIsoDeposit(const IsoDeposit &dep) { setIsoDeposit(pat::HcalIso, dep); }
void userIsoDeposit(const IsoDeposit &dep, uint8_t index = 0) {
setIsoDeposit(IsolationKeys(UserBaseIso + index), dep);
}
/// Vertex association (or associations, if any). Return null pointer if none has been set
const pat::VertexAssociation *vertexAssociation(size_t index = 0) const {
return vtxAss_.size() > index ? &vtxAss_[index] : nullptr;
}
/// Vertex associations. Can be empty if it was not enabled in the config file
const std::vector<pat::VertexAssociation> &vertexAssociations() const { return vtxAss_; }
/// Set a single vertex association
void setVertexAssociation(const pat::VertexAssociation &assoc) {
vtxAss_ = std::vector<pat::VertexAssociation>(1, assoc);
}
/// Set multiple vertex associations
void setVertexAssociations(const std::vector<pat::VertexAssociation> &assocs) { vtxAss_ = assocs; }
protected:
// Any sort of single tracks
reco::TrackRef trackRef_, standaloneTrackRef_, combinedTrackRef_; // ref
reco::TrackCollection track_, standaloneTrack_, combinedTrack_; // embedded
// GsfTrack
reco::GsfTrackRef gsfTrackRef_; // normal
reco::GsfTrackCollection gsfTrack_; // embedded
// CaloTower
CaloTowerRef caloTowerRef_; // ref
CaloTowerCollection caloTower_; // embedded
// SuperCluster
reco::SuperClusterRef superClusterRef_; // ref
reco::SuperClusterCollection superCluster_; // embedded
// Multiple tracks
reco::TrackRefVector trackRefs_; // by ref
reco::TrackCollection tracks_; // embedded
// information originally in external branches
// some quality variable
float quality_;
// --- Isolation and IsoDeposit related datamebers ---
typedef std::vector<std::pair<IsolationKeys, pat::IsoDeposit> > IsoDepositPairs;
IsoDepositPairs isoDeposits_;
std::vector<float> isolations_;
// --- Vertexing information
std::vector<pat::VertexAssociation> vtxAss_;
void fillInFrom(const reco::Candidate &cand);
};
} // namespace pat
#endif
|