Project
Loading...
Searching...
No Matches
NonlinearityHandler.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#include <algorithm>
12#include <iostream>
13#include <cmath>
14#include <TMath.h> // for TMath::Pi() - to be removed once we switch to c++20
16
17using namespace o2::emcal;
18
19NonlinearityHandler::NonlinearityHandler(NonlinType_t nonlintype) : mNonlinearyFunction(nonlintype)
20{
21 initParams();
22}
23
24void NonlinearityHandler::initParams()
25{
26 std::fill(mNonlinearityParam.begin(), mNonlinearityParam.end(), 0);
27 switch (mNonlinearyFunction) {
29 mNonlinearityParam[0] = 1.09357;
30 mNonlinearityParam[1] = 0.0192266;
31 mNonlinearityParam[2] = 0.291993;
32 mNonlinearityParam[3] = 370.927;
33 mNonlinearityParam[4] = 694.656;
34 break;
36 mNonlinearityParam[0] = 1.014;
37 mNonlinearityParam[1] = -0.03329;
38 mNonlinearityParam[2] = -0.3853;
39 mNonlinearityParam[3] = 0.5423;
40 mNonlinearityParam[4] = -0.4335;
41 break;
43 mNonlinearityParam[0] = 3.11111e-02;
44 mNonlinearityParam[1] = -5.71666e-02;
45 mNonlinearityParam[2] = 5.67995e-01;
46 break;
48 mNonlinearityParam[0] = 9.81039e-01;
49 mNonlinearityParam[1] = 1.13508e-01;
50 mNonlinearityParam[2] = 1.00173e+00;
51 mNonlinearityParam[3] = 9.67998e-02;
52 mNonlinearityParam[4] = 2.19381e+02;
53 mNonlinearityParam[5] = 6.31604e+01;
54 mNonlinearityParam[6] = 1;
55 break;
57 mNonlinearityParam[0] = 1.0;
58 mNonlinearityParam[1] = 6.64778e-02;
59 mNonlinearityParam[2] = 1.570;
60 mNonlinearityParam[3] = 9.67998e-02;
61 mNonlinearityParam[4] = 2.19381e+02;
62 mNonlinearityParam[5] = 6.31604e+01;
63 mNonlinearityParam[6] = 1.01286;
64 break;
66 mNonlinearityParam[0] = 1.0;
67 mNonlinearityParam[1] = 0.0797873;
68 mNonlinearityParam[2] = 1.68322;
69 mNonlinearityParam[3] = 0.0806098;
70 mNonlinearityParam[4] = 244.586;
71 mNonlinearityParam[5] = 116.938;
72 mNonlinearityParam[6] = 1.00437;
73 break;
75 mNonlinearityParam[0] = 0.99078;
76 mNonlinearityParam[1] = 0.161499;
77 mNonlinearityParam[2] = 0.655166;
78 mNonlinearityParam[3] = 0.134101;
79 mNonlinearityParam[4] = 163.282;
80 mNonlinearityParam[5] = 23.6904;
81 mNonlinearityParam[6] = 0.978;
82 break;
84 // Parameters until November 2015, use now kBeamTestCorrectedv3
85 mNonlinearityParam[0] = 0.983504;
86 mNonlinearityParam[1] = 0.210106;
87 mNonlinearityParam[2] = 0.897274;
88 mNonlinearityParam[3] = 0.0829064;
89 mNonlinearityParam[4] = 152.299;
90 mNonlinearityParam[5] = 31.5028;
91 mNonlinearityParam[6] = 0.968;
92 break;
94 // New parametrization of kBeamTestCorrected
95 // excluding point at 0.5 GeV from Beam Test Data
96 // https://indico.cern.ch/event/438805/contribution/1/attachments/1145354/1641875/emcalPi027August2015.pdf
97
98 mNonlinearityParam[0] = 0.976941;
99 mNonlinearityParam[1] = 0.162310;
100 mNonlinearityParam[2] = 1.08689;
101 mNonlinearityParam[3] = 0.0819592;
102 mNonlinearityParam[4] = 152.338;
103 mNonlinearityParam[5] = 30.9594;
104 mNonlinearityParam[6] = 0.9615;
105 break;
106
108 // New parametrization of kBeamTestCorrected,
109 // fitting new points for E>100 GeV.
110 // I should have same performance as v3 in the low energies
111 // See EMCal meeting 21/09/2018 slides
112 // https://indico.cern.ch/event/759154/contributions/3148448/attachments/1721042/2778585/nonLinearityUpdate.pdf
113 // and jira ticket EMCAL-190
114
115 mNonlinearityParam[0] = 0.9892;
116 mNonlinearityParam[1] = 0.1976;
117 mNonlinearityParam[2] = 0.865;
118 mNonlinearityParam[3] = 0.06775;
119 mNonlinearityParam[4] = 156.6;
120 mNonlinearityParam[5] = 47.18;
121 mNonlinearityParam[6] = 0.97;
122 break;
123
126 mNonlinearityParam[0] = 1.91897;
127 mNonlinearityParam[1] = 0.0264988;
128 mNonlinearityParam[2] = 0.965663;
129 mNonlinearityParam[3] = -187.501;
130 mNonlinearityParam[4] = 2762.51;
131 break;
132
133 default:
134 break;
135 }
136 if (mNonlinearyFunction == NonlinType_t::DATA_TESTBEAM_SHAPER) {
137 mApplyScaleCorrection = true;
138 }
139}
141{
142 double correctedEnergy = energy;
143 switch (mNonlinearyFunction) {
145 correctedEnergy = evaluatePi0MC(energy);
146 break;
148 correctedEnergy = evaluatePi0MCv2(energy);
156 correctedEnergy = evaluateTestbeamCorrected(energy);
157 break;
161 correctedEnergy = evaluateTestbeamShaper(energy);
162 break;
163 default:
164 throw UninitException();
165 }
166 if (mApplyScaleCorrection) {
167 correctedEnergy /= 1.0505;
168 }
169 return correctedEnergy;
170}
171
172double NonlinearityHandler::evaluateTestbeamShaper(double energy) const
173{
174 return energy / (1.00 * (mNonlinearityParam[0] + mNonlinearityParam[1] * std::log(energy)) / (1 + (mNonlinearityParam[2] * std::exp((energy - mNonlinearityParam[3]) / mNonlinearityParam[4]))));
175}
176
177double NonlinearityHandler::evaluateTestbeamCorrected(double energy) const
178{
179 return energy * mNonlinearityParam[6] / (mNonlinearityParam[0] * (1. / (1. + mNonlinearityParam[1] * std::exp(-energy / mNonlinearityParam[2])) * 1. / (1. + mNonlinearityParam[3] * std::exp((energy - mNonlinearityParam[4]) / mNonlinearityParam[5]))));
180}
181
182double NonlinearityHandler::evaluatePi0MC(double energy) const
183{
184 return energy * (mNonlinearityParam[0] * std::exp(-mNonlinearityParam[1] / energy)) +
185 ((mNonlinearityParam[2] / (mNonlinearityParam[3] * 2. * TMath::Pi()) *
186 std::exp(-(energy - mNonlinearityParam[4]) * (energy - mNonlinearityParam[4]) / (2. * mNonlinearityParam[3] * mNonlinearityParam[3]))));
187}
188
189double NonlinearityHandler::evaluatePi0MCv2(double energy) const
190{
191 return energy * mNonlinearityParam[0] / TMath::Power(energy + mNonlinearityParam[1], mNonlinearityParam[2]) + 1;
192}
193
195{
196 if (energy < 40) {
197 return energy * 16.3 / 16;
198 }
199 constexpr std::array<double, 8> par = {{1, 29.8279, 0.607704, 0.00164896, -2.28595e-06, -8.54664e-10, 5.50191e-12, -3.28098e-15}};
200 double x = par[0] * energy / ecalibHG / 16 / 0.0162;
201
202 double res = par[1];
203 res += par[2] * x;
204 res += par[3] * x * x;
205 res += par[4] * x * x * x;
206 res += par[5] * x * x * x * x;
207 res += par[6] * x * x * x * x * x;
208 res += par[7] * x * x * x * x * x * x;
209
210 return ecalibHG * 16.3 * res * 0.0162;
211}
212
214{
215 stream << "Nonlinearity function: " << getNonlinName(mNonlinearyFunction)
216 << "(Parameters:";
217 bool first = true;
218 for (auto& param : mNonlinearityParam) {
219 if (first) {
220 first = false;
221 } else {
222 stream << ",";
223 }
224 stream << " " << param;
225 }
226 stream << ")";
227}
228
230{
232 if (name == "MC_Pi0") {
233 return NLType::MC_PI0;
234 }
235 if (name == "MC_Pi0_v2") {
236 return NLType::MC_PI0_V2;
237 }
238 if (name == "MC_Pi0_v3") {
239 return NLType::MC_PI0_V3;
240 }
241 if (name == "MC_Pi0_v5") {
242 return NLType::MC_PI0_V5;
243 }
244 if (name == "MC_Pi0_v6") {
245 return NLType::MC_PI0_V6;
246 }
247 if (name == "MC_TestbeamFinal") {
248 return NLType::MC_TESTBEAM_FINAL;
249 }
250 if (name == "DATA_BeamTestCorrected") {
251 return NLType::DATA_TESTBEAM_CORRECTED;
252 }
253 if (name == "DATA_BeamTestCorrected_v2") {
254 return NLType::DATA_TESTBEAM_CORRECTED_V2;
255 }
256 if (name == "DATA_BeamTestCorrected_v3") {
257 return NLType::DATA_TESTBEAM_CORRECTED_V3;
258 }
259 if (name == "DATA_BeamTestCorrected_v4") {
260 return NLType::DATA_TESTBEAM_CORRECTED_V4;
261 }
262 if (name == "DATA_TestbeamFinal") {
263 return NLType::DATA_TESTBEAM_SHAPER;
264 }
265 if (name == "DATA_TestbeamFinal_NoScale") {
266 return NLType::DATA_TESTBEAM_SHAPER_WOSCALE;
267 }
268 return NLType::UNKNOWN;
269}
270
272{
274 switch (nonlin) {
275 case NLType::MC_PI0:
276 return "MC_Pi0";
277 case NLType::MC_PI0_V2:
278 return "MC_Pi0_v2";
279 case NLType::MC_PI0_V3:
280 return "MC_Pi0_v3";
281 case NLType::MC_PI0_V5:
282 return "MC_Pi0_v5";
283 case NLType::MC_PI0_V6:
284 return "MC_Pi0_v6";
285 case NLType::MC_TESTBEAM_FINAL:
286 return "MC_TestbeamFinal";
287 case NLType::DATA_TESTBEAM_CORRECTED:
288 return "DATA_BeamTestCorrected";
289 case NLType::DATA_TESTBEAM_CORRECTED_V2:
290 return "DATA_BeamTestCorrected_v2";
291 case NLType::DATA_TESTBEAM_CORRECTED_V3:
292 return "DATA_BeamTestCorrected_v3";
293 case NLType::DATA_TESTBEAM_CORRECTED_V4:
294 return "DATA_BeamTestCorrected_v4";
295 case NLType::DATA_TESTBEAM_SHAPER:
296 return "DATA_TestbeamFinal";
297 case NLType::DATA_TESTBEAM_SHAPER_WOSCALE:
298 return "DATA_TestbeamFinal_NoScale";
299 case NLType::UNKNOWN:
300 return "Unknown";
301 default:
302 return "";
303 }
304}
305
307{
308 auto found = mHandlers.find(nonlintype);
309 if (found != mHandlers.end()) {
310 return found->second;
311 }
312 auto [insert_result, insert_status] = mHandlers.try_emplace(nonlintype, NonlinearityHandler(nonlintype));
313 if (insert_status) {
314 return insert_result->second;
315 }
316 throw NonlinInitError();
317}
318
320{
321 return getNonlinearity(getNonlinType(nonname));
322}
323
324NonlinearityHandler::NonlinType_t NonlinearityFactory::getNonlinType(const std::string_view nonlinName) const
325{
326 auto found = mNonlinNames.find(static_cast<std::string>(nonlinName));
327 if (found != mNonlinNames.end()) {
328 return found->second;
329 }
331}
332
333void NonlinearityFactory::initNonlinNames()
334{
336 constexpr std::array<NLType, 12> nonlintypes = {{NLType::MC_PI0,
337 NLType::MC_PI0_V2,
338 NLType::MC_PI0_V3,
339 NLType::MC_PI0_V5,
340 NLType::MC_PI0_V6,
341 NLType::MC_TESTBEAM_FINAL,
342 NLType::DATA_TESTBEAM_CORRECTED,
343 NLType::DATA_TESTBEAM_CORRECTED_V2,
344 NLType::DATA_TESTBEAM_CORRECTED_V3,
345 NLType::DATA_TESTBEAM_CORRECTED_V4,
346 NLType::DATA_TESTBEAM_SHAPER,
347 NLType::DATA_TESTBEAM_SHAPER_WOSCALE
348
349 }};
350 for (auto nonlin : nonlintypes) {
351 mNonlinNames[NonlinearityHandler::getNonlinName(nonlin)] = nonlin;
352 }
353}
354
355std::ostream& o2::emcal::operator<<(std::ostream& in, const NonlinearityHandler& handler)
356{
357 handler.printStream(in);
358 return in;
359}
uint32_t res
Definition RawData.h:0
Handling request of non-exisiting nonlinearity functions.
Handling errors of initialisation of a certain nonlinearity function.
NonlinearityHandler & getNonlinearity(NonlinearityHandler::NonlinType_t nonlintype)
Get nonlinearity handler for the given nonlinearty type.
Handling missing initialisation of the NonlinearityHanlder.
Nonlinearity functions for energy correction.
NonlinType_t
Types of nonlinearity functions available.
@ MC_PI0
MC, function corresponding to inital testbeam nonlin without shaper correction.
@ MC_PI0_V5
MC, function corresponding to inital testbeam nonlin without shaper correction, version 5.
@ DATA_TESTBEAM_SHAPER_WOSCALE
Data, testbeam nonlin for shaper correction, without energy rescaling.
@ DATA_TESTBEAM_CORRECTED_V4
Data, inital testbeam nonlin without shaper correction, version 4.
@ MC_PI0_V6
MC, function corresponding to inital testbeam nonlin without shaper correction, version 6.
@ MC_TESTBEAM_FINAL
MC, function corresponding to data testbeam nonlin for shaper correction, with energy rescaling.
@ MC_PI0_V3
MC, function corresponding to inital testbeam nonlin without shaper correction, version 3.
@ DATA_TESTBEAM_CORRECTED
Data, inital testbeam nonlin without shaper correction.
@ DATA_TESTBEAM_CORRECTED_V3
Data, inital testbeam nonlin without shaper correction, version 3.
@ DATA_TESTBEAM_CORRECTED_V2
Data, inital testbeam nonlin without shaper correction, version 2.
@ DATA_TESTBEAM_SHAPER
Data, testbeam nonlin for shaper correction, with energy rescaling.
@ MC_PI0_V2
MC, function corresponding to inital testbeam nonlin without shaper correction, version 2.
double getCorrectedClusterEnergy(double energy) const
Get corrected cluster energy for the selected nonlinearity parameterization.
static double evaluateShaperCorrectionCellEnergy(double energy, double ecalibHG=1)
Get corrected energy at cell level for the shaper saturation at high energy.
static NonlinType_t getNonlinType(const std::string_view name)
Get type of a nonlinearity function from its name.
NonlinearityHandler()=default
Dummy constructor.
void printStream(std::ostream &stream) const
Print information about the nonlinearity function.
static const char * getNonlinName(NonlinType_t nonlin)
Get name of the nonlinearity function from the function type.
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint const GLchar * name
Definition glcorearb.h:781
GLenum GLfloat param
Definition glcorearb.h:271
GLuint GLuint stream
Definition glcorearb.h:1806
std::ostream & operator<<(std::ostream &stream, const Cell &cell)
Stream operator for EMCAL cell.
Definition Cell.cxx:355