musrfit 1.10.0
PRunAsymmetryBNMR.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PRunAsymmetryBNMR.cpp
4
5 Author: Zaher Salman
6 Based on PRunAsymmetry.cpp by Andreas Suter
7 e-mail: zaher.salman@psi.ch
8
9***************************************************************************/
10
11/***************************************************************************
12 * Copyright (C) 2018-2026 by Zaher Salman *
13 * zaher.salman@psi.ch *
14 * *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
19 * *
20 * This program is distributed in the hope that it will be useful, *
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
23 * GNU General Public License for more details. *
24 * *
25 * You should have received a copy of the GNU General Public License *
26 * along with this program; if not, write to the *
27 * Free Software Foundation, Inc., *
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
29 ***************************************************************************/
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#ifdef HAVE_GOMP
36#include <omp.h>
37#endif
38
39#include <stdio.h>
40
41#include <iostream>
42#include <string>
43#include <vector>
44
45#include <TString.h>
46
47#include "PMusr.h"
48#include "PStringUtils.h"
49#include "PRunAsymmetryBNMR.h"
50
51//--------------------------------------------------------------------------
52// Constructor
53//--------------------------------------------------------------------------
62{
63 fNoOfFitBins = 0;
64 fPacking = -1;
65 fTheoAsData = false;
66
67 // the 2 following variables are need in case fit range is given in bins, and since
68 // the fit range can be changed in the command block, these variables need to be accessible
69 fGoodBins[0] = -1;
70 fGoodBins[1] = -1;
71
72 fStartTimeBin = -1;
73 fEndTimeBin = -1;
74}
75
76//--------------------------------------------------------------------------
77// Constructor
78//--------------------------------------------------------------------------
103PRunAsymmetryBNMR::PRunAsymmetryBNMR(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData) :
104 PRunBase(msrInfo, rawData, runNo, tag), fTheoAsData(theoAsData)
105{
106 // the 2 following variables are need in case fit range is given in bins, and since
107 // the fit range can be changed in the command block, these variables need to be accessible
108 fGoodBins[0] = -1;
109 fGoodBins[1] = -1;
110
111 fStartTimeBin = -1;
112 fEndTimeBin = -1;
113
114 fPacking = fRunInfo->GetPacking();
115 if (fPacking == -1) { // i.e. packing is NOT given in the RUN-block, it must be given in the GLOBAL-block
116 fPacking = fMsrInfo->GetMsrGlobal()->GetPacking();
117 }
118 if (fPacking == -1) { // this should NOT happen, somethin is severely wrong
119 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PRunAsymmetryBNMR(): **SEVERE ERROR**: Couldn't find any packing information!";
120 std::cerr << std::endl << ">> This is very bad :-(, will quit ...";
121 std::cerr << std::endl;
122 fValid = false;
123 return;
124 }
125
126 // check if alpha and/or beta is fixed --------------------
127
128 PMsrParamList *param = msrInfo->GetMsrParamList();
129
130 // check if alpha is given
131 Bool_t alphaFixedToOne = false;
132 Bool_t alphaSetDefault = false;
133 if (fRunInfo->GetAlphaParamNo() == -1) { // no alpha given
134 // std::cerr << std::endl << ">> PRunAsymmetryBNMR::PRunAsymmetryBNMR(): **ERROR** no alpha parameter given! This is needed for an asymmetry fit!";
135 // std::cerr << std::endl;
136 // fValid = false;
137 // return;
138 alphaSetDefault = true;
139 } else if (fRunInfo->GetAlphaParamNo() >= MSR_PARAM_FUN_OFFSET) { // alpha seems to be a function
140 if ((fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET < 0) ||
141 (fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET > msrInfo->GetNoOfFuncs())) {
142 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PRunAsymmetryBNMR(): **ERROR** alpha parameter is a function with no = " << fRunInfo->GetAlphaParamNo();
143 std::cerr << std::endl << ">> This is out of bound, since there are only " << msrInfo->GetNoOfFuncs() << " functions.";
144 std::cerr << std::endl;
145 fValid = false;
146 return;
147 }
148 } else if ((fRunInfo->GetAlphaParamNo() < 0) || (fRunInfo->GetAlphaParamNo() > (Int_t)param->size())) { // check if alpha parameter is within proper bounds
149 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PRunAsymmetryBNMR(): **ERROR** alpha parameter no = " << fRunInfo->GetAlphaParamNo();
150 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
151 std::cerr << std::endl;
152 fValid = false;
153 return;
154 } else { // check if alpha is fixed
155 if (((*param)[fRunInfo->GetAlphaParamNo()-1].fStep == 0.0) &&
156 ((*param)[fRunInfo->GetAlphaParamNo()-1].fValue == 1.0))
157 alphaFixedToOne = true;
158 }
159
160 // check if beta is given
161 Bool_t betaFixedToOne = false;
162 if (fRunInfo->GetBetaParamNo() == -1) { // no beta given hence assuming beta == 1
163 betaFixedToOne = true;
164 } else if (fRunInfo->GetBetaParamNo() >= MSR_PARAM_FUN_OFFSET) { // beta seems to be a function
165 if ((fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET < 0) ||
166 (fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET > msrInfo->GetNoOfFuncs())) {
167 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PRunAsymmetryBNMR(): **ERROR** beta parameter is a function with no = " << fRunInfo->GetBetaParamNo();
168 std::cerr << std::endl << ">> This is out of bound, since there are only " << msrInfo->GetNoOfFuncs() << " functions.";
169 std::cerr << std::endl;
170 fValid = false;
171 return;
172 }
173 } else if ((fRunInfo->GetBetaParamNo() < 0) || (fRunInfo->GetBetaParamNo() > (Int_t)param->size())) { // check if beta parameter is within proper bounds
174 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PRunAsymmetryBNMR(): **ERROR** beta parameter no = " << fRunInfo->GetBetaParamNo();
175 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
176 std::cerr << std::endl;
177 fValid = false;
178 return;
179 } else { // check if beta is fixed
180 if (((*param)[fRunInfo->GetBetaParamNo()-1].fStep == 0.0) &&
181 ((*param)[fRunInfo->GetBetaParamNo()-1].fValue == 1.0))
182 betaFixedToOne = true;
183 }
184
185 // set fAlphaBetaTag
186 if (alphaFixedToOne && betaFixedToOne) // alpha == 1, beta == 1
187 fAlphaBetaTag = 1;
188 else if (!alphaFixedToOne && betaFixedToOne & !alphaSetDefault) // alpha != 1, beta == 1
189 fAlphaBetaTag = 2;
190 else if (alphaFixedToOne && !betaFixedToOne) // alpha == 1, beta != 1
191 fAlphaBetaTag = 3;
192 else if (!alphaFixedToOne && betaFixedToOne & alphaSetDefault) // alpha ??, beta == 1
193 fAlphaBetaTag = 5;
194 else if (!alphaFixedToOne && !betaFixedToOne & alphaSetDefault) // alpha ??, beta != 1
195 fAlphaBetaTag = 6;
196 else
197 fAlphaBetaTag = 4;
198
199 // calculate fData
200 if (!PrepareData())
201 fValid = false;
202}
203
204//--------------------------------------------------------------------------
205// Destructor
206//--------------------------------------------------------------------------
214{
215 fForwardp.clear();
216 fForwardpErr.clear();
217 fBackwardp.clear();
218 fBackwardpErr.clear();
219
220 fForwardm.clear();
221 fForwardmErr.clear();
222 fBackwardm.clear();
223 fBackwardmErr.clear();
224}
225
226//--------------------------------------------------------------------------
227// CalcChiSquare (public)
228//--------------------------------------------------------------------------
245Double_t PRunAsymmetryBNMR::CalcChiSquare(const std::vector<Double_t>& par)
246{
247 Double_t chisq = 0.0;
248 Double_t diff = 0.0;
249 Double_t asymFcnValue = 0.0;
250 Double_t a, b, f;
251
252 // calculate functions
253 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
254 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
255 }
256
257 // calculate chi square
258 Double_t time(1.0),alphaest;
259 Int_t i;
260
261 // determine alpha/beta
262 alphaest = fRunInfo->GetEstimatedAlpha();
263 switch (fAlphaBetaTag) {
264 case 1: // alpha == 1, beta == 1
265 a = 1.0;
266 b = 1.0;
267 break;
268 case 2: // alpha != 1, beta == 1
269 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
270 a = par[fRunInfo->GetAlphaParamNo()-1];
271 } else { // alpha is function
272 // get function number
273 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
274 // evaluate function
275 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
276 }
277 b = 1.0;
278 break;
279 case 3: // alpha == 1, beta != 1
280 a = 1.0;
281 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
282 b = par[fRunInfo->GetBetaParamNo()-1];
283 } else { // beta is a function
284 // get function number
285 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
286 // evaluate function
287 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
288 }
289 break;
290 case 4: // alpha != 1, beta != 1
291 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
292 a = par[fRunInfo->GetAlphaParamNo()-1];
293 } else { // alpha is function
294 // get function number
295 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
296 // evaluate function
297 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
298 }
299 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
300 b = par[fRunInfo->GetBetaParamNo()-1];
301 } else { // beta is a function
302 // get function number
303 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
304 // evaluate function
305 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
306 }
307 break;
308 case 5: // alpha ?? , beta == 1
309 a = alphaest;
310 b = 1.0;
311 break;
312 case 6: // alpha ??, beta != 1
313 a = alphaest;
314 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
315 b = par[fRunInfo->GetBetaParamNo()-1];
316 } else { // beta is a function
317 // get function number
318 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
319 // evaluate function
320 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
321 }
322 break;
323 default:
324 a = 1.0;
325 b = 1.0;
326 break;
327 }
328
329 // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
330 // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
331 // for a given set of parameters---which should be done outside of the parallelized loop.
332 // For all other functions it means a tiny and acceptable overhead.
333 asymFcnValue = fTheory->Func(time, par, fFuncValues);
334
335 #ifdef HAVE_GOMP
336 Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
337 if (chunk < 10)
338 chunk = 10;
339 #pragma omp parallel for default(shared) private(i,time,diff,asymFcnValue,f) schedule(dynamic,chunk) reduction(+:chisq)
340 #endif
341 for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
342 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
343 f = fTheory->Func(time, par, fFuncValues)/2.0;
344 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0))-(-f*(a*b+1.0)-(a-1.0))/((a+1.0)+f*(a*b-1.0));
345 diff = fData.GetValue()->at(i) - asymFcnValue;
346 chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
347 }
348
349 return chisq;
350}
351
352//--------------------------------------------------------------------------
353// CalcChiSquareExpected (public)
354//--------------------------------------------------------------------------
364Double_t PRunAsymmetryBNMR::CalcChiSquareExpected(const std::vector<Double_t>& par)
365{
366 return 0.0;
367}
368
369//--------------------------------------------------------------------------
370// CalcMaxLikelihood (public)
371//--------------------------------------------------------------------------
381Double_t PRunAsymmetryBNMR::CalcMaxLikelihood(const std::vector<Double_t>& par)
382{
383 std::cout << std::endl << "PRunAsymmetryBNMR::CalcMaxLikelihood(): not implemented yet ..." << std::endl;
384
385 return 1.0;
386}
387
388//--------------------------------------------------------------------------
389// GetNoOfFitBins (public)
390//--------------------------------------------------------------------------
399{
401
402 return fNoOfFitBins;
403}
404
405//--------------------------------------------------------------------------
406// SetFitRangeBin (public)
407//--------------------------------------------------------------------------
426void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange)
427{
428 TString str;
429 Ssiz_t idx = -1;
430 Int_t offset = 0;
431
432 std::vector<std::string> tok = PStringUtils::Split(fitRange.Data(), " \t");
433
434 if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1
435 // handle fgb+n0 entry
436 str = tok[1];
437 // check if there is an offset present
438 idx = str.First("+");
439 if (idx != -1) { // offset present
440 str.Remove(0, idx+1);
441 if (str.IsFloat()) // if str is a valid number, convert is to an integer
442 offset = str.Atoi();
443 }
444 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
445
446 // handle lgb-n1 entry
447 str = tok[2];
448 // check if there is an offset present
449 idx = str.First("-");
450 if (idx != -1) { // offset present
451 str.Remove(0, idx+1);
452 if (str.IsFloat()) // if str is a valid number, convert is to an integer
453 offset = str.Atoi();
454 }
455 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
456 } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
457 UInt_t pos = 2*(fRunNo+1)-1;
458
459 if (pos + 1 >= tok.size()) {
460 std::cerr << std::endl << ">> PRunAsymmetryBNMR::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
461 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
462 } else {
463 // handle fgb+n0 entry
464 str = tok[pos];
465 // check if there is an offset present
466 idx = str.First("+");
467 if (idx != -1) { // offset present
468 str.Remove(0, idx+1);
469 if (str.IsFloat()) // if str is a valid number, convert is to an integer
470 offset = str.Atoi();
471 }
472 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
473
474 // handle lgb-n1 entry
475 str = tok[pos+1];
476 // check if there is an offset present
477 idx = str.First("-");
478 if (idx != -1) { // offset present
479 str.Remove(0, idx+1);
480 if (str.IsFloat()) // if str is a valid number, convert is to an integer
481 offset = str.Atoi();
482 }
483 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
484 }
485 } else { // error
486 std::cerr << std::endl << ">> PRunAsymmetryBNMR::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
487 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
488 }
489}
490
491//--------------------------------------------------------------------------
492// CalcNoOfFitBins (public)
493//--------------------------------------------------------------------------
502{
503 // In order not having to loop over all bins and to stay consistent with the chisq method, calculate the start and end bins explicitly
504 fStartTimeBin = static_cast<Int_t>(ceil((fFitStartTime - fData.GetDataTimeStart())/fData.GetDataTimeStep()));
505 if (fStartTimeBin < 0)
506 fStartTimeBin = 0;
507 fEndTimeBin = static_cast<Int_t>(floor((fFitEndTime - fData.GetDataTimeStart())/fData.GetDataTimeStep())) + 1;
508 if (fEndTimeBin > static_cast<Int_t>(fData.GetValue()->size()))
509 fEndTimeBin = fData.GetValue()->size();
510
512 fNoOfFitBins = static_cast<UInt_t>(fEndTimeBin - fStartTimeBin);
513 else
514 fNoOfFitBins = 0;
515}
516
517//--------------------------------------------------------------------------
518// CalcTheory (protected)
519//--------------------------------------------------------------------------
536{
537 // feed the parameter vector
538 std::vector<Double_t> par;
539 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
540 for (UInt_t i=0; i<paramList->size(); i++)
541 par.push_back((*paramList)[i].fValue);
542
543 // calculate functions
544 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
545 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
546 }
547
548 // calculate asymmetry
549 Double_t asymFcnValue = 0.0;
550 Double_t a, b, f, alphaest;
551 Double_t time;
552
553 // Get estimated alpha
554 alphaest = fRunInfo->GetEstimatedAlpha();
555
556 for (UInt_t i=0; i<fData.GetValue()->size(); i++) {
557 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
558 switch (fAlphaBetaTag) {
559 case 1: // alpha == 1, beta == 1
560 asymFcnValue = fTheory->Func(time, par, fFuncValues);
561 break;
562 case 2: // alpha != 1, beta == 1
563 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
564 a = par[fRunInfo->GetAlphaParamNo()-1];
565 } else { // alpha is function
566 // get function number
567 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
568 // evaluate function
569 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
570 }
571 f = fTheory->Func(time, par, fFuncValues);
572 asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0)) - (-f*(a+1.0)-(a-1.0))/((a+1.0)+f*(a-1.0));
573 break;
574 case 3: // alpha == 1, beta != 1
575 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
576 b = par[fRunInfo->GetBetaParamNo()-1];
577 } else { // beta is a function
578 // get function number
579 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
580 // evaluate function
581 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
582 }
583 f = fTheory->Func(time, par, fFuncValues);
584 asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0))-f*(b+1.0)/(2.0+f*(b-1.0));
585 break;
586 case 4: // alpha != 1, beta != 1
587 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
588 a = par[fRunInfo->GetAlphaParamNo()-1];
589 } else { // alpha is function
590 // get function number
591 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
592 // evaluate function
593 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
594 }
595 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
596 b = par[fRunInfo->GetBetaParamNo()-1];
597 } else { // beta is a function
598 // get function number
599 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
600 // evaluate function
601 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
602 }
603 f = fTheory->Func(time, par, fFuncValues);
604 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0))-(-f*(a*b+1.0)-(a-1.0))/((a+1.0)+f*(a*b-1.0));
605 break;
606 case 5: // alpha ?? , beta == 1
607 a = alphaest;
608 f = fTheory->Func(time, par, fFuncValues);
609 asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0)) - (-f*(a+1.0)-(a-1.0))/((a+1.0)+f*(a-1.0));
610 break;
611 case 6: // alpha ??, beta != 1
612 a = alphaest;
613 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
614 b = par[fRunInfo->GetBetaParamNo()-1];
615 } else { // beta is a function
616 // get function number
617 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
618 // evaluate function
619 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
620 }
621 f = fTheory->Func(time, par, fFuncValues);
622 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0))-(-f*(a*b+1.0)-(a-1.0))/((a+1.0)+f*(a*b-1.0));
623 break;
624 default:
625 asymFcnValue = 0.0;
626 break;
627 }
628 fData.AppendTheoryValue(asymFcnValue);
629 }
630
631 // clean up
632 par.clear();
633}
634
635//--------------------------------------------------------------------------
636// PrepareData (protected)
637//--------------------------------------------------------------------------
660{
661 if (!fValid)
662 return false;
663
664 // keep the Global block info
665 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
666
667 // get forward/backward histo from PRunDataHandler object ------------------------
668 // get the correct run
669 PRawRunData *runData = fRawData->GetRunData(*(fRunInfo->GetRunName()));
670 if (!runData) { // run not found
671 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **ERROR** Couldn't get run " << fRunInfo->GetRunName()->Data() << "!";
672 std::cerr << std::endl;
673 return false;
674 }
675
676 // keep the field from the meta-data from the data-file
677 fMetaData.fField = runData->GetField();
678
679 // keep the energy from the meta-data from the data-file
680 fMetaData.fEnergy = runData->GetEnergy();
681
682 // keep the temperature(s) from the meta-data from the data-file
683 for (unsigned int i=0; i<runData->GetNoOfTemperatures(); i++)
684 fMetaData.fTemp.push_back(runData->GetTemperature(i));
685
686 // collect histogram numbers
687 PUIntVector forwardHistoNo;
688 PUIntVector backwardHistoNo;
689 for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
690 forwardHistoNo.push_back(fRunInfo->GetForwardHistoNo(i));
691
692 if (!runData->IsPresent(forwardHistoNo[i])) {
693 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **PANIC ERROR**:";
694 std::cerr << std::endl << ">> forwardHistoNo found = " << forwardHistoNo[i] << ", which is NOT present in the data file!?!?";
695 std::cerr << std::endl << ">> Will quit :-(";
696 std::cerr << std::endl;
697 // clean up
698 forwardHistoNo.clear();
699 backwardHistoNo.clear();
700 return false;
701 }
702 }
703 for (UInt_t i=0; i<fRunInfo->GetBackwardHistoNoSize(); i++) {
704 backwardHistoNo.push_back(fRunInfo->GetBackwardHistoNo(i));
705
706 if (!runData->IsPresent(backwardHistoNo[i])) {
707 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **PANIC ERROR**:";
708 std::cerr << std::endl << ">> backwardHistoNo found = " << backwardHistoNo[i] << ", which is NOT present in the data file!?!?";
709 std::cerr << std::endl << ">> Will quit :-(";
710 std::cerr << std::endl;
711 // clean up
712 forwardHistoNo.clear();
713 backwardHistoNo.clear();
714 return false;
715 }
716 }
717/* //as35
718 if (forwardHistoNo.size() != backwardHistoNo.size()) {
719 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **PANIC ERROR**:";
720 std::cerr << std::endl << ">> # of forward histograms different from # of backward histograms.";
721 std::cerr << std::endl << ">> Will quit :-(";
722 std::cerr << std::endl;
723 // clean up
724 forwardHistoNo.clear();
725 backwardHistoNo.clear();
726 return false;
727 }
728*/ //as35
729
730 // keep the time resolution in (s)
731 fTimeResolution = runData->GetTimeResolution()/1.0e3;
732 std::cout.precision(10);
733 std::cout << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): time resolution=" << std::fixed << runData->GetTimeResolution() << "(ms)" << std::endl;
734
735 // get all the proper t0's and addt0's for the current RUN block
736 if (!GetProperT0(runData, globalBlock, forwardHistoNo, backwardHistoNo)) {
737 return false;
738 }
739
740 // keep the histo of each group at this point (addruns handled below)
741 std::vector<PDoubleVector> forward, backward;
742 forward.resize(forwardHistoNo.size()); // resize to number of groups
743 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
744 forward[i].resize(runData->GetDataBin(forwardHistoNo[i])->size());
745 forward[i] = *runData->GetDataBin(forwardHistoNo[i]);
746 }
747 backward.resize(backwardHistoNo.size()); // resize to number of groups
748 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
749 backward[i].resize(runData->GetDataBin(backwardHistoNo[i])->size());
750 backward[i] = *runData->GetDataBin(backwardHistoNo[i]);
751 }
752
753 // check if addrun's are present, and if yes add data
754 // check if there are runs to be added to the current one
755 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
756 PRawRunData *addRunData;
757 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
758 // get run to be added to the main one
759 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
760 if (addRunData == nullptr) { // couldn't get run
761 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
762 std::cerr << std::endl;
763 return false;
764 }
765
766 // add forward run
767 UInt_t addRunSize;
768 for (UInt_t k=0; k<forwardHistoNo.size(); k++) { // fill each group
769 addRunSize = addRunData->GetDataBin(forwardHistoNo[k])->size();
770 for (UInt_t j=0; j<addRunData->GetDataBin(forwardHistoNo[k])->size(); j++) { // loop over the bin indices
771 // make sure that the index stays in the proper range
772 if ((static_cast<Int_t>(j)+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]) >= 0) &&
773 (j+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]) < addRunSize)) {
774 forward[k][j] += addRunData->GetDataBin(forwardHistoNo[k])->at(j+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]));
775 }
776 }
777 }
778
779 // add backward run
780 for (UInt_t k=0; k<backwardHistoNo.size(); k++) { // fill each group
781 addRunSize = addRunData->GetDataBin(backwardHistoNo[k])->size();
782 for (UInt_t j=0; j<addRunData->GetDataBin(backwardHistoNo[k])->size(); j++) { // loop over the bin indices
783 // make sure that the index stays in the proper range
784 if ((static_cast<Int_t>(j)+static_cast<Int_t>(fAddT0s[i-1][2*k+1])-static_cast<Int_t>(fT0s[2*k+1]) >= 0) &&
785 (j+static_cast<Int_t>(fAddT0s[i-1][2*k+1])-static_cast<Int_t>(fT0s[2*k+1]) < addRunSize)) {
786 backward[k][j] += addRunData->GetDataBin(backwardHistoNo[k])->at(j+static_cast<Int_t>(fAddT0s[i-1][2*k+1])-static_cast<Int_t>(fT0s[2*k+1]));
787 }
788 }
789 }
790 }
791 }
792
793 // set forward histo data of the first group
794 fForwardp.resize(forward[0].size());
795 fForwardm.resize(forward[0].size());
796 for (UInt_t i=0; i<fForwardp.size(); i++) {
797 fForwardp[i] = forward[0][i];
798 fForwardm[i] = forward[1][i];
799 }
800 // set backward histo data of the first group
801 fBackwardp.resize(backward[0].size());
802 fBackwardm.resize(backward[0].size());
803 for (UInt_t i=0; i<fBackwardp.size(); i++) {
804 fBackwardp[i] = backward[0][i];
805 fBackwardm[i] = backward[1][i];
806 }
807
808 // subtract background from histogramms ------------------------------------------
809 if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) { // no fixed background given
810 if (fRunInfo->GetBkgRange(0) >= 0) { // background range given
812 return false;
813 } else { // no background given to do the job, try to estimate it
814 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.1), 0);
815 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.6), 1);
816 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.1), 2);
817 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.6), 3);
818 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **WARNING** Neither fix background nor background bins are given!";
819 std::cerr << std::endl << ">> Will try the following:";
820 std::cerr << std::endl << ">> forward: bkg start = " << fRunInfo->GetBkgRange(0) << ", bkg end = " << fRunInfo->GetBkgRange(1);
821 std::cerr << std::endl << ">> backward: bkg start = " << fRunInfo->GetBkgRange(2) << ", bkg end = " << fRunInfo->GetBkgRange(3);
822 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS MAKES ANY SENSE! Better check ...";
823 std::cerr << std::endl;
825 return false;
826 }
827 } else { // fixed background given
828 if (!SubtractFixBkg())
829 return false;
830 }
831
832 UInt_t histoNo[2] = {forwardHistoNo[0], backwardHistoNo[0]};
833
834 // get the data range (fgb/lgb) for the current RUN block
835 if (!GetProperDataRange(runData, histoNo)) {
836 return false;
837 }
838
839 // get the fit range for the current RUN block
840 GetProperFitRange(globalBlock);
841
842 // everything looks fine, hence fill data set
843 Bool_t status;
844 switch(fHandleTag) {
845 case kFit:
847 break;
848 case kView:
849 status = PrepareViewData(runData, histoNo);
850 break;
851 default:
852 status = false;
853 break;
854 }
855
856 // clean up
857 forwardHistoNo.clear();
858 backwardHistoNo.clear();
859
860 return status;
861}
862
863//--------------------------------------------------------------------------
864// SubtractFixBkg (private)
865//--------------------------------------------------------------------------
883{
884 Double_t dval;
885
886 // Order in RunInfo structure Fp, Fm, Bp, Bm
887 for (UInt_t i=0; i<fForwardp.size(); i++) {
888 // keep the error, and make sure that the bin is NOT empty
889 if (fForwardp[i] != 0.0)
890 dval = TMath::Sqrt(fForwardp[i]);
891 else
892 dval = 1.0;
893 fForwardpErr.push_back(dval);
894 fForwardp[i] -= fRunInfo->GetBkgFix(0);
895
896 // keep the error, and make sure that the bin is NOT empty
897 if (fForwardm[i] != 0.0)
898 dval = TMath::Sqrt(fForwardm[i]);
899 else
900 dval = 1.0;
901 fForwardmErr.push_back(dval);
902 fForwardm[i] -= fRunInfo->GetBkgFix(1);
903
904 // keep the error, and make sure that the bin is NOT empty
905 if (fBackwardp[i] != 0.0)
906 dval = TMath::Sqrt(fBackwardp[i]);
907 else
908 dval = 1.0;
909 fBackwardpErr.push_back(dval);
910 fBackwardp[i] -= fRunInfo->GetBkgFix(2);
911
912 // keep the error, and make sure that the bin is NOT empty
913 if (fBackwardm[i] != 0.0)
914 dval = TMath::Sqrt(fBackwardm[i]);
915 else
916 dval = 1.0;
917 fBackwardmErr.push_back(dval);
918 fBackwardm[i] -= fRunInfo->GetBkgFix(3);
919 }
920
921 return true;
922}
923
924//--------------------------------------------------------------------------
925// SubtractEstimatedBkg (private)
926//--------------------------------------------------------------------------
945{
946 Double_t beamPeriod = 0.0;
947
948 // check if data are from PSI, RAL, or TRIUMF
949 if (fRunInfo->GetInstitute()->Contains("psi"))
950 beamPeriod = ACCEL_PERIOD_PSI;
951 else if (fRunInfo->GetInstitute()->Contains("ral"))
952 beamPeriod = ACCEL_PERIOD_RAL;
953 else if (fRunInfo->GetInstitute()->Contains("triumf"))
954 beamPeriod = ACCEL_PERIOD_TRIUMF;
955 else
956 beamPeriod = 0.0;
957
958 // check if start and end are in proper order
959 Int_t start[2] = {fRunInfo->GetBkgRange(0), fRunInfo->GetBkgRange(2)};
960 Int_t end[2] = {fRunInfo->GetBkgRange(1), fRunInfo->GetBkgRange(3)};
961 for (UInt_t i=0; i<2; i++) {
962 if (end[i] < start[i]) {
963 std::cout << std::endl << "PRunAsymmetryBNMR::SubtractEstimatedBkg(): end = " << end[i] << " > start = " << start[i] << "! Will swap them!";
964 UInt_t keep = end[i];
965 end[i] = start[i];
966 start[i] = keep;
967 }
968 }
969
970 // calculate proper background range
971 for (UInt_t i=0; i<2; i++) {
972 if (beamPeriod != 0.0) {
973 Double_t timeBkg = static_cast<Double_t>(end[i]-start[i])*(fTimeResolution*fPacking); // length of the background intervall in time
974 UInt_t fullCycles = static_cast<UInt_t>(timeBkg/beamPeriod); // how many proton beam cylces can be placed within the proposed background intervall
975 // correct the end of the background intervall such that the background is as close as possible to a multiple of the proton cylce
976 end[i] = start[i] + static_cast<UInt_t>((fullCycles*beamPeriod)/(fTimeResolution*fPacking));
977 std::cout << "PRunAsymmetryBNMR::SubtractEstimatedBkg(): Background " << start[i] << ", " << end[i] << std::endl;
978 if (end[i] == start[i])
979 end[i] = fRunInfo->GetBkgRange(2*i+1);
980 }
981 }
982
983 // check if start is within histogram bounds
984 if ((start[0] < 0) || (start[0] >= fForwardp.size()) ||
985 (start[1] < 0) || (start[1] >= fBackwardp.size())) {
986 std::cerr << std::endl << ">> PRunAsymmetryBNMR::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
987 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForwardp.size() << "/" << fBackwardp.size() << ").";
988 std::cerr << std::endl << ">> background start (f/b) = (" << start[0] << "/" << start[1] << ").";
989 return false;
990 }
991
992 // check if end is within histogram bounds
993 if ((end[0] < 0) || (end[0] >= fForwardp.size()) ||
994 (end[1] < 0) || (end[1] >= fBackwardp.size())) {
995 std::cerr << std::endl << ">> PRunAsymmetryBNMR::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
996 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForwardp.size() << "/" << fBackwardp.size() << ").";
997 std::cerr << std::endl << ">> background end (f/b) = (" << end[0] << "/" << end[1] << ").";
998 return false;
999 }
1000
1001 // calculate background
1002 Double_t bkgp[2] = {0.0, 0.0};
1003 Double_t errBkgp[2] = {0.0, 0.0};
1004 Double_t bkgm[2] = {0.0, 0.0};
1005 Double_t errBkgm[2] = {0.0, 0.0};
1006
1007 // forward
1008 for (UInt_t i=start[0]; i<=end[0]; i++) {
1009 bkgp[0] += fForwardp[i];
1010 bkgm[0] += fForwardm[i];
1011 }
1012 errBkgp[0] = TMath::Sqrt(bkgp[0])/(end[0] - start[0] + 1);
1013 bkgp[0] /= static_cast<Double_t>(end[0] - start[0] + 1);
1014 std::cout << std::endl << ">> estimated pos hel forward histo background: " << bkgp[0];
1015 errBkgm[0] = TMath::Sqrt(bkgp[0])/(end[0] - start[0] + 1);
1016 bkgm[0] /= static_cast<Double_t>(end[0] - start[0] + 1);
1017 std::cout << std::endl << ">> estimated neg hel forward histo background: " << bkgm[0];
1018
1019 // backward
1020 for (UInt_t i=start[1]; i<=end[1]; i++) {
1021 bkgp[1] += fBackwardp[i];
1022 bkgm[1] += fBackwardm[i];
1023 }
1024 errBkgp[1] = TMath::Sqrt(bkgp[1])/(end[1] - start[1] + 1);
1025 bkgp[1] /= static_cast<Double_t>(end[1] - start[1] + 1);
1026 std::cout << std::endl << ">> estimated pos hel backward histo background: " << bkgp[1];
1027 errBkgm[1] = TMath::Sqrt(bkgm[1])/(end[1] - start[1] + 1);
1028 bkgm[1] /= static_cast<Double_t>(end[1] - start[1] + 1);
1029 std::cout << std::endl << ">> estimated neg hel backward histo background: " << bkgm[1];
1030
1031 // correct error for forward, backward
1032 Double_t errVal = 0.0;
1033 for (UInt_t i=0; i<fForwardp.size(); i++) {
1034 if (fForwardp[i] > 0.0)
1035 errVal = TMath::Sqrt(fForwardp[i]+errBkgp[0]*errBkgp[0]);
1036 else
1037 errVal = 1.0;
1038 fForwardpErr.push_back(errVal);
1039 if (fBackwardp[i] > 0.0)
1040 errVal = TMath::Sqrt(fBackwardp[i]+errBkgp[1]*errBkgp[1]);
1041 else
1042 errVal = 1.0;
1043 fBackwardpErr.push_back(errVal);
1044 if (fForwardm[i] > 0.0)
1045 errVal = TMath::Sqrt(fForwardm[i]+errBkgm[0]*errBkgm[0]);
1046 else
1047 errVal = 1.0;
1048 fForwardmErr.push_back(errVal);
1049 if (fBackwardm[i] > 0.0)
1050 errVal = TMath::Sqrt(fBackwardm[i]+errBkgm[1]*errBkgm[1]);
1051 else
1052 errVal = 1.0;
1053 fBackwardmErr.push_back(errVal);
1054 }
1055
1056 // subtract background from data
1057 for (UInt_t i=0; i<fForwardp.size(); i++) {
1058 fForwardp[i] -= bkgp[0];
1059 fBackwardp[i] -= bkgp[1];
1060 fForwardm[i] -= bkgm[0];
1061 fBackwardm[i] -= bkgm[1];
1062 }
1063
1064 fRunInfo->SetBkgEstimated(bkgp[0], 0);
1065 fRunInfo->SetBkgEstimated(bkgp[1], 1);
1066 fRunInfo->SetBkgEstimated(bkgm[0], 3);
1067 fRunInfo->SetBkgEstimated(bkgm[1], 4);
1068
1069 // Get estimate for alpha once
1070 Double_t alpha;
1071 alpha = EstimateAlpha();
1072 fRunInfo->SetEstimatedAlpha(alpha);
1073
1074
1075 return true;
1076}
1077
1078//--------------------------------------------------------------------------
1079// PrepareFitData (protected)
1080//--------------------------------------------------------------------------
1093{
1094 // transform raw histo data. This is done the following way (for details see the manual):
1095 // first rebin the data, than calculate the asymmetry
1096
1097 // everything looks fine, hence fill packed forward and backward histo
1098 PRunData forwardpPacked;
1099 PRunData backwardpPacked;
1100 PRunData forwardmPacked;
1101 PRunData backwardmPacked;
1102 Double_t valuep = 0.0;
1103 Double_t errorp = 0.0;
1104 Double_t valuem = 0.0;
1105 Double_t errorm = 0.0;
1106
1107 // forward
1108 for (Int_t i=fGoodBins[0]; i<fGoodBins[1]; i++) {
1109 if (fPacking == 1) {
1110 forwardpPacked.AppendValue(fForwardp[i]);
1111 forwardpPacked.AppendErrorValue(fForwardpErr[i]);
1112 forwardmPacked.AppendValue(fForwardm[i]);
1113 forwardmPacked.AppendErrorValue(fForwardmErr[i]);
1114 } else { // packed data, i.e. fPacking > 1
1115 if (((i-fGoodBins[0]) % fPacking == 0) && (i != fGoodBins[0])) { // fill data
1116 // in order that after rebinning the fit does not need to be redone (important for plots)
1117 // the value is normalize to per bin
1118 valuep /= fPacking;
1119 valuem /= fPacking;
1120 forwardpPacked.AppendValue(valuep);
1121 forwardmPacked.AppendValue(valuem);
1122 if (valuep == 0.0) {
1123 forwardpPacked.AppendErrorValue(1.0);
1124 } else {
1125 forwardpPacked.AppendErrorValue(TMath::Sqrt(errorp)/fPacking);
1126 }
1127 if (valuem == 0.0) {
1128 forwardmPacked.AppendErrorValue(1.0);
1129 } else {
1130 forwardmPacked.AppendErrorValue(TMath::Sqrt(errorm)/fPacking);
1131 }
1132 valuep = 0.0;
1133 errorp = 0.0;
1134 valuem = 0.0;
1135 errorm = 0.0;
1136 }
1137 valuep += fForwardp[i];
1138 errorp += fForwardpErr[i]*fForwardpErr[i];
1139 valuem += fForwardm[i];
1140 errorm += fForwardmErr[i]*fForwardmErr[i];
1141 }
1142 }
1143
1144 // backward
1145 for (Int_t i=fGoodBins[2]; i<fGoodBins[3]; i++) {
1146 if (fPacking == 1) {
1147 backwardpPacked.AppendValue(fBackwardp[i]);
1148 backwardpPacked.AppendErrorValue(fBackwardpErr[i]);
1149 backwardmPacked.AppendValue(fBackwardm[i]);
1150 backwardmPacked.AppendErrorValue(fBackwardmErr[i]);
1151 } else { // packed data, i.e. fPacking > 1
1152 if (((i-fGoodBins[2]) % fPacking == 0) && (i != fGoodBins[2])) { // fill data
1153 // in order that after rebinning the fit does not need to be redone (important for plots)
1154 // the value is normalize to per bin
1155 valuep /= fPacking;
1156 valuem /= fPacking;
1157 backwardpPacked.AppendValue(valuep);
1158 backwardmPacked.AppendValue(valuem);
1159 if (valuep == 0.0) {
1160 backwardpPacked.AppendErrorValue(1.0);
1161 } else {
1162 backwardpPacked.AppendErrorValue(TMath::Sqrt(errorp)/fPacking);
1163 }
1164 if (valuem == 0.0) {
1165 backwardmPacked.AppendErrorValue(1.0);
1166 } else {
1167 backwardmPacked.AppendErrorValue(TMath::Sqrt(errorm)/fPacking);
1168 }
1169 valuep = 0.0;
1170 errorp = 0.0;
1171 valuem = 0.0;
1172 errorm = 0.0;
1173 }
1174 valuep += fBackwardp[i];
1175 errorp += fBackwardpErr[i]*fBackwardpErr[i];
1176 valuem += fBackwardm[i];
1177 errorm += fBackwardmErr[i]*fBackwardmErr[i];
1178 }
1179 }
1180
1181 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1182 UInt_t noOfBins = forwardpPacked.GetValue()->size();
1183 if (forwardpPacked.GetValue()->size() != backwardpPacked.GetValue()->size()) {
1184 if (forwardpPacked.GetValue()->size() > backwardpPacked.GetValue()->size())
1185 noOfBins = backwardpPacked.GetValue()->size();
1186 }
1187
1188 // form asymmetry including error propagation
1189 Double_t asym,error;
1190 Double_t fp, bp, efp, ebp;
1191 Double_t fm, bm, efm, ebm;
1192 // fill data time start, and step
1193 // data start at data_start-t0 shifted by (pack-1)/2
1194 fData.SetDataTimeStart(fTimeResolution*(static_cast<Double_t>(fGoodBins[0])-fT0s[0]+static_cast<Double_t>(fPacking-1)/2.0));
1195 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(fPacking));
1196 for (UInt_t i=0; i<noOfBins; i++) {
1197 // to make the formulae more readable
1198 fp = forwardpPacked.GetValue()->at(i);
1199 bp = backwardpPacked.GetValue()->at(i);
1200 efp = forwardpPacked.GetError()->at(i);
1201 ebp = backwardpPacked.GetError()->at(i);
1202 fm = forwardmPacked.GetValue()->at(i);
1203 bm = backwardmPacked.GetValue()->at(i);
1204 efm = forwardmPacked.GetError()->at(i);
1205 ebm = backwardmPacked.GetError()->at(i);
1206 // check that there are indeed bins
1207 if (fp+bp != 0.0)
1208 asym = (fp-bp) / (fp+bp) - (fm-bm) / (fm+bm);
1209 else
1210 asym = 0.0;
1211 fData.AppendValue(asym);
1212 // calculate the error
1213 if (fp+bp != 0.0)
1214 errorp = 2.0/((fp+bp)*(fp+bp))*TMath::Sqrt(bp*bp*efp*efp+ebp*ebp*fp*fp);
1215 else
1216 errorp = 1.0;
1217 if (fm+bm != 0.0)
1218 errorm = 2.0/((fm+bm)*(fm+bm))*TMath::Sqrt(bm*bm*efm*efm+ebm*ebm*fm*fm);
1219 else
1220 errorp = 1.0;
1221
1222 error = TMath::Sqrt(errorp*errorp+errorm*errorm);
1223 fData.AppendErrorValue(error);
1224 }
1225
1227
1228 // clean up
1229 fForwardp.clear();
1230 fForwardpErr.clear();
1231 fBackwardp.clear();
1232 fBackwardpErr.clear();
1233 fForwardm.clear();
1234 fForwardmErr.clear();
1235 fBackwardm.clear();
1236 fBackwardmErr.clear();
1237
1238 return true;
1239}
1240//--------------------------------------------------------------------------
1254Bool_t PRunAsymmetryBNMR::PrepareViewData(PRawRunData* runData, UInt_t histoNo[2])
1255{
1256 // check if view_packing is wished
1257 Int_t packing = fPacking;
1258 if (fMsrInfo->GetMsrPlotList()->at(0).fViewPacking > 0) {
1259 packing = fMsrInfo->GetMsrPlotList()->at(0).fViewPacking;
1260 }
1261
1262 // feed the parameter vector
1263 std::vector<Double_t> par;
1264 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
1265 for (UInt_t i=0; i<paramList->size(); i++)
1266 par.push_back((*paramList)[i].fValue);
1267
1268 // transform raw histo data. This is done the following way (for details see the manual):
1269 // first rebin the data, than calculate the asymmetry
1270
1271 // first get start data, end data, and t0
1272 Int_t start[2] = {fGoodBins[0], fGoodBins[2]};
1273 Int_t end[2] = {fGoodBins[1], fGoodBins[3]};
1274 Int_t t0[2] = {static_cast<Int_t>(fT0s[0]), static_cast<Int_t>(fT0s[1])};
1275
1276 // check if the data ranges and t0's between forward/backward are compatible
1277 Int_t fgb[2];
1278 if (start[0]-t0[0] != start[1]-t0[1]) { // wrong fgb aligning
1279 if (abs(start[0]-t0[0]) > abs(start[1]-t0[1])) {
1280 fgb[0] = start[0];
1281 fgb[1] = t0[1] + start[0]-t0[0];
1282 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **WARNING** needed to shift backward fgb from ";
1283 std::cerr << start[1] << " to " << fgb[1] << std::endl;
1284 } else {
1285 fgb[0] = t0[0] + start[1]-t0[1];
1286 fgb[1] = start[1];
1287 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **WARNING** needed to shift forward fgb from ";
1288 std::cerr << start[0] << " to " << fgb[0] << std::endl;
1289 }
1290 } else { // fgb aligning is correct
1291 fgb[0] = start[0];
1292 fgb[1] = start[1];
1293 }
1294
1295 Int_t val = fgb[0]-packing*(fgb[0]/packing);
1296 do {
1297 if (fgb[1] - fgb[0] < 0)
1298 val += packing;
1299 } while (val + fgb[1] - fgb[0] < 0);
1300
1301 start[0] = val;
1302 start[1] = val + fgb[1] - fgb[0];
1303
1304 // make sure that there are equal number of rebinned bins in forward and backward
1305 UInt_t noOfBins0 = (runData->GetDataBin(histoNo[0])->size()-start[0])/packing;
1306 UInt_t noOfBins1 = (runData->GetDataBin(histoNo[1])->size()-start[1])/packing;
1307 if (noOfBins0 > noOfBins1)
1308 noOfBins0 = noOfBins1;
1309 end[0] = start[0] + noOfBins0 * packing;
1310 end[1] = start[1] + noOfBins0 * packing;
1311
1312 // check if start, end, and t0 make any sense
1313 // 1st check if start and end are in proper order
1314 for (UInt_t i=0; i<2; i++) {
1315 if (end[i] < start[i]) { // need to swap them
1316 Int_t keep = end[i];
1317 end[i] = start[i];
1318 start[i] = keep;
1319 }
1320 // 2nd check if start is within proper bounds
1321 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1322 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **ERROR** start data bin doesn't make any sense!";
1323 std::cerr << std::endl;
1324 return false;
1325 }
1326 // 3rd check if end is within proper bounds
1327 if ((end[i] < 0) || (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1328 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **ERROR** end data bin doesn't make any sense!";
1329 std::cerr << std::endl;
1330 return false;
1331 }
1332 // 4th check if t0 is within proper bounds
1333 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1334 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **ERROR** t0 data bin doesn't make any sense!";
1335 std::cerr << std::endl;
1336 return false;
1337 }
1338 }
1339
1340 // everything looks fine, hence fill packed forward and backward histo
1341 PRunData forwardpPacked;
1342 PRunData backwardpPacked;
1343 PRunData forwardmPacked;
1344 PRunData backwardmPacked;
1345 Double_t valuep = 0.0;
1346 Double_t errorp = 0.0;
1347 Double_t valuem = 0.0;
1348 Double_t errorm = 0.0;
1349 Double_t value = 0.0;
1350 Double_t error = 0.0;
1351
1352 // forward
1353 for (Int_t i=start[0]; i<end[0]; i++) {
1354 if (packing == 1) {
1355 forwardpPacked.AppendValue(fForwardp[i]);
1356 forwardpPacked.AppendErrorValue(fForwardpErr[i]);
1357 forwardmPacked.AppendValue(fForwardm[i]);
1358 forwardmPacked.AppendErrorValue(fForwardmErr[i]);
1359 } else { // packed data, i.e. packing > 1
1360 if (((i-start[0]) % packing == 0) && (i != start[0])) { // fill data
1361 // in order that after rebinning the fit does not need to be redone (important for plots)
1362 // the value is normalize to per bin
1363 valuep /= packing;
1364 forwardpPacked.AppendValue(valuep);
1365 valuem /= packing;
1366 forwardmPacked.AppendValue(valuem);
1367 if (valuep == 0.0) {
1368 forwardpPacked.AppendErrorValue(1.0);
1369 } else {
1370 forwardpPacked.AppendErrorValue(TMath::Sqrt(errorp)/packing);
1371 }
1372 if (valuem == 0.0) {
1373 forwardmPacked.AppendErrorValue(1.0);
1374 } else {
1375 forwardmPacked.AppendErrorValue(TMath::Sqrt(errorm)/packing);
1376 }
1377 valuep = 0.0;
1378 errorp = 0.0;
1379 valuem = 0.0;
1380 errorm = 0.0;
1381 }
1382 valuep += fForwardp[i];
1383 errorp += fForwardpErr[i]*fForwardpErr[i];
1384 valuem += fForwardm[i];
1385 errorm += fForwardmErr[i]*fForwardmErr[i];
1386 }
1387 }
1388
1389 // backward
1390 for (Int_t i=start[1]; i<end[1]; i++) {
1391 if (packing == 1) {
1392 backwardpPacked.AppendValue(fBackwardp[i]);
1393 backwardpPacked.AppendErrorValue(fBackwardpErr[i]);
1394 backwardmPacked.AppendValue(fBackwardm[i]);
1395 backwardmPacked.AppendErrorValue(fBackwardmErr[i]);
1396 } else { // packed data, i.e. packing > 1
1397 if (((i-start[1]) % packing == 0) && (i != start[1])) { // fill data
1398 // in order that after rebinning the fit does not need to be redone (important for plots)
1399 // the value is normalize to per bin
1400 valuep /= packing;
1401 valuem /= packing;
1402 backwardpPacked.AppendValue(valuep);
1403 backwardmPacked.AppendValue(valuem);
1404 if (valuep == 0.0) {
1405 backwardpPacked.AppendErrorValue(1.0);
1406 } else {
1407 backwardpPacked.AppendErrorValue(TMath::Sqrt(errorp)/packing);
1408 }
1409 if (valuem == 0.0) {
1410 backwardmPacked.AppendErrorValue(1.0);
1411 } else {
1412 backwardmPacked.AppendErrorValue(TMath::Sqrt(errorm)/packing);
1413 }
1414 valuep = 0.0;
1415 errorp = 0.0;
1416 valuem = 0.0;
1417 errorm = 0.0;
1418 }
1419 valuep += fBackwardp[i];
1420 errorp += fBackwardpErr[i]*fBackwardpErr[i];
1421 valuem += fBackwardm[i];
1422 errorm += fBackwardmErr[i]*fBackwardmErr[i];
1423 }
1424 }
1425
1426 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1427 UInt_t noOfBins = forwardpPacked.GetValue()->size();
1428 if (forwardpPacked.GetValue()->size() != backwardpPacked.GetValue()->size()) {
1429 if (forwardpPacked.GetValue()->size() > backwardpPacked.GetValue()->size())
1430 noOfBins = backwardpPacked.GetValue()->size();
1431 }
1432
1433 // form asymmetry including error propagation
1434 Double_t asym;
1435 Double_t fp, bp, efp, ebp, alpha, beta = 1.0;
1436 Double_t fm, bm, efm, ebm;
1437 // set data time start, and step
1438 // data start at data_start-t0
1439 fData.SetDataTimeStart(fTimeResolution*(static_cast<Double_t>(start[0])-t0[0]+static_cast<Double_t>(packing-1)/2.0));
1440 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(packing));
1441
1442 // Get estimate for alpha once
1443 alpha = EstimateAlpha();
1444
1445 // get the proper alpha and beta
1446 switch (fAlphaBetaTag) {
1447 case 1: // alpha == 1, beta == 1
1448 alpha = 1.0;
1449 beta = 1.0;
1450 break;
1451 case 2: // alpha != 1, beta == 1
1452 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1453 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1454 } else { // alpha is function
1455 // get function number
1456 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1457 // evaluate function
1458 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1459 }
1460 beta = 1.0;
1461 break;
1462 case 3: // alpha == 1, beta != 1
1463 alpha = 1.0;
1464 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1465 beta = par[fRunInfo->GetBetaParamNo()-1];
1466 } else { // beta is a function
1467 // get function number
1468 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1469 // evaluate function
1470 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1471 }
1472 break;
1473 case 4: // alpha != 1, beta != 1
1474 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1475 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1476 } else { // alpha is function
1477 // get function number
1478 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1479 // evaluate function
1480 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1481 }
1482 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1483 beta = par[fRunInfo->GetBetaParamNo()-1];
1484 } else { // beta is a function
1485 // get function number
1486 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1487 // evaluate function
1488 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1489 }
1490 break;
1491 case 5: // alpha ?? , beta == 1
1492 // use estimated value
1493 beta = 1.0;
1494 break;
1495 case 6: // alpha ??, beta != 1
1496 // use estimated value
1497 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1498 beta = par[fRunInfo->GetBetaParamNo()-1];
1499 } else { // beta is a function
1500 // get function number
1501 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1502 // evaluate function
1503 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1504 }
1505 break;
1506 default:
1507 break;
1508 }
1509
1510 for (UInt_t i=0; i<forwardpPacked.GetValue()->size(); i++) {
1511 // to make the formulae more readable
1512 fp = forwardpPacked.GetValue()->at(i);
1513 bp = backwardpPacked.GetValue()->at(i);
1514 efp = forwardpPacked.GetError()->at(i);
1515 ebp = backwardpPacked.GetError()->at(i);
1516 fm = forwardmPacked.GetValue()->at(i);
1517 bm = backwardmPacked.GetValue()->at(i);
1518 efm = forwardmPacked.GetError()->at(i);
1519 ebm = backwardmPacked.GetError()->at(i);
1520 // check that there are indeed bins
1521 if (fp+bp != 0.0)
1522 asym = (alpha*fp-bp) / (alpha*beta*fp+bp) - (alpha*fm-bm) / (alpha*beta*fm+bm);
1523 else
1524 asym = 0.0;
1525 fData.AppendValue(asym);
1526 // calculate the error
1527 if (fp+bp != 0.0)
1528 errorp = 2.0/((fp+bp)*(fp+bp))*TMath::Sqrt(bp*bp*efp*efp+ebp*ebp*fp*fp);
1529 else
1530 errorp = 1.0;
1531 if (fm+bm != 0.0)
1532 errorm = 2.0/((fm+bm)*(fm+bm))*TMath::Sqrt(bm*bm*efm*efm+ebm*ebm*fm*fm);
1533 else
1534 errorm = 1.0;
1535 error = TMath::Sqrt(errorp*errorp+errorm*errorm);
1536 fData.AppendErrorValue(error);
1537 }
1538
1540
1541 // clean up
1542 fForwardp.clear();
1543 fForwardpErr.clear();
1544 fBackwardp.clear();
1545 fBackwardpErr.clear();
1546 fForwardm.clear();
1547 fForwardmErr.clear();
1548 fBackwardm.clear();
1549 fBackwardmErr.clear();
1550
1551 // fill theory vector for kView
1552 // calculate functions
1553 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
1554 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
1555 }
1556
1557 // calculate theory
1558 UInt_t size = runData->GetDataBin(histoNo[0])->size();
1559
1560 Int_t factor = 8; // 8 times more points for the theory (if fTheoAsData == false)
1561 fData.SetTheoryTimeStart(fData.GetDataTimeStart());
1562 if (fTheoAsData) { // calculate theory only at the data points
1563 fData.SetTheoryTimeStep(fData.GetDataTimeStep());
1564 } else {
1565 // finer binning for the theory (8 times as many points = factor)
1566 size *= factor;
1567 fData.SetTheoryTimeStep(fData.GetDataTimeStep()/(Double_t)factor);
1568 }
1569
1570 Double_t time;
1571 for (UInt_t i=0; i<size; i++) {
1572 time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
1573 value = fTheory->Func(time, par, fFuncValues);
1574 if (fabs(value) > 10.0) { // dirty hack needs to be fixed!!
1575 value = 0.0;
1576 }
1577 fData.AppendTheoryValue(value);
1578 }
1579
1580 // clean up
1581 par.clear();
1582
1583 return true;
1584}
1585
1586
1587//--------------------------------------------------------------------------
1588// GetProperT0 (private)
1589//--------------------------------------------------------------------------
1608Bool_t PRunAsymmetryBNMR::GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHistoNo, PUIntVector &backwardHistoNo)
1609{
1610 // feed all T0's
1611 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1612 fT0s.clear();
1613 // this strange fT0 size estimate is needed in case #forw histos != #back histos
1614 size_t size = 2*forwardHistoNo.size();
1615 if (backwardHistoNo.size() > forwardHistoNo.size())
1616 size = 2*backwardHistoNo.size();
1617 fT0s.resize(size);
1618 for (UInt_t i=0; i<fT0s.size(); i++) {
1619 fT0s[i] = -1.0;
1620 }
1621
1622 // fill in the T0's from the msr-file (if present)
1623 for (UInt_t i=0; i<fRunInfo->GetT0BinSize(); i++) {
1624 fT0s[i] = fRunInfo->GetT0Bin(i);
1625 }
1626
1627 // fill in the missing T0's from the GLOBAL block section (if present)
1628 for (UInt_t i=0; i<globalBlock->GetT0BinSize(); i++) {
1629 if (fT0s[i] == -1) { // i.e. not given in the RUN block section
1630 fT0s[i] = globalBlock->GetT0Bin(i);
1631 }
1632 }
1633
1634 // fill in the missing T0's from the data file, if not already present in the msr-file
1635 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1636 if (fT0s[2*i] == -1.0) // i.e. not present in the msr-file, try the data file
1637 if (runData->GetT0Bin(forwardHistoNo[i]) > 0.0) {
1638 fT0s[2*i] = runData->GetT0Bin(forwardHistoNo[i]);
1639 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1640 }
1641 }
1642 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1643 if (fT0s[2*i+1] == -1.0) // i.e. not present in the msr-file, try the data file
1644 if (runData->GetT0Bin(backwardHistoNo[i]) > 0.0) {
1645 fT0s[2*i+1] = runData->GetT0Bin(backwardHistoNo[i]);
1646 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1647 }
1648 }
1649
1650 // fill in the T0's gaps, i.e. in case the T0's are NEITHER in the msr-file and NOR in the data file
1651 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1652 if (fT0s[2*i] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1653 fT0s[2*i] = runData->GetT0BinEstimated(forwardHistoNo[i]);
1654 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1655
1656 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1657 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1658 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << runData->GetT0BinEstimated(forwardHistoNo[i]);
1659 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1660 std::cerr << std::endl;
1661 }
1662 }
1663 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1664 if (fT0s[2*i+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1665 fT0s[2*i+1] = runData->GetT0BinEstimated(backwardHistoNo[i]);
1666 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1667
1668 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1669 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1670 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[i]);
1671 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1672 std::cerr << std::endl;
1673 }
1674 }
1675
1676 // check if t0 is within proper bounds
1677 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1678 if ((fT0s[2*i] < 0) || (fT0s[2*i] > static_cast<Int_t>(runData->GetDataBin(forwardHistoNo[i])->size()))) {
1679 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **ERROR** t0 data bin (" << fT0s[2*i] << ") doesn't make any sense!";
1680 std::cerr << std::endl << ">> forwardHistoNo " << forwardHistoNo[i];
1681 std::cerr << std::endl;
1682 return false;
1683 }
1684 }
1685 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1686 if ((fT0s[2*i+1] < 0) || (fT0s[2*i+1] > static_cast<Int_t>(runData->GetDataBin(backwardHistoNo[i])->size()))) {
1687 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **ERROR** t0 data bin (" << fT0s[2*i+1] << ") doesn't make any sense!";
1688 std::cerr << std::endl << ">> backwardHistoNo " << backwardHistoNo[i];
1689 std::cerr << std::endl;
1690 return false;
1691 }
1692 }
1693
1694 // check if addrun's are present, and if yes add the necessary t0's
1695 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
1696 PRawRunData *addRunData;
1697 fAddT0s.resize(fRunInfo->GetRunNameSize()-1); // resize to the number of addruns
1698 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
1699 // get run to be added to the main one
1700 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
1701 if (addRunData == 0) { // couldn't get run
1702 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
1703 std::cerr << std::endl;
1704 return false;
1705 }
1706
1707 // feed all T0's
1708 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1709 fAddT0s[i-1].clear();
1710 fAddT0s[i-1].resize(2*forwardHistoNo.size());
1711 for (UInt_t j=0; j<fAddT0s[i-1].size(); j++) {
1712 fAddT0s[i-1][j] = -1.0;
1713 }
1714
1715 // fill in the T0's from the msr-file (if present)
1716 for (Int_t j=0; j<fRunInfo->GetAddT0BinSize(i-1); j++) {
1717 fAddT0s[i-1][j] = fRunInfo->GetAddT0Bin(i-1, j);
1718 }
1719
1720 // fill in the T0's from the data file, if not already present in the msr-file
1721 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1722 if (fAddT0s[i-1][2*j] == -1.0) // i.e. not present in the msr-file, try the data file
1723 if (addRunData->GetT0Bin(forwardHistoNo[j]) > 0.0) {
1724 fAddT0s[i-1][2*j] = addRunData->GetT0Bin(forwardHistoNo[j]);
1725 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1726 }
1727 }
1728 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1729 if (fAddT0s[i-1][2*j+1] == -1.0) // i.e. not present in the msr-file, try the data file
1730 if (addRunData->GetT0Bin(backwardHistoNo[j]) > 0.0) {
1731 fAddT0s[i-1][2*j+1] = addRunData->GetT0Bin(backwardHistoNo[j]);
1732 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1733 }
1734 }
1735
1736 // fill in the T0's gaps, i.e. in case the T0's are NOT in the msr-file and NOT in the data file
1737 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1738 if (fAddT0s[i-1][2*j] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1739 fAddT0s[i-1][2*j] = addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1740 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1741
1742 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1743 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1744 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1745 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1746 std::cerr << std::endl;
1747 }
1748 }
1749 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1750 if (fAddT0s[i-1][2*j+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1751 fAddT0s[i-1][2*j+1] = addRunData->GetT0BinEstimated(backwardHistoNo[j]);
1752 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1753
1754 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1755 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1756 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[j]);
1757 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1758 std::cerr << std::endl;
1759 }
1760 }
1761 }
1762 }
1763
1764 return true;
1765}
1766
1767//--------------------------------------------------------------------------
1768// GetProperDataRange (private)
1769//--------------------------------------------------------------------------
1783Bool_t PRunAsymmetryBNMR::GetProperDataRange(PRawRunData* runData, UInt_t histoNo[2])
1784{
1785 // first get start/end data
1786 Int_t start[2] = {fRunInfo->GetDataRange(0), fRunInfo->GetDataRange(2)};
1787 Int_t end[2] = {fRunInfo->GetDataRange(1), fRunInfo->GetDataRange(3)};
1788 // check if data range has been provided in the RUN block. If not, try the GLOBAL block
1789 if (start[0] == -1) {
1790 start[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(0);
1791 }
1792 if (start[1] == -1) {
1793 start[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(2);
1794 }
1795 if (end[0] == -1) {
1796 end[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(1);
1797 }
1798 if (end[1] == -1) {
1799 end[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(3);
1800 }
1801
1802 Double_t t0[2] = {fT0s[0], fT0s[1]};
1803 Int_t offset = static_cast<Int_t>((10.0e-3/fTimeResolution)); // needed in case first good bin is not given, default = 10ns
1804
1805 // check if data range has been provided, and if not try to estimate them
1806 if (start[0] < 0) {
1807 start[0] = static_cast<Int_t>(t0[0])+offset;
1808 fRunInfo->SetDataRange(start[0], 0);
1809 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[0] << ".";
1810 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS DOES MAKE ANY SENSE.";
1811 std::cerr << std::endl;
1812 }
1813 if (start[1] < 0) {
1814 start[1] = static_cast<Int_t>(t0[1])+offset;
1815 fRunInfo->SetDataRange(start[1], 2);
1816 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[1] << ".";
1817 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS DOES MAKE ANY SENSE.";
1818 std::cerr << std::endl;
1819 }
1820 if (end[0] < 0) {
1821 end[0] = runData->GetDataBin(histoNo[0])->size();
1822 fRunInfo->SetDataRange(end[0], 1);
1823 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range end = " << end[0] << ".";
1824 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS DOES MAKE ANY SENSE.";
1825 std::cerr << std::endl;
1826 }
1827 if (end[1] < 0) {
1828 end[1] = runData->GetDataBin(histoNo[1])->size();
1829 fRunInfo->SetDataRange(end[1], 3);
1830 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range end = " << end[1] << ".";
1831 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS DOES MAKE ANY SENSE.";
1832 std::cerr << std::endl;
1833 }
1834
1835 // check if start, end, and t0 make any sense
1836 // 1st check if start and end are in proper order
1837 for (UInt_t i=0; i<2; i++) {
1838 if (end[i] < start[i]) { // need to swap them
1839 Int_t keep = end[i];
1840 end[i] = start[i];
1841 start[i] = keep;
1842 }
1843 // 2nd check if start is within proper bounds
1844 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1845 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **ERROR** start data bin doesn't make any sense!";
1846 std::cerr << std::endl;
1847 return false;
1848 }
1849 // 3rd check if end is within proper bounds
1850 if (end[i] < 0) {
1851 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **ERROR** end data bin (" << end[i] << ") doesn't make any sense!";
1852 std::cerr << std::endl;
1853 return false;
1854 }
1855 if (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())) {
1856 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** end data bin (" << end[i] << ") > histo length (" << static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()) << ").";
1857 std::cerr << std::endl << ">> Will set end = (histo length - 1). Consider to change it in the msr-file." << std::endl;
1858 std::cerr << std::endl;
1859 end[i] = static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())-1;
1860 }
1861 // 4th check if t0 is within proper bounds
1862 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1863 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **ERROR** t0 data bin doesn't make any sense!";
1864 std::cerr << std::endl;
1865 return false;
1866 }
1867 }
1868
1869 // check that start-t0 is the same for forward as for backward, otherwise take max(start[i]-t0[i])
1870 if (fabs(static_cast<Double_t>(start[0])-t0[0]) > fabs(static_cast<Double_t>(start[1])-t0[1])){
1871 start[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(start[0]) - t0[0]);
1872 end[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(end[0]) - t0[0]);
1873 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange **WARNING** needed to shift backward data range.";
1874 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(2) << ", " << fRunInfo->GetDataRange(3);
1875 std::cerr << std::endl << ">> used : " << start[1] << ", " << end[1];
1876 std::cerr << std::endl;
1877 }
1878 if (fabs(static_cast<Double_t>(start[0])-t0[0]) < fabs(static_cast<Double_t>(start[1])-t0[1])){
1879 start[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(start[1]) - t0[1]);
1880 end[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(end[1]) - t0[1]);
1881 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange **WARNING** needed to shift forward data range.";
1882 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(0) << ", " << fRunInfo->GetDataRange(1);
1883 std::cerr << std::endl << ">> used : " << start[0] << ", " << end[0];
1884 std::cerr << std::endl;
1885 }
1886
1887 // keep good bins for potential latter use
1888 fGoodBins[0] = start[0];
1889 fGoodBins[1] = end[0];
1890 fGoodBins[2] = start[1];
1891 fGoodBins[3] = end[1];
1892
1893 return true;
1894}
1895
1896//--------------------------------------------------------------------------
1897// GetProperFitRange (private)
1898//--------------------------------------------------------------------------
1916{
1917 // set fit start/end time; first check RUN Block
1918 fFitStartTime = fRunInfo->GetFitRange(0);
1919 fFitEndTime = fRunInfo->GetFitRange(1);
1920 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1921 if (fRunInfo->IsFitRangeInBin()) {
1922 fFitStartTime = (fGoodBins[0] + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1923 fFitEndTime = (fGoodBins[1] - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1924 // write these times back into the data structure. This way it is available when writting the log-file
1925 fRunInfo->SetFitRange(fFitStartTime, 0);
1926 fRunInfo->SetFitRange(fFitEndTime, 1);
1927 }
1928 if (fFitStartTime == PMUSR_UNDEFINED) { // fit start/end NOT found in the RUN block, check GLOBAL block
1929 fFitStartTime = globalBlock->GetFitRange(0);
1930 fFitEndTime = globalBlock->GetFitRange(1);
1931 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1932 if (globalBlock->IsFitRangeInBin()) {
1933 fFitStartTime = (fGoodBins[0] + globalBlock->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1934 fFitEndTime = (fGoodBins[1] - globalBlock->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1935 // write these times back into the data structure. This way it is available when writting the log-file
1936 globalBlock->SetFitRange(fFitStartTime, 0);
1937 globalBlock->SetFitRange(fFitEndTime, 1);
1938 }
1939 }
1941 fFitStartTime = (fGoodBins[0] - fT0s[0]) * fTimeResolution; // (fgb-t0)*dt
1942 fFitEndTime = (fGoodBins[1] - fT0s[0]) * fTimeResolution; // (lgb-t0)*dt
1943 std::cerr << ">> PRunSingleHisto::GetProperFitRange(): **WARNING** Couldn't get fit start/end time!" << std::endl;
1944 std::cerr << ">> Will set it to fgb/lgb which given in time is: " << fFitStartTime << "..." << fFitEndTime << " (usec)" << std::endl;
1945 }
1946}
1947
1948
1949//--------------------------------------------------------------------------
1950// EstimateAlpha (private)
1951//--------------------------------------------------------------------------
1966{
1967
1968 Double_t SumF[2] = {0.0, 0.0};
1969 Double_t SumB[2] = {0.0, 0.0};
1970 Double_t alpha = 1;
1971
1972
1973 // forward
1974 for (Int_t i=0; i<fForwardp.size(); i++) {
1975 SumF[0] += fForwardp[i];
1976 SumF[1] += fForwardm[i];
1977 }
1978
1979 // backward
1980 for (Int_t i=0; i<fBackwardp.size(); i++) {
1981 SumB[0] += fBackwardp[i];
1982 SumB[1] += fBackwardm[i];
1983 }
1984
1985 // Spit out estimated alpha value from total counts (Bp+Bm)/(Fp+Fm)
1986 if ( (SumF[0]+SumF[1]) == 0) {
1987 alpha = 1;
1988 } else {
1989 alpha = (SumB[0]+SumB[1])/(SumF[0]+SumF[1]);
1990 }
1991 std::cout << std::endl << ">> PRunAsymmetryBNMR::EstimateAlpha(): alpha estimate=" << alpha << std::endl;
1992
1993 return alpha;
1994}
std::vector< UInt_t > PUIntVector
Definition PMusr.h:375
#define ACCEL_PERIOD_TRIUMF
TRIUMF accelerator cycle: 43.37 ns.
Definition PMusr.h:156
EPMusrHandleTag
Definition PMusr.h:427
@ kFit
Fitting mode - perform least-squares fit to data.
Definition PMusr.h:429
@ kView
Viewing mode - display data and theory without fitting.
Definition PMusr.h:430
#define PMUSR_UNDEFINED
Definition PMusr.h:177
#define MSR_PARAM_FUN_OFFSET
Offset added to function indices for parameter parsing.
Definition PMusr.h:265
std::vector< PMsrParamStructure > PMsrParamList
Definition PMusr.h:1040
#define ACCEL_PERIOD_PSI
PSI (Paul Scherrer Institute) accelerator cycle: 19.75 ns.
Definition PMusr.h:154
#define ACCEL_PERIOD_RAL
RAL (Rutherford Appleton Lab) - pulsed beam.
Definition PMusr.h:158
if(xmlFile.is_open())
return status
virtual void SetFitRange(Double_t dval, UInt_t idx)
Definition PMusr.cpp:1171
virtual Double_t GetFitRange(UInt_t idx)
Definition PMusr.cpp:1154
virtual UInt_t GetT0BinSize()
Definition PMusr.h:1068
virtual Bool_t IsFitRangeInBin()
Definition PMusr.h:1073
virtual Int_t GetFitRangeOffset(UInt_t idx)
Definition PMusr.cpp:1191
virtual Double_t GetT0Bin(UInt_t idx=0)
Definition PMusr.cpp:1038
MSR file parser and manager for the musrfit framework.
virtual PMsrParamList * GetMsrParamList()
Returns pointer to fit parameter list.
virtual const PDoubleVector * GetDataBin(const UInt_t histoNo)
Definition PMusr.h:896
virtual const Double_t GetT0Bin(const UInt_t histoNo)
Definition PMusr.h:884
virtual const Double_t GetTimeResolution()
Definition PMusr.h:882
virtual const Bool_t IsPresent(UInt_t histoNo)
Definition PMusr.h:883
virtual const UInt_t GetNoOfTemperatures()
Definition PMusr.h:874
virtual const Double_t GetField()
Definition PMusr.h:873
virtual const Double_t GetEnergy()
Definition PMusr.h:878
virtual const Double_t GetT0BinEstimated(const UInt_t histoNo)
Definition PMusr.h:885
virtual const PDoublePairVector * GetTemperature() const
Definition PMusr.h:875
virtual Bool_t GetProperT0(PRawRunData *runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHisto, PUIntVector &backwardHistoNo)
Retrieves proper t0 values for all histograms.
UInt_t fAlphaBetaTag
Tag indicating α/β configuration: 1=both unity, 2=α free/β unity, 3=α unity/β free,...
Bool_t SubtractEstimatedBkg()
Estimates and subtracts background from histograms.
Bool_t SubtractFixBkg()
Subtracts fixed background from histograms.
virtual ~PRunAsymmetryBNMR()
Destructor.
virtual UInt_t GetNoOfFitBins()
Returns the number of bins used in the fit.
virtual Bool_t PrepareViewData(PRawRunData *runData, UInt_t histoNo[2])
Prepares data for viewing/plotting.
UInt_t fNoOfFitBins
Number of bins included in the fit.
PDoubleVector fBackwardmErr
Negative helicity backward histogram errors.
virtual Double_t EstimateAlpha()
Estimates α parameter from data.
virtual Double_t CalcChiSquareExpected(const std::vector< Double_t > &par)
Calculates expected chi-square (for statistical analysis).
virtual Bool_t PrepareFitData()
Prepares data specifically for fitting.
PDoubleVector fForwardm
Negative helicity forward histogram data.
virtual Bool_t PrepareData()
Prepares all data for fitting or viewing.
PDoubleVector fForwardpErr
Positive helicity forward histogram errors.
Bool_t fTheoAsData
If true, theory calculated only at data points; if false, extra points for nicer Fourier transforms.
Int_t fGoodBins[4]
Good bin boundaries: [0]=forward first, [1]=forward last, [2]=backward first, [3]=backward last.
Int_t fStartTimeBin
First bin index for fitting.
virtual void CalcNoOfFitBins()
Calculates the number of bins to be fitted.
PDoubleVector fBackwardpErr
Positive helicity backward histogram errors.
virtual void CalcTheory()
Calculates theoretical asymmetry function.
virtual Double_t CalcMaxLikelihood(const std::vector< Double_t > &par)
Calculates maximum likelihood estimator.
PDoubleVector fForwardmErr
Negative helicity forward histogram errors.
PDoubleVector fBackwardp
Positive helicity backward histogram data.
virtual Double_t CalcChiSquare(const std::vector< Double_t > &par)
Calculates chi-square for the current parameter set.
virtual void SetFitRangeBin(const TString fitRange)
Sets the fit range in bins.
PDoubleVector fBackwardm
Negative helicity backward histogram data.
Int_t fEndTimeBin
Last bin index for fitting.
PRunAsymmetryBNMR()
Default constructor.
virtual void GetProperFitRange(PMsrGlobalBlock *globalBlock)
Determines the proper fit range from global block.
PDoubleVector fForwardp
Positive helicity forward histogram data.
virtual Bool_t GetProperDataRange(PRawRunData *runData, UInt_t histoNo[2])
Retrieves proper data range for histograms.
Int_t fPacking
Bin packing factor from RUN or GLOBAL block.
Double_t fTimeResolution
Time resolution of raw histogram data in microseconds (μs), e.g., 0.01953125 μs for PSI GPS.
Definition PRunBase.h:276
Bool_t fValid
Flag indicating if run object initialized successfully; false if any error occurred.
Definition PRunBase.h:266
Double_t fFitEndTime
Fit range end time in microseconds (μs) relative to t0.
Definition PRunBase.h:282
PDoubleVector fFuncValues
Cached values of user-defined functions from FUNCTIONS block, evaluated at current parameters.
Definition PRunBase.h:284
PMsrHandler * fMsrInfo
Pointer to MSR file handler (owned externally, not deleted here)
Definition PRunBase.h:271
PMetaData fMetaData
Experimental metadata extracted from data file header (magnetic field, temperature,...
Definition PRunBase.h:277
std::unique_ptr< PTheory > fTheory
Theory function evaluator (smart pointer, automatically deleted)
Definition PRunBase.h:285
std::vector< PDoubleVector > fAddT0s
Time-zero bin values for additional runs to be added to main run.
Definition PRunBase.h:279
EPMusrHandleTag fHandleTag
Operation mode: kFit (fitting), kView (display only), kEmpty (uninitialized)
Definition PRunBase.h:268
PRunData fData
Processed data container: background-corrected, packed, with theory values.
Definition PRunBase.h:275
PRunDataHandler * fRawData
Pointer to raw data handler (owned externally, not deleted here)
Definition PRunBase.h:273
PDoubleVector fT0s
Time-zero bin values for all histograms in this run (forward, backward, etc.)
Definition PRunBase.h:278
PRunBase()
Default constructor.
Definition PRunBase.cpp:52
Int_t fRunNo
Run number (0-based index in MSR file RUN blocks)
Definition PRunBase.h:270
PMsrRunBlock * fRunInfo
Pointer to this run's RUN block settings within fMsrInfo.
Definition PRunBase.h:272
Double_t fFitStartTime
Fit range start time in microseconds (μs) relative to t0.
Definition PRunBase.h:281
Raw data file reader and format converter for μSR data.
virtual void AppendErrorValue(Double_t dval)
Definition PMusr.h:511
virtual void AppendValue(Double_t dval)
Definition PMusr.h:508
virtual const PDoubleVector * GetValue()
Returns pointer to data value vector (asymmetry, counts, or y-data)
Definition PMusr.h:482
virtual const PDoubleVector * GetError()
Returns pointer to data error vector (statistical uncertainties)
Definition PMusr.h:484
static std::vector< std::string > Split(const std::string &str, const std::string &delimiters)