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