ATLAS Offline Software
Loading...
Searching...
No Matches
ZDCDataAnalyzer.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include <utility>
9#include <format>
10
12
13
15 {"moduleEnabled", {JSON::value_t::array, 4, true, false}},
16 {"iterativeCalibCorr", {JSON::value_t::array, 4, true, false}},
17 {"delayedOrder", {JSON::value_t::array, 4, true, false}}
18};
19
20
21ZDCDataAnalyzer::ZDCDataAnalyzer(ZDCMsg::MessageFunctionPtr msgFunc_p, int nSample, float deltaTSample, size_t preSampleIdx, const std::string & fitFunction,
22 const ZDCModuleIntArray& peak2ndDerivMinSamples,
23 const ZDCModuleFloatArray& peak2ndDerivMinThresholdsHG,
24 const ZDCModuleFloatArray& peak2ndDerivMinThresholdsLG,
25 unsigned int LGMode) :
26 m_msgFunc_p(std::move(msgFunc_p))
27{
28 m_moduleEnabled[0] = {{true, true, true, true}};
29 m_moduleEnabled[1] = {{true, true, true, true}};
30
31 m_moduleAnalyzers[0] = {{0, 0, 0, 0}};
32 m_moduleAnalyzers[1] = {{0, 0, 0, 0}};
33
34 m_calibAmplitude[0] = {{0, 0, 0, 0}};
35 m_calibAmplitude[1] = {{0, 0, 0, 0}};
36
37 m_calibTime[0] = {{0, 0, 0, 0}};
38 m_calibTime[1] = {{0, 0, 0, 0}};
39
40 m_dataLoaded[0] = {{false, false, false, false}};
41 m_dataLoaded[1] = {{false, false, false, false}};
42
43 m_delayedOrder[0] = {0, 0, 0, 0};
44 m_delayedOrder[1] = {0, 0, 0, 0};
45
46 // For now we are using hard-coded gain factors and pedestals
47 //
48 m_HGGains[0] = {{10, 10, 10, 10}};
49 m_HGGains[1] = {{10, 10, 10, 10}};
50
51 m_pedestals[0] = {{100, 100, 100, 100}};
52 m_pedestals[1] = {{100, 100, 100, 100}};
53
54 // Construct the per-module pulse analyzers
55 //
56 for (size_t side : {0, 1}) {
57 for (size_t module : {0, 1, 2, 3}) {
58 std::string moduleTag= "_s" + std::to_string(side) + "_m" +std::to_string(module);
59 m_moduleAnalyzers[side][module] = make_unique<ZDCPulseAnalyzer>(m_msgFunc_p, std::move(moduleTag), nSample, deltaTSample, preSampleIdx,
60 m_pedestals[side][module], fitFunction,
61 peak2ndDerivMinSamples[side][module],
62 peak2ndDerivMinThresholdsHG[side][module],
63 peak2ndDerivMinThresholdsLG[side][module]);
64 m_moduleAnalyzers[side][module]->setLGMode(LGMode);
65 }
66 }
67}
68
70 m_msgFunc_p(msgFunc_p)
71{
72 init();
73
74 // Construct the object that will extract the data and pulse analyzer
75 // configurations from the input JSON configuration
76 //
77 // For the data anlyzer we use 1 channel since the relevant
78 // configurations will all be per-side
79 //
80 m_dataAnalyzerConfig = std::make_unique<ZDCJSONConfig>(std::vector<std::string>{"C", "A"}, 1);
81 m_pulseAnalyzerConfig = std::make_unique<ZDCJSONConfig>(std::vector<std::string>{"C", "A"}, 4);
82
83
84 // Extract the JSON object for the pulse analyzer(s)
85 //
86 JSON DAconfig = configJSON["DataAnalyzer"];
87 if (DAconfig.is_null()) {
88 (*m_msgFunc_p)(ZDCMsg::Fatal, "JSON configuration object for ZDCDataAnalyzer not found");
89 return;
90 }
91
92 auto [result, resultStr] = m_dataAnalyzerConfig->ParseConfig(DAconfig, ZDCDataAnalyzer::JSONConfigParams);
93 if (!result) {
94 (*m_msgFunc_p)(ZDCMsg::Fatal, "Error parsing ZDCDataAnalyzer JSON config, error = " + resultStr);
95 return;
96 }
97
98 // The data analyzer configuration is simple enough we handle it inline
99 //
100 for (size_t side : {0, 1}) {
101 for (size_t module : {0, 1, 2, 3}) {
102 m_moduleEnabled[side][module] = true;
103 }
104
105 // Now extract information from ZDCDataAnalyzer-specific configuration
106 //
107 JSON sideConfig = m_dataAnalyzerConfig->getChannelConfig(side, 0);
108 JSON modEnable = sideConfig["moduleEnabled"];
109 JSON delayedOrder = sideConfig["delayedOrder"];
110 JSON iterativeCalibCorr = sideConfig["iterativeCalibCorr"];
111
112 if (!modEnable.is_null()) {
113 if (modEnable.size() != 4) {
114 (*m_msgFunc_p)(ZDCMsg::Fatal, "Error parsing ZDCDataAnalyzer JSON config, incorrect size of moduleEnabled");
115 return;
116 }
117
118 for (size_t module : {0, 1, 2, 3}) {
119 m_moduleEnabled[side][module] = modEnable[module];
120 }
121 }
122 if (!delayedOrder.is_null()) {
123 if (delayedOrder.size() != 4) {
124 (*m_msgFunc_p)(ZDCMsg::Fatal, "Error parsing ZDCDataAnalyzer JSON config, incorrect size of delayedOrder");
125 return;
126 }
127
128 for (size_t module : {0, 1, 2, 3}) {
129 m_delayedOrder[side][module] = delayedOrder[module];
130 }
131 }
132
133
134 // Check for JSON entries for iterative NL correction
135 if (!iterativeCalibCorr.is_null()) {
136
137
138 for (const auto & modIterCalibCorr : iterativeCalibCorr) {
139 if (modIterCalibCorr.size() != 3) {
140 (*m_msgFunc_p)(ZDCMsg::Fatal, "Error parsing ZDCDataAnalyzer JSON config, incorrect size of iterativeCalibCorr entry " + modIterCalibCorr.dump());
141 return;
142 }
143
144 unsigned int module = modIterCalibCorr[0];
145 float refFrac = modIterCalibCorr[1];
146 JSON coeffArray = modIterCalibCorr[2];
147
148 std::vector<float> polyCoeff;
149 for (auto elem : coeffArray) {
150 polyCoeff.push_back(elem);
151 }
152
153 (*m_msgFunc_p)(ZDCMsg::Debug, "Iterative correction using module " + std::to_string(module) + " with reference energy fraction " + std::to_string(refFrac) + " and polynomial with " + std::to_string(polyCoeff.size()) + " terms");
154
155
156 m_iterCalibCorr[side].push_back(std::make_tuple(module, refFrac, polyCoeff));
157 }
158 }
159
161 }
162
163 for (size_t side : {0, 1}) {
164 for (size_t module : {0, 1, 2, 3}) {
165
166 (*m_msgFunc_p)(
168 "Setting up ZDCPulseAnalyzer for side " + std::to_string(side) +
169 ", module " + std::to_string(module) +
170 ", enabled = " + std::to_string(m_moduleEnabled[side][module]) +
171 ", delayedOrder = " +
172 std::to_string(m_delayedOrder[side][module]));
173 }
174 }
175
176
177
178 // Extract the JSON object for the pulse analyzer(s)
179 //
180 JSON PAconfig = configJSON["PulseAnalyzer"];
181 if (PAconfig.is_null()) {
182 (*m_msgFunc_p)(ZDCMsg::Fatal, "JSON configuration object for ZDCPulseAnalyzer not found");
183 return;
184 }
185
186 // Do the parsing of the pulse analyzer JSON configuration
187 //
188 auto [result2, resultStr2] = m_pulseAnalyzerConfig->ParseConfig(PAconfig, ZDCPulseAnalyzer::JSONConfigParams);
189 if (!result2) {
190 (*m_msgFunc_p)(ZDCMsg::Fatal, "Error parsing ZDCPulseAnalyzer JSON config, error = " + resultStr2);
191 return;
192 }
193
194 // Now set up each of the pulse analyzers
195 //
196 for (size_t side : {0, 1}) {
197 for (size_t module : {0, 1, 2, 3}) {
198
199 (*m_msgFunc_p)(ZDCMsg::Info, "Setting up ZDCPulseAnalyzer for side " + std::to_string(side) +
200 ", module " + std::to_string(module));
201
202 //
203 // Get the parsed configuration JSON object for this module
204 //
205 JSON moduleConfig = m_pulseAnalyzerConfig->getChannelConfig(side, module);
206
207 std::ostringstream ostr;
208 ostr << "JSON configuration for ZDC pulse analyyzer for side " << std::to_string(side)
209 << ", module " << std::to_string(module) << "\n" << moduleConfig.dump(2);
210 (*m_msgFunc_p)(ZDCMsg::Verbose, ostr.str());
211
212 // Construct the ZDCPulseAnalyzer object
213 //
214 m_moduleAnalyzers[side][module] = std::make_unique<ZDCPulseAnalyzer>(msgFunc_p, moduleConfig);
215
216 (*m_msgFunc_p)(ZDCMsg::Info, "Finished constructing ZDCPulseAnalyzer for side " + std::to_string(side) +
217 ", module " + std::to_string(module));
218
219 }
220 }
221
222 // Check for the enabling of re-pass
223 //
225
226 (*m_msgFunc_p)(ZDCMsg::Info, "ZDCDataAnalyzer construction complete");
227}
228
230{
231 for (size_t side : {0, 1}) {
232 m_moduleSum[side] = 0;
233 m_moduleSumErrSq[side] = 0;
234 m_moduleSumPreSample[side] = 0;
235 m_calibModuleSum[side] = 0;
236 m_calibModuleSumErrSq[side] = 0;
237
238 m_NLcalibModuleSum[side] = 0;
239 m_NLcalibModuleSumErrSq[side] = 0;
240 m_averageTime[side] = 0;
241 m_fail[side] = 0;
242
243 for (size_t module : {0, 1, 2, 3}) {
244 m_moduleEnabled[side][module] = true;
245 m_calibAmplitude[side][module] = 0;
246 m_calibTime[side][module] = 0;
247
248 m_dataLoaded[side][module] = false;
249 m_delayedOrder[side][module] = 0;
250
251 // Default "calibrations"
252 //
253 m_currentECalibCoeff[side][module] = 1;
254 m_currentT0OffsetsHG[side][module] = 0;
255 m_currentT0OffsetsLG[side][module] = 0;
256
257 }
258 }
259
261 {{ {{0,0,0,0,0,0}},{{0,0,0,0,0,0}},{{0,0,0,0,0,0}} }},
262 {{ {{0,0,0,0,0,0}},{{0,0,0,0,0,0}},{{0,0,0,0,0,0}} }} }};
263
264}
265
266bool ZDCDataAnalyzer::disableModule(size_t side, size_t module)
267{
268 if (side < 2 && module < 4) {
269 //
270 // Can't disable in the middle of analysis
271 //
272 if (m_dataLoaded[side][module]) return false;
273 else {
274 m_moduleEnabled[side][module] = false;
275 return true;
276 }
277 }
278 else {
279 return false;
280 }
281}
282
284{
285 for (size_t side : {0, 1}) {
286 for (size_t module : {0, 1, 2, 3}) {
287 m_moduleAnalyzers[side][module]->saveFitFunc(save);
288 }
289 }
290}
291
292
293void ZDCDataAnalyzer::enableDelayed(float deltaT, const ZDCModuleFloatArray& undelayedDelayedPedestalDiff)
294{
295 int delayedOrder = deltaT < 0 ? -1 : 1;
296 for (size_t side : {0, 1}) {
297 for (size_t module : {0, 1, 2, 3}) {
298 m_delayedOrder[side][module] = delayedOrder;
299 m_moduleAnalyzers[side][module]->enableDelayed(std::abs(deltaT), undelayedDelayedPedestalDiff[side][module]);
300 }
301 }
302}
303
304void ZDCDataAnalyzer::enableDelayed(const ZDCModuleFloatArray& delayDeltaTArray, const ZDCModuleFloatArray& undelayedDelayedPedestalDiff)
305{
306 for (size_t side : {0, 1}) {
307 for (size_t module : {0, 1, 2, 3}) {
308 if (delayDeltaTArray[side][module] < 0) m_delayedOrder[side][module] = -1;
309 else m_delayedOrder[side][module] = 1;
310
311 (*m_msgFunc_p)(ZDCMsg::Verbose, "Enabling use of delayed samples on side, module = " + std::to_string(side) + ", " +
312 std::to_string(module) + ", delta t = " + std::to_string(delayDeltaTArray[side][module]));
313
314 m_moduleAnalyzers[side][module]->enableDelayed(std::abs(delayDeltaTArray[side][module]), undelayedDelayedPedestalDiff[side][module]);
315 }
316 }
317}
318
319void ZDCDataAnalyzer::enablePreExclusion(unsigned int maxSamplesExcl, const ZDCModuleIntArray& HGADCThresh, const ZDCModuleIntArray& LGADCThresh)
320{
321 for (size_t side : {0, 1}) {
322 for (size_t module : {0, 1, 2, 3}) {
323 m_moduleAnalyzers[side][module]->enablePreExclusion(maxSamplesExcl, HGADCThresh[side][module], LGADCThresh[side][module]);
324 }
325 }
326}
327
328void ZDCDataAnalyzer::enablePreExclusion(unsigned int maxSamplesExcl, unsigned int HGADCThresh, unsigned int LGADCThresh)
329{
330 for (size_t side : {0, 1}) {
331 for (size_t module : {0, 1, 2, 3}) {
332 m_moduleAnalyzers[side][module]->enablePreExclusion(maxSamplesExcl, HGADCThresh, LGADCThresh);
333 }
334 }
335}
336
337void ZDCDataAnalyzer::enablePostExclusion(unsigned int maxSamplesExcl, const ZDCModuleIntArray& HGADCThresh, const ZDCModuleIntArray& LGADCThresh)
338{
339 for (size_t side : {0, 1}) {
340 for (size_t module : {0, 1, 2, 3}) {
341 m_moduleAnalyzers[side][module]->enablePostExclusion(maxSamplesExcl, HGADCThresh[side][module], LGADCThresh[side][module]);
342 }
343 }
344}
345
346void ZDCDataAnalyzer::enablePostExclusion(unsigned int maxSamplesExcl, unsigned int HGADCThresh, unsigned int LGADCThresh)
347{
348 for (size_t side : {0, 1}) {
349 for (size_t module : {0, 1, 2, 3}) {
350 m_moduleAnalyzers[side][module]->enablePostExclusion(maxSamplesExcl, HGADCThresh, LGADCThresh);
351 }
352 }
353}
354
355
356void ZDCDataAnalyzer::enableRepass(const ZDCModuleFloatArray& peak2ndDerivMinRepassHG, const ZDCModuleFloatArray& peak2ndDerivMinRepassLG)
357{
358 m_repassEnabled = true;
359 for (size_t side : {0, 1}) {
360 for (size_t module : {0, 1, 2, 3}) {
361 m_moduleAnalyzers[side][module]->enableRepass(peak2ndDerivMinRepassHG[side][module], peak2ndDerivMinRepassLG[side][module]);
362 }
363 }
364}
365
366void ZDCDataAnalyzer::setMinimumSignificance(float sigMinHG, float sigMinLG)
367{
368 for (size_t side : {0, 1}) {
369 for (size_t module : {0, 1, 2, 3}) {
370 m_moduleAnalyzers[side][module]->setMinimumSignificance(sigMinHG, sigMinLG);
371 }
372 }
373}
374
376{
377 for (size_t side : {0, 1}) {
378 for (size_t module : {0, 1, 2, 3}) {
379 m_moduleAnalyzers[side][module]->set2ndDerivStep(step);
380 }
381 }
382}
383
384void ZDCDataAnalyzer::SetGainFactorsHGLG(float gainFactorHG, float gainFactorLG)
385{
386 for (size_t side : {0, 1}) {
387 for (size_t module : {0, 1, 2, 3}) {
388 m_moduleAnalyzers[side][module]->SetGainFactorsHGLG(gainFactorHG, gainFactorLG);
389 }
390 }
391}
392
394{
395 for (size_t side : {0, 1}) {
396 for (size_t module : {0, 1, 2, 3}) {
397 m_moduleAnalyzers[side][module]->SetGainFactorsHGLG(gainFactorsHG[side][module], gainFactorsLG[side][module]);
398 }
399 }
400}
401
403 for (size_t side : {0, 1}) {
404 for (size_t module : {0, 1, 2, 3}) {
405 m_moduleAnalyzers[side][module]->SetPeak2ndDerivMinTolerance(tolerance);
406 }
407 }
408}
409
410
412 for (size_t side : {0, 1}) {
413 for (size_t module : {0, 1, 2, 3}) {
414 m_moduleAnalyzers[side][module]->SetFitTimeMax(tmax);
415 }
416 }
417}
418
419
420
422 const ZDCModuleFloatArray& tau1, const ZDCModuleFloatArray& tau2,
423 const ZDCModuleFloatArray& t0HG, const ZDCModuleFloatArray& t0LG)
424{
425 for (size_t side : {0, 1}) {
426 for (size_t module : {0, 1, 2, 3}) {
427 m_moduleAnalyzers[side][module]->SetTauT0Values(fixTau1[side][module], fixTau2[side][module],
428 tau1[side][module], tau2[side][module], t0HG[side][module], t0LG[side][module]);
429 }
430 }
431}
432
433void ZDCDataAnalyzer::SetNoiseSigmas(const ZDCModuleFloatArray& noiseSigmasHG, const ZDCModuleFloatArray& noiseSigmasLG)
434{
435 for (size_t side : {0, 1}) {
436 for (size_t module : {0, 1, 2, 3}) {
437 m_moduleAnalyzers[side][module]->SetNoiseSigmas(noiseSigmasHG[side][module], noiseSigmasLG[side][module]);
438 }
439 }
440}
441
442void ZDCDataAnalyzer::setPerSampleNoiseSigmas(const std::array<std::array<std::vector<float>,4>,2>& sampleNoiseVecsHG,
443 const std::array<std::array<std::vector<float>,4>,2>& sampleNoiseVecsLG)
444{
445 for (size_t side : {0, 1}) {
446 for (size_t module : {0, 1, 2, 3}) {
447 m_moduleAnalyzers[side][module]->setPerSampleNoiseSigmas(sampleNoiseVecsHG[side][module], sampleNoiseVecsLG[side][module]);
448 }
449 }
450}
451
453 for (size_t side : {0, 1}) {
454 for (size_t module : {0, 1, 2, 3}) {
455 m_moduleAmpFractionLG[side][module] = moduleAmpFractionLG[side][module];
456 }
457 }
458}
459
461 const ZDCModuleFloatArray& maxAmpHG, const ZDCModuleFloatArray& maxAmpLG)
462{
463 for (size_t side : {0, 1}) {
464 for (size_t module : {0, 1, 2, 3}) {
465 m_moduleAnalyzers[side][module]->SetFitMinMaxAmp(minAmpHG[side][module], minAmpLG[side][module],
466 maxAmpHG[side][module], maxAmpLG[side][module]);
467
468 }
469 }
470}
471
472void ZDCDataAnalyzer::SetFitMinMaxAmpValues(float minHG, float minLG, float maxHG, float maxLG)
473{
474 for (size_t side : {0, 1}) {
475 for (size_t module : {0, 1, 2, 3}) {
476 m_moduleAnalyzers[side][module]->SetFitMinMaxAmp(minHG, minLG, maxHG, maxLG);
477 }
478 }
479}
480
482 const ZDCModuleFloatArray& LGOverflowADC)
483{
484 for (size_t side : {0, 1}) {
485 for (size_t module : {0, 1, 2, 3}) {
486 m_moduleAnalyzers[side][module]->SetADCOverUnderflowValues(HGOverflowADC[side][module], HGUnderflowADC[side][module], LGOverflowADC[side][module]);
487 }
488 }
489}
490
491void ZDCDataAnalyzer::SetCutValues(const ZDCModuleFloatArray& chisqDivAmpCutHG, const ZDCModuleFloatArray& chisqDivAmpCutLG,
492 const ZDCModuleFloatArray& deltaT0MinHG, const ZDCModuleFloatArray& deltaT0MaxHG,
493 const ZDCModuleFloatArray& deltaT0MinLG, const ZDCModuleFloatArray& deltaT0MaxLG)
494{
495 for (size_t side : {0, 1}) {
496 for (size_t module : {0, 1, 2, 3}) {
497 m_moduleAnalyzers[side][module]->SetCutValues(chisqDivAmpCutHG[side][module], chisqDivAmpCutLG[side][module],
498 deltaT0MinHG[side][module], deltaT0MaxHG[side][module],
499 deltaT0MinLG[side][module], deltaT0MaxLG[side][module]);
500 }
501 }
502}
503
504void ZDCDataAnalyzer::SetTimeCuts(const ZDCModuleFloatArray& deltaT0MinHG, const ZDCModuleFloatArray& deltaT0MaxHG,
505 const ZDCModuleFloatArray& deltaT0MinLG, const ZDCModuleFloatArray& deltaT0MaxLG)
506{
507 for (size_t side : {0, 1}) {
508 for (size_t module : {0, 1, 2, 3}) {
509 m_moduleAnalyzers[side][module]->SetTimeCuts(deltaT0MinHG[side][module], deltaT0MaxHG[side][module],
510 deltaT0MinLG[side][module], deltaT0MaxLG[side][module]);
511 }
512 }
513}
514
515void ZDCDataAnalyzer::SetChisqCuts(const ZDCModuleFloatArray& chisqDivAmpCutHG, const ZDCModuleFloatArray& chisqDivAmpScaleHG,
516 const ZDCModuleFloatArray& chisqDivAmpOffsetHG, const ZDCModuleFloatArray& chisqDivAmpPowerHG,
517 const ZDCModuleFloatArray& chisqDivAmpCutLG, const ZDCModuleFloatArray& chisqDivAmpScaleLG,
518 const ZDCModuleFloatArray& chisqDivAmpOffsetLG, const ZDCModuleFloatArray& chisqDivAmpPowerLG)
519{
520 for (size_t side : {0, 1}) {
521 for (size_t module : {0, 1, 2, 3}) {
522 m_moduleAnalyzers[side][module]->SetChisqCuts(chisqDivAmpCutHG[side][module], chisqDivAmpScaleHG[side][module],
523 chisqDivAmpOffsetHG[side][module], chisqDivAmpPowerHG[side][module],
524 chisqDivAmpCutLG[side][module], chisqDivAmpScaleLG[side][module],
525 chisqDivAmpOffsetLG[side][module], chisqDivAmpPowerLG[side][module]);
526 }
527 }
528}
529
530void ZDCDataAnalyzer::enablePostPulseCheck(unsigned int postPulseSampleDelta, float postPulseDerivMinSig,
531 float postPulseAbsDer2ndMinSig, float minMainDer2ndRatio)
532{
533 for (size_t side : {0, 1}) {
534 for (size_t module : {0, 1, 2, 3}) {
535 m_moduleAnalyzers[side][module]->enablePostPulseCheck(postPulseSampleDelta, postPulseDerivMinSig, postPulseAbsDer2ndMinSig, minMainDer2ndRatio);
536 }
537 }
538}
539
541 const std::array<std::array<std::vector<float>, 4>, 2>& HGParamArr,
542 const std::array<std::array<std::vector<float>, 4>, 2>& LGParamArr)
543{
544 for (size_t side : {0, 1}) {
545 for (size_t module : {0, 1, 2, 3}) {
546 m_moduleAnalyzers[side][module]->SetTimingCorrParams(mode, refADC, refScale,
547 HGParamArr.at(side).at(module), LGParamArr.at(side).at(module));
548 }
549 }
550
551}
552
553void ZDCDataAnalyzer::SetNonlinCorrParams(float refADC, float refScale,
554 const std::array<std::array<std::vector<float>, 4>, 2>& HGNonlinCorrParams,
555 const std::array<std::array<std::vector<float>, 4>, 2>& LGNonlinCorrParams)
556{
557 for (size_t side : {0, 1}) {
558 for (size_t module : {0, 1, 2, 3}) {
559 m_moduleAnalyzers[side][module]->SetNonlinCorrParams(refADC, refScale,
560 HGNonlinCorrParams[side][module],
561 LGNonlinCorrParams[side][module]);
562 }
563 }
564}
565
566void ZDCDataAnalyzer::SetNLcalibParams(std::array< std::array< std::vector<float>, 3>, 2>& nlcalibParams)
567{
568 for (size_t side: {0,1})
569 {
570 for (size_t module: {0,1,2})
571 {
572 m_NLcalibFactors[side][module] = nlcalibParams[side][module];
573 }
574 }
575 m_haveNLcalib = true;
576}
577
578void ZDCDataAnalyzer::enableFADCCorrections(bool correctPerSample,
579 std::array<std::array<std::unique_ptr<const TH1>, 4>, 2>& corrHistHG,
580 std::array<std::array<std::unique_ptr<const TH1>, 4>, 2>& corrHistLG)
581{
582 if (correctPerSample)
583 (*m_msgFunc_p)(ZDCMsg::Info, "ZDCDataAnalyzer::enabling FADC Corrections per sample");
584 else
585 (*m_msgFunc_p)(ZDCMsg::Info, "ZDCDataAnalyzer::enabling FADC Corrections per amplitude");
586
587 for (size_t side : {0, 1}) {
588 for (size_t module : {0, 1, 2, 3}) {
589 m_moduleAnalyzers[side][module]->enableFADCCorrections(correctPerSample, corrHistHG[side][module], corrHistLG[side][module]);
590 }
591 }
592}
593
595{
596 for (size_t side : {0, 1}) {
597 for (size_t module : {0, 1, 2, 3}) {
598 m_moduleAnalyzers[side][module]->disableFADCCorrections();
599 }
600 }
601}
602
603void ZDCDataAnalyzer::enableTimeSigCut(bool AND, float sigCut, const std::string& TF1String,
604 const std::array<std::array<std::vector<double>, 4>, 2>& parsHGArr,
605 const std::array<std::array<std::vector<double>, 4>, 2>& parsLGArr)
606{
607 for (size_t side : {0, 1}) {
608 for (size_t module : {0, 1, 2, 3}) {
609 m_moduleAnalyzers[side][module]->enableTimeSigCut(AND, sigCut, TF1String, parsHGArr[side][module], parsLGArr[side][module]);
610 }
611 }
612}
613
615{
616 (*m_msgFunc_p)(ZDCMsg::Verbose, ("Starting new event, event index = " + std::to_string(m_eventCount)));
617
618 // See if we have to load up new calibrations
619 //
620 if (lumiBlock != m_currentLB) {
621 (*m_msgFunc_p)(ZDCMsg::Verbose, ("Starting new luminosity block " + std::to_string(lumiBlock)));
622
623 if (m_haveECalib) {
624 (*m_msgFunc_p)(ZDCMsg::Verbose, ("Loading energy calibrations for event " + std::to_string(m_eventCount) + ", lumi block " +
625 std::to_string(lumiBlock)));
626
627 for (size_t side : {0, 1}) {
628 for (size_t module : {0, 1, 2, 3}) {
629 float splineLBMin = m_LBDepEcalibSplines[side][module]->GetXmin();
630 float splineLBMax = m_LBDepEcalibSplines[side][module]->GetXmax();
631
632 if (lumiBlock >= splineLBMin && lumiBlock <= splineLBMax) {
633 m_currentECalibCoeff[side][module] = m_LBDepEcalibSplines[side][module]->Eval(lumiBlock);
634 }
635 else if (lumiBlock < splineLBMin) {
636 m_currentECalibCoeff[side][module] = m_LBDepEcalibSplines[side][module]->Eval(splineLBMin);
637 }
638 else {
639 m_currentECalibCoeff[side][module] = m_LBDepEcalibSplines[side][module]->Eval(splineLBMax);
640 }
641 }
642 }
643 } // end of if (_haveEcalib) {
644
645 if (m_haveT0Calib) {
646 (*m_msgFunc_p)(ZDCMsg::Verbose, ("Loading timing calibrations for event " + std::to_string(m_eventCount) + ", lumi block " + std::to_string(lumiBlock)));
647
648 for (size_t side : {0, 1}) {
649 for (size_t module : {0, 1, 2, 3}) {
650 float splineLBMin = m_T0HGOffsetSplines[side][module]->GetXmin();
651 float splineLBMax = m_T0HGOffsetSplines[side][module]->GetXmax();
652
653 if (lumiBlock >= splineLBMin && lumiBlock <= splineLBMax) {
654 m_currentT0OffsetsHG[side][module] = m_T0HGOffsetSplines[side][module]->Eval(lumiBlock);
655 m_currentT0OffsetsLG[side][module] = m_T0LGOffsetSplines[side][module]->Eval(lumiBlock);
656 }
657 else if (lumiBlock < splineLBMin) {
658 m_currentT0OffsetsHG[side][module] = m_T0HGOffsetSplines[side][module]->Eval(splineLBMin);
659 m_currentT0OffsetsLG[side][module] = m_T0LGOffsetSplines[side][module]->Eval(splineLBMin);
660 }
661 else {
662 m_currentT0OffsetsHG[side][module] = m_T0HGOffsetSplines[side][module]->Eval(splineLBMax);
663 m_currentT0OffsetsLG[side][module] = m_T0LGOffsetSplines[side][module]->Eval(splineLBMax);
664 }
665 }
666 }
667 } // end of if (m_haveT0Calib)
668 }
669
670 // Initialize transient results
671 //
672 for (size_t side : {0, 1}) {
673 for (size_t module : {0, 1, 2, 3}) {
674 m_dataLoaded[side][module] = false;
675 m_moduleStatus[side][module] = 0;
676 m_calibAmplitude[side][module] = 0;
677 m_calibTime[side][module] = 0;
678 // _moduleFail[side][module] = false;
679 }
680
681 m_moduleSum[side] = 0;
682 m_moduleSumErrSq[side] = 0;
683 m_moduleSumPreSample[side] = 0;
684 m_moduleSumBkgdFrac[side] = 0;
685
686 m_calibModuleSum[side] = 0;
687 m_calibModuleSumErrSq[side] = 0;
688 m_calibModSumBkgdFrac[side] = 0;
689
690 m_NLcalibModuleSum[side] = 0;
691 m_NLcalibModuleSumErrSq[side] = 0;
692 m_NLcalibModSumBkgdFrac[side] = 0;
693
694 m_averageTime[side] = 0;
695 m_fail[side] = false;
696 }
697
698 m_moduleMask = 0;
699 m_currentLB = lumiBlock;
700}
701
702void ZDCDataAnalyzer::LoadAndAnalyzeData(size_t side, size_t module, const std::vector<float>& HGSamples, const std::vector<float>& LGSamples)
703{
704
705 // We immediately return if this module is disabled
706 //
707 if (!m_moduleEnabled[side][module]) {
708 (*m_msgFunc_p)(ZDCMsg::Verbose, ("Skipping analysis of disabled module for event index " + std::to_string(m_eventCount) + ", side, module = " + std::to_string(side) + ", " + std::to_string(module)));
709
710 return;
711 }
712
713 (*m_msgFunc_p)(ZDCMsg::Verbose, ("/n Loading data for event index " + std::to_string(m_eventCount) + ", side, module = " + std::to_string(side) + ", " + std::to_string(module)));
714
715 ZDCPulseAnalyzer* pulseAna_p = m_moduleAnalyzers[side][module].get();
716 pulseAna_p->LoadAndAnalyzeData(HGSamples, LGSamples);
717 m_dataLoaded[side][module] = true;
718
719 if (pulseAna_p->failed()) {
720 (*m_msgFunc_p)(ZDCMsg::Debug, ("ZDCPulseAnalyzer::LoadData() returned fail for event " + std::to_string(m_eventCount) + ", side, module = " + std::to_string(side) + ", " + std::to_string(module)));
721
722 m_fail[side] = true;
723 }
724
725 m_moduleStatus[side][module] = pulseAna_p->GetStatusMask();
726}
727
728void ZDCDataAnalyzer::LoadAndAnalyzeData(size_t side, size_t module, const std::vector<float>& HGSamples, const std::vector<float>& LGSamples,
729 const std::vector<float>& HGSamplesDelayed, const std::vector<float>& LGSamplesDelayed)
730{
731 // We immediately return if this module is disabled
732 //
733 if (!m_moduleEnabled[side][module]) {
734 (*m_msgFunc_p)(ZDCMsg::Debug, ("Skipping analysis of disabled mofule for event index " + std::to_string(m_eventCount) + ", side, module = " + std::to_string(side) + ", " + std::to_string(module)));
735
736 return;
737 }
738
739 if (m_delayedOrder[side][module] == 0) {
740 (*m_msgFunc_p)(ZDCMsg::Error, ("Handling of delayed pulses not enabled, on side, module = " + std::to_string(side) + ", " + std::to_string(module) + ", skipping processing for event index " + std::to_string(m_eventCount)));
741 return;
742 }
743
744 (*m_msgFunc_p)(ZDCMsg::Verbose, ("Loading undelayed and delayed data for event index " + std::to_string(m_eventCount) + ", side, module = " + std::to_string(side) + ", " + std::to_string(module)));
745
746 ZDCPulseAnalyzer* pulseAna_p = m_moduleAnalyzers[side][module].get();
747 if (m_delayedOrder[side][module] > 0) {
748 pulseAna_p->LoadAndAnalyzeData(HGSamples, LGSamples, HGSamplesDelayed, LGSamplesDelayed);
749 }
750 else {
751 pulseAna_p->LoadAndAnalyzeData(HGSamplesDelayed, LGSamplesDelayed, HGSamples, LGSamples);
752 }
753 m_dataLoaded[side][module] = true;
754
755 if (pulseAna_p->failed()) {
756 (*m_msgFunc_p)(ZDCMsg::Debug, ("ZDCPulseAnalyzer::LoadData() returned fail for event " + std::to_string(m_eventCount) + ", side, module = " + std::to_string(side) + ", " + std::to_string(module)));
757
758 m_fail[side] = true;
759 }
760
761 m_moduleStatus[side][module] = pulseAna_p->GetStatusMask();
762}
763
765{
766 // First make sure that all data is loaded. while we're at it, count how many modules on each side have a pulse
767 //
768 unsigned int sideNPulsesMod[2] = {0, 0};
769
770 for (size_t side : {0, 1}) {
771 for (size_t module : {0, 1, 2, 3}) {
772 if (!m_dataLoaded[side][module] && m_moduleEnabled[side][module]) {return false;}
773 if (m_moduleAnalyzers[side][module]->armSumInclude()) {sideNPulsesMod[side]++;}
774 }
775 }
776
777 // Are we doing a repass? If so, reanalyze modules for which no pulse was found the first time
778 // as long as we have one module with a pulse on the given side
779 //
780 if (m_repassEnabled) {
781 for (size_t side : {0, 1}) {
782 if (sideNPulsesMod[side] == 0) continue;
783
784 for (size_t module : {0, 1, 2, 3}) {
785 if (!m_moduleEnabled[side][module]) continue;
786
787 ZDCPulseAnalyzer* pulseAna_p = m_moduleAnalyzers[side][module].get();
788
789 // If this module had no pulse the first time, reanalyze it (with a lower 2nd derivative threshold)
790 //
791 if (!pulseAna_p->havePulse()) {
792 (*m_msgFunc_p)(ZDCMsg::Debug, ("ZDCPulseAnalyzer:: performing a repass on data for side, module = " + std::to_string(side) + ", " + std::to_string(module)));
793 pulseAna_p->ReanalyzeData();
794 m_moduleStatus[side][module] = pulseAna_p->GetStatusMask();
795 }
796 }
797 }
798 }
799
800 // Now sum up amplitudes etc
801 //
802 for (size_t side : {0, 1}) {
803 float tempFraction = 1.0;
804 double sumAmpTimesBkgdFrac = 0.0;
805 double sumCalibAmpTimesBkgdFrac = 0.0;
806
807 for (size_t module : {0, 1, 2, 3}) {
808 ZDCPulseAnalyzer* pulseAna_p = m_moduleAnalyzers[side][module].get();
809
810 if (pulseAna_p->armSumInclude()) {
811 int moduleMaskBit = 4 * side + module;
812 m_moduleMask |= 1 << moduleMaskBit;
813
814 float amplitude = pulseAna_p->GetAmplitude();
815 float ampError = pulseAna_p->GetAmpError();
816 float bkgdFraction = pulseAna_p->GetBkgdMaxFraction();
817
818 m_calibAmplitude[side][module] = amplitude * m_currentECalibCoeff[side][module];
819
820 float calibAmpError = ampError * m_currentECalibCoeff[side][module];
821
822 float timeCalib = pulseAna_p->GetT0Corr();
823 if (pulseAna_p->useLowGain()) {timeCalib -= m_currentT0OffsetsLG[side][module];}
824 else {timeCalib -= m_currentT0OffsetsHG[side][module];}
825
826 m_calibTime[side][module] = timeCalib;
827
828 m_moduleSum[side] += amplitude;
829 m_moduleSumErrSq[side] += ampError * ampError;
830 sumAmpTimesBkgdFrac += amplitude*bkgdFraction;
831
832 m_moduleSumPreSample[side] += pulseAna_p->GetPreSampleAmp();
833
834 m_calibModuleSum[side] += m_calibAmplitude[side][module];
835 m_calibModuleSumErrSq[side] += calibAmpError * calibAmpError;
836
837 m_averageTime[side] += m_calibTime[side][module] * m_calibAmplitude[side][module];
838 sumCalibAmpTimesBkgdFrac += amplitude*bkgdFraction;
839 }
840
841 // subtract the fraction of LGOverflow events if we have fraction available (<0 means unavailable)
842 if (pulseAna_p->LGOverflow() && m_moduleAmpFractionLG[side][module] > 0) {tempFraction -= m_moduleAmpFractionLG[side][module];}
843 }
844
845 {
847 if (m_moduleSum[side] > 0) m_moduleSumBkgdFrac[side] = sumAmpTimesBkgdFrac/m_moduleSum[side];
848 else m_moduleSumBkgdFrac[side] = 0;
849 }
850
851 if (m_calibModuleSum[side] > 1e-6) {
852 m_averageTime[side] /= m_calibModuleSum[side];
853 m_calibModSumBkgdFrac[side] = sumCalibAmpTimesBkgdFrac/m_calibModuleSum[side];
854 }
855 else {
856 m_averageTime[side] = 0;
857 m_calibModSumBkgdFrac[side] = 0;
858 }
859
860 if (tempFraction < 1.0) {m_moduleSum[side] /= tempFraction;}
861 }
862
864
865 m_eventCount++;
866 return true;
867}
868
869
871{
872 if (!m_haveIterCalibCorr) return;
873
874
875 //loop over both sides; first index in m_iterCalibcorr
876 for (int iside:{0,1}){
877
878 // If the module mask is empty for this side, there's nothing to do
879 if ((m_moduleMask>>(4*iside)&0xf) == 0) continue;
880
881 if (m_calibModuleSum[iside]>0.){ //it's theoretically possible that: one or more modules fired → module mask is nonzero → mask check passes
882 //but their calibrated amplitudes are so small they sum to essentially zero
883
884 //use uncorrected energy first and update in each iteration of the loop over module tuples
885 float totalmoduleE= m_calibModuleSum[iside];
886
887 //loop over module tuples
888 for (auto modtuple : m_iterCalibCorr[iside]){
889 //get and unpack tuple
890 unsigned int modnum = std::get<0>(modtuple);
891 float ftyp = std::get<1>(modtuple);
892 std::vector<float> polyCoeffs = std::get<2>(modtuple);
893
894 //calculate energy fraction using current total energy
895 float f= m_calibAmplitude[iside][modnum]/totalmoduleE;
896
897 //calculate energy correction
898 float CorrFact = 0;
899 for (size_t i=0;i<polyCoeffs.size(); i++){
900 CorrFact += std::pow(f -ftyp,i)*polyCoeffs[i];
901 }
902
903 //check that CorrFact !=0 so we don't divide by 0 [[unlikely]
904 if (CorrFact == 0.){
905 (*m_msgFunc_p)(ZDCMsg::Error,"ZDCDataAnalyzer::DoNLcalibModuleSum: Denominator is zero");
906 return;
907 }
908
909 //apply energy correction
910 totalmoduleE= totalmoduleE/CorrFact;
911 }
912
913 //m_calibModuleSum[iside] = totalmoduleE;
914 m_NLcalibModuleSum[iside] = totalmoduleE;
915 m_NLcalibModuleSumErrSq[iside] = 0.; // no error for now
916 }
917
918 else{
919 (*m_msgFunc_p)(ZDCMsg::Info,"SUM = 0!!");
920 m_NLcalibModuleSum[iside] = 0.;
921 m_NLcalibModuleSumErrSq[iside] = 0.; // no error for now
922 }
923 }
924
925}
std::array< std::array< std::vector< float >, 3 >, 2 > m_NLcalibFactors
std::unique_ptr< ZDCJSONConfig > m_dataAnalyzerConfig
void enablePreExclusion(unsigned int maxSamplesExcl, const ZDCModuleIntArray &HGADCThresh, const ZDCModuleIntArray &LGADCThresh)
void SetNoiseSigmas(const ZDCModuleFloatArray &noiseSigmasHG, const ZDCModuleFloatArray &noiseSigmasLG)
void SetCutValues(const ZDCModuleFloatArray &chisqDivAmpCutHG, const ZDCModuleFloatArray &chisqDivAmpCutLG, const ZDCModuleFloatArray &deltaT0MinHG, const ZDCModuleFloatArray &deltaT0MaxHG, const ZDCModuleFloatArray &deltaT0MinLG, const ZDCModuleFloatArray &deltaT0MaxLG)
void SetChisqCuts(const ZDCModuleFloatArray &chisqDivAmpCutHG, const ZDCModuleFloatArray &chisqDivAmpScaleHG, const ZDCModuleFloatArray &chisqDivAmpOffsetHG, const ZDCModuleFloatArray &chisqDivAmpPowerHG, const ZDCModuleFloatArray &chisqDivAmpCutLG, const ZDCModuleFloatArray &chisqDivAmpScaleLG, const ZDCModuleFloatArray &chisqDivAmpOffsetLG, const ZDCModuleFloatArray &chisqDivAmpPowerLG)
void enablePostExclusion(unsigned int maxSamplesExcl, const ZDCModuleIntArray &HGADCThresh, const ZDCModuleIntArray &LGADCThresh)
void SetFitTimeMax(float tmax)
ZDCMsg::MessageFunctionPtr m_msgFunc_p
void setPerSampleNoiseSigmas(const std::array< std::array< std::vector< float >, 4 >, 2 > &sampleNoiseVecsHG, const std::array< std::array< std::vector< float >, 4 >, 2 > &sampleNoiseVecsLG)
std::array< std::array< std::unique_ptr< ZDCPulseAnalyzer >, 4 >, 2 > m_moduleAnalyzers
void enableFADCCorrections(bool correctPerSample, std::array< std::array< std::unique_ptr< const TH1 >, 4 >, 2 > &correHistHG, std::array< std::array< std::unique_ptr< const TH1 >, 4 >, 2 > &correHistLG)
std::array< float, 2 > m_NLcalibModSumBkgdFrac
std::array< std::array< std::unique_ptr< TSpline >, 4 >, 2 > m_T0LGOffsetSplines
std::array< std::array< bool, 4 >, 2 > ZDCModuleBoolArray
void LoadAndAnalyzeData(size_t side, size_t module, const std::vector< float > &HGSamples, const std::vector< float > &LGSamples)
void saveFitFunc(bool save)
ZDCModuleFloatArray m_pedestals
std::array< std::array< float, 4 >, 2 > m_calibAmplitude
std::array< float, 2 > m_moduleSumPreSample
ZDCModuleBoolArray m_moduleEnabled
std::array< std::array< float, 4 >, 2 > ZDCModuleFloatArray
std::array< float, 2 > m_calibModSumBkgdFrac
ZDCModuleFloatArray m_currentECalibCoeff
bool disableModule(size_t side, size_t module)
std::unique_ptr< ZDCJSONConfig > m_pulseAnalyzerConfig
void SetTauT0Values(const ZDCModuleBoolArray &fxiTau1, const ZDCModuleBoolArray &fxiTau2, const ZDCModuleFloatArray &tau1, const ZDCModuleFloatArray &tau2, const ZDCModuleFloatArray &t0HG, const ZDCModuleFloatArray &t0LG)
std::array< float, 2 > m_averageTime
void SetGainFactorsHGLG(float gainFactorHG, float gainFactorLG)
void enablePostPulseCheck(unsigned int postPulseSampleDelta, float postPulseDerivMinSig, float postPulseAbsDer2ndMinSig, float minMainDer2ndRatio)
std::array< std::array< int, 4 >, 2 > ZDCModuleIntArray
void SetTimeCuts(const ZDCModuleFloatArray &deltaT0MinHG, const ZDCModuleFloatArray &deltaT0MaxHG, const ZDCModuleFloatArray &deltaT0MinLG, const ZDCModuleFloatArray &deltaT0MaxLG)
void SetModuleAmpFractionLG(const ZDCDataAnalyzer::ZDCModuleFloatArray &moduleAmpFractionLG)
void setMinimumSignificance(float sigMinHG, float sigMinLG)
std::array< std::array< bool, 4 >, 2 > m_dataLoaded
void enableRepass(const ZDCModuleFloatArray &peak2ndDerivMinRepassHG, const ZDCModuleFloatArray &peak2ndDerivMinRepassLG)
unsigned int m_moduleMask
std::array< std::array< std::unique_ptr< TSpline >, 4 >, 2 > m_LBDepEcalibSplines
std::array< bool, 2 > m_fail
void enableTimeSigCut(bool AND, float sigCut, const std::string &TF1String, const std::array< std::array< std::vector< double >, 4 >, 2 > &parsHGArr, const std::array< std::array< std::vector< double >, 4 >, 2 > &parsLGArr)
std::array< std::array< float, 4 >, 2 > m_calibTime
void SetNLcalibParams(std::array< std::array< std::vector< float >, 3 >, 2 > &nlcalibParams)
void SetPeak2ndDerivMinTolerances(size_t tolerance)
std::array< std::array< float, 4 >, 2 > m_moduleAmpFractionLG
std::array< float, 2 > m_moduleSumErrSq
std::array< std::array< std::unique_ptr< TSpline >, 4 >, 2 > m_T0HGOffsetSplines
ZDCModuleFloatArray m_HGGains
std::array< float, 2 > m_moduleSum
std::array< std::vector< std::tuple< unsigned int, float, std::vector< float > > >, 2 > m_iterCalibCorr
std::array< float, 2 > m_NLcalibModuleSum
std::array< float, 2 > m_calibModuleSumErrSq
std::array< float, 2 > m_calibModuleSum
std::array< std::array< int, 4 >, 2 > m_delayedOrder
void SetADCOverUnderflowValues(const ZDCModuleFloatArray &HGOverflowADC, const ZDCModuleFloatArray &HGUnderflowADC, const ZDCModuleFloatArray &LGOverflowADC)
void enableDelayed(float deltaT, const ZDCModuleFloatArray &undelayedDelayedPedestalDiff)
ZDCDataAnalyzer(ZDCMsg::MessageFunctionPtr messageFunc_p, int nSample, float deltaTSample, size_t preSampleIdx, const std::string &fitFunction, const ZDCModuleIntArray &peak2ndDerivMinSamples, const ZDCModuleFloatArray &peak2ndDerivMinThresholdsHG, const ZDCModuleFloatArray &peak2ndDerivMinThresholdsLG, unsigned int LGMode=ZDCPulseAnalyzer::LGModeNormal)
void set2ndDerivStep(size_t step)
std::array< float, 2 > m_moduleSumBkgdFrac
bool getPulseAnalyzerGlobalPar(const std::string &key, T &value)
std::array< float, 2 > m_NLcalibModuleSumErrSq
ZDCModuleFloatArray m_currentT0OffsetsHG
void StartEvent(int lumiBlock)
ZDCJSONConfig::JSON JSON
static const ZDCJSONConfig::JSONParamList JSONConfigParams
void SetFitMinMaxAmpValues(const ZDCModuleFloatArray &minAmpHG, const ZDCModuleFloatArray &minAmpLG, const ZDCModuleFloatArray &maxAmpHG, const ZDCModuleFloatArray &maxAmpLG)
void SetTimingCorrParams(ZDCPulseAnalyzer::TimingCorrMode mode, float refADC, float refScale, const std::array< std::array< std::vector< float >, 4 >, 2 > &HGParamArr, const std::array< std::array< std::vector< float >, 4 >, 2 > &LGParamArr)
void SetNonlinCorrParams(float refADC, float refScale, const std::array< std::array< std::vector< float >, 4 >, 2 > &HGNonlinCorrParams, const std::array< std::array< std::vector< float >, 4 >, 2 > &LHGNonlinCorrParams)
ZDCModuleFloatArray m_currentT0OffsetsLG
std::array< std::array< unsigned int, 4 >, 2 > m_moduleStatus
std::map< std::string, JSONParamDescr > JSONParamList
bool LGOverflow() const
float GetAmpError() const
float GetAmplitude() const
float GetT0Corr() const
bool useLowGain() const
bool havePulse() const
bool armSumInclude() const
unsigned int GetStatusMask() const
float GetPreSampleAmp() const
static const ZDCJSONConfig::JSONParamList JSONConfigParams
float GetBkgdMaxFraction() const
@ Fatal
Definition ZDCMsg.h:23
@ Debug
Definition ZDCMsg.h:19
@ Verbose
Definition ZDCMsg.h:18
@ Error
Definition ZDCMsg.h:22
@ Info
Definition ZDCMsg.h:20
std::shared_ptr< MessageFunction > MessageFunctionPtr
Definition ZDCMsg.h:14
STL namespace.
Tell the compiler to optimize assuming that FP may trap.
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24