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::array<float,6>, 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 int deriv2ndThreshDSHG = -45;
837 const int deriv2ndThreshDSLG = -10;
838 const unsigned int peakSample = 10;
839
840 const float deltaTcutLow = -10;
841 const float deltaTcutHigh = 10;
842 const float chisqDivAmpCutHGVal = 30;
843 const float chisqDivAmpCutLGVal = 50;
844
845 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
846 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
847
848 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
849 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
850 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
851
852 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
853 {1.35, 1.4, 1.3, 1.1}}};
854
855 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
856
857 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.5, 31.5, 29.5, 30.5}, {34.5, 33.0, 33, 34.0}}};
858 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{32.25, 32.0, 30.5, 30.5}, {32.4, 33.5, 30.5, 31.4}}};
859
860 for (size_t side : {0, 1}) {
861 for (size_t module : {0, 1, 2, 3}) {
862 fixTau1Arr[side][module] = true;
863 fixTau2Arr[side][module] = false;
864
865 peak2ndDerivMinSamples[side][module] = peakSample;
866 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
867 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
868
869 deltaT0CutLow[side][module] = deltaTcutLow;
870 deltaT0CutHigh[side][module] = deltaTcutHigh;
871 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
872 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
873 }
874 }
875
876 ATH_MSG_DEBUG( "PbPb2024: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
877
878 // Construct the data analyzer
879 //
880 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
882 m_presample, "FermiExpLHCf",
883 peak2ndDerivMinSamples,
884 peak2ndDerivMinThresholdsHG,
885 peak2ndDerivMinThresholdsLG,
887 zdcDataAnalyzer->set2ndDerivStep(1);
888 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
889
890 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1.0}}};
891 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{4,4,4,4}, {4,4,4,4}}};
892
893 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 4 applied to LG ADC, 1 to HG ADC values
894
895 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
896 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
897 //
898 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.5, 1.5, 1.5, 1.5}, {1.5, 1.5, 1.5, 1.5}}};
899 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
900
901 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
902
903 // Now set cuts and default fit parameters
904 //
905 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
906 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
907 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
908
909 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
910 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
911 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
912
913 // Enable two-pass analysis
914 //
915 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-30, -30, -30, -30},
916 {-30, -30, -30, -30},}};
917
918 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
919 {-8, -8, -8, -8}}};
920
921 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
922
923 // Turn on exclusion of early and late samples to address OOT pileup
924 //
925 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
926 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
927
928 // Set up non-linear corrections for the ZDC
929 //
930 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
931
932 nonLinearCorrCoefficHG[0][0] = {-0.0225871, 0.00702802, 0.00201155, -0.00675293, 0.00186212} ;
933 nonLinearCorrCoefficHG[0][1] = {-0.0155562, 0.00594092, 0.00382112, -0.00665466, 0.00143384} ;
934 nonLinearCorrCoefficHG[0][2] = {-0.0313621, 0.0134528, 0.00529013, -0.0111751, 0.0029913} ;
935 nonLinearCorrCoefficHG[0][3] = {-0.025108, 0.00301898, 0.022472, -0.0204288, 0.00453215} ;
936 nonLinearCorrCoefficHG[1][0] = {-0.0266648, 0.0106792, -0.00939959, 0.000833011, 0.000199051} ;
937 nonLinearCorrCoefficHG[1][1] = {-0.0246541, 0.000327376, 0.00754946, -0.00710273, 0.00136899} ;
938 nonLinearCorrCoefficHG[1][2] = {-0.0175283, 0.0127954, 0.000235749, -0.00769698, 0.00221995} ;;
939 nonLinearCorrCoefficHG[1][3] = {-0.0279931, 0.0188122, 0.0126234, -0.0169907, 0.00398826} ;
940
941
942 // Remove nonlinear corrections while we study the injector pulse
943 nonLinearCorrCoefficHG = {{ {{{0},
944 {0},
945 {0},
946 {0}}},
947 {{{0},
948 {0},
949 {0},
950 {0}}} }};
951
952 //
953 // We are disabling the old FADC correction moving forward
954 if (m_doNonLinCorr)
955 zdcDataAnalyzer->SetNonlinCorrParams(1000, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
956
957 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
958 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
959 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
960 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
961 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
962
963 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
964 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
965 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
966 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
967
968 // +++ BAC 07-26-24
969 //
970 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
971 // made at the same time to match the timing shift of the LG channels
972 //
973 // ---
974 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
975 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
976 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
977 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
978
979 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
980 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
981 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
982 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
983
984 // Commenting out the timing correlation for PbPb2024: re-calibraton needed
985 // zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
986
987 // Set the amplitude fit range limits
988 //
989 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
990
991
992 /*
993{{
994 {{{{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}}}},
995 {{{{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}}}}
996 }};
997 */
998
999 std::array< std::array< std::array<float,6>, 3>, 2> nlCalib = {{
1000 {{ {{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}} }},
1001 {{ {{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}} }}
1002 }};
1003
1004 zdcDataAnalyzer->SetNLcalibParams(nlCalib);
1005
1006 return zdcDataAnalyzer;
1007}
1008
1009std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializepO2025()
1010{
1011 // Key configuration parameters needed for the data analyzer construction
1012 //
1013 m_deltaTSample = 3.125;
1014 m_numSample = 24;
1015
1016 const int deriv2ndThreshDSHG = -45;
1017 const int deriv2ndThreshDSLG = -10;
1018 const unsigned int peakSample = 10;
1019
1020 const float deltaTcutLow = -10;
1021 const float deltaTcutHigh = 10;
1022 const float chisqDivAmpCutHGVal = 30;
1023 const float chisqDivAmpCutLGVal = 50;
1024
1025 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1026 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1027
1028 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1029 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1030 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1031
1032 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
1033 {1.35, 1.4, 1.3, 1.1}}};
1034
1035 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
1036
1037 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.5, 31.5, 29.5, 30.5}, {34.5, 33.0, 33, 34.0}}};
1038 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{32.25, 32.0, 30.5, 30.5}, {32.4, 33.5, 30.5, 31.4}}};
1039
1040 for (size_t side : {0, 1}) {
1041 for (size_t module : {0, 1, 2, 3}) {
1042 fixTau1Arr[side][module] = true;
1043 fixTau2Arr[side][module] = false;
1044
1045 peak2ndDerivMinSamples[side][module] = peakSample;
1046 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1047 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1048
1049 deltaT0CutLow[side][module] = deltaTcutLow;
1050 deltaT0CutHigh[side][module] = deltaTcutHigh;
1051 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1052 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1053 }
1054 }
1055
1056 ATH_MSG_DEBUG( "PbPb2024: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1057
1058 // Construct the data analyzer
1059 //
1060 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1062 m_presample, "FermiExpLHCf",
1063 peak2ndDerivMinSamples,
1064 peak2ndDerivMinThresholdsHG,
1065 peak2ndDerivMinThresholdsLG,
1067 zdcDataAnalyzer->set2ndDerivStep(1);
1068 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1069
1070 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1.0}}};
1071 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{4,4,4,4}, {4,4,4,4}}};
1072
1073 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1074
1075 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1076 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1077 //
1078 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.5, 1.5, 1.5, 1.5}, {1.5, 1.5, 1.5, 1.5}}};
1079 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
1080
1081 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1082
1083 // Now set cuts and default fit parameters
1084 //
1085 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1086 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1087 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1088
1089 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1090 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1091 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1092
1093 // Enable two-pass analysis
1094 //
1095 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-30, -30, -30, -30},
1096 {-30, -30, -30, -30},}};
1097
1098 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
1099 {-8, -8, -8, -8}}};
1100
1101 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
1102
1103 // Turn on exclusion of early and late samples to address OOT pileup
1104 //
1105 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
1106 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
1107
1108 // Set up non-linear corrections for the ZDC
1109 //
1110 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
1111
1112 nonLinearCorrCoefficHG[0][0] = {-0.0225871, 0.00702802, 0.00201155, -0.00675293, 0.00186212} ;
1113 nonLinearCorrCoefficHG[0][1] = {-0.0155562, 0.00594092, 0.00382112, -0.00665466, 0.00143384} ;
1114 nonLinearCorrCoefficHG[0][2] = {-0.0313621, 0.0134528, 0.00529013, -0.0111751, 0.0029913} ;
1115 nonLinearCorrCoefficHG[0][3] = {-0.025108, 0.00301898, 0.022472, -0.0204288, 0.00453215} ;
1116 nonLinearCorrCoefficHG[1][0] = {-0.0266648, 0.0106792, -0.00939959, 0.000833011, 0.000199051} ;
1117 nonLinearCorrCoefficHG[1][1] = {-0.0246541, 0.000327376, 0.00754946, -0.00710273, 0.00136899} ;
1118 nonLinearCorrCoefficHG[1][2] = {-0.0175283, 0.0127954, 0.000235749, -0.00769698, 0.00221995} ;;
1119 nonLinearCorrCoefficHG[1][3] = {-0.0279931, 0.0188122, 0.0126234, -0.0169907, 0.00398826} ;
1120
1121
1122 // Remove nonlinear corrections while we study the injector pulse
1123 nonLinearCorrCoefficHG = {{ {{{0},
1124 {0},
1125 {0},
1126 {0}}},
1127 {{{0},
1128 {0},
1129 {0},
1130 {0}}} }};
1131
1132 //
1133 // We are disabling the old FADC correction moving forward
1134 if (m_doNonLinCorr)
1135 zdcDataAnalyzer->SetNonlinCorrParams(1000, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
1136
1137 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
1138 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
1139 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
1140 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
1141 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
1142
1143 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
1144 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
1145 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
1146 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
1147
1148 // +++ BAC 07-26-24
1149 //
1150 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
1151 // made at the same time to match the timing shift of the LG channels
1152 //
1153 // ---
1154 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
1155 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
1156 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
1157 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
1158
1159 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
1160 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
1161 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
1162 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
1163
1164 // Commenting out the timing correlation for PbPb2024: re-calibraton needed
1165 // zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1166
1167 // Set the amplitude fit range limits
1168 //
1169 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1170
1171 zdcDataAnalyzer->disableModule(0, 0); // required since EM not installed
1172
1173 return zdcDataAnalyzer;
1174}
1175
1176std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializepO2025B()
1177{
1178 // Key configuration parameters needed for the data analyzer construction
1179 //
1180 m_deltaTSample = 3.125;
1181 m_numSample = 24;
1182
1183 const int deriv2ndThreshDSHG = -45;
1184 const int deriv2ndThreshDSLG = -10;
1185 const unsigned int peakSample = 10;
1186
1187 const float deltaTcutLow = -10;
1188 const float deltaTcutHigh = 10;
1189 const float chisqDivAmpCutHGVal = 30;
1190 const float chisqDivAmpCutLGVal = 50;
1191
1192 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1193 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1194
1195 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1196 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1197 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1198
1199 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
1200 {1.35, 1.4, 1.3, 1.1}}};
1201
1202 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
1203
1204 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.5, 31.5, 29.5, 30.5}, {34.5, 33.0, 33, 34.0}}};
1205 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{32.25, 32.0, 30.5, 30.5}, {32.4, 33.5, 30.5, 31.4}}};
1206
1207 for (size_t side : {0, 1}) {
1208 for (size_t module : {0, 1, 2, 3}) {
1209 fixTau1Arr[side][module] = true;
1210 fixTau2Arr[side][module] = false;
1211
1212 peak2ndDerivMinSamples[side][module] = peakSample;
1213 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1214 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1215
1216 deltaT0CutLow[side][module] = deltaTcutLow;
1217 deltaT0CutHigh[side][module] = deltaTcutHigh;
1218 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1219 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1220 }
1221 }
1222
1223 ATH_MSG_DEBUG( "PbPb2024: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1224
1225 // Construct the data analyzer
1226 //
1227 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1229 m_presample, "FermiExpLHCf",
1230 peak2ndDerivMinSamples,
1231 peak2ndDerivMinThresholdsHG,
1232 peak2ndDerivMinThresholdsLG,
1234 zdcDataAnalyzer->set2ndDerivStep(1);
1235 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1236
1237 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1.0}}}; //
1238 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{4,4,4,4}, {3,4,4,4}}}; // decided to move the change to the HG/LG ratio
1239
1240 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1241
1242 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1243 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1244 //
1245 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.5, 1.5, 1.5, 1.5}, {1.5, 1.5, 1.5, 1.5}}};
1246 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
1247
1248 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1249
1250 // Now set cuts and default fit parameters
1251 //
1252 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1253 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1254 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1255
1256 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1257 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1258 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1259
1260 // Enable two-pass analysis
1261 //
1262 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-30, -30, -30, -30},
1263 {-30, -30, -30, -30},}};
1264
1265 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
1266 {-8, -8, -8, -8}}};
1267
1268 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
1269
1270 // Turn on exclusion of early and late samples to address OOT pileup
1271 //
1272 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
1273 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
1274
1275 // Set up non-linear corrections for the ZDC
1276 //
1277 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
1278
1279 nonLinearCorrCoefficHG[0][0] = {-0.0225871, 0.00702802, 0.00201155, -0.00675293, 0.00186212} ;
1280 nonLinearCorrCoefficHG[0][1] = {-0.0155562, 0.00594092, 0.00382112, -0.00665466, 0.00143384} ;
1281 nonLinearCorrCoefficHG[0][2] = {-0.0313621, 0.0134528, 0.00529013, -0.0111751, 0.0029913} ;
1282 nonLinearCorrCoefficHG[0][3] = {-0.025108, 0.00301898, 0.022472, -0.0204288, 0.00453215} ;
1283 nonLinearCorrCoefficHG[1][0] = {-0.0266648, 0.0106792, -0.00939959, 0.000833011, 0.000199051} ;
1284 nonLinearCorrCoefficHG[1][1] = {-0.0246541, 0.000327376, 0.00754946, -0.00710273, 0.00136899} ;
1285 nonLinearCorrCoefficHG[1][2] = {-0.0175283, 0.0127954, 0.000235749, -0.00769698, 0.00221995} ;;
1286 nonLinearCorrCoefficHG[1][3] = {-0.0279931, 0.0188122, 0.0126234, -0.0169907, 0.00398826} ;
1287
1288
1289 // Remove nonlinear corrections while we study the injector pulse
1290 nonLinearCorrCoefficHG = {{ {{{0},
1291 {0},
1292 {0},
1293 {0}}},
1294 {{{0},
1295 {0},
1296 {0},
1297 {0}}} }};
1298
1299 //
1300 // We are disabling the old FADC correction moving forward
1301 if (m_doNonLinCorr)
1302 zdcDataAnalyzer->SetNonlinCorrParams(1000, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
1303
1304 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
1305 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
1306 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
1307 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
1308 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
1309
1310 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
1311 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
1312 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
1313 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
1314
1315 // +++ BAC 07-26-24
1316 //
1317 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
1318 // made at the same time to match the timing shift of the LG channels
1319 //
1320 // ---
1321 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
1322 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
1323 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
1324 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
1325
1326 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
1327 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
1328 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
1329 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
1330
1331 // Commenting out the timing correlation for PbPb2024: re-calibraton needed
1332 // zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1333
1334 // Set the amplitude fit range limits
1335 //
1336 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1337
1338 zdcDataAnalyzer->disableModule(0, 0); // required since EM not installed
1339
1340 return zdcDataAnalyzer;
1341}
1342
1343std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeInjectorpp2024()
1344{
1345 // Key configuration parameters needed for the data analyzer construction
1346 //
1347 m_deltaTSample = 3.125;
1348 m_numSample = 24;
1349
1350 const int deriv2ndThreshDSHG = -10;
1351 const int deriv2ndThreshDSLG = -10;
1352 const unsigned int peakSample = 10;
1353
1354 const float deltaTcutLow = -50;
1355 const float deltaTcutHigh = 50;
1356 const float chisqDivAmpCutHGVal = 30;
1357 const float chisqDivAmpCutLGVal = 50;
1358
1359 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1360 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1361
1362 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1363 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1364 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1365
1366 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.2, 1.4, 1.3, 1.2},
1367 {1.35, 1.4, 1.3, 1.1}}};
1368
1369 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
1370
1371 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.25, 31.25, 31.25, 31.25}, {31.25, 31.25, 31.25, 31.25}}};
1372 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{28, 28, 28, 28}, {28, 28, 28, 28}}};
1373
1374 for (size_t side : {0, 1}) {
1375 for (size_t module : {0, 1, 2, 3}) {
1376 fixTau1Arr[side][module] = false;
1377 fixTau2Arr[side][module] = true;
1378
1379 peak2ndDerivMinSamples[side][module] = peakSample;
1380 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1381 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1382
1383 deltaT0CutLow[side][module] = deltaTcutLow;
1384 deltaT0CutHigh[side][module] = deltaTcutHigh;
1385 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1386 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1387 }
1388 }
1389
1390 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1391
1392 // Construct the data analyzer
1393 //
1394 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1396 m_presample, "FermiExpLHCf",
1397 peak2ndDerivMinSamples,
1398 peak2ndDerivMinThresholdsHG,
1399 peak2ndDerivMinThresholdsLG,
1401 zdcDataAnalyzer->set2ndDerivStep(2);
1402 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(10);
1403
1404 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1405 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1406
1407 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1408
1409 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1410 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1411 //
1412 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1413 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{10.0, 10.0, 10.0, 10.0}, {10.0, 10.0, 10.0, 10.0}}};
1414
1415 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1416
1417 // Now set cuts and default fit parameters
1418 //
1419 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1420 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1421 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1422
1423 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1424 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1425 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1426
1427 // Turn on exclusion of early and late samples to address OOT pileup
1428 //
1429 zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
1430 zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
1431
1432
1433 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
1434 timeCorrCoefficHG[0][0] = {0.07, -0.020672, 0.070206, 0.004961, -0.010821, -0.001835};
1435 timeCorrCoefficHG[0][1] = {0.04, -0.012961, 0.008204, 0.010771, 0.011593, 0.002045};
1436 timeCorrCoefficHG[0][2] = {0.04, 0.017393, 0.017597, 0.003736, -0.001696, -0.000465};
1437 timeCorrCoefficHG[0][3] = {0.04, 0.018463, 0.009862, -0.000277, -0.000268, 0.000192};
1438
1439 timeCorrCoefficHG[1][0] = {0.13, -0.106068, 0.078153, 0.034479, -0.004964, -0.001688};
1440 timeCorrCoefficHG[1][1] = {0.03, -0.007518, 0.008937, 0.015319, 0.012290, 0.001889};
1441 timeCorrCoefficHG[1][2] = {-0.01, 0.006711, -0.001652, -0.004223, -0.000573, 0.000161};
1442 timeCorrCoefficHG[1][3] = {0.015, 0.017993, 0.006339, 0.003122, 0.002980, 0.000735};
1443
1444 // +++ BAC 07-26-24
1445 //
1446 // The +3.25 in the constant t0 correction term accounts for a change in the nominal T0 from 31.25 to 28
1447 // made at the same time to match the timing shift of the LG channels
1448 //
1449 // ---
1450 timeCorrCoefficLG[0][0] = {0.035f+3.25f, -0.126189, 0.022724, 0.039116, -0.098255};
1451 timeCorrCoefficLG[0][1] = {0.022f+3.25f, -0.165988, -0.014125, 0.057323, -0.205109};
1452 timeCorrCoefficLG[0][2] = {0.01f+3.25f, -0.136087, -0.007248, -0.014452, -0.060469};
1453 timeCorrCoefficLG[0][3] = {0.0f+3.25f, -0.131067, 0.025579, 0.059994, -0.065595};
1454
1455 timeCorrCoefficLG[1][0] = {0.076f+3.25f, -0.300587, -0.041827, 0.641108, -0.594157};
1456 timeCorrCoefficLG[1][1] = {0.057f+3.25f, -0.223443, -0.125013, -0.176900, 0.348081};
1457 timeCorrCoefficLG[1][2] = {0.015f+3.25f, -0.141721, 0.023936, 0.099657, -0.188526};
1458 timeCorrCoefficLG[1][3] = {0.01f+3.25f, -0.152589, 0.016122, -0.086580, 0.563625};
1459
1460 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1461
1462 // Set the amplitude fit range limits
1463 //
1464 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1465
1466 return zdcDataAnalyzer;
1467}
1468
1469std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeInjectorPbPb2024()
1470{
1471 // Key configuration parameters needed for the data analyzer construction
1472 //
1473 m_deltaTSample = 3.125;
1474 m_numSample = 24;
1475
1476 const int deriv2ndThreshDSHG = -25;
1477 const int deriv2ndThreshDSLG = -10;
1478 const unsigned int peakSample = 10;
1479
1480 const float deltaTcutLow = -10;
1481 const float deltaTcutHigh = 10;
1482 const float chisqDivAmpCutHGVal = 30;
1483 const float chisqDivAmpCutLGVal = 50;
1484
1485 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1486 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1487
1488 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1489 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1490 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1491
1492 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.8, 1.8, 1.8, 1.8}, {1.8, 1.8, 1.8, 1.8}}};
1493
1494 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{5.5, 5.5, 5.5, 5.5}, {5.5, 5.5, 5.5, 5.5}}};
1495
1496 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{33.25, 33, 29.5, 33}, {31.5, 32.5, 32, 32.25}}};
1497 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{30.5, 30, 26.75, 30}, {29.5, 32.5, 29.5, 29}}};
1498
1499 for (size_t side : {0, 1}) {
1500 for (size_t module : {0, 1, 2, 3}) {
1501 fixTau1Arr[side][module] = false;
1502 fixTau2Arr[side][module] = true;
1503
1504 peak2ndDerivMinSamples[side][module] = peakSample;
1505 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1506 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1507
1508 deltaT0CutLow[side][module] = deltaTcutLow;
1509 deltaT0CutHigh[side][module] = deltaTcutHigh;
1510 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1511 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1512 }
1513 }
1514
1515 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1516
1517 // Construct the data analyzer
1518 //
1519 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1521 m_presample, "FermiExpLHCf",
1522 peak2ndDerivMinSamples,
1523 peak2ndDerivMinThresholdsHG,
1524 peak2ndDerivMinThresholdsLG,
1526
1527 zdcDataAnalyzer->set2ndDerivStep(2);
1528 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1529
1530 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1531 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{10, 10, 10, 10}, {10, 10, 10, 10}}};
1532
1533 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1534
1535 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1536 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1537 //
1538 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{2.0, 2.0, 2.0, 2.0}, {2.0, 2.0, 2.0, 2.0}}};
1539 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{15.0, 15.0, 15.0, 15.0}, {15.0, 15.0, 15.0, 15.0}}};
1540
1541 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1542
1543 // Now set cuts and default fit parameters
1544 //
1545 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1546 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1547 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1548
1549 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1550 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1551 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1552
1553 // Set the amplitude fit range limits
1554 //
1555 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1556
1557 return zdcDataAnalyzer;
1558}
1559
1560std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeInjectorpOOONeNe2025()
1561{
1562 // Key configuration parameters needed for the data analyzer construction
1563 //
1564 m_deltaTSample = 3.125;
1565 m_numSample = 24;
1566
1567 const int deriv2ndThreshDSHG = -25;
1568 const int deriv2ndThreshDSLG = -10;
1569 const unsigned int peakSample = 10;
1570
1571 const float deltaTcutLow = -10;
1572 const float deltaTcutHigh = 10;
1573 const float chisqDivAmpCutHGVal = 30;
1574 const float chisqDivAmpCutLGVal = 50;
1575
1576 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1577 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1578
1579 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1580 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1581 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1582
1583 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.8, 1.8, 1.8, 1.8}, {1.8, 1.8, 1.8, 1.8}}};
1584
1585 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{5.5, 5.5, 5.5, 5.5}, {5.5, 5.5, 5.5, 5.5}}};
1586
1587 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{33.25, 33, 29.5, 33}, {31.5, 32.5, 32, 32.25}}};
1588 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{30.5, 30, 26.75, 30}, {29.5, 32.5, 29.5, 29}}};
1589
1590 for (size_t side : {0, 1}) {
1591 for (size_t module : {0, 1, 2, 3}) {
1592 fixTau1Arr[side][module] = false;
1593 fixTau2Arr[side][module] = true;
1594
1595 peak2ndDerivMinSamples[side][module] = peakSample;
1596 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1597 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1598
1599 deltaT0CutLow[side][module] = deltaTcutLow;
1600 deltaT0CutHigh[side][module] = deltaTcutHigh;
1601 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1602 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1603 }
1604 }
1605
1606 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1607
1608 // Construct the data analyzer
1609 //
1610 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1612 m_presample, "FermiExpLHCf",
1613 peak2ndDerivMinSamples,
1614 peak2ndDerivMinThresholdsHG,
1615 peak2ndDerivMinThresholdsLG,
1617
1618 zdcDataAnalyzer->set2ndDerivStep(2);
1619 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1620
1621 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1622 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{4,4,4,4}, {4,4,4,4}}};
1623
1624 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 4 applied to LG ADC, 1 to HG ADC values
1625
1626 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1627 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1628 //
1629 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{2.0, 2.0, 2.0, 2.0}, {2.0, 2.0, 2.0, 2.0}}};
1630 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{15.0, 15.0, 15.0, 15.0}, {15.0, 15.0, 15.0, 15.0}}};
1631
1632 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1633
1634 // Now set cuts and default fit parameters
1635 //
1636 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1637 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1638 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1639
1640 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1641 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1642 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1643
1644 // Set the amplitude fit range limits
1645 //
1646 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1647
1648 return zdcDataAnalyzer;
1649}
1650
1651std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeMonteCarloPbPb2023()
1652{
1653 // Key configuration parameters needed for the data analyzer construction
1654 //
1655 m_deltaTSample = 3.125;
1656 m_numSample = 24;
1657
1658 const int deriv2ndThreshDSHG = -25;
1659 const int deriv2ndThreshDSLG = -10;
1660 const unsigned int peakSample = 10;
1661
1662 const float deltaTcutLow = -10;
1663 const float deltaTcutHigh = 10;
1664 const float chisqDivAmpCutHGVal = 30;
1665 const float chisqDivAmpCutLGVal = 50;
1666
1667 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples;
1668 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG;
1669
1670 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow, deltaT0CutHigh;
1671 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG, chisqDivAmpCutLG;
1672 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr, fixTau2Arr;
1673
1674 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{1.1, 1.1, 1.1, 1.1},
1675 {1.1, 1.1, 1.1, 1.1}}};
1676
1677 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{4.4, 4.7, 4.5, 4.6}, {4.8, 4.6, 4.4, 4.2}}};
1678
1679 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{31.25, 31.25, 31.25, 31.25}, {31.25, 31.25, 31.25, 31.25}}};
1680 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{31.25, 31.25, 31.25, 31.25}, {31.25, 31.25, 31.25, 31.25}}};
1681
1682 for (size_t side : {0, 1}) {
1683 for (size_t module : {0, 1, 2, 3}) {
1684 fixTau1Arr[side][module] = false;
1685 fixTau2Arr[side][module] = false;
1686
1687 peak2ndDerivMinSamples[side][module] = peakSample;
1688 peak2ndDerivMinThresholdsHG[side][module] = deriv2ndThreshDSHG;
1689 peak2ndDerivMinThresholdsLG[side][module] = deriv2ndThreshDSLG;
1690
1691 deltaT0CutLow[side][module] = deltaTcutLow;
1692 deltaT0CutHigh[side][module] = deltaTcutHigh;
1693 chisqDivAmpCutLG[side][module] = chisqDivAmpCutLGVal;
1694 chisqDivAmpCutHG[side][module] = chisqDivAmpCutHGVal;
1695 }
1696 }
1697
1698 ATH_MSG_DEBUG( "PbPb2023: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1699
1700 // Construct the data analyzer
1701 //
1702 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(),
1704 m_presample, "FermiExpLHCf",
1705 peak2ndDerivMinSamples,
1706 peak2ndDerivMinThresholdsHG,
1707 peak2ndDerivMinThresholdsLG,
1708 m_lowGainMode));
1709 zdcDataAnalyzer->set2ndDerivStep(2);
1710 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(3);
1711
1712 ZDCDataAnalyzer::ZDCModuleFloatArray gainsHG = {{{1, 1, 1, 1},{1, 1, 1, 1}}};
1713 ZDCDataAnalyzer::ZDCModuleFloatArray gainsLG = {{{10.,10.,10.,10.},{10.,10.,10.,10.}}}; // apply constant factor of 10 to high gain data
1714
1715 zdcDataAnalyzer->SetGainFactorsHGLG(gainsHG, gainsLG); // a gain adjustment of 10 applied to LG ADC, 1 to HG ADC values
1716
1717 // These noise sigmas we read off from the ch_x_BaselineStdev monitoring histograms with our
1718 // final readout configuration for the Pb+Pb run by BAC on 25-09-2023
1719 //
1720 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1.0, 1.0, 1.0, 1.0}, {1.0, 1.0, 1.0, 1.0}}};
1721 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{1.5, 1.7, 3, 1.7}, {1.7, 1.6, 2.2, 1.8}}};
1722
1723 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
1724
1725 // Now set cuts and default fit parameters
1726 //
1727 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{3500, 3500, 3500, 3500}}, {{3500, 3500, 3500, 3500}}}};
1728 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{1, 1, 1, 1}}, {{1, 1, 1, 1}}}};
1729 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{4000, 4000, 4000, 4000}}, {{4000, 4000, 4000, 4000}}}};
1730
1731 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1732 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
1733 zdcDataAnalyzer->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1734
1735 // Enable two-pass analysis
1736 //
1737 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassHG = {{{-10, -10, -10, -10},
1738 {-10, -10, -10, -10}}};
1739
1740 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinRepassLG = {{{-8, -8, -8, -8},
1741 {-8, -8, -8, -8}}};
1742
1743 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG);
1744
1745 // Turn on exclusion of early and late samples to address OOT pileup
1746 //
1747 //zdcDataAnalyzer->enablePreExclusion(4, 500, 200);
1748 //zdcDataAnalyzer->enablePostExclusion(4, 300, 200);
1749
1750 // Set up non-linear corrections for the ZDC
1751 //
1752 std::array<std::array<std::vector<float>, 4>, 2> nonLinearCorrCoefficHG, nonLinearCorrCoefficLG;
1753
1754 nonLinearCorrCoefficHG = {{ {{{0},
1755 {0},
1756 {0},
1757 {0}}},
1758 {{{0},
1759 {0},
1760 {0},
1761 {0}}} }};
1762
1763 // For now we don't use corrections on the LG as it's much harder to measure them
1764 //
1765 nonLinearCorrCoefficLG = {{ {{{0},
1766 {0},
1767 {0},
1768 {0}}},
1769 {{{0},
1770 {0},
1771 {0},
1772 {0}}} }};
1773
1774 if (m_doNonLinCorr)
1775 zdcDataAnalyzer->SetNonlinCorrParams(0, 1000, nonLinearCorrCoefficHG, nonLinearCorrCoefficLG);
1776
1777 std::array<std::array<std::vector<float>, 4>, 2> timeCorrCoefficHG, timeCorrCoefficLG;
1778 timeCorrCoefficHG[0][0] = {};
1779 timeCorrCoefficHG[0][1] = {};
1780 timeCorrCoefficHG[0][2] = {};
1781 timeCorrCoefficHG[0][3] = {};
1782
1783 timeCorrCoefficHG[1][0] = {};
1784 timeCorrCoefficHG[1][1] = {};
1785 timeCorrCoefficHG[1][2] = {};
1786 timeCorrCoefficHG[1][3] = {};
1787
1788 timeCorrCoefficLG[0][0] = {};
1789 timeCorrCoefficLG[0][1] = {};
1790 timeCorrCoefficLG[0][2] = {};
1791 timeCorrCoefficLG[0][3] = {};
1792
1793 timeCorrCoefficLG[1][0] = {};
1794 timeCorrCoefficLG[1][1] = {};
1795 timeCorrCoefficLG[1][2] = {};
1796 timeCorrCoefficLG[1][3] = {};
1797
1798 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLog, 0, 700, timeCorrCoefficHG, timeCorrCoefficLG);
1799
1800 // Set the amplitude fit range limits
1801 //
1802 zdcDataAnalyzer->SetFitMinMaxAmpValues(2, 2, 6000, 6000);
1803
1804 return zdcDataAnalyzer;
1805}
1806
1807std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializeDefault()
1808{
1809 // We rely completely on the default parameters specified in the job properties to control:
1810 // # samples
1811 // frequency (more precisely, time/sample)
1812 // which sample to use as the pre-sample
1813 // where to expact the maxim of the peak (min 2nd derivative)
1814 // thresholds on the 2nd derivative for valid pulses
1815 // whether to fix the tau values in the pulse fitting
1816 // the default tau values
1817 // the nominal T0
1818 // delta T and chisq/amp cuts
1819 //
1820 // For now, we continue to use hard-coded values for the maximum and minimum ADC values
1821 // For now we also use the FermiExp pulse model.
1822 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
1823 ZDCDataAnalyzer::ZDCModuleFloatArray tau1{}, tau2{}, t0{};
1824 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
1825 ZDCDataAnalyzer::ZDCModuleFloatArray deltaT0CutLow{}, deltaT0CutHigh{}, chisqDivAmpCut{};
1826 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
1827
1828 for (size_t side : {0, 1}) {
1829 for (size_t module : {0, 1, 2, 3}) {
1830 fixTau1Arr[side][module] = m_fixTau1;
1831 fixTau2Arr[side][module] = m_fixTau2;
1832 tau1[side][module] = m_tau1;
1833 tau2[side][module] = m_tau2;
1834
1835 peak2ndDerivMinSamples[side][module] = m_peakSample;
1836 peak2ndDerivMinThresholdsHG[side][module] = -m_Peak2ndDerivThresh;
1837 peak2ndDerivMinThresholdsLG[side][module] = -m_Peak2ndDerivThresh / 2;
1838
1839 t0[side][module] = m_t0;
1840 deltaT0CutLow[side][module] = -m_deltaTCut;
1841 deltaT0CutHigh[side][module] = m_deltaTCut;
1842 chisqDivAmpCut[side][module] = m_ChisqRatioCut;
1843 }
1844 }
1845
1846 ATH_MSG_DEBUG( "Default: delta t cut, value low = " << deltaT0CutLow[0][0] << ", high = " << deltaT0CutHigh[0][0] );
1847
1848 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
1849 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
1850 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
1851
1852 // Construct the data analyzer
1853 //
1854 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(), m_numSample, m_deltaTSample, m_presample, "FermiExp", peak2ndDerivMinSamples,
1855 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode));
1856
1857 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1858 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0, t0);
1859 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, deltaT0CutLow, deltaT0CutHigh, deltaT0CutLow, deltaT0CutHigh);
1860
1861 if (m_combineDelay) {
1862 ZDCDataAnalyzer::ZDCModuleFloatArray defaultPedestalShifts = {{{{0, 0, 0, 0}}, {{0, 0, 0, 0}}}};
1863
1864 zdcDataAnalyzer->enableDelayed(m_delayDeltaT, defaultPedestalShifts);
1865 }
1866
1867 return zdcDataAnalyzer;
1868}
1869
1870std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializePbPb2015G4()
1871{
1872 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
1873 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
1874 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
1875 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCut{};
1876 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
1877
1878 const int peakSample = 4;
1879 const float peak2ndDerivThreshHG = -12;
1880 const float peak2ndDerivThreshLG = -10;
1881 ZDCDataAnalyzer::ZDCModuleFloatArray tau1Arr = {{{4.000, 4.000, 4.000, 4.000},
1882 {4.000, 4.000, 4.000, 4.000}}};
1883 ZDCDataAnalyzer::ZDCModuleFloatArray tau2Arr = {{{25.36, 25.05, 25.43, 25.60},
1884 {25.11, 25.08, 25.18, 25.48}}};
1885
1886 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{57.31, 57.28, 57.30, 57.28},
1887 {57.28, 57.29, 57.31, 57.33}}};
1888 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{57.31, 57.28, 57.30, 57.28},
1889 {57.28, 57.29, 57.31, 57.33}}};
1890
1891 // Delta T0 cut
1892 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{-10, -10, -10, -10}, {-10, -10, -10, -10}}};
1893 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{ 10, 10, 10, 10}, { 10, 10, 10, 10}}};
1894 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{-10, -10, -10, -10}, {-10, -10, -10, -10}}};
1895 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{ 10, 10, 10, 10}, { 10, 10, 10, 10}}};
1896
1897 for (size_t side : {0, 1}) {
1898 for (size_t module : {0, 1, 2, 3}) {
1899 fixTau1Arr[side][module] = true;
1900 fixTau2Arr[side][module] = true;
1901
1902 peak2ndDerivMinSamples[side][module] = peakSample;
1903 peak2ndDerivMinThresholdsHG[side][module] = peak2ndDerivThreshHG;
1904 peak2ndDerivMinThresholdsLG[side][module] = peak2ndDerivThreshLG;
1905
1906 chisqDivAmpCut[side][module] = 15;
1907 }
1908 }
1909
1910 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{ 800, 800, 800, 800}}, {{ 800, 800, 800, 800}}}};
1911 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{ 10, 10, 10, 10}}, {{ 10, 10, 10, 10}}}};
1912 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
1913
1914 m_deltaTSample = 12.5;
1915
1916 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(), 7, m_deltaTSample, 0, "FermiExp", peak2ndDerivMinSamples,
1917 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode));
1918
1919 // Open up tolerances on the position of the peak for now
1920 //
1921 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(1);
1922
1923 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
1924 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1Arr, tau2Arr, t0HG, t0LG);
1925 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
1926
1927 zdcDataAnalyzer->SetFitTimeMax(85);
1928
1929 return zdcDataAnalyzer;
1930}
1931
1932std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializepPb2016()
1933{
1934 //
1935 // For now, we continue to use hard-coded values for the maximum and minimum ADC values
1936 // For now we also use the FermiExp pulse model.
1937
1938 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
1939 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{};
1940 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCut{};
1941 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
1942
1943 // For now we allow the tau values to be controlled by the job properties until they are better determined
1944 //
1945 const int peakSample = 5;
1946 const float peak2ndDerivThreshHG = -12;
1947 const float peak2ndDerivThreshLG = -10;
1948 ZDCDataAnalyzer::ZDCModuleFloatArray tau1Arr = {{{4.000, 3.380, 3.661, 3.679},
1949 {4.472, 4.656, 3.871, 4.061}
1950 }};
1951
1952 ZDCDataAnalyzer::ZDCModuleFloatArray tau2Arr = {{{22, 24.81, 24.48, 24.45},
1953 {24.17, 24.22, 25.46, 24.45}
1954 }};
1955
1956 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{70.00, 72.74, 73.09, 72.25},
1957 {75.11, 74.94, 73.93, 74.45}
1958 }};
1959 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{70.00, 73.41, 74.27, 73.30},
1960 {76.28, 76.07, 74.98, 76.54}
1961 }};
1962
1963 // Delta T0 cut
1964 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{ -6, -5, -5, -5}, {-5, -5, -5, -5}}};
1965 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{8, 8, 8, 11}, {8, 10, 8, 12}}};
1966 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{ -6, -5, -5, -5}, {-5, -5, -5, -5}}};
1967 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{8, 8, 8, 11}, {8, 10, 8, 12}}};
1968
1969
1970 for (size_t side : {0, 1}) {
1971 for (size_t module : {0, 1, 2, 3}) {
1972 fixTau1Arr[side][module] = true;
1973 fixTau2Arr[side][module] = true;
1974
1975 peak2ndDerivMinSamples[side][module] = peakSample;
1976 peak2ndDerivMinThresholdsHG[side][module] = peak2ndDerivThreshHG;
1977 peak2ndDerivMinThresholdsLG[side][module] = peak2ndDerivThreshLG;
1978
1979 chisqDivAmpCut[side][module] = 15;
1980 }
1981 }
1982
1983 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
1984 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
1985 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
1986
1987 std::array<std::array<std::vector<float>, 4>, 2> slewingParamsHG, slewingParamsLG;
1988 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
1989 slewingParamsHG[0][0] = {0, 0, 0, 0};
1990 slewingParamsHG[0][1] = { -4.780244e-01, -7.150874e-02, 4.614585e-02, 8.015731e-04};
1991 slewingParamsHG[0][2] = { -5.253412e-01, -5.718167e-02, 5.243121e-02, 2.128398e-03};
1992 slewingParamsHG[0][3] = { -5.773952e-01, -5.687478e-02, 4.564267e-02, 1.462294e-03};
1993
1994 slewingParamsHG[1][0] = { 7.105115e-01, -3.686143e-02, 7.727447e-02, 5.924152e-03};
1995 slewingParamsHG[1][1] = { 4.052120e-02, 4.450686e-03, 8.031615e-02, 4.038097e-03};
1996 slewingParamsHG[1][2] = { 3.389476e-02, -2.056782e-02, 4.805321e-02, -2.627999e-03};
1997 slewingParamsHG[1][3] = { 2.069765e-01, -2.890419e-02, 6.084375e-02, 3.742011e-03};
1998
1999 slewingParamsLG[0][0] = {0, 0, 0, 0};
2000 slewingParamsLG[0][1] = { -1.632547e+00, -4.827813e-01, -1.379131e-01, -2.522607e-02};
2001 slewingParamsLG[0][2] = { -7.254288e+00, -5.454064e+00, -1.619126e+00, -1.739665e-01};
2002 slewingParamsLG[0][3] = { -1.548400e+01, -1.277708e+01, -3.729333e+00, -3.700458e-01};
2003
2004 slewingParamsLG[1][0] = { 1.142767e-01, -3.608906e-02, 9.642735e-02, -3.097043e-03};
2005 slewingParamsLG[1][1] = { -5.615388e-01, -1.655047e-02, 8.327350e-02, -4.231348e-03};
2006 slewingParamsLG[1][2] = { -7.370728e-01, -2.887482e-02, 8.293875e-02, -4.482743e-03};
2007 slewingParamsLG[1][3] = { -1.270636e+00, -2.791777e-01, -5.807295e-02, -2.332612e-02};
2008
2009 // Construct the data analyzer
2010 //
2011 // We adopt hard-coded values for the number of samples and the frequency which we kept fixed for all physics data
2012 //
2013 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer (new ZDCDataAnalyzer(MakeMessageFunction(), 7, 25, 0, "FermiExpLinear", peak2ndDerivMinSamples,
2014 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode));
2015
2016 // Open up tolerances on the position of the peak for now
2017 //
2018 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(1);
2019
2020 // We alwyas disable the 12EM (sideC) module which was not present (LHCf)
2021 //
2022 zdcDataAnalyzer->disableModule(0, 0);
2023
2024 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
2025 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1Arr, tau2Arr, t0HG, t0LG);
2026 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
2027
2028 // We allow the combineDelay to be controlled by the properties
2029 //
2030 // if (m_combineDelay) {
2031 m_combineDelay = true;
2032 ZDCDataAnalyzer::ZDCModuleFloatArray defaultPedestalShifts = {{{{0, 0, 0, 0}}, {{0, 0, 0, 0}}}};
2033
2034 zdcDataAnalyzer->enableDelayed(-12.5, defaultPedestalShifts);
2035 zdcDataAnalyzer->SetFitTimeMax(140); // This restrict the fit range of the pulse fitting
2036 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLin, 500, 100,
2037 slewingParamsHG, slewingParamsLG); // add time slewing correction Sep 17 2019 Bill
2038 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
2039
2040 return zdcDataAnalyzer;
2041}
2042
2043std::unique_ptr<ZDCDataAnalyzer> ZdcAnalysisTool::initializePbPb2018()
2044{
2045 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples{};
2046 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG{}, peak2ndDerivMinThresholdsLG{}, peak2ndDerivMinRepassHG{}, peak2ndDerivMinRepassLG{};
2047 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCut{};
2048 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
2049
2050 static constexpr int peakSample = 5;
2051 static constexpr float peak2ndDerivThreshHG = -35;
2052 static constexpr float peak2ndDerivThreshLG = -20;
2053 static constexpr float peak2ndDerivRepassHG = -10;
2054 static constexpr float peak2ndDerivRepassLG = -6;
2055
2056 ZDCDataAnalyzer::ZDCModuleFloatArray tau1Arr = {{{3.877, 3.998, 3.821, 3.858},
2057 {4.296, 4.064, 3.497, 3.642}
2058 }};
2059
2060 ZDCDataAnalyzer::ZDCModuleFloatArray tau2Arr = {{{24.40, 25.28, 25.66, 24.12},
2061 {24.42, 24.99, 25.72, 25.29}
2062 }};
2063
2064 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{70.51, 70.57, 70.13, 69.98},
2065 {74.18, 72.79, 71.77, 72.62}
2066 }};
2067 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{70.70, 70.78, 70.76, 70.91},
2068 {75.16, 73.71, 72.25, 73.61}
2069 }};
2070
2071 ZDCDataAnalyzer::ZDCModuleFloatArray moduleAmpFractionLG = {{{0.2760, 0.3045, 0.2369, 0.1826},
2072 {0.3216, 0.2593, 0.2511, 0.1680}
2073 }};
2074
2075 // Delta T0 cut
2076 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{ -6, -5, -5, -5}, {-5, -5, -5, -5}}};
2077 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{8, 8, 8, 11}, {8, 10, 8, 12}}};
2078 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{ -6, -5, -5, -5}, {-5, -5, -5, -5}}};
2079 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{8, 8, 8, 11}, {8, 10, 8, 12}}};
2080
2081 for (size_t side : {0, 1}) {
2082 for (size_t module : {0, 1, 2, 3}) {
2083 fixTau1Arr[side][module] = true;
2084 fixTau2Arr[side][module] = true;
2085
2086 peak2ndDerivMinSamples[side][module] = peakSample;
2087 peak2ndDerivMinThresholdsHG[side][module] = peak2ndDerivThreshHG;
2088 peak2ndDerivMinThresholdsLG[side][module] = peak2ndDerivThreshLG;
2089 peak2ndDerivMinRepassHG [side][module] = peak2ndDerivRepassHG;
2090 peak2ndDerivMinRepassLG [side][module] = peak2ndDerivRepassLG;
2091
2092 chisqDivAmpCut[side][module] = 15;
2093 }
2094 }
2095
2096 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
2097 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2098 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
2099
2100 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasLG = {{{1, 1, 1, 1}, {1, 1, 1, 1}}};
2101 ZDCDataAnalyzer::ZDCModuleFloatArray noiseSigmasHG = {{{12, 12, 12, 12}, {12, 12, 12, 12}}};
2102
2103
2104 std::array<std::array<std::vector<float>, 4>, 2> slewingParamsHG, slewingParamsLG;
2105 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
2106 slewingParamsHG[0][0] = { -1.335560e-01, -6.071869e-03, 5.858193e-02, 2.473300e-03};
2107 slewingParamsHG[0][1] = { -1.223062e-01, -4.379469e-02, 4.452285e-02, 2.130210e-03};
2108 slewingParamsHG[0][2] = { -1.021415e-01, -4.254239e-02, 4.939866e-02, 3.849738e-03};
2109 slewingParamsHG[0][3] = { -8.234056e-02, -3.938803e-02, 4.689029e-02, 2.784816e-03};
2110
2111 slewingParamsHG[1][0] = { -1.640979e-01, -2.780350e-02, 5.755065e-02, -4.244651e-04};
2112 slewingParamsHG[1][1] = { -1.422324e-01, 2.663803e-02, 7.295366e-02, 3.740496e-03};
2113 slewingParamsHG[1][2] = { -9.858124e-02, -2.426132e-02, 4.895967e-02, 2.291393e-03};
2114 slewingParamsHG[1][3] = { -1.070401e-01, -2.256383e-03, 5.833770e-02, 2.255208e-03};
2115
2116 slewingParamsLG[0][0] = { -2.588446e-01, -3.241086e-02, 7.828661e-02, 1.945547e-03};
2117 slewingParamsLG[0][1] = { -3.112495e-01, -7.419508e-02, 6.825776e-02, 2.148860e-03};
2118 slewingParamsLG[0][2] = { -3.470650e-01, -5.836748e-02, 6.204396e-02, 1.550421e-03};
2119 slewingParamsLG[0][3] = { -4.485435e-01, -4.603790e-02, 5.944799e-02, -1.174585e-03};
2120
2121 slewingParamsLG[1][0] = { -3.291676e-01, -4.023732e-02, 8.608755e-02, -3.958167e-03};
2122 slewingParamsLG[1][1] = { -2.608969e-01, -2.129786e-03, 6.930791e-02, -4.141910e-03};
2123 slewingParamsLG[1][2] = { -2.505712e-01, -2.195804e-02, 5.137261e-02, -4.058378e-03};
2124 slewingParamsLG[1][3] = { -5.083206e-01, 3.776601e-02, 1.284275e-01, 1.014067e-02};
2125
2126 // Construct the data analyzer
2127 //
2128 // We adopt hard-coded values for the number of samples and the frequency which we kept fixed for all physics data
2129 //
2130 std::unique_ptr<ZDCDataAnalyzer> zdcDataAnalyzer = std::make_unique<ZDCDataAnalyzer>(MakeMessageFunction(), 7, 25, 0, "FermiExpLinear", peak2ndDerivMinSamples, // presample index changed to zero 4/6/19
2131 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode);
2132
2133 // Open up tolerances on the position of the peak for now
2134 //
2135 zdcDataAnalyzer->SetPeak2ndDerivMinTolerances(1);
2136
2137 // We alwyas disable the 12EM (sideC) module which was not present (LHCf)
2138 //
2139
2140 zdcDataAnalyzer->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
2141 zdcDataAnalyzer->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1Arr, tau2Arr, t0HG, t0LG);
2142 zdcDataAnalyzer->SetModuleAmpFractionLG(moduleAmpFractionLG); // fraction calculation for LGOverflows added Nov 23, 2020
2143 zdcDataAnalyzer->SetCutValues(chisqDivAmpCut, chisqDivAmpCut, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
2144
2145 // We allow the combineDelay to be controlled by the properties
2146 //
2147 m_combineDelay = true;
2148 ZDCDataAnalyzer::ZDCModuleFloatArray defaultPedestalShifts = {{{{0, 0, 0, 0}}, {{0, 0, 0, 0}}}};
2149
2150 // We use per-module delays to handle the delayed-undelayed swap on EMC
2151 //
2152 ZDCDataAnalyzer::ZDCModuleFloatArray delayDeltaTs = {{{{12.5, -12.5, -12.5, -12.5}},
2153 {{ -12.5, -12.5, -12.5, -12.5}}
2154 }
2155 };
2156
2157 zdcDataAnalyzer->enableDelayed(delayDeltaTs, defaultPedestalShifts);
2158 zdcDataAnalyzer->SetFitTimeMax(140); // This restrict the fit range of the pulse fitting, requested by BAC 4/6/19
2159 zdcDataAnalyzer->enableRepass(peak2ndDerivMinRepassHG, peak2ndDerivMinRepassLG); // add repass as default Jul 21 2020 Bill
2160 zdcDataAnalyzer->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLin, 500, 100,
2161 slewingParamsHG, slewingParamsLG); // add time slewing correction Sep 17 2019 Bill
2162 // ref. https://indico.cern.ch/event/849143/contributions/3568263/attachments/1909759/3155352/ZDCWeekly_20190917_PengqiYin.pdf
2163
2164 zdcDataAnalyzer->SetNoiseSigmas(noiseSigmasHG, noiseSigmasLG);
2165
2166 return zdcDataAnalyzer;
2167}
2168
2170{
2171 // We have a complete configuration and so we override all of the default parameters
2172 //
2173
2174 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{{4.2, 3.8, 5.2, 5.0}},
2175 {{5.0, 3.7, 3.5, 3.5}}
2176 }
2177 };
2178
2179 // identical to 80 MHz -- is this right
2180 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{{20.0, 20.4, 18.9, 20.8}},
2181 {{19.1, 21.9, 22.6, 23.4}}
2182 }
2183 };
2184
2185 ZDCDataAnalyzer::ZDCModuleIntArray peak2ndDerivMinSamples = {{{{1, 1, 2, 1}},
2186 {{1, 1, 1, 1}}
2187 }
2188 };
2189
2190 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsHG = {{{{ -8, -8, -8, -8}},
2191 {{ -8, -8, -8, -8}}
2192 }
2193 };
2194
2195 ZDCDataAnalyzer::ZDCModuleFloatArray peak2ndDerivMinThresholdsLG = {{{{ -4, -4, -4, -4}},
2196 {{ -4, -4, -4, -4}}
2197 }
2198 };
2199
2200 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
2201 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2202 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{1020, 1020, 1020, 1020}}, {{1020, 1020, 1020, 1020}}}};
2203
2204 // Set Tau and nominal timing offsets
2205 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
2206
2207 bool fixTau1 = true;
2208 bool fixTau2 = true;
2209
2210 for (size_t side : {0, 1}) {
2211 for (size_t module : {0, 1, 2, 3}) {
2212 fixTau1Arr[side][module] = fixTau1;
2213 fixTau2Arr[side][module] = fixTau2;
2214 }
2215 }
2216
2217 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{{53.942, 49.887, 59.633, 46.497}},
2218 {{46.314, 42.267, 50.327, 41.605}}
2219 }
2220 };
2221 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{{51.771, 47.936, 57.438, 44.191}},
2222 {{44.295, 41.755, 48.081, 40.175}}
2223 }
2224 };
2225
2226
2227 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2228 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutLG = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2229 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{{ -6, -5, -5, -5}}, {{ -5, -5, -5, -5}}}};
2230 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{{8, 8, 8, 11}}, {{8, 10, 8, 12}}}};
2231 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{{ -6, -5, -5, -5}}, {{ -5, -5, -5, -5}}}};
2232 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{{8, 8, 8, 11}}, {{8, 10, 8, 12}}}};
2233
2234 std::array<std::array<std::vector<float>, 4>, 2> slewingParamsHG, slewingParamsLG;
2235
2236 slewingParamsHG[0][0] = {0, -7.904e-02, 4.686e-02, 1.530e-03 };
2237 slewingParamsHG[0][1] = {0, 2.250e-02, 4.732e-02, 6.050e-03 };
2238 slewingParamsHG[0][2] = {0, 4.388e-02, 6.707e-02, -5.526e-05 };
2239 slewingParamsHG[0][3] = {0, 1.205e-01, 2.726e-02, 2.610e-03 };
2240
2241 slewingParamsHG[1][0] = {0, 6.861e-02, 5.175e-03, -9.018e-04 };
2242 slewingParamsHG[1][1] = {0, 3.855e-01, -4.442e-02, -2.022e-02 };
2243 slewingParamsHG[1][2] = {0, -4.337e-03, 3.841e-02, 4.661e-03 };
2244 slewingParamsHG[1][3] = {0, 3.623e-01, -3.882e-02, -1.805e-02 };
2245
2246 slewingParamsLG[0][0] = {0, 1.708e-02, 7.929e-02, 5.079e-03 };
2247 slewingParamsLG[0][1] = {0, 1.406e-01, 1.209e-01, -1.922e-04 };
2248 slewingParamsLG[0][2] = {0, 1.762e-01, 1.118e-01, 1.679e-04 };
2249 slewingParamsLG[0][3] = {0, 1.361e-02, -2.685e-02, -4.168e-02 };
2250
2251 slewingParamsLG[1][0] = {0, 1.962e-01, -5.025e-03, -2.001e-02 };
2252 slewingParamsLG[1][1] = {0, 3.258e-01, 1.229e-02, -2.925e-02 };
2253 slewingParamsLG[1][2] = {0, 1.393e-01, 8.113e-02, -2.594e-03 };
2254 slewingParamsLG[1][3] = {0, 1.939e-01, 2.188e-02, -5.579e-02 };
2255
2256 m_zdcDataAnalyzer_40MHz.reset (new ZDCDataAnalyzer(MakeMessageFunction(), 7, 25, 0, "FermiExp", peak2ndDerivMinSamples,
2257 peak2ndDerivMinThresholdsHG, peak2ndDerivMinThresholdsLG, m_lowGainMode));
2258
2259 m_zdcDataAnalyzer_40MHz->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
2260 m_zdcDataAnalyzer_40MHz->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
2261 m_zdcDataAnalyzer_40MHz->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
2262 m_zdcDataAnalyzer_40MHz->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLin, 500, 100,
2263 slewingParamsHG, slewingParamsLG);
2264
2265 std::array<std::array<std::vector<float>, 4>, 2> moduleHGNonLinCorr, moduleLGNonLinCorr;
2266 moduleHGNonLinCorr[0][0] = { -3.76800e-02, 4.63597e-02};
2267 moduleHGNonLinCorr[0][1] = { -1.02185e-01, -1.17548e-01};
2268 moduleHGNonLinCorr[0][2] = { -8.78451e-02, -1.52174e-01};
2269 moduleHGNonLinCorr[0][3] = { -1.04835e-01, -1.96514e-01};
2270 moduleHGNonLinCorr[1][0] = { -6.83115e-02, 3.57802e-02};
2271 moduleHGNonLinCorr[1][1] = { -1.08162e-01, -1.91413e-01};
2272 moduleHGNonLinCorr[1][2] = { -7.82514e-02, -1.21218e-01};
2273 moduleHGNonLinCorr[1][3] = { -2.34354e-02, -2.52033e-01};
2274
2275 moduleLGNonLinCorr = {{ {{{0},
2276 {0},
2277 {0},
2278 {0}}},
2279 {{{0},
2280 {0},
2281 {0},
2282 {0}}} }};
2283
2284 if (m_doNonLinCorr) m_zdcDataAnalyzer_40MHz->SetNonlinCorrParams(500, 1000, moduleHGNonLinCorr, moduleLGNonLinCorr);
2285
2286}
2287
2289{
2290 // We have a complete configuration and so we override all of the default parameters
2291 //
2292
2293 m_peak2ndDerivMinSamples = {{{{3, 2, 3, 2}},
2294 {{2, 2, 2, 2}}
2295 }
2296 };
2297
2298 m_peak2ndDerivMinThresholdsHG = {{{{ -8, -8, -8, -8}},
2299 {{ -8, -8, -8, -8}}
2300 }
2301 };
2302
2303 m_peak2ndDerivMinThresholdsLG = {{{{ -4, -4, -4, -4}},
2304 {{ -4, -4, -4, -4}}
2305 }
2306 };
2307
2308 ZDCDataAnalyzer::ZDCModuleFloatArray HGOverFlowADC = {{{{800, 800, 800, 800}}, {{800, 800, 800, 800}}}};
2309 ZDCDataAnalyzer::ZDCModuleFloatArray HGUnderFlowADC = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2310 ZDCDataAnalyzer::ZDCModuleFloatArray LGOverFlowADC = {{{{950, 950, 950, 950}}, {{950, 950, 950, 950}}}};
2311
2312 // Set Tau and nominal timing offsets
2313 ZDCDataAnalyzer::ZDCModuleBoolArray fixTau1Arr{}, fixTau2Arr{};
2314
2315 bool fixTau1 = true;
2316 bool fixTau2 = true;
2317
2318 for (size_t side : {0, 1}) {
2319 for (size_t module : {0, 1, 2, 3}) {
2320 fixTau1Arr[side][module] = fixTau1;
2321 fixTau2Arr[side][module] = fixTau2;
2322 }
2323 }
2324
2325 ZDCDataAnalyzer::ZDCModuleFloatArray tau1 = {{{{3.9, 3.4, 4.1, 4.2}},
2326 {{4.2, 3.6, 3.3, 3.4}}
2327 }
2328 };
2329
2330 ZDCDataAnalyzer::ZDCModuleFloatArray tau2 = {{{{20.0, 20.4, 18.9, 20.8}},
2331 {{19.1, 21.9, 22.6, 23.4}}
2332 }
2333 };
2334
2335 ZDCDataAnalyzer::ZDCModuleFloatArray t0HG = {{{{44.24, 40.35, 49.3, 36.0}},
2336 {{36.0, 31.1, 40.75, 30.5}}
2337 }
2338 };
2339
2340 ZDCDataAnalyzer::ZDCModuleFloatArray t0LG = {{{{42.65, 38.5, 47.4, 34}},
2341 {{33.7, 29.9, 39.0, 29.3}}
2342 }
2343 };
2344
2345 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutHG = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2346 ZDCDataAnalyzer::ZDCModuleFloatArray chisqDivAmpCutLG = {{{{10, 10, 10, 10}}, {{10, 10, 10, 10}}}};
2347 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowHG = {{{{ -6, -5, -5, -5}}, {{ -5, -5, -5, -5}}}};
2348 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighHG = {{{{8, 8, 8, 11}}, {{8, 10, 8, 12}}}};
2349 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutLowLG = {{{{ -6, -5, -5, -5}}, {{ -5, -5, -5, -5}}}};
2350 ZDCDataAnalyzer::ZDCModuleFloatArray DeltaT0CutHighLG = {{{{8, 8, 8, 11}}, {{8, 10, 8, 12}}}};
2351
2352 std::array<std::array<std::vector<float>, 4>, 2> slewingParamsHG, slewingParamsLG;
2353
2354 slewingParamsHG[0][0] = {0, -6.5e-2, 2.85e-2, -2.83e-3};
2355 slewingParamsHG[0][1] = {0, -5.5e-2, 5.13e-2, 5.6e-3};
2356 slewingParamsHG[0][2] = {0, -1.45e-3, 9.3e-2, 3.9e-3};
2357 slewingParamsHG[0][3] = {0, -2.36e-2, 8.3e-2, 1.1e-3};
2358
2359 slewingParamsHG[1][0] = {0, -6.5e-2, 4.84e-2, -3.7e-3};
2360 slewingParamsHG[1][1] = {0, 1.34e-2, 6.57e-2, 5.37e-3};
2361 slewingParamsHG[1][2] = {0, -5.37e-2, 3.49e-2, 3.8e-3};
2362 slewingParamsHG[1][3] = {0, -3.3e-2, 3.9e-2, 2.2e-3};
2363
2364 slewingParamsLG[0][0] = {0, -9.6e-2, 4.39e-2, 2.93e-3 };
2365 slewingParamsLG[0][1] = {0, -5.0e-2, 14.9e-2, 20.6e-3 };
2366 slewingParamsLG[0][2] = {0, -4.4e-2, 5.3e-2, 0, };
2367 slewingParamsLG[0][3] = {0, -9.90e-2, 4.08e-2, 0, };
2368
2369 slewingParamsLG[1][0] = {0, -8.7e-2, 4.2e-2, -3.2e-3 };
2370 slewingParamsLG[1][1] = {0, -3.26e-2, 3.84e-2, -2.32e-3};
2371 slewingParamsLG[1][2] = {0, -26.8e-2, -2.64e-2, -5.3e-3 };
2372 slewingParamsLG[1][3] = {0, -13.2e-2, 0.45e-2, -2.4e-3 };
2373
2374
2377
2378 m_zdcDataAnalyzer_80MHz->SetADCOverUnderflowValues(HGOverFlowADC, HGUnderFlowADC, LGOverFlowADC);
2379 m_zdcDataAnalyzer_80MHz->SetTauT0Values(fixTau1Arr, fixTau2Arr, tau1, tau2, t0HG, t0LG);
2380 m_zdcDataAnalyzer_80MHz->SetCutValues(chisqDivAmpCutHG, chisqDivAmpCutLG, DeltaT0CutLowHG, DeltaT0CutHighHG, DeltaT0CutLowLG, DeltaT0CutHighLG);
2381 m_zdcDataAnalyzer_80MHz->SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrLin, 500, 100,
2382 slewingParamsHG, slewingParamsLG);
2383
2384 std::array<std::array<std::vector<float>, 4>, 2> moduleHGNonLinCorr, moduleLGNonLinCorr;
2385 moduleHGNonLinCorr[0][0] = { -3.76800e-02, 4.63597e-02};
2386 moduleHGNonLinCorr[0][1] = { -1.02185e-01, -1.17548e-01};
2387 moduleHGNonLinCorr[0][2] = { -8.78451e-02, -1.52174e-01};
2388 moduleHGNonLinCorr[0][3] = { -1.04835e-01, -1.96514e-01};
2389 moduleHGNonLinCorr[1][0] = { -6.83115e-02, 3.57802e-02};
2390 moduleHGNonLinCorr[1][1] = { -1.08162e-01, -1.91413e-01};
2391 moduleHGNonLinCorr[1][2] = { -7.82514e-02, -1.21218e-01};
2392 moduleHGNonLinCorr[1][3] = { -2.34354e-02, -2.52033e-01};
2393
2394 moduleLGNonLinCorr = {{ {{{0},
2395 {0},
2396 {0},
2397 {0}}},
2398 {{{0},
2399 {0},
2400 {0},
2401 {0}}} }};
2402
2403 if (m_doNonLinCorr) m_zdcDataAnalyzer_80MHz->SetNonlinCorrParams(500, 1000, moduleHGNonLinCorr, moduleLGNonLinCorr);
2404}
2405
2407{
2408 m_tf1SincInterp.reset (new TF1("SincInterp", ZDC::SincInterp, -5., 160., 8));
2409 m_tf1SincInterp->SetNpx(300);
2410
2411 // Set up calibrations
2412 //
2413 std::string filename = PathResolverFindCalibFile( "ZdcAnalysis/ZdcAnalysisConfig.conf" );
2414 TEnv env(filename.c_str());
2415
2416 m_zdcEnergyCalibFileName = std::string(env.GetValue("ZdcEnergyCalibFileName", "ZdcCalibrations_v1.root"));
2417 ATH_MSG_INFO("ZDC energy calibration filename " << m_zdcEnergyCalibFileName);
2418 m_zdcTimeCalibFileName = std::string(env.GetValue("ZdcTimeCalibFileName", "ZdcTimeCalibrations_v1.root"));
2419 ATH_MSG_INFO("ZDC time calibration filename " << m_zdcTimeCalibFileName);
2420 m_zdcTriggerEffParamsFileName = std::string(env.GetValue("ZdcTriggerEffFileName", "ZdcTriggerEffParameters_v6.root"));
2421 ATH_MSG_INFO("ZDC trigger efficiencies filename " << m_zdcTriggerEffParamsFileName);
2422
2423
2424 if (m_forceCalibRun > -1) {
2425 ATH_MSG_DEBUG("CAREFUL: forcing calibration run/LB =" << m_forceCalibRun << "/" << m_forceCalibLB);
2426
2427 if (m_forceCalibLB < 0) {
2428 ATH_MSG_ERROR("Invalid settings: Forced run > 0 but lumi block < 0");
2429 return StatusCode::FAILURE;
2430 }
2431 }
2432
2433 // Use configuration to direct initialization
2434 //
2435 if (m_configuration == "default") {
2437 }
2438 else if (m_configuration == "PbPb2015") {
2441
2443 }
2444 else if (m_configuration == "pPb2016") {
2446 }
2447 else if (m_configuration == "PbPb2018") {
2449 }
2450 else if (m_configuration == "PbPb2015G4") {
2452 }
2453 else if (m_configuration == "LHCf2022") {
2455 }
2456 else if (m_configuration == "pp2023") {
2458 }
2459 else if (m_configuration == "pp2024") {
2461 }
2462 else if (m_configuration == "PbPb2023") {
2464 }
2465 else if (m_configuration == "PbPb2024") {
2467 }
2468 else if (m_configuration == "OONeNe2025") {
2470 }
2471 else if (m_configuration == "pO2025") {
2473 }
2474 else if (m_configuration == "pO2025B") {
2476 }
2477 else if (m_configuration == "Injectorpp2024") {
2479 }
2480 else if (m_configuration == "InjectorPbPb2024") {
2482 }
2483 else if (m_configuration == "InjectorpOOONeNe2025") {
2485 }
2486 else if (m_configuration == "MonteCarloPbPb2023") {
2488 }
2489 else if (m_configuration == "JSON") {
2491 }
2492 else {
2493 ATH_MSG_ERROR("Unknown configuration: " << m_configuration);
2494 return StatusCode::FAILURE;
2495 }
2496
2497 // If an aux suffix is provided, prepend it with "_" so we don't have to do so at each use
2498 //
2499
2500 ATH_MSG_INFO("Configuration: " << m_configuration);
2501 ATH_MSG_DEBUG("FlipEMDelay: " << m_flipEMDelay);
2502 ATH_MSG_DEBUG("LowGainMode: " << m_lowGainMode);
2503
2504 ATH_MSG_DEBUG("Using Combined delayed and undelayed samples: " << m_combineDelay);
2505
2506 ATH_MSG_DEBUG("WriteAux: " << m_writeAux);
2507 ATH_MSG_DEBUG("AuxSuffix: " << m_auxSuffix);
2508 ATH_MSG_DEBUG("DoCalib: " << m_doCalib);
2509 ATH_MSG_DEBUG("ForceCalibRun: " << m_forceCalibRun);
2510 ATH_MSG_DEBUG("ForceCalibLB: " << m_forceCalibLB);
2511 ATH_MSG_DEBUG("NumSampl: " << m_numSample);
2512 ATH_MSG_DEBUG("DeltaTSample: " << m_deltaTSample);
2513 ATH_MSG_DEBUG("Presample: " << m_presample);
2514 ATH_MSG_DEBUG("PeakSample: " << m_peakSample);
2515 ATH_MSG_DEBUG("Peak2ndDerivThresh: " << m_Peak2ndDerivThresh);
2516
2517 if (m_combineDelay) ATH_MSG_DEBUG("DelayDeltaT: " << m_delayDeltaT);
2518
2519 ATH_MSG_DEBUG("T0: " << m_t0);
2520 ATH_MSG_DEBUG("Tau1: " << m_tau1);
2521 ATH_MSG_DEBUG("Tau2: " << m_tau2);
2522 ATH_MSG_DEBUG("FixTau1: " << m_fixTau1);
2523 ATH_MSG_DEBUG("FixTau2: " << m_fixTau2);
2524 ATH_MSG_DEBUG("DeltaTCut: " << m_deltaTCut);
2525 ATH_MSG_DEBUG("ChisqRatioCut: " << m_ChisqRatioCut);
2526
2527 Dump_setting(); // for good measure
2528
2529 ATH_CHECK( m_eventInfoKey.initialize());
2530
2531 // Initialize decorations
2532
2534 ATH_CHECK( m_zdcModuleAmplitude.initialize());
2536 ATH_CHECK( m_zdcModuleCalibEnergy.initialize());
2538 ATH_CHECK( m_zdcModuleCalibTime.initialize());
2540 ATH_CHECK( m_zdcModuleStatus.initialize());
2542 ATH_CHECK( m_zdcModuleTime.initialize());
2544 ATH_CHECK( m_zdcModuleChisq.initialize());
2546 ATH_CHECK( m_zdcModuleAmpNoNonLin.initialize());
2548 ATH_CHECK( m_zdcModuleFitAmp.initialize());
2550 ATH_CHECK( m_zdcModuleFitAmpError.initialize());
2552 ATH_CHECK( m_zdcModuleFitT0.initialize());
2556 ATH_CHECK( m_zdcModulePreSampleAmp.initialize());
2558 ATH_CHECK( m_zdcModulePresample.initialize());
2560 ATH_CHECK( m_zdcModuleMinDeriv2nd.initialize());
2562 ATH_CHECK( m_zdcModuleMaxADC.initialize());
2563
2565 ATH_CHECK( m_zdcModuleMaxADCHG.initialize());
2567 ATH_CHECK( m_zdcModuleMaxADCLG.initialize());
2568
2569 // LG refit data
2570 //
2572 ATH_CHECK(m_zdcModuleFitAmpLGRefit.initialize());
2574 ATH_CHECK(m_zdcModuleAmpLGRefit.initialize());
2578 ATH_CHECK(m_zdcModuleT0LGRefit.initialize());
2580 ATH_CHECK(m_zdcModuleT0SubLGRefit.initialize());
2582 ATH_CHECK( m_zdcModuleChisqLGRefit.initialize());
2583
2584 // ZDC per-calorimeter data
2585 //
2587 ATH_CHECK( m_zdcSumUncalibSum.initialize());
2589 ATH_CHECK( m_zdcSumUncalibSumErr.initialize());
2591 ATH_CHECK( m_zdcSumCalibEnergy.initialize());
2593 ATH_CHECK( m_zdcSumCalibEnergyErr.initialize());
2595 ATH_CHECK( m_zdcSumNLCalibEnergy.initialize());
2597 ATH_CHECK( m_zdcSumNLCalibEnergyErr.initialize());
2599 ATH_CHECK( m_zdcSumFinalEnergy.initialize());
2601 ATH_CHECK( m_zdcSumAverageTime.initialize());
2603 ATH_CHECK( m_zdcSumStatus.initialize());
2605 ATH_CHECK( m_zdcSumModuleMask.initialize());
2606
2607 if (m_writeAux && m_auxSuffix != "") {
2608 ATH_MSG_DEBUG("suffix string = " << m_auxSuffix);
2609 }
2610
2611 m_init = true;
2612
2613 return StatusCode::SUCCESS;
2614}
2615
2620
2621StatusCode ZdcAnalysisTool::configureNewRun(unsigned int runNumber)
2622{
2623 ATH_MSG_DEBUG("Setting up new run " << runNumber);
2624
2625 // We do nothing for the default configuration
2626 //
2627 if (m_configuration != "default") {
2628 if (m_configuration == "PbPb2015") {
2629 //
2630 // Two periods, 40 MHz and 80 MHz readout
2631 //
2632 if (runNumber < 287222) m_zdcDataAnalyzer = m_zdcDataAnalyzer_40MHz;
2634 }
2635 }
2636
2637 return StatusCode::SUCCESS;
2638}
2639
2640
2641StatusCode ZdcAnalysisTool::recoZdcModules(const xAOD::ZdcModuleContainer& moduleContainer, const xAOD::ZdcModuleContainer& moduleSumContainer)
2642{
2643
2644 if (moduleContainer.size()==0) return StatusCode::SUCCESS; // if no modules, do nothing
2645
2647 if (!eventInfo.isValid()) return StatusCode::FAILURE;
2648
2649 // Check for decoding errors and bail out if ZDC error found
2650 bool zdcErr = eventInfo->isEventFlagBitSet(xAOD::EventInfo::ForwardDet, ZdcEventInfo::ZDCDECODINGERROR );
2651 if (zdcErr)
2652 {
2653 ATH_MSG_WARNING("ZDC decoding error found - abandoning ZDC reco!");
2654 return StatusCode::SUCCESS;
2655 }
2656
2657 // check for new run number, if new, possibly update configuration and/or calibrations
2658 //
2659 unsigned int thisRunNumber = eventInfo->runNumber();
2660 if (thisRunNumber != m_runNumber) {
2661 ATH_MSG_DEBUG("ZDC analysis tool will be configured for run " << thisRunNumber);
2662
2663 ATH_CHECK(configureNewRun(thisRunNumber)); // ALWAYS check methods that return StatusCode
2664
2665 ATH_MSG_DEBUG("Setting up calibrations");
2666
2667 if (m_doFADCCorr)
2668 {
2669 unsigned int calibRunNumber = thisRunNumber;
2670 if (m_forceCalibRun > -1) calibRunNumber = m_forceCalibRun;
2671 try
2672 {
2673 setFADCCorrections(calibRunNumber);
2674 }
2675 catch(std::runtime_error&)
2676 {
2677 m_doFADCCorr = false;
2678 }
2679 }
2680
2681 if (m_doCalib) {
2682 //
2683 // Check for calibration override
2684 //
2685 unsigned int calibRunNumber = thisRunNumber;
2686 if (m_forceCalibRun > -1) calibRunNumber = m_forceCalibRun;
2687 try
2688 {
2689 setEnergyCalibrations(calibRunNumber);
2690 }
2691 catch(std::runtime_error&)
2692 {
2693 m_doCalib = false;
2694 }
2695
2696 if (m_doTrigEff) initializeTriggerEffs(calibRunNumber); // if energy calibrations fail to load, then so will trigger efficiencies
2697 if (m_doTimeCalib) setTimeCalibrations(calibRunNumber);
2698 }
2699
2700 m_runNumber = thisRunNumber;
2701 }
2702
2703 m_lumiBlock = eventInfo->lumiBlock();
2704
2705 unsigned int calibLumiBlock = m_lumiBlock;
2706 if (m_doCalib) {
2707 if (m_forceCalibRun > 0) calibLumiBlock = m_forceCalibLB;
2708 }
2709
2710 ATH_MSG_DEBUG("Starting event processing");
2711 ATH_MSG_DEBUG("LB=" << calibLumiBlock);
2712
2713 m_zdcDataAnalyzer->StartEvent(calibLumiBlock);
2714
2715 static const SG::ConstAccessor<std::vector<uint16_t> > g0dataAcc ("g0data");
2716 static const SG::ConstAccessor<std::vector<uint16_t> > g1dataAcc ("g1data");
2717
2718 const std::vector<unsigned short>* adcUndelayLG = 0;
2719 const std::vector<unsigned short>* adcUndelayHG = 0;
2720
2721 const std::vector<unsigned short>* adcDelayLG = 0;
2722 const std::vector<unsigned short>* adcDelayHG = 0;
2723
2724 ATH_MSG_DEBUG("Processing modules");
2725 for (const auto zdcModule : moduleContainer)
2726 {
2727 int side = -1;
2728 if (zdcModule->zdcSide() == -1) side = 0;
2729 else if (zdcModule->zdcSide() == 1) side = 1;
2730 else {
2731 // Invalid side
2732 //
2733 ATH_MSG_WARNING("Invalid side value found for module number: " << zdcModule->zdcModule() << ", side value = " << side);
2734 continue;
2735 }
2736 // Ignore MC only modules
2737 if(zdcModule->zdcModule() > 4) continue;
2738
2739 if (zdcModule->zdcType() == 0) {
2740 //
2741 // This is ZDC data
2742 //
2743 if (m_LHCRun==3) // no delay channels, so we drop the index
2744 {
2745 adcUndelayLG = &g0dataAcc(*zdcModule); // g0
2746 adcUndelayHG = &g1dataAcc(*zdcModule); // g1
2747 }
2748 else if (m_LHCRun==2)
2749 {
2750
2751
2752 static const SG::ConstAccessor<std::vector<uint16_t> > g0d1dataAcc ("g0d1data");
2753 static const SG::ConstAccessor<std::vector<uint16_t> > g1d1dataAcc ("g1d1data");
2754 static const SG::ConstAccessor<std::vector<uint16_t> > g0d0dataAcc ("g0d0data");
2755 static const SG::ConstAccessor<std::vector<uint16_t> > g1d0dataAcc ("g1d0data");
2756
2757 if (zdcModule->zdcModule() == 0 && m_flipEMDelay) // flip delay/non-delay for 2015 ONLY
2758 {
2759 adcUndelayLG = &g0d1dataAcc(*zdcModule); // g0d1
2760 adcUndelayHG = &g1d1dataAcc(*zdcModule); // g1d1
2761 adcDelayLG = &g0d0dataAcc(*zdcModule); // g0d0
2762 adcDelayHG = &g1d0dataAcc(*zdcModule); // g1d0
2763 }
2764 else // nominal configuation
2765 {
2766 adcUndelayLG = &g0d0dataAcc(*zdcModule); // g0d0
2767 adcUndelayHG = &g1d0dataAcc(*zdcModule); // g1d0
2768 adcDelayLG = &g0d1dataAcc(*zdcModule); // g0d1
2769 adcDelayHG = &g1d1dataAcc(*zdcModule); // g1d1
2770 }
2771 }
2772 else
2773 {
2774 ATH_MSG_WARNING("Unknown LHC Run " << m_LHCRun);
2775 return StatusCode::FAILURE;
2776 }
2777
2778 // Why were these static? to optimize processing time
2779 std::vector<float> HGUndelADCSamples(m_numSample);
2780 std::vector<float> LGUndelADCSamples(m_numSample);
2781
2782 if (LGUndelADCSamples.size() < adcUndelayLG->size()) {
2783 LGUndelADCSamples.resize(adcUndelayLG->size());
2784 }
2785
2786 if (HGUndelADCSamples.size() < adcUndelayHG->size()) {
2787 HGUndelADCSamples.resize(adcUndelayHG->size());
2788 }
2789
2790 std::copy(adcUndelayLG->begin(), adcUndelayLG->end(), LGUndelADCSamples.begin());
2791 std::copy(adcUndelayHG->begin(), adcUndelayHG->end(), HGUndelADCSamples.begin());
2792
2793 int side = (zdcModule->zdcSide() == -1) ? 0 : 1 ;
2794
2795 if (!m_combineDelay) {
2796 m_zdcDataAnalyzer->LoadAndAnalyzeData(side, zdcModule->zdcModule(), HGUndelADCSamples, LGUndelADCSamples);
2797 }
2798 else {
2799 std::vector<float> HGDelayADCSamples(m_numSample);
2800 std::vector<float> LGDelayADCSamples(m_numSample);
2801 if (adcDelayLG and adcDelayHG){
2802 std::copy(adcDelayLG->begin(), adcDelayLG->end(), LGDelayADCSamples.begin());
2803 std::copy(adcDelayHG->begin(), adcDelayHG->end(), HGDelayADCSamples.begin());
2804 }else{
2805 ATH_MSG_ERROR("adcDelayLG or adcDelayHG pointers are null");
2806 return StatusCode::FAILURE;
2807 }
2808 // If the delayed channels actually come earlier (as in the pPb in 2016), we invert the meaning of delayed and undelayed
2809 // see the initialization sections for similar inversion on the sign of the pedestal difference
2810 //
2811
2812 m_zdcDataAnalyzer->LoadAndAnalyzeData(side, zdcModule->zdcModule(),
2813 HGUndelADCSamples, LGUndelADCSamples,
2814 HGDelayADCSamples, LGDelayADCSamples);
2815 }
2816 }
2817 }
2818
2819 ATH_MSG_DEBUG("Finishing event processing");
2820
2821 m_zdcDataAnalyzer->FinishEvent();
2822
2823 ATH_MSG_DEBUG("Adding variables with suffix=" + m_auxSuffix);
2824
2842
2849
2850 // CalibTime
2851 // Status
2852 // Time
2853 // Chisq
2854 // AmpNoNonLin
2855 // FitAmp
2856 // FitAmpError
2857 // FitT0
2858 // BkgdMaxFraction
2859 // PreSampleAmp
2860 // Presample
2861 // MinDeriv2nd
2862 // MaxADC
2863
2864 for (const auto zdcModule : moduleContainer)
2865 {
2866 int side = (zdcModule->zdcSide() == -1) ? 0 : 1 ;
2867 int mod = zdcModule->zdcModule();
2868 // Ignore MC only modules
2869 if(mod > 4) continue;
2870
2871 if (zdcModule->zdcType() == 0) {
2872 // this is the main ZDC
2873 if (m_writeAux) {
2874 float calibEnergy = m_zdcDataAnalyzer->GetModuleCalibAmplitude(side, mod);
2875 zdcModuleCalibEnergy(*zdcModule) = calibEnergy;
2876 zdcModuleCalibTime(*zdcModule) = m_zdcDataAnalyzer->GetModuleCalibTime(side, mod);
2877
2878 zdcModuleAmplitude(*zdcModule) = m_zdcDataAnalyzer->GetModuleAmplitude(side, mod);
2879 zdcModuleStatus(*zdcModule) = m_zdcDataAnalyzer->GetModuleStatus(side, mod);
2880 zdcModuleTime(*zdcModule) = m_zdcDataAnalyzer->GetModuleTime(side, mod);
2881
2882 const ZDCPulseAnalyzer* pulseAna_p = m_zdcDataAnalyzer->GetPulseAnalyzer(side, mod);
2883 zdcModuleChisq(*zdcModule) = pulseAna_p->GetChisq();
2884 zdcModuleAmpNoNonLin(*zdcModule) = pulseAna_p->GetAmpNoNonLin();
2885 zdcModuleFitAmp(*zdcModule) = pulseAna_p->GetFitAmplitude();
2886 zdcModuleFitAmpError(*zdcModule) = pulseAna_p->GetAmpError();
2887 zdcModuleFitT0(*zdcModule) = pulseAna_p->GetFitT0();
2888 zdcModuleBkgdMaxFraction(*zdcModule) = pulseAna_p->GetBkgdMaxFraction();
2889 zdcModulePreSampleAmp(*zdcModule) = pulseAna_p->GetPreSampleAmp();
2890 zdcModulePresample(*zdcModule) = pulseAna_p->getPresample();
2891 zdcModuleMinDeriv2nd(*zdcModule) = pulseAna_p->GetMinDeriv2nd();
2892 zdcModuleMaxADC(*zdcModule) = pulseAna_p->getMaxADCSub();
2893 zdcModuleMaxADCHG(*zdcModule) = pulseAna_p->getMaxADCHG();
2894 zdcModuleMaxADCLG(*zdcModule) = pulseAna_p->getMaxADCLG();
2895
2896 zdcModuleAmpLGRefit(*zdcModule) = pulseAna_p->getRefitLGAmp();
2897 zdcModuleFitAmpLGRefit(*zdcModule) = pulseAna_p->getRefitLGFitAmp();
2898 zdcModuleAmpCorrLGRefit(*zdcModule) = pulseAna_p->getRefitLGAmpCorr();
2899 zdcModuleT0LGRefit(*zdcModule) = pulseAna_p->getRefitLGTime();
2900 zdcModuleT0SubLGRefit(*zdcModule) = pulseAna_p->getRefitLGTimeSub();
2901 zdcModuleChisqLGRefit(*zdcModule) = pulseAna_p->getRefitLGChisq();
2902 }
2903 //ATH_MSG_DEBUG ("side = " << side << " module=" << zdcModule->zdcModule() << " CalibEnergy=" << zdcModule->auxdecor<float>("CalibEnergy")
2904 // << " should be " << m_zdcDataAnalyzer->GetModuleCalibAmplitude(side, mod));
2905 }
2906 }
2907
2908 // Output sum information
2909 // In Run 3 - we have to assume the container already exists (since it is needed to store the per-side trigger info)
2910 // reprocessing will add new variables with the suffix
2911
2922
2923 for (const auto zdc_sum: moduleSumContainer)
2924 {
2925 ATH_MSG_DEBUG("Extracting ZDC side " << zdc_sum->zdcSide());
2926
2927 if (zdc_sum->zdcSide()==0) continue; // skip new global sum
2928
2929 int iside = (zdc_sum->zdcSide()==-1) ? 0 : 1;
2930
2931 float uncalibSum = getUncalibModuleSum(iside);
2932 zdcSumUncalibSum(*zdc_sum) = uncalibSum;
2933 float uncalibSumErr = getUncalibModuleSumErr(iside);
2934 zdcSumUncalibSumErr(*zdc_sum) = uncalibSumErr;
2935
2936 float calibEnergy = getCalibModuleSum(iside);
2937 zdcSumCalibEnergy(*zdc_sum) = calibEnergy;
2938 float calibEnergyErr = getCalibModuleSumErr(iside);
2939 zdcSumCalibEnergyErr(*zdc_sum) = calibEnergyErr;
2940
2941 float nlcalibEnergy = getNLCalibModuleSum(iside);
2942 zdcSumNLCalibEnergy(*zdc_sum) = nlcalibEnergy;
2943 float nlcalibEnergyErr = getNLCalibModuleSumErr(iside);
2944 zdcSumNLCalibEnergyErr(*zdc_sum) = nlcalibEnergyErr;
2945
2946 float finalEnergy = calibEnergy;
2947 zdcSumFinalEnergy(*zdc_sum) = finalEnergy;
2948 zdcSumAverageTime(*zdc_sum) = getAverageTime(iside);
2949 zdcSumStatus(*zdc_sum) = !sideFailed(iside);
2950 zdcSumModuleMask(*zdc_sum) = (getModuleMask() >> (4 * iside)) & 0xF;
2951 }
2952
2953 return StatusCode::SUCCESS;
2954}
2955
2956void ZdcAnalysisTool::setEnergyCalibrations(unsigned int runNumber)
2957{
2958
2959 char name[128];
2960
2961 std::string filename;
2962 if (m_LHCRun==3)
2963 {
2964 filename = PathResolverFindCalibFile( ("ZdcAnalysis/ZdcCalib_Run"+TString::Itoa(runNumber,10)+".root").Data() );
2965 }
2966 else if (m_LHCRun==2)
2967 {
2968 filename = PathResolverFindCalibFile( ("ZdcAnalysis/" + m_zdcEnergyCalibFileName).c_str() );
2969 }
2970 else
2971 {
2972 ATH_MSG_WARNING("No LHC Run defined, so no calibration allowed");
2973 return;
2974 }
2975
2976 ATH_MSG_INFO("Opening energy calibration file " << filename);
2977 std::unique_ptr<TFile> fCalib (TFile::Open(filename.c_str(), "READ"));
2978
2979 if (fCalib == nullptr || fCalib->IsZombie())
2980 {
2981 ATH_MSG_INFO ("failed to open file: " << filename);
2982 throw std::runtime_error ("failed to open file " + filename);
2983 }
2984
2985 std::array<std::array<std::unique_ptr<TSpline>, 4>, 2> splines;
2986
2987 // "m_calibVersion", called CalibVersion when settings parameters in python, is a directory within the run-based calibration file
2988 TString calibVersion;
2989 if (m_calibVersion != "") calibVersion = m_calibVersion + "/";
2990
2991 for (int iside = 0; iside < 2; iside++)
2992 {
2993 for (int imod = 0; imod < 4; imod++)
2994 {
2995 sprintf(name, "ZDC_Ecalib_run%u_s%d_m%d", runNumber, iside, imod);
2996 ATH_MSG_DEBUG("Searching for spline " << name);
2997 TSpline3* s = (TSpline3*) fCalib->GetObjectChecked(calibVersion+TString(name), "TSpline3");
2998 if (!s && m_doCalib)
2999 {
3000 ATH_MSG_WARNING("No calibrations for run " << runNumber);
3001 m_doCalib = false;
3002 }
3003
3004 if (s)
3005 {
3006 splines[iside][imod].reset (s);
3007 }
3008 else
3009 {
3010 ATH_MSG_WARNING("No spline " << name);
3011 }
3012 }
3013 }
3014 fCalib->Close();
3015
3016 if (m_doCalib) m_zdcDataAnalyzer->LoadEnergyCalibrations(std::move(splines));
3017
3018 return;
3019}
3020
3021void ZdcAnalysisTool::setTimeCalibrations(unsigned int runNumber)
3022{
3023 std::string filename;
3024
3025 if (m_LHCRun==3)
3026 {
3027 filename = PathResolverFindCalibFile( ("ZdcAnalysis/ZdcCalib_Run"+TString::Itoa(runNumber,10)+".root").Data() );
3028 }
3029 else if (m_LHCRun==2)
3030 {
3031 filename = PathResolverFindCalibFile( "ZdcAnalysis/" + m_zdcTimeCalibFileName );
3032 }
3033 else
3034 {
3035 ATH_MSG_WARNING("No LHC Run defined, so no time calibration allowed");
3036 return;
3037 }
3038
3039 char name[128] = {0};
3040 ATH_MSG_INFO("Opening time calibration file " << filename);
3041 std::unique_ptr<TFile> fCalib (TFile::Open(filename.c_str(), "READ"));
3042
3043 // "m_calibVersion", called CalibVersion when settings parameters in python, is a directory within the run-based calibration file
3044 TString calibVersion = "";
3045 if (m_calibVersion != "") calibVersion = m_calibVersion + "/";
3046
3047 if (fCalib && !fCalib->IsZombie())
3048 {
3049 bool success = true;
3050 std::array<std::array<std::unique_ptr<TSpline>, 4>, 2> T0HGOffsetSplines;
3051 std::array<std::array<std::unique_ptr<TSpline>, 4>, 2> T0LGOffsetSplines;
3052 std::unique_ptr<TSpline3> spline;
3053 for (int iside = 0; iside < 2; iside++)
3054 {
3055 for (int imod = 0; imod < 4; imod++)
3056 {
3057 sprintf(name, "ZDC_T0calib_run%u_HG_s%d_m%d", runNumber, iside, imod);
3058 spline.reset (static_cast<TSpline3*>(fCalib->GetObjectChecked(calibVersion+TString(name), "TSpline3")));
3059 if (spline)
3060 {
3061 T0HGOffsetSplines[iside][imod] = std::move (spline);
3062 }
3063 else
3064 {
3065 ATH_MSG_WARNING("No time calib. spline " << calibVersion+name);
3066 success = false;
3067 }
3068
3069 sprintf(name, "ZDC_T0calib_run%u_LG_s%d_m%d", runNumber, iside, imod);
3070 spline.reset (static_cast<TSpline3*>(fCalib->GetObjectChecked(calibVersion+TString(name), "TSpline3")));
3071 if (spline)
3072 {
3073 T0LGOffsetSplines[iside][imod] = std::move (spline);
3074 }
3075 else
3076 {
3077 ATH_MSG_WARNING("No time calib. spline " << calibVersion+name);
3078 success = false;
3079 }
3080 }
3081 }
3082
3083 if (success)
3084 m_zdcDataAnalyzer->LoadT0Calibrations(std::move(T0HGOffsetSplines), std::move(T0LGOffsetSplines));
3085 else
3086 ATH_MSG_WARNING("Time calibration failed - no T0 offsets loaded " << calibVersion+name);
3087
3088 fCalib->Close();
3089 }
3090 else
3091 {
3092 ATH_MSG_WARNING("No time calibration file " << filename);
3093 }
3094}
3095
3096void ZdcAnalysisTool::setFADCCorrections(unsigned int runNumber)
3097{
3098 std::string filename;
3099
3100 if (m_LHCRun==3) {
3101 std::string runString;
3102
3103 if (runNumber == 0) runString = "ZdcFADCCorr_" + m_configuration + "_default.root";
3104 else runString = ("ZdcFADCCorr_Run"+TString::Itoa(runNumber,10)+".root").Data();
3105
3106 filename = PathResolverFindCalibFile("ZdcAnalysis/" + runString );
3107 }
3108 else {
3109 ATH_MSG_WARNING("setFADCCorrections: FADC corrections not implemented for Run 2");
3110 return;
3111 }
3112
3113 if (filename.empty())
3114 {
3115 ATH_MSG_INFO("FADC correction requested but no calibration file found");
3116 m_doFADCCorr = false;
3117 return;
3118 }
3119
3120 ATH_MSG_INFO("Opening FADC corrections file " << filename);
3121 std::unique_ptr<TFile> fFADCCorr(TFile::Open(filename.c_str(), "READ"));
3122
3123 if (!fFADCCorr->IsOpen()) {
3124 ATH_MSG_INFO ("setFADCCorrections: failed to open file: " << filename);
3125 throw std::runtime_error ("ZdcAnalysisTool failed to open FADCCorrections file " + filename);
3126 }
3127
3128 // Attempt to read histograms with corrections from file
3129 //
3130 bool readSuccess = true;
3131 std::array<std::array<std::unique_ptr<const TH1>, 4>, 2> histogramsHG;
3132 std::array<std::array<std::unique_ptr<const TH1>, 4>, 2> histogramsLG;
3133
3134 for (size_t side : {0, 1}) {
3135 for (int module : {0, 1, 2, 3}) {
3136 std::string histNameHG = "ZDC_FADCCorr_s" + std::to_string(side) + "_m" + std::to_string(module)+"_HG";
3137 std::string histNameLG = "ZDC_FADCCorr_s" + std::to_string(side) + "_m" + std::to_string(module)+"_LG";
3138
3139 ATH_MSG_DEBUG("setFADCCorrections: Searching for histograms HG and LG: " << histNameHG << ", " << histNameLG);
3140
3141 TH1* histHG_ptr = static_cast<TH1*>(fFADCCorr->GetObjectChecked(histNameHG.c_str(), "TH1"));
3142 TH1* histLG_ptr = static_cast<TH1*>(fFADCCorr->GetObjectChecked(histNameLG.c_str(), "TH1"));
3143
3144 if (!histHG_ptr || !histLG_ptr) {
3145 std::string errMsg = "setFADCCorrections: unable to read FADC correction histogram(s) ";
3146 if (!histHG_ptr) errMsg += histNameHG + " ";
3147 if (!histLG_ptr) errMsg += histNameLG;
3148
3149 ATH_MSG_ERROR(errMsg);
3150 readSuccess = false;
3151 break;
3152 }
3153 else {
3154 //
3155 // Check for valid range (Lion uses -0.5 to 4095.5)
3156 //
3157
3158 if ( std::abs(histHG_ptr->GetXaxis()->GetXmin()+0.5) > 1e-3 || std::abs(histHG_ptr->GetXaxis()->GetXmax() - 4095.5) > 1e-3) {
3159 ATH_MSG_ERROR("setFADCCorrections: invalid axis range for HG FADC corrections in histogram with name " << histNameHG);
3160 readSuccess = false;
3161 break;
3162 }
3163 if (std::abs(histLG_ptr->GetXaxis()->GetXmin()+0.5) > 1e-3 || std::abs(histLG_ptr->GetXaxis()->GetXmax() - 4095.5) > 1e-3) {
3164 ATH_MSG_ERROR("setFADCCorrections: invalid axis range for HG FADC corrections in histogram with name " << histNameLG);
3165 readSuccess = false;
3166 break;
3167 }
3168
3169 histogramsHG[side][module].reset(histHG_ptr);
3170 histogramsLG[side][module].reset(histLG_ptr);
3171 }
3172 }
3173 }
3174
3175 fFADCCorr->Close();
3176
3177 if (readSuccess) {
3178 m_zdcDataAnalyzer->enableFADCCorrections(m_doFADCCorrPerSample, histogramsHG, histogramsLG);
3179 }
3180 else {
3181 ATH_MSG_ERROR("setFADCCorrections: due to at least one error, FADC corrections are not implemented");
3182 m_doFADCCorr = false;
3183 }
3184
3185 return;
3186}
3187
3188
3190{
3191 if (!m_init)
3192 {
3193 ATH_MSG_WARNING("Tool not initialized!");
3194 return StatusCode::FAILURE;
3195 }
3196 m_eventReady = false;
3197 ATH_MSG_DEBUG ("Trying to retrieve " << m_zdcModuleContainerName);
3198
3199 m_zdcModules = 0;
3201
3202 m_zdcSums = 0;
3204
3205 m_eventReady = true;
3206
3208
3209 return StatusCode::SUCCESS;
3210}
3211
3212bool ZdcAnalysisTool::sigprocMaxFinder(const std::vector<unsigned short>& adc, float deltaT, float& amp, float& time, float& qual)
3213{
3214 size_t nsamp = adc.size();
3215 float presamp = adc.at(0);
3216 unsigned short max_adc = 0;
3217 int max_index = -1;
3218 for (size_t i = 0; i < nsamp; i++)
3219 {
3220 if (adc[i] > max_adc)
3221 {
3222 max_adc = adc[i];
3223 max_index = i;
3224 }
3225 }
3226 amp = max_adc - presamp;
3227 time = max_index * deltaT;
3228 qual = 1.;
3229
3230 if (max_index == -1)
3231 {
3232 qual = 0.;
3233 return false;
3234 }
3235
3236 return true;
3237}
3238
3239bool ZdcAnalysisTool::sigprocSincInterp(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 m_tf1SincInterp->SetParameter(0, deltaT);
3244 for (size_t i = 0; i < nsamp; i++)
3245 {
3246 m_tf1SincInterp->SetParameter(i + 1, adc.at(i) - presamp);
3247 }
3248 amp = m_tf1SincInterp->GetMaximum();
3249 time = m_tf1SincInterp->GetMaximumX();
3250 qual = 1.;
3251 return true;
3252}
3253
3255{
3256 if (!m_zdcDataAnalyzer) return 0;
3257 return m_zdcDataAnalyzer->GetModuleSum(side);
3258}
3259
3261{
3262 if (!m_zdcDataAnalyzer) return 0;
3263 return m_zdcDataAnalyzer->GetCalibModuleSum(side);
3264}
3265
3267{
3268 if (!m_zdcDataAnalyzer) return 0;
3269 return m_zdcDataAnalyzer->GetCalibModuleSumErr(side);
3270}
3271
3273{
3274 if (!m_zdcDataAnalyzer) return 0;
3275 return m_zdcDataAnalyzer->GetNLcalibModuleSum(side);
3276}
3277
3279{
3280 if (!m_zdcDataAnalyzer) return 0;
3281 return m_zdcDataAnalyzer->GetNLcalibModuleSumErr(side);
3282}
3283
3285{
3286 if (!m_zdcDataAnalyzer) return 0;
3287 return m_zdcDataAnalyzer->GetModuleSum(side);
3288}
3289
3291{
3292 if (!m_zdcDataAnalyzer) return 0;
3293 return m_zdcDataAnalyzer->GetModuleSumErr(side);
3294}
3295
3297{
3298 if (!m_zdcDataAnalyzer) return 0;
3299 return m_zdcDataAnalyzer->GetAverageTime(side);
3300}
3301
3303{
3304 if (!m_zdcDataAnalyzer) return 0;
3305 return m_zdcDataAnalyzer->SideFailed(side);
3306}
3307
3309{
3310 if (!m_zdcDataAnalyzer) return 0;
3311 return m_zdcDataAnalyzer->GetModuleMask();
3312}
3313
3315{
3316 if (!m_doTrigEff) return -1;
3317
3318 m_zdcTriggerEfficiency->UpdatelumiBlock(m_lumiBlock);
3319 float adcSum = getModuleSum(side);
3320 double eff = m_zdcTriggerEfficiency->GetEfficiency(side, adcSum);
3321 return eff;
3322}
3323
3325{
3326 if (!m_doCalib) return -1;
3327
3328 m_zdcTriggerEfficiency->UpdatelumiBlock(m_lumiBlock);
3329 float adcSum = getModuleSum(side);
3330 std::pair<double, double> eff_pair = m_zdcTriggerEfficiency->GetEfficiencyAndError(msg(), side, adcSum);
3331 return eff_pair.second;
3332}
3333
3334
3335} // 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 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()
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