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
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
|
#ifndef EgammaCandidates_Photon_h
#define EgammaCandidates_Photon_h
/** \class reco::Photon
*
* \author N. Marinelli Univ. of Notre Dame
* Photon object built out of PhotonCore
* stores isolation, shower shape and additional info
* needed for identification
*
*
*/
#include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
#include "DataFormats/EgammaCandidates/interface/Conversion.h"
#include "DataFormats/EgammaCandidates/interface/ConversionFwd.h"
#include "DataFormats/EgammaCandidates/interface/PhotonCore.h"
#include "DataFormats/EgammaReco/interface/ElectronSeed.h"
#include "DataFormats/EgammaReco/interface/SuperCluster.h"
#include <numeric>
namespace reco {
class Photon : public RecoCandidate {
public:
/// Forward declaration of data structures included in the object
struct FiducialFlags;
struct IsolationVariables;
struct ShowerShape;
struct MIPVariables;
struct SaturationInfo;
/// default constructor
Photon() : RecoCandidate() {
pixelSeed_ = false;
haloTaggerMVAVal_ = 99;
}
/// copy constructor
Photon(const Photon&);
/// constructor from values
Photon(const LorentzVector& p4, const Point& caloPos, const PhotonCoreRef& core, const Point& vtx = Point(0, 0, 0));
/// assignment operator
Photon& operator=(const Photon&) = default;
/// destructor
~Photon() override;
/// returns a clone of the candidate
Photon* clone() const override;
/// returns a reference to the core photon object
reco::PhotonCoreRef photonCore() const { return photonCore_; }
void setPhotonCore(const reco::PhotonCoreRef& photonCore) { photonCore_ = photonCore; }
//
/// Retrieve photonCore attributes
//
// retrieve provenance
bool isPFlowPhoton() const { return this->photonCore()->isPFlowPhoton(); }
bool isStandardPhoton() const { return this->photonCore()->isStandardPhoton(); }
/// Ref to SuperCluster
reco::SuperClusterRef superCluster() const override;
/// Ref to PFlow SuperCluster
reco::SuperClusterRef parentSuperCluster() const { return this->photonCore()->parentSuperCluster(); }
/// vector of references to Conversion's
reco::ConversionRefVector conversions() const { return this->photonCore()->conversions(); }
enum ConversionProvenance { egamma = 0, pflow = 1, both = 2 };
/// vector of references to one leg Conversion's
reco::ConversionRefVector conversionsOneLeg() const { return this->photonCore()->conversionsOneLeg(); }
/// Bool flagging photons with a vector of refereces to conversions with size >0
bool hasConversionTracks() const {
if (!this->photonCore()->conversions().empty() || !this->photonCore()->conversionsOneLeg().empty())
return true;
else
return false;
}
/// reference to electron Pixel seed
reco::ElectronSeedRefVector electronPixelSeeds() const { return this->photonCore()->electronPixelSeeds(); }
/// Bool flagging photons having a non-zero size vector of Ref to electornPixel seeds
bool hasPixelSeed() const {
if (!(this->photonCore()->electronPixelSeeds()).empty())
return true;
else
return false;
}
int conversionTrackProvenance(const edm::RefToBase<reco::Track>& convTrack) const;
/// position in ECAL: this is th SC position if r9<0.93. If r8>0.93 is position of seed BasicCluster taking shower depth for unconverted photon
math::XYZPointF caloPosition() const { return caloPosition_; }
/// set primary event vertex used to define photon direction
void setVertex(const Point& vertex) override;
/// Implement Candidate method for particle species
bool isPhoton() const override { return true; }
//=======================================================
// Fiducial Flags
//=======================================================
struct FiducialFlags {
//Fiducial flags
bool isEB; //Photon is in EB
bool isEE; //Photon is in EE
bool isEBEtaGap; //Photon is in supermodule/supercrystal eta gap in EB
bool isEBPhiGap; //Photon is in supermodule/supercrystal phi gap in EB
bool isEERingGap; //Photon is in crystal ring gap in EE
bool isEEDeeGap; //Photon is in crystal dee gap in EE
bool isEBEEGap; //Photon is in border between EB and EE.
FiducialFlags()
: isEB(false),
isEE(false),
isEBEtaGap(false),
isEBPhiGap(false),
isEERingGap(false),
isEEDeeGap(false),
isEBEEGap(false)
{}
};
/// set flags for photons in the ECAL fiducial volume
void setFiducialVolumeFlags(const FiducialFlags& a) { fiducialFlagBlock_ = a; }
/// Ritrievs fiducial flags
/// true if photon is in ECAL barrel
bool isEB() const { return fiducialFlagBlock_.isEB; }
// true if photon is in ECAL endcap
bool isEE() const { return fiducialFlagBlock_.isEE; }
/// true if photon is in EB, and inside the boundaries in super crystals/modules
bool isEBGap() const { return (isEBEtaGap() || isEBPhiGap()); }
bool isEBEtaGap() const { return fiducialFlagBlock_.isEBEtaGap; }
bool isEBPhiGap() const { return fiducialFlagBlock_.isEBPhiGap; }
/// true if photon is in EE, and inside the boundaries in supercrystal/D
bool isEEGap() const { return (isEERingGap() || isEEDeeGap()); }
bool isEERingGap() const { return fiducialFlagBlock_.isEERingGap; }
bool isEEDeeGap() const { return fiducialFlagBlock_.isEEDeeGap; }
/// true if photon is in boundary between EB and EE
bool isEBEEGap() const { return fiducialFlagBlock_.isEBEEGap; }
//=======================================================
// Shower Shape Variables
//=======================================================
struct ShowerShape {
float sigmaEtaEta;
float sigmaIetaIeta;
float e1x5;
float e2x5;
float e3x3;
float e5x5;
float maxEnergyXtal;
float hcalDepth1OverEcal; // hcal over ecal energy using first hcal depth
float hcalDepth2OverEcal; // hcal over ecal energy using 2nd hcal depth
float hcalDepth1OverEcalBc;
float hcalDepth2OverEcalBc;
std::array<float, 7> hcalOverEcal; // hcal over ecal seed cluster energy per depth (using rechits within a cone)
std::array<float, 7>
hcalOverEcalBc; // hcal over ecal seed cluster energy per depth (using rechits behind clusters)
std::vector<CaloTowerDetId> hcalTowersBehindClusters;
bool invalidHcal;
bool pre7DepthHcal; // to work around an ioread rule issue on legacy RECO files
float effSigmaRR;
float sigmaIetaIphi;
float sigmaIphiIphi;
float e2nd;
float eTop;
float eLeft;
float eRight;
float eBottom;
float e1x3;
float e2x2;
float e2x5Max;
float e2x5Left;
float e2x5Right;
float e2x5Top;
float e2x5Bottom;
float smMajor;
float smMinor;
float smAlpha;
ShowerShape()
: sigmaEtaEta(std::numeric_limits<float>::max()),
sigmaIetaIeta(std::numeric_limits<float>::max()),
e1x5(0.f),
e2x5(0.f),
e3x3(0.f),
e5x5(0.f),
maxEnergyXtal(0.f),
hcalDepth1OverEcal(0.f),
hcalDepth2OverEcal(0.f),
hcalDepth1OverEcalBc(0.f),
hcalDepth2OverEcalBc(0.f),
hcalOverEcal{{0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}},
hcalOverEcalBc{{0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}},
invalidHcal(false),
pre7DepthHcal(true),
effSigmaRR(std::numeric_limits<float>::max()),
sigmaIetaIphi(std::numeric_limits<float>::max()),
sigmaIphiIphi(std::numeric_limits<float>::max()),
e2nd(0.f),
eTop(0.f),
eLeft(0.f),
eRight(0.f),
eBottom(0.f),
e1x3(0.f),
e2x2(0.f),
e2x5Max(0.f),
e2x5Left(0.f),
e2x5Right(0.f),
e2x5Top(0.f),
e2x5Bottom(0.f),
smMajor(0.f),
smMinor(0.f),
smAlpha(0.f) {}
};
const ShowerShape& showerShapeVariables() const { return showerShapeBlock_; }
const ShowerShape& full5x5_showerShapeVariables() const { return full5x5_showerShapeBlock_; }
void setShowerShapeVariables(const ShowerShape& a) { showerShapeBlock_ = a; }
void full5x5_setShowerShapeVariables(const ShowerShape& a) { full5x5_showerShapeBlock_ = a; }
/// the total hadronic over electromagnetic fraction
float hcalOverEcal(const ShowerShape& ss, int depth) const {
if (ss.pre7DepthHcal) {
if (depth == 0)
return ss.hcalDepth1OverEcal + ss.hcalDepth2OverEcal;
else if (depth == 1)
return ss.hcalDepth1OverEcal;
else if (depth == 2)
return ss.hcalDepth2OverEcal;
return 0.f;
} else {
const auto& hovere = ss.hcalOverEcal;
return (!(depth > 0 and depth < 8)) ? std::accumulate(std::begin(hovere), std::end(hovere), 0.f)
: hovere[depth - 1];
}
}
float hcalOverEcal(int depth = 0) const { return hcalOverEcal(showerShapeBlock_, depth); }
float hadronicOverEm(int depth = 0) const { return hcalOverEcal(depth); }
/// the ratio of total energy of hcal rechits behind the SC and the SC energy
float hcalOverEcalBc(const ShowerShape& ss, int depth) const {
if (ss.pre7DepthHcal) {
if (depth == 0)
return ss.hcalDepth1OverEcalBc + ss.hcalDepth2OverEcalBc;
else if (depth == 1)
return ss.hcalDepth1OverEcalBc;
else if (depth == 2)
return ss.hcalDepth2OverEcalBc;
return 0.f;
} else {
const auto& hovere = ss.hcalOverEcalBc;
return (!(depth > 0 and depth < 8)) ? std::accumulate(std::begin(hovere), std::end(hovere), 0.f)
: hovere[depth - 1];
}
}
float hcalOverEcalBc(int depth = 0) const { return hcalOverEcalBc(showerShapeBlock_, depth); }
float hadTowOverEm(int depth = 0) const { return hcalOverEcalBc(depth); }
const std::vector<CaloTowerDetId>& hcalTowersBehindClusters() const {
return showerShapeBlock_.hcalTowersBehindClusters;
}
/// returns false if H/E is not reliably estimated (e.g. because hcal was off or masked)
bool hadronicOverEmValid() const { return !showerShapeBlock_.invalidHcal; }
bool hadTowOverEmValid() const { return !showerShapeBlock_.invalidHcal; }
/// Shower shape variables
float e1x5() const { return showerShapeBlock_.e1x5; }
float e2x5() const { return showerShapeBlock_.e2x5; }
float e3x3() const { return showerShapeBlock_.e3x3; }
float e5x5() const { return showerShapeBlock_.e5x5; }
float maxEnergyXtal() const { return showerShapeBlock_.maxEnergyXtal; }
float sigmaEtaEta() const { return showerShapeBlock_.sigmaEtaEta; }
float sigmaIetaIeta() const { return showerShapeBlock_.sigmaIetaIeta; }
float r1x5() const { return showerShapeBlock_.e1x5 / showerShapeBlock_.e5x5; }
float r2x5() const { return showerShapeBlock_.e2x5 / showerShapeBlock_.e5x5; }
float r9() const { return showerShapeBlock_.e3x3 / this->superCluster()->rawEnergy(); }
///full5x5 Shower shape variables
float full5x5_e1x5() const { return full5x5_showerShapeBlock_.e1x5; }
float full5x5_e2x5() const { return full5x5_showerShapeBlock_.e2x5; }
float full5x5_e3x3() const { return full5x5_showerShapeBlock_.e3x3; }
float full5x5_e5x5() const { return full5x5_showerShapeBlock_.e5x5; }
float full5x5_maxEnergyXtal() const { return full5x5_showerShapeBlock_.maxEnergyXtal; }
float full5x5_sigmaEtaEta() const { return full5x5_showerShapeBlock_.sigmaEtaEta; }
float full5x5_sigmaIetaIeta() const { return full5x5_showerShapeBlock_.sigmaIetaIeta; }
float full5x5_r1x5() const { return full5x5_showerShapeBlock_.e1x5 / full5x5_showerShapeBlock_.e5x5; }
float full5x5_r2x5() const { return full5x5_showerShapeBlock_.e2x5 / full5x5_showerShapeBlock_.e5x5; }
float full5x5_r9() const { return full5x5_showerShapeBlock_.e3x3 / this->superCluster()->rawEnergy(); }
/// the total hadronic over electromagnetic fraction
float full5x5_hcalOverEcal(int depth = 0) const { return hcalOverEcal(full5x5_showerShapeBlock_, depth); }
float full5x5_hadronicOverEm(int depth = 0) const { return full5x5_hcalOverEcal(depth); }
/// the ratio of total energy of hcal rechits behind the SC and the SC energy
float full5x5_hcalOverEcalBc(int depth = 0) const { return hcalOverEcalBc(full5x5_showerShapeBlock_, depth); }
float full5x5_hadTowOverEm(int depth = 0) const { return full5x5_hcalOverEcalBc(depth); }
//=======================================================
// SaturationInfo
//=======================================================
struct SaturationInfo {
int nSaturatedXtals;
bool isSeedSaturated;
SaturationInfo() : nSaturatedXtals(0), isSeedSaturated(false) {}
};
// accessors
float nSaturatedXtals() const { return saturationInfo_.nSaturatedXtals; }
float isSeedSaturated() const { return saturationInfo_.isSeedSaturated; }
const SaturationInfo& saturationInfo() const { return saturationInfo_; }
void setSaturationInfo(const SaturationInfo& s) { saturationInfo_ = s; }
//=======================================================
// Energy Determinations
//=======================================================
enum P4type { undefined = -1, ecal_standard = 0, ecal_photons = 1, regression1 = 2, regression2 = 3 };
struct EnergyCorrections {
float scEcalEnergy;
float scEcalEnergyError;
LorentzVector scEcalP4;
float phoEcalEnergy;
float phoEcalEnergyError;
LorentzVector phoEcalP4;
float regression1Energy;
float regression1EnergyError;
LorentzVector regression1P4;
float regression2Energy;
float regression2EnergyError;
LorentzVector regression2P4;
P4type candidateP4type;
EnergyCorrections()
: scEcalEnergy(0.),
scEcalEnergyError(999.),
scEcalP4(0., 0., 0., 0.),
phoEcalEnergy(0.),
phoEcalEnergyError(999.),
phoEcalP4(0., 0., 0., 0.),
regression1Energy(0.),
regression1EnergyError(999.),
regression1P4(0., 0., 0., 0.),
regression2Energy(0.),
regression2EnergyError(999.),
regression2P4(0., 0., 0., 0.),
candidateP4type(undefined) {}
};
using RecoCandidate::p4;
using RecoCandidate::setP4;
//sets both energy and its uncertainty
void setCorrectedEnergy(P4type type, float E, float dE, bool toCand = true);
void setP4(P4type type, const LorentzVector& p4, float p4Error, bool setToRecoCandidate);
void setEnergyCorrections(const EnergyCorrections& e) { eCorrections_ = e; }
void setCandidateP4type(const P4type type) { eCorrections_.candidateP4type = type; }
float getCorrectedEnergy(P4type type) const;
float getCorrectedEnergyError(P4type type) const;
P4type getCandidateP4type() const { return eCorrections_.candidateP4type; }
const LorentzVector& p4(P4type type) const;
const EnergyCorrections& energyCorrections() const { return eCorrections_; }
//=======================================================
// MIP Variables
//=======================================================
struct MIPVariables {
float mipChi2;
float mipTotEnergy;
float mipSlope;
float mipIntercept;
int mipNhitCone;
bool mipIsHalo;
MIPVariables()
:
mipChi2(0),
mipTotEnergy(0),
mipSlope(0),
mipIntercept(0),
mipNhitCone(0),
mipIsHalo(false) {}
};
/// MIP variables
float mipChi2() const { return mipVariableBlock_.mipChi2; }
float mipTotEnergy() const { return mipVariableBlock_.mipTotEnergy; }
float mipSlope() const { return mipVariableBlock_.mipSlope; }
float mipIntercept() const { return mipVariableBlock_.mipIntercept; }
int mipNhitCone() const { return mipVariableBlock_.mipNhitCone; }
bool mipIsHalo() const { return mipVariableBlock_.mipIsHalo; }
///set mip Variables
void setMIPVariables(const MIPVariables& mipVar) { mipVariableBlock_ = mipVar; }
//=======================================================
// Isolation Variables
//=======================================================
struct IsolationVariables {
//These are analysis quantities calculated in the PhotonIDAlgo class
//EcalRecHit isolation
float ecalRecHitSumEt;
//HcalTower isolation
float hcalTowerSumEt;
//HcalDepth1Tower isolation
float hcalDepth1TowerSumEt;
//HcalDepth2Tower isolation
float hcalDepth2TowerSumEt;
//HcalTower isolation subtracting the hadronic energy in towers behind the BCs in the SC
float hcalTowerSumEtBc;
//HcalDepth1Tower isolation subtracting the hadronic energy in towers behind the BCs in the SC
float hcalDepth1TowerSumEtBc;
//HcalDepth2Tower isolation subtracting the hadronic energy in towers behind the BCs in the SC
float hcalDepth2TowerSumEtBc;
std::array<float, 7> hcalRecHitSumEt; // ...per depth, with photon footprint within a cone removed
std::array<float, 7> hcalRecHitSumEtBc; // ...per depth, with hcal rechits behind cluster removed
bool pre7DepthHcal; // to work around an ioread rule issue on legacy RECO files
//Sum of track pT in a cone of dR
float trkSumPtSolidCone;
//Sum of track pT in a hollow cone of outer radius, inner radius
float trkSumPtHollowCone;
//Number of tracks in a cone of dR
int nTrkSolidCone;
//Number of tracks in a hollow cone of outer radius, inner radius
int nTrkHollowCone;
IsolationVariables()
:
ecalRecHitSumEt(0.f),
hcalTowerSumEt(0.f),
hcalDepth1TowerSumEt(0.f),
hcalDepth2TowerSumEt(0.f),
hcalTowerSumEtBc(0.f),
hcalDepth1TowerSumEtBc(0.f),
hcalDepth2TowerSumEtBc(0.f),
hcalRecHitSumEt{{0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}},
hcalRecHitSumEtBc{{0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}},
pre7DepthHcal(true),
trkSumPtSolidCone(0.f),
trkSumPtHollowCone(0.f),
nTrkSolidCone(0),
nTrkHollowCone(0) {}
};
/// set relevant isolation variables
void setIsolationVariables(const IsolationVariables& isolInDr04, const IsolationVariables& isolInDr03) {
isolationR04_ = isolInDr04;
isolationR03_ = isolInDr03;
}
/// Egamma Isolation variables in cone dR=0.4
///Ecal isolation sum calculated from recHits
float ecalRecHitSumEtConeDR04() const { return isolationR04_.ecalRecHitSumEt; }
/// Hcal isolation sum for each depth excluding the region containing the rechits used for hcalOverEcal()
float hcalTowerSumEt(const IsolationVariables& iv, int depth) const {
if (iv.pre7DepthHcal) {
if (depth == 0)
return iv.hcalTowerSumEt;
else if (depth == 1)
return iv.hcalDepth1TowerSumEt;
else if (depth == 2)
return iv.hcalDepth2TowerSumEt;
return 0.f;
} else {
const auto& hcaliso = iv.hcalRecHitSumEt;
return (!(depth > 0 and depth < 8)) ? std::accumulate(std::begin(hcaliso), std::end(hcaliso), 0.f)
: hcaliso[depth - 1];
}
}
float hcalTowerSumEtConeDR04(int depth = 0) const { return hcalTowerSumEt(isolationR04_, depth); }
/// Hcal isolation sum for each depth excluding the region containing the rechits used for hcalOverEcalBc()
float hcalTowerSumEtBc(const IsolationVariables& iv, int depth) const {
if (iv.pre7DepthHcal) {
if (depth == 0)
return iv.hcalTowerSumEtBc;
else if (depth == 1)
return iv.hcalDepth1TowerSumEtBc;
else if (depth == 2)
return iv.hcalDepth2TowerSumEtBc;
return 0.f;
} else {
const auto& hcaliso = iv.hcalRecHitSumEtBc;
return (!(depth > 0 and depth < 8)) ? std::accumulate(std::begin(hcaliso), std::end(hcaliso), 0.f)
: hcaliso[depth - 1];
}
}
float hcalTowerSumEtBcConeDR04(int depth = 0) const { return hcalTowerSumEtBc(isolationR04_, depth); }
// Track pT sum
float trkSumPtSolidConeDR04() const { return isolationR04_.trkSumPtSolidCone; }
//As above, excluding the core at the center of the cone
float trkSumPtHollowConeDR04() const { return isolationR04_.trkSumPtHollowCone; }
//Returns number of tracks in a cone of dR
int nTrkSolidConeDR04() const { return isolationR04_.nTrkSolidCone; }
//As above, excluding the core at the center of the cone
int nTrkHollowConeDR04() const { return isolationR04_.nTrkHollowCone; }
//
/// Isolation variables in cone dR=0.3
float ecalRecHitSumEtConeDR03() const { return isolationR03_.ecalRecHitSumEt; }
/// Hcal isolation sum for each depth excluding the region containing the rechits used for hcalOverEcal()
float hcalTowerSumEtConeDR03(int depth = 0) const { return hcalTowerSumEt(isolationR03_, depth); }
/// Hcal isolation sum for each depth excluding the region containing the rechits used for hcalOverEcalBc()
float hcalTowerSumEtBcConeDR03(int depth = 0) const { return hcalTowerSumEtBc(isolationR03_, depth); }
// Track pT sum c
float trkSumPtSolidConeDR03() const { return isolationR03_.trkSumPtSolidCone; }
//As above, excluding the core at the center of the cone
float trkSumPtHollowConeDR03() const { return isolationR03_.trkSumPtHollowCone; }
//Returns number of tracks in a cone of dR
int nTrkSolidConeDR03() const { return isolationR03_.nTrkSolidCone; }
//As above, excluding the core at the center of the cone
int nTrkHollowConeDR03() const { return isolationR03_.nTrkHollowCone; }
//=======================================================
// PFlow based Isolation Variables
//=======================================================
struct PflowIsolationVariables {
float chargedHadronIso; //charged hadron isolation with dxy,dz match to pv
float chargedHadronWorstVtxIso; //max charged hadron isolation when dxy/dz matching to given vtx
float chargedHadronWorstVtxGeomVetoIso; //as chargedHadronWorstVtxIso but an additional geometry based veto cone
float chargedHadronPFPVIso; //only considers particles assigned to the primary vertex (PV) by particle flow, corresponds to <10_6 chargedHadronIso
float neutralHadronIso;
float photonIso;
float sumEcalClusterEt; //sum pt of ecal clusters, vetoing clusters part of photon
float sumHcalClusterEt; //sum pt of hcal clusters, vetoing clusters part of photon
PflowIsolationVariables()
:
chargedHadronIso(0.),
chargedHadronWorstVtxIso(0.),
chargedHadronWorstVtxGeomVetoIso(0.),
chargedHadronPFPVIso(0.),
neutralHadronIso(0.),
photonIso(0.),
sumEcalClusterEt(0.),
sumHcalClusterEt(0.) {}
};
/// Accessors for Particle Flow Isolation variables
float chargedHadronIso() const { return pfIsolation_.chargedHadronIso; }
float chargedHadronWorstVtxIso() const { return pfIsolation_.chargedHadronWorstVtxIso; }
float chargedHadronWorstVtxGeomVetoIso() const { return pfIsolation_.chargedHadronWorstVtxGeomVetoIso; }
float chargedHadronPFPVIso() const { return pfIsolation_.chargedHadronPFPVIso; }
float neutralHadronIso() const { return pfIsolation_.neutralHadronIso; }
float photonIso() const { return pfIsolation_.photonIso; }
//backwards compat functions for pat::Photon
float ecalPFClusterIso() const { return pfIsolation_.sumEcalClusterEt; };
float hcalPFClusterIso() const { return pfIsolation_.sumHcalClusterEt; };
/// Get Particle Flow Isolation variables block
const PflowIsolationVariables& getPflowIsolationVariables() const { return pfIsolation_; }
/// Set Particle Flow Isolation variables
void setPflowIsolationVariables(const PflowIsolationVariables& pfisol) { pfIsolation_ = pfisol; }
static constexpr float mvaPlaceholder = -999999999.;
struct PflowIDVariables {
int nClusterOutsideMustache;
float etOutsideMustache;
float mva;
float dnn;
PflowIDVariables()
: nClusterOutsideMustache(-1), etOutsideMustache(mvaPlaceholder), mva(mvaPlaceholder), dnn(mvaPlaceholder) {}
};
// getters
int nClusterOutsideMustache() const { return pfID_.nClusterOutsideMustache; }
float etOutsideMustache() const { return pfID_.etOutsideMustache; }
float pfMVA() const { return pfID_.mva; }
float pfDNN() const { return pfID_.dnn; }
// setters
void setPflowIDVariables(const PflowIDVariables& pfid) { pfID_ = pfid; }
// go back to run2-like 2 effective depths if desired - depth 1 is the normal depth 1, depth 2 is the sum over the rest
void hcalToRun2EffDepth();
///MVA based beam halo tagger - trained for EE and for pT > 200 GeV
float haloTaggerMVAVal() const { return haloTaggerMVAVal_; }
///set the haloTaggerMVAVal here
void setHaloTaggerMVAVal(float x) { haloTaggerMVAVal_ = x; }
private:
/// check overlap with another candidate
bool overlap(const Candidate&) const override;
/// position of seed BasicCluster for shower depth of unconverted photon
math::XYZPointF caloPosition_;
/// reference to the PhotonCore
reco::PhotonCoreRef photonCore_;
//
bool pixelSeed_;
//
FiducialFlags fiducialFlagBlock_;
IsolationVariables isolationR04_;
IsolationVariables isolationR03_;
ShowerShape showerShapeBlock_;
ShowerShape full5x5_showerShapeBlock_;
SaturationInfo saturationInfo_;
EnergyCorrections eCorrections_;
MIPVariables mipVariableBlock_;
PflowIsolationVariables pfIsolation_;
PflowIDVariables pfID_;
float haloTaggerMVAVal_;
};
} // namespace reco
#endif
|