ATLAS Offline Software
Loading...
Searching...
No Matches
ZDCFitWrapper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <numeric>
6#include <memory>
8
9void ZDCFitWrapper::Initialize(float initialAmp, float initialT0, float ampMin, float ampMax)
10{
11 // Clear the errors on the TF1 because retaining the errors seems to affect
12 // the convergence of fits
13 //
14 unsigned int npar = GetWrapperTF1()->GetNpar();
15 std::vector<double> zeroVec(npar, 0.0);
16 GetWrapperTF1()->SetParErrors(&zeroVec[0]);
17
18 // If we adjusted the time range on the previous event, restore to default
19 //
22
23 m_adjTLimitsEvent = false;
24 m_tminAdjust = 0;
25 }
26
27 SetAmpMinMax(ampMin, ampMax);
28
29 DoInitialize(initialAmp, initialT0, ampMin, ampMax);
30}
31
32void ZDCFitWrapper::Initialize(float initialAmp, float initialT0, float ampMin, float ampMax, float fitTmin, float fitTmax, float fitTRef)
33{
34 // Clear the errors on the TF1 because retaining the errors seems to affect
35 // the convergence of fits
36 //
37 unsigned int npar = GetWrapperTF1()->GetNpar();
38 std::vector<double> zeroVec(npar, 0.0);
39 GetWrapperTF1()->SetParErrors(&zeroVec[0]);
40
41 m_adjTLimitsEvent = true;
42
43 m_tminAdjust = fitTRef; // Note: this is the time corresponding to the sample used for presample subtraction
44
45 m_tempTmin = std::max(m_t0Min, fitTmin);
46 m_tempTmax = std::min(m_t0Max, fitTmax);
47
48 SetAmpMinMax(ampMin, ampMax);
50
51 DoInitialize(initialAmp, initialT0, ampMin, ampMax);
52}
53
54ZDCFitExpFermiVariableTaus::ZDCFitExpFermiVariableTaus(const std::string& tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
55 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiVariableTaus" + tag).c_str(), ZDCFermiExpFit, tmin, tmax, 5)),
56 m_fixTau1(fixTau1), m_fixTau2(fixTau2), m_tau1(tau1), m_tau2(tau2)
57{
58 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
59
60 theTF1->SetParName(0, "Amp");
61 theTF1->SetParName(1, "T0");
62 theTF1->SetParName(2, "#tau_{1}");
63 theTF1->SetParName(3, "#tau_{2}");
64 theTF1->SetParName(4, "C");
65
66 // BAC, parameter 0 limits now is set in DoInitialize
67 theTF1->SetParLimits(1, tmin, tmax);
68 theTF1->SetParLimits(2, 3, 6);
69 theTF1->SetParLimits(3, 10, 40);
70
71 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
72 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
73}
74
75void ZDCFitExpFermiVariableTaus::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
76{
77 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
78
79 theTF1->SetParameter(0, initialAmp);
80 theTF1->SetParameter(1, initialT0);
81 theTF1->SetParameter(4, 0);
82
83 theTF1->SetParLimits(0, ampMin, ampMax);
84
85 if (!m_fixTau1) theTF1->SetParameter(2, m_tau1);
86 if (!m_fixTau2) theTF1->SetParameter(3, m_tau2);
87}
88
89void ZDCFitExpFermiVariableTaus::SetT0FitLimits(float t0Min, float t0Max)
90{
91 // Set the parameter limits accordingly on the TF1
92 //
93 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
94 theTF1->SetParLimits(1, t0Min, t0Max);
95}
96
98{
99 // We force the constant terms to zero
100 //
101 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
102
103 theTF1->FixParameter(4, 0);
104}
106{
107 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
108 theTF1->ReleaseParameter(4);
109}
110
111ZDCFitExpFermiVariableTausRun3::ZDCFitExpFermiVariableTausRun3(const std::string& tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
112 ZDCFitExpFermiVariableTaus(tag, tmin, tmax, fixTau1, fixTau2, tau1, tau2)
113{
114 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
115 theTF1->SetParLimits(2, 0.5, 3);
116 theTF1->SetParLimits(3, 4, 10);
117
118 // Since we st parameter ranges, we have to redo the fixing (or not) again here
119 //
120 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
121 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
122}
123
124
125ZDCFitExpFermiVariableTausLHCf::ZDCFitExpFermiVariableTausLHCf(const std::string& tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
126 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiVariableTausLHCf" + tag).c_str(), ZDCFermiExpFitRefl, tmin, tmax, 9)),
127 m_fixTau1(fixTau1), m_fixTau2(fixTau2), m_tau1(tau1), m_tau2(tau2)
128{
129 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
130
131 theTF1->SetParName(0, "Amp");
132 theTF1->SetParName(1, "T0");
133 theTF1->SetParName(2, "#tau_{1}");
134 theTF1->SetParName(3, "#tau_{2}");
135 theTF1->SetParName(4, "C");
136 theTF1->SetParName(5, "refdelay");
137 theTF1->SetParName(6, "reflAmpFrac");
138 theTF1->SetParName(7, "reflWidth");
139 theTF1->SetParName(8, "delta");
140
141 theTF1->SetParLimits(1, tmin, tmax);
142 theTF1->SetParLimits(4, -100, 100);
143 theTF1->SetParLimits(6, -1e-4, 0.35);
144
145 theTF1->FixParameter(5, 6.5);
146 theTF1->FixParameter(7, 1.5);
147 theTF1->FixParameter(8, 0.01);
148
149 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
150 else theTF1->SetParLimits(2, 1, 2);
151
152 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
153 else theTF1->SetParLimits(3, 3.5, 6);
154}
155
156void ZDCFitExpFermiVariableTausLHCf::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
157{
158 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
159
160 theTF1->SetParameter(0, initialAmp);
161
162 float t0 = initialT0;
163 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
164 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
165 theTF1->SetParameter(1, t0);
166
167 theTF1->SetParameter(1, initialT0);
168 theTF1->SetParameter(4, 0);
169 theTF1->SetParameter(6, 0.1);
170
171 theTF1->SetParLimits(0, ampMin, ampMax);
172
173 if (!m_fixTau1) theTF1->SetParameter(2, m_tau1);
174 if (!m_fixTau2) theTF1->SetParameter(3, m_tau2);
175
176 // Set the parameter errors which ROOT now uses <<<to set the initial step sizes>>>
177 //
178 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
179
180 theTF1->SetParError(0, ampStep);
181 theTF1->SetParError(1, 1.0);
182
183 if (!m_fixTau1) theTF1->SetParError(2, 0.05);
184 if (!m_fixTau2) theTF1->SetParError(3, 0.25);
185
186 theTF1->SetParError(4, 2);
187 theTF1->SetParError(5, 0.25);
188 theTF1->SetParError(6, 0.05);
189}
190
192{
193 // Set the parameter limits accordingly on the TF1
194 //
195 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
196 theTF1->SetParLimits(1, t0Min, t0Max);
197}
198
200{
201 // We force the constant and reflection terms to zero
202 //
203 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
204
205 theTF1->FixParameter(4, 0);
206 theTF1->FixParameter(6, 0);
207}
209{
210 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
211 theTF1->ReleaseParameter(4);
212 theTF1->SetParameter(4, 0);
213
214 theTF1->ReleaseParameter(6);
215 theTF1->SetParLimits(6, -1e-4, 0.35);
216 theTF1->SetParameter(6, 0.1);
217}
218
219ZDCFitExpFermiVariableTausInduct::ZDCFitExpFermiVariableTausInduct(const std::string& tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
220 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiVariableTausInduct" + tag).c_str(), ZDCFermiExpFitInduct, tmin, tmax, 10)),
221 m_fixTau1(fixTau1), m_fixTau2(fixTau2), m_tau1(tau1), m_tau2(tau2)
222{
223 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
224
225 theTF1->SetParName(0, "Amp");
226 theTF1->SetParName(1, "T0");
227 theTF1->SetParName(2, "#tau_{1}");
228 theTF1->SetParName(3, "#tau_{2}");
229 theTF1->SetParName(4, "C");
230 theTF1->SetParName(5, "period");
231 theTF1->SetParName(6, "IndA");
232 theTF1->SetParName(7, "IndB");
233 theTF1->SetParName(8, "tauI");
234 theTF1->SetParName(9, "delta");
235
236 theTF1->SetParLimits(1, tmin, tmax);
237 theTF1->SetParLimits(4, -50, 50);
238 theTF1->SetParLimits(5, 10, 50);
239 theTF1->SetParLimits(6, 0, 2);
240 theTF1->SetParLimits(7, 0, 2);
241 // theTF1->SetParLimits(8, 1, 6);
242 theTF1->FixParameter(8, 5.5);
243 theTF1->FixParameter(5, 16);
244 // theTF1->SetParLimits(9, 0, 0.05);
245
246
247 FixDelta(0.015);
248
249 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
250 else theTF1->SetParLimits(2, 0.5, 3);
251
252 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
253 else theTF1->SetParLimits(3, 3.5, 8);
254}
255
256void ZDCFitExpFermiVariableTausInduct::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
257{
258 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
259
260 theTF1->SetParameter(0, initialAmp);
261 theTF1->SetParLimits(0, ampMin, ampMax);
262
263 float t0 = initialT0;
264 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
265 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
266 theTF1->SetParameter(1, t0);
267
268 theTF1->SetParameter(6, 0.25);
269 theTF1->SetParameter(7, 0.8);
270 if (!m_fixDelta) theTF1->SetParameter(9, 0.);
271
272 if (!m_fixTau1) theTF1->SetParameter(2, m_tau1);
273 if (!m_fixTau2) theTF1->SetParameter(3, m_tau2);
274
275 // Set the parameter errors which ROOT now uses <<<to set the initial step sizes>>>
276 //
277 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
278
279 theTF1->SetParError(0, ampStep);
280 theTF1->SetParError(1, 1.0);
281
282 if (!m_fixTau1) theTF1->SetParError(2, 0.05);
283 if (!m_fixTau2) theTF1->SetParError(3, 0.25);
284
285 theTF1->SetParError(4, 1);
286 theTF1->SetParError(5, 5);
287 theTF1->SetParError(6, 0.1);
288 theTF1->SetParError(7, 0.1);
289}
290
292{
293 // Set the parameter limits accordingly on the TF1
294 //
295 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
296 theTF1->SetParLimits(1, t0Min, t0Max);
297}
298
300{
301 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
302 theTF1->FixParameter(6, 0.25);
303 theTF1->FixParameter(4, 0);
304 // theTF1->FixParameter(7, 0.1);
305}
306
308{
309 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
310 theTF1->ReleaseParameter(6);
311 theTF1->ReleaseParameter(4);
312 theTF1->SetParLimits(6, 0, 2);
313 theTF1->SetParLimits(4, -50, 50);
314
315}
316
317ZDCFitExpFermiFixedTaus::ZDCFitExpFermiFixedTaus(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
318 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiFixedTaus" + tag).c_str(), this, tmin, tmax, 3)),
319 m_tau1(tau1), m_tau2(tau2)
320{
321 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
322
323 // BAC, parameter 0 limits now is set in DoInitialize
324 theTF1->SetParLimits(1, tmin, tmax);
325
326 theTF1->SetParName(0, "Amp");
327 theTF1->SetParName(1, "T0");
328 theTF1->SetParName(2, "C");
329
330 // Now create the reference function that we use to evaluate ExpFermiFit more efficiently
331 //
332 std::string funcNameRefFunc = "ExpFermiFixedTausRefFunc" + tag;
333 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
334
335 m_expFermiFunc->SetParameter(0, 1);
336 m_expFermiFunc->SetParameter(1, 0);
337 m_expFermiFunc->SetParameter(2, m_tau1);
338 m_expFermiFunc->SetParameter(3, m_tau2);
339 m_expFermiFunc->SetParameter(4, 0);
340
341 m_norm = 1. / m_expFermiFunc->GetMaximum();
342 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
343}
344
345void ZDCFitExpFermiFixedTaus::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
346{
347 GetWrapperTF1()->SetParameter(0, initialAmp);
348 GetWrapperTF1()->SetParameter(1, initialT0);
349
350 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
351}
353{
354 // We force the constant tersm to zero
355 //
356 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
357
358 theTF1->FixParameter(2, 0);
359}
361{
362 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
363 theTF1->ReleaseParameter(2);
364}
365
366void ZDCFitExpFermiFixedTaus::SetT0FitLimits(float t0Min, float t0Max)
367{
368 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
369}
370
371ZDCFitExpFermiPrePulse::ZDCFitExpFermiPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
372 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 5)),
373 m_tau1(tau1), m_tau2(tau2)
374{
375 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
376 //
377 std::string funcNameRefFunc = "ExpFermiPrePulseRefFunc" + tag;
378
379 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
380
381 m_expFermiFunc->SetParameter(0, 1);
382 m_expFermiFunc->SetParameter(1, 0);
383 m_expFermiFunc->SetParameter(2, m_tau1);
384 m_expFermiFunc->SetParameter(3, m_tau2);
385 m_expFermiFunc->SetParameter(4, 0);
386
387 m_norm = 1. / m_expFermiFunc->GetMaximum();
388 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
389
390 // Now set up the actual TF1
391 //
392 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
393
394 // BAC, parameter 0 limits now is set in DoInitialize
395 theTF1->SetParLimits(1, tmin, tmax);
396 theTF1->SetParLimits(2, 1, 8196); // Increase the upper range to 2 times of ADC range to deal with large exponential tail case of pre-pulse.
397 theTF1->SetParLimits(3, -20, 10);
398
399 theTF1->SetParName(0, "Amp");
400 theTF1->SetParName(1, "T0");
401 theTF1->SetParName(2, "Amp_{pre}");
402 theTF1->SetParName(3, "T0_{pre}");
403 theTF1->SetParName(4, "C");
404}
405
407{
408 // We force the constant term and per-pulse amplitude to zero
409 //
410 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
411
412 theTF1->FixParameter(2, 0);
413 theTF1->FixParameter(4, 0);
414}
416{
417 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
418 theTF1->ReleaseParameter(2);
419 theTF1->ReleaseParameter(4);
420
421 theTF1->SetParLimits(2, 1, 8196); // Increase the upper range to 2 times of ADC range to deal with large exponential tail case of pre-pulse.
422}
423
425{
426 if (tmin > GetTMin()) {
427 m_preT0Min = tmin;
428 GetWrapperTF1()->ReleaseParameter(3);
429 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
430 }
431 else {
432 m_preT0Min = -25;
433 GetWrapperTF1()->SetParLimits(3, -25, tmax);
434 }
435 m_preT0Max = tmax;
436}
437
438void ZDCFitExpFermiPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
439{
440 GetWrapperTF1()->SetParameter(0, initialAmp);
441 GetWrapperTF1()->SetParameter(1, initialT0);
442 GetWrapperTF1()->SetParameter(2, 5);
443 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
444
445 // Set parameter errors for fit step size
446 //
447 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
448 GetWrapperTF1()->SetParError(0, ampStep);
449 GetWrapperTF1()->SetParError(1, 1.0);
450 GetWrapperTF1()->SetParError(2, 2);
451 GetWrapperTF1()->SetParError(3, 1.0);
452 GetWrapperTF1()->SetParError(4, 1.0);
453}
454
455void ZDCFitExpFermiPrePulse::SetT0FitLimits(float t0Min, float t0Max)
456{
457 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
458 theTF1->SetParLimits(1, t0Min, t0Max);
459}
460
461ZDCFitExpFermiPreExp::ZDCFitExpFermiPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
462 float defExpTau, float fixExpTau) :
463 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiPreExp" + tag).c_str(), this, tmin, tmax, 6), defExpTau, fixExpTau),
464 m_tau1(tau1), m_tau2(tau2)
465{
466 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
467 //
468 std::string funcNameRefFunc = "ExpFermiPreExpRefFunc" + tag;
469
470 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 8);
471
472 // The parameters for the FermiExp
473 //
474 m_expFermiFunc->SetParameter(0, 1);
475 m_expFermiFunc->SetParameter(1, 0);
476 m_expFermiFunc->SetParameter(2, m_tau1);
477 m_expFermiFunc->SetParameter(3, m_tau2);
478 m_expFermiFunc->SetParameter(4, 0);
479
480 m_norm = 1. / m_expFermiFunc->GetMaximum();
481 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
482
483 // Now set up the actual TF1
484 //
485 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
486 theTF1->SetParName(0, "Amp");
487 theTF1->SetParName(1, "T0");
488 theTF1->SetParName(2, "Amp_{pre}");
489 theTF1->SetParName(3, "tau_{pre}");
490 theTF1->SetParName(4, "tausqrt_{pre}");
491 theTF1->SetParName(5, "C");
492
493 theTF1->SetParLimits(1, tmin, tmax);
494 theTF1->SetParLimits(2, -1, 8196); // Increase the upper range to 2 times of ADC range to deal with large exponential tail case of pre-pulse.
495 theTF1->SetParLimits(3, 6, 30);
496 theTF1->SetParLimits(4, -0.2, 0.2);
497 theTF1->SetParLimits(5, -50, 50);
498}
499
501{
502 // We force the constant term and per-pulse amplitude to zero
503 //
504 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
505
506 theTF1->FixParameter(2, 0);
507 theTF1->FixParameter(3, getDefaultExpTau());
508 theTF1->FixParameter(5, 0);
509}
511{
512 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
513
514 theTF1->ReleaseParameter(2);
515 theTF1->SetParLimits(2, -1, 8196); // Increase the upper range to 2 times of ADC range to deal with large exponential tail case of pre-pulse.
516
517 theTF1->ReleaseParameter(3);
518 theTF1->SetParLimits(3, 6, 30);
519 theTF1->SetParameter(3, getDefaultExpTau());
520
521 theTF1->ReleaseParameter(5);
522 theTF1->SetParLimits(5, -50, 50);
523 theTF1->SetParameter(5, 0);
524}
525
526void ZDCFitExpFermiPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
527{
528 GetWrapperTF1()->SetParameter(0, initialAmp);
529 GetWrapperTF1()->SetParameter(1, initialT0);
530 GetWrapperTF1()->SetParameter(2, 0);
531 GetWrapperTF1()->SetParameter(3, getDefaultExpTau());
532 GetWrapperTF1()->SetParameter(4, 0.);
533 GetWrapperTF1()->SetParameter(5, 0);
534
535 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
536
537 // Set parameter errors for fit step size
538 //
539 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
540 GetWrapperTF1()->SetParError(0, ampStep);
541 GetWrapperTF1()->SetParError(1, 1.0);
542 GetWrapperTF1()->SetParError(2, ampStep/2);
543 GetWrapperTF1()->SetParError(3, 1.0);
544 GetWrapperTF1()->SetParError(4, 0.025);
545 GetWrapperTF1()->SetParError(5, 1.0);
546}
547
548void ZDCFitExpFermiPreExp::SetT0FitLimits(float t0Min, float t0Max)
549{
550 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
551 theTF1->SetParLimits(1, t0Min, t0Max);
552}
553
554ZDCFitExpFermiLHCfPreExp::ZDCFitExpFermiLHCfPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
555 float defExpTau, float fixExpTau) :
556 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiLHCfPreExp" + tag).c_str(), this, tmin, tmax, 8), defExpTau, fixExpTau),
557 m_tau1(tau1), m_tau2(tau2)
558{
559 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
560 //
561 std::string funcNameRefFunc = "ExpFermiLHCfPreExpRefFunc" + tag;
562
563 m_expFermiLHCfFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitRefl, tmin, tmax, 9);
564
565 // The parameters for the FermiExpRefl
566 //
567 m_expFermiLHCfFunc->SetParameter(0, 1);
568 m_expFermiLHCfFunc->SetParameter(1, 0);
569 m_expFermiLHCfFunc->SetParameter(2, m_tau1);
570 m_expFermiLHCfFunc->SetParameter(3, m_tau2);
571 m_expFermiLHCfFunc->SetParameter(4, 0);
572 m_expFermiLHCfFunc->SetParameter(5, 6.5);
573 m_expFermiLHCfFunc->SetParameter(6, 0.1);
574 m_expFermiLHCfFunc->SetParameter(7, 1.5);
575 m_expFermiLHCfFunc->SetParameter(8, 0.01);
576
577 // Now set up the actual TF1
578 //
579 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
580 theTF1->SetParName(0, "Amp");
581 theTF1->SetParName(1, "T0");
582 theTF1->SetParName(2, "Tau1");
583 theTF1->SetParName(3, "Tau2");
584 theTF1->SetParName(4, "Amp_{pre}");
585 theTF1->SetParName(5, "tau_{pre}");
586 theTF1->SetParName(6, "bsqrt_{pre}");
587 theTF1->SetParName(7, "ReflFrac");
588
589 theTF1->SetParLimits(1, tmin, tmax);
590 theTF1->SetParLimits(2, 1.0, 2);
591 theTF1->SetParLimits(3, 3.5, 5.5);
592 theTF1->SetParLimits(4, -1, 8196); // Increase the upper range to 2 times of ADC range to deal with large exponential tail case of pre-pulse.
593 theTF1->SetParLimits(5, 4, 12);
594 theTF1->SetParLimits(6, -0.001, 0.001);
595 theTF1->SetParLimits(7, -1.0e-4, 0.3);
596}
597
598void ZDCFitExpFermiLHCfPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
599{
600 GetWrapperTF1()->SetParameter(0, std::max(initialAmp, ampMin));
601
602 float t0 = initialT0;
603 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
604 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
605 GetWrapperTF1()->SetParameter(1, t0);
606
607 GetWrapperTF1()->SetParameter(2, std::max(m_tau1, (float) 1.01));
608 GetWrapperTF1()->SetParameter(3, m_tau2);
609 GetWrapperTF1()->SetParameter(4, 0.);
610 GetWrapperTF1()->SetParameter(5, std::max(getDefaultExpTau(), (float) 6.01));
611 GetWrapperTF1()->SetParameter(6, 0);
612 GetWrapperTF1()->SetParameter(7, 0.2);
613
614 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
615
616 // Set parameter errors for fit step size
617 //
618 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
619 GetWrapperTF1()->SetParError(0, ampStep);
620 GetWrapperTF1()->SetParError(1, 1.0);
621 GetWrapperTF1()->SetParError(2, 0.1);
622 GetWrapperTF1()->SetParError(3, 0.1);
623 GetWrapperTF1()->SetParError(4, 1.0);
624 GetWrapperTF1()->SetParError(5, 0.5);
625 GetWrapperTF1()->SetParError(6, 0.001);
626 GetWrapperTF1()->SetParError(7, 0.01);
627}
628
630{
631 // We force the constant term and per-pulse amplitude to zero
632 //
633 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
634
635 theTF1->FixParameter(5, std::max(getDefaultExpTau(), (float) 6.01));
636 theTF1->FixParameter(6, 0);
637 theTF1->FixParameter(7, 0.20);
638}
640{
641 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
642
643 theTF1->ReleaseParameter(5);
644 theTF1->SetParLimits(5, 6, 12);
645
646 theTF1->ReleaseParameter(6);
647 theTF1->SetParLimits(6, -0.001, 0.001);
648 GetWrapperTF1()->SetParameter(6, 0);
649
650 theTF1->ReleaseParameter(7);
651 theTF1->SetParLimits(7, -1.0e-4, 0.3);
652 GetWrapperTF1()->SetParameter(7, 0.2);
653
654}
655
656void ZDCFitExpFermiLHCfPreExp::SetT0FitLimits(float t0Min, float t0Max)
657{
658 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
659 theTF1->SetParLimits(1, t0Min, t0Max);
660}
661
662ZDCFitExpFermiLHCfPrePulse::ZDCFitExpFermiLHCfPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
663 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiLHCfPrePulse" + tag).c_str(), this, tmin, tmax, 7)),
664 m_tau1(tau1), m_tau2(tau2)
665{
666 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
667 //
668 std::string funcNameRefFunc = "ExpFermiLHCfPrePulseRefFunc" + tag;
669 std::string funcNamePreFunc = "ExpFermiLHCfPrePulsePreFunc" + tag;
670
671 m_expFermiLHCfFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitRefl, tmin, tmax, 9);
672 m_expFermiLHCfFunc->SetParameter(0, 1);
673 m_expFermiLHCfFunc->SetParameter(1, 0);
674 m_expFermiLHCfFunc->SetParameter(2, m_tau1);
675 m_expFermiLHCfFunc->SetParameter(3, m_tau2);
676 m_expFermiLHCfFunc->SetParameter(4, 0);
677 m_expFermiLHCfFunc->SetParameter(5, 6.5);
678 m_expFermiLHCfFunc->SetParameter(6, 0.2);
679 m_expFermiLHCfFunc->SetParameter(7, 1.5);
680 m_expFermiLHCfFunc->SetParameter(8, 0.01);
681
682 m_expFermiPreFunc = std::make_shared<TF1>(funcNamePreFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 9);
683
684 m_expFermiPreFunc->SetParameter(0, 1);
685 m_expFermiPreFunc->SetParameter(1, 0);
686 m_expFermiPreFunc->SetParameter(2, m_tau1);
687 m_expFermiPreFunc->SetParameter(3, m_tau2);
688 m_expFermiPreFunc->SetParameter(4, 0);
689 m_preNorm = 1. / m_expFermiPreFunc->GetMaximum();
690
691 // Now set up the actual TF1
692 //
693 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
694
695 // The actual paerameters we fit
696 //
697 theTF1->SetParName(0, "Amp");
698 theTF1->SetParName(1, "T0");
699 theTF1->SetParName(2, "tau1");
700 theTF1->SetParName(3, "tau2");
701 theTF1->SetParName(4, "Amp_{pre}");
702 theTF1->SetParName(5, "T0_{pre}");
703 theTF1->SetParName(6, "C");
704
705 // BAC, parameter 0 limits now is set in DoInitialize
706 theTF1->SetParLimits(1, tmin, tmax);
707 theTF1->SetParLimits(2, 1.0, 2);
708 theTF1->SetParLimits(3, 3.5, 5.5);
709 theTF1->SetParLimits(4, 1, 8196); // Increase the upper range to 2 times of ADC range to deal with large exponential tail case of pre-pulse.
710 theTF1->SetParLimits(5, -20, 10);
711 theTF1->SetParLimits(6, -50, 50);
712
713}
714
716{
717 // We force the constant term and per-pulse amplitude to zero
718 //
719 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
720
721 theTF1->FixParameter(4, 0);
722 theTF1->FixParameter(6, 0);
723}
725{
726 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
727 theTF1->ReleaseParameter(4);
728 theTF1->ReleaseParameter(6);
729
730 theTF1->SetParLimits(4, 1, 8196); // Increase the upper range to 2 times of ADC range to deal with large exponential tail case of pre-pulse.
731 theTF1->SetParLimits(6, -50, 50);
732}
733
735{
736 if (tmin > GetTMin()) {
737 m_preT0Min = tmin;
738 GetWrapperTF1()->ReleaseParameter(5);
739 GetWrapperTF1()->SetParLimits(5, tmin, tmax);
740 }
741 else {
742 m_preT0Min = -25;
743 GetWrapperTF1()->SetParLimits(5, -25, tmax);
744 }
745 m_preT0Max = tmax;
746}
747
748void ZDCFitExpFermiLHCfPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
749{
750 GetWrapperTF1()->SetParameter(0, initialAmp);
751 GetWrapperTF1()->SetParameter(1, initialT0);
752 GetWrapperTF1()->SetParameter(2, m_tau1);
753 GetWrapperTF1()->SetParameter(3, m_tau2);
754 GetWrapperTF1()->SetParameter(4, 5);
755 GetWrapperTF1()->SetParameter(5, -10);
756 GetWrapperTF1()->SetParameter(6, 0);
757
758 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
759 // Set parameter errors for fit step size
760 //
761 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
762 GetWrapperTF1()->SetParError(0, ampStep);
763 GetWrapperTF1()->SetParError(1, 1.0);
764 GetWrapperTF1()->SetParError(2, 0.05);
765 GetWrapperTF1()->SetParError(3, 1);
766 GetWrapperTF1()->SetParError(4, 5.0);
767 GetWrapperTF1()->SetParError(5, 1.0);
768 GetWrapperTF1()->SetParError(6, 2.0);
769}
770
771void ZDCFitExpFermiLHCfPrePulse::SetT0FitLimits(float t0Min, float t0Max)
772{
773 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
774 theTF1->SetParLimits(1, t0Min, t0Max);
775}
776
777ZDCFitExpFermiInductPreExp::ZDCFitExpFermiInductPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
778 float defExpTau, float fixExpTau) :
779 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiInductPreExp" + tag).c_str(), this, tmin, tmax, 8), defExpTau, fixExpTau),
780 m_tau1(tau1), m_tau2(tau2)
781{
782 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
783 //
784 std::string funcNameRefFunc = "ExpFermiInductPreExpRefFunc" + tag;
785
786 m_expFermiInductFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitInduct, tmin, tmax, 10);
787
788 // The parameters for the FermiExpInduct
789 //
790 m_expFermiInductFunc->SetParameter(0, 1);
791 m_expFermiInductFunc->SetParameter(1, 0);
792 m_expFermiInductFunc->SetParameter(2, m_tau1); // tau1 is fixed
793 m_expFermiInductFunc->SetParameter(3, m_tau2); // tau2 is fixed
794 m_expFermiInductFunc->SetParameter(4, 0); // the constant term will be handled directly not here
795 m_expFermiInductFunc->SetParameter(5, 16); // the period will be fixed
796 m_expFermiInductFunc->SetParameter(6, 0.25); // A will be varied as part of the fit
797 m_expFermiInductFunc->SetParameter(7, 0.5); // B will be varied as part of the fit
798 m_expFermiInductFunc->SetParameter(8, 5.5);
799 m_expFermiInductFunc->SetParameter(9, 0.015);
800
801 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
802
803 // Now set up the actual TF1
804 //
805 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
806 theTF1->SetParName(0, "Amp");
807 theTF1->SetParName(1, "T0");
808 theTF1->SetParName(2, "Amp_{pre}");
809 theTF1->SetParName(3, "tau_{pre}");
810 theTF1->SetParName(4, "bsqrt_{pre}");
811 theTF1->SetParName(5, "C");
812 theTF1->SetParName(6, "IndA");
813 theTF1->SetParName(7, "IndB");
814
815 theTF1->SetParLimits(1, tmin, tmax);
816 theTF1->SetParLimits(2, -1, 8196); // Increase the upper range to 2 times of ADC range to deal with large exponential tail case of pre-pulse.
817 theTF1->SetParLimits(3, 4, 12);
818 theTF1->SetParLimits(4, -0.001, 0.001);
819 theTF1->SetParLimits(6, 0.0, 1);
820 theTF1->SetParLimits(7, 0, 2);
821}
822
823void ZDCFitExpFermiInductPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
824{
825 GetWrapperTF1()->SetParameter(0, std::max(initialAmp, ampMin));
826
827 float t0 = initialT0;
828 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
829 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
830 GetWrapperTF1()->SetParameter(1, t0);
831
832 GetWrapperTF1()->SetParameter(2, 1);
833 GetWrapperTF1()->SetParameter(3, std::max(getDefaultExpTau(), (float) 6.01));
834 GetWrapperTF1()->SetParameter(6, 0.2);
835 GetWrapperTF1()->SetParameter(7, 0.5);
836
837 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
838
839 // Set parameter errors for fit step size
840 //
841 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
842 GetWrapperTF1()->SetParError(0, ampStep);
843 GetWrapperTF1()->SetParError(1, 1.0);
844 GetWrapperTF1()->SetParError(2, 5.0);
845 GetWrapperTF1()->SetParError(3, 0.5);
846 GetWrapperTF1()->SetParError(4, 0.01);
847 GetWrapperTF1()->SetParError(5, 1);
848 GetWrapperTF1()->SetParError(6, 0.05);
849 GetWrapperTF1()->SetParError(7, 0.05);
850}
851
858
859void ZDCFitExpFermiInductPreExp::SetT0FitLimits(float t0Min, float t0Max)
860{
861 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
862 theTF1->SetParLimits(1, t0Min, t0Max);
863}
864
865ZDCFitExpFermiInductPrePulse::ZDCFitExpFermiInductPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
866 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiInductPrePulse" + tag).c_str(), this, tmin, tmax, 7)),
867 m_tau1(tau1), m_tau2(tau2)
868{
869 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
870 //
871 std::string funcNameRefFunc = "ExpFermiInductPrePulseRefFunc" + tag;
872 std::string funcNamePreFunc = "ExpFermiInductPrePulsePreFunc" + tag;
873
874 m_expFermiInductFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitInduct, tmin, tmax, 9);
875 m_expFermiInductFunc->SetParameter(0, 1);
876 m_expFermiInductFunc->SetParameter(1, 0);
877 m_expFermiInductFunc->SetParameter(2, m_tau1);
878 m_expFermiInductFunc->SetParameter(3, m_tau2);
879 m_expFermiInductFunc->SetParameter(4, 0);
880 m_expFermiInductFunc->SetParameter(5, 16);
881 m_expFermiInductFunc->SetParameter(6, 0.25);
882 m_expFermiInductFunc->SetParameter(7, 0.15);
883 m_expFermiInductFunc->SetParameter(8, 5.5);
884 m_expFermiInductFunc->SetParameter(9, 0.015);
885
886 m_expFermiPreFunc = std::make_shared<TF1>(funcNamePreFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 9);
887
888 m_expFermiPreFunc->SetParameter(0, 1);
889 m_expFermiPreFunc->SetParameter(1, 0);
890 m_expFermiPreFunc->SetParameter(2, m_tau1);
891 m_expFermiPreFunc->SetParameter(3, m_tau2);
892 m_expFermiPreFunc->SetParameter(4, 0);
893 m_preNorm = 1. / m_expFermiPreFunc->GetMaximum();
894
895 // Now set up the actual TF1
896 //
897 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
898
899 // The actual paerameters we fit
900 //
901 theTF1->SetParName(0, "Amp");
902 theTF1->SetParName(1, "T0");
903 theTF1->SetParName(2, "Amp_{pre}");
904 theTF1->SetParName(3, "T0_{pre}");
905 theTF1->SetParName(4, "C");
906 theTF1->SetParName(5, "IndA");
907 theTF1->SetParName(6, "IndB");
908
909 // BAC, parameter 0 limits now is set in DoInitialize
910 theTF1->SetParLimits(1, tmin, tmax);
911 theTF1->SetParLimits(2, -50, 50);
912 theTF1->SetParLimits(3, 0, 1);
913 theTF1->SetParLimits(4, 0, 2);
914}
915
922
924{
925 if (tmin > GetTMin()) {
926 m_preT0Min = tmin;
927 GetWrapperTF1()->ReleaseParameter(3);
928 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
929 }
930 else {
931 m_preT0Min = -25;
932 GetWrapperTF1()->SetParLimits(3, -25, tmax);
933 }
934 m_preT0Max = tmax;
935}
936
937void ZDCFitExpFermiInductPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
938{
939 GetWrapperTF1()->SetParameter(0, initialAmp);
940 GetWrapperTF1()->SetParameter(1, initialT0);
941 GetWrapperTF1()->SetParameter(2, 5);
942 GetWrapperTF1()->SetParameter(3, -10);
943 GetWrapperTF1()->SetParameter(4, 0);
944 GetWrapperTF1()->SetParameter(5, 0.25);
945 GetWrapperTF1()->SetParameter(6, 0.5);
946
947 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
948 // Set parameter errors for fit step size
949 //
950 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
951 GetWrapperTF1()->SetParError(0, ampStep);
952 GetWrapperTF1()->SetParError(1, 1.0);
953 GetWrapperTF1()->SetParError(2, 0.05);
954 GetWrapperTF1()->SetParError(3, 1);
955 GetWrapperTF1()->SetParError(4, 5.0);
956 GetWrapperTF1()->SetParError(5, 0.1);
957 GetWrapperTF1()->SetParError(6, 0.1);
958}
959
961{
962 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
963 theTF1->SetParLimits(1, t0Min, t0Max);
964}
965
966
967// --------------------------------------------------------------------------------------------------------------------------------------------
968//
969ZDCFitExpFermiLinearFixedTaus::ZDCFitExpFermiLinearFixedTaus(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
970 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiFixedTaus" + tag).c_str(), this, tmin, tmax, 4)),
971 m_tau1(tau1), m_tau2(tau2)
972{
973 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
974
975 // BAC, parameter 0 limits now is set in DoInitialize
976 theTF1->SetParLimits(1, tmin, tmax);
977
978 theTF1->SetParName(0, "Amp");
979 theTF1->SetParName(1, "T0");
980 theTF1->SetParName(2, "s_{b}");
981 theTF1->SetParName(3, "c_{b}");
982
983 // Now create the reference function that we use to evaluate ExpFermiFit more efficiently
984 //
985 std::string funcNameRefFunc = "ExpFermiFixedTausRefFunc" + tag;
986
987 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
988
989 m_expFermiFunc->SetParameter(0, 1);
990 m_expFermiFunc->SetParameter(1, 0);
991 m_expFermiFunc->SetParameter(2, m_tau1);
992 m_expFermiFunc->SetParameter(3, m_tau2);
993 m_expFermiFunc->FixParameter(4, 0);
994
995 m_norm = 1. / m_expFermiFunc->GetMaximum();
996 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
997}
998
1000{
1001 // We force the linear terms to zero
1002 //
1003 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1004
1005 theTF1->FixParameter(2, 0);
1006 theTF1->FixParameter(3, 0);
1007}
1008
1010{
1011 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1012 theTF1->ReleaseParameter(2);
1013 theTF1->ReleaseParameter(3);
1014}
1015
1016void ZDCFitExpFermiLinearFixedTaus::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1017{
1018 float slope = std::abs(0.1 * initialAmp / initialT0);
1019 float intercept = std::abs(0.1 * initialAmp);
1020 GetWrapperTF1()->SetParLimits(2, -slope , slope );
1021 GetWrapperTF1()->SetParLimits(3, -intercept, intercept);
1022
1023 GetWrapperTF1()->SetParameter(0, initialAmp);
1024 GetWrapperTF1()->SetParameter(1, initialT0);
1025 GetWrapperTF1()->SetParameter(2, 0);
1026 GetWrapperTF1()->SetParameter(3, 0);
1027
1028 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1029
1030 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
1031
1032 GetWrapperTF1()->SetParError(0, ampStep);
1033 GetWrapperTF1()->SetParError(1, 1);
1034 GetWrapperTF1()->SetParError(2, 1);
1035 GetWrapperTF1()->SetParError(3, 0.5);
1036}
1037
1039{
1040 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1041 theTF1->SetParLimits(1, t0Min, t0Max);
1042}
1043
1044// --------------------------------------------------------------------------------------------------------------------------------------------
1045//
1046ZDCFitExpFermiLinearPrePulse::ZDCFitExpFermiLinearPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1047 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiLinearPrePulse" + tag).c_str(), this, tmin, tmax, 6)),
1048 m_tau1(tau1), m_tau2(tau2)
1049{
1050 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1051 //
1052 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
1053
1054 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
1055
1056 m_expFermiFunc->SetParameter(0, 1);
1057 m_expFermiFunc->SetParameter(1, 0);
1058 m_expFermiFunc->SetParameter(2, m_tau1);
1059 m_expFermiFunc->SetParameter(3, m_tau2);
1060 m_expFermiFunc->FixParameter(4, 0);
1061
1062 m_norm = 1. / m_expFermiFunc->GetMaximum();
1063 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1064
1065 // Now set up the actual TF1
1066 //
1067 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
1068
1069 theTF1->SetParName(0, "Amp");
1070 theTF1->SetParName(1, "T0");
1071 theTF1->SetParName(2, "Amp_{pre}");
1072 theTF1->SetParName(3, "T0_{pre}");
1073 theTF1->SetParName(4, "s_{b}");
1074 theTF1->SetParName(5, "c_{b}");
1075
1076 // BAC, parameter 0 limits now is set in DoInitialize
1077 theTF1->SetParLimits(1, tmin, tmax);
1078 theTF1->SetParLimits(2, 1, 4096); // Increase the upper range to 4 times of ADC range to deal with large exponential tail case of pre-pulse.
1079 theTF1->SetParLimits(3, -20, 10);
1080}
1081
1083{
1084 // We force the linear terms and prepulse terms to zero
1085 //
1086 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1087
1088 theTF1->FixParameter(4, 0);
1089 theTF1->FixParameter(5, 0);
1090}
1092{
1093 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1094
1095 theTF1->ReleaseParameter(4);
1096 theTF1->ReleaseParameter(5);
1097}
1098
1100{
1101 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1102}
1103
1104void ZDCFitExpFermiLinearPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1105{
1106 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
1107 float intercept = std::abs(0.5 * initialAmp);
1108 GetWrapperTF1()->SetParLimits(4, -slope , slope );
1109 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
1110
1111 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1112
1113 GetWrapperTF1()->SetParameter(0, initialAmp);
1114 GetWrapperTF1()->SetParameter(1, initialT0);
1115 GetWrapperTF1()->SetParameter(2, 5);
1116 GetWrapperTF1()->SetParameter(5, 0);
1117
1118 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
1119
1120 GetWrapperTF1()->SetParError(0, ampStep);
1121 GetWrapperTF1()->SetParError(1, 1.0);
1122 GetWrapperTF1()->SetParError(2, 1);
1123 GetWrapperTF1()->SetParError(3, 1);
1124 GetWrapperTF1()->SetParError(4, 0.1);
1125 GetWrapperTF1()->SetParError(5, 1);
1126}
1127
1129{
1130 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1131}
1132
1133
1134// --------------------------------------------------------------------------------------------------------------------------------------------
1135//
1136ZDCFitComplexPrePulse::ZDCFitComplexPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1137 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 7)),
1138 m_tau1(tau1), m_tau2(tau2)
1139{
1140 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1141 //
1142 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
1143
1144 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 4);
1145
1146 m_expFermiFunc->SetParameter(0, 1);
1147 m_expFermiFunc->SetParameter(1, 0);
1148 m_expFermiFunc->SetParameter(2, m_tau1);
1149 m_expFermiFunc->SetParameter(3, m_tau2);
1150
1151 m_norm = 1. / m_expFermiFunc->GetMaximum();
1152 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1153
1154 // Now set up the actual TF1
1155 //
1156 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1157
1158 // BAC, parameter 0 limits now is set in DoInitialize
1159 theTF1->SetParLimits(1, tmin, tmax);
1160 theTF1->SetParLimits(2, 0, 2048); // Pre-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1161 theTF1->SetParLimits(3, 0, 40);
1162 theTF1->SetParLimits(6, 0, 4096); // Increase the upper range to 4 times of ADC range to deal with large exponential tail case of pre-pulse.
1163
1164 theTF1->SetParName(0, "Amp");
1165 theTF1->SetParName(1, "T0");
1166 theTF1->SetParName(2, "Amp_{pre}");
1167 theTF1->SetParName(3, "T0_{pre}");
1168 theTF1->SetParName(4, "s_{b}");
1169 theTF1->SetParName(5, "c_{b}");
1170 theTF1->SetParName(6, "Amp_{exp}");
1171}
1172
1174{
1175 // We force the linear terms and prepulse terms to zero
1176 //
1177 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1178
1179 theTF1->FixParameter(2, 0);
1180 theTF1->FixParameter(4, 0);
1181 theTF1->FixParameter(5, 0);
1182}
1184{
1185 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1186 theTF1->ReleaseParameter(2);
1187 theTF1->ReleaseParameter(4);
1188 theTF1->ReleaseParameter(5);
1189}
1190
1192{
1193 if (tmin > GetTMin()) {
1194 GetWrapperTF1()->ReleaseParameter(3);
1195 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1196 }
1197 else {
1198 GetWrapperTF1()->SetParLimits(3, 0, tmax);
1199 }
1200}
1201
1202void ZDCFitComplexPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1203{
1204 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
1205 float intercept = std::abs(0.1 * initialAmp); // reduce from 0.25 to 0.1 fix some fail issue
1206 GetWrapperTF1()->SetParLimits(4, -slope , slope ); // if the lower limit is set to 0, there will be some fit fail issue...
1207 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
1208
1209 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1210
1211 GetWrapperTF1()->SetParameter(0, initialAmp);
1212 GetWrapperTF1()->SetParameter(1, initialT0);
1213 GetWrapperTF1()->SetParameter(2, 5);
1214 GetWrapperTF1()->SetParameter(3, 10);
1215 GetWrapperTF1()->SetParameter(4, 0);
1216 GetWrapperTF1()->SetParameter(5, 0);
1217 GetWrapperTF1()->SetParameter(6, 1);
1218}
1219
1220void ZDCFitComplexPrePulse::SetT0FitLimits(float t0Min, float t0Max)
1221{
1222 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1223}
1224
1225
1226
1227// --------------------------------------------------------------------------------------------------------------------------------------------
1228//
1229ZDCFitGeneralPulse::ZDCFitGeneralPulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1230 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 9)),
1231 m_tau1(tau1), m_tau2(tau2)
1232{
1233 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1234 //
1235 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
1236
1237 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 4);
1238
1239 m_expFermiFunc->SetParameter(0, 1);
1240 m_expFermiFunc->SetParameter(1, 0);
1241 m_expFermiFunc->SetParameter(2, m_tau1);
1242 m_expFermiFunc->SetParameter(3, m_tau2);
1243
1244 m_norm = 1. / m_expFermiFunc->GetMaximum();
1245 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1246
1247 // Now set up the actual TF1
1248 //
1249 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1250
1251 // BAC, parameter 0 limits now is set in DoInitialize
1252 theTF1->SetParLimits(1, tmin, tmax);
1253 theTF1->SetParLimits(2, 0, 2048); // Pre-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1254 theTF1->SetParLimits(3, 0, 40);
1255 theTF1->SetParLimits(6, 0, 4096); // Increase the upper range to 4 times of ADC range to deal with large exponential tail case of pre-pulse.
1256 theTF1->SetParLimits(7, 0, 2048); // Post-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1257 theTF1->SetParLimits(8, 100, 163);
1258
1259 theTF1->SetParName(0, "Amp");
1260 theTF1->SetParName(1, "T0");
1261 theTF1->SetParName(2, "Amp_{pre}");
1262 theTF1->SetParName(3, "T0_{pre}");
1263 theTF1->SetParName(4, "s_{b}");
1264 theTF1->SetParName(5, "c_{b}");
1265 theTF1->SetParName(6, "Amp_{exp}");
1266 theTF1->SetParName(7, "Amp_{post}");
1267 theTF1->SetParName(8, "T0_{post}");
1268}
1269
1271{
1272 // We force the linear terms and prepulse terms to zero
1273 //
1274 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1275
1276 theTF1->FixParameter(2, 0);
1277 theTF1->FixParameter(4, 0);
1278 theTF1->FixParameter(5, 0);
1279}
1281{
1282 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1283 theTF1->ReleaseParameter(2);
1284 theTF1->ReleaseParameter(4);
1285 theTF1->ReleaseParameter(5);
1286}
1287
1288void ZDCFitGeneralPulse::SetPrePulseT0Range(float tmin, float tmax)
1289{
1290 if (tmin > GetTMin()) {
1291 if (tmin < 0) tmin = 0;
1292 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1293 }
1294 else {
1295 GetWrapperTF1()->SetParLimits(3, 0, tmax);
1296 }
1297}
1298
1299void ZDCFitGeneralPulse::SetPostPulseT0Range(float tmin, float tmax, float initialPostT0)
1300{
1301 GetWrapperTF1()->SetParLimits(8, tmin, tmax);
1302 float iniPostT0 = initialPostT0;
1303 GetWrapperTF1()->SetParameter(8, iniPostT0);
1304}
1305
1306void ZDCFitGeneralPulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1307{
1308 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
1309 float intercept = std::abs(0.1 * initialAmp); // reduce from 0.25 to 0.1 fix some fail issue
1310 GetWrapperTF1()->SetParLimits(4, -slope , slope ); // if the lower limit is set to 0, there will be some fit fail issue...
1311 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
1312
1313 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1314
1315 GetWrapperTF1()->SetParameter(0, initialAmp);
1316 GetWrapperTF1()->SetParameter(1, initialT0);
1317 GetWrapperTF1()->SetParameter(4, 0);
1318 GetWrapperTF1()->SetParameter(5, 0);
1319 GetWrapperTF1()->SetParameter(7, 5);
1320}
1321
1322void ZDCFitGeneralPulse::SetT0FitLimits(float t0Min, float t0Max)
1323{
1324 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1325}
static Double_t t0
double ZDCFermiExpFit(const double *xvec, const double *pvec)
double ZDCFermiExpFitRefl(const double *xvec, const double *pvec)
double ZDCFermiExpFitInduct(const double *xvec, const double *pvec)
virtual void UnconstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void ConstrainFit() override
virtual void SetPrePulseT0Range(float tmin, float tmax) override
virtual void SetT0FitLimits(float tMin, float tMax) override
ZDCFitComplexPrePulse(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
std::shared_ptr< TF1 > m_expFermiFunc
ZDCFitExpFermiFixedTaus(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
virtual void ConstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
std::shared_ptr< TF1 > m_expFermiFunc
virtual void UnconstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void UnconstrainFit() override
std::shared_ptr< TF1 > m_expFermiInductFunc
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void ConstrainFit() override
ZDCFitExpFermiInductPreExp(const std::string &tag, float tmin, float tmax, float tau1, float tau2, float defExpTau, float fixExpTau)
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void UnconstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
ZDCFitExpFermiInductPrePulse(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
std::shared_ptr< TF1 > m_expFermiPreFunc
std::shared_ptr< TF1 > m_expFermiInductFunc
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void SetPrePulseT0Range(float tmin, float tmax) override
virtual void ConstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void ConstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
std::shared_ptr< TF1 > m_expFermiLHCfFunc
ZDCFitExpFermiLHCfPreExp(const std::string &tag, float tmin, float tmax, float tau1, float tau2, float defExpTau, float fixExpTau)
virtual void UnconstrainFit() override
std::shared_ptr< TF1 > m_expFermiPreFunc
std::shared_ptr< TF1 > m_expFermiLHCfFunc
virtual void ConstrainFit() override
virtual void SetPrePulseT0Range(float tmin, float tmax) override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
ZDCFitExpFermiLHCfPrePulse(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
virtual void UnconstrainFit() override
std::shared_ptr< TF1 > m_expFermiFunc
virtual void SetT0FitLimits(float tMin, float tMax) override
ZDCFitExpFermiLinearFixedTaus(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
virtual void ConstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void UnconstrainFit() override
virtual void ConstrainFit() override
virtual void SetPrePulseT0Range(float tmin, float tmax) override
virtual void UnconstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
ZDCFitExpFermiLinearPrePulse(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
std::shared_ptr< TF1 > m_expFermiFunc
virtual void SetT0FitLimits(float tMin, float tMax) override
std::shared_ptr< TF1 > m_expFermiFunc
virtual void UnconstrainFit() override
virtual void ConstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
ZDCFitExpFermiPreExp(const std::string &tag, float tmin, float tmax, float tau1, float tau2, float defExpTau, float fixExpTau)
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void ConstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
std::shared_ptr< TF1 > m_expFermiFunc
virtual void SetPrePulseT0Range(float tmin, float tmax) override
virtual void UnconstrainFit() override
ZDCFitExpFermiPrePulse(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
ZDCFitExpFermiVariableTausInduct(const std::string &tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2)
virtual void ConstrainFit() override
virtual void UnconstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void UnconstrainFit() override
ZDCFitExpFermiVariableTausLHCf(const std::string &tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2)
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void ConstrainFit() override
ZDCFitExpFermiVariableTausRun3(const std::string &tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2)
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void ConstrainFit() override
ZDCFitExpFermiVariableTaus(const std::string &tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2)
virtual void UnconstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void UnconstrainFit() override
virtual void ConstrainFit() override
std::shared_ptr< TF1 > m_expFermiFunc
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void SetPostPulseT0Range(float tmin, float tmax, float initialPostT0) override
ZDCFitGeneralPulse(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
virtual void SetPrePulseT0Range(float tmin, float tmax) override
void Initialize(float initialAmp, float initialT0, float ampMin, float ampMax)
float GetTMin() const
virtual std::shared_ptr< TF1 > GetWrapperTF1()
float GetT0Max() const
float GetT0Min() const
virtual void SetT0FitLimits(float tMin, float tMax)=0
ZDCFitWrapper(const std::shared_ptr< TF1 > &wrapperTF1)
void SetAmpMinMax(float minAmp, float maxAmp)
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)=0
float getDefaultExpTau() const
ZDCPreExpFitWrapper(std::shared_ptr< TF1 > wrapperTF1, float defaultExpTau, bool fixTau)
bool fixExpTau() const
ZDCPrePulseFitWrapper(std::shared_ptr< TF1 > wrapperTF1)
STL namespace.