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
6#include <numeric>
7#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, 9)),
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, "Acos");
232 theTF1->SetParName(7, "Bsin");
233 theTF1->SetParName(8, "delta");
234
235 theTF1->SetParLimits(1, tmin, tmax);
236 theTF1->SetParLimits(4, -50, 50);
237 theTF1->SetParLimits(5, 10, 50);
238 theTF1->SetParLimits(6, 0, 1);
239 theTF1->SetParLimits(7, -1, 1);
240
241 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
242 else theTF1->SetParLimits(2, 0.5, 3);
243
244 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
245 else theTF1->SetParLimits(3, 3.5, 8);
246}
247
248void ZDCFitExpFermiVariableTausInduct::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
249{
250 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
251
252 theTF1->SetParameter(0, initialAmp);
253 theTF1->SetParLimits(0, ampMin, ampMax);
254
255 float t0 = initialT0;
256 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
257 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
258 theTF1->SetParameter(1, t0);
259
260 theTF1->SetParameter(1, initialT0);
261 theTF1->FixParameter(5, 13.5);
262 theTF1->SetParameter(6, 0.5);
263 theTF1->SetParameter(7, 0.5);
264 theTF1->FixParameter(8, 0);
265
266 // theTF1->SetParLimits(0, ampMin, ampMax);
267
268 if (!m_fixTau1) theTF1->SetParameter(2, m_tau1);
269 if (!m_fixTau2) theTF1->SetParameter(3, m_tau2);
270
271 // Set the parameter errors which ROOT now uses <<<to set the initial step sizes>>>
272 //
273 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
274
275 theTF1->SetParError(0, ampStep);
276 theTF1->SetParError(1, 1.0);
277
278 if (!m_fixTau1) theTF1->SetParError(2, 0.05);
279 if (!m_fixTau2) theTF1->SetParError(3, 0.25);
280
281 theTF1->SetParError(4, 1);
282 theTF1->SetParError(5, 5);
283 theTF1->SetParError(6, 0.1);
284 theTF1->SetParError(7, 0.1);
285}
286
288{
289 // Set the parameter limits accordingly on the TF1
290 //
291 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
292 theTF1->SetParLimits(1, t0Min, t0Max);
293}
294
301
302ZDCFitExpFermiFixedTaus::ZDCFitExpFermiFixedTaus(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
303 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiFixedTaus" + tag).c_str(), this, tmin, tmax, 3)),
304 m_tau1(tau1), m_tau2(tau2)
305{
306 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
307
308 // BAC, parameter 0 limits now is set in DoInitialize
309 theTF1->SetParLimits(1, tmin, tmax);
310
311 theTF1->SetParName(0, "Amp");
312 theTF1->SetParName(1, "T0");
313 theTF1->SetParName(2, "C");
314
315 // Now create the reference function that we use to evaluate ExpFermiFit more efficiently
316 //
317 std::string funcNameRefFunc = "ExpFermiFixedTausRefFunc" + tag;
318 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
319
320 m_expFermiFunc->SetParameter(0, 1);
321 m_expFermiFunc->SetParameter(1, 0);
322 m_expFermiFunc->SetParameter(2, m_tau1);
323 m_expFermiFunc->SetParameter(3, m_tau2);
324 m_expFermiFunc->SetParameter(4, 0);
325
326 m_norm = 1. / m_expFermiFunc->GetMaximum();
327 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
328}
329
330void ZDCFitExpFermiFixedTaus::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
331{
332 GetWrapperTF1()->SetParameter(0, initialAmp);
333 GetWrapperTF1()->SetParameter(1, initialT0);
334
335 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
336}
338{
339 // We force the constant tersm to zero
340 //
341 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
342
343 theTF1->FixParameter(2, 0);
344}
346{
347 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
348 theTF1->ReleaseParameter(2);
349}
350
351void ZDCFitExpFermiFixedTaus::SetT0FitLimits(float t0Min, float t0Max)
352{
353 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
354}
355
356ZDCFitExpFermiPrePulse::ZDCFitExpFermiPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
357 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 5)),
358 m_tau1(tau1), m_tau2(tau2)
359{
360 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
361 //
362 std::string funcNameRefFunc = "ExpFermiPrePulseRefFunc" + tag;
363
364 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
365
366 m_expFermiFunc->SetParameter(0, 1);
367 m_expFermiFunc->SetParameter(1, 0);
368 m_expFermiFunc->SetParameter(2, m_tau1);
369 m_expFermiFunc->SetParameter(3, m_tau2);
370 m_expFermiFunc->SetParameter(4, 0);
371
372 m_norm = 1. / m_expFermiFunc->GetMaximum();
373 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
374
375 // Now set up the actual TF1
376 //
377 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
378
379 // BAC, parameter 0 limits now is set in DoInitialize
380 theTF1->SetParLimits(1, tmin, tmax);
381 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.
382 theTF1->SetParLimits(3, -20, 10);
383
384 theTF1->SetParName(0, "Amp");
385 theTF1->SetParName(1, "T0");
386 theTF1->SetParName(2, "Amp_{pre}");
387 theTF1->SetParName(3, "T0_{pre}");
388 theTF1->SetParName(4, "C");
389}
390
392{
393 // We force the constant term and per-pulse amplitude to zero
394 //
395 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
396
397 theTF1->FixParameter(2, 0);
398 theTF1->FixParameter(4, 0);
399}
401{
402 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
403 theTF1->ReleaseParameter(2);
404 theTF1->ReleaseParameter(4);
405
406 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.
407}
408
410{
411 if (tmin > GetTMin()) {
412 m_preT0Min = tmin;
413 GetWrapperTF1()->ReleaseParameter(3);
414 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
415 }
416 else {
417 m_preT0Min = -25;
418 GetWrapperTF1()->SetParLimits(3, -25, tmax);
419 }
420 m_preT0Max = tmax;
421}
422
423void ZDCFitExpFermiPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
424{
425 GetWrapperTF1()->SetParameter(0, initialAmp);
426 GetWrapperTF1()->SetParameter(1, initialT0);
427 GetWrapperTF1()->SetParameter(2, 5);
428 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
429
430 // Set parameter errors for fit step size
431 //
432 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
433 GetWrapperTF1()->SetParError(0, ampStep);
434 GetWrapperTF1()->SetParError(1, 1.0);
435 GetWrapperTF1()->SetParError(2, 2);
436 GetWrapperTF1()->SetParError(3, 1.0);
437 GetWrapperTF1()->SetParError(4, 1.0);
438}
439
440void ZDCFitExpFermiPrePulse::SetT0FitLimits(float t0Min, float t0Max)
441{
442 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
443 theTF1->SetParLimits(1, t0Min, t0Max);
444}
445
446ZDCFitExpFermiPreExp::ZDCFitExpFermiPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
447 float defExpTau, float fixExpTau) :
448 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiPreExp" + tag).c_str(), this, tmin, tmax, 6), defExpTau, fixExpTau),
449 m_tau1(tau1), m_tau2(tau2)
450{
451 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
452 //
453 std::string funcNameRefFunc = "ExpFermiPreExpRefFunc" + tag;
454
455 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 8);
456
457 // The parameters for the FermiExp
458 //
459 m_expFermiFunc->SetParameter(0, 1);
460 m_expFermiFunc->SetParameter(1, 0);
461 m_expFermiFunc->SetParameter(2, m_tau1);
462 m_expFermiFunc->SetParameter(3, m_tau2);
463 m_expFermiFunc->SetParameter(4, 0);
464
465 m_norm = 1. / m_expFermiFunc->GetMaximum();
466 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
467
468 // Now set up the actual TF1
469 //
470 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
471 theTF1->SetParName(0, "Amp");
472 theTF1->SetParName(1, "T0");
473 theTF1->SetParName(2, "Amp_{pre}");
474 theTF1->SetParName(3, "tau_{pre}");
475 theTF1->SetParName(4, "tausqrt_{pre}");
476 theTF1->SetParName(5, "C");
477
478 theTF1->SetParLimits(1, tmin, tmax);
479 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.
480 theTF1->SetParLimits(3, 6, 30);
481 theTF1->SetParLimits(4, -0.2, 0.2);
482 theTF1->SetParLimits(5, -50, 50);
483}
484
486{
487 // We force the constant term and per-pulse amplitude to zero
488 //
489 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
490
491 theTF1->FixParameter(2, 0);
492 theTF1->FixParameter(3, getDefaultExpTau());
493 theTF1->FixParameter(5, 0);
494}
496{
497 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
498
499 theTF1->ReleaseParameter(2);
500 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.
501
502 theTF1->ReleaseParameter(3);
503 theTF1->SetParLimits(3, 6, 30);
504 theTF1->SetParameter(3, getDefaultExpTau());
505
506 theTF1->ReleaseParameter(5);
507 theTF1->SetParLimits(5, -50, 50);
508 theTF1->SetParameter(5, 0);
509}
510
511void ZDCFitExpFermiPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
512{
513 GetWrapperTF1()->SetParameter(0, initialAmp);
514 GetWrapperTF1()->SetParameter(1, initialT0);
515 GetWrapperTF1()->SetParameter(2, 0);
516 GetWrapperTF1()->SetParameter(3, getDefaultExpTau());
517 GetWrapperTF1()->SetParameter(4, 0.);
518 GetWrapperTF1()->SetParameter(5, 0);
519
520 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
521
522 // Set parameter errors for fit step size
523 //
524 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
525 GetWrapperTF1()->SetParError(0, ampStep);
526 GetWrapperTF1()->SetParError(1, 1.0);
527 GetWrapperTF1()->SetParError(2, ampStep/2);
528 GetWrapperTF1()->SetParError(3, 1.0);
529 GetWrapperTF1()->SetParError(4, 0.025);
530 GetWrapperTF1()->SetParError(5, 1.0);
531}
532
533void ZDCFitExpFermiPreExp::SetT0FitLimits(float t0Min, float t0Max)
534{
535 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
536 theTF1->SetParLimits(1, t0Min, t0Max);
537}
538
539ZDCFitExpFermiLHCfPreExp::ZDCFitExpFermiLHCfPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
540 float defExpTau, float fixExpTau) :
541 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiLHCfPreExp" + tag).c_str(), this, tmin, tmax, 8), defExpTau, fixExpTau),
542 m_tau1(tau1), m_tau2(tau2)
543{
544 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
545 //
546 std::string funcNameRefFunc = "ExpFermiLHCfPreExpRefFunc" + tag;
547
548 m_expFermiLHCfFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitRefl, tmin, tmax, 9);
549
550 // The parameters for the FermiExpRefl
551 //
552 m_expFermiLHCfFunc->SetParameter(0, 1);
553 m_expFermiLHCfFunc->SetParameter(1, 0);
554 m_expFermiLHCfFunc->SetParameter(2, m_tau1);
555 m_expFermiLHCfFunc->SetParameter(3, m_tau2);
556 m_expFermiLHCfFunc->SetParameter(4, 0);
557 m_expFermiLHCfFunc->SetParameter(5, 6.5);
558 m_expFermiLHCfFunc->SetParameter(6, 0.1);
559 m_expFermiLHCfFunc->SetParameter(7, 1.5);
560 m_expFermiLHCfFunc->SetParameter(8, 0.01);
561
562 // Now set up the actual TF1
563 //
564 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
565 theTF1->SetParName(0, "Amp");
566 theTF1->SetParName(1, "T0");
567 theTF1->SetParName(2, "Tau1");
568 theTF1->SetParName(3, "Tau2");
569 theTF1->SetParName(4, "Amp_{pre}");
570 theTF1->SetParName(5, "tau_{pre}");
571 theTF1->SetParName(6, "bsqrt_{pre}");
572 theTF1->SetParName(7, "ReflFrac");
573
574 theTF1->SetParLimits(1, tmin, tmax);
575 theTF1->SetParLimits(2, 1.0, 2);
576 theTF1->SetParLimits(3, 3.5, 5.5);
577 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.
578 theTF1->SetParLimits(5, 4, 12);
579 theTF1->SetParLimits(6, -0.001, 0.001);
580 theTF1->SetParLimits(7, -1.0e-4, 0.3);
581}
582
583void ZDCFitExpFermiLHCfPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
584{
585 GetWrapperTF1()->SetParameter(0, std::max(initialAmp, ampMin));
586
587 float t0 = initialT0;
588 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
589 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
590 GetWrapperTF1()->SetParameter(1, t0);
591
592 GetWrapperTF1()->SetParameter(2, std::max(m_tau1, (float) 1.01));
593 GetWrapperTF1()->SetParameter(3, m_tau2);
594 GetWrapperTF1()->SetParameter(4, 0.);
595 GetWrapperTF1()->SetParameter(5, std::max(getDefaultExpTau(), (float) 6.01));
596 GetWrapperTF1()->SetParameter(6, 0);
597 GetWrapperTF1()->SetParameter(7, 0.2);
598
599 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
600
601 // Set parameter errors for fit step size
602 //
603 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
604 GetWrapperTF1()->SetParError(0, ampStep);
605 GetWrapperTF1()->SetParError(1, 1.0);
606 GetWrapperTF1()->SetParError(2, 0.1);
607 GetWrapperTF1()->SetParError(3, 0.1);
608 GetWrapperTF1()->SetParError(4, 1.0);
609 GetWrapperTF1()->SetParError(5, 0.5);
610 GetWrapperTF1()->SetParError(6, 0.001);
611 GetWrapperTF1()->SetParError(7, 0.01);
612}
613
615{
616 // We force the constant term and per-pulse amplitude to zero
617 //
618 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
619
620 theTF1->FixParameter(5, std::max(getDefaultExpTau(), (float) 6.01));
621 theTF1->FixParameter(6, 0);
622 theTF1->FixParameter(7, 0.20);
623}
625{
626 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
627
628 theTF1->ReleaseParameter(5);
629 theTF1->SetParLimits(5, 6, 12);
630
631 theTF1->ReleaseParameter(6);
632 theTF1->SetParLimits(6, -0.001, 0.001);
633 GetWrapperTF1()->SetParameter(6, 0);
634
635 theTF1->ReleaseParameter(7);
636 theTF1->SetParLimits(7, -1.0e-4, 0.3);
637 GetWrapperTF1()->SetParameter(7, 0.2);
638
639}
640
641void ZDCFitExpFermiLHCfPreExp::SetT0FitLimits(float t0Min, float t0Max)
642{
643 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
644 theTF1->SetParLimits(1, t0Min, t0Max);
645}
646
647ZDCFitExpFermiLHCfPrePulse::ZDCFitExpFermiLHCfPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
648 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiLHCfPrePulse" + tag).c_str(), this, tmin, tmax, 7)),
649 m_tau1(tau1), m_tau2(tau2)
650{
651 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
652 //
653 std::string funcNameRefFunc = "ExpFermiLHCfPrePulseRefFunc" + tag;
654 std::string funcNamePreFunc = "ExpFermiLHCfPrePulsePreFunc" + tag;
655
656 m_expFermiLHCfFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitRefl, tmin, tmax, 9);
657 m_expFermiLHCfFunc->SetParameter(0, 1);
658 m_expFermiLHCfFunc->SetParameter(1, 0);
659 m_expFermiLHCfFunc->SetParameter(2, m_tau1);
660 m_expFermiLHCfFunc->SetParameter(3, m_tau2);
661 m_expFermiLHCfFunc->SetParameter(4, 0);
662 m_expFermiLHCfFunc->SetParameter(5, 6.5);
663 m_expFermiLHCfFunc->SetParameter(6, 0.2);
664 m_expFermiLHCfFunc->SetParameter(7, 1.5);
665 m_expFermiLHCfFunc->SetParameter(8, 0.01);
666
667 m_expFermiPreFunc = std::make_shared<TF1>(funcNamePreFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 9);
668
669 m_expFermiPreFunc->SetParameter(0, 1);
670 m_expFermiPreFunc->SetParameter(1, 0);
671 m_expFermiPreFunc->SetParameter(2, m_tau1);
672 m_expFermiPreFunc->SetParameter(3, m_tau2);
673 m_expFermiPreFunc->SetParameter(4, 0);
674 m_preNorm = 1. / m_expFermiPreFunc->GetMaximum();
675
676 // Now set up the actual TF1
677 //
678 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
679
680 // The actual paerameters we fit
681 //
682 theTF1->SetParName(0, "Amp");
683 theTF1->SetParName(1, "T0");
684 theTF1->SetParName(2, "tau1");
685 theTF1->SetParName(3, "tau2");
686 theTF1->SetParName(4, "Amp_{pre}");
687 theTF1->SetParName(5, "T0_{pre}");
688 theTF1->SetParName(6, "C");
689
690 // BAC, parameter 0 limits now is set in DoInitialize
691 theTF1->SetParLimits(1, tmin, tmax);
692 theTF1->SetParLimits(2, 1.0, 2);
693 theTF1->SetParLimits(3, 3.5, 5.5);
694 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.
695 theTF1->SetParLimits(5, -20, 10);
696 theTF1->SetParLimits(6, -50, 50);
697
698}
699
701{
702 // We force the constant term and per-pulse amplitude to zero
703 //
704 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
705
706 theTF1->FixParameter(4, 0);
707 theTF1->FixParameter(6, 0);
708}
710{
711 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
712 theTF1->ReleaseParameter(4);
713 theTF1->ReleaseParameter(6);
714
715 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.
716 theTF1->SetParLimits(6, -50, 50);
717}
718
720{
721 if (tmin > GetTMin()) {
722 m_preT0Min = tmin;
723 GetWrapperTF1()->ReleaseParameter(5);
724 GetWrapperTF1()->SetParLimits(5, tmin, tmax);
725 }
726 else {
727 m_preT0Min = -25;
728 GetWrapperTF1()->SetParLimits(5, -25, tmax);
729 }
730 m_preT0Max = tmax;
731}
732
733void ZDCFitExpFermiLHCfPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
734{
735 GetWrapperTF1()->SetParameter(0, initialAmp);
736 GetWrapperTF1()->SetParameter(1, initialT0);
737 GetWrapperTF1()->SetParameter(2, m_tau1);
738 GetWrapperTF1()->SetParameter(3, m_tau2);
739 GetWrapperTF1()->SetParameter(4, 5);
740 GetWrapperTF1()->SetParameter(5, -10);
741 GetWrapperTF1()->SetParameter(6, 0);
742
743 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
744 // Set parameter errors for fit step size
745 //
746 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
747 GetWrapperTF1()->SetParError(0, ampStep);
748 GetWrapperTF1()->SetParError(1, 1.0);
749 GetWrapperTF1()->SetParError(2, 0.05);
750 GetWrapperTF1()->SetParError(3, 1);
751 GetWrapperTF1()->SetParError(4, 5.0);
752 GetWrapperTF1()->SetParError(5, 1.0);
753 GetWrapperTF1()->SetParError(6, 2.0);
754}
755
756void ZDCFitExpFermiLHCfPrePulse::SetT0FitLimits(float t0Min, float t0Max)
757{
758 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
759 theTF1->SetParLimits(1, t0Min, t0Max);
760}
761
762ZDCFitExpFermiInductPreExp::ZDCFitExpFermiInductPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
763 float defExpTau, float fixExpTau) :
764 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiInductPreExp" + tag).c_str(), this, tmin, tmax, 8), defExpTau, fixExpTau),
765 m_tau1(tau1), m_tau2(tau2)
766{
767 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
768 //
769 std::string funcNameRefFunc = "ExpFermiInductPreExpRefFunc" + tag;
770
771 m_expFermiInductFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitInduct, tmin, tmax, 9);
772
773 // The parameters for the FermiExpInduct
774 //
775 m_expFermiInductFunc->SetParameter(0, 1);
776 m_expFermiInductFunc->SetParameter(1, 0);
777 m_expFermiInductFunc->SetParameter(2, m_tau1); // tau1 is fixed
778 m_expFermiInductFunc->SetParameter(3, m_tau2); // tau2 is fixed
779 m_expFermiInductFunc->SetParameter(4, 0); // the constant term will be handled directly not here
780 m_expFermiInductFunc->SetParameter(5, 13.5); // the period will be fixed
781 m_expFermiInductFunc->SetParameter(6, 0.5); // A will be varied as part of the fit
782 m_expFermiInductFunc->SetParameter(7, 0.5); // B will be varied as part of the fit
783 m_expFermiInductFunc->SetParameter(8, 0.);
784
785 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
786
787 // Now set up the actual TF1
788 //
789 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
790 theTF1->SetParName(0, "Amp");
791 theTF1->SetParName(1, "T0");
792 theTF1->SetParName(2, "Amp_{pre}");
793 theTF1->SetParName(3, "tau_{pre}");
794 theTF1->SetParName(4, "bsqrt_{pre}");
795 theTF1->SetParName(5, "C");
796 theTF1->SetParName(6, "IndA");
797 theTF1->SetParName(7, "IndB");
798
799 theTF1->SetParLimits(1, tmin, tmax);
800 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.
801 theTF1->SetParLimits(3, 4, 12);
802 theTF1->SetParLimits(4, -0.001, 0.001);
803 theTF1->SetParLimits(6, 0.05, 1);
804 theTF1->SetParLimits(7, -1, 1);
805}
806
807void ZDCFitExpFermiInductPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
808{
809 GetWrapperTF1()->SetParameter(0, std::max(initialAmp, ampMin));
810
811 float t0 = initialT0;
812 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
813 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
814 GetWrapperTF1()->SetParameter(1, t0);
815
816 GetWrapperTF1()->SetParameter(2, 1);
817 GetWrapperTF1()->SetParameter(3, std::max(getDefaultExpTau(), (float) 6.01));
818 GetWrapperTF1()->SetParameter(6, 0.2);
819 GetWrapperTF1()->SetParameter(7, 0.2);
820
821 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
822
823 // Set parameter errors for fit step size
824 //
825 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
826 GetWrapperTF1()->SetParError(0, ampStep);
827 GetWrapperTF1()->SetParError(1, 1.0);
828 GetWrapperTF1()->SetParError(2, 5.0);
829 GetWrapperTF1()->SetParError(3, 0.5);
830 GetWrapperTF1()->SetParError(4, 0.01);
831 GetWrapperTF1()->SetParError(5, 1);
832 GetWrapperTF1()->SetParError(6, 0.05);
833 GetWrapperTF1()->SetParError(7, 0.05);
834}
835
842
843void ZDCFitExpFermiInductPreExp::SetT0FitLimits(float t0Min, float t0Max)
844{
845 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
846 theTF1->SetParLimits(1, t0Min, t0Max);
847}
848
849
850// --------------------------------------------------------------------------------------------------------------------------------------------
851//
852ZDCFitExpFermiLinearFixedTaus::ZDCFitExpFermiLinearFixedTaus(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
853 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiFixedTaus" + tag).c_str(), this, tmin, tmax, 4)),
854 m_tau1(tau1), m_tau2(tau2)
855{
856 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
857
858 // BAC, parameter 0 limits now is set in DoInitialize
859 theTF1->SetParLimits(1, tmin, tmax);
860
861 theTF1->SetParName(0, "Amp");
862 theTF1->SetParName(1, "T0");
863 theTF1->SetParName(2, "s_{b}");
864 theTF1->SetParName(3, "c_{b}");
865
866 // Now create the reference function that we use to evaluate ExpFermiFit more efficiently
867 //
868 std::string funcNameRefFunc = "ExpFermiFixedTausRefFunc" + tag;
869
870 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
871
872 m_expFermiFunc->SetParameter(0, 1);
873 m_expFermiFunc->SetParameter(1, 0);
874 m_expFermiFunc->SetParameter(2, m_tau1);
875 m_expFermiFunc->SetParameter(3, m_tau2);
876 m_expFermiFunc->FixParameter(4, 0);
877
878 m_norm = 1. / m_expFermiFunc->GetMaximum();
879 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
880}
881
883{
884 // We force the linear terms to zero
885 //
886 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
887
888 theTF1->FixParameter(2, 0);
889 theTF1->FixParameter(3, 0);
890}
891
893{
894 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
895 theTF1->ReleaseParameter(2);
896 theTF1->ReleaseParameter(3);
897}
898
899void ZDCFitExpFermiLinearFixedTaus::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
900{
901 float slope = std::abs(0.1 * initialAmp / initialT0);
902 float intercept = std::abs(0.1 * initialAmp);
903 GetWrapperTF1()->SetParLimits(2, -slope , slope );
904 GetWrapperTF1()->SetParLimits(3, -intercept, intercept);
905
906 GetWrapperTF1()->SetParameter(0, initialAmp);
907 GetWrapperTF1()->SetParameter(1, initialT0);
908 GetWrapperTF1()->SetParameter(2, 0);
909 GetWrapperTF1()->SetParameter(3, 0);
910
911 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
912
913 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
914
915 GetWrapperTF1()->SetParError(0, ampStep);
916 GetWrapperTF1()->SetParError(1, 1);
917 GetWrapperTF1()->SetParError(2, 1);
918 GetWrapperTF1()->SetParError(3, 0.5);
919}
920
922{
923 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
924 theTF1->SetParLimits(1, t0Min, t0Max);
925}
926
927// --------------------------------------------------------------------------------------------------------------------------------------------
928//
929ZDCFitExpFermiLinearPrePulse::ZDCFitExpFermiLinearPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
930 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiLinearPrePulse" + tag).c_str(), this, tmin, tmax, 6)),
931 m_tau1(tau1), m_tau2(tau2)
932{
933 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
934 //
935 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
936
937 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
938
939 m_expFermiFunc->SetParameter(0, 1);
940 m_expFermiFunc->SetParameter(1, 0);
941 m_expFermiFunc->SetParameter(2, m_tau1);
942 m_expFermiFunc->SetParameter(3, m_tau2);
943 m_expFermiFunc->FixParameter(4, 0);
944
945 m_norm = 1. / m_expFermiFunc->GetMaximum();
946 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
947
948 // Now set up the actual TF1
949 //
950 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
951
952 theTF1->SetParName(0, "Amp");
953 theTF1->SetParName(1, "T0");
954 theTF1->SetParName(2, "Amp_{pre}");
955 theTF1->SetParName(3, "T0_{pre}");
956 theTF1->SetParName(4, "s_{b}");
957 theTF1->SetParName(5, "c_{b}");
958
959 // BAC, parameter 0 limits now is set in DoInitialize
960 theTF1->SetParLimits(1, tmin, tmax);
961 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.
962 theTF1->SetParLimits(3, -20, 10);
963}
964
966{
967 // We force the linear terms and prepulse terms to zero
968 //
969 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
970
971 theTF1->FixParameter(4, 0);
972 theTF1->FixParameter(5, 0);
973}
975{
976 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
977
978 theTF1->ReleaseParameter(4);
979 theTF1->ReleaseParameter(5);
980}
981
983{
984 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
985}
986
987void ZDCFitExpFermiLinearPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
988{
989 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
990 float intercept = std::abs(0.5 * initialAmp);
991 GetWrapperTF1()->SetParLimits(4, -slope , slope );
992 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
993
994 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
995
996 GetWrapperTF1()->SetParameter(0, initialAmp);
997 GetWrapperTF1()->SetParameter(1, initialT0);
998 GetWrapperTF1()->SetParameter(2, 5);
999 GetWrapperTF1()->SetParameter(5, 0);
1000
1001 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
1002
1003 GetWrapperTF1()->SetParError(0, ampStep);
1004 GetWrapperTF1()->SetParError(1, 1.0);
1005 GetWrapperTF1()->SetParError(2, 1);
1006 GetWrapperTF1()->SetParError(3, 1);
1007 GetWrapperTF1()->SetParError(4, 0.1);
1008 GetWrapperTF1()->SetParError(5, 1);
1009}
1010
1012{
1013 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1014}
1015
1016
1017// --------------------------------------------------------------------------------------------------------------------------------------------
1018//
1019ZDCFitComplexPrePulse::ZDCFitComplexPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1020 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 7)),
1021 m_tau1(tau1), m_tau2(tau2)
1022{
1023 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1024 //
1025 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
1026
1027 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 4);
1028
1029 m_expFermiFunc->SetParameter(0, 1);
1030 m_expFermiFunc->SetParameter(1, 0);
1031 m_expFermiFunc->SetParameter(2, m_tau1);
1032 m_expFermiFunc->SetParameter(3, m_tau2);
1033
1034 m_norm = 1. / m_expFermiFunc->GetMaximum();
1035 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1036
1037 // Now set up the actual TF1
1038 //
1039 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1040
1041 // BAC, parameter 0 limits now is set in DoInitialize
1042 theTF1->SetParLimits(1, tmin, tmax);
1043 theTF1->SetParLimits(2, 0, 2048); // Pre-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1044 theTF1->SetParLimits(3, 0, 40);
1045 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.
1046
1047 theTF1->SetParName(0, "Amp");
1048 theTF1->SetParName(1, "T0");
1049 theTF1->SetParName(2, "Amp_{pre}");
1050 theTF1->SetParName(3, "T0_{pre}");
1051 theTF1->SetParName(4, "s_{b}");
1052 theTF1->SetParName(5, "c_{b}");
1053 theTF1->SetParName(6, "Amp_{exp}");
1054}
1055
1057{
1058 // We force the linear terms and prepulse terms to zero
1059 //
1060 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1061
1062 theTF1->FixParameter(2, 0);
1063 theTF1->FixParameter(4, 0);
1064 theTF1->FixParameter(5, 0);
1065}
1067{
1068 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1069 theTF1->ReleaseParameter(2);
1070 theTF1->ReleaseParameter(4);
1071 theTF1->ReleaseParameter(5);
1072}
1073
1075{
1076 if (tmin > GetTMin()) {
1077 GetWrapperTF1()->ReleaseParameter(3);
1078 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1079 }
1080 else {
1081 GetWrapperTF1()->SetParLimits(3, 0, tmax);
1082 }
1083}
1084
1085void ZDCFitComplexPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1086{
1087 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
1088 float intercept = std::abs(0.1 * initialAmp); // reduce from 0.25 to 0.1 fix some fail issue
1089 GetWrapperTF1()->SetParLimits(4, -slope , slope ); // if the lower limit is set to 0, there will be some fit fail issue...
1090 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
1091
1092 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1093
1094 GetWrapperTF1()->SetParameter(0, initialAmp);
1095 GetWrapperTF1()->SetParameter(1, initialT0);
1096 GetWrapperTF1()->SetParameter(2, 5);
1097 GetWrapperTF1()->SetParameter(3, 10);
1098 GetWrapperTF1()->SetParameter(4, 0);
1099 GetWrapperTF1()->SetParameter(5, 0);
1100 GetWrapperTF1()->SetParameter(6, 1);
1101}
1102
1103void ZDCFitComplexPrePulse::SetT0FitLimits(float t0Min, float t0Max)
1104{
1105 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1106}
1107
1108
1109
1110// --------------------------------------------------------------------------------------------------------------------------------------------
1111//
1112ZDCFitGeneralPulse::ZDCFitGeneralPulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1113 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 9)),
1114 m_tau1(tau1), m_tau2(tau2)
1115{
1116 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1117 //
1118 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
1119
1120 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 4);
1121
1122 m_expFermiFunc->SetParameter(0, 1);
1123 m_expFermiFunc->SetParameter(1, 0);
1124 m_expFermiFunc->SetParameter(2, m_tau1);
1125 m_expFermiFunc->SetParameter(3, m_tau2);
1126
1127 m_norm = 1. / m_expFermiFunc->GetMaximum();
1128 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1129
1130 // Now set up the actual TF1
1131 //
1132 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1133
1134 // BAC, parameter 0 limits now is set in DoInitialize
1135 theTF1->SetParLimits(1, tmin, tmax);
1136 theTF1->SetParLimits(2, 0, 2048); // Pre-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1137 theTF1->SetParLimits(3, 0, 40);
1138 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.
1139 theTF1->SetParLimits(7, 0, 2048); // Post-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1140 theTF1->SetParLimits(8, 100, 163);
1141
1142 theTF1->SetParName(0, "Amp");
1143 theTF1->SetParName(1, "T0");
1144 theTF1->SetParName(2, "Amp_{pre}");
1145 theTF1->SetParName(3, "T0_{pre}");
1146 theTF1->SetParName(4, "s_{b}");
1147 theTF1->SetParName(5, "c_{b}");
1148 theTF1->SetParName(6, "Amp_{exp}");
1149 theTF1->SetParName(7, "Amp_{post}");
1150 theTF1->SetParName(8, "T0_{post}");
1151}
1152
1154{
1155 // We force the linear terms and prepulse terms to zero
1156 //
1157 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1158
1159 theTF1->FixParameter(2, 0);
1160 theTF1->FixParameter(4, 0);
1161 theTF1->FixParameter(5, 0);
1162}
1164{
1165 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1166 theTF1->ReleaseParameter(2);
1167 theTF1->ReleaseParameter(4);
1168 theTF1->ReleaseParameter(5);
1169}
1170
1171void ZDCFitGeneralPulse::SetPrePulseT0Range(float tmin, float tmax)
1172{
1173 if (tmin > GetTMin()) {
1174 if (tmin < 0) tmin = 0;
1175 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1176 }
1177 else {
1178 GetWrapperTF1()->SetParLimits(3, 0, tmax);
1179 }
1180}
1181
1182void ZDCFitGeneralPulse::SetPostPulseT0Range(float tmin, float tmax, float initialPostT0)
1183{
1184 GetWrapperTF1()->SetParLimits(8, tmin, tmax);
1185 float iniPostT0 = initialPostT0;
1186 GetWrapperTF1()->SetParameter(8, iniPostT0);
1187}
1188
1189void ZDCFitGeneralPulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1190{
1191 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
1192 float intercept = std::abs(0.1 * initialAmp); // reduce from 0.25 to 0.1 fix some fail issue
1193 GetWrapperTF1()->SetParLimits(4, -slope , slope ); // if the lower limit is set to 0, there will be some fit fail issue...
1194 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
1195
1196 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1197
1198 GetWrapperTF1()->SetParameter(0, initialAmp);
1199 GetWrapperTF1()->SetParameter(1, initialT0);
1200 GetWrapperTF1()->SetParameter(4, 0);
1201 GetWrapperTF1()->SetParameter(5, 0);
1202 GetWrapperTF1()->SetParameter(7, 5);
1203}
1204
1205void ZDCFitGeneralPulse::SetT0FitLimits(float t0Min, float t0Max)
1206{
1207 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1208}
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 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.