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
9const std::map<std::string, std::vector<ZDCFitWrapper::FitParameter>> ZDCFitExpFermiVariableTausInduct::s_ConfigParamMap =
10 {
11 {"default",
12 {{{"A", 1000, false, 2, 5000, 50, false, 0}},
13 {{"T0", 40, false, 0, 100, 2, false, 0}},
14 {{"tau1", 0, false, 0.5, 3, 0.05, false, 0}}, // default value set via JSON
15 {{"tau2", 0, false, 3.5, 8, 0.25, false, 0}}, // default value set via JSON
16 {{"C", 0, false, -50, 50, 1, true, 0}},
17 {{"period", 13.5, true, 10, 30, 0, false, 0}},
18 {{"IndA", 0.2, false, -2, 2, 0.1, false, 0}},
19 {{"IndB", 0.2, false, -2, 2, 0.1, false, 0}},
20 {{"bI", 0.18, false, -1, 1, 0.025, false, 0}},
21 {{"delta", 0.015, true, 0, 0, 0, false, 0}}}
22 },
23 {"PbPb2026",
24 {{{"period", 16, true, 0, 0, 0, false, 0}},
25 {{"IndA", 0.25, false, 0, 2, 0.1, false, 0}},
26 {{"IndB", 0.8, false, 0, 2, 0.1, false, 0}},
27 {{"bI", 0.18, false, -1, 1, 0.025, false, 0}},
28 {{"delta", 0.015, true, 0, 0, 0, false, 0}},
29 {{"C", 0, false, -50, 50, 1, true, 0}},
30 }
31 },
32 {"PbPb2025",
33 {{{"tau2", 0, false, 5, 8, 0.25, false, 0}}, // adjust the range
34 {{"period", 13.5, true, 0, 0, 0, false, 0}},
35 {{"IndA", 0.1, false, -0.5, 2, 0.1, true, 0}},
36 {{"IndB", 0.2, false, -0.5, 2, 0.1, false, 0}},
37 {{"bI", -0.02, true, -0.5, 0.5, 0.025, true, -0.02}},
38 }
39 },
40 {"PbPb2025FreeInduct",
41 {{{"period", 13, false, 10, 30, 1, true, 13}},
42 {{"IndA", 0.25, false, -1, 2, 0.1, true, 0}},
43 {{"IndB", 0.8, false, -1, 2, 0.1, false, 0}},
44 {{"bI", -0.025, false, -0.5, 0.5, 0, false, 0}},
45 }
46 },
47 {"PbPb2024",
48 {{{"period", 16, true, 0, 0, 0, false, 0}},
49 {{"IndA", 0.25, false, 0, 2, 0.1, false, 0}},
50 {{"IndB", 0.8, false, 0, 2, 0.1, false, 0}},
51 {{"bI", 0.018, true, 0, -0.5, 0.5, false, 0}},
52 {{"delta", 0.015, true, 0, 0, 0, false, 0}},
53 }
54 },
55 };
56
57const std::map<std::string, std::vector<ZDCFitWrapper::FitParameter>> ZDCFitExpFermiInductPreExp::s_ConfigParamMap =
58 {
59 {"default",
60 {{{"A", 1000, false, 2, 5000, 50, false, 0}},
61 {{"T0", 40, false, 0, 100, 1, false, 0}},
62 {{"Aexp", 0, false, 0.5, 3, 0.05, false, 0}},
63 {{"tauexp", 0, false, 3.5, 8, 0.25, false, 0}},
64 {{"bsqrtexp", 0, false, -50, 50, 1, true, 0}},
65 {{"C", 0, false, -50, 50, 1, true, 0}},
66 {{"period", 13.5, true, 0, 0, 0, false, 0}},
67 {{"IndA", 0.2, false, -2, 2, 0.1, false, 0}},
68 {{"IndB", 0.2, false, -2, 2, 0.1, false, 0}},
69 {{"bI", -0.02, true, -0.5, 0.5, 0.025, true, -0.02}}
70 }
71 },
72 {"PbPb2025",
73 {{{"period", 13.5, true, 0, 0, 0, false, 0}},
74 {{"IndA", 0.1, false, -0.5, 2, 0.1, true, 0}},
75 {{"IndB", 0.2, false, -0.5, 2, 0.1, false, 0}},
76 {{"bI", -0.02, true, -0.5, 0.5, 0.025, true, -0.02}},
77 }
78 },
79 {"PbPb2025FreeInduct",
80 {{{"period", 13, false, 10, 30, 1, true, 13}},
81 {{"IndA", 0.25, false, -1, 2, 0.1, true, 0}},
82 {{"IndB", 0.8, false, -1, 2, 0.1, false, 0}},
83 {{"bI", -0.025, false, -0.5, 0.5, 0, false, 0}},
84 }
85 }
86 };
87
88const std::map<std::string, std::vector<ZDCFitWrapper::FitParameter>> ZDCFitExpFermiInductPrePulse::s_ConfigParamMap =
89 {
90 {"default",
91 {{{"A", 1000, false, 2, 5000, 50, false, 0}},
92 {{"T0", 40, false, 0, 100, 1, false, 0}},
93 {{"Apre", 0, false, 0.5, 3, 0.05, false, 0}},
94 {{"T0pre", 0, false, 3.5, 8, 0.25, false, 0}},
95 {{"C", 0, false, -50, 50, 1, true, 0}},
96 {{"period", 13.5, true, 0, 0, 0, false, 0}},
97 {{"IndA", 0.2, false, -2, 2, 0.1, false, 0}},
98 {{"IndB", 0.2, false, -2, 2, 0.1, false, 0}},
99 {{"bI", -0.02, true, -0.5, 0.5, 0.025, true, -0.02}}
100 }
101 },
102 {"PbPb2025",
103 {{{"period", 13.5, true, 0, 0, 0, false, 0}},
104 {{"IndA", 0.1, false, -0.5, 2, 0.1, true, 0}},
105 {{"IndB", 0.2, false, -0.5, 2, 0.1, false, 0}},
106 {{"bI", -0.02, true, -0.5, 0.5, 0.025, true, -0.02}},
107 }
108 },
109 {"PbPb2025FreeInduct",
110 {{{"period", 13, false, 10, 30, 1, true, 13}},
111 {{"IndA", 0.25, false, -1, 2, 0.1, true, 0}},
112 {{"IndB", 0.8, false, -1, 2, 0.1, false, 0}},
113 {{"bI", -0.025, false, -0.5, 0.5, 0, false, 0}},
114 }
115 }
116 };
117
119{
120 auto iter = std::find_if(m_parameterSet.begin(), m_parameterSet.end(),
121 [name](const FitParameter& parDesc){return parDesc.name() == name;});
122 if (iter == m_parameterSet.end()) throw std::logic_error("ZDCFitWrapper::GetParameterDescr: invalid parameter name: " + name );
123 return *iter;
124}
125
126void ZDCFitWrapper::LoadDefaultParameterSet(const std::vector<FitParameter>& parameterSet)
127{
128 // First step is to check consistency with number of parameters in TF1
129 //
130 if (int(parameterSet.size()) != m_wrapperTF1->GetNpar()) throw std::logic_error("ZDCFitWrapper::LoadDefaultParameterSet:: Incorrect number of parameters in default parameter set");
131
132 m_parameterSet = parameterSet;
133 m_haveParameterSet = true;
134
135 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
136
137 // Loop over passed descriptors
138 //
139 unsigned parIndex = 0;
140 for (const auto & parDescr : parameterSet) {
141 //
142 // Load the settings for this parameter in the TF1
143 //
144 std::string name = parDescr.name();
145 theTF1->SetParName(parIndex, name.c_str());
146
147 bool fixed = parDescr.fixed();
148
149 if (fixed) {
150 float fixedValue = parDescr.defaultValue();
151 theTF1->FixParameter(parIndex, fixedValue);
152 }
153 else {
154 float lowerLimit = parDescr.lowerLimit();
155 float upperLimit = parDescr.upperLimit();
156 theTF1->SetParLimits(parIndex, lowerLimit, upperLimit);
157 }
158
159 parIndex++;
160 }
161}
162
163void ZDCFitWrapper::OverrideParameterSet(const std::vector<FitParameter>& overParamSet)
164{
165 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
166
167 // Loop over the provided parameter descriptors
168 //
169 for (const auto & parDescr : overParamSet) {
170 std::string inputName = parDescr.name();
171
172 // Fit the parameter name in the current list
173 //
174 auto iter = std::find_if(m_parameterSet.begin(), m_parameterSet.end(),
175 [inputName](const FitParameter& parDesc){return parDesc.name() == inputName;});
176 if (iter == m_parameterSet.end()) throw std::logic_error("ZDCFitWrapper::OverrideParameterSet: invalid parameter name: " +inputName );
177
178 // Update the descriptor for this parameter
179 //
180 (*iter) = parDescr;
181
182 // Update the settings in the TF!
183 //
184 unsigned int parIndex = std::distance(m_parameterSet.begin(), iter);
185 bool fixed = parDescr.fixed();
186
187 if (fixed) {
188 float fixedValue = parDescr.defaultValue();
189 theTF1->FixParameter(parIndex, fixedValue);
190 }
191 else {
192 float lowerLimit = parDescr.lowerLimit();
193 float upperLimit = parDescr.upperLimit();
194 theTF1->SetParLimits(parIndex, lowerLimit, upperLimit);
195 }
196 }
197}
198
199void ZDCFitWrapper::Initialize(float initialAmp, float initialT0, float ampMin, float ampMax)
200{
201 // Clear the errors on the TF1 because retaining the errors seems to affect
202 // the convergence of fits
203 //
204 auto tf1_p = GetWrapperTF1();
205 unsigned int npar = tf1_p->GetNpar();
206 std::vector<double> zeroVec(npar, 0.0);
207 GetWrapperTF1()->SetParErrors(&zeroVec[0]);
208
209 // If we adjusted the time range on the previous event, restore to default
210 //
211 if (m_adjTLimitsEvent) {
213
214 m_adjTLimitsEvent = false;
215 m_tminAdjust = 0;
216 }
217
218 SetAmpMinMax(ampMin, ampMax);
219
220 //
221 // Do we have parameter sets?
222 //
223 if (m_haveParameterSet) {
224 for (unsigned int ipar = 0; ipar < m_parameterSet.size(); ipar++) {
225 //
226 // Yes, use parameter descriptors to initialize the TF1
227 //
228 const auto & fitparDescr = m_parameterSet[ipar];
229
230 if (!fitparDescr.fixed()) {
231 tf1_p->SetParameter(ipar, fitparDescr.defaultValue());
232 tf1_p->SetParError(ipar, fitparDescr.stepSize());
233 }
234 }
235
236 tf1_p->SetParameter(0, initialAmp);
237 tf1_p->SetParameter(1, initialT0);
238 }
239 else {
240 //
241 // No, perform the wrapper-implemented initialize
242 //
243 DoInitialize(initialAmp, initialT0, ampMin, ampMax);
244
245 // Clear the errors on the TF1 because retaining the errors seems to affect
246 // the convergence of fits
247 //
248 unsigned int npar = GetWrapperTF1()->GetNpar();
249 std::vector<double> zeroVec(npar, 0.0);
250 tf1_p->SetParErrors(&zeroVec[0]);
251
252 }
253}
254
255void ZDCFitWrapper::Initialize(float initialAmp, float initialT0, float ampMin, float ampMax, float fitTmin, float fitTmax, float fitTRef)
256{
257
258 // First do the nominal initializatioon
259 //
260 Initialize(initialAmp, initialT0, ampMin, ampMax);
261
262 // Now account for the modified time range
263 //
264 m_adjTLimitsEvent = true;
265
266 // Handle the specific limits on T0
267 //
268 m_tminAdjust = fitTRef; // Note: this is the time corresponding to the sample used for presample subtraction
269
270 m_tempTmin = std::max(m_t0Min, fitTmin);
271 m_tempTmax = std::min(m_t0Max, fitTmax);
272
273 SetAmpMinMax(ampMin, ampMax);
275}
276
278{
279 if (m_haveParameterSet) {
280 auto tf1_p = GetWrapperTF1();
281
282 for (unsigned int ipar = 2; ipar < m_parameterSet.size(); ipar++) {
283 const auto & fitparDescr = m_parameterSet[ipar];
284
285 if (!fitparDescr.fixed() && fitparDescr.constrainFixed()) {
286 tf1_p->FixParameter(ipar, fitparDescr.constrainValue());
287 }
288 }
289 }
290 else doConstrainFit();
291}
292
294{
295 if (m_haveParameterSet) {
296 auto tf1_p = GetWrapperTF1();
297
298 for (unsigned int ipar = 2; ipar < m_parameterSet.size(); ipar++) {
299 const auto & fitparDescr = m_parameterSet[ipar];
300
301 if (!fitparDescr.fixed() && fitparDescr.constrainFixed()) {
302 tf1_p->ReleaseParameter(ipar);
303 tf1_p->SetParameter(ipar, fitparDescr.defaultValue());
304
305 float lowerLimit = fitparDescr.lowerLimit();
306 float upperLimit = fitparDescr.upperLimit();
307 tf1_p->SetParLimits(ipar, lowerLimit, upperLimit);
308
309 tf1_p->SetParError(ipar, fitparDescr.stepSize());
310 }
311 }
312 }
313 else doUnconstrainFit();
314}
315
316ZDCFitExpFermiVariableTaus::ZDCFitExpFermiVariableTaus(const std::string& tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
317 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiVariableTaus" + tag).c_str(), ZDCFermiExpFit, tmin, tmax, 5)),
318 m_fixTau1(fixTau1), m_fixTau2(fixTau2), m_tau1(tau1), m_tau2(tau2)
319{
320 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
321
322 theTF1->SetParName(0, "Amp");
323 theTF1->SetParName(1, "T0");
324 theTF1->SetParName(2, "tau1");
325 theTF1->SetParName(3, "tau2");
326 theTF1->SetParName(4, "C");
327
328 // BAC, parameter 0 limits now is set in DoInitialize
329 theTF1->SetParLimits(1, tmin, tmax);
330 theTF1->SetParLimits(2, 3, 6);
331 theTF1->SetParLimits(3, 10, 40);
332
333 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
334 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
335}
336
337void ZDCFitExpFermiVariableTaus::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
338{
339 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
340
341 theTF1->SetParameter(0, initialAmp);
342 theTF1->SetParameter(1, initialT0);
343 theTF1->SetParameter(4, 0);
344
345 theTF1->SetParLimits(0, ampMin, ampMax);
346
347 if (!m_fixTau1) theTF1->SetParameter(2, m_tau1);
348 if (!m_fixTau2) theTF1->SetParameter(3, m_tau2);
349}
350
351void ZDCFitExpFermiVariableTaus::SetT0FitLimits(float t0Min, float t0Max)
352{
353 // Set the parameter limits accordingly on the TF1
354 //
355 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
356 theTF1->SetParLimits(1, t0Min, t0Max);
357}
358
360{
361 // We force the constant terms to zero
362 //
363 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
364
365 theTF1->FixParameter(4, 0);
366}
368{
369 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
370 theTF1->ReleaseParameter(4);
371}
372
373ZDCFitExpFermiVariableTausRun3::ZDCFitExpFermiVariableTausRun3(const std::string& tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
374 ZDCFitExpFermiVariableTaus(tag, tmin, tmax, fixTau1, fixTau2, tau1, tau2)
375{
376 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
377 theTF1->SetParLimits(2, 0.5, 3);
378 theTF1->SetParLimits(3, 4, 10);
379
380 // Since we st parameter ranges, we have to redo the fixing (or not) again here
381 //
382 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
383 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
384}
385
386
387ZDCFitExpFermiVariableTausLHCf::ZDCFitExpFermiVariableTausLHCf(const std::string& tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
388 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiVariableTausLHCf" + tag).c_str(), ZDCFermiExpFitRefl, tmin, tmax, 9)),
389 m_fixTau1(fixTau1), m_fixTau2(fixTau2), m_tau1(tau1), m_tau2(tau2)
390{
391 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
392
393 theTF1->SetParName(0, "Amp");
394 theTF1->SetParName(1, "T0");
395 theTF1->SetParName(2, "tau1");
396 theTF1->SetParName(3, "tau2");
397 theTF1->SetParName(4, "C");
398 theTF1->SetParName(5, "refdelay");
399 theTF1->SetParName(6, "reflAmpFrac");
400 theTF1->SetParName(7, "reflWidth");
401 theTF1->SetParName(8, "delta");
402
403 theTF1->SetParLimits(1, tmin, tmax);
404 theTF1->SetParLimits(4, -100, 100);
405 theTF1->SetParLimits(6, -1e-4, 0.35);
406
407 theTF1->FixParameter(5, 6.5);
408 theTF1->FixParameter(7, 1.5);
409 theTF1->FixParameter(8, 0.01);
410
411 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
412 else theTF1->SetParLimits(2, 1, 2);
413
414 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
415 else theTF1->SetParLimits(3, 3.5, 6);
416}
417
418void ZDCFitExpFermiVariableTausLHCf::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
419{
420 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
421
422 theTF1->SetParameter(0, initialAmp);
423
424 float t0 = initialT0;
425 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
426 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
427 theTF1->SetParameter(1, t0);
428
429 theTF1->SetParameter(1, initialT0);
430 theTF1->SetParameter(4, 0);
431 theTF1->SetParameter(6, 0.1);
432
433 theTF1->SetParLimits(0, ampMin, ampMax);
434
435 if (!m_fixTau1) theTF1->SetParameter(2, m_tau1);
436 if (!m_fixTau2) theTF1->SetParameter(3, m_tau2);
437
438 // Set the parameter errors which ROOT now uses <<<to set the initial step sizes>>>
439 //
440 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
441
442 theTF1->SetParError(0, ampStep);
443 theTF1->SetParError(1, 1.0);
444
445 if (!m_fixTau1) theTF1->SetParError(2, 0.05);
446 if (!m_fixTau2) theTF1->SetParError(3, 0.25);
447
448 theTF1->SetParError(4, 2);
449 theTF1->SetParError(5, 0.25);
450 theTF1->SetParError(6, 0.05);
451}
452
454{
455 // Set the parameter limits accordingly on the TF1
456 //
457 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
458 theTF1->SetParLimits(1, t0Min, t0Max);
459}
460
462{
463 // We force the constant and reflection terms to zero
464 //
465 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
466
467 theTF1->FixParameter(4, 0);
468 theTF1->FixParameter(6, 0);
469}
471{
472 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
473 theTF1->ReleaseParameter(4);
474 theTF1->SetParameter(4, 0);
475
476 theTF1->ReleaseParameter(6);
477 theTF1->SetParLimits(6, -1e-4, 0.35);
478 theTF1->SetParameter(6, 0.1);
479}
480
481ZDCFitExpFermiVariableTausInduct::ZDCFitExpFermiVariableTausInduct(const std::string& tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
482 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiVariableTausInduct" + tag).c_str(), ZDCFermiExpFitInduct, tmin, tmax, 10)),
483 m_fixTau1(fixTau1), m_fixTau2(fixTau2), m_tau1(tau1), m_tau2(tau2)
484{
485 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
486
487 theTF1->SetParName(0, "Amp");
488 theTF1->SetParName(1, "T0");
489 theTF1->SetParName(2, "tau1");
490 theTF1->SetParName(3, "tau2");
491 theTF1->SetParName(4, "C");
492 theTF1->SetParName(5, "period");
493 theTF1->SetParName(6, "IndA");
494 theTF1->SetParName(7, "IndB");
495 theTF1->SetParName(8, "tauI");
496 theTF1->SetParName(9, "delta");
497
498 theTF1->SetParLimits(1, tmin, tmax);
499 theTF1->SetParLimits(4, -50, 50);
500 theTF1->SetParLimits(5, 10, 50);
501 theTF1->SetParLimits(6, 0, 2);
502 theTF1->SetParLimits(7, 0, 2);
503 // theTF1->SetParLimits(8, 1, 6);
504 theTF1->FixParameter(8, 5.5);
505 theTF1->FixParameter(5, 16);
506 // theTF1->SetParLimits(9, 0, 0.05);
507
508
509 FixDelta(0.015);
510
511 if (m_fixTau1) theTF1->FixParameter(2, m_tau1);
512 else theTF1->SetParLimits(2, 0.5, 3);
513
514 if (m_fixTau2) theTF1->FixParameter(3, m_tau2);
515 else theTF1->SetParLimits(3, 3.5, 8);
516}
517
518
519ZDCFitExpFermiVariableTausInduct::ZDCFitExpFermiVariableTausInduct(const std::string& tag, const std::string & paramSet, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2) :
520 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiVariableTausInduct" + tag).c_str(), ZDCFermiExpFitInduct, tmin, tmax, 10),
521 s_ConfigParamMap.at("default"))
522{
523
524 auto iter = s_ConfigParamMap.find(paramSet);
525 if (iter == s_ConfigParamMap.end()) throw std::runtime_error("ZDCFitExpFermiVariableTausInduct:: invalid parameter set identifier: " + paramSet);
526
527 std::vector<ZDCFitWrapper::FitParameter> overRideParams = iter->second;
528
529 // Handle the JSON-based tau settings (this is ugly and temporary until we get the more general parameter overriding implemented)
530 //
531 auto tau1Iter = std::find_if(overRideParams.begin(), overRideParams.end(), [](const FitParameter& parDesc){return parDesc.name() == "tau1";});
532 if (tau1Iter != overRideParams.end()) {
533 if (fixTau1) tau1Iter->setFixed(tau1);
534 else tau1Iter->setDefaultValue(tau1);
535 }
536 else {
537 FitParameter tau1Descr = GetParameterDescr("tau1");
538 if (fixTau1) tau1Descr.setFixed(tau1);
539 else tau1Descr.setDefaultValue(tau1);
540 overRideParams.push_back(std::move(tau1Descr));
541 }
542
543 auto tau2Iter = std::find_if(overRideParams.begin(), overRideParams.end(), [](const FitParameter& parDesc){return parDesc.name() == "tau2";});
544 if (tau2Iter != overRideParams.end()) {
545 if (fixTau2) tau2Iter->setFixed(tau2);
546 else tau2Iter->setDefaultValue(tau2);
547 }
548 else {
549 FitParameter tau2Descr = GetParameterDescr("tau2");
550 if (fixTau2) tau2Descr.setFixed(tau2);
551 else tau2Descr.setDefaultValue(std::move(tau2));
552 overRideParams.push_back(tau2Descr);
553 }
554
555 OverrideParameterSet(overRideParams);
556}
557
558void ZDCFitExpFermiVariableTausInduct::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
559{
560 // Note: if we use parameter sets, this code never gets called as the base class executes the initialize
561 //
562 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
563
564 theTF1->SetParameter(0, initialAmp);
565 theTF1->SetParLimits(0, ampMin, ampMax);
566
567 float t0 = initialT0;
568 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
569 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
570 theTF1->SetParameter(1, t0);
571
572 theTF1->SetParameter(6, 0.25);
573 theTF1->SetParameter(7, 0.8);
574 if (!m_fixDelta) theTF1->SetParameter(9, 0.);
575
576 if (!m_fixTau1) theTF1->SetParameter(2, m_tau1);
577 if (!m_fixTau2) theTF1->SetParameter(3, m_tau2);
578
579 // Set the parameter errors which ROOT now uses <<<to set the initial step sizes>>>
580 //
581 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
582
583 theTF1->SetParError(0, ampStep);
584 theTF1->SetParError(1, 1.0);
585
586 if (!m_fixTau1) theTF1->SetParError(2, 0.05);
587 if (!m_fixTau2) theTF1->SetParError(3, 0.25);
588
589 theTF1->SetParError(4, 1);
590 theTF1->SetParError(5, 5);
591 theTF1->SetParError(6, 0.1);
592 theTF1->SetParError(7, 0.1);
593}
594
596{
597 // Set the parameter limits accordingly on the TF1
598 //
599 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
600 theTF1->SetParLimits(1, t0Min, t0Max);
601}
602
604{
605 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
606 theTF1->FixParameter(6, 0.25);
607 theTF1->FixParameter(4, 0);
608 // theTF1->FixParameter(7, 0.1);
609}
610
612{
613 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
614 theTF1->ReleaseParameter(6);
615 theTF1->ReleaseParameter(4);
616 theTF1->SetParLimits(6, 0, 2);
617 theTF1->SetParLimits(4, -50, 50);
618
619}
620
621ZDCFitExpFermiFixedTaus::ZDCFitExpFermiFixedTaus(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
622 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiFixedTaus" + tag).c_str(), this, tmin, tmax, 3)),
623 m_tau1(tau1), m_tau2(tau2)
624{
625 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
626
627 // BAC, parameter 0 limits now is set in DoInitialize
628 theTF1->SetParLimits(1, tmin, tmax);
629
630 theTF1->SetParName(0, "Amp");
631 theTF1->SetParName(1, "T0");
632 theTF1->SetParName(2, "C");
633
634 // Now create the reference function that we use to evaluate ExpFermiFit more efficiently
635 //
636 std::string funcNameRefFunc = "ExpFermiFixedTausRefFunc" + tag;
637 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
638
639 m_expFermiFunc->SetParameter(0, 1);
640 m_expFermiFunc->SetParameter(1, 0);
641 m_expFermiFunc->SetParameter(2, m_tau1);
642 m_expFermiFunc->SetParameter(3, m_tau2);
643 m_expFermiFunc->SetParameter(4, 0);
644
645 m_norm = 1. / m_expFermiFunc->GetMaximum();
646 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
647}
648
649void ZDCFitExpFermiFixedTaus::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
650{
651 GetWrapperTF1()->SetParameter(0, initialAmp);
652 GetWrapperTF1()->SetParameter(1, initialT0);
653
654 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
655}
657{
658 // We force the constant tersm to zero
659 //
660 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
661
662 theTF1->FixParameter(2, 0);
663}
665{
666 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
667 theTF1->ReleaseParameter(2);
668}
669
670void ZDCFitExpFermiFixedTaus::SetT0FitLimits(float t0Min, float t0Max)
671{
672 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
673}
674
675ZDCFitExpFermiPrePulse::ZDCFitExpFermiPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
676 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 5)),
677 m_tau1(tau1), m_tau2(tau2)
678{
679 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
680 //
681 std::string funcNameRefFunc = "ExpFermiPrePulseRefFunc" + tag;
682
683 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
684
685 m_expFermiFunc->SetParameter(0, 1);
686 m_expFermiFunc->SetParameter(1, 0);
687 m_expFermiFunc->SetParameter(2, m_tau1);
688 m_expFermiFunc->SetParameter(3, m_tau2);
689 m_expFermiFunc->SetParameter(4, 0);
690
691 m_norm = 1. / m_expFermiFunc->GetMaximum();
692 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
693
694 // Now set up the actual TF1
695 //
696 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
697
698 // BAC, parameter 0 limits now is set in DoInitialize
699 theTF1->SetParLimits(1, tmin, tmax);
700 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.
701 theTF1->SetParLimits(3, -20, 10);
702
703 theTF1->SetParName(0, "Amp");
704 theTF1->SetParName(1, "T0");
705 theTF1->SetParName(2, "Amp_{pre}");
706 theTF1->SetParName(3, "T0_{pre}");
707 theTF1->SetParName(4, "C");
708}
709
711{
712 // We force the constant term and per-pulse amplitude to zero
713 //
714 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
715
716 theTF1->FixParameter(2, 0);
717 theTF1->FixParameter(4, 0);
718}
720{
721 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
722 theTF1->ReleaseParameter(2);
723 theTF1->ReleaseParameter(4);
724
725 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.
726}
727
729{
730 if (tmin > GetTMin()) {
731 m_preT0Min = tmin;
732 GetWrapperTF1()->ReleaseParameter(3);
733 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
734 }
735 else {
736 m_preT0Min = -25;
737 GetWrapperTF1()->SetParLimits(3, -25, tmax);
738 }
739 m_preT0Max = tmax;
740}
741
742void ZDCFitExpFermiPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
743{
744 GetWrapperTF1()->SetParameter(0, initialAmp);
745 GetWrapperTF1()->SetParameter(1, initialT0);
746 GetWrapperTF1()->SetParameter(2, 5);
747 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
748
749 // Set parameter errors for fit step size
750 //
751 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
752 GetWrapperTF1()->SetParError(0, ampStep);
753 GetWrapperTF1()->SetParError(1, 1.0);
754 GetWrapperTF1()->SetParError(2, 2);
755 GetWrapperTF1()->SetParError(3, 1.0);
756 GetWrapperTF1()->SetParError(4, 1.0);
757}
758
759void ZDCFitExpFermiPrePulse::SetT0FitLimits(float t0Min, float t0Max)
760{
761 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
762 theTF1->SetParLimits(1, t0Min, t0Max);
763}
764
765ZDCFitExpFermiPreExp::ZDCFitExpFermiPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
766 float defExpTau, float fixExpTau) :
767 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiPreExp" + tag).c_str(), this, tmin, tmax, 6), defExpTau, fixExpTau),
768 m_tau1(tau1), m_tau2(tau2)
769{
770 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
771 //
772 std::string funcNameRefFunc = "ExpFermiPreExpRefFunc" + tag;
773
774 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 8);
775
776 // The parameters for the FermiExp
777 //
778 m_expFermiFunc->SetParameter(0, 1);
779 m_expFermiFunc->SetParameter(1, 0);
780 m_expFermiFunc->SetParameter(2, m_tau1);
781 m_expFermiFunc->SetParameter(3, m_tau2);
782 m_expFermiFunc->SetParameter(4, 0);
783
784 m_norm = 1. / m_expFermiFunc->GetMaximum();
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, "tausqrt_{pre}");
795 theTF1->SetParName(5, "C");
796
797 theTF1->SetParLimits(1, tmin, tmax);
798 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.
799 theTF1->SetParLimits(3, 6, 30);
800 theTF1->SetParLimits(4, -0.2, 0.2);
801 theTF1->SetParLimits(5, -50, 50);
802}
803
805{
806 // We force the constant term and per-pulse amplitude to zero
807 //
808 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
809
810 theTF1->FixParameter(2, 0);
811 theTF1->FixParameter(3, getDefaultExpTau());
812 theTF1->FixParameter(5, 0);
813}
815{
816 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
817
818 theTF1->ReleaseParameter(2);
819 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.
820
821 theTF1->ReleaseParameter(3);
822 theTF1->SetParLimits(3, 6, 30);
823 theTF1->SetParameter(3, getDefaultExpTau());
824
825 theTF1->ReleaseParameter(5);
826 theTF1->SetParLimits(5, -50, 50);
827 theTF1->SetParameter(5, 0);
828}
829
830void ZDCFitExpFermiPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
831{
832 GetWrapperTF1()->SetParameter(0, initialAmp);
833 GetWrapperTF1()->SetParameter(1, initialT0);
834 GetWrapperTF1()->SetParameter(2, 0);
835 GetWrapperTF1()->SetParameter(3, getDefaultExpTau());
836 GetWrapperTF1()->SetParameter(4, 0.);
837 GetWrapperTF1()->SetParameter(5, 0);
838
839 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
840
841 // Set parameter errors for fit step size
842 //
843 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
844 GetWrapperTF1()->SetParError(0, ampStep);
845 GetWrapperTF1()->SetParError(1, 1.0);
846 GetWrapperTF1()->SetParError(2, ampStep/2);
847 GetWrapperTF1()->SetParError(3, 1.0);
848 GetWrapperTF1()->SetParError(4, 0.025);
849 GetWrapperTF1()->SetParError(5, 1.0);
850}
851
852void ZDCFitExpFermiPreExp::SetT0FitLimits(float t0Min, float t0Max)
853{
854 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
855 theTF1->SetParLimits(1, t0Min, t0Max);
856}
857
858ZDCFitExpFermiLHCfPreExp::ZDCFitExpFermiLHCfPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
859 float defExpTau, float fixExpTau) :
860 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiLHCfPreExp" + tag).c_str(), this, tmin, tmax, 8), defExpTau, fixExpTau),
861 m_tau1(tau1), m_tau2(tau2)
862{
863 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
864 //
865 std::string funcNameRefFunc = "ExpFermiLHCfPreExpRefFunc" + tag;
866
867 m_expFermiLHCfFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitRefl, tmin, tmax, 9);
868
869 // The parameters for the FermiExpRefl
870 //
871 m_expFermiLHCfFunc->SetParameter(0, 1);
872 m_expFermiLHCfFunc->SetParameter(1, 0);
873 m_expFermiLHCfFunc->SetParameter(2, m_tau1);
874 m_expFermiLHCfFunc->SetParameter(3, m_tau2);
875 m_expFermiLHCfFunc->SetParameter(4, 0);
876 m_expFermiLHCfFunc->SetParameter(5, 6.5);
877 m_expFermiLHCfFunc->SetParameter(6, 0.1);
878 m_expFermiLHCfFunc->SetParameter(7, 1.5);
879 m_expFermiLHCfFunc->SetParameter(8, 0.01);
880
881 // Now set up the actual TF1
882 //
883 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
884 theTF1->SetParName(0, "Amp");
885 theTF1->SetParName(1, "T0");
886 theTF1->SetParName(2, "Tau1");
887 theTF1->SetParName(3, "Tau2");
888 theTF1->SetParName(4, "Amp_{pre}");
889 theTF1->SetParName(5, "tau_{pre}");
890 theTF1->SetParName(6, "bsqrt_{pre}");
891 theTF1->SetParName(7, "ReflFrac");
892
893 theTF1->SetParLimits(1, tmin, tmax);
894 theTF1->SetParLimits(2, 1.0, 2);
895 theTF1->SetParLimits(3, 3.5, 5.5);
896 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.
897 theTF1->SetParLimits(5, 4, 12);
898 theTF1->SetParLimits(6, -0.001, 0.001);
899 theTF1->SetParLimits(7, -1.0e-4, 0.3);
900}
901
902void ZDCFitExpFermiLHCfPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
903{
904 GetWrapperTF1()->SetParameter(0, std::max(initialAmp, ampMin));
905
906 float t0 = initialT0;
907 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
908 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
909 GetWrapperTF1()->SetParameter(1, t0);
910
911 GetWrapperTF1()->SetParameter(2, std::max(m_tau1, (float) 1.01));
912 GetWrapperTF1()->SetParameter(3, m_tau2);
913 GetWrapperTF1()->SetParameter(4, 0.);
914 GetWrapperTF1()->SetParameter(5, std::max(getDefaultExpTau(), (float) 6.01));
915 GetWrapperTF1()->SetParameter(6, 0);
916 GetWrapperTF1()->SetParameter(7, 0.2);
917
918 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
919
920 // Set parameter errors for fit step size
921 //
922 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
923 GetWrapperTF1()->SetParError(0, ampStep);
924 GetWrapperTF1()->SetParError(1, 1.0);
925 GetWrapperTF1()->SetParError(2, 0.1);
926 GetWrapperTF1()->SetParError(3, 0.1);
927 GetWrapperTF1()->SetParError(4, 1.0);
928 GetWrapperTF1()->SetParError(5, 0.5);
929 GetWrapperTF1()->SetParError(6, 0.001);
930 GetWrapperTF1()->SetParError(7, 0.01);
931}
932
934{
935 // We force the constant term and per-pulse amplitude to zero
936 //
937 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
938
939 theTF1->FixParameter(5, std::max(getDefaultExpTau(), (float) 6.01));
940 theTF1->FixParameter(6, 0);
941 theTF1->FixParameter(7, 0.20);
942}
944{
945 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
946
947 theTF1->ReleaseParameter(5);
948 theTF1->SetParLimits(5, 6, 12);
949
950 theTF1->ReleaseParameter(6);
951 theTF1->SetParLimits(6, -0.001, 0.001);
952 GetWrapperTF1()->SetParameter(6, 0);
953
954 theTF1->ReleaseParameter(7);
955 theTF1->SetParLimits(7, -1.0e-4, 0.3);
956 GetWrapperTF1()->SetParameter(7, 0.2);
957
958}
959
960void ZDCFitExpFermiLHCfPreExp::SetT0FitLimits(float t0Min, float t0Max)
961{
962 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
963 theTF1->SetParLimits(1, t0Min, t0Max);
964}
965
966ZDCFitExpFermiLHCfPrePulse::ZDCFitExpFermiLHCfPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
967 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiLHCfPrePulse" + tag).c_str(), this, tmin, tmax, 7)),
968 m_tau1(tau1), m_tau2(tau2)
969{
970 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
971 //
972 std::string funcNameRefFunc = "ExpFermiLHCfPrePulseRefFunc" + tag;
973 std::string funcNamePreFunc = "ExpFermiLHCfPrePulsePreFunc" + tag;
974
975 m_expFermiLHCfFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitRefl, tmin, tmax, 9);
976 m_expFermiLHCfFunc->SetParameter(0, 1);
977 m_expFermiLHCfFunc->SetParameter(1, 0);
978 m_expFermiLHCfFunc->SetParameter(2, m_tau1);
979 m_expFermiLHCfFunc->SetParameter(3, m_tau2);
980 m_expFermiLHCfFunc->SetParameter(4, 0);
981 m_expFermiLHCfFunc->SetParameter(5, 6.5);
982 m_expFermiLHCfFunc->SetParameter(6, 0.2);
983 m_expFermiLHCfFunc->SetParameter(7, 1.5);
984 m_expFermiLHCfFunc->SetParameter(8, 0.01);
985
986 m_expFermiPreFunc = std::make_shared<TF1>(funcNamePreFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 9);
987
988 m_expFermiPreFunc->SetParameter(0, 1);
989 m_expFermiPreFunc->SetParameter(1, 0);
990 m_expFermiPreFunc->SetParameter(2, m_tau1);
991 m_expFermiPreFunc->SetParameter(3, m_tau2);
992 m_expFermiPreFunc->SetParameter(4, 0);
993 m_preNorm = 1. / m_expFermiPreFunc->GetMaximum();
994
995 // Now set up the actual TF1
996 //
997 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
998
999 // The actual paerameters we fit
1000 //
1001 theTF1->SetParName(0, "Amp");
1002 theTF1->SetParName(1, "T0");
1003 theTF1->SetParName(2, "tau1");
1004 theTF1->SetParName(3, "tau2");
1005 theTF1->SetParName(4, "Amp_{pre}");
1006 theTF1->SetParName(5, "T0_{pre}");
1007 theTF1->SetParName(6, "C");
1008
1009 // BAC, parameter 0 limits now is set in DoInitialize
1010 theTF1->SetParLimits(1, tmin, tmax);
1011 theTF1->SetParLimits(2, 1.0, 2);
1012 theTF1->SetParLimits(3, 3.5, 5.5);
1013 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.
1014 theTF1->SetParLimits(5, -20, 10);
1015 theTF1->SetParLimits(6, -50, 50);
1016
1017}
1018
1020{
1021 // We force the constant term and per-pulse amplitude to zero
1022 //
1023 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1024
1025 theTF1->FixParameter(4, 0);
1026 theTF1->FixParameter(6, 0);
1027}
1029{
1030 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1031 theTF1->ReleaseParameter(4);
1032 theTF1->ReleaseParameter(6);
1033
1034 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.
1035 theTF1->SetParLimits(6, -50, 50);
1036}
1037
1039{
1040 if (tmin > GetTMin()) {
1041 m_preT0Min = tmin;
1042 GetWrapperTF1()->ReleaseParameter(5);
1043 GetWrapperTF1()->SetParLimits(5, tmin, tmax);
1044 }
1045 else {
1046 m_preT0Min = -25;
1047 GetWrapperTF1()->SetParLimits(5, -25, tmax);
1048 }
1049 m_preT0Max = tmax;
1050}
1051
1052void ZDCFitExpFermiLHCfPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1053{
1054 GetWrapperTF1()->SetParameter(0, initialAmp);
1055 GetWrapperTF1()->SetParameter(1, initialT0);
1056 GetWrapperTF1()->SetParameter(2, m_tau1);
1057 GetWrapperTF1()->SetParameter(3, m_tau2);
1058 GetWrapperTF1()->SetParameter(4, 5);
1059 GetWrapperTF1()->SetParameter(5, -10);
1060 GetWrapperTF1()->SetParameter(6, 0);
1061
1062 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1063 // Set parameter errors for fit step size
1064 //
1065 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
1066 GetWrapperTF1()->SetParError(0, ampStep);
1067 GetWrapperTF1()->SetParError(1, 1.0);
1068 GetWrapperTF1()->SetParError(2, 0.05);
1069 GetWrapperTF1()->SetParError(3, 1);
1070 GetWrapperTF1()->SetParError(4, 5.0);
1071 GetWrapperTF1()->SetParError(5, 1.0);
1072 GetWrapperTF1()->SetParError(6, 2.0);
1073}
1074
1076{
1077 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1078 theTF1->SetParLimits(1, t0Min, t0Max);
1079}
1080
1081ZDCFitExpFermiInductPreExp::ZDCFitExpFermiInductPreExp(const std::string& tag, float tmin, float tmax, float tau1, float tau2,
1082 float defExpTau, float fixExpTau) :
1083 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiInductPreExp" + tag).c_str(), this, tmin, tmax, 10), defExpTau, fixExpTau),
1084 m_tau1(tau1), m_tau2(tau2)
1085{
1086 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1087 //
1088 std::string funcNameRefFunc = "ExpFermiInductPreExpRefFunc" + tag;
1089
1090 m_expFermiInductFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitInduct, tmin, tmax, 10);
1091
1092 // The parameters for the FermiExpInduct
1093 //
1094 m_expFermiInductFunc->SetParameter(0, 1);
1095 m_expFermiInductFunc->SetParameter(1, 0);
1096 m_expFermiInductFunc->SetParameter(2, m_tau1); // tau1 is fixed
1097 m_expFermiInductFunc->SetParameter(3, m_tau2); // tau2 is fixed
1098 m_expFermiInductFunc->SetParameter(4, 0); // the constant term will be handled directly not here
1099 m_expFermiInductFunc->SetParameter(5, 14); // the period will be fixed
1100 m_expFermiInductFunc->SetParameter(6, 0.25); // A will be varied as part of the fit
1101 m_expFermiInductFunc->SetParameter(7, 0.5); // B will be varied as part of the fit
1102 m_expFermiInductFunc->SetParameter(8, 0.18);
1103 m_expFermiInductFunc->SetParameter(9, 0.015);
1104
1105 // Now set up the actual TF1
1106 //
1107 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
1108 theTF1->SetParName(0, "Amp");
1109 theTF1->SetParName(1, "T0");
1110 theTF1->SetParName(2, "Aexp");
1111 theTF1->SetParName(3, "tauexp");
1112 theTF1->SetParName(4, "bsqrtexp");
1113 theTF1->SetParName(5, "C");
1114 theTF1->SetParName(6, "Period");
1115 theTF1->SetParName(7, "IndA");
1116 theTF1->SetParName(8, "IndB");
1117 theTF1->SetParName(9, "bI");
1118
1119 theTF1->SetParLimits(1, tmin, tmax);
1120 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.
1121 theTF1->SetParLimits(3, 4, 12);
1122 theTF1->SetParLimits(4, -0.001, 0.001);
1123 theTF1->SetParLimits(5, -10, 10);
1124 theTF1->FixParameter(6, 13);
1125 theTF1->SetParLimits(7, -0.1, 2);
1126 theTF1->SetParLimits(8, -0.1, 2);
1127 theTF1->SetParLimits(9, -0.05, 0.5);
1128
1129}
1130
1131ZDCFitExpFermiInductPreExp::ZDCFitExpFermiInductPreExp(const std::string& tag, const std::string & paramSet, float tmin, float tmax, float tau1, float tau2) :
1132 ZDCPreExpFitWrapper(std::make_shared<TF1>(("ExpFermiInductPreExp" + tag).c_str(), this, tmin, tmax, 10), s_ConfigParamMap.at("default")),
1133 m_tau1(tau1), m_tau2(tau2)
1134{
1135 auto iter = s_ConfigParamMap.find(paramSet);
1136 if (iter == s_ConfigParamMap.end()) throw std::runtime_error("ZDCFitExpFermiVariableTausInduct:: invalid parameter set identifier: " + paramSet);
1137
1138 std::vector<ZDCFitWrapper::FitParameter> overRideParams = iter->second;
1139
1140 OverrideParameterSet(overRideParams);
1141
1142 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1143 //
1144 std::string funcNameRefFunc = "ExpFermiInductPreExpRefFunc" + tag;
1145
1146 m_expFermiInductFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitInduct, tmin, tmax, 10);
1147
1148 // The parameters for the FermiExpInduct
1149 //
1150 m_expFermiInductFunc->SetParameter(0, 1);
1151 m_expFermiInductFunc->SetParameter(1, 0);
1152 m_expFermiInductFunc->SetParameter(2, m_tau1); // tau1 is fixed
1153 m_expFermiInductFunc->SetParameter(3, m_tau2); // tau2 is fixed
1154 m_expFermiInductFunc->SetParameter(4, 0); // the constant term will be handled directly not here
1155 m_expFermiInductFunc->SetParameter(5, 14); // the period will be fixed
1156 m_expFermiInductFunc->SetParameter(6, 0.25); // A will be varied as part of the fit
1157 m_expFermiInductFunc->SetParameter(7, 0.5); // B will be varied as part of the fit
1158 m_expFermiInductFunc->SetParameter(8, 0.18);
1159 m_expFermiInductFunc->SetParameter(9, 0.015);
1160}
1161
1162void ZDCFitExpFermiInductPreExp::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1163{
1164 GetWrapperTF1()->SetParameter(0, std::max(initialAmp, ampMin));
1165
1166 float t0 = initialT0;
1167 if (t0 < GetT0Min()) t0 = GetT0Min()*1.1;
1168 if (t0 > GetT0Max()) t0 = GetT0Max()/1.1;
1169 GetWrapperTF1()->SetParameter(1, t0);
1170
1171 GetWrapperTF1()->SetParameter(2, 1);
1172 GetWrapperTF1()->SetParameter(3, std::max(getDefaultExpTau(), (float) 6.01));
1173 GetWrapperTF1()->SetParameter(6, 14);
1174 GetWrapperTF1()->SetParameter(7, 0.2);
1175 GetWrapperTF1()->SetParameter(8, 0.2);
1176 GetWrapperTF1()->SetParameter(9, 0.01);
1177
1178 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1179
1180 // Set parameter errors for fit step size
1181 //
1182 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
1183 GetWrapperTF1()->SetParError(0, ampStep);
1184 GetWrapperTF1()->SetParError(1, 1.0);
1185 GetWrapperTF1()->SetParError(2, 5.0);
1186 GetWrapperTF1()->SetParError(3, 0.5);
1187 GetWrapperTF1()->SetParError(4, 0.01);
1188 GetWrapperTF1()->SetParError(5, 1);
1189 GetWrapperTF1()->SetParError(6, 1);
1190 GetWrapperTF1()->SetParError(7, 0.05);
1191 GetWrapperTF1()->SetParError(8, 0.05);
1192 GetWrapperTF1()->SetParError(9, 0.01);
1193}
1194
1201
1203{
1204 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1205 theTF1->SetParLimits(1, t0Min, t0Max);
1206}
1207
1208ZDCFitExpFermiInductPrePulse::ZDCFitExpFermiInductPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1209 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiInductPrePulse" + tag).c_str(), this, tmin, tmax, 9)),
1210 m_tau1(tau1), m_tau2(tau2)
1211{
1212 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1213 //
1214 std::string funcNameRefFunc = "ExpFermiInductPrePulseRefFunc" + tag;
1215 std::string funcNamePreFunc = "ExpFermiInductPrePulsePreFunc" + tag;
1216
1217 m_expFermiInductFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitInduct, tmin, tmax, 9);
1218 m_expFermiInductFunc->SetParameter(0, 1);
1219 m_expFermiInductFunc->SetParameter(1, 0);
1220 m_expFermiInductFunc->SetParameter(2, m_tau1);
1221 m_expFermiInductFunc->SetParameter(3, m_tau2);
1222 m_expFermiInductFunc->SetParameter(4, 0);
1223 m_expFermiInductFunc->SetParameter(5, 14);
1224 m_expFermiInductFunc->SetParameter(6, 0.25);
1225 m_expFermiInductFunc->SetParameter(7, 0.15);
1226 m_expFermiInductFunc->SetParameter(8, 0.18);
1227 m_expFermiInductFunc->SetParameter(9, 0.015);
1228
1229 m_expFermiPreFunc = std::make_shared<TF1>(funcNamePreFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 5);
1230
1231 m_expFermiPreFunc->SetParameter(0, 1);
1232 m_expFermiPreFunc->SetParameter(1, 0);
1233 m_expFermiPreFunc->SetParameter(2, m_tau1);
1234 m_expFermiPreFunc->SetParameter(3, m_tau2);
1235 m_expFermiPreFunc->SetParameter(4, 0);
1236 m_preNorm = 1. / m_expFermiPreFunc->GetMaximum();
1237
1238 // Now set up the actual TF1
1239 //
1240 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
1241
1242 // The actual paerameters we fit
1243 //
1244 theTF1->SetParName(0, "Amp");
1245 theTF1->SetParName(1, "T0");
1246 theTF1->SetParName(2, "Apre");
1247 theTF1->SetParName(3, "T0pre");
1248 theTF1->SetParName(4, "C");
1249 theTF1->SetParName(5, "Period");
1250 theTF1->SetParName(6, "IndA");
1251 theTF1->SetParName(7, "IndB");
1252 theTF1->SetParName(8, "bI");
1253
1254 // BAC, parameter 0 limits now is set in DoInitialize
1255 theTF1->SetParLimits(1, tmin, tmax);
1256 theTF1->SetParLimits(2, 0, 5000);
1257 theTF1->SetParLimits(3, 0, 30);
1258 theTF1->SetParLimits(4, 0, 2);
1259 theTF1->SetParLimits(3, 4, 12);
1260 theTF1->SetParLimits(4, -50, 50);
1261 theTF1->SetParLimits(5, 10, 20);
1262 theTF1->SetParLimits(6, -0.1, 1);
1263 theTF1->SetParLimits(7, -0.1, 1);
1264 theTF1->SetParLimits(9, -0.2, 0.2);
1265
1266 GetWrapperTF1()->FixParameter(5, 14);
1267 GetWrapperTF1()->FixParameter(8, 0.02);
1268}
1269
1270ZDCFitExpFermiInductPrePulse::ZDCFitExpFermiInductPrePulse(const std::string& tag, const std::string & paramSet, float tmin, float tmax, float tau1, float tau2) :
1271 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiInductPrePulse" + tag).c_str(), this, tmin, tmax, 9), s_ConfigParamMap.at("default")),
1272 m_tau1(tau1), m_tau2(tau2)
1273{
1274 auto iter = s_ConfigParamMap.find(paramSet);
1275 if (iter == s_ConfigParamMap.end()) throw std::runtime_error("ZDCFitExpFermiVariableTausInduct:: invalid parameter set identifier: " + paramSet);
1276
1277 std::vector<ZDCFitWrapper::FitParameter> overRideParams = iter->second;
1278
1279 OverrideParameterSet(overRideParams);
1280
1281 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1282 //
1283 std::string funcNameRefFunc = "ExpFermiInductPrePulseRefFunc" + tag;
1284 std::string funcNamePreFunc = "ExpFermiInductPrePulsePreFunc" + tag;
1285
1286 m_expFermiPreFunc = std::make_shared<TF1>(funcNamePreFunc.c_str(), ZDCFermiExpFit, tmin, tmax, 5);
1287
1288 m_expFermiPreFunc->SetParameter(0, 1);
1289 m_expFermiPreFunc->SetParameter(1, 0);
1290 m_expFermiPreFunc->SetParameter(2, m_tau1);
1291 m_expFermiPreFunc->SetParameter(3, m_tau2);
1292 m_expFermiPreFunc->SetParameter(4, 0);
1293
1294 // Make the base function that we use
1295 //
1296 m_expFermiInductFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFitInduct, tmin, tmax, 9);
1297 m_expFermiInductFunc->SetParameter(0, 1);
1298 m_expFermiInductFunc->SetParameter(1, 0);
1299 m_expFermiInductFunc->SetParameter(2, m_tau1);
1300 m_expFermiInductFunc->SetParameter(3, m_tau2);
1301 m_expFermiInductFunc->SetParameter(4, 0);
1302 m_expFermiInductFunc->SetParameter(5, 14);
1303 m_expFermiInductFunc->SetParameter(6, 0.25);
1304 m_expFermiInductFunc->SetParameter(7, 0.15);
1305 m_expFermiInductFunc->SetParameter(8, 0.18);
1306 m_expFermiInductFunc->SetParameter(9, 0.015);
1307
1308}
1309
1311{
1312 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1313 theTF1->FixParameter(4, 0);
1314 theTF1->FixParameter(5, 0);
1315 theTF1->FixParameter(7, 0);
1316}
1318{
1319 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1320 theTF1->ReleaseParameter(5);
1321 theTF1->ReleaseParameter(7);
1322 theTF1->SetParLimits(4, -0.001, 0.001);
1323 theTF1->SetParLimits(5, -10, 10);
1324 theTF1->SetParLimits(7, -0.1, 2);
1325}
1326
1328{
1329 if (tmin > GetTMin()) {
1330 m_preT0Min = tmin;
1331 GetWrapperTF1()->ReleaseParameter(3);
1332 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1333 }
1334 else {
1335 m_preT0Min = -25;
1336 GetWrapperTF1()->SetParLimits(3, -25, tmax);
1337 }
1338 m_preT0Max = tmax;
1339}
1340
1341void ZDCFitExpFermiInductPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1342{
1343 GetWrapperTF1()->SetParameter(0, initialAmp);
1344 GetWrapperTF1()->SetParameter(1, initialT0);
1345 GetWrapperTF1()->SetParameter(2, 5);
1346 GetWrapperTF1()->SetParameter(3, 10);
1347 GetWrapperTF1()->SetParameter(4, 0);
1348 GetWrapperTF1()->SetParameter(5, 0);
1349 GetWrapperTF1()->SetParameter(6, 0.1);
1350 GetWrapperTF1()->SetParameter(7, 0.1);
1351
1352 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1353 // Set parameter errors for fit step size
1354 //
1355 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
1356 GetWrapperTF1()->SetParError(0, ampStep);
1357 GetWrapperTF1()->SetParError(1, 1.0);
1358 GetWrapperTF1()->SetParError(2, 0.05);
1359 GetWrapperTF1()->SetParError(3, 1);
1360 GetWrapperTF1()->SetParError(4, 5.0);
1361 GetWrapperTF1()->SetParError(5, 5);
1362 GetWrapperTF1()->SetParError(6, 0.05);
1363 GetWrapperTF1()->SetParError(7, 0.05);
1364}
1365
1367{
1368 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1369 theTF1->SetParLimits(1, t0Min, t0Max);
1370}
1371
1372
1373// --------------------------------------------------------------------------------------------------------------------------------------------
1374//
1375ZDCFitExpFermiLinearFixedTaus::ZDCFitExpFermiLinearFixedTaus(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1376 ZDCFitWrapper(std::make_shared<TF1>(("ExpFermiFixedTaus" + tag).c_str(), this, tmin, tmax, 4)),
1377 m_tau1(tau1), m_tau2(tau2)
1378{
1379 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1380
1381 // BAC, parameter 0 limits now is set in DoInitialize
1382 theTF1->SetParLimits(1, tmin, tmax);
1383
1384 theTF1->SetParName(0, "Amp");
1385 theTF1->SetParName(1, "T0");
1386 theTF1->SetParName(2, "s_{b}");
1387 theTF1->SetParName(3, "c_{b}");
1388
1389 // Now create the reference function that we use to evaluate ExpFermiFit more efficiently
1390 //
1391 std::string funcNameRefFunc = "ExpFermiFixedTausRefFunc" + tag;
1392
1393 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
1394
1395 m_expFermiFunc->SetParameter(0, 1);
1396 m_expFermiFunc->SetParameter(1, 0);
1397 m_expFermiFunc->SetParameter(2, m_tau1);
1398 m_expFermiFunc->SetParameter(3, m_tau2);
1399 m_expFermiFunc->FixParameter(4, 0);
1400
1401 m_norm = 1. / m_expFermiFunc->GetMaximum();
1402 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1403}
1404
1406{
1407 // We force the linear terms to zero
1408 //
1409 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1410
1411 theTF1->FixParameter(2, 0);
1412 theTF1->FixParameter(3, 0);
1413}
1414
1416{
1417 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1418 theTF1->ReleaseParameter(2);
1419 theTF1->ReleaseParameter(3);
1420}
1421
1422void ZDCFitExpFermiLinearFixedTaus::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1423{
1424 float slope = std::abs(0.1 * initialAmp / initialT0);
1425 float intercept = std::abs(0.1 * initialAmp);
1426 GetWrapperTF1()->SetParLimits(2, -slope , slope );
1427 GetWrapperTF1()->SetParLimits(3, -intercept, intercept);
1428
1429 GetWrapperTF1()->SetParameter(0, initialAmp);
1430 GetWrapperTF1()->SetParameter(1, initialT0);
1431 GetWrapperTF1()->SetParameter(2, 0);
1432 GetWrapperTF1()->SetParameter(3, 0);
1433
1434 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1435
1436 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
1437
1438 GetWrapperTF1()->SetParError(0, ampStep);
1439 GetWrapperTF1()->SetParError(1, 1);
1440 GetWrapperTF1()->SetParError(2, 1);
1441 GetWrapperTF1()->SetParError(3, 0.5);
1442}
1443
1445{
1446 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1447 theTF1->SetParLimits(1, t0Min, t0Max);
1448}
1449
1450// --------------------------------------------------------------------------------------------------------------------------------------------
1451//
1452ZDCFitExpFermiLinearPrePulse::ZDCFitExpFermiLinearPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1453 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiLinearPrePulse" + tag).c_str(), this, tmin, tmax, 6)),
1454 m_tau1(tau1), m_tau2(tau2)
1455{
1456 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1457 //
1458 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
1459
1460 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 5);
1461
1462 m_expFermiFunc->SetParameter(0, 1);
1463 m_expFermiFunc->SetParameter(1, 0);
1464 m_expFermiFunc->SetParameter(2, m_tau1);
1465 m_expFermiFunc->SetParameter(3, m_tau2);
1466 m_expFermiFunc->FixParameter(4, 0);
1467
1468 m_norm = 1. / m_expFermiFunc->GetMaximum();
1469 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1470
1471 // Now set up the actual TF1
1472 //
1473 std::shared_ptr<TF1> theTF1 = ZDCFitWrapper::GetWrapperTF1();
1474
1475 theTF1->SetParName(0, "Amp");
1476 theTF1->SetParName(1, "T0");
1477 theTF1->SetParName(2, "Amp_{pre}");
1478 theTF1->SetParName(3, "T0_{pre}");
1479 theTF1->SetParName(4, "s_{b}");
1480 theTF1->SetParName(5, "c_{b}");
1481
1482 // BAC, parameter 0 limits now is set in DoInitialize
1483 theTF1->SetParLimits(1, tmin, tmax);
1484 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.
1485 theTF1->SetParLimits(3, -20, 10);
1486}
1487
1489{
1490 // We force the linear terms and prepulse terms to zero
1491 //
1492 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1493
1494 theTF1->FixParameter(4, 0);
1495 theTF1->FixParameter(5, 0);
1496}
1498{
1499 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1500
1501 theTF1->ReleaseParameter(4);
1502 theTF1->ReleaseParameter(5);
1503}
1504
1506{
1507 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1508}
1509
1510void ZDCFitExpFermiLinearPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1511{
1512 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
1513 float intercept = std::abs(0.5 * initialAmp);
1514 GetWrapperTF1()->SetParLimits(4, -slope , slope );
1515 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
1516
1517 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1518
1519 GetWrapperTF1()->SetParameter(0, initialAmp);
1520 GetWrapperTF1()->SetParameter(1, initialT0);
1521 GetWrapperTF1()->SetParameter(2, 5);
1522 GetWrapperTF1()->SetParameter(5, 0);
1523
1524 double ampStep = std::min(0.05*initialAmp, std::abs(ampMax - initialAmp)/2.);
1525
1526 GetWrapperTF1()->SetParError(0, ampStep);
1527 GetWrapperTF1()->SetParError(1, 1.0);
1528 GetWrapperTF1()->SetParError(2, 1);
1529 GetWrapperTF1()->SetParError(3, 1);
1530 GetWrapperTF1()->SetParError(4, 0.1);
1531 GetWrapperTF1()->SetParError(5, 1);
1532}
1533
1535{
1536 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1537}
1538
1539
1540// --------------------------------------------------------------------------------------------------------------------------------------------
1541//
1542ZDCFitComplexPrePulse::ZDCFitComplexPrePulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1543 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 7)),
1544 m_tau1(tau1), m_tau2(tau2)
1545{
1546 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1547 //
1548 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
1549
1550 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 4);
1551
1552 m_expFermiFunc->SetParameter(0, 1);
1553 m_expFermiFunc->SetParameter(1, 0);
1554 m_expFermiFunc->SetParameter(2, m_tau1);
1555 m_expFermiFunc->SetParameter(3, m_tau2);
1556
1557 m_norm = 1. / m_expFermiFunc->GetMaximum();
1558 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1559
1560 // Now set up the actual TF1
1561 //
1562 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1563
1564 // BAC, parameter 0 limits now is set in DoInitialize
1565 theTF1->SetParLimits(1, tmin, tmax);
1566 theTF1->SetParLimits(2, 0, 2048); // Pre-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1567 theTF1->SetParLimits(3, 0, 40);
1568 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.
1569
1570 theTF1->SetParName(0, "Amp");
1571 theTF1->SetParName(1, "T0");
1572 theTF1->SetParName(2, "Amp_{pre}");
1573 theTF1->SetParName(3, "T0_{pre}");
1574 theTF1->SetParName(4, "s_{b}");
1575 theTF1->SetParName(5, "c_{b}");
1576 theTF1->SetParName(6, "Amp_{exp}");
1577}
1578
1580{
1581 // We force the linear terms and prepulse terms to zero
1582 //
1583 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1584
1585 theTF1->FixParameter(2, 0);
1586 theTF1->FixParameter(4, 0);
1587 theTF1->FixParameter(5, 0);
1588}
1590{
1591 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1592 theTF1->ReleaseParameter(2);
1593 theTF1->ReleaseParameter(4);
1594 theTF1->ReleaseParameter(5);
1595}
1596
1598{
1599 if (tmin > GetTMin()) {
1600 GetWrapperTF1()->ReleaseParameter(3);
1601 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1602 }
1603 else {
1604 GetWrapperTF1()->SetParLimits(3, 0, tmax);
1605 }
1606}
1607
1608void ZDCFitComplexPrePulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1609{
1610 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
1611 float intercept = std::abs(0.1 * initialAmp); // reduce from 0.25 to 0.1 fix some fail issue
1612 GetWrapperTF1()->SetParLimits(4, -slope , slope ); // if the lower limit is set to 0, there will be some fit fail issue...
1613 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
1614
1615 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1616
1617 GetWrapperTF1()->SetParameter(0, initialAmp);
1618 GetWrapperTF1()->SetParameter(1, initialT0);
1619 GetWrapperTF1()->SetParameter(2, 5);
1620 GetWrapperTF1()->SetParameter(3, 10);
1621 GetWrapperTF1()->SetParameter(4, 0);
1622 GetWrapperTF1()->SetParameter(5, 0);
1623 GetWrapperTF1()->SetParameter(6, 1);
1624}
1625
1626void ZDCFitComplexPrePulse::SetT0FitLimits(float t0Min, float t0Max)
1627{
1628 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1629}
1630
1631
1632
1633// --------------------------------------------------------------------------------------------------------------------------------------------
1634//
1635ZDCFitGeneralPulse::ZDCFitGeneralPulse(const std::string& tag, float tmin, float tmax, float tau1, float tau2) :
1636 ZDCPrePulseFitWrapper(std::make_shared<TF1>(("ExpFermiPrePulse" + tag).c_str(), this, tmin, tmax, 9)),
1637 m_tau1(tau1), m_tau2(tau2)
1638{
1639 // Create the reference function that we use to evaluate ExpFermiFit more efficiently
1640 //
1641 std::string funcNameRefFunc = "ExpFermiPerPulseRefFunc" + tag;
1642
1643 m_expFermiFunc = std::make_shared<TF1>(funcNameRefFunc.c_str(), ZDCFermiExpFit, -50, 100, 4);
1644
1645 m_expFermiFunc->SetParameter(0, 1);
1646 m_expFermiFunc->SetParameter(1, 0);
1647 m_expFermiFunc->SetParameter(2, m_tau1);
1648 m_expFermiFunc->SetParameter(3, m_tau2);
1649
1650 m_norm = 1. / m_expFermiFunc->GetMaximum();
1651 m_timeCorr = m_tau1 * std::log(m_tau2 / m_tau1 - 1.0);
1652
1653 // Now set up the actual TF1
1654 //
1655 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1656
1657 // BAC, parameter 0 limits now is set in DoInitialize
1658 theTF1->SetParLimits(1, tmin, tmax);
1659 theTF1->SetParLimits(2, 0, 2048); // Pre-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1660 theTF1->SetParLimits(3, 0, 40);
1661 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.
1662 theTF1->SetParLimits(7, 0, 2048); // Post-pulse upper bound should not be greater 2 times of ADC range with overflow constrains.
1663 theTF1->SetParLimits(8, 100, 163);
1664
1665 theTF1->SetParName(0, "Amp");
1666 theTF1->SetParName(1, "T0");
1667 theTF1->SetParName(2, "Amp_{pre}");
1668 theTF1->SetParName(3, "T0_{pre}");
1669 theTF1->SetParName(4, "s_{b}");
1670 theTF1->SetParName(5, "c_{b}");
1671 theTF1->SetParName(6, "Amp_{exp}");
1672 theTF1->SetParName(7, "Amp_{post}");
1673 theTF1->SetParName(8, "T0_{post}");
1674}
1675
1677{
1678 // We force the linear terms and prepulse terms to zero
1679 //
1680 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1681
1682 theTF1->FixParameter(2, 0);
1683 theTF1->FixParameter(4, 0);
1684 theTF1->FixParameter(5, 0);
1685}
1687{
1688 std::shared_ptr<TF1> theTF1 = GetWrapperTF1();
1689 theTF1->ReleaseParameter(2);
1690 theTF1->ReleaseParameter(4);
1691 theTF1->ReleaseParameter(5);
1692}
1693
1694void ZDCFitGeneralPulse::SetPrePulseT0Range(float tmin, float tmax)
1695{
1696 if (tmin > GetTMin()) {
1697 if (tmin < 0) tmin = 0;
1698 GetWrapperTF1()->SetParLimits(3, tmin, tmax);
1699 }
1700 else {
1701 GetWrapperTF1()->SetParLimits(3, 0, tmax);
1702 }
1703}
1704
1705void ZDCFitGeneralPulse::SetPostPulseT0Range(float tmin, float tmax, float initialPostT0)
1706{
1707 GetWrapperTF1()->SetParLimits(8, tmin, tmax);
1708 float iniPostT0 = initialPostT0;
1709 GetWrapperTF1()->SetParameter(8, iniPostT0);
1710}
1711
1712void ZDCFitGeneralPulse::DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)
1713{
1714 float slope = std::abs(initialAmp / initialT0); // to be studied more ??? limit 0.1 0.05
1715 float intercept = std::abs(0.1 * initialAmp); // reduce from 0.25 to 0.1 fix some fail issue
1716 GetWrapperTF1()->SetParLimits(4, -slope , slope ); // if the lower limit is set to 0, there will be some fit fail issue...
1717 GetWrapperTF1()->SetParLimits(5, -intercept, intercept);
1718
1719 GetWrapperTF1()->SetParLimits(0, ampMin, ampMax);
1720
1721 GetWrapperTF1()->SetParameter(0, initialAmp);
1722 GetWrapperTF1()->SetParameter(1, initialT0);
1723 GetWrapperTF1()->SetParameter(4, 0);
1724 GetWrapperTF1()->SetParameter(5, 0);
1725 GetWrapperTF1()->SetParameter(7, 5);
1726}
1727
1728void ZDCFitGeneralPulse::SetT0FitLimits(float t0Min, float t0Max)
1729{
1730 GetWrapperTF1()->SetParLimits(1, t0Min, t0Max);
1731}
static Double_t t0
if(pathvar)
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 DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void SetPrePulseT0Range(float tmin, float tmax) override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void doConstrainFit() override
ZDCFitComplexPrePulse(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
std::shared_ptr< TF1 > m_expFermiFunc
virtual void doUnconstrainFit() override
ZDCFitExpFermiFixedTaus(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
virtual void doUnconstrainFit() override
virtual void doConstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
std::shared_ptr< TF1 > m_expFermiFunc
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void doUnconstrainFit() override
std::shared_ptr< TF1 > m_expFermiInductFunc
virtual void doConstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
static const std::map< std::string, std::vector< ZDCFitWrapper::FitParameter > > s_ConfigParamMap
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 doConstrainFit() override
static const std::map< std::string, std::vector< ZDCFitWrapper::FitParameter > > s_ConfigParamMap
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void doUnconstrainFit() 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 DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void SetT0FitLimits(float tMin, float tMax) override
std::shared_ptr< TF1 > m_expFermiLHCfFunc
virtual void doConstrainFit() override
virtual void doUnconstrainFit() override
ZDCFitExpFermiLHCfPreExp(const std::string &tag, float tmin, float tmax, float tau1, float tau2, float defExpTau, float fixExpTau)
std::shared_ptr< TF1 > m_expFermiPreFunc
std::shared_ptr< TF1 > m_expFermiLHCfFunc
virtual void SetPrePulseT0Range(float tmin, float tmax) override
virtual void doConstrainFit() override
virtual void doUnconstrainFit() 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)
std::shared_ptr< TF1 > m_expFermiFunc
virtual void doUnconstrainFit() override
virtual void doConstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
ZDCFitExpFermiLinearFixedTaus(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
virtual void doUnconstrainFit() override
virtual void SetPrePulseT0Range(float tmin, float tmax) 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 doConstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
std::shared_ptr< TF1 > m_expFermiFunc
virtual void doUnconstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void doConstrainFit() 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 doUnconstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void doConstrainFit() 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
ZDCFitExpFermiPrePulse(const std::string &tag, float tmin, float tmax, float tau1, float tau2)
static const std::map< std::string, std::vector< ZDCFitWrapper::FitParameter > > s_ConfigParamMap
virtual void doConstrainFit() override
ZDCFitExpFermiVariableTausInduct(const std::string &tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2)
virtual void doUnconstrainFit() 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 doUnconstrainFit() override
ZDCFitExpFermiVariableTausLHCf(const std::string &tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2)
virtual void doConstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) 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
ZDCFitExpFermiVariableTaus(const std::string &tag, float tmin, float tmax, bool fixTau1, bool fixTau2, float tau1, float tau2)
virtual void doConstrainFit() override
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void doUnconstrainFit() override
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax) override
std::shared_ptr< TF1 > m_expFermiFunc
virtual void SetT0FitLimits(float tMin, float tMax) override
virtual void doUnconstrainFit() 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 doConstrainFit() override
virtual void SetPrePulseT0Range(float tmin, float tmax) override
void Initialize(float initialAmp, float initialT0, float ampMin, float ampMax)
float GetTMin() const
void OverrideParameterSet(const std::vector< FitParameter > &parameterSet)
virtual void doUnconstrainFit()=0
virtual std::shared_ptr< TF1 > GetWrapperTF1()
ZDCFitWrapper()=delete
float GetT0Max() const
std::vector< FitParameter > m_parameterSet
void LoadDefaultParameterSet(const std::vector< FitParameter > &parameterSet)
bool m_haveParameterSet
float GetT0Min() const
virtual void SetT0FitLimits(float tMin, float tMax)=0
void SetAmpMinMax(float minAmp, float maxAmp)
virtual void DoInitialize(float initialAmp, float initialT0, float ampMin, float ampMax)=0
virtual void doConstrainFit()=0
const FitParameter & GetParameterDescr(const std::string &name)
std::shared_ptr< TF1 > m_wrapperTF1
float getDefaultExpTau() const
ZDCPreExpFitWrapper(std::shared_ptr< TF1 > wrapperTF1, float defaultExpTau, bool fixTau)
bool fixExpTau() const
ZDCPrePulseFitWrapper(std::shared_ptr< TF1 > wrapperTF1)
STL namespace.