ATLAS Offline Software
Loading...
Searching...
No Matches
WeightPFOTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8static constexpr float GeV = 1000.f;
9
10namespace CP {
11
13 {}
14
15 // Further details of the motivation for this procedure and explanations
16 // of how it works can be found in section 4 of:
17 // Eur. Phys. J. C 81 (2021) 689: https://arxiv.org/abs/2007.02645
18 //
19 //The intended result is briefly described below.
20 //CP::EM Case
21 // Subtraction applied (inDenseEnvironment==false)
22 // pt < 30 GeV: Ptrk [weight = 1]
23 // 30 <= pt < 60 GeV: Ptrk ( E/P + (1-E/P)(1 - (pt - 30)/30 ) ) [weight = E/P + (1-E/P)(1 - (pt - 30)/30 )]
24 // pt >= 60 GeV: Ptrk * E/P [weight = E/P]
25 //
26 // Subtraction not applied (inDenseEnvironment==true)
27 // pt < 30 GeV: Ptrk (1 - E/P) + Ecal [weight = (1-E/P]
28 // 30 <= pt < 60 GeV: Ptrk ( (1-E/P)(1 - (pt - 30)/30 ) ) + Ecal [weight = (1-E/P)(1 - (pt - 30)/30 )]
29 // pt >= 60 GeV: Ecal [weight = 0]
30 //
31 //CP::LC Case - this follows when you assuem E/p = 1 for the LC scale in the above formulae
32 //Subtraction applied (inDenseEnvironment==false)
33 // pt < 30 GeV: Ptrk weight = 1
34 // 30 <= pt < 60 GeV: weight = 0
35 // pt >= 60 GeV: weight = 1;
36 //
37 // Subtraction not applied (inDenseEnvironment==true)
38 // All Pt ranges: weight = 0
39
40 StatusCode WeightPFOTool::fillWeight( const xAOD::PFO& cpfo, float& weight ) const {
41
42 //we need to convert the string scale back to the enum
43 PFO_JetMETConfig_inputScale theNeutralPFOScale = CP::EM;
45 bool answer = inputScaleMapper.getValue(m_theNeutralPFOScaleString,theNeutralPFOScale);
46 if (false == answer) ATH_MSG_FATAL("Invalid neutral PFO Scale has been specified in PFlowUtils::PFOWeightTool");
47
48 // Compute the weights internally
49 weight = 0.;
50 if(cpfo.pt()>100 * GeV) {
51 ATH_MSG_WARNING("PFO with invalid pt " << cpfo.pt() << ", quitting.");
52 return StatusCode::FAILURE;
53 }
54
55 int isInDenseEnvironment = false;
56 float expectedEnergy = 0.0;
57 bool gotVariable = cpfo.attribute(xAOD::PFODetails::PFOAttributes::eflowRec_isInDenseEnvironment,isInDenseEnvironment);
58 gotVariable &= cpfo.attribute(xAOD::PFODetails::PFOAttributes::eflowRec_tracksExpectedEnergyDeposit,expectedEnergy);
59 if (!gotVariable) {
60 ATH_MSG_WARNING("This charged PFO did not have eflowRec_isInDenseEnvironment or eflowRec_tracksExpectedEnergyDeposit set");
61 return StatusCode::FAILURE;
62 } else {
63 //EM case first
64 if (CP::EM == theNeutralPFOScale){
65 // Start by computing the correction as though we subtracted the calo energy
66 // This interpolates between the full track P and the expected calo E
67 float EoverP = expectedEnergy/cpfo.e(); // divide once only
69 if(cpfo.pt()<30*GeV) { // take full track
70 weight = 1.;
71 } else if(cpfo.pt()<60*GeV) { // linearly interpolate between 1 and E/P
72 float interpolf = (1.0 - (cpfo.pt()-(30*GeV))/(30*GeV));
73 weight = EoverP + interpolf * (1-EoverP);
74 } else { // take the expected energy
75 weight = EoverP;
76 }
77 }
78
79 ATH_MSG_VERBOSE("cpfo in dense environment? " << isInDenseEnvironment);
80 ATH_MSG_VERBOSE("cpfo pt: " << cpfo.pt() << ", E/P: " << EoverP << ", weight: " << weight);
81
82 if(isInDenseEnvironment) {
83 // In this case we further remove the expected deposited energy from the track
84 weight -= EoverP;
85 }
86 }//EM Scale
87 else if (CP::LC == theNeutralPFOScale){
88 if(!isInDenseEnvironment){
89 if(cpfo.pt()<30*GeV || cpfo.pt() >= 60*GeV) weight = 1;
90 }
91 }
92 }
93
94 ATH_MSG_VERBOSE("Weight before zero check: " << weight);
95 // If the weight went to 0, set it to the ghost scale, so that the cPFOs
96 // are always added to the track.
97 if (weight<1e-9) {weight = 1e-20;}
98 ATH_MSG_VERBOSE("Final weight: " << weight);
99 return StatusCode::SUCCESS;
100 }
101
102 StatusCode WeightPFOTool::fillWeight( const xAOD::FlowElement& cpfo, float& weight ) const {
103
104 if(!(cpfo.signalType() & xAOD::FlowElement::PFlow)){
105 ATH_MSG_WARNING("FlowElement was not a PFO. Signal type was: " << cpfo.signalType());
106 return StatusCode::FAILURE;
107 }
108
109 //we need to convert the string scale back to the enum
110 PFO_JetMETConfig_inputScale theNeutralPFOScale = CP::EM;
112 bool answer = inputScaleMapper.getValue(m_theNeutralPFOScaleString,theNeutralPFOScale);
113 if (false == answer) ATH_MSG_FATAL("Invalid neutral PFO Scale has been specified in PFlowUtils::PFOWeightTool");
114
115 // Compute the weights internally
116 weight = 0.;
117 if(cpfo.pt()>100*GeV) {
118 ATH_MSG_WARNING("PFO with invalid pt " << cpfo.pt() << ", quitting.");
119 return StatusCode::FAILURE;
120 }
121
122 const static SG::ConstAccessor<int> accDenseEnv("IsInDenseEnvironment");
123 int isInDenseEnvironment = accDenseEnv(cpfo);
124
125 //EM case first
126 if (CP::EM == theNeutralPFOScale){
127 // Start by computing the correction as though we subtracted the calo energy
128 // This interpolates between the full track P and the expected calo E
130
131 ATH_MSG_VERBOSE("cpfo in dense environment? " << isInDenseEnvironment);
132
133 // In this case we further remove the expected deposited energy from the track
134 if(isInDenseEnvironment) fillDoubleCountingWeight(cpfo,weight);
135
136 }//EM Scale
137 else if (CP::LC == theNeutralPFOScale){
138 if(!isInDenseEnvironment){
139 if(cpfo.pt()<30*GeV || cpfo.pt() >= 60*GeV) weight = 1;
140 }
141 }
142
143 ATH_MSG_VERBOSE("Weight before zero check: " << weight);
144 // If the weight went to 0, set it to the ghost scale, so that the cPFOs
145 // are always added to the track.
146 if (weight<1e-9) {weight = 1e-20;}
147 ATH_MSG_VERBOSE("Final weight: " << weight);
148 return StatusCode::SUCCESS;
149 }
150
151 void WeightPFOTool::fillInterpolationWeight(const xAOD::FlowElement& cpfo, float& weight) const{
152
153 const static SG::ConstAccessor<float> accExpE("TracksExpectedEnergyDeposit");
154 float expectedEnergy = accExpE(cpfo);
155
156 float EoverP = expectedEnergy/cpfo.e();
157 if(cpfo.pt()<30*GeV) { // take full track
158 weight = 1.;
159 } else if(cpfo.pt()<60*GeV) { // linearly interpolate between 1 and E/P
160 float interpolf = (1.0 - (cpfo.pt()-(30*GeV))/(30*GeV));
161 weight = EoverP + interpolf * (1-EoverP);
162 } else { // take the expected energy
163 weight = EoverP;
164 }
165
166 ATH_MSG_VERBOSE("cpfo pt: " << cpfo.pt() << ", E/P: " << EoverP << ", weight: " << weight);
167
168 }
169
170 void WeightPFOTool::fillDoubleCountingWeight(const xAOD::FlowElement& cpfo, float& weight) const{
171
172 const static SG::ConstAccessor<float> accExpE("TracksExpectedEnergyDeposit");
173 float expectedEnergy = accExpE(cpfo);
174
175 float EoverP = expectedEnergy/cpfo.e();
176 weight -= EoverP;
177
178 }
179
180}//namespace CP
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
void fillDoubleCountingWeight(const xAOD::FlowElement &cpfo, float &weight) const
WeightPFOTool(const std::string &name)
Athena constructor.
Gaudi::Property< std::string > m_theNeutralPFOScaleString
Gaudi::Property< bool > m_doEoverPweight
void fillInterpolationWeight(const xAOD::FlowElement &cpfo, float &weight) const
StatusCode fillWeight(const xAOD::PFO &cpfo, float &weight) const
Declare the interface that the class provides.
Helper class to provide constant type-safe access to aux data.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
virtual double pt() const override
signal_t signalType() const
virtual double e() const override
The total energy of the particle.
bool attribute(PFODetails::PFOAttributes AttributeType, T &anAttribute) const
get a PFO Variable via enum
virtual double e() const
The total energy of the particle.
Definition PFO_v1.cxx:81
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition PFO_v1.cxx:52
Select isolated Photons, Electrons and Muons.
PFO_v1 PFO
Definition of the current "pfo version".
Definition PFO.h:17
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16
bool getValue(const std::string &nameToMapFrom, PFO_JetMETConfig_inputScale &inputScaleToMapTo)