ATLAS Offline Software
Loading...
Searching...
No Matches
ZdcAnalysisTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "TGraph.h"
7#include "TEnv.h"
8#include "TSystem.h"
11#include "TFile.h"
12#include <sstream>
13#include <memory>
21#include <fstream>
22#include <nlohmann/json.hpp>
23
24namespace ZDC
25{
26ZdcAnalysisTool::ZdcAnalysisTool(const std::string& name)
27 : asg::AsgTool(name), m_name(name), m_init(false),
28 m_writeAux(false), m_eventReady(false),
31{
32
33#ifndef XAOD_STANDALONE
34 declareInterface<IZdcAnalysisTool>(this);
35#endif
36
37 declareProperty("ZdcModuleContainerName", m_zdcModuleContainerName = "ZdcModules", "Location of ZDC processed data");
38 declareProperty("ZdcSumContainerName", m_zdcSumContainerName = "ZdcSums", "Location of ZDC processed sums");
39 declareProperty("JSONConfigurationFile",m_jsonConfigurationFile = "ZdcAnalysisConfig.json" );
40 declareProperty("Configuration", m_configuration = "PbPb2015");
41 declareProperty("FlipEMDelay", m_flipEMDelay = false);
42 declareProperty("LowGainMode", m_lowGainMode = 0);
43 declareProperty("WriteAux", m_writeAux = true);
44 declareProperty("AuxSuffix", m_auxSuffix = "");
45
46 // The following job properties enable/disable and affect the calibration of the ZDC energies
47 //
48 declareProperty("DoCalib", m_doCalib = true);
49 declareProperty("CalibVersion", m_calibVersion = "");
50 declareProperty("DoTrigEff", m_doTrigEff = true);
51 declareProperty("DoTimeCalib", m_doTimeCalib = true);
52 declareProperty("ZdcAnalysisConfigPath", m_zdcAnalysisConfigPath = "$ROOTCOREBIN/data/ZdcAnalysis", "ZDC Analysis config file path");
53 //declareProperty("ForceCalibRun",m_forceCalibRun=287931); // last run of Pb+Pb 2015
54 declareProperty("ForceCalibRun", m_forceCalibRun = -1); // last run of Pb+Pb 2015
55 declareProperty("ForceCalibLB", m_forceCalibLB = 814); // last LB of Pb+Pb 2015
56
57 declareProperty("DoNonLinCorr", m_doNonLinCorr = true); // how we have run with 2023 and most of 2024
58 declareProperty("DoFADCCorr", m_doFADCCorr = false);
59 declareProperty("DoFADCCorrPerSample", m_doFADCCorrPerSample = false);
60
61 // The following parameters are primarily used for the "default" configuration, but also may be
62 // use to modify/tailor other configurations
63 //
64 declareProperty("NumSampl", m_numSample = 7);
65 declareProperty("DeltaTSample", m_deltaTSample = 25);
66 declareProperty("Presample", m_presample = 0);
67 declareProperty("CombineDelay", m_combineDelay = false);
68 declareProperty("DelayDeltaT", m_delayDeltaT = -12.5);
69
70 declareProperty("PeakSample", m_peakSample = 11);
71 declareProperty("Peak2ndDerivThresh", m_Peak2ndDerivThresh = 20);
72
73 declareProperty("T0", m_t0 = 30);
74 declareProperty("Tau1", m_tau1 = 5);
75 declareProperty("Tau2", m_tau2 = 25);
76 declareProperty("FixTau1", m_fixTau1 = false);
77 declareProperty("FixTau2", m_fixTau2 = false);
78
79 declareProperty("DeltaTCut", m_deltaTCut = 10);
80 declareProperty("ChisqRatioCut", m_ChisqRatioCut = 10);
81
82 declareProperty("LHCRun", m_LHCRun = 3);
83
84}
85
87{
88 ATH_MSG_DEBUG("Deleting ZdcAnalysisTool named " << m_name);
89}
90
91void ZdcAnalysisTool::initializeTriggerEffs(unsigned int runNumber)
92{
93 if (!m_doTrigEff) return;
94
96 {
97 ATH_MSG_DEBUG("Creating new ZDCTriggerEfficiency");
99 }
100
101 std::string filename = PathResolverFindCalibFile( ("ZdcAnalysis/" + m_zdcTriggerEffParamsFileName) );
102 ATH_MSG_DEBUG ("Found trigger config file " << filename);
103 ATH_MSG_DEBUG("Opening trigger efficiency file " << filename);
104
105 std::unique_ptr<TFile> file (TFile::Open(filename.c_str(), "READ"));
106 if (file == nullptr || file->IsZombie())
107 {
108 ATH_MSG_WARNING("No trigger efficiencies at " << filename);
109 return;
110 }
111
112 //file->Print();
113
114 ATH_MSG_DEBUG("Reading in trigger efficiencies");
115
116 std::stringstream Aalpha_name;
117 Aalpha_name << "A_alpha_" << runNumber;
118 TSpline3* par_A_alpha = (TSpline3*)file->GetObjectChecked(Aalpha_name.str().c_str(), "TSpline3");
119
120 if (!par_A_alpha)
121 {
122 ATH_MSG_WARNING("No trigger efficiencies for run number " << runNumber);
123 m_doCalib = false;
124 }
125
126 std::stringstream Abeta_name;
127 Abeta_name << "A_beta_" << runNumber;
128 TSpline3* par_A_beta = (TSpline3*)file->GetObjectChecked(Abeta_name.str().c_str(), "TSpline3");
129 std::stringstream Atheta_name;
130 Atheta_name << "A_theta_" << runNumber;
131 TSpline3* par_A_theta = (TSpline3*)file->GetObjectChecked(Atheta_name.str().c_str(), "TSpline3");
132
133 std::stringstream Calpha_name;
134 Calpha_name << "C_alpha_" << runNumber;
135 TSpline3* par_C_alpha = (TSpline3*)file->GetObjectChecked(Calpha_name.str().c_str(), "TSpline3");
136 std::stringstream Cbeta_name;
137 Cbeta_name << "C_beta_" << runNumber;
138 TSpline3* par_C_beta = (TSpline3*)file->GetObjectChecked(Cbeta_name.str().c_str(), "TSpline3");
139 std::stringstream Ctheta_name;
140 Ctheta_name << "C_theta_" << runNumber;
141 TSpline3* par_C_theta = (TSpline3*)file->GetObjectChecked(Ctheta_name.str().c_str(), "TSpline3");
142
143 std::stringstream Err_Aalpha_name;
144 Err_Aalpha_name << "A_alpha_error_" << runNumber;
145 TSpline3* parErr_A_alpha = (TSpline3*)file->GetObjectChecked(Err_Aalpha_name.str().c_str(), "TSpline3");
146 std::stringstream Err_Abeta_name;
147 Err_Abeta_name << "A_beta_error_" << runNumber;
148 TSpline3* parErr_A_beta = (TSpline3*)file->GetObjectChecked(Err_Abeta_name.str().c_str(), "TSpline3");
149 std::stringstream Err_Atheta_name;
150 Err_Atheta_name << "A_theta_error_" << runNumber;
151 TSpline3* parErr_A_theta = (TSpline3*)file->GetObjectChecked(Err_Atheta_name.str().c_str(), "TSpline3");
152
153 std::stringstream Err_Calpha_name;
154 Err_Calpha_name << "C_alpha_error_" << runNumber;
155 TSpline3* parErr_C_alpha = (TSpline3*)file->GetObjectChecked(Err_Calpha_name.str().c_str(), "TSpline3");
156 std::stringstream Err_Cbeta_name;
157 Err_Cbeta_name << "C_beta_error_" << runNumber;
158 TSpline3* parErr_C_beta = (TSpline3*)file->GetObjectChecked(Err_Cbeta_name.str().c_str(), "TSpline3");
159 std::stringstream Err_Ctheta_name;
160 Err_Ctheta_name << "C_theta_error_" << runNumber;
161 TSpline3* parErr_C_theta = (TSpline3*)file->GetObjectChecked(Err_Ctheta_name.str().c_str(), "TSpline3");
162
163
164 std::stringstream Cov_A_alpha_beta_name;
165 Cov_A_alpha_beta_name << "cov_A_alpha_beta_" << runNumber;
166 TSpline3* cov_A_alpha_beta = (TSpline3*)file->GetObjectChecked(Cov_A_alpha_beta_name.str().c_str(), "TSpline3");
167 std::stringstream Cov_A_alpha_theta_name;
168 Cov_A_alpha_theta_name << "cov_A_alpha_theta_" << runNumber;
169 TSpline3* cov_A_alpha_theta = (TSpline3*)file->GetObjectChecked(Cov_A_alpha_theta_name.str().c_str(), "TSpline3");
170 std::stringstream Cov_A_beta_theta_name;
171 Cov_A_beta_theta_name << "cov_A_beta_theta_" << runNumber;
172 TSpline3* cov_A_beta_theta = (TSpline3*)file->GetObjectChecked(Cov_A_beta_theta_name.str().c_str(), "TSpline3");
173
174 std::stringstream Cov_C_alpha_beta_name;
175 Cov_C_alpha_beta_name << "cov_C_alpha_beta_" << runNumber;
176 TSpline3* cov_C_alpha_beta = (TSpline3*)file->GetObjectChecked(Cov_C_alpha_beta_name.str().c_str(), "TSpline3");
177 std::stringstream Cov_C_alpha_theta_name;
178 Cov_C_alpha_theta_name << "cov_C_alpha_theta_" << runNumber;
179 TSpline3* cov_C_alpha_theta = (TSpline3*)file->GetObjectChecked(Cov_C_alpha_theta_name.str().c_str(), "TSpline3");
180 std::stringstream Cov_C_beta_theta_name;
181 Cov_C_beta_theta_name << "cov_C_beta_theta_" << runNumber;
182 TSpline3* cov_C_beta_theta = (TSpline3*)file->GetObjectChecked(Cov_C_beta_theta_name.str().c_str(), "TSpline3");
183
184 std::array<std::vector<TSpline3*>, 2> effparams;
185 std::array<std::vector<TSpline3*>, 2> effparamErrors;
186 std::array<std::vector<TSpline3*>, 2> effparamsCorrCoeffs;
187 //side0: C; side1: A
188 effparams[0] = {par_C_alpha, par_C_beta, par_C_theta};
189 effparams[1] = {par_A_alpha, par_A_beta, par_A_theta};
190 effparamErrors[0] = {parErr_C_alpha, parErr_C_beta, parErr_C_theta};
191 effparamErrors[1] = {parErr_A_alpha, parErr_A_beta, parErr_A_theta};
192 effparamsCorrCoeffs[0] = {cov_C_alpha_beta, cov_C_alpha_theta, cov_C_beta_theta};
193 effparamsCorrCoeffs[1] = {cov_A_alpha_beta, cov_A_alpha_theta, cov_A_beta_theta};
194
195 ATH_MSG_DEBUG("Trying to set parameters and errors at " << m_zdcTriggerEfficiency);
196
197 m_zdcTriggerEfficiency->SetEffParamsAndErrors(effparams, effparamErrors);
198 m_zdcTriggerEfficiency->SetEffParamCorrCoeffs(effparamsCorrCoeffs);
199
200 return;
201
202}
203
204std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeFromJSON()
205{
206 std::string fullPath="ZdcAnalysis/"+m_jsonConfigurationFile;
207 std::string filePath = PathResolverFindCalibFile( fullPath );
208 std::ifstream ifs(filePath);
209 nlohmann::json jsonConfig;
210 if (ifs.is_open())
211 {
212 ifs >> jsonConfig;
213 ATH_MSG_INFO("Loaded ZDC JSON from file " << filePath);
214 ATH_MSG_DEBUG("JSON config dump: " << jsonConfig.dump());
215 }
216 else
217 ATH_MSG_ERROR("No ZDC JSON found at " << filePath);
218
219
220 //std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer(new ZDCDataAnalyzer(MakeMessageFunction(),jsonConfig["ZDC"]));
221 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer = std::make_unique<ZDCDataAnalyzer>(MakeMessageFunction(),jsonConfig["ZDC"]);
222
223 return zdcDataAnalyzer;
224}
225
226std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeLHCf2022()
227{
228
229 m_deltaTSample = 3.125;
230 m_numSample = 24;
231
232 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples = {{{0, 9, 9, 9}, {0, 9, 10, 8}}};
233
234 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
235 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow{}, deltaT0CutHigh{}, chisqDivAmpCut{};
236 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
237
238 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{0, 1.1, 1.1, 1.1},
239 {0, 1.1, 1.1, 1.1}}};
240
241 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{6, 5, 5, 5}, {5.5, 5.5, 5.5, 5.5}}};
242
243 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{0, 26.3, 26.5, 26.8}, {32, 32, 32, 32}}};
244
245 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{0, 31.1, 28.1, 27.0}, {0, 26.6, 26.3, 25.3}}};
246
247 for (size_t side : {0, 1}) {
248 for (size_t module : {0, 1, 2, 3}) {
249 fixTau1Arr[side][module] = true;
250 fixTau2Arr[side][module] = false;
251
252 peak2ndDerivMinThresholdsHG[side][module] = -35;
253 peak2ndDerivMinThresholdsLG[side][module] = -16;
254
255 deltaT0CutLow[side][module] = -10;
256 deltaT0CutHigh[side][module] = 10;
257 chisqDivAmpCut[side][module] = 20;
258 }
259 }
260
261 ATH_MSG_DEBUG( "LHCF2022: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
262
263 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
264 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
265 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
266
267 // For the LHCf run, use low gain samples
268 //
270
271 // Construct the data analyzer
272 //
273 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
275 m_presample, "FermiExpLHCf",
276 peak2ndDerivMinSamples,
277 peak2ndDerivMinThresholdsHG,
278 peak2ndDerivMinThresholdsLG,
279 m_lowGainMode));
280
281 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(2);
282 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
283 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
284 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
285
286 zdcDataAnalyzer->SetGainFactorsHGLG(0.1, 1); // a gain adjustment of unity applied to LG ADC, 0.1 to HG ADC values
287
288 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{2, 2, 2, 2}, {2, 2, 2, 2}}};
289 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{20, 20, 20, 20}, {20, 20, 20, 20}}};
290
291 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
292
293 // Enable two-pass analysis
294 //
295 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-12, -12, -12, -12},
296 {-12, -12, -12, -12}}};
297
298 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
299 {-8, -8, -8, -8}}};
300
301 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
302
303 // Set the amplitude fit range limits
304 //
305 zdcDataAnalyzer->SetFitMinMaxAmpValues(5, 2, 5000, 5000);
306
307 // disable EM module on each side
308 zdcDataAnalyzer->disableModule(0, 0);
309 zdcDataAnalyzer->disableModule(1, 0);
310
311 return zdcDataAnalyzer;
312
313}
314
315std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializepp2023()
316{
317
318 m_deltaTSample = 3.125;
319 m_numSample = 24;
321
322 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples = {{{12, 12, 12, 12}, {12, 12, 12, 12}}};
323
324 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
325 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow{}, deltaT0CutHigh{}, chisqDivAmpCut{};
326 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
327
328 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.1, 1.1, 1.1, 1.1},
329 {1.1, 1.1, 1.1, 1.1}}};
330
331 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{5.5, 5.5, 5.5, 5.5}, {5.5, 5.5, 5.5, 5.5}}};
332
333 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{36, 36, 36, 36}, {36, 36, 36, 36}}};
334
335 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{36, 36, 36, 36}, {36, 36, 36, 36}}};
336
337 const int deriv2ndThreshDSHG = -35;
338 const int deriv2ndThreshDSLG = -10;
339
340 const float deltaTcutLow = -10;
341 const float deltaTcutHigh = 10;
342 const float chisqDivAmpCutVal = 10;
343
344 for (size_t side : {0, 1}) {
345 for (size_t module : {0, 1, 2, 3}) {
346 fixTau1Arr[side][module] = true;
347 fixTau2Arr[side][module] = false;
348
349 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
350 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
351
352 deltaT0CutLow[side][module] = deltaTcutLow;
353 deltaT0CutHigh[side][module] = deltaTcutHigh;
354 chisqDivAmpCut[side][module] = chisqDivAmpCutVal;
355 }
356 }
357
358 ATH_MSG_DEBUG( "pp2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
359
360 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
361 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
362 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
363
364 // Construct the data analyzer
365 //
366 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
368 m_presample, "FermiExpLHCf",
369 peak2ndDerivMinSamples,
370 peak2ndDerivMinThresholdsHG,
371 peak2ndDerivMinThresholdsLG,
372 m_lowGainMode));
373
374 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
375 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
376 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
377 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
378
379 zdcDataAnalyzer->SetGainFactorsHGLG(1, 10); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
380
381 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{0.5, 0.5, 0.5, 0.5}, {0.5, 0.5, 0.5, 0.5}}};
382 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{2, 2, 2, 2}, {2, 2, 2, 2}}};
383
384 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
385
386 // Enable two-pass analysis
387 //
388 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-12, -12, -12, -12},
389 {-12, -12, -12, -12}}};
390
391 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
392 {-8, -8, -8, -8}}};
393
394 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
395
396 // Set the amplitude fit range limits
397 //
398 zdcDataAnalyzer->SetFitMinMaxAmpValues(5, 2, 5000, 5000);
399
400 return zdcDataAnalyzer;
401
402}
403
404std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializepp2024()
405{
406
407 m_deltaTSample = 3.125;
408 m_numSample = 24;
410
411 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples = {{{12, 12, 12, 12}, {12, 12, 12, 12}}};
412
413 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
414 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh, chisqDivAmpCut;
415 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
416
417 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.1, 1.1, 1.1, 1.1},
418 {1.1, 1.1, 1.1, 1.1}}};
419
420 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{5.5, 5.5, 5.5, 5.5}, {5.5, 5.5, 5.5, 5.5}}};
421
422 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{36, 36, 36, 36}, {36, 36, 36, 36}}};
423
424 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{36, 36, 36, 36}, {36, 36, 36, 36}}};
425
426 const int deriv2ndThreshDSHG = -35;
427 const int deriv2ndThreshDSLG = -10;
428
429 const float deltaTcutLow = -10;
430 const float deltaTcutHigh = 10;
431 const float chisqDivAmpCutVal = 100;
432
433 for (size_t side : {0, 1}) {
434 for (size_t module : {0, 1, 2, 3}) {
435 fixTau1Arr[side][module] = true;
436 fixTau2Arr[side][module] = false;
437
438 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
439 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
440
441 deltaT0CutLow[side][module] = deltaTcutLow;
442 deltaT0CutHigh[side][module] = deltaTcutHigh;
443 chisqDivAmpCut[side][module] = chisqDivAmpCutVal;
444 }
445 }
446
447 ATH_MSG_DEBUG( "pp2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
448
449 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
450 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
451 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
452
453 // Construct the data analyzer
454 //
455 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
457 m_presample, "FermiExpLHCf",
458 peak2ndDerivMinSamples,
459 peak2ndDerivMinThresholdsHG,
460 peak2ndDerivMinThresholdsLG,
461 m_lowGainMode));
462
463 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
464 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
465 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
466 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
467
468 zdcDataAnalyzer->SetGainFactorsHGLG(1, 1); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
469
470 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{0.5, 0.5, 0.5, 0.5}, {0.5, 0.5, 0.5, 0.5}}};
471 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{2, 2, 2, 2}, {2, 2, 2, 2}}};
472
473 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
474
475 // Enable two-pass analysis
476 //
477 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-12, -12, -12, -12},
478 {-12, -12, -12, -12}}};
479
480 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
481 {-8, -8, -8, -8}}};
482
483 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
484
485 // Set the amplitude fit range limits
486 //
487 zdcDataAnalyzer->SetFitMinMaxAmpValues(5, 2, 5000, 5000);
488
489 return zdcDataAnalyzer;
490
491}
492
493std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializePbPb2023()
494{
495 // Key configuration parameters needed for the data analyzer construction
496 //
497 m_deltaTSample = 3.125;
498 m_numSample = 24;
499
500 const int deriv2ndThreshDSHG = -25;
501 const int deriv2ndThreshDSLG = -10;
502 const unsigned int peakSample = 10;
503
504 const float deltaTcutLow = -10;
505 const float deltaTcutHigh = 10;
506 const float chisqDivAmpCutHGVal = 30;
507 const float chisqDivAmpCutLGVal = 50;
508
509 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
510 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
511
512 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow{}, deltaT0CutHigh{};
513 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG{}, chisqDivAmpCutLG{};
514 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
515
516 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
517 {1.35, 1.4, 1.3, 1.1}}};
518
519 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
520
521 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.25, 31.25, 31.25, 31.25}, {31.25, 31.25, 31.25, 31.25}}};
522 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{28, 28, 28, 28}, {28, 28, 28, 28}}};
523
524 for (size_t side : {0, 1}) {
525 for (size_t module : {0, 1, 2, 3}) {
526 fixTau1Arr[side][module] = true;
527 fixTau2Arr[side][module] = false;
528
529 peak2ndDerivMinSamples[side][module] = peakSample;
530 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
531 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
532
533 deltaT0CutLow[side][module] = deltaTcutLow;
534 deltaT0CutHigh[side][module] = deltaTcutHigh;
535 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
536 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
537 }
538 }
539
540 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
541
542 // Construct the data analyzer
543 //
544 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
546 m_presample, "FermiExpLHCf",
547 peak2ndDerivMinSamples,
548 peak2ndDerivMinThresholdsHG,
549 peak2ndDerivMinThresholdsLG,
551 zdcDataAnalyzer->set2ndDerivStep(2);
552 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
553
554 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1.042, 1.078, 1.008, 1.066},{1.047, 1.060, 1.010, 0.99}}};
555 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
556
557 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
558
559 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
560 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
561 //
562 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
563 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{1.5, 1.7, 3, 1.7}, {1.7, 1.6, 2.2, 1.8}}};
564
565 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
566
567 // Now set cuts and default fit parameters
568 //
569 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
570 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
571 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
572
573 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
574 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
575 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
576
577 // Enable two-pass analysis
578 //
579 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-20, -20, -20, -20},
580 {-20, -20, -20, -20},}};
581
582 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
583 {-8, -8, -8, -8}}};
584
585 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
586
587 // Turn on exclusion of early and late samples to address OOT pileup
588 //
589 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
590 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
591
592 // Set up non-linear corrections for the ZDC
593 //
594 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
595
596 nonLinearCorrCoefficHG[0][0] = {-0.0225871, 0.00702802, 0.00201155, -0.00675293, 0.00186212} ;
597 nonLinearCorrCoefficHG[0][1] = {-0.0155562, 0.00594092, 0.00382112, -0.00665466, 0.00143384} ;
598 nonLinearCorrCoefficHG[0][2] = {-0.0313621, 0.0134528, 0.00529013, -0.0111751, 0.0029913} ;
599 nonLinearCorrCoefficHG[0][3] = {-0.025108, 0.00301898, 0.022472, -0.0204288, 0.00453215} ;
600 nonLinearCorrCoefficHG[1][0] = {-0.0266648, 0.0106792, -0.00939959, 0.000833011, 0.000199051} ;
601 nonLinearCorrCoefficHG[1][1] = {-0.0246541, 0.000327376, 0.00754946, -0.00710273, 0.00136899} ;
602 nonLinearCorrCoefficHG[1][2] = {-0.0175283, 0.0127954, 0.000235749, -0.00769698, 0.00221995} ;;
603 nonLinearCorrCoefficHG[1][3] = {-0.0279931, 0.0188122, 0.0126234, -0.0169907, 0.00398826} ;
604
605 // For now we don't use corrections on the LG as it's much harder to measure them
606 //
607 nonLinearCorrCoefficLG = {{ {{{0},
608 {0},
609 {0},
610 {0}}},
611 {{{0},
612 {0},
613 {0},
614 {0}}} }};
615
616 // Now use 1000 as the offset for the high gain non-linear correction due to the improved
617 // clarity in the high gain/low gain response change around the 10 bit mark with the new LG refit procedure
618 //
619 if (m_doNonLinCorr)
620 zdcDataAnalyzer->SetNonlinCorrParams(1000, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
621
622 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
623 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
624 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
625 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
626 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
627
628 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
629 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
630 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
631 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
632
633 // +++ BAC 07-26-24
634 //
635 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
636 // made at the same time to match the timing shift of the LG channels
637 //
638 // ---
639 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
640 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
641 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
642 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
643
644 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
645 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
646 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
647 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
648
649 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
650
651 // Set the amplitude fit range limits
652 //
653 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
654
655 return zdcDataAnalyzer;
656}
657
658std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializePbPb2024()
659{
660 // Key configuration parameters needed for the data analyzer construction
661 //
662 m_deltaTSample = 3.125;
663 m_numSample = 24;
664
665 const int deriv2ndThreshDSHG = -45;
666 const int deriv2ndThreshDSLG = -10;
667 const unsigned int peakSample = 10;
668
669 const float deltaTcutLow = -10;
670 const float deltaTcutHigh = 10;
671 const float chisqDivAmpCutHGVal = 30;
672 const float chisqDivAmpCutLGVal = 50;
673
674 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
675 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
676
677 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
678 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
679 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
680
681 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
682 {1.35, 1.4, 1.3, 1.1}}};
683
684 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
685
686 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.5, 31.5, 29.5, 30.5}, {34.5, 33.0, 33, 34.0}}};
687 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{32.25, 32.0, 30.5, 30.5}, {32.4, 33.5, 30.5, 31.4}}};
688
689 for (size_t side : {0, 1}) {
690 for (size_t module : {0, 1, 2, 3}) {
691 fixTau1Arr[side][module] = true;
692 fixTau2Arr[side][module] = false;
693
694 peak2ndDerivMinSamples[side][module] = peakSample;
695 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
696 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
697
698 deltaT0CutLow[side][module] = deltaTcutLow;
699 deltaT0CutHigh[side][module] = deltaTcutHigh;
700 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
701 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
702 }
703 }
704
705 ATH_MSG_DEBUG( "PbPb2024: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
706
707 // Construct the data analyzer
708 //
709 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
711 m_presample, "FermiExpLHCf",
712 peak2ndDerivMinSamples,
713 peak2ndDerivMinThresholdsHG,
714 peak2ndDerivMinThresholdsLG,
716 zdcDataAnalyzer->set2ndDerivStep(2);
717 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
718
719 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1.0}}};
720 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{9.36, 9.7, 10.95, 10.5}, {9.9, 10.5, 11.2, 10.4}}};
721
722 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
723
724 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
725 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
726 //
727 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.5, 1.5, 1.5, 1.5}, {1.5, 1.5, 1.5, 1.5}}};
728 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
729
730 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
731
732 // Now set cuts and default fit parameters
733 //
734 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
735 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
736 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
737
738 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
739 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
740 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
741
742 // Enable two-pass analysis
743 //
744 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-30, -30, -30, -30},
745 {-30, -30, -30, -30},}};
746
747 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
748 {-8, -8, -8, -8}}};
749
750 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
751
752 // Turn on exclusion of early and late samples to address OOT pileup
753 //
754 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
755 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
756
757 // Set up non-linear corrections for the ZDC
758 //
759 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
760
761 nonLinearCorrCoefficHG[0][0] = {-0.0225871, 0.00702802, 0.00201155, -0.00675293, 0.00186212} ;
762 nonLinearCorrCoefficHG[0][1] = {-0.0155562, 0.00594092, 0.00382112, -0.00665466, 0.00143384} ;
763 nonLinearCorrCoefficHG[0][2] = {-0.0313621, 0.0134528, 0.00529013, -0.0111751, 0.0029913} ;
764 nonLinearCorrCoefficHG[0][3] = {-0.025108, 0.00301898, 0.022472, -0.0204288, 0.00453215} ;
765 nonLinearCorrCoefficHG[1][0] = {-0.0266648, 0.0106792, -0.00939959, 0.000833011, 0.000199051} ;
766 nonLinearCorrCoefficHG[1][1] = {-0.0246541, 0.000327376, 0.00754946, -0.00710273, 0.00136899} ;
767 nonLinearCorrCoefficHG[1][2] = {-0.0175283, 0.0127954, 0.000235749, -0.00769698, 0.00221995} ;;
768 nonLinearCorrCoefficHG[1][3] = {-0.0279931, 0.0188122, 0.0126234, -0.0169907, 0.00398826} ;
769
770
771 // Remove nonlinear corrections while we study the injector pulse
772 nonLinearCorrCoefficHG = {{ {{{0},
773 {0},
774 {0},
775 {0}}},
776 {{{0},
777 {0},
778 {0},
779 {0}}} }};
780
781 //
782 // We are disabling the old FADC correction moving forward
783 if (m_doNonLinCorr)
784 zdcDataAnalyzer->SetNonlinCorrParams(1000, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
785
786 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
787 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
788 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
789 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
790 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
791
792 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
793 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
794 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
795 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
796
797 // +++ BAC 07-26-24
798 //
799 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
800 // made at the same time to match the timing shift of the LG channels
801 //
802 // ---
803 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
804 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
805 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
806 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
807
808 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
809 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
810 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
811 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
812
813 // Commenting out the timing correlation for PbPb2024: re-calibraton needed
814 // zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
815
816 std::array< std::array< std::vector<float>, 3>, 2> nlCalib = {{
817 {{ {{0.3, 1, -0.00753349, 0.882218, 0.019739, 1.0803}},{{0.3, 1, 0.0181165, 0.620646, -0.171213, 2.2143}},{{0.25, 1, -0.108547, 0.106, -1.3594, 4.1509}} }},
818 {{ {{0.3, 1, -0.00753349, 0.882218, 0.019739, 1.0803}},{{0.3, 1, 0.0181165, 0.620646, -0.171213, 2.2143}},{{0.25, 1, -0.108547, 0.106, -1.3594, 4.1509}} }}
819 }};
820
821 zdcDataAnalyzer->SetNLcalibParams(nlCalib);
822
823 // Set the amplitude fit range limits
824 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
825
826 return zdcDataAnalyzer;
827}
828
829std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeOONeNe2025()
830{
831 // Key configuration parameters needed for the data analyzer construction
832 //
833 m_deltaTSample = 3.125;
834 m_numSample = 24;
835
836 const unsigned int peakSample = 10;
837
838 const float deltaTcutLow = -10;
839 const float deltaTcutHigh = 10;
840 const float chisqDivAmpCutHGVal = 15;
841 const float chisqDivAmpCutLGVal = 15;
842
843 float deriv2ndThreshSigHGPass1 = 4.;
844 float deriv2ndThreshSigHGPass2 = 2.;
845
846 float deriv2ndThreshSigLGPass1 = 4;
847 float deriv2ndThreshSigLGPass2 = 2;
848
849 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
850 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
851 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG;
852
853 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
854 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
855
856 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.6, 1.22, 1.45, 1.35},
857 {1.5, 1.45, 1.3, 1.05}}};
858
859 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{7.0, 6.2, 5.5, 5.5}, {7, 5.3, 5.7, 6.5}}};
860
861 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.5, 31.5, 29.5, 30.5}, {34.5, 33.0, 33, 34.0}}};
862 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{32.25, 32.0, 30.5, 30.5}, {32.4, 33.5, 30.5, 31.4}}};
863
864 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpScaleHG, chisqDivAmpOffsetHG, chisqDivAmpPowerHG;
865 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutLG, chisqDivAmpScaleLG, chisqDivAmpOffsetLG, chisqDivAmpPowerLG;
866
867 chisqDivAmpScaleHG = {{{39.2, 4.2, 10.2, 17.2}, {16.6, 9.9, 29, 32.7}}};
868 chisqDivAmpOffsetHG = {{{0.58, 1.47, 1.14, 0.91}, {0.91, 1.1, 0.75, 0.64}}};
869 chisqDivAmpPowerHG = {{{2.50, 3.22, 2.79, 2.37}, {3.03, 3.07, 2.89, 2.53}}};
870
871 // The chisq values in the low gain fits almost scale with the gain-corrected amplitude (i.e. as 4^2 times HG)
872 // but not quite. However, the other parameters seem to work well enough over the limited low gain
873 // range populated in O+O collisions. Thus, we use the below parameters to adjust the LG scale factor
874 //
875 ZDCDataAnalyzer::ZDCModuleFloatArray chisqRatioLGHGScaleFactor = {{{6.6, 7.6, 12.3, 10}, {9.3, 12.9, 8.4, 10}}};
876
877 // In OO data the LG fits seem to track the HG fits well, so use same chisq parameters
878 //
879 chisqDivAmpOffsetLG = chisqDivAmpOffsetHG;
880 chisqDivAmpPowerLG = chisqDivAmpPowerHG;
881
882 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.5, 1.5, 1.5, 1.5}, {4, 1.5, 1.5, 1.5}}};
883 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{4.2, 4.2, 4.2, 4.2}, {4.2, 4.2, 4.2, 4.2}}};
884
885 for (size_t side : {0, 1}) {
886 for (size_t module : {0, 1, 2, 3}) {
887 fixTau1Arr[side][module] = true;
888 fixTau2Arr[side][module] = true;
889
890 peak2ndDerivMinSamples[side][module] = peakSample;
891
892 deltaT0CutLow[side][module] = deltaTcutLow;
893 deltaT0CutHigh[side][module] = deltaTcutHigh;
894
895 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
896 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
897
898 chisqDivAmpScaleLG[side][module] = chisqRatioLGHGScaleFactor[side][module]*chisqDivAmpScaleHG[side][module];
899
900 peak2ndDerivMinThresholdsHG[side][module] = noiseSigmasHG[side][module]*std::sqrt(6.0)*deriv2ndThreshSigHGPass1;
901 peak2ndDerivMinThresholdsLG[side][module] = noiseSigmasLG[side][module]*std::sqrt(6.0)*deriv2ndThreshSigLGPass1;
902
903 peak2ndDerivMinRepassHG[side][module] = noiseSigmasHG[side][module]*std::sqrt(6.0)*deriv2ndThreshSigHGPass2;
904 peak2ndDerivMinRepassLG[side][module] = noiseSigmasLG[side][module]*std::sqrt(6.0)*deriv2ndThreshSigLGPass2;
905 }
906 }
907
908 // Construct the data analyzer
909 //
910 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
912 m_presample, "FermiExpInduct",
913 peak2ndDerivMinSamples,
914 peak2ndDerivMinThresholdsHG,
915 peak2ndDerivMinThresholdsLG,
917 zdcDataAnalyzer->set2ndDerivStep(1);
918 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(4);
919
920 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1.0}}};
921 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{4,4,4,4}, {4,4,4,4}}};
922
923 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 4 applied to LG ADC, 1 to HG ADC values
924
925 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
926 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
927 //
928
929 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
930
931 std::vector<float> sampleNoiseHG = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 8, 12, 12, 16, 16, 12, 6, 4, 4, 4};
932 std::vector<float> sampleNoiseLG = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 12, 12, 12, 16, 20, 12, 4, 1, 1, 1, 1};
933
934 std::array<std::array<std::vector<float>,4>,2> sampleNoiseVecsHG, sampleNoiseVecsLG;
935 for (size_t side : {0, 1}) {
936 for (size_t module : {0, 1, 2, 3}) {
937 sampleNoiseVecsHG[side][module] = sampleNoiseHG;
938 sampleNoiseVecsLG[side][module] = sampleNoiseLG;
939 }
940 }
941 zdcDataAnalyzer->setPerSampleNoiseSigmas(sampleNoiseVecsHG, sampleNoiseVecsLG);
942
943 // Now set cuts and default fit parameters
944 //
945 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
946 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
947 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
948
949 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
950 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
951 zdcDataAnalyzer->SetTimeCuts(deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
952 zdcDataAnalyzer->SetChisqCuts(chisqDivAmpCutHG, chisqDivAmpScaleHG, chisqDivAmpOffsetHG, chisqDivAmpPowerHG,
953 chisqDivAmpCutLG, chisqDivAmpScaleLG, chisqDivAmpOffsetLG, chisqDivAmpPowerLG);
954
955 // Enable two-pass analysis
956 //
957 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
958
959 // Turn on exclusion of early and late samples to address OOT pileup
960 //
961 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
962 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
963
964 // Set up non-linear corrections for the ZDC
965 //
966 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
967
968 nonLinearCorrCoefficHG[0][0] = {-0.0225871, 0.00702802, 0.00201155, -0.00675293, 0.00186212} ;
969 nonLinearCorrCoefficHG[0][1] = {-0.0155562, 0.00594092, 0.00382112, -0.00665466, 0.00143384} ;
970 nonLinearCorrCoefficHG[0][2] = {-0.0313621, 0.0134528, 0.00529013, -0.0111751, 0.0029913} ;
971 nonLinearCorrCoefficHG[0][3] = {-0.025108, 0.00301898, 0.022472, -0.0204288, 0.00453215} ;
972 nonLinearCorrCoefficHG[1][0] = {-0.0266648, 0.0106792, -0.00939959, 0.000833011, 0.000199051} ;
973 nonLinearCorrCoefficHG[1][1] = {-0.0246541, 0.000327376, 0.00754946, -0.00710273, 0.00136899} ;
974 nonLinearCorrCoefficHG[1][2] = {-0.0175283, 0.0127954, 0.000235749, -0.00769698, 0.00221995} ;;
975 nonLinearCorrCoefficHG[1][3] = {-0.0279931, 0.0188122, 0.0126234, -0.0169907, 0.00398826} ;
976
977 m_doFADCCorr = true;
979
980 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
981 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
982 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
983 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
984 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
985
986 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
987 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
988 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
989 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
990
991 // +++ BAC 07-26-24
992 //
993 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
994 // made at the same time to match the timing shift of the LG channels
995 //
996 // ---
997 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
998 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
999 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
1000 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
1001
1002 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
1003 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
1004 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
1005 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
1006
1007 // Commenting out the timing correlation for PbPb2024: re-calibraton needed
1008 // zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1009
1010 // Set the amplitude fit range limits
1011 //
1012 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1013 zdcDataAnalyzer->setMinimumSignificance(4,5);
1014
1015 /*
1016{{
1017 {{{{0.3, 1, -0.00753349, 0.882218, 0.019739, 1.0803}},{{0.3, 1, 0.0181165, 0.620646, -0.171213, 2.2143}},{{0.25, 1, -0.108547, 0.106, -1.3594, 4.1509}}}},
1018 {{{{0.3, 1, -0.00753349, 0.882218, 0.019739, 1.0803}},{{0.3, 1, 0.0181165, 0.620646, -0.171213, 2.2143}},{{0.25, 1, -0.108547, 0.106, -1.3594, 4.1509}}}}
1019 }};
1020 */
1021
1022 std::array< std::array< std::vector<float>, 3>, 2> nlCalib = {{
1023 {{ {{0.3, 1, -0.00753349, 0.882218, 0.019739, 1.0803}},{{0.3, 1, 0.0181165, 0.620646, -0.171213, 2.2143}},{{0.25, 1, -0.108547, 0.106, -1.3594, 4.1509}} }},
1024 {{ {{0.3, 1, -0.00753349, 0.882218, 0.019739, 1.0803}},{{0.3, 1, 0.0181165, 0.620646, -0.171213, 2.2143}},{{0.25, 1, -0.108547, 0.106, -1.3594, 4.1509}} }}
1025 }};
1026
1027 zdcDataAnalyzer->SetNLcalibParams(nlCalib);
1028
1029 return zdcDataAnalyzer;
1030}
1031
1032std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializepO2025()
1033{
1034 // Key configuration parameters needed for the data analyzer construction
1035 //
1036 m_deltaTSample = 3.125;
1037 m_numSample = 24;
1038
1039 const int deriv2ndThreshDSHG = -45;
1040 const int deriv2ndThreshDSLG = -10;
1041 const unsigned int peakSample = 10;
1042
1043 const float deltaTcutLow = -10;
1044 const float deltaTcutHigh = 10;
1045 const float chisqDivAmpCutHGVal = 30;
1046 const float chisqDivAmpCutLGVal = 50;
1047
1048 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1049 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1050
1051 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1052 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1053 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1054
1055 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
1056 {1.35, 1.4, 1.3, 1.1}}};
1057
1058 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
1059
1060 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.5, 31.5, 29.5, 30.5}, {34.5, 33.0, 33, 34.0}}};
1061 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{32.25, 32.0, 30.5, 30.5}, {32.4, 33.5, 30.5, 31.4}}};
1062
1063 for (size_t side : {0, 1}) {
1064 for (size_t module : {0, 1, 2, 3}) {
1065 fixTau1Arr[side][module] = true;
1066 fixTau2Arr[side][module] = false;
1067
1068 peak2ndDerivMinSamples[side][module] = peakSample;
1069 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1070 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1071
1072 deltaT0CutLow[side][module] = deltaTcutLow;
1073 deltaT0CutHigh[side][module] = deltaTcutHigh;
1074 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1075 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1076 }
1077 }
1078
1079 //ATH_MSG_DEBUG( "PbPb2024: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1080
1081 // Construct the data analyzer
1082 //
1083 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1085 m_presample, "FermiExpInduct",
1086 peak2ndDerivMinSamples,
1087 peak2ndDerivMinThresholdsHG,
1088 peak2ndDerivMinThresholdsLG,
1090 zdcDataAnalyzer->set2ndDerivStep(1);
1091 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1092
1093 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1.0}}};
1094 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{4,4,4,4}, {4,4,4,4}}};
1095
1096 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1097
1098 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1099 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1100 //
1101 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.5, 1.5, 1.5, 1.5}, {1.5, 1.5, 1.5, 1.5}}};
1102 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
1103
1104 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1105
1106 // Now set cuts and default fit parameters
1107 //
1108 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1109 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1110 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1111
1112 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1113 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1114 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1115
1116 // Enable two-pass analysis
1117 //
1118 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-30, -30, -30, -30},
1119 {-30, -30, -30, -30},}};
1120
1121 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
1122 {-8, -8, -8, -8}}};
1123
1124 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
1125
1126 // Turn on exclusion of early and late samples to address OOT pileup
1127 //
1128 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
1129 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
1130
1131 // Set up non-linear corrections for the ZDC
1132 //
1133 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
1134
1135 nonLinearCorrCoefficHG[0][0] = {-0.0225871, 0.00702802, 0.00201155, -0.00675293, 0.00186212} ;
1136 nonLinearCorrCoefficHG[0][1] = {-0.0155562, 0.00594092, 0.00382112, -0.00665466, 0.00143384} ;
1137 nonLinearCorrCoefficHG[0][2] = {-0.0313621, 0.0134528, 0.00529013, -0.0111751, 0.0029913} ;
1138 nonLinearCorrCoefficHG[0][3] = {-0.025108, 0.00301898, 0.022472, -0.0204288, 0.00453215} ;
1139 nonLinearCorrCoefficHG[1][0] = {-0.0266648, 0.0106792, -0.00939959, 0.000833011, 0.000199051} ;
1140 nonLinearCorrCoefficHG[1][1] = {-0.0246541, 0.000327376, 0.00754946, -0.00710273, 0.00136899} ;
1141 nonLinearCorrCoefficHG[1][2] = {-0.0175283, 0.0127954, 0.000235749, -0.00769698, 0.00221995} ;;
1142 nonLinearCorrCoefficHG[1][3] = {-0.0279931, 0.0188122, 0.0126234, -0.0169907, 0.00398826} ;
1143
1144
1145 // Remove nonlinear corrections while we study the injector pulse
1146 nonLinearCorrCoefficHG = {{ {{{0},
1147 {0},
1148 {0},
1149 {0}}},
1150 {{{0},
1151 {0},
1152 {0},
1153 {0}}} }};
1154
1155 //
1156 // We are disabling the old FADC correction moving forward
1157 if (m_doNonLinCorr)
1158 zdcDataAnalyzer->SetNonlinCorrParams(1000, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
1159
1160 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
1161 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
1162 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
1163 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
1164 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
1165
1166 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
1167 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
1168 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
1169 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
1170
1171 // +++ BAC 07-26-24
1172 //
1173 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
1174 // made at the same time to match the timing shift of the LG channels
1175 //
1176 // ---
1177 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
1178 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
1179 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
1180 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
1181
1182 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
1183 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
1184 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
1185 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
1186
1187 // Commenting out the timing correlation for PbPb2024: re-calibraton needed
1188 // zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1189
1190 // Set the amplitude fit range limits
1191 //
1192 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1193
1194 zdcDataAnalyzer->disableModule(0, 0); // required since EM not installed
1195
1196 return zdcDataAnalyzer;
1197}
1198
1199std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializepO2025B()
1200{
1201 // Key configuration parameters needed for the data analyzer construction
1202 //
1203 m_deltaTSample = 3.125;
1204 m_numSample = 24;
1205
1206 const int deriv2ndThreshDSHG = -45;
1207 const int deriv2ndThreshDSLG = -10;
1208 const unsigned int peakSample = 10;
1209
1210 const float deltaTcutLow = -10;
1211 const float deltaTcutHigh = 10;
1212 const float chisqDivAmpCutHGVal = 30;
1213 const float chisqDivAmpCutLGVal = 50;
1214
1215 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1216 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1217
1218 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1219 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1220 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1221
1222 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
1223 {1.35, 1.4, 1.3, 1.1}}};
1224
1225 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
1226
1227 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.5, 31.5, 29.5, 30.5}, {34.5, 33.0, 33, 34.0}}};
1228 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{32.25, 32.0, 30.5, 30.5}, {32.4, 33.5, 30.5, 31.4}}};
1229
1230 for (size_t side : {0, 1}) {
1231 for (size_t module : {0, 1, 2, 3}) {
1232 fixTau1Arr[side][module] = true;
1233 fixTau2Arr[side][module] = false;
1234
1235 peak2ndDerivMinSamples[side][module] = peakSample;
1236 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1237 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1238
1239 deltaT0CutLow[side][module] = deltaTcutLow;
1240 deltaT0CutHigh[side][module] = deltaTcutHigh;
1241 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1242 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1243 }
1244 }
1245
1246 ATH_MSG_DEBUG( "PbPb2024: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1247
1248 // Construct the data analyzer
1249 //
1250 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1252 m_presample, "FermiExpLHCf",
1253 peak2ndDerivMinSamples,
1254 peak2ndDerivMinThresholdsHG,
1255 peak2ndDerivMinThresholdsLG,
1257 zdcDataAnalyzer->set2ndDerivStep(1);
1258 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1259
1260 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1.0}}}; //
1261 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{4,4,4,4}, {3,4,4,4}}}; // decided to move the change to the HG/LG ratio
1262
1263 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1264
1265 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1266 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1267 //
1268 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.5, 1.5, 1.5, 1.5}, {1.5, 1.5, 1.5, 1.5}}};
1269 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
1270
1271 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1272
1273 // Now set cuts and default fit parameters
1274 //
1275 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1276 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1277 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1278
1279 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1280 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1281 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1282
1283 // Enable two-pass analysis
1284 //
1285 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-30, -30, -30, -30},
1286 {-30, -30, -30, -30},}};
1287
1288 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
1289 {-8, -8, -8, -8}}};
1290
1291 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
1292
1293 // Turn on exclusion of early and late samples to address OOT pileup
1294 //
1295 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
1296 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
1297
1298 // Set up non-linear corrections for the ZDC
1299 //
1300 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
1301
1302 nonLinearCorrCoefficHG[0][0] = {-0.0225871, 0.00702802, 0.00201155, -0.00675293, 0.00186212} ;
1303 nonLinearCorrCoefficHG[0][1] = {-0.0155562, 0.00594092, 0.00382112, -0.00665466, 0.00143384} ;
1304 nonLinearCorrCoefficHG[0][2] = {-0.0313621, 0.0134528, 0.00529013, -0.0111751, 0.0029913} ;
1305 nonLinearCorrCoefficHG[0][3] = {-0.025108, 0.00301898, 0.022472, -0.0204288, 0.00453215} ;
1306 nonLinearCorrCoefficHG[1][0] = {-0.0266648, 0.0106792, -0.00939959, 0.000833011, 0.000199051} ;
1307 nonLinearCorrCoefficHG[1][1] = {-0.0246541, 0.000327376, 0.00754946, -0.00710273, 0.00136899} ;
1308 nonLinearCorrCoefficHG[1][2] = {-0.0175283, 0.0127954, 0.000235749, -0.00769698, 0.00221995} ;;
1309 nonLinearCorrCoefficHG[1][3] = {-0.0279931, 0.0188122, 0.0126234, -0.0169907, 0.00398826} ;
1310
1311
1312 // Remove nonlinear corrections while we study the injector pulse
1313 nonLinearCorrCoefficHG = {{ {{{0},
1314 {0},
1315 {0},
1316 {0}}},
1317 {{{0},
1318 {0},
1319 {0},
1320 {0}}} }};
1321
1322 //
1323 // We are disabling the old FADC correction moving forward
1324 if (m_doNonLinCorr)
1325 zdcDataAnalyzer->SetNonlinCorrParams(1000, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
1326
1327 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
1328 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
1329 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
1330 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
1331 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
1332
1333 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
1334 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
1335 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
1336 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
1337
1338 // +++ BAC 07-26-24
1339 //
1340 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
1341 // made at the same time to match the timing shift of the LG channels
1342 //
1343 // ---
1344 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
1345 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
1346 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
1347 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
1348
1349 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
1350 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
1351 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
1352 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
1353
1354 // Commenting out the timing correlation for PbPb2024: re-calibraton needed
1355 // zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1356
1357 // Set the amplitude fit range limits
1358 //
1359 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1360
1361 zdcDataAnalyzer->disableModule(0, 0); // required since EM not installed
1362
1363 return zdcDataAnalyzer;
1364}
1365
1366std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeInjectorpp2024()
1367{
1368 // Key configuration parameters needed for the data analyzer construction
1369 //
1370 m_deltaTSample = 3.125;
1371 m_numSample = 24;
1372
1373 const int deriv2ndThreshDSHG = -10;
1374 const int deriv2ndThreshDSLG = -10;
1375 const unsigned int peakSample = 10;
1376
1377 const float deltaTcutLow = -50;
1378 const float deltaTcutHigh = 50;
1379 const float chisqDivAmpCutHGVal = 30;
1380 const float chisqDivAmpCutLGVal = 50;
1381
1382 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1383 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1384
1385 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1386 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1387 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1388
1389 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
1390 {1.35, 1.4, 1.3, 1.1}}};
1391
1392 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
1393
1394 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.25, 31.25, 31.25, 31.25}, {31.25, 31.25, 31.25, 31.25}}};
1395 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{28, 28, 28, 28}, {28, 28, 28, 28}}};
1396
1397 for (size_t side : {0, 1}) {
1398 for (size_t module : {0, 1, 2, 3}) {
1399 fixTau1Arr[side][module] = false;
1400 fixTau2Arr[side][module] = true;
1401
1402 peak2ndDerivMinSamples[side][module] = peakSample;
1403 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1404 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1405
1406 deltaT0CutLow[side][module] = deltaTcutLow;
1407 deltaT0CutHigh[side][module] = deltaTcutHigh;
1408 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1409 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1410 }
1411 }
1412
1413 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1414
1415 // Construct the data analyzer
1416 //
1417 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1419 m_presample, "FermiExpLHCf",
1420 peak2ndDerivMinSamples,
1421 peak2ndDerivMinThresholdsHG,
1422 peak2ndDerivMinThresholdsLG,
1424 zdcDataAnalyzer->set2ndDerivStep(2);
1425 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(10);
1426
1427 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1428 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1429
1430 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1431
1432 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1433 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1434 //
1435 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1436 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{10.0, 10.0, 10.0, 10.0}, {10.0, 10.0, 10.0, 10.0}}};
1437
1438 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1439
1440 // Now set cuts and default fit parameters
1441 //
1442 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1443 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1444 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1445
1446 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1447 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1448 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1449
1450 // Turn on exclusion of early and late samples to address OOT pileup
1451 //
1452 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
1453 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
1454
1455
1456 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
1457 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
1458 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
1459 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
1460 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
1461
1462 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
1463 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
1464 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
1465 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
1466
1467 // +++ BAC 07-26-24
1468 //
1469 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
1470 // made at the same time to match the timing shift of the LG channels
1471 //
1472 // ---
1473 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
1474 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
1475 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
1476 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
1477
1478 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
1479 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
1480 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
1481 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
1482
1483 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1484
1485 // Set the amplitude fit range limits
1486 //
1487 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1488
1489 return zdcDataAnalyzer;
1490}
1491
1492std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeInjectorPbPb2024()
1493{
1494 // Key configuration parameters needed for the data analyzer construction
1495 //
1496 m_deltaTSample = 3.125;
1497 m_numSample = 24;
1498
1499 const int deriv2ndThreshDSHG = -25;
1500 const int deriv2ndThreshDSLG = -10;
1501 const unsigned int peakSample = 10;
1502
1503 const float deltaTcutLow = -10;
1504 const float deltaTcutHigh = 10;
1505 const float chisqDivAmpCutHGVal = 30;
1506 const float chisqDivAmpCutLGVal = 50;
1507
1508 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1509 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1510
1511 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1512 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1513 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1514
1515 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.8, 1.8, 1.8, 1.8}, {1.8, 1.8, 1.8, 1.8}}};
1516
1517 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{5.5, 5.5, 5.5, 5.5}, {5.5, 5.5, 5.5, 5.5}}};
1518
1519 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{33.25, 33, 29.5, 33}, {31.5, 32.5, 32, 32.25}}};
1520 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{30.5, 30, 26.75, 30}, {29.5, 32.5, 29.5, 29}}};
1521
1522 for (size_t side : {0, 1}) {
1523 for (size_t module : {0, 1, 2, 3}) {
1524 fixTau1Arr[side][module] = false;
1525 fixTau2Arr[side][module] = true;
1526
1527 peak2ndDerivMinSamples[side][module] = peakSample;
1528 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1529 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1530
1531 deltaT0CutLow[side][module] = deltaTcutLow;
1532 deltaT0CutHigh[side][module] = deltaTcutHigh;
1533 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1534 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1535 }
1536 }
1537
1538 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1539
1540 // Construct the data analyzer
1541 //
1542 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1544 m_presample, "FermiExpLHCf",
1545 peak2ndDerivMinSamples,
1546 peak2ndDerivMinThresholdsHG,
1547 peak2ndDerivMinThresholdsLG,
1549
1550 zdcDataAnalyzer->set2ndDerivStep(2);
1551 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1552
1553 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1554 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
1555
1556 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1557
1558 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1559 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1560 //
1561 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{2.0, 2.0, 2.0, 2.0}, {2.0, 2.0, 2.0, 2.0}}};
1562 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{15.0, 15.0, 15.0, 15.0}, {15.0, 15.0, 15.0, 15.0}}};
1563
1564 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1565
1566 // Now set cuts and default fit parameters
1567 //
1568 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1569 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1570 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1571
1572 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1573 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1574 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1575
1576 // Set the amplitude fit range limits
1577 //
1578 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1579
1580 return zdcDataAnalyzer;
1581}
1582
1583std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeInjectorpOOONeNe2025()
1584{
1585 // Key configuration parameters needed for the data analyzer construction
1586 //
1587 m_deltaTSample = 3.125;
1588 m_numSample = 24;
1589
1590 const int deriv2ndThreshDSHG = -25;
1591 const int deriv2ndThreshDSLG = -10;
1592 const unsigned int peakSample = 10;
1593
1594 const float deltaTcutLow = -10;
1595 const float deltaTcutHigh = 10;
1596 const float chisqDivAmpCutHGVal = 30;
1597 const float chisqDivAmpCutLGVal = 50;
1598
1599 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1600 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1601
1602 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1603 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1604 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1605
1606 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.8, 1.8, 1.8, 1.8}, {1.8, 1.8, 1.8, 1.8}}};
1607
1608 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{5.5, 5.5, 5.5, 5.5}, {5.5, 5.5, 5.5, 5.5}}};
1609
1610 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{33.25, 33, 29.5, 33}, {31.5, 32.5, 32, 32.25}}};
1611 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{30.5, 30, 26.75, 30}, {29.5, 32.5, 29.5, 29}}};
1612
1613 for (size_t side : {0, 1}) {
1614 for (size_t module : {0, 1, 2, 3}) {
1615 fixTau1Arr[side][module] = false;
1616 fixTau2Arr[side][module] = true;
1617
1618 peak2ndDerivMinSamples[side][module] = peakSample;
1619 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1620 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1621
1622 deltaT0CutLow[side][module] = deltaTcutLow;
1623 deltaT0CutHigh[side][module] = deltaTcutHigh;
1624 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1625 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1626 }
1627 }
1628
1629 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1630
1631 // Construct the data analyzer
1632 //
1633 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1635 m_presample, "FermiExpLHCf",
1636 peak2ndDerivMinSamples,
1637 peak2ndDerivMinThresholdsHG,
1638 peak2ndDerivMinThresholdsLG,
1640
1641 zdcDataAnalyzer->set2ndDerivStep(2);
1642 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1643
1644 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1645 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{4,4,4,4}, {4,4,4,4}}};
1646
1647 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 4 applied to LG ADC, 1 to HG ADC values
1648
1649 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1650 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1651 //
1652 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{2.0, 2.0, 2.0, 2.0}, {2.0, 2.0, 2.0, 2.0}}};
1653 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{15.0, 15.0, 15.0, 15.0}, {15.0, 15.0, 15.0, 15.0}}};
1654
1655 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1656
1657 // Now set cuts and default fit parameters
1658 //
1659 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1660 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1661 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1662
1663 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1664 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1665 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1666
1667 // Set the amplitude fit range limits
1668 //
1669 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1670
1671 return zdcDataAnalyzer;
1672}
1673
1674std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeMonteCarloPbPb2023()
1675{
1676 // Key configuration parameters needed for the data analyzer construction
1677 //
1678 m_deltaTSample = 3.125;
1679 m_numSample = 24;
1680
1681 const int deriv2ndThreshDSHG = -25;
1682 const int deriv2ndThreshDSLG = -10;
1683 const unsigned int peakSample = 10;
1684
1685 const float deltaTcutLow = -10;
1686 const float deltaTcutHigh = 10;
1687 const float chisqDivAmpCutHGVal = 30;
1688 const float chisqDivAmpCutLGVal = 50;
1689
1690 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1691 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1692
1693 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1694 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1695 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1696
1697 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.1, 1.1, 1.1, 1.1},
1698 {1.1, 1.1, 1.1, 1.1}}};
1699
1700 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
1701
1702 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.25, 31.25, 31.25, 31.25}, {31.25, 31.25, 31.25, 31.25}}};
1703 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{31.25, 31.25, 31.25, 31.25}, {31.25, 31.25, 31.25, 31.25}}};
1704
1705 for (size_t side : {0, 1}) {
1706 for (size_t module : {0, 1, 2, 3}) {
1707 fixTau1Arr[side][module] = false;
1708 fixTau2Arr[side][module] = false;
1709
1710 peak2ndDerivMinSamples[side][module] = peakSample;
1711 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1712 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1713
1714 deltaT0CutLow[side][module] = deltaTcutLow;
1715 deltaT0CutHigh[side][module] = deltaTcutHigh;
1716 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1717 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1718 }
1719 }
1720
1721 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1722
1723 // Construct the data analyzer
1724 //
1725 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1727 m_presample, "FermiExpLHCf",
1728 peak2ndDerivMinSamples,
1729 peak2ndDerivMinThresholdsHG,
1730 peak2ndDerivMinThresholdsLG,
1731 m_lowGainMode));
1732 zdcDataAnalyzer->set2ndDerivStep(2);
1733 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1734
1735 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1}}};
1736 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{10.,10.,10.,10.},{10.,10.,10.,10.}}}; // apply constant factor of 10 to high gain data
1737
1738 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1739
1740 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1741 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1742 //
1743 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1744 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{1.5, 1.7, 3, 1.7}, {1.7, 1.6, 2.2, 1.8}}};
1745
1746 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1747
1748 // Now set cuts and default fit parameters
1749 //
1750 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1751 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1752 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1753
1754 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1755 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1756 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1757
1758 // Enable two-pass analysis
1759 //
1760 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-10, -10, -10, -10},
1761 {-10, -10, -10, -10}}};
1762
1763 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
1764 {-8, -8, -8, -8}}};
1765
1766 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
1767
1768 // Turn on exclusion of early and late samples to address OOT pileup
1769 //
1770 //zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
1771 //zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
1772
1773 // Set up non-linear corrections for the ZDC
1774 //
1775 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
1776
1777 nonLinearCorrCoefficHG = {{ {{{0},
1778 {0},
1779 {0},
1780 {0}}},
1781 {{{0},
1782 {0},
1783 {0},
1784 {0}}} }};
1785
1786 // For now we don't use corrections on the LG as it's much harder to measure them
1787 //
1788 nonLinearCorrCoefficLG = {{ {{{0},
1789 {0},
1790 {0},
1791 {0}}},
1792 {{{0},
1793 {0},
1794 {0},
1795 {0}}} }};
1796
1797 if (m_doNonLinCorr)
1798 zdcDataAnalyzer->SetNonlinCorrParams(0, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
1799
1800 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
1801 timeCorrCoefficHG[0][0] = {};
1802 timeCorrCoefficHG[0][1] = {};
1803 timeCorrCoefficHG[0][2] = {};
1804 timeCorrCoefficHG[0][3] = {};
1805
1806 timeCorrCoefficHG[1][0] = {};
1807 timeCorrCoefficHG[1][1] = {};
1808 timeCorrCoefficHG[1][2] = {};
1809 timeCorrCoefficHG[1][3] = {};
1810
1811 timeCorrCoefficLG[0][0] = {};
1812 timeCorrCoefficLG[0][1] = {};
1813 timeCorrCoefficLG[0][2] = {};
1814 timeCorrCoefficLG[0][3] = {};
1815
1816 timeCorrCoefficLG[1][0] = {};
1817 timeCorrCoefficLG[1][1] = {};
1818 timeCorrCoefficLG[1][2] = {};
1819 timeCorrCoefficLG[1][3] = {};
1820
1821 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1822
1823 // Set the amplitude fit range limits
1824 //
1825 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1826
1827 return zdcDataAnalyzer;
1828}
1829
1830std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeDefault()
1831{
1832 // We rely completely on the default parameters specified in the job properties to control:
1833 // # samples
1834 // frequency (more precisely, time/sample)
1835 // which sample to use as the pre-sample
1836 // where to expact the maxim of the peak (min 2nd derivative)
1837 // thresholds on the 2nd derivative for valid pulses
1838 // whether to fix the tau values in the pulse fitting
1839 // the default tau values
1840 // the nominal T0
1841 // delta T and chisq/amp cuts
1842 //
1843 // For now, we continue to use hard-coded values for the maximum and minimum ADC values
1844 // For now we also use the FermiExp pulse model.
1845 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
1846 ZDCDataAnalyzer::ZDCModuleFloatArray tau1{}, tau2{}, t0{};
1847 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
1848 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow{}, deltaT0CutHigh{}, chisqDivAmpCut{};
1849 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
1850
1851 for (size_t side : {0, 1}) {
1852 for (size_t module : {0, 1, 2, 3}) {
1853 fixTau1Arr[side][module] = m_fixTau1;
1854 fixTau2Arr[side][module] = m_fixTau2;
1855 tau1[side][module] = m_tau1;
1856 tau2[side][module] = m_tau2;
1857
1858 peak2ndDerivMinSamples[side][module] = m_peakSample;
1859 peak2ndDerivMinThresholdsHG[side][module] = -m_Peak2ndDerivThresh;
1860 peak2ndDerivMinThresholdsLG[side][module] = -m_Peak2ndDerivThresh / 2;
1861
1862 t0[side][module] = m_t0;
1863 deltaT0CutLow[side][module] = -m_deltaTCut;
1864 deltaT0CutHigh[side][module] = m_deltaTCut;
1865 chisqDivAmpCut[side][module] = m_ChisqRatioCut;
1866 }
1867 }
1868
1869 ATH_MSG_DEBUG( "Default: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1870
1871 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
1872 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
1873 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
1874
1875 // Construct the data analyzer
1876 //
1877 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(), m_numSample, m_deltaTSample, m_presample, "FermiExp", peak2ndDerivMinSamples,
1878 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode));
1879
1880 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1881 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0, t0);
1882 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1883
1884 if (m_combineDelay) {
1885 ZDCDataAnalyzer::ZDCModuleFloatArray defaultPedestalShifts = {{{{0, 0, 0, 0}}, {{0, 0, 0, 0}}}};
1886
1887 zdcDataAnalyzer->enableDelayed(m_delayDeltaT, defaultPedestalShifts);
1888 }
1889
1890 return zdcDataAnalyzer;
1891}
1892
1893std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializePbPb2015G4()
1894{
1895 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
1896 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
1897 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
1898 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCut{};
1899 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
1900
1901 const int peakSample = 4;
1902 const float peak2ndDerivThreshHG = -12;
1903 const float peak2ndDerivThreshLG = -10;
1904 ZDCDataAnalyzer::ZDCModuleFloatArray tau1Arr = {{{4.000, 4.000, 4.000, 4.000},
1905 {4.000, 4.000, 4.000, 4.000}}};
1906 ZDCDataAnalyzer::ZDCModuleFloatArray tau2Arr = {{{25.36, 25.05, 25.43, 25.60},
1907 {25.11, 25.08, 25.18, 25.48}}};
1908
1909 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{57.31, 57.28, 57.30, 57.28},
1910 {57.28, 57.29, 57.31, 57.33}}};
1911 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{57.31, 57.28, 57.30, 57.28},
1912 {57.28, 57.29, 57.31, 57.33}}};
1913
1914 // Delta T0 cut
1915 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{-10, -10, -10, -10}, {-10, -10, -10, -10}}};
1916 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{ 10, 10, 10, 10}, { 10, 10, 10, 10}}};
1917 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{-10, -10, -10, -10}, {-10, -10, -10, -10}}};
1918 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{ 10, 10, 10, 10}, { 10, 10, 10, 10}}};
1919
1920 for (size_t side : {0, 1}) {
1921 for (size_t module : {0, 1, 2, 3}) {
1922 fixTau1Arr[side][module] = true;
1923 fixTau2Arr[side][module] = true;
1924
1925 peak2ndDerivMinSamples[side][module] = peakSample;
1926 peak2ndDerivMinThresholdsHG[side][module] = peak2ndDerivThreshHG;
1927 peak2ndDerivMinThresholdsLG[side][module] = peak2ndDerivThreshLG;
1928
1929 chisqDivAmpCut[side][module] = 15;
1930 }
1931 }
1932
1933 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{ 800, 800, 800, 800}}, {{ 800, 800, 800, 800}}}};
1934 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{ 10, 10, 10, 10}}, {{ 10, 10, 10, 10}}}};
1935 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
1936
1937 m_deltaTSample = 12.5;
1938
1939 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(), 7, m_deltaTSample, 0, "FermiExp", peak2ndDerivMinSamples,
1940 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode));
1941
1942 // Open up tolerances on the position of the peak for now
1943 //
1944 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(1);
1945
1946 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1947 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1Arr, tau2Arr, t0HG, t0LG);
1948 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
1949
1950 zdcDataAnalyzer->SetFitTimeMax(85);
1951
1952 return zdcDataAnalyzer;
1953}
1954
1955std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializepPb2016()
1956{
1957 //
1958 // For now, we continue to use hard-coded values for the maximum and minimum ADC values
1959 // For now we also use the FermiExp pulse model.
1960
1961 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
1962 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
1963 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCut{};
1964 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
1965
1966 // For now we allow the tau values to be controlled by the job properties until they are better determined
1967 //
1968 const int peakSample = 5;
1969 const float peak2ndDerivThreshHG = -12;
1970 const float peak2ndDerivThreshLG = -10;
1971 ZDCDataAnalyzer::ZDCModuleFloatArray tau1Arr = {{{4.000, 3.380, 3.661, 3.679},
1972 {4.472, 4.656, 3.871, 4.061}
1973 }};
1974
1975 ZDCDataAnalyzer::ZDCModuleFloatArray tau2Arr = {{{22, 24.81, 24.48, 24.45},
1976 {24.17, 24.22, 25.46, 24.45}
1977 }};
1978
1979 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{70.00, 72.74, 73.09, 72.25},
1980 {75.11, 74.94, 73.93, 74.45}
1981 }};
1982 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{70.00, 73.41, 74.27, 73.30},
1983 {76.28, 76.07, 74.98, 76.54}
1984 }};
1985
1986 // Delta T0 cut
1987 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{ -6, -5, -5, -5}, {-5, -5, -5, -5}}};
1988 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{8, 8, 8, 11}, {8, 10, 8, 12}}};
1989 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{ -6, -5, -5, -5}, {-5, -5, -5, -5}}};
1990 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{8, 8, 8, 11}, {8, 10, 8, 12}}};
1991
1992
1993 for (size_t side : {0, 1}) {
1994 for (size_t module : {0, 1, 2, 3}) {
1995 fixTau1Arr[side][module] = true;
1996 fixTau2Arr[side][module] = true;
1997
1998 peak2ndDerivMinSamples[side][module] = peakSample;
1999 peak2ndDerivMinThresholdsHG[side][module] = peak2ndDerivThreshHG;
2000 peak2ndDerivMinThresholdsLG[side][module] = peak2ndDerivThreshLG;
2001
2002 chisqDivAmpCut[side][module] = 15;
2003 }
2004 }
2005
2006 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
2007 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2008 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
2009
2010 std::array<std::array<std::vector<float>, 4>, 2> slewingParamsHG, slewingParamsLG;
2011 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
2012 slewingParamsHG[0][0] = {0, 0, 0, 0};
2013 slewingParamsHG[0][1] = { -4.780244e-01, -7.150874e-02, 4.614585e-02, 8.015731e-04};
2014 slewingParamsHG[0][2] = { -5.253412e-01, -5.718167e-02, 5.243121e-02, 2.128398e-03};
2015 slewingParamsHG[0][3] = { -5.773952e-01, -5.687478e-02, 4.564267e-02, 1.462294e-03};
2016
2017 slewingParamsHG[1][0] = { 7.105115e-01, -3.686143e-02, 7.727447e-02, 5.924152e-03};
2018 slewingParamsHG[1][1] = { 4.052120e-02, 4.450686e-03, 8.031615e-02, 4.038097e-03};
2019 slewingParamsHG[1][2] = { 3.389476e-02, -2.056782e-02, 4.805321e-02, -2.627999e-03};
2020 slewingParamsHG[1][3] = { 2.069765e-01, -2.890419e-02, 6.084375e-02, 3.742011e-03};
2021
2022 slewingParamsLG[0][0] = {0, 0, 0, 0};
2023 slewingParamsLG[0][1] = { -1.632547e+00, -4.827813e-01, -1.379131e-01, -2.522607e-02};
2024 slewingParamsLG[0][2] = { -7.254288e+00, -5.454064e+00, -1.619126e+00, -1.739665e-01};
2025 slewingParamsLG[0][3] = { -1.548400e+01, -1.277708e+01, -3.729333e+00, -3.700458e-01};
2026
2027 slewingParamsLG[1][0] = { 1.142767e-01, -3.608906e-02, 9.642735e-02, -3.097043e-03};
2028 slewingParamsLG[1][1] = { -5.615388e-01, -1.655047e-02, 8.327350e-02, -4.231348e-03};
2029 slewingParamsLG[1][2] = { -7.370728e-01, -2.887482e-02, 8.293875e-02, -4.482743e-03};
2030 slewingParamsLG[1][3] = { -1.270636e+00, -2.791777e-01, -5.807295e-02, -2.332612e-02};
2031
2032 // Construct the data analyzer
2033 //
2034 // We adopt hard-coded values for the number of samples and the frequency which we kept fixed for all physics data
2035 //
2036 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(), 7, 25, 0, "FermiExpLinear", peak2ndDerivMinSamples,
2037 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode));
2038
2039 // Open up tolerances on the position of the peak for now
2040 //
2041 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(1);
2042
2043 // We alwyas disable the 12EM (sideC) module which was not present (LHCf)
2044 //
2045 zdcDataAnalyzer->disableModule(0, 0);
2046
2047 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
2048 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1Arr, tau2Arr, t0HG, t0LG);
2049 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
2050
2051 // We allow the combineDelay to be controlled by the properties
2052 //
2053 // if (m_combineDelay) {
2054 m_combineDelay = true;
2055 ZDCDataAnalyzer::ZDCModuleFloatArray defaultPedestalShifts = {{{{0, 0, 0, 0}}, {{0, 0, 0, 0}}}};
2056
2057 zdcDataAnalyzer->enableDelayed(-12.5, defaultPedestalShifts);
2058 zdcDataAnalyzer->SetFitTimeMax(140); // This restrict the fit range of the pulse fitting
2059 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLin, 500, 100,
2060 slewingParamsHG, slewingParamsLG); // add time slewing correction Sep 17 2019 Bill
2061 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
2062
2063 return zdcDataAnalyzer;
2064}
2065
2066std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializePbPb2018()
2067{
2068 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
2069 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{}, peak2ndDerivMinRepassHG{}, peak2ndDerivMinRepassLG{};
2070 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCut{};
2071 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
2072
2073 static constexpr int peakSample = 5;
2074 static constexpr float peak2ndDerivThreshHG = -35;
2075 static constexpr float peak2ndDerivThreshLG = -20;
2076 static constexpr float peak2ndDerivRepassHG = -10;
2077 static constexpr float peak2ndDerivRepassLG = -6;
2078
2079 ZDCDataAnalyzer::ZDCModuleFloatArray tau1Arr = {{{3.877, 3.998, 3.821, 3.858},
2080 {4.296, 4.064, 3.497, 3.642}
2081 }};
2082
2083 ZDCDataAnalyzer::ZDCModuleFloatArray tau2Arr = {{{24.40, 25.28, 25.66, 24.12},
2084 {24.42, 24.99, 25.72, 25.29}
2085 }};
2086
2087 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{70.51, 70.57, 70.13, 69.98},
2088 {74.18, 72.79, 71.77, 72.62}
2089 }};
2090 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{70.70, 70.78, 70.76, 70.91},
2091 {75.16, 73.71, 72.25, 73.61}
2092 }};
2093
2094 ZDCDataAnalyzer::ZDCModuleFloatArray moduleAmpFractionLG = {{{0.2760, 0.3045, 0.2369, 0.1826},
2095 {0.3216, 0.2593, 0.2511, 0.1680}
2096 }};
2097
2098 // Delta T0 cut
2099 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{ -6, -5, -5, -5}, {-5, -5, -5, -5}}};
2100 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{8, 8, 8, 11}, {8, 10, 8, 12}}};
2101 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{ -6, -5, -5, -5}, {-5, -5, -5, -5}}};
2102 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{8, 8, 8, 11}, {8, 10, 8, 12}}};
2103
2104 for (size_t side : {0, 1}) {
2105 for (size_t module : {0, 1, 2, 3}) {
2106 fixTau1Arr[side][module] = true;
2107 fixTau2Arr[side][module] = true;
2108
2109 peak2ndDerivMinSamples[side][module] = peakSample;
2110 peak2ndDerivMinThresholdsHG[side][module] = peak2ndDerivThreshHG;
2111 peak2ndDerivMinThresholdsLG[side][module] = peak2ndDerivThreshLG;
2112 peak2ndDerivMinRepassHG [side][module] = peak2ndDerivRepassHG;
2113 peak2ndDerivMinRepassLG [side][module] = peak2ndDerivRepassLG;
2114
2115 chisqDivAmpCut[side][module] = 15;
2116 }
2117 }
2118
2119 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
2120 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2121 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
2122
2123 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1, 1, 1, 1}, {1, 1, 1, 1}}};
2124 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{12, 12, 12, 12}, {12, 12, 12, 12}}};
2125
2126
2127 std::array<std::array<std::vector<float>, 4>, 2> slewingParamsHG, slewingParamsLG;
2128 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
2129 slewingParamsHG[0][0] = { -1.335560e-01, -6.071869e-03, 5.858193e-02, 2.473300e-03};
2130 slewingParamsHG[0][1] = { -1.223062e-01, -4.379469e-02, 4.452285e-02, 2.130210e-03};
2131 slewingParamsHG[0][2] = { -1.021415e-01, -4.254239e-02, 4.939866e-02, 3.849738e-03};
2132 slewingParamsHG[0][3] = { -8.234056e-02, -3.938803e-02, 4.689029e-02, 2.784816e-03};
2133
2134 slewingParamsHG[1][0] = { -1.640979e-01, -2.780350e-02, 5.755065e-02, -4.244651e-04};
2135 slewingParamsHG[1][1] = { -1.422324e-01, 2.663803e-02, 7.295366e-02, 3.740496e-03};
2136 slewingParamsHG[1][2] = { -9.858124e-02, -2.426132e-02, 4.895967e-02, 2.291393e-03};
2137 slewingParamsHG[1][3] = { -1.070401e-01, -2.256383e-03, 5.833770e-02, 2.255208e-03};
2138
2139 slewingParamsLG[0][0] = { -2.588446e-01, -3.241086e-02, 7.828661e-02, 1.945547e-03};
2140 slewingParamsLG[0][1] = { -3.112495e-01, -7.419508e-02, 6.825776e-02, 2.148860e-03};
2141 slewingParamsLG[0][2] = { -3.470650e-01, -5.836748e-02, 6.204396e-02, 1.550421e-03};
2142 slewingParamsLG[0][3] = { -4.485435e-01, -4.603790e-02, 5.944799e-02, -1.174585e-03};
2143
2144 slewingParamsLG[1][0] = { -3.291676e-01, -4.023732e-02, 8.608755e-02, -3.958167e-03};
2145 slewingParamsLG[1][1] = { -2.608969e-01, -2.129786e-03, 6.930791e-02, -4.141910e-03};
2146 slewingParamsLG[1][2] = { -2.505712e-01, -2.195804e-02, 5.137261e-02, -4.058378e-03};
2147 slewingParamsLG[1][3] = { -5.083206e-01, 3.776601e-02, 1.284275e-01, 1.014067e-02};
2148
2149 // Construct the data analyzer
2150 //
2151 // We adopt hard-coded values for the number of samples and the frequency which we kept fixed for all physics data
2152 //
2153 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer = std::make_unique<ZDCDataAnalyzer>(MakeMessageFunction(), 7, 25, 0, "FermiExpLinear", peak2ndDerivMinSamples, // presample index changed to zero 4/6/19
2154 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode);
2155
2156 // Open up tolerances on the position of the peak for now
2157 //
2158 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(1);
2159
2160 // We alwyas disable the 12EM (sideC) module which was not present (LHCf)
2161 //
2162
2163 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
2164 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1Arr, tau2Arr, t0HG, t0LG);
2165 zdcDataAnalyzer->SetModuleAmpFractionLG(moduleAmpFractionLG); // fraction calculation for LGOverflows added Nov 23, 2020
2166 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
2167
2168 // We allow the combineDelay to be controlled by the properties
2169 //
2170 m_combineDelay = true;
2171 ZDCDataAnalyzer::ZDCModuleFloatArray defaultPedestalShifts = {{{{0, 0, 0, 0}}, {{0, 0, 0, 0}}}};
2172
2173 // We use per-module delays to handle the delayed-undelayed swap on EMC
2174 //
2175 ZDCDataAnalyzer::ZDCModuleFloatArray delayDeltaTs = {{{{12.5, -12.5, -12.5, -12.5}},
2176 {{ -12.5, -12.5, -12.5, -12.5}}
2177 }
2178 };
2179
2180 zdcDataAnalyzer->enableDelayed(delayDeltaTs, defaultPedestalShifts);
2181 zdcDataAnalyzer->SetFitTimeMax(140); // This restrict the fit range of the pulse fitting, requested by BAC 4/6/19
2182 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG); // add repass as default Jul 21 2020 Bill
2183 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLin, 500, 100,
2184 slewingParamsHG, slewingParamsLG); // add time slewing correction Sep 17 2019 Bill
2185 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
2186
2187 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
2188
2189 return zdcDataAnalyzer;
2190}
2191
2193{
2194 // We have a complete configuration and so we override all of the default parameters
2195 //
2196
2197 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{{4.2, 3.8, 5.2, 5.0}},
2198 {{5.0, 3.7, 3.5, 3.5}}
2199 }
2200 };
2201
2202 // identical to 80 MHz -- is this right
2203 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{{20.0, 20.4, 18.9, 20.8}},
2204 {{19.1, 21.9, 22.6, 23.4}}
2205 }
2206 };
2207
2208 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples = {{{{1, 1, 2, 1}},
2209 {{1, 1, 1, 1}}
2210 }
2211 };
2212
2213 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG = {{{{ -8, -8, -8, -8}},
2214 {{ -8, -8, -8, -8}}
2215 }
2216 };
2217
2218 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsLG = {{{{ -4, -4, -4, -4}},
2219 {{ -4, -4, -4, -4}}
2220 }
2221 };
2222
2223 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
2224 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2225 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
2226
2227 // Set Tau and nominal timing offsets
2228 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
2229
2230 bool fixTau1 = true;
2231 bool fixTau2 = true;
2232
2233 for (size_t side : {0, 1}) {
2234 for (size_t module : {0, 1, 2, 3}) {
2235 fixTau1Arr[side][module] = fixTau1;
2236 fixTau2Arr[side][module] = fixTau2;
2237 }
2238 }
2239
2240 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{{53.942, 49.887, 59.633, 46.497}},
2241 {{46.314, 42.267, 50.327, 41.605}}
2242 }
2243 };
2244 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{{51.771, 47.936, 57.438, 44.191}},
2245 {{44.295, 41.755, 48.081, 40.175}}
2246 }
2247 };
2248
2249
2250 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2251 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutLG = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2252 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{{ -6, -5, -5, -5}}, {{ -5, -5, -5, -5}}}};
2253 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{{8, 8, 8, 11}}, {{8, 10, 8, 12}}}};
2254 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{{ -6, -5, -5, -5}}, {{ -5, -5, -5, -5}}}};
2255 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{{8, 8, 8, 11}}, {{8, 10, 8, 12}}}};
2256
2257 std::array<std::array<std::vector<float>, 4>, 2> slewingParamsHG, slewingParamsLG;
2258
2259 slewingParamsHG[0][0] = {0, -7.904e-02, 4.686e-02, 1.530e-03 };
2260 slewingParamsHG[0][1] = {0, 2.250e-02, 4.732e-02, 6.050e-03 };
2261 slewingParamsHG[0][2] = {0, 4.388e-02, 6.707e-02, -5.526e-05 };
2262 slewingParamsHG[0][3] = {0, 1.205e-01, 2.726e-02, 2.610e-03 };
2263
2264 slewingParamsHG[1][0] = {0, 6.861e-02, 5.175e-03, -9.018e-04 };
2265 slewingParamsHG[1][1] = {0, 3.855e-01, -4.442e-02, -2.022e-02 };
2266 slewingParamsHG[1][2] = {0, -4.337e-03, 3.841e-02, 4.661e-03 };
2267 slewingParamsHG[1][3] = {0, 3.623e-01, -3.882e-02, -1.805e-02 };
2268
2269 slewingParamsLG[0][0] = {0, 1.708e-02, 7.929e-02, 5.079e-03 };
2270 slewingParamsLG[0][1] = {0, 1.406e-01, 1.209e-01, -1.922e-04 };
2271 slewingParamsLG[0][2] = {0, 1.762e-01, 1.118e-01, 1.679e-04 };
2272 slewingParamsLG[0][3] = {0, 1.361e-02, -2.685e-02, -4.168e-02 };
2273
2274 slewingParamsLG[1][0] = {0, 1.962e-01, -5.025e-03, -2.001e-02 };
2275 slewingParamsLG[1][1] = {0, 3.258e-01, 1.229e-02, -2.925e-02 };
2276 slewingParamsLG[1][2] = {0, 1.393e-01, 8.113e-02, -2.594e-03 };
2277 slewingParamsLG[1][3] = {0, 1.939e-01, 2.188e-02, -5.579e-02 };
2278
2279 m_zdcDataAnalyzer_40MHz.reset (new ZDCDataAnalyzer(MakeMessageFunction(), 7, 25, 0, "FermiExp", peak2ndDerivMinSamples,
2280 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode));
2281
2282 m_zdcDataAnalyzer_40MHz->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
2283 m_zdcDataAnalyzer_40MHz->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
2284 m_zdcDataAnalyzer_40MHz->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
2285 m_zdcDataAnalyzer_40MHz->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLin, 500, 100,
2286 slewingParamsHG, slewingParamsLG);
2287
2288 std::array<std::array<std::vector<float>, 4>, 2> moduleHGNonLinCorr, moduleLGNonLinCorr;
2289 moduleHGNonLinCorr[0][0] = { -3.76800e-02, 4.63597e-02};
2290 moduleHGNonLinCorr[0][1] = { -1.02185e-01, -1.17548e-01};
2291 moduleHGNonLinCorr[0][2] = { -8.78451e-02, -1.52174e-01};
2292 moduleHGNonLinCorr[0][3] = { -1.04835e-01, -1.96514e-01};
2293 moduleHGNonLinCorr[1][0] = { -6.83115e-02, 3.57802e-02};
2294 moduleHGNonLinCorr[1][1] = { -1.08162e-01, -1.91413e-01};
2295 moduleHGNonLinCorr[1][2] = { -7.82514e-02, -1.21218e-01};
2296 moduleHGNonLinCorr[1][3] = { -2.34354e-02, -2.52033e-01};
2297
2298 moduleLGNonLinCorr = {{ {{{0},
2299 {0},
2300 {0},
2301 {0}}},
2302 {{{0},
2303 {0},
2304 {0},
2305 {0}}} }};
2306
2307 if (m_doNonLinCorr) m_zdcDataAnalyzer_40MHz->SetNonlinCorrParams(500, 1000, moduleHGNonLinCorr, moduleLGNonLinCorr);
2308
2309}
2310
2312{
2313 // We have a complete configuration and so we override all of the default parameters
2314 //
2315
2316 m_peak2ndDerivMinSamples = {{{{3, 2, 3, 2}},
2317 {{2, 2, 2, 2}}
2318 }
2319 };
2320
2321 m_peak2ndDerivMinThresholdsHG = {{{{ -8, -8, -8, -8}},
2322 {{ -8, -8, -8, -8}}
2323 }
2324 };
2325
2326 m_peak2ndDerivMinThresholdsLG = {{{{ -4, -4, -4, -4}},
2327 {{ -4, -4, -4, -4}}
2328 }
2329 };
2330
2331 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
2332 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2333 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{950, 950, 950, 950}}, {{950, 950, 950, 950}}}};
2334
2335 // Set Tau and nominal timing offsets
2336 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
2337
2338 bool fixTau1 = true;
2339 bool fixTau2 = true;
2340
2341 for (size_t side : {0, 1}) {
2342 for (size_t module : {0, 1, 2, 3}) {
2343 fixTau1Arr[side][module] = fixTau1;
2344 fixTau2Arr[side][module] = fixTau2;
2345 }
2346 }
2347
2348 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{{3.9, 3.4, 4.1, 4.2}},
2349 {{4.2, 3.6, 3.3, 3.4}}
2350 }
2351 };
2352
2353 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{{20.0, 20.4, 18.9, 20.8}},
2354 {{19.1, 21.9, 22.6, 23.4}}
2355 }
2356 };
2357
2358 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{{44.24, 40.35, 49.3, 36.0}},
2359 {{36.0, 31.1, 40.75, 30.5}}
2360 }
2361 };
2362
2363 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{{42.65, 38.5, 47.4, 34}},
2364 {{33.7, 29.9, 39.0, 29.3}}
2365 }
2366 };
2367
2368 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2369 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutLG = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2370 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{{ -6, -5, -5, -5}}, {{ -5, -5, -5, -5}}}};
2371 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{{8, 8, 8, 11}}, {{8, 10, 8, 12}}}};
2372 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{{ -6, -5, -5, -5}}, {{ -5, -5, -5, -5}}}};
2373 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{{8, 8, 8, 11}}, {{8, 10, 8, 12}}}};
2374
2375 std::array<std::array<std::vector<float>, 4>, 2> slewingParamsHG, slewingParamsLG;
2376
2377 slewingParamsHG[0][0] = {0, -6.5e-2, 2.85e-2, -2.83e-3};
2378 slewingParamsHG[0][1] = {0, -5.5e-2, 5.13e-2, 5.6e-3};
2379 slewingParamsHG[0][2] = {0, -1.45e-3, 9.3e-2, 3.9e-3};
2380 slewingParamsHG[0][3] = {0, -2.36e-2, 8.3e-2, 1.1e-3};
2381
2382 slewingParamsHG[1][0] = {0, -6.5e-2, 4.84e-2, -3.7e-3};
2383 slewingParamsHG[1][1] = {0, 1.34e-2, 6.57e-2, 5.37e-3};
2384 slewingParamsHG[1][2] = {0, -5.37e-2, 3.49e-2, 3.8e-3};
2385 slewingParamsHG[1][3] = {0, -3.3e-2, 3.9e-2, 2.2e-3};
2386
2387 slewingParamsLG[0][0] = {0, -9.6e-2, 4.39e-2, 2.93e-3 };
2388 slewingParamsLG[0][1] = {0, -5.0e-2, 14.9e-2, 20.6e-3 };
2389 slewingParamsLG[0][2] = {0, -4.4e-2, 5.3e-2, 0, };
2390 slewingParamsLG[0][3] = {0, -9.90e-2, 4.08e-2, 0, };
2391
2392 slewingParamsLG[1][0] = {0, -8.7e-2, 4.2e-2, -3.2e-3 };
2393 slewingParamsLG[1][1] = {0, -3.26e-2, 3.84e-2, -2.32e-3};
2394 slewingParamsLG[1][2] = {0, -26.8e-2, -2.64e-2, -5.3e-3 };
2395 slewingParamsLG[1][3] = {0, -13.2e-2, 0.45e-2, -2.4e-3 };
2396
2397
2400
2401 m_zdcDataAnalyzer_80MHz->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
2402 m_zdcDataAnalyzer_80MHz->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
2403 m_zdcDataAnalyzer_80MHz->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
2404 m_zdcDataAnalyzer_80MHz->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLin, 500, 100,
2405 slewingParamsHG, slewingParamsLG);
2406
2407 std::array<std::array<std::vector<float>, 4>, 2> moduleHGNonLinCorr, moduleLGNonLinCorr;
2408 moduleHGNonLinCorr[0][0] = { -3.76800e-02, 4.63597e-02};
2409 moduleHGNonLinCorr[0][1] = { -1.02185e-01, -1.17548e-01};
2410 moduleHGNonLinCorr[0][2] = { -8.78451e-02, -1.52174e-01};
2411 moduleHGNonLinCorr[0][3] = { -1.04835e-01, -1.96514e-01};
2412 moduleHGNonLinCorr[1][0] = { -6.83115e-02, 3.57802e-02};
2413 moduleHGNonLinCorr[1][1] = { -1.08162e-01, -1.91413e-01};
2414 moduleHGNonLinCorr[1][2] = { -7.82514e-02, -1.21218e-01};
2415 moduleHGNonLinCorr[1][3] = { -2.34354e-02, -2.52033e-01};
2416
2417 moduleLGNonLinCorr = {{ {{{0},
2418 {0},
2419 {0},
2420 {0}}},
2421 {{{0},
2422 {0},
2423 {0},
2424 {0}}} }};
2425
2426 if (m_doNonLinCorr) m_zdcDataAnalyzer_80MHz->SetNonlinCorrParams(500, 1000, moduleHGNonLinCorr, moduleLGNonLinCorr);
2427}
2428
2430{
2431 m_tf1SincInterp.reset (new TF1("SincInterp", ZDC::SincInterp, -5., 160., 8));
2432 m_tf1SincInterp->SetNpx(300);
2433
2434 // Set up calibrations
2435 //
2436 std::string filename = PathResolverFindCalibFile( "ZdcAnalysis/ZdcAnalysisConfig.conf" );
2437 TEnv env(filename.c_str());
2438
2439 m_zdcEnergyCalibFileName = std::string(env.GetValue("ZdcEnergyCalibFileName", "ZdcCalibrations_v1.root"));
2440 ATH_MSG_INFO("ZDC energy calibration filename " << m_zdcEnergyCalibFileName);
2441 m_zdcTimeCalibFileName = std::string(env.GetValue("ZdcTimeCalibFileName", "ZdcTimeCalibrations_v1.root"));
2442 ATH_MSG_INFO("ZDC time calibration filename " << m_zdcTimeCalibFileName);
2443 m_zdcTriggerEffParamsFileName = std::string(env.GetValue("ZdcTriggerEffFileName", "ZdcTriggerEffParameters_v6.root"));
2444 ATH_MSG_INFO("ZDC trigger efficiencies filename " << m_zdcTriggerEffParamsFileName);
2445
2446
2447 if (m_forceCalibRun > -1) {
2448 ATH_MSG_DEBUG("CAREFUL: forcing calibration run/LB =" << m_forceCalibRun << "/" << m_forceCalibLB);
2449
2450 if (m_forceCalibLB < 0) {
2451 ATH_MSG_ERROR("Invalid settings: Forced run > 0 but lumi block < 0");
2452 return StatusCode::FAILURE;
2453 }
2454 }
2455
2456 // Use configuration to direct initialization
2457 //
2458 if (m_configuration == "default") {
2460 }
2461 else if (m_configuration == "PbPb2015") {
2464
2466 }
2467 else if (m_configuration == "pPb2016") {
2469 }
2470 else if (m_configuration == "PbPb2018") {
2472 }
2473 else if (m_configuration == "PbPb2015G4") {
2475 }
2476 else if (m_configuration == "LHCf2022") {
2478 }
2479 else if (m_configuration == "pp2023") {
2481 }
2482 else if (m_configuration == "pp2024") {
2484 }
2485 else if (m_configuration == "PbPb2023") {
2487 }
2488 else if (m_configuration == "PbPb2024") {
2490 }
2491 else if (m_configuration == "OONeNe2025") {
2493 }
2494 else if (m_configuration == "pO2025") {
2496 }
2497 else if (m_configuration == "pO2025B") {
2499 }
2500 else if (m_configuration == "Injectorpp2024") {
2502 }
2503 else if (m_configuration == "InjectorPbPb2024") {
2505 }
2506 else if (m_configuration == "InjectorpOOONeNe2025") {
2508 }
2509 else if (m_configuration == "MonteCarloPbPb2023") {
2511 }
2512 else if (m_configuration == "JSON") {
2514 }
2515 else {
2516 ATH_MSG_ERROR("Unknown configuration: " << m_configuration);
2517 return StatusCode::FAILURE;
2518 }
2519
2520 // If an aux suffix is provided, prepend it with "_" so we don't have to do so at each use
2521 //
2522
2523 ATH_MSG_INFO("Configuration: " << m_configuration);
2524 ATH_MSG_DEBUG("FlipEMDelay: " << m_flipEMDelay);
2525 ATH_MSG_DEBUG("LowGainMode: " << m_lowGainMode);
2526
2527 ATH_MSG_DEBUG("Using Combined delayed and undelayed samples: " << m_combineDelay);
2528
2529 ATH_MSG_DEBUG("WriteAux: " << m_writeAux);
2530 ATH_MSG_DEBUG("AuxSuffix: " << m_auxSuffix);
2531 ATH_MSG_DEBUG("DoCalib: " << m_doCalib);
2532 ATH_MSG_DEBUG("ForceCalibRun: " << m_forceCalibRun);
2533 ATH_MSG_DEBUG("ForceCalibLB: " << m_forceCalibLB);
2534 ATH_MSG_DEBUG("NumSampl: " << m_numSample);
2535 ATH_MSG_DEBUG("DeltaTSample: " << m_deltaTSample);
2536 ATH_MSG_DEBUG("Presample: " << m_presample);
2537 ATH_MSG_DEBUG("PeakSample: " << m_peakSample);
2538 ATH_MSG_DEBUG("Peak2ndDerivThresh: " << m_Peak2ndDerivThresh);
2539
2540 if (m_combineDelay) ATH_MSG_DEBUG("DelayDeltaT: " << m_delayDeltaT);
2541
2542 ATH_MSG_DEBUG("T0: " << m_t0);
2543 ATH_MSG_DEBUG("Tau1: " << m_tau1);
2544 ATH_MSG_DEBUG("Tau2: " << m_tau2);
2545 ATH_MSG_DEBUG("FixTau1: " << m_fixTau1);
2546 ATH_MSG_DEBUG("FixTau2: " << m_fixTau2);
2547 ATH_MSG_DEBUG("DeltaTCut: " << m_deltaTCut);
2548 ATH_MSG_DEBUG("ChisqRatioCut: " << m_ChisqRatioCut);
2549
2550 Dump_setting(); // for good measure
2551
2552 ATH_CHECK( m_eventInfoKey.initialize());
2553
2554 // Initialize decorations
2555
2557 ATH_CHECK( m_zdcModuleAmplitude.initialize());
2559 ATH_CHECK( m_zdcModuleCalibEnergy.initialize());
2561 ATH_CHECK( m_zdcModuleCalibTime.initialize());
2563 ATH_CHECK( m_zdcModuleStatus.initialize());
2565 ATH_CHECK( m_zdcModuleTime.initialize());
2567 ATH_CHECK( m_zdcModuleChisq.initialize());
2569 ATH_CHECK( m_zdcModuleChisqRatio.initialize());
2571 ATH_CHECK( m_zdcModuleAmpNoNonLin.initialize());
2573 ATH_CHECK( m_zdcModuleFitAmp.initialize());
2575 ATH_CHECK( m_zdcModuleFitAmpError.initialize());
2577 ATH_CHECK( m_zdcModuleFitT0.initialize());
2581 ATH_CHECK( m_zdcModulePreSampleAmp.initialize());
2583 ATH_CHECK( m_zdcModulePresample.initialize());
2585 ATH_CHECK( m_zdcModuleMinDeriv2nd.initialize());
2587 ATH_CHECK( m_zdcModuleMaxADC.initialize());
2588
2590 ATH_CHECK( m_zdcModuleMaxADCHG.initialize());
2592 ATH_CHECK( m_zdcModuleMaxADCLG.initialize());
2593
2594 // LG refit data
2595 //
2597 ATH_CHECK(m_zdcModuleFitAmpLGRefit.initialize());
2599 ATH_CHECK(m_zdcModuleAmpLGRefit.initialize());
2603 ATH_CHECK(m_zdcModuleT0LGRefit.initialize());
2605 ATH_CHECK(m_zdcModuleT0SubLGRefit.initialize());
2607 ATH_CHECK( m_zdcModuleChisqLGRefit.initialize());
2608
2609 // ZDC per-calorimeter data
2610 //
2612 ATH_CHECK( m_zdcSumUncalibSum.initialize());
2614 ATH_CHECK( m_zdcSumUncalibSumErr.initialize());
2616 ATH_CHECK( m_zdcSumCalibEnergy.initialize());
2618 ATH_CHECK( m_zdcSumCalibEnergyErr.initialize());
2620 ATH_CHECK( m_zdcSumNLCalibEnergy.initialize());
2622 ATH_CHECK( m_zdcSumNLCalibEnergyErr.initialize());
2624 ATH_CHECK( m_zdcSumFinalEnergy.initialize());
2626 ATH_CHECK( m_zdcSumAverageTime.initialize());
2628 ATH_CHECK( m_zdcSumStatus.initialize());
2630 ATH_CHECK( m_zdcSumModuleMask.initialize());
2631
2632 if (m_writeAux && m_auxSuffix != "") {
2633 ATH_MSG_DEBUG("suffix string = " << m_auxSuffix);
2634 }
2635
2636 m_init = true;
2637
2638 return StatusCode::SUCCESS;
2639}
2640
2645
2646StatusCode ZdcAnalysisTool::configureNewRun(unsigned int runNumber)
2647{
2648 ATH_MSG_DEBUG("Setting up new run " << runNumber);
2649
2650 // We do nothing for the default configuration
2651 //
2652 if (m_configuration != "default") {
2653 if (m_configuration == "PbPb2015") {
2654 //
2655 // Two periods, 40 MHz and 80 MHz readout
2656 //
2657 if (runNumber < 287222) m_zdcDataAnalyzer = m_zdcDataAnalyzer_40MHz;
2659 }
2660 }
2661
2662 return StatusCode::SUCCESS;
2663}
2664
2665
2666StatusCode ZdcAnalysisTool::recoZdcModules(const xAOD::ZdcModuleContainer& moduleContainer, const xAOD::ZdcModuleContainer& moduleSumContainer)
2667{
2668
2669 if (moduleContainer.size()==0) return StatusCode::SUCCESS; // if no modules, do nothing
2670
2672 if (!eventInfo.isValid()) return StatusCode::FAILURE;
2673
2674 // Check for decoding errors and bail out if ZDC error found
2675 bool zdcErr = eventInfo->isEventFlagBitSet(xAOD::EventInfo::ForwardDet, ZdcEventInfo::ZDCDECODINGERROR );
2676 if (zdcErr)
2677 {
2678 ATH_MSG_WARNING("ZDC decoding error found - abandoning ZDC reco!");
2679 return StatusCode::SUCCESS;
2680 }
2681
2682 // check for new run number, if new, possibly update configuration and/or calibrations
2683 //
2684 unsigned int thisRunNumber = eventInfo->runNumber();
2685 if (thisRunNumber != m_runNumber) {
2686 ATH_MSG_DEBUG("ZDC analysis tool will be configured for run " << thisRunNumber);
2687
2688 ATH_CHECK(configureNewRun(thisRunNumber)); // ALWAYS check methods that return StatusCode
2689
2690 ATH_MSG_DEBUG("Setting up calibrations");
2691
2692 if (m_doFADCCorr)
2693 {
2694 unsigned int calibRunNumber = thisRunNumber;
2695 if (m_forceCalibRun > -1) calibRunNumber = m_forceCalibRun;
2696 try
2697 {
2698 setFADCCorrections(calibRunNumber);
2699 }
2700 catch(std::runtime_error&)
2701 {
2702 m_doFADCCorr = false;
2703 }
2704 }
2705
2706 if (m_doCalib) {
2707 //
2708 // Check for calibration override
2709 //
2710 unsigned int calibRunNumber = thisRunNumber;
2711 if (m_forceCalibRun > -1) calibRunNumber = m_forceCalibRun;
2712 try
2713 {
2714 setEnergyCalibrations(calibRunNumber);
2715 }
2716 catch(std::runtime_error&)
2717 {
2718 m_doCalib = false;
2719 }
2720
2721 if (m_doTrigEff) initializeTriggerEffs(calibRunNumber); // if energy calibrations fail to load, then so will trigger efficiencies
2722 if (m_doTimeCalib) setTimeCalibrations(calibRunNumber);
2723 }
2724
2725 m_runNumber = thisRunNumber;
2726 }
2727
2728 m_lumiBlock = eventInfo->lumiBlock();
2729
2730 unsigned int calibLumiBlock = m_lumiBlock;
2731 if (m_doCalib) {
2732 if (m_forceCalibRun > 0) calibLumiBlock = m_forceCalibLB;
2733 }
2734
2735 ATH_MSG_DEBUG("Starting event processing");
2736 ATH_MSG_DEBUG("LB=" << calibLumiBlock);
2737
2738 m_zdcDataAnalyzer->StartEvent(calibLumiBlock);
2739
2740 static const SG::ConstAccessor<std::vector<uint16_t> > g0dataAcc ("g0data");
2741 static const SG::ConstAccessor<std::vector<uint16_t> > g1dataAcc ("g1data");
2742
2743 const std::vector<unsigned short>* adcUndelayLG = 0;
2744 const std::vector<unsigned short>* adcUndelayHG = 0;
2745
2746 const std::vector<unsigned short>* adcDelayLG = 0;
2747 const std::vector<unsigned short>* adcDelayHG = 0;
2748
2749 ATH_MSG_DEBUG("Processing modules");
2750 for (const auto zdcModule : moduleContainer)
2751 {
2752 int side = -1;
2753 if (zdcModule->zdcSide() == -1) side = 0;
2754 else if (zdcModule->zdcSide() == 1) side = 1;
2755 else {
2756 // Invalid side
2757 //
2758 ATH_MSG_WARNING("Invalid side value found for module number: " << zdcModule->zdcModule() << ", side value = " << side);
2759 continue;
2760 }
2761 // Ignore MC only modules
2762 if(zdcModule->zdcModule() > 4) continue;
2763
2764 if (zdcModule->zdcType() == 0) {
2765 //
2766 // This is ZDC data
2767 //
2768 if (m_LHCRun==3) // no delay channels, so we drop the index
2769 {
2770 adcUndelayLG = &g0dataAcc(*zdcModule); // g0
2771 adcUndelayHG = &g1dataAcc(*zdcModule); // g1
2772 }
2773 else if (m_LHCRun==2)
2774 {
2775
2776
2777 static const SG::ConstAccessor<std::vector<uint16_t> > g0d1dataAcc ("g0d1data");
2778 static const SG::ConstAccessor<std::vector<uint16_t> > g1d1dataAcc ("g1d1data");
2779 static const SG::ConstAccessor<std::vector<uint16_t> > g0d0dataAcc ("g0d0data");
2780 static const SG::ConstAccessor<std::vector<uint16_t> > g1d0dataAcc ("g1d0data");
2781
2782 if (zdcModule->zdcModule() == 0 && m_flipEMDelay) // flip delay/non-delay for 2015 ONLY
2783 {
2784 adcUndelayLG = &g0d1dataAcc(*zdcModule); // g0d1
2785 adcUndelayHG = &g1d1dataAcc(*zdcModule); // g1d1
2786 adcDelayLG = &g0d0dataAcc(*zdcModule); // g0d0
2787 adcDelayHG = &g1d0dataAcc(*zdcModule); // g1d0
2788 }
2789 else // nominal configuation
2790 {
2791 adcUndelayLG = &g0d0dataAcc(*zdcModule); // g0d0
2792 adcUndelayHG = &g1d0dataAcc(*zdcModule); // g1d0
2793 adcDelayLG = &g0d1dataAcc(*zdcModule); // g0d1
2794 adcDelayHG = &g1d1dataAcc(*zdcModule); // g1d1
2795 }
2796 }
2797 else
2798 {
2799 ATH_MSG_WARNING("Unknown LHC Run " << m_LHCRun);
2800 return StatusCode::FAILURE;
2801 }
2802
2803 // Why were these static? to optimize processing time
2804 std::vector<float> HGUndelADCSamples(m_numSample);
2805 std::vector<float> LGUndelADCSamples(m_numSample);
2806
2807 if (LGUndelADCSamples.size() < adcUndelayLG->size()) {
2808 LGUndelADCSamples.resize(adcUndelayLG->size());
2809 }
2810
2811 if (HGUndelADCSamples.size() < adcUndelayHG->size()) {
2812 HGUndelADCSamples.resize(adcUndelayHG->size());
2813 }
2814
2815 std::copy(adcUndelayLG->begin(), adcUndelayLG->end(), LGUndelADCSamples.begin());
2816 std::copy(adcUndelayHG->begin(), adcUndelayHG->end(), HGUndelADCSamples.begin());
2817
2818 int side = (zdcModule->zdcSide() == -1) ? 0 : 1 ;
2819
2820 if (!m_combineDelay) {
2821 m_zdcDataAnalyzer->LoadAndAnalyzeData(side, zdcModule->zdcModule(), HGUndelADCSamples, LGUndelADCSamples);
2822 }
2823 else {
2824 std::vector<float> HGDelayADCSamples(m_numSample);
2825 std::vector<float> LGDelayADCSamples(m_numSample);
2826 if (adcDelayLG and adcDelayHG){
2827 std::copy(adcDelayLG->begin(), adcDelayLG->end(), LGDelayADCSamples.begin());
2828 std::copy(adcDelayHG->begin(), adcDelayHG->end(), HGDelayADCSamples.begin());
2829 }else{
2830 ATH_MSG_ERROR("adcDelayLG or adcDelayHG pointers are null");
2831 return StatusCode::FAILURE;
2832 }
2833 // If the delayed channels actually come earlier (as in the pPb in 2016), we invert the meaning of delayed and undelayed
2834 // see the initialization sections for similar inversion on the sign of the pedestal difference
2835 //
2836
2837 m_zdcDataAnalyzer->LoadAndAnalyzeData(side, zdcModule->zdcModule(),
2838 HGUndelADCSamples, LGUndelADCSamples,
2839 HGDelayADCSamples, LGDelayADCSamples);
2840 }
2841 }
2842 }
2843
2844 ATH_MSG_DEBUG("Finishing event processing");
2845
2846 m_zdcDataAnalyzer->FinishEvent();
2847
2848 ATH_MSG_DEBUG("Adding variables with suffix=" + m_auxSuffix);
2849
2868
2875
2876 // CalibTime
2877 // Status
2878 // Time
2879 // Chisq
2880 // AmpNoNonLin
2881 // FitAmp
2882 // FitAmpError
2883 // FitT0
2884 // BkgdMaxFraction
2885 // PreSampleAmp
2886 // Presample
2887 // MinDeriv2nd
2888 // MaxADC
2889
2890 for (const auto zdcModule : moduleContainer)
2891 {
2892 int side = (zdcModule->zdcSide() == -1) ? 0 : 1 ;
2893 int mod = zdcModule->zdcModule();
2894 // Ignore MC only modules
2895 if(mod > 4) continue;
2896
2897 if (zdcModule->zdcType() == 0) {
2898 // this is the main ZDC
2899 if (m_writeAux) {
2900 float calibEnergy = m_zdcDataAnalyzer->GetModuleCalibAmplitude(side, mod);
2901 zdcModuleCalibEnergy(*zdcModule) = calibEnergy;
2902 zdcModuleCalibTime(*zdcModule) = m_zdcDataAnalyzer->GetModuleCalibTime(side, mod);
2903
2904 zdcModuleAmplitude(*zdcModule) = m_zdcDataAnalyzer->GetModuleAmplitude(side, mod);
2905 zdcModuleStatus(*zdcModule) = m_zdcDataAnalyzer->GetModuleStatus(side, mod);
2906 zdcModuleTime(*zdcModule) = m_zdcDataAnalyzer->GetModuleTime(side, mod);
2907
2908 const ZDCPulseAnalyzer* pulseAna_p = m_zdcDataAnalyzer->GetPulseAnalyzer(side, mod);
2909 zdcModuleChisq(*zdcModule) = pulseAna_p->GetChisq();
2910 zdcModuleChisqRatio(*zdcModule) = pulseAna_p->GetChisqRatio();
2911 zdcModuleAmpNoNonLin(*zdcModule) = pulseAna_p->GetAmpNoNonLin();
2912 zdcModuleFitAmp(*zdcModule) = pulseAna_p->GetFitAmplitude();
2913 zdcModuleFitAmpError(*zdcModule) = pulseAna_p->GetAmpError();
2914 zdcModuleFitT0(*zdcModule) = pulseAna_p->GetFitT0();
2915 zdcModuleBkgdMaxFraction(*zdcModule) = pulseAna_p->GetBkgdMaxFraction();
2916 zdcModulePreSampleAmp(*zdcModule) = pulseAna_p->GetPreSampleAmp();
2917 zdcModulePresample(*zdcModule) = pulseAna_p->getPresample();
2918 zdcModuleMinDeriv2nd(*zdcModule) = pulseAna_p->GetMinDeriv2nd();
2919 zdcModuleMaxADC(*zdcModule) = pulseAna_p->getMaxADCSub();
2920 zdcModuleMaxADCHG(*zdcModule) = pulseAna_p->getMaxADCHG();
2921 zdcModuleMaxADCLG(*zdcModule) = pulseAna_p->getMaxADCLG();
2922
2923 zdcModuleAmpLGRefit(*zdcModule) = pulseAna_p->getRefitLGAmp();
2924 zdcModuleFitAmpLGRefit(*zdcModule) = pulseAna_p->getRefitLGFitAmp();
2925 zdcModuleAmpCorrLGRefit(*zdcModule) = pulseAna_p->getRefitLGAmpCorr();
2926 zdcModuleT0LGRefit(*zdcModule) = pulseAna_p->getRefitLGTime();
2927 zdcModuleT0SubLGRefit(*zdcModule) = pulseAna_p->getRefitLGTimeSub();
2928 zdcModuleChisqLGRefit(*zdcModule) = pulseAna_p->getRefitLGChisq();
2929 }
2930 //ATH_MSG_DEBUG ("side = " << side << " module=" << zdcModule->zdcModule() << " CalibEnergy=" << zdcModule->auxdecor<float>("CalibEnergy")
2931 // << " should be " << m_zdcDataAnalyzer->GetModuleCalibAmplitude(side, mod));
2932 }
2933 }
2934
2935 // Output sum information
2936 // In Run 3 - we have to assume the container already exists (since it is needed to store the per-side trigger info)
2937 // reprocessing will add new variables with the suffix
2938
2949
2950 for (const auto zdc_sum: moduleSumContainer)
2951 {
2952 ATH_MSG_DEBUG("Extracting ZDC side " << zdc_sum->zdcSide());
2953
2954 if (zdc_sum->zdcSide()==0) continue; // skip new global sum
2955
2956 int iside = (zdc_sum->zdcSide()==-1) ? 0 : 1;
2957
2958 float uncalibSum = getUncalibModuleSum(iside);
2959 zdcSumUncalibSum(*zdc_sum) = uncalibSum;
2960 float uncalibSumErr = getUncalibModuleSumErr(iside);
2961 zdcSumUncalibSumErr(*zdc_sum) = uncalibSumErr;
2962
2963 float calibEnergy = getCalibModuleSum(iside);
2964 zdcSumCalibEnergy(*zdc_sum) = calibEnergy;
2965 float calibEnergyErr = getCalibModuleSumErr(iside);
2966 zdcSumCalibEnergyErr(*zdc_sum) = calibEnergyErr;
2967
2968 float nlcalibEnergy = getNLCalibModuleSum(iside);
2969 zdcSumNLCalibEnergy(*zdc_sum) = nlcalibEnergy;
2970 float nlcalibEnergyErr = getNLCalibModuleSumErr(iside);
2971 zdcSumNLCalibEnergyErr(*zdc_sum) = nlcalibEnergyErr;
2972
2973 float finalEnergy = calibEnergy;
2974 zdcSumFinalEnergy(*zdc_sum) = finalEnergy;
2975 zdcSumAverageTime(*zdc_sum) = getAverageTime(iside);
2976 zdcSumStatus(*zdc_sum) = !sideFailed(iside);
2977 zdcSumModuleMask(*zdc_sum) = (getModuleMask() >> (4 * iside)) & 0xF;
2978 }
2979
2980 return StatusCode::SUCCESS;
2981}
2982
2983void ZdcAnalysisTool::setEnergyCalibrations(unsigned int runNumber)
2984{
2985
2986 char name[128];
2987
2988 std::string filename;
2989 if (m_LHCRun==3)
2990 {
2991 filename = PathResolverFindCalibFile( ("ZdcAnalysis/ZdcCalib_Run"+TString::Itoa(runNumber,10)+".root").Data() );
2992 }
2993 else if (m_LHCRun==2)
2994 {
2995 filename = PathResolverFindCalibFile( ("ZdcAnalysis/" + m_zdcEnergyCalibFileName).c_str() );
2996 }
2997 else
2998 {
2999 ATH_MSG_WARNING("No LHC Run defined, so no calibration allowed");
3000 return;
3001 }
3002
3003 ATH_MSG_INFO("Opening energy calibration file " << filename);
3004 std::unique_ptr<TFile> fCalib (TFile::Open(filename.c_str(), "READ"));
3005
3006 if (fCalib == nullptr || fCalib->IsZombie())
3007 {
3008 ATH_MSG_INFO ("failed to open file: " << filename);
3009 throw std::runtime_error ("failed to open file " + filename);
3010 }
3011
3012 std::array<std::array<std::unique_ptr<TSpline>, 4>, 2> splines;
3013
3014 // "m_calibVersion", called CalibVersion when settings parameters in python, is a directory within the run-based calibration file
3015 TString calibVersion;
3016 if (m_calibVersion != "") calibVersion = m_calibVersion + "/";
3017
3018 for (int iside = 0; iside < 2; iside++)
3019 {
3020 for (int imod = 0; imod < 4; imod++)
3021 {
3022 sprintf(name, "ZDC_Ecalib_run%u_s%d_m%d", runNumber, iside, imod);
3023 ATH_MSG_DEBUG("Searching for spline " << name);
3024 TSpline3* s = (TSpline3*) fCalib->GetObjectChecked(calibVersion+TString(name), "TSpline3");
3025 if (!s && m_doCalib)
3026 {
3027 ATH_MSG_WARNING("No calibrations for run " << runNumber);
3028 m_doCalib = false;
3029 }
3030
3031 if (s)
3032 {
3033 splines[iside][imod].reset (s);
3034 }
3035 else
3036 {
3037 ATH_MSG_WARNING("No spline " << name);
3038 }
3039 }
3040 }
3041 fCalib->Close();
3042
3043 if (m_doCalib) m_zdcDataAnalyzer->LoadEnergyCalibrations(std::move(splines));
3044
3045 return;
3046}
3047
3048void ZdcAnalysisTool::setTimeCalibrations(unsigned int runNumber)
3049{
3050 std::string filename;
3051
3052 if (m_LHCRun==3)
3053 {
3054 filename = PathResolverFindCalibFile( ("ZdcAnalysis/ZdcCalib_Run"+TString::Itoa(runNumber,10)+".root").Data() );
3055 }
3056 else if (m_LHCRun==2)
3057 {
3058 filename = PathResolverFindCalibFile( "ZdcAnalysis/" + m_zdcTimeCalibFileName );
3059 }
3060 else
3061 {
3062 ATH_MSG_WARNING("No LHC Run defined, so no time calibration allowed");
3063 return;
3064 }
3065
3066 char name[128] = {0};
3067 ATH_MSG_INFO("Opening time calibration file " << filename);
3068 std::unique_ptr<TFile> fCalib (TFile::Open(filename.c_str(), "READ"));
3069
3070 // "m_calibVersion", called CalibVersion when settings parameters in python, is a directory within the run-based calibration file
3071 TString calibVersion = "";
3072 if (m_calibVersion != "") calibVersion = m_calibVersion + "/";
3073
3074 if (fCalib && !fCalib->IsZombie())
3075 {
3076 bool success = true;
3077 std::array<std::array<std::unique_ptr<TSpline>, 4>, 2> T0HGOffsetSplines;
3078 std::array<std::array<std::unique_ptr<TSpline>, 4>, 2> T0LGOffsetSplines;
3079 std::unique_ptr<TSpline3> spline;
3080 for (int iside = 0; iside < 2; iside++)
3081 {
3082 for (int imod = 0; imod < 4; imod++)
3083 {
3084 sprintf(name, "ZDC_T0calib_run%u_HG_s%d_m%d", runNumber, iside, imod);
3085 spline.reset (static_cast<TSpline3*>(fCalib->GetObjectChecked(calibVersion+TString(name), "TSpline3")));
3086 if (spline)
3087 {
3088 T0HGOffsetSplines[iside][imod] = std::move (spline);
3089 }
3090 else
3091 {
3092 ATH_MSG_WARNING("No time calib. spline " << calibVersion+name);
3093 success = false;
3094 }
3095
3096 sprintf(name, "ZDC_T0calib_run%u_LG_s%d_m%d", runNumber, iside, imod);
3097 spline.reset (static_cast<TSpline3*>(fCalib->GetObjectChecked(calibVersion+TString(name), "TSpline3")));
3098 if (spline)
3099 {
3100 T0LGOffsetSplines[iside][imod] = std::move (spline);
3101 }
3102 else
3103 {
3104 ATH_MSG_WARNING("No time calib. spline " << calibVersion+name);
3105 success = false;
3106 }
3107 }
3108 }
3109
3110 if (success)
3111 m_zdcDataAnalyzer->LoadT0Calibrations(std::move(T0HGOffsetSplines), std::move(T0LGOffsetSplines));
3112 else
3113 ATH_MSG_WARNING("Time calibration failed - no T0 offsets loaded " << calibVersion+name);
3114
3115 fCalib->Close();
3116 }
3117 else
3118 {
3119 ATH_MSG_WARNING("No time calibration file " << filename);
3120 }
3121}
3122
3123void ZdcAnalysisTool::setFADCCorrections(unsigned int runNumber)
3124{
3125 std::string filename;
3126
3127 if (m_LHCRun==3) {
3128 std::string runString;
3129
3130 if (runNumber == 0) runString = "ZdcFADCCorr_" + m_configuration + "_default.root";
3131 else runString = ("ZdcFADCCorr_Run"+TString::Itoa(runNumber,10)+".root").Data();
3132
3133 filename = PathResolverFindCalibFile("ZdcAnalysis/" + runString );
3134 }
3135 else {
3136 ATH_MSG_WARNING("setFADCCorrections: FADC corrections not implemented for Run 2");
3137 return;
3138 }
3139
3140 if (filename.empty())
3141 {
3142 ATH_MSG_INFO("FADC correction requested but no calibration file found");
3143 m_doFADCCorr = false;
3144 return;
3145 }
3146
3147 ATH_MSG_INFO("Opening FADC corrections file " << filename);
3148 std::unique_ptr<TFile> fFADCCorr(TFile::Open(filename.c_str(), "READ"));
3149
3150 if (!fFADCCorr->IsOpen()) {
3151 ATH_MSG_INFO ("setFADCCorrections: failed to open file: " << filename);
3152 throw std::runtime_error ("ZdcAnalysisTool failed to open FADCCorrections file " + filename);
3153 }
3154
3155 // Attempt to read histograms with corrections from file
3156 //
3157 bool readSuccess = true;
3158 std::array<std::array<std::unique_ptr<const TH1>, 4>, 2> histogramsHG;
3159 std::array<std::array<std::unique_ptr<const TH1>, 4>, 2> histogramsLG;
3160
3161 for (size_t side : {0, 1}) {
3162 for (int module : {0, 1, 2, 3}) {
3163 std::string histNameHG = "ZDC_FADCCorr_s" + std::to_string(side) + "_m" + std::to_string(module)+"_HG";
3164 std::string histNameLG = "ZDC_FADCCorr_s" + std::to_string(side) + "_m" + std::to_string(module)+"_LG";
3165
3166 ATH_MSG_DEBUG("setFADCCorrections: Searching for histograms HG and LG: " << histNameHG << ", " << histNameLG);
3167
3168 TH1* histHG_ptr = static_cast<TH1*>(fFADCCorr->GetObjectChecked(histNameHG.c_str(), "TH1"));
3169 TH1* histLG_ptr = static_cast<TH1*>(fFADCCorr->GetObjectChecked(histNameLG.c_str(), "TH1"));
3170
3171 if (!histHG_ptr || !histLG_ptr) {
3172 std::string errMsg = "setFADCCorrections: unable to read FADC correction histogram(s) ";
3173 if (!histHG_ptr) errMsg += histNameHG + " ";
3174 if (!histLG_ptr) errMsg += histNameLG;
3175
3176 ATH_MSG_ERROR(errMsg);
3177 readSuccess = false;
3178 break;
3179 }
3180 else {
3181 //
3182 // Check for valid range (Lion uses -0.5 to 4095.5)
3183 //
3184
3185 if ( std::abs(histHG_ptr->GetXaxis()->GetXmin()+0.5) > 1e-3 || std::abs(histHG_ptr->GetXaxis()->GetXmax() - 4095.5) > 1e-3) {
3186 ATH_MSG_ERROR("setFADCCorrections: invalid axis range for HG FADC corrections in histogram with name " << histNameHG);
3187 readSuccess = false;
3188 break;
3189 }
3190 if (std::abs(histLG_ptr->GetXaxis()->GetXmin()+0.5) > 1e-3 || std::abs(histLG_ptr->GetXaxis()->GetXmax() - 4095.5) > 1e-3) {
3191 ATH_MSG_ERROR("setFADCCorrections: invalid axis range for HG FADC corrections in histogram with name " << histNameLG);
3192 readSuccess = false;
3193 break;
3194 }
3195
3196 histogramsHG[side][module].reset(histHG_ptr);
3197 histogramsLG[side][module].reset(histLG_ptr);
3198 }
3199 }
3200 }
3201
3202 fFADCCorr->Close();
3203
3204 if (readSuccess) {
3205 m_zdcDataAnalyzer->enableFADCCorrections(m_doFADCCorrPerSample, histogramsHG, histogramsLG);
3206 }
3207 else {
3208 ATH_MSG_ERROR("setFADCCorrections: due to at least one error, FADC corrections are not implemented");
3209 m_doFADCCorr = false;
3210 }
3211
3212 return;
3213}
3214
3215
3217{
3218 if (!m_init)
3219 {
3220 ATH_MSG_WARNING("Tool not initialized!");
3221 return StatusCode::FAILURE;
3222 }
3223 m_eventReady = false;
3224 ATH_MSG_DEBUG ("Trying to retrieve " << m_zdcModuleContainerName);
3225
3226 m_zdcModules = 0;
3228
3229 m_zdcSums = 0;
3231
3232 m_eventReady = true;
3233
3235
3236 return StatusCode::SUCCESS;
3237}
3238
3239bool ZdcAnalysisTool::sigprocMaxFinder(const std::vector<unsigned short>& adc, float deltaT, float& amp, float& time, float& qual)
3240{
3241 size_t nsamp = adc.size();
3242 float presamp = adc.at(0);
3243 unsigned short max_adc = 0;
3244 int max_index = -1;
3245 for (size_t i = 0; i < nsamp; i++)
3246 {
3247 if (adc[i] > max_adc)
3248 {
3249 max_adc = adc[i];
3250 max_index = i;
3251 }
3252 }
3253 amp = max_adc - presamp;
3254 time = max_index * deltaT;
3255 qual = 1.;
3256
3257 if (max_index == -1)
3258 {
3259 qual = 0.;
3260 return false;
3261 }
3262
3263 return true;
3264}
3265
3266bool ZdcAnalysisTool::sigprocSincInterp(const std::vector<unsigned short>& adc, float deltaT, float& amp, float& time, float& qual)
3267{
3268 size_t nsamp = adc.size();
3269 float presamp = adc.at(0);
3270 m_tf1SincInterp->SetParameter(0, deltaT);
3271 for (size_t i = 0; i < nsamp; i++)
3272 {
3273 m_tf1SincInterp->SetParameter(i + 1, adc.at(i) - presamp);
3274 }
3275 amp = m_tf1SincInterp->GetMaximum();
3276 time = m_tf1SincInterp->GetMaximumX();
3277 qual = 1.;
3278 return true;
3279}
3280
3282{
3283 if (!m_zdcDataAnalyzer) return 0;
3284 return m_zdcDataAnalyzer->GetModuleSum(side);
3285}
3286
3288{
3289 if (!m_zdcDataAnalyzer) return 0;
3290 return m_zdcDataAnalyzer->GetCalibModuleSum(side);
3291}
3292
3294{
3295 if (!m_zdcDataAnalyzer) return 0;
3296 return m_zdcDataAnalyzer->GetCalibModuleSumErr(side);
3297}
3298
3300{
3301 if (!m_zdcDataAnalyzer) return 0;
3302 return m_zdcDataAnalyzer->GetNLcalibModuleSum(side);
3303}
3304
3306{
3307 if (!m_zdcDataAnalyzer) return 0;
3308 return m_zdcDataAnalyzer->GetNLcalibModuleSumErr(side);
3309}
3310
3312{
3313 if (!m_zdcDataAnalyzer) return 0;
3314 return m_zdcDataAnalyzer->GetModuleSum(side);
3315}
3316
3318{
3319 if (!m_zdcDataAnalyzer) return 0;
3320 return m_zdcDataAnalyzer->GetModuleSumErr(side);
3321}
3322
3324{
3325 if (!m_zdcDataAnalyzer) return 0;
3326 return m_zdcDataAnalyzer->GetAverageTime(side);
3327}
3328
3330{
3331 if (!m_zdcDataAnalyzer) return 0;
3332 return m_zdcDataAnalyzer->SideFailed(side);
3333}
3334
3336{
3337 if (!m_zdcDataAnalyzer) return 0;
3338 return m_zdcDataAnalyzer->GetModuleMask();
3339}
3340
3342{
3343 if (!m_doTrigEff) return -1;
3344
3345 m_zdcTriggerEfficiency->UpdatelumiBlock(m_lumiBlock);
3346 float adcSum = getModuleSum(side);
3347 double eff = m_zdcTriggerEfficiency->GetEfficiency(side, adcSum);
3348 return eff;
3349}
3350
3352{
3353 if (!m_doCalib) return -1;
3354
3355 m_zdcTriggerEfficiency->UpdatelumiBlock(m_lumiBlock);
3356 float adcSum = getModuleSum(side);
3357 std::pair<double, double> eff_pair = m_zdcTriggerEfficiency->GetEfficiencyAndError(msg(), side, adcSum);
3358 return eff_pair.second;
3359}
3360
3361
3362} // namespace ZDC
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
Handle class for recording to StoreGate.
@ Data
Definition BaseObject.h:11
Helper class to provide constant type-safe access to aux data.
static Double_t t0
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Define enumerations for event-level ZDC data.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
size_type size() const noexcept
Returns the number of elements in the collection.
Helper class to provide constant type-safe access to aux data.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
std::array< std::array< bool, 4 >, 2 > ZDCModuleBoolArray
std::array< std::array< float, 4 >, 2 > ZDCModuleFloatArray
std::array< std::array< int, 4 >, 2 > ZDCModuleIntArray
float GetAmpError() const
float GetFitT0() const
float getMaxADCLG() const
float getRefitLGAmpCorr() const
float getRefitLGAmp() const
float GetChisqRatio() const
float getRefitLGChisq() const
float GetFitAmplitude() const
float GetAmpNoNonLin() const
float getRefitLGTimeSub() const
float getMaxADCHG() const
float GetChisq() const
float getRefitLGFitAmp() const
float GetMinDeriv2nd() const
float getPresample() const
float getMaxADCSub() const
float GetPreSampleAmp() const
float getRefitLGTime() const
float GetBkgdMaxFraction() const
static bool sigprocMaxFinder(const std::vector< unsigned short > &adc, float deltaT, float &amp, float &time, float &qual)
void setEnergyCalibrations(unsigned int runNumber)
std::string m_zdcTriggerEffParamsFileName
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleAmpLGRefit
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleFitT0
std::unique_ptr< ZDCDataAnalyzer > initializeInjectorPbPb2024()
std::unique_ptr< TF1 > m_tf1SincInterp
std::unique_ptr< ZDCDataAnalyzer > initializepO2025()
double getTriggerEfficiency(int side)
ZdcAnalysisTool(const std::string &name)
float getCalibModuleSumErr(int side)
std::shared_ptr< ZDCDataAnalyzer > m_zdcDataAnalyzer
std::unique_ptr< ZDCDataAnalyzer > initializePbPb2024()
void setTimeCalibrations(unsigned int runNumber)
std::shared_ptr< ZDCDataAnalyzer > m_zdcDataAnalyzer_80MHz
std::unique_ptr< ZDCDataAnalyzer > initializepp2024()
ZDCDataAnalyzer::ZDCModuleFloatArray m_peak2ndDerivMinThresholdsHG
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleMaxADC
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleT0SubLGRefit
std::unique_ptr< ZDCDataAnalyzer > initializepPb2016()
std::shared_ptr< ZDCTriggerEfficiency > m_zdcTriggerEfficiency
virtual ~ZdcAnalysisTool() override
std::unique_ptr< ZDCDataAnalyzer > initializeInjectorpp2024()
StatusCode initialize() override
Dummy implementation of the initialisation function.
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumModuleMask
std::string m_zdcSumContainerName
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleT0LGRefit
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleChisqLGRefit
float getCalibModuleSum(int side)
StatusCode recoZdcModules(const xAOD::ZdcModuleContainer &moduleContainer, const xAOD::ZdcModuleContainer &moduleSumContainer) override
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumStatus
std::unique_ptr< ZDCDataAnalyzer > initializeLHCf2022()
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleChisqRatio
std::string m_zdcAnalysisConfigPath
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumCalibEnergyErr
std::unique_ptr< ZDCDataAnalyzer > initializeMonteCarloPbPb2023()
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumNLCalibEnergy
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumUncalibSum
ZDCDataAnalyzer::ZDCModuleIntArray m_peak2ndDerivMinSamples
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleMaxADCHG
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumAverageTime
const xAOD::ZdcModuleContainer * m_zdcModules
std::unique_ptr< ZDCDataAnalyzer > initializeInjectorpOOONeNe2025()
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleTime
ZDCMsg::MessageFunctionPtr MakeMessageFunction()
std::shared_ptr< ZDCDataAnalyzer > m_zdcDataAnalyzer_40MHz
float getUncalibModuleSum(int side)
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumCalibEnergy
float getNLCalibModuleSumErr(int side)
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleFitAmpLGRefit
std::unique_ptr< ZDCDataAnalyzer > initializepO2025B()
std::string m_zdcEnergyCalibFileName
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumUncalibSumErr
const xAOD::ZdcModuleContainer * m_zdcSums
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumFinalEnergy
std::unique_ptr< ZDCDataAnalyzer > initializePbPb2015G4()
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleMinDeriv2nd
std::unique_ptr< ZDCDataAnalyzer > initializeOONeNe2025()
double getTriggerEfficiencyUncertainty(int side)
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleAmpCorrLGRefit
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleChisq
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleFitAmp
float getNLCalibModuleSum(int side)
ZDCDataAnalyzer::ZDCModuleFloatArray m_peak2ndDerivMinThresholdsLG
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleFitAmpError
std::string m_zdcModuleContainerName
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModulePresample
float getAverageTime(int side)
StatusCode configureNewRun(unsigned int runNumber)
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleMaxADCLG
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleAmplitude
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcSumNLCalibEnergyErr
std::unique_ptr< ZDCDataAnalyzer > initializeFromJSON()
std::unique_ptr< ZDCDataAnalyzer > initializepp2023()
std::unique_ptr< ZDCDataAnalyzer > initializeDefault()
std::unique_ptr< ZDCDataAnalyzer > initializePbPb2018()
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleStatus
std::string m_zdcTimeCalibFileName
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleCalibEnergy
std::string m_jsonConfigurationFile
void initializeTriggerEffs(unsigned int runNumber)
StatusCode reprocessZdc() override
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleBkgdMaxFraction
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
std::unique_ptr< ZDCDataAnalyzer > initializePbPb2023()
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleAmpNoNonLin
float getUncalibModuleSumErr(int side)
bool sigprocSincInterp(const std::vector< unsigned short > &adc, float deltaT, float &amp, float &time, float &qual)
float getModuleSum(int side)
void setFADCCorrections(unsigned int runNumber=0)
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModulePreSampleAmp
SG::WriteDecorHandleKey< xAOD::ZdcModuleContainer > m_zdcModuleCalibTime
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
@ ForwardDet
The forward detectors.
double SincInterp(const double *xvec, const double *pvec)
ZdcModuleContainer_v1 ZdcModuleContainer
MsgStream & msg
Definition testRead.cxx:32
TFile * file