ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Reconstruction
Jet
JetRecTools
Root
SoftKillerWeightTool.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#include "
JetRecTools/SoftKillerWeightTool.h
"
6
7
#include "fastjet/ClusterSequenceArea.hh"
8
#include "fastjet/Selector.hh"
9
#include "fastjet/RectangularGrid.hh"
10
#include "fastjet/contrib/SoftKiller.hh"
11
12
#include "
xAODPFlow/PFO.h
"
13
#include "
xAODPFlow/FlowElement.h
"
14
#include "
xAODPFlow/TrackCaloCluster.h
"
15
16
17
using namespace
std
;
18
19
namespace
{
20
const
static
SG::AuxElement::ConstAccessor<float> acc_clambda(
"CENTER_LAMBDA"
);
21
}
22
23
SoftKillerWeightTool::SoftKillerWeightTool
(
const
std::string& name) :
JetConstituentModifierBase
(name)
24
,
m_lambdaCalDivide
(317)
25
,
m_isCaloSplit
(false)
26
,
m_gridSpacing
(0.6)
27
,
m_eCalGrid
(0.5)
28
,
m_hCalGrid
(0.5)
29
,
m_rapmin
(0.0)
30
,
m_rapmax
(2.5)
31
,
m_rapminApplied
(0)
32
,
m_rapmaxApplied
(10)
33
,
m_ignoreChargedPFOs
(true)
34
35
{
36
37
declareProperty
(
"SKGridSize"
,
m_gridSpacing
);
38
declareProperty
(
"SKRapMin"
,
m_rapmin
);
39
declareProperty
(
"SKRapMax"
,
m_rapmax
);
40
declareProperty
(
"SKRapMinApplied"
,
m_rapminApplied
);
41
declareProperty
(
"SKRapMaxApplied"
,
m_rapmaxApplied
);
42
declareProperty
(
"isCaloSplit"
,
m_isCaloSplit
);
43
declareProperty
(
"ECalGridSize"
,
m_eCalGrid
);
44
declareProperty
(
"HCalGridSize"
,
m_hCalGrid
);
45
46
// Option to disregard cPFOs in the weight calculation
47
declareProperty
(
"IgnoreChargedPFO"
,
m_ignoreChargedPFOs
);
48
}
49
50
51
StatusCode
SoftKillerWeightTool::initialize
() {
52
if
(
m_isCaloSplit
&& (
m_inputType
!=
xAOD::Type::ParticleFlow
&&
m_inputType
!=
xAOD::Type::CaloCluster
&&
m_inputType
!=
xAOD::Type::FlowElement
)) {
53
ATH_MSG_ERROR
(
"SoftKillerWeightTool requires CaloCluster or PFO inputs when isCaloSplit is true."
54
<<
" It cannot apply split calorimeters on objects of type "
55
<<
m_inputType
);
56
return
StatusCode::FAILURE;
57
}
58
59
if
(
m_inputType
==
xAOD::Type::ParticleFlow
) {
60
if
(
m_ignoreChargedPFOs
&&
m_applyToChargedPFO
) {
61
ATH_MSG_ERROR
(
"Incompatible configuration: setting both IgnoreChargedPFO and ApplyToChargedPFO to true"
62
<<
"will set all cPFOs to zero"
);
63
return
StatusCode::FAILURE;
64
}
65
if
(!
m_applyToNeutralPFO
) {
66
ATH_MSG_ERROR
(
"Incompatible configuration: ApplyToNeutralPFO=False -- what kind of pileup do you wish to suppress?"
);
67
return
StatusCode::FAILURE;
68
}
69
}
70
return
StatusCode::SUCCESS;
71
}
72
73
StatusCode
SoftKillerWeightTool::process_impl
(
xAOD::IParticleContainer
* cont)
const
{
74
const
static
SG::AuxElement::Accessor<float> weightAcc(
"SoftKillerWeight"
);
// Handle for PU weighting here
75
double
minPt(0.), minPtECal(0.), minPtHCal(0.);
76
if
(!
m_isCaloSplit
) {
77
minPt =
getSoftKillerMinPt
(*cont);
78
ATH_MSG_VERBOSE
(
"For current event, minpt = "
<< minPt);
79
}
80
else
{
81
std::pair<double,double> minPt_split =
getSoftKillerMinPtSplit
(*cont);
82
minPtECal = minPt_split.first;
83
minPtHCal = minPt_split.second;
84
ATH_MSG_VERBOSE
(
"For current event, minpt = "
<< minPtECal <<
" (ECAL), "
85
<< minPtHCal <<
" (HCAL)"
);
86
}
87
88
for
(
xAOD::IParticle
* part : *cont) {
89
float
w = 1;
90
if
(!
m_isCaloSplit
) w =
calculateWeight
(*part, minPt);
91
else
w =
calculateSplitWeight
(*part, minPtECal, minPtHCal);
92
// use parent class's type-sensitive setter
93
ATH_CHECK
(
setEnergyPt
(part, part->e()*w, part->pt()*w,&weightAcc) );
94
}
95
return
StatusCode::SUCCESS;
96
}
97
98
99
// Finds the pT cut for this event based on the SK results
100
// The partSK collection contains all particles that aren't cut, so particles below
101
// its min pT are cut
102
double
SoftKillerWeightTool::findMinPt
(
const
vector<fastjet::PseudoJet> &partSK)
const
{
103
if
(partSK.empty()) {
return
0.;}
104
double
minPt = 999999999999;
105
106
for
(
unsigned
int
i=0; i < partSK.size(); i++){
107
if
( partSK[i].pt() < minPt) minPt = partSK[i].pt();
108
}
109
110
// There is a small rounding error which I account for this way
111
return
(minPt - 1e-12);
112
}
113
114
115
116
// Reweights particles (when calo isn't split)
117
double
SoftKillerWeightTool::getSoftKillerMinPt
(
xAOD::IParticleContainer
& cont)
const
{
118
vector<fastjet::PseudoJet> partPJ;
119
partPJ.reserve(cont.
size
());
120
121
for
(
xAOD::IParticle
* part : cont){
122
// Only use positive E
123
bool
accept = part->e() > 1e-9;
124
// For PFlow we would only want to apply the correction to neutral PFOs,
125
// because charged hadron subtraction handles the charged PFOs.
126
// However, we might still want to use the cPFOs for the min pt calculation
127
if
(
m_inputType
==
xAOD::Type::ParticleFlow
&&
m_ignoreChargedPFOs
) {
128
xAOD::PFO
* pfo =
static_cast<
xAOD::PFO
*
>
(part);
129
accept = !pfo->
isCharged
();
130
}
131
if
(
m_inputType
==
xAOD::Type::TrackCaloCluster
) {
132
xAOD::TrackCaloCluster
* tcc =
static_cast<
xAOD::TrackCaloCluster
*
>
(part);
133
accept = (tcc->
taste
()!= 0);
134
}
135
if
(
m_inputType
==
xAOD::Type::FlowElement
){
136
xAOD::FlowElement
* fe =
static_cast<
xAOD::FlowElement
*
>
(part);
137
if
(fe->
signalType
() &
xAOD::FlowElement::PFlow
){
138
if
(
m_ignoreChargedPFOs
) accept = !fe->
isCharged
();
139
}
140
else
141
accept = !fe->
isCharged
();
142
}
143
if
(accept) {
144
partPJ.emplace_back( part->p4() );
145
}
146
}
147
148
fastjet::Selector selector = fastjet::SelectorAbsRapRange(
m_rapmin
,
m_rapmax
);
149
fastjet::RectangularGrid SKgrid(-
m_rapmax
,
m_rapmax
,
m_gridSpacing
,
m_gridSpacing
, selector);
150
fastjet::contrib::SoftKiller softkiller(SKgrid);
151
std::vector<fastjet::PseudoJet> partSK = softkiller(selector(partPJ));
152
153
return
findMinPt
(partSK);
154
}
155
156
std::pair<double,double>
SoftKillerWeightTool::getSoftKillerMinPtSplit
(
xAOD::IParticleContainer
& cont)
const
{
157
vector<fastjet::PseudoJet> partPJ_ECal;
158
partPJ_ECal.reserve(cont.
size
());
159
vector<fastjet::PseudoJet> partPJ_HCal;
160
partPJ_HCal.reserve(cont.
size
());
161
162
for
(
xAOD::IParticle
* part : cont){
163
// Only use positive E
164
bool
accept = part->e() > 1e-9;
165
// For PFlow we would only want to apply the correction to neutral PFOs,
166
// because charged hadron subtraction handles the charged PFOs.
167
// However, we might still want to use the cPFOs for the min pt calculation
168
if
(
m_inputType
==
xAOD::Type::ParticleFlow
&&
m_ignoreChargedPFOs
) {
169
xAOD::PFO
* pfo =
static_cast<
xAOD::PFO
*
>
(part);
170
accept = !pfo->
isCharged
();
171
}
172
if
(
m_inputType
==
xAOD::Type::TrackCaloCluster
) {
173
xAOD::TrackCaloCluster
* tcc =
static_cast<
xAOD::TrackCaloCluster
*
>
(part);
174
accept = (tcc->
taste
()!= 0);
175
}
176
if
(
m_inputType
==
xAOD::Type::FlowElement
){
177
xAOD::FlowElement
* fe =
static_cast<
xAOD::FlowElement
*
>
(part);
178
if
(fe->
signalType
() &
xAOD::FlowElement::PFlow
){
179
if
(
m_ignoreChargedPFOs
) accept = !fe->
isCharged
();
180
}
181
else
182
accept = !fe->
isCharged
();
183
}
184
if
(accept) {
185
double
center_lambda = acc_clambda.isAvailable(*part) ? acc_clambda(*part) : 0.;
186
if
( center_lambda <
m_lambdaCalDivide
) partPJ_ECal.emplace_back( part->p4() );
187
if
( center_lambda >=
m_lambdaCalDivide
) partPJ_HCal.emplace_back( part->p4() );
188
}
189
}
190
191
fastjet::Selector selector = fastjet::SelectorAbsRapRange(
m_rapmin
,
m_rapmax
);
192
fastjet::RectangularGrid SKgridECal(-
m_rapmax
,
m_rapmax
,
m_eCalGrid
,
m_eCalGrid
, selector);
193
fastjet::contrib::SoftKiller softkillerECal(SKgridECal);
194
std::vector<fastjet::PseudoJet> partSK_ECal = softkillerECal(selector(partPJ_ECal));
195
double
minPtECal =
findMinPt
(partSK_ECal);
196
197
fastjet::RectangularGrid SKgridHCal(-
m_rapmax
,
m_rapmax
,
m_hCalGrid
,
m_hCalGrid
, selector);
198
fastjet::contrib::SoftKiller softkillerHCal(SKgridHCal);
199
std::vector<fastjet::PseudoJet> partSK_HCal = softkillerHCal(selector(partPJ_HCal));
200
double
minPtHCal =
findMinPt
(partSK_HCal);
201
return
std::make_pair(minPtECal,minPtHCal);
202
}
203
204
float
SoftKillerWeightTool::calculateWeight
(
xAOD::IParticle
& part,
double
minPt)
const
{
205
// If the particle pT is below the SoftKiller pT cut, rescale 4-momentum to 0
206
if
( abs(part.eta()) <
m_rapminApplied
|| abs(part.eta()) >
m_rapmaxApplied
)
return
1;
207
if
( part.pt() < minPt)
return
0;
208
return
1;
209
}
210
211
212
float
SoftKillerWeightTool::calculateSplitWeight
(
xAOD::IParticle
& part,
double
minPtECal,
double
minPtHCal)
const
{
213
if
( abs(part.eta()) <
m_rapminApplied
|| abs(part.eta()) >
m_rapmaxApplied
)
return
1;
214
double
center_lambda = acc_clambda.isAvailable(part) ? acc_clambda(part) : 0.;
215
216
//Make a separate pT cut for the ECal and HCal
217
if
( center_lambda <
m_lambdaCalDivide
&& part.pt() < minPtECal)
return
0;
218
if
( part.pt() < minPtHCal)
return
0;
219
return
1;
220
}
221
222
223
ATH_CHECK
#define ATH_CHECK
Evaluate an expression and check for errors.
Definition
AthCheckMacros.h:40
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition
AthMsgStreamMacros.h:33
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition
AthMsgStreamMacros.h:28
FlowElement.h
PFO.h
SoftKillerWeightTool.h
TrackCaloCluster.h
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Definition
AthCommonDataStore.h:145
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
JetConstituentModifierBase::m_applyToNeutralPFO
bool m_applyToNeutralPFO
Definition
JetConstituentModifierBase.h:63
JetConstituentModifierBase::JetConstituentModifierBase
JetConstituentModifierBase(const std::string &name)
Definition
JetConstituentModifierBase.cxx:14
JetConstituentModifierBase::m_inputType
unsigned int m_inputType
Definition
JetConstituentModifierBase.h:60
JetConstituentModifierBase::setEnergyPt
StatusCode setEnergyPt(xAOD::IParticle *obj, float e, float pt, const SG::AuxElement::Accessor< float > *weightAcc=nullptr) const
Definition
JetConstituentModifierBase.cxx:61
JetConstituentModifierBase::m_applyToChargedPFO
bool m_applyToChargedPFO
Definition
JetConstituentModifierBase.h:62
SoftKillerWeightTool::getSoftKillerMinPt
double getSoftKillerMinPt(xAOD::IParticleContainer &cont) const
Definition
SoftKillerWeightTool.cxx:117
SoftKillerWeightTool::SoftKillerWeightTool
SoftKillerWeightTool(const std::string &name)
Definition
SoftKillerWeightTool.cxx:23
SoftKillerWeightTool::m_rapmin
float m_rapmin
Definition
SoftKillerWeightTool.h:92
SoftKillerWeightTool::m_rapmaxApplied
float m_rapmaxApplied
Definition
SoftKillerWeightTool.h:95
SoftKillerWeightTool::m_hCalGrid
float m_hCalGrid
Definition
SoftKillerWeightTool.h:91
SoftKillerWeightTool::m_rapminApplied
float m_rapminApplied
Definition
SoftKillerWeightTool.h:94
SoftKillerWeightTool::process_impl
StatusCode process_impl(xAOD::IParticleContainer *cont) const
Definition
SoftKillerWeightTool.cxx:73
SoftKillerWeightTool::m_eCalGrid
float m_eCalGrid
Definition
SoftKillerWeightTool.h:90
SoftKillerWeightTool::calculateSplitWeight
float calculateSplitWeight(xAOD::IParticle &part, double minPtECal, double minPtHCal) const
Definition
SoftKillerWeightTool.cxx:212
SoftKillerWeightTool::m_rapmax
float m_rapmax
Definition
SoftKillerWeightTool.h:93
SoftKillerWeightTool::m_ignoreChargedPFOs
bool m_ignoreChargedPFOs
Definition
SoftKillerWeightTool.h:96
SoftKillerWeightTool::getSoftKillerMinPtSplit
std::pair< double, double > getSoftKillerMinPtSplit(xAOD::IParticleContainer &cont) const
Definition
SoftKillerWeightTool.cxx:156
SoftKillerWeightTool::m_lambdaCalDivide
float m_lambdaCalDivide
Definition
SoftKillerWeightTool.h:85
SoftKillerWeightTool::m_isCaloSplit
bool m_isCaloSplit
Definition
SoftKillerWeightTool.h:88
SoftKillerWeightTool::findMinPt
double findMinPt(const std::vector< fastjet::PseudoJet > &partSK) const
Definition
SoftKillerWeightTool.cxx:102
SoftKillerWeightTool::initialize
StatusCode initialize()
Dummy implementation of the initialisation function.
Definition
SoftKillerWeightTool.cxx:51
SoftKillerWeightTool::m_gridSpacing
float m_gridSpacing
Definition
SoftKillerWeightTool.h:89
SoftKillerWeightTool::calculateWeight
float calculateWeight(xAOD::IParticle &part, double minPt) const
Definition
SoftKillerWeightTool.cxx:204
xAOD::FlowElement_v1::signalType
signal_t signalType() const
xAOD::FlowElement_v1::PFlow
@ PFlow
Definition
FlowElement_v1.h:45
xAOD::FlowElement_v1::isCharged
bool isCharged() const
Definition
FlowElement_v1.cxx:56
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition
Event/xAOD/xAODBase/xAODBase/IParticle.h:41
xAOD::PFO_v1::isCharged
bool isCharged() const
is a charged PFO
Definition
PFO_v1.cxx:251
xAOD::TrackCaloCluster_v1::taste
virtual int taste() const
The taste of the particle.
std
STL namespace.
xAODType::ParticleFlow
@ ParticleFlow
The object is a particle-flow object.
Definition
ObjectType.h:41
xAODType::FlowElement
@ FlowElement
The object is a track-calo-cluster.
Definition
ObjectType.h:52
xAODType::CaloCluster
@ CaloCluster
The object is a calorimeter cluster.
Definition
ObjectType.h:39
xAODType::TrackCaloCluster
@ TrackCaloCluster
The object is a track-calo-cluster.
Definition
ObjectType.h:51
xAOD::PFO
PFO_v1 PFO
Definition of the current "pfo version".
Definition
PFO.h:17
xAOD::FlowElement
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition
FlowElement.h:16
xAOD::TrackCaloCluster
TrackCaloCluster_v1 TrackCaloCluster
Reference the current persistent version:
Definition
TrackCaloCluster.h:12
xAOD::IParticleContainer
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
Definition
xAOD/xAODBase/xAODBase/IParticleContainer.h:32
Generated on
for ATLAS Offline Software by
1.17.0