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() < 0) || (fRunInfo->GetAlphaParamNo() > (Int_t)param->size())) { // check if alpha parameter is within proper bounds
140 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PRunAsymmetryBNMR(): **ERROR** alpha parameter no = " << fRunInfo->GetAlphaParamNo();
141 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
142 std::cerr << std::endl;
143 fValid = false;
144 return;
145 } else { // check if alpha is fixed
146 if (((*param)[fRunInfo->GetAlphaParamNo()-1].fStep == 0.0) &&
147 ((*param)[fRunInfo->GetAlphaParamNo()-1].fValue == 1.0))
148 alphaFixedToOne = true;
149 }
150
151 // check if beta is given
152 Bool_t betaFixedToOne = false;
153 if (fRunInfo->GetBetaParamNo() == -1) { // no beta given hence assuming beta == 1
154 betaFixedToOne = true;
155 } else if ((fRunInfo->GetBetaParamNo() < 0) || (fRunInfo->GetBetaParamNo() > (Int_t)param->size())) { // check if beta parameter is within proper bounds
156 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PRunAsymmetryBNMR(): **ERROR** beta parameter no = " << fRunInfo->GetBetaParamNo();
157 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
158 std::cerr << std::endl;
159 fValid = false;
160 return;
161 } else { // check if beta is fixed
162 if (((*param)[fRunInfo->GetBetaParamNo()-1].fStep == 0.0) &&
163 ((*param)[fRunInfo->GetBetaParamNo()-1].fValue == 1.0))
164 betaFixedToOne = true;
165 }
166
167 // set fAlphaBetaTag
168 if (alphaFixedToOne && betaFixedToOne) // alpha == 1, beta == 1
169 fAlphaBetaTag = 1;
170 else if (!alphaFixedToOne && betaFixedToOne & !alphaSetDefault) // alpha != 1, beta == 1
171 fAlphaBetaTag = 2;
172 else if (alphaFixedToOne && !betaFixedToOne) // alpha == 1, beta != 1
173 fAlphaBetaTag = 3;
174 else if (!alphaFixedToOne && betaFixedToOne & alphaSetDefault) // alpha ??, beta == 1
175 fAlphaBetaTag = 5;
176 else if (!alphaFixedToOne && !betaFixedToOne & alphaSetDefault) // alpha ??, beta != 1
177 fAlphaBetaTag = 6;
178 else
179 fAlphaBetaTag = 4;
180
181 // calculate fData
182 if (!PrepareData())
183 fValid = false;
184}
185
186//--------------------------------------------------------------------------
187// Destructor
188//--------------------------------------------------------------------------
196{
197 fForwardp.clear();
198 fForwardpErr.clear();
199 fBackwardp.clear();
200 fBackwardpErr.clear();
201
202 fForwardm.clear();
203 fForwardmErr.clear();
204 fBackwardm.clear();
205 fBackwardmErr.clear();
206}
207
208//--------------------------------------------------------------------------
209// CalcChiSquare (public)
210//--------------------------------------------------------------------------
227Double_t PRunAsymmetryBNMR::CalcChiSquare(const std::vector<Double_t>& par)
228{
229 Double_t chisq = 0.0;
230 Double_t diff = 0.0;
231 Double_t asymFcnValue = 0.0;
232 Double_t a, b, f;
233
234 // calculate functions
235 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
236 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
237 }
238
239 // calculate chi square
240 Double_t time(1.0),alphaest;
241 Int_t i;
242
243 // determine alpha/beta
244 alphaest = fRunInfo->GetEstimatedAlpha();
245 switch (fAlphaBetaTag) {
246 case 1: // alpha == 1, beta == 1
247 a = 1.0;
248 b = 1.0;
249 break;
250 case 2: // alpha != 1, beta == 1
251 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
252 a = par[fRunInfo->GetAlphaParamNo()-1];
253 } else { // alpha is function
254 // get function number
255 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
256 // evaluate function
257 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
258 }
259 b = 1.0;
260 break;
261 case 3: // alpha == 1, beta != 1
262 a = 1.0;
263 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
264 b = par[fRunInfo->GetBetaParamNo()-1];
265 } else { // beta is a function
266 // get function number
267 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
268 // evaluate function
269 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
270 }
271 break;
272 case 4: // alpha != 1, beta != 1
273 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
274 a = par[fRunInfo->GetAlphaParamNo()-1];
275 } else { // alpha is function
276 // get function number
277 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
278 // evaluate function
279 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
280 }
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 5: // alpha ?? , beta == 1
291 a = alphaest;
292 b = 1.0;
293 break;
294 case 6: // alpha ??, beta != 1
295 a = alphaest;
296 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
297 b = par[fRunInfo->GetBetaParamNo()-1];
298 } else { // beta is a function
299 // get function number
300 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
301 // evaluate function
302 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
303 }
304 break;
305 default:
306 a = 1.0;
307 b = 1.0;
308 break;
309 }
310
311 // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
312 // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
313 // for a given set of parameters---which should be done outside of the parallelized loop.
314 // For all other functions it means a tiny and acceptable overhead.
315 asymFcnValue = fTheory->Func(time, par, fFuncValues);
316
317 #ifdef HAVE_GOMP
318 Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
319 if (chunk < 10)
320 chunk = 10;
321 #pragma omp parallel for default(shared) private(i,time,diff,asymFcnValue,f) schedule(dynamic,chunk) reduction(+:chisq)
322 #endif
323 for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
324 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
325 f = fTheory->Func(time, par, fFuncValues)/2.0;
326 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));
327 diff = fData.GetValue()->at(i) - asymFcnValue;
328 chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
329 }
330
331 return chisq;
332}
333
334//--------------------------------------------------------------------------
335// CalcChiSquareExpected (public)
336//--------------------------------------------------------------------------
346Double_t PRunAsymmetryBNMR::CalcChiSquareExpected(const std::vector<Double_t>& par)
347{
348 return 0.0;
349}
350
351//--------------------------------------------------------------------------
352// CalcMaxLikelihood (public)
353//--------------------------------------------------------------------------
363Double_t PRunAsymmetryBNMR::CalcMaxLikelihood(const std::vector<Double_t>& par)
364{
365 std::cout << std::endl << "PRunAsymmetryBNMR::CalcMaxLikelihood(): not implemented yet ..." << std::endl;
366
367 return 1.0;
368}
369
370//--------------------------------------------------------------------------
371// GetNoOfFitBins (public)
372//--------------------------------------------------------------------------
381{
383
384 return fNoOfFitBins;
385}
386
387//--------------------------------------------------------------------------
388// SetFitRangeBin (public)
389//--------------------------------------------------------------------------
408void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange)
409{
410 TString str;
411 Ssiz_t idx = -1;
412 Int_t offset = 0;
413
414 std::vector<std::string> tok = PStringUtils::Split(fitRange.Data(), " \t");
415
416 if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1
417 // handle fgb+n0 entry
418 str = tok[1];
419 // check if there is an offset present
420 idx = str.First("+");
421 if (idx != -1) { // offset present
422 str.Remove(0, idx+1);
423 if (str.IsFloat()) // if str is a valid number, convert is to an integer
424 offset = str.Atoi();
425 }
426 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
427
428 // handle lgb-n1 entry
429 str = tok[2];
430 // check if there is an offset present
431 idx = str.First("-");
432 if (idx != -1) { // offset present
433 str.Remove(0, idx+1);
434 if (str.IsFloat()) // if str is a valid number, convert is to an integer
435 offset = str.Atoi();
436 }
437 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
438 } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
439 UInt_t pos = 2*(fRunNo+1)-1;
440
441 if (pos + 1 >= tok.size()) {
442 std::cerr << std::endl << ">> PRunAsymmetryBNMR::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
443 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
444 } else {
445 // handle fgb+n0 entry
446 str = tok[pos];
447 // check if there is an offset present
448 idx = str.First("+");
449 if (idx != -1) { // offset present
450 str.Remove(0, idx+1);
451 if (str.IsFloat()) // if str is a valid number, convert is to an integer
452 offset = str.Atoi();
453 }
454 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
455
456 // handle lgb-n1 entry
457 str = tok[pos+1];
458 // check if there is an offset present
459 idx = str.First("-");
460 if (idx != -1) { // offset present
461 str.Remove(0, idx+1);
462 if (str.IsFloat()) // if str is a valid number, convert is to an integer
463 offset = str.Atoi();
464 }
465 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
466 }
467 } else { // error
468 std::cerr << std::endl << ">> PRunAsymmetryBNMR::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
469 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
470 }
471}
472
473//--------------------------------------------------------------------------
474// CalcNoOfFitBins (public)
475//--------------------------------------------------------------------------
484{
485 // In order not having to loop over all bins and to stay consistent with the chisq method, calculate the start and end bins explicitly
486 fStartTimeBin = static_cast<Int_t>(ceil((fFitStartTime - fData.GetDataTimeStart())/fData.GetDataTimeStep()));
487 if (fStartTimeBin < 0)
488 fStartTimeBin = 0;
489 fEndTimeBin = static_cast<Int_t>(floor((fFitEndTime - fData.GetDataTimeStart())/fData.GetDataTimeStep())) + 1;
490 if (fEndTimeBin > static_cast<Int_t>(fData.GetValue()->size()))
491 fEndTimeBin = fData.GetValue()->size();
492
494 fNoOfFitBins = static_cast<UInt_t>(fEndTimeBin - fStartTimeBin);
495 else
496 fNoOfFitBins = 0;
497}
498
499//--------------------------------------------------------------------------
500// CalcTheory (protected)
501//--------------------------------------------------------------------------
518{
519 // feed the parameter vector
520 std::vector<Double_t> par;
521 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
522 for (UInt_t i=0; i<paramList->size(); i++)
523 par.push_back((*paramList)[i].fValue);
524
525 // calculate functions
526 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
527 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
528 }
529
530 // calculate asymmetry
531 Double_t asymFcnValue = 0.0;
532 Double_t a, b, f, alphaest;
533 Double_t time;
534
535 // Get estimated alpha
536 alphaest = fRunInfo->GetEstimatedAlpha();
537
538 for (UInt_t i=0; i<fData.GetValue()->size(); i++) {
539 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
540 switch (fAlphaBetaTag) {
541 case 1: // alpha == 1, beta == 1
542 asymFcnValue = fTheory->Func(time, par, fFuncValues);
543 break;
544 case 2: // alpha != 1, beta == 1
545 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
546 a = par[fRunInfo->GetAlphaParamNo()-1];
547 } else { // alpha is function
548 // get function number
549 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
550 // evaluate function
551 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
552 }
553 f = fTheory->Func(time, par, fFuncValues);
554 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));
555 break;
556 case 3: // alpha == 1, beta != 1
557 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
558 b = par[fRunInfo->GetBetaParamNo()-1];
559 } else { // beta is a function
560 // get function number
561 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
562 // evaluate function
563 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
564 }
565 f = fTheory->Func(time, par, fFuncValues);
566 asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0))-f*(b+1.0)/(2.0+f*(b-1.0));
567 break;
568 case 4: // alpha != 1, beta != 1
569 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
570 a = par[fRunInfo->GetAlphaParamNo()-1];
571 } else { // alpha is function
572 // get function number
573 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
574 // evaluate function
575 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
576 }
577 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
578 b = par[fRunInfo->GetBetaParamNo()-1];
579 } else { // beta is a function
580 // get function number
581 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
582 // evaluate function
583 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
584 }
585 f = fTheory->Func(time, par, fFuncValues);
586 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));
587 break;
588 case 5: // alpha ?? , beta == 1
589 a = alphaest;
590 f = fTheory->Func(time, par, fFuncValues);
591 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));
592 break;
593 case 6: // alpha ??, beta != 1
594 a = alphaest;
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 default:
607 asymFcnValue = 0.0;
608 break;
609 }
610 fData.AppendTheoryValue(asymFcnValue);
611 }
612
613 // clean up
614 par.clear();
615}
616
617//--------------------------------------------------------------------------
618// PrepareData (protected)
619//--------------------------------------------------------------------------
642{
643 if (!fValid)
644 return false;
645
646 // keep the Global block info
647 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
648
649 // get forward/backward histo from PRunDataHandler object ------------------------
650 // get the correct run
651 PRawRunData *runData = fRawData->GetRunData(*(fRunInfo->GetRunName()));
652 if (!runData) { // run not found
653 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **ERROR** Couldn't get run " << fRunInfo->GetRunName()->Data() << "!";
654 std::cerr << std::endl;
655 return false;
656 }
657
658 // keep the field from the meta-data from the data-file
659 fMetaData.fField = runData->GetField();
660
661 // keep the energy from the meta-data from the data-file
662 fMetaData.fEnergy = runData->GetEnergy();
663
664 // keep the temperature(s) from the meta-data from the data-file
665 for (unsigned int i=0; i<runData->GetNoOfTemperatures(); i++)
666 fMetaData.fTemp.push_back(runData->GetTemperature(i));
667
668 // collect histogram numbers
669 PUIntVector forwardHistoNo;
670 PUIntVector backwardHistoNo;
671 for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
672 forwardHistoNo.push_back(fRunInfo->GetForwardHistoNo(i));
673
674 if (!runData->IsPresent(forwardHistoNo[i])) {
675 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **PANIC ERROR**:";
676 std::cerr << std::endl << ">> forwardHistoNo found = " << forwardHistoNo[i] << ", which is NOT present in the data file!?!?";
677 std::cerr << std::endl << ">> Will quit :-(";
678 std::cerr << std::endl;
679 // clean up
680 forwardHistoNo.clear();
681 backwardHistoNo.clear();
682 return false;
683 }
684 }
685 for (UInt_t i=0; i<fRunInfo->GetBackwardHistoNoSize(); i++) {
686 backwardHistoNo.push_back(fRunInfo->GetBackwardHistoNo(i));
687
688 if (!runData->IsPresent(backwardHistoNo[i])) {
689 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **PANIC ERROR**:";
690 std::cerr << std::endl << ">> backwardHistoNo found = " << backwardHistoNo[i] << ", which is NOT present in the data file!?!?";
691 std::cerr << std::endl << ">> Will quit :-(";
692 std::cerr << std::endl;
693 // clean up
694 forwardHistoNo.clear();
695 backwardHistoNo.clear();
696 return false;
697 }
698 }
699/* //as35
700 if (forwardHistoNo.size() != backwardHistoNo.size()) {
701 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **PANIC ERROR**:";
702 std::cerr << std::endl << ">> # of forward histograms different from # of backward histograms.";
703 std::cerr << std::endl << ">> Will quit :-(";
704 std::cerr << std::endl;
705 // clean up
706 forwardHistoNo.clear();
707 backwardHistoNo.clear();
708 return false;
709 }
710*/ //as35
711
712 // keep the time resolution in (s)
713 fTimeResolution = runData->GetTimeResolution()/1.0e3;
714 std::cout.precision(10);
715 std::cout << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): time resolution=" << std::fixed << runData->GetTimeResolution() << "(ms)" << std::endl;
716
717 // get all the proper t0's and addt0's for the current RUN block
718 if (!GetProperT0(runData, globalBlock, forwardHistoNo, backwardHistoNo)) {
719 return false;
720 }
721
722 // keep the histo of each group at this point (addruns handled below)
723 std::vector<PDoubleVector> forward, backward;
724 forward.resize(forwardHistoNo.size()); // resize to number of groups
725 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
726 forward[i].resize(runData->GetDataBin(forwardHistoNo[i])->size());
727 forward[i] = *runData->GetDataBin(forwardHistoNo[i]);
728 }
729 backward.resize(backwardHistoNo.size()); // resize to number of groups
730 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
731 backward[i].resize(runData->GetDataBin(backwardHistoNo[i])->size());
732 backward[i] = *runData->GetDataBin(backwardHistoNo[i]);
733 }
734
735 // check if addrun's are present, and if yes add data
736 // check if there are runs to be added to the current one
737 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
738 PRawRunData *addRunData;
739 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
740 // get run to be added to the main one
741 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
742 if (addRunData == nullptr) { // couldn't get run
743 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
744 std::cerr << std::endl;
745 return false;
746 }
747
748 // add forward run
749 UInt_t addRunSize;
750 for (UInt_t k=0; k<forwardHistoNo.size(); k++) { // fill each group
751 addRunSize = addRunData->GetDataBin(forwardHistoNo[k])->size();
752 for (UInt_t j=0; j<addRunData->GetDataBin(forwardHistoNo[k])->size(); j++) { // loop over the bin indices
753 // make sure that the index stays in the proper range
754 if ((static_cast<Int_t>(j)+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]) >= 0) &&
755 (j+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]) < addRunSize)) {
756 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]));
757 }
758 }
759 }
760
761 // add backward run
762 for (UInt_t k=0; k<backwardHistoNo.size(); k++) { // fill each group
763 addRunSize = addRunData->GetDataBin(backwardHistoNo[k])->size();
764 for (UInt_t j=0; j<addRunData->GetDataBin(backwardHistoNo[k])->size(); j++) { // loop over the bin indices
765 // make sure that the index stays in the proper range
766 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) &&
767 (j+static_cast<Int_t>(fAddT0s[i-1][2*k+1])-static_cast<Int_t>(fT0s[2*k+1]) < addRunSize)) {
768 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]));
769 }
770 }
771 }
772 }
773 }
774
775 // set forward histo data of the first group
776 fForwardp.resize(forward[0].size());
777 fForwardm.resize(forward[0].size());
778 for (UInt_t i=0; i<fForwardp.size(); i++) {
779 fForwardp[i] = forward[0][i];
780 fForwardm[i] = forward[1][i];
781 }
782 // set backward histo data of the first group
783 fBackwardp.resize(backward[0].size());
784 fBackwardm.resize(backward[0].size());
785 for (UInt_t i=0; i<fBackwardp.size(); i++) {
786 fBackwardp[i] = backward[0][i];
787 fBackwardm[i] = backward[1][i];
788 }
789
790 // subtract background from histogramms ------------------------------------------
791 if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) { // no fixed background given
792 if (fRunInfo->GetBkgRange(0) >= 0) { // background range given
794 return false;
795 } else { // no background given to do the job, try to estimate it
796 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.1), 0);
797 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.6), 1);
798 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.1), 2);
799 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.6), 3);
800 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **WARNING** Neither fix background nor background bins are given!";
801 std::cerr << std::endl << ">> Will try the following:";
802 std::cerr << std::endl << ">> forward: bkg start = " << fRunInfo->GetBkgRange(0) << ", bkg end = " << fRunInfo->GetBkgRange(1);
803 std::cerr << std::endl << ">> backward: bkg start = " << fRunInfo->GetBkgRange(2) << ", bkg end = " << fRunInfo->GetBkgRange(3);
804 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS MAKES ANY SENSE! Better check ...";
805 std::cerr << std::endl;
807 return false;
808 }
809 } else { // fixed background given
810 if (!SubtractFixBkg())
811 return false;
812 }
813
814 UInt_t histoNo[2] = {forwardHistoNo[0], backwardHistoNo[0]};
815
816 // get the data range (fgb/lgb) for the current RUN block
817 if (!GetProperDataRange(runData, histoNo)) {
818 return false;
819 }
820
821 // get the fit range for the current RUN block
822 GetProperFitRange(globalBlock);
823
824 // everything looks fine, hence fill data set
825 Bool_t status;
826 switch(fHandleTag) {
827 case kFit:
829 break;
830 case kView:
831 status = PrepareViewData(runData, histoNo);
832 break;
833 default:
834 status = false;
835 break;
836 }
837
838 // clean up
839 forwardHistoNo.clear();
840 backwardHistoNo.clear();
841
842 return status;
843}
844
845//--------------------------------------------------------------------------
846// SubtractFixBkg (private)
847//--------------------------------------------------------------------------
865{
866 Double_t dval;
867
868 // Order in RunInfo structure Fp, Fm, Bp, Bm
869 for (UInt_t i=0; i<fForwardp.size(); i++) {
870 // keep the error, and make sure that the bin is NOT empty
871 if (fForwardp[i] != 0.0)
872 dval = TMath::Sqrt(fForwardp[i]);
873 else
874 dval = 1.0;
875 fForwardpErr.push_back(dval);
876 fForwardp[i] -= fRunInfo->GetBkgFix(0);
877
878 // keep the error, and make sure that the bin is NOT empty
879 if (fForwardm[i] != 0.0)
880 dval = TMath::Sqrt(fForwardm[i]);
881 else
882 dval = 1.0;
883 fForwardmErr.push_back(dval);
884 fForwardm[i] -= fRunInfo->GetBkgFix(1);
885
886 // keep the error, and make sure that the bin is NOT empty
887 if (fBackwardp[i] != 0.0)
888 dval = TMath::Sqrt(fBackwardp[i]);
889 else
890 dval = 1.0;
891 fBackwardpErr.push_back(dval);
892 fBackwardp[i] -= fRunInfo->GetBkgFix(2);
893
894 // keep the error, and make sure that the bin is NOT empty
895 if (fBackwardm[i] != 0.0)
896 dval = TMath::Sqrt(fBackwardm[i]);
897 else
898 dval = 1.0;
899 fBackwardmErr.push_back(dval);
900 fBackwardm[i] -= fRunInfo->GetBkgFix(3);
901 }
902
903 return true;
904}
905
906//--------------------------------------------------------------------------
907// SubtractEstimatedBkg (private)
908//--------------------------------------------------------------------------
927{
928 Double_t beamPeriod = 0.0;
929
930 // check if data are from PSI, RAL, or TRIUMF
931 if (fRunInfo->GetInstitute()->Contains("psi"))
932 beamPeriod = ACCEL_PERIOD_PSI;
933 else if (fRunInfo->GetInstitute()->Contains("ral"))
934 beamPeriod = ACCEL_PERIOD_RAL;
935 else if (fRunInfo->GetInstitute()->Contains("triumf"))
936 beamPeriod = ACCEL_PERIOD_TRIUMF;
937 else
938 beamPeriod = 0.0;
939
940 // check if start and end are in proper order
941 Int_t start[2] = {fRunInfo->GetBkgRange(0), fRunInfo->GetBkgRange(2)};
942 Int_t end[2] = {fRunInfo->GetBkgRange(1), fRunInfo->GetBkgRange(3)};
943 for (UInt_t i=0; i<2; i++) {
944 if (end[i] < start[i]) {
945 std::cout << std::endl << "PRunAsymmetryBNMR::SubtractEstimatedBkg(): end = " << end[i] << " > start = " << start[i] << "! Will swap them!";
946 UInt_t keep = end[i];
947 end[i] = start[i];
948 start[i] = keep;
949 }
950 }
951
952 // calculate proper background range
953 for (UInt_t i=0; i<2; i++) {
954 if (beamPeriod != 0.0) {
955 Double_t timeBkg = static_cast<Double_t>(end[i]-start[i])*(fTimeResolution*fPacking); // length of the background intervall in time
956 UInt_t fullCycles = static_cast<UInt_t>(timeBkg/beamPeriod); // how many proton beam cylces can be placed within the proposed background intervall
957 // correct the end of the background intervall such that the background is as close as possible to a multiple of the proton cylce
958 end[i] = start[i] + static_cast<UInt_t>((fullCycles*beamPeriod)/(fTimeResolution*fPacking));
959 std::cout << "PRunAsymmetryBNMR::SubtractEstimatedBkg(): Background " << start[i] << ", " << end[i] << std::endl;
960 if (end[i] == start[i])
961 end[i] = fRunInfo->GetBkgRange(2*i+1);
962 }
963 }
964
965 // check if start is within histogram bounds
966 if ((start[0] < 0) || (start[0] >= fForwardp.size()) ||
967 (start[1] < 0) || (start[1] >= fBackwardp.size())) {
968 std::cerr << std::endl << ">> PRunAsymmetryBNMR::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
969 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForwardp.size() << "/" << fBackwardp.size() << ").";
970 std::cerr << std::endl << ">> background start (f/b) = (" << start[0] << "/" << start[1] << ").";
971 return false;
972 }
973
974 // check if end is within histogram bounds
975 if ((end[0] < 0) || (end[0] >= fForwardp.size()) ||
976 (end[1] < 0) || (end[1] >= fBackwardp.size())) {
977 std::cerr << std::endl << ">> PRunAsymmetryBNMR::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
978 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForwardp.size() << "/" << fBackwardp.size() << ").";
979 std::cerr << std::endl << ">> background end (f/b) = (" << end[0] << "/" << end[1] << ").";
980 return false;
981 }
982
983 // calculate background
984 Double_t bkgp[2] = {0.0, 0.0};
985 Double_t errBkgp[2] = {0.0, 0.0};
986 Double_t bkgm[2] = {0.0, 0.0};
987 Double_t errBkgm[2] = {0.0, 0.0};
988
989 // forward
990 for (UInt_t i=start[0]; i<=end[0]; i++) {
991 bkgp[0] += fForwardp[i];
992 bkgm[0] += fForwardm[i];
993 }
994 errBkgp[0] = TMath::Sqrt(bkgp[0])/(end[0] - start[0] + 1);
995 bkgp[0] /= static_cast<Double_t>(end[0] - start[0] + 1);
996 std::cout << std::endl << ">> estimated pos hel forward histo background: " << bkgp[0];
997 errBkgm[0] = TMath::Sqrt(bkgp[0])/(end[0] - start[0] + 1);
998 bkgm[0] /= static_cast<Double_t>(end[0] - start[0] + 1);
999 std::cout << std::endl << ">> estimated neg hel forward histo background: " << bkgm[0];
1000
1001 // backward
1002 for (UInt_t i=start[1]; i<=end[1]; i++) {
1003 bkgp[1] += fBackwardp[i];
1004 bkgm[1] += fBackwardm[i];
1005 }
1006 errBkgp[1] = TMath::Sqrt(bkgp[1])/(end[1] - start[1] + 1);
1007 bkgp[1] /= static_cast<Double_t>(end[1] - start[1] + 1);
1008 std::cout << std::endl << ">> estimated pos hel backward histo background: " << bkgp[1];
1009 errBkgm[1] = TMath::Sqrt(bkgm[1])/(end[1] - start[1] + 1);
1010 bkgm[1] /= static_cast<Double_t>(end[1] - start[1] + 1);
1011 std::cout << std::endl << ">> estimated neg hel backward histo background: " << bkgm[1];
1012
1013 // correct error for forward, backward
1014 Double_t errVal = 0.0;
1015 for (UInt_t i=0; i<fForwardp.size(); i++) {
1016 if (fForwardp[i] > 0.0)
1017 errVal = TMath::Sqrt(fForwardp[i]+errBkgp[0]*errBkgp[0]);
1018 else
1019 errVal = 1.0;
1020 fForwardpErr.push_back(errVal);
1021 if (fBackwardp[i] > 0.0)
1022 errVal = TMath::Sqrt(fBackwardp[i]+errBkgp[1]*errBkgp[1]);
1023 else
1024 errVal = 1.0;
1025 fBackwardpErr.push_back(errVal);
1026 if (fForwardm[i] > 0.0)
1027 errVal = TMath::Sqrt(fForwardm[i]+errBkgm[0]*errBkgm[0]);
1028 else
1029 errVal = 1.0;
1030 fForwardmErr.push_back(errVal);
1031 if (fBackwardm[i] > 0.0)
1032 errVal = TMath::Sqrt(fBackwardm[i]+errBkgm[1]*errBkgm[1]);
1033 else
1034 errVal = 1.0;
1035 fBackwardmErr.push_back(errVal);
1036 }
1037
1038 // subtract background from data
1039 for (UInt_t i=0; i<fForwardp.size(); i++) {
1040 fForwardp[i] -= bkgp[0];
1041 fBackwardp[i] -= bkgp[1];
1042 fForwardm[i] -= bkgm[0];
1043 fBackwardm[i] -= bkgm[1];
1044 }
1045
1046 fRunInfo->SetBkgEstimated(bkgp[0], 0);
1047 fRunInfo->SetBkgEstimated(bkgp[1], 1);
1048 fRunInfo->SetBkgEstimated(bkgm[0], 3);
1049 fRunInfo->SetBkgEstimated(bkgm[1], 4);
1050
1051 // Get estimate for alpha once
1052 Double_t alpha;
1053 alpha = EstimateAlpha();
1054 fRunInfo->SetEstimatedAlpha(alpha);
1055
1056
1057 return true;
1058}
1059
1060//--------------------------------------------------------------------------
1061// PrepareFitData (protected)
1062//--------------------------------------------------------------------------
1075{
1076 // transform raw histo data. This is done the following way (for details see the manual):
1077 // first rebin the data, than calculate the asymmetry
1078
1079 // everything looks fine, hence fill packed forward and backward histo
1080 PRunData forwardpPacked;
1081 PRunData backwardpPacked;
1082 PRunData forwardmPacked;
1083 PRunData backwardmPacked;
1084 Double_t valuep = 0.0;
1085 Double_t errorp = 0.0;
1086 Double_t valuem = 0.0;
1087 Double_t errorm = 0.0;
1088
1089 // forward
1090 for (Int_t i=fGoodBins[0]; i<fGoodBins[1]; i++) {
1091 if (fPacking == 1) {
1092 forwardpPacked.AppendValue(fForwardp[i]);
1093 forwardpPacked.AppendErrorValue(fForwardpErr[i]);
1094 forwardmPacked.AppendValue(fForwardm[i]);
1095 forwardmPacked.AppendErrorValue(fForwardmErr[i]);
1096 } else { // packed data, i.e. fPacking > 1
1097 if (((i-fGoodBins[0]) % fPacking == 0) && (i != fGoodBins[0])) { // fill data
1098 // in order that after rebinning the fit does not need to be redone (important for plots)
1099 // the value is normalize to per bin
1100 valuep /= fPacking;
1101 valuem /= fPacking;
1102 forwardpPacked.AppendValue(valuep);
1103 forwardmPacked.AppendValue(valuem);
1104 if (valuep == 0.0) {
1105 forwardpPacked.AppendErrorValue(1.0);
1106 } else {
1107 forwardpPacked.AppendErrorValue(TMath::Sqrt(errorp)/fPacking);
1108 }
1109 if (valuem == 0.0) {
1110 forwardmPacked.AppendErrorValue(1.0);
1111 } else {
1112 forwardmPacked.AppendErrorValue(TMath::Sqrt(errorm)/fPacking);
1113 }
1114 valuep = 0.0;
1115 errorp = 0.0;
1116 valuem = 0.0;
1117 errorm = 0.0;
1118 }
1119 valuep += fForwardp[i];
1120 errorp += fForwardpErr[i]*fForwardpErr[i];
1121 valuem += fForwardm[i];
1122 errorm += fForwardmErr[i]*fForwardmErr[i];
1123 }
1124 }
1125
1126 // backward
1127 for (Int_t i=fGoodBins[2]; i<fGoodBins[3]; i++) {
1128 if (fPacking == 1) {
1129 backwardpPacked.AppendValue(fBackwardp[i]);
1130 backwardpPacked.AppendErrorValue(fBackwardpErr[i]);
1131 backwardmPacked.AppendValue(fBackwardm[i]);
1132 backwardmPacked.AppendErrorValue(fBackwardmErr[i]);
1133 } else { // packed data, i.e. fPacking > 1
1134 if (((i-fGoodBins[2]) % fPacking == 0) && (i != fGoodBins[2])) { // fill data
1135 // in order that after rebinning the fit does not need to be redone (important for plots)
1136 // the value is normalize to per bin
1137 valuep /= fPacking;
1138 valuem /= fPacking;
1139 backwardpPacked.AppendValue(valuep);
1140 backwardmPacked.AppendValue(valuem);
1141 if (valuep == 0.0) {
1142 backwardpPacked.AppendErrorValue(1.0);
1143 } else {
1144 backwardpPacked.AppendErrorValue(TMath::Sqrt(errorp)/fPacking);
1145 }
1146 if (valuem == 0.0) {
1147 backwardmPacked.AppendErrorValue(1.0);
1148 } else {
1149 backwardmPacked.AppendErrorValue(TMath::Sqrt(errorm)/fPacking);
1150 }
1151 valuep = 0.0;
1152 errorp = 0.0;
1153 valuem = 0.0;
1154 errorm = 0.0;
1155 }
1156 valuep += fBackwardp[i];
1157 errorp += fBackwardpErr[i]*fBackwardpErr[i];
1158 valuem += fBackwardm[i];
1159 errorm += fBackwardmErr[i]*fBackwardmErr[i];
1160 }
1161 }
1162
1163 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1164 UInt_t noOfBins = forwardpPacked.GetValue()->size();
1165 if (forwardpPacked.GetValue()->size() != backwardpPacked.GetValue()->size()) {
1166 if (forwardpPacked.GetValue()->size() > backwardpPacked.GetValue()->size())
1167 noOfBins = backwardpPacked.GetValue()->size();
1168 }
1169
1170 // form asymmetry including error propagation
1171 Double_t asym,error;
1172 Double_t fp, bp, efp, ebp;
1173 Double_t fm, bm, efm, ebm;
1174 // fill data time start, and step
1175 // data start at data_start-t0 shifted by (pack-1)/2
1176 fData.SetDataTimeStart(fTimeResolution*(static_cast<Double_t>(fGoodBins[0])-fT0s[0]+static_cast<Double_t>(fPacking-1)/2.0));
1177 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(fPacking));
1178 for (UInt_t i=0; i<noOfBins; i++) {
1179 // to make the formulae more readable
1180 fp = forwardpPacked.GetValue()->at(i);
1181 bp = backwardpPacked.GetValue()->at(i);
1182 efp = forwardpPacked.GetError()->at(i);
1183 ebp = backwardpPacked.GetError()->at(i);
1184 fm = forwardmPacked.GetValue()->at(i);
1185 bm = backwardmPacked.GetValue()->at(i);
1186 efm = forwardmPacked.GetError()->at(i);
1187 ebm = backwardmPacked.GetError()->at(i);
1188 // check that there are indeed bins
1189 if (fp+bp != 0.0)
1190 asym = (fp-bp) / (fp+bp) - (fm-bm) / (fm+bm);
1191 else
1192 asym = 0.0;
1193 fData.AppendValue(asym);
1194 // calculate the error
1195 if (fp+bp != 0.0)
1196 errorp = 2.0/((fp+bp)*(fp+bp))*TMath::Sqrt(bp*bp*efp*efp+ebp*ebp*fp*fp);
1197 else
1198 errorp = 1.0;
1199 if (fm+bm != 0.0)
1200 errorm = 2.0/((fm+bm)*(fm+bm))*TMath::Sqrt(bm*bm*efm*efm+ebm*ebm*fm*fm);
1201 else
1202 errorp = 1.0;
1203
1204 error = TMath::Sqrt(errorp*errorp+errorm*errorm);
1205 fData.AppendErrorValue(error);
1206 }
1207
1209
1210 // clean up
1211 fForwardp.clear();
1212 fForwardpErr.clear();
1213 fBackwardp.clear();
1214 fBackwardpErr.clear();
1215 fForwardm.clear();
1216 fForwardmErr.clear();
1217 fBackwardm.clear();
1218 fBackwardmErr.clear();
1219
1220 return true;
1221}
1222//--------------------------------------------------------------------------
1236Bool_t PRunAsymmetryBNMR::PrepareViewData(PRawRunData* runData, UInt_t histoNo[2])
1237{
1238 // check if view_packing is wished
1239 Int_t packing = fPacking;
1240 if (fMsrInfo->GetMsrPlotList()->at(0).fViewPacking > 0) {
1241 packing = fMsrInfo->GetMsrPlotList()->at(0).fViewPacking;
1242 }
1243
1244 // feed the parameter vector
1245 std::vector<Double_t> par;
1246 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
1247 for (UInt_t i=0; i<paramList->size(); i++)
1248 par.push_back((*paramList)[i].fValue);
1249
1250 // transform raw histo data. This is done the following way (for details see the manual):
1251 // first rebin the data, than calculate the asymmetry
1252
1253 // first get start data, end data, and t0
1254 Int_t start[2] = {fGoodBins[0], fGoodBins[2]};
1255 Int_t end[2] = {fGoodBins[1], fGoodBins[3]};
1256 Int_t t0[2] = {static_cast<Int_t>(fT0s[0]), static_cast<Int_t>(fT0s[1])};
1257
1258 // check if the data ranges and t0's between forward/backward are compatible
1259 Int_t fgb[2];
1260 if (start[0]-t0[0] != start[1]-t0[1]) { // wrong fgb aligning
1261 if (abs(start[0]-t0[0]) > abs(start[1]-t0[1])) {
1262 fgb[0] = start[0];
1263 fgb[1] = t0[1] + start[0]-t0[0];
1264 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **WARNING** needed to shift backward fgb from ";
1265 std::cerr << start[1] << " to " << fgb[1] << std::endl;
1266 } else {
1267 fgb[0] = t0[0] + start[1]-t0[1];
1268 fgb[1] = start[1];
1269 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **WARNING** needed to shift forward fgb from ";
1270 std::cerr << start[0] << " to " << fgb[0] << std::endl;
1271 }
1272 } else { // fgb aligning is correct
1273 fgb[0] = start[0];
1274 fgb[1] = start[1];
1275 }
1276
1277 Int_t val = fgb[0]-packing*(fgb[0]/packing);
1278 do {
1279 if (fgb[1] - fgb[0] < 0)
1280 val += packing;
1281 } while (val + fgb[1] - fgb[0] < 0);
1282
1283 start[0] = val;
1284 start[1] = val + fgb[1] - fgb[0];
1285
1286 // make sure that there are equal number of rebinned bins in forward and backward
1287 UInt_t noOfBins0 = (runData->GetDataBin(histoNo[0])->size()-start[0])/packing;
1288 UInt_t noOfBins1 = (runData->GetDataBin(histoNo[1])->size()-start[1])/packing;
1289 if (noOfBins0 > noOfBins1)
1290 noOfBins0 = noOfBins1;
1291 end[0] = start[0] + noOfBins0 * packing;
1292 end[1] = start[1] + noOfBins0 * packing;
1293
1294 // check if start, end, and t0 make any sense
1295 // 1st check if start and end are in proper order
1296 for (UInt_t i=0; i<2; i++) {
1297 if (end[i] < start[i]) { // need to swap them
1298 Int_t keep = end[i];
1299 end[i] = start[i];
1300 start[i] = keep;
1301 }
1302 // 2nd check if start is within proper bounds
1303 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1304 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **ERROR** start data bin doesn't make any sense!";
1305 std::cerr << std::endl;
1306 return false;
1307 }
1308 // 3rd check if end is within proper bounds
1309 if ((end[i] < 0) || (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1310 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **ERROR** end data bin doesn't make any sense!";
1311 std::cerr << std::endl;
1312 return false;
1313 }
1314 // 4th check if t0 is within proper bounds
1315 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1316 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareViewData(): **ERROR** t0 data bin doesn't make any sense!";
1317 std::cerr << std::endl;
1318 return false;
1319 }
1320 }
1321
1322 // everything looks fine, hence fill packed forward and backward histo
1323 PRunData forwardpPacked;
1324 PRunData backwardpPacked;
1325 PRunData forwardmPacked;
1326 PRunData backwardmPacked;
1327 Double_t valuep = 0.0;
1328 Double_t errorp = 0.0;
1329 Double_t valuem = 0.0;
1330 Double_t errorm = 0.0;
1331 Double_t value = 0.0;
1332 Double_t error = 0.0;
1333
1334 // forward
1335 for (Int_t i=start[0]; i<end[0]; i++) {
1336 if (packing == 1) {
1337 forwardpPacked.AppendValue(fForwardp[i]);
1338 forwardpPacked.AppendErrorValue(fForwardpErr[i]);
1339 forwardmPacked.AppendValue(fForwardm[i]);
1340 forwardmPacked.AppendErrorValue(fForwardmErr[i]);
1341 } else { // packed data, i.e. packing > 1
1342 if (((i-start[0]) % packing == 0) && (i != start[0])) { // fill data
1343 // in order that after rebinning the fit does not need to be redone (important for plots)
1344 // the value is normalize to per bin
1345 valuep /= packing;
1346 forwardpPacked.AppendValue(valuep);
1347 valuem /= packing;
1348 forwardmPacked.AppendValue(valuem);
1349 if (valuep == 0.0) {
1350 forwardpPacked.AppendErrorValue(1.0);
1351 } else {
1352 forwardpPacked.AppendErrorValue(TMath::Sqrt(errorp)/packing);
1353 }
1354 if (valuem == 0.0) {
1355 forwardmPacked.AppendErrorValue(1.0);
1356 } else {
1357 forwardmPacked.AppendErrorValue(TMath::Sqrt(errorm)/packing);
1358 }
1359 valuep = 0.0;
1360 errorp = 0.0;
1361 valuem = 0.0;
1362 errorm = 0.0;
1363 }
1364 valuep += fForwardp[i];
1365 errorp += fForwardpErr[i]*fForwardpErr[i];
1366 valuem += fForwardm[i];
1367 errorm += fForwardmErr[i]*fForwardmErr[i];
1368 }
1369 }
1370
1371 // backward
1372 for (Int_t i=start[1]; i<end[1]; i++) {
1373 if (packing == 1) {
1374 backwardpPacked.AppendValue(fBackwardp[i]);
1375 backwardpPacked.AppendErrorValue(fBackwardpErr[i]);
1376 backwardmPacked.AppendValue(fBackwardm[i]);
1377 backwardmPacked.AppendErrorValue(fBackwardmErr[i]);
1378 } else { // packed data, i.e. packing > 1
1379 if (((i-start[1]) % packing == 0) && (i != start[1])) { // fill data
1380 // in order that after rebinning the fit does not need to be redone (important for plots)
1381 // the value is normalize to per bin
1382 valuep /= packing;
1383 valuem /= packing;
1384 backwardpPacked.AppendValue(valuep);
1385 backwardmPacked.AppendValue(valuem);
1386 if (valuep == 0.0) {
1387 backwardpPacked.AppendErrorValue(1.0);
1388 } else {
1389 backwardpPacked.AppendErrorValue(TMath::Sqrt(errorp)/packing);
1390 }
1391 if (valuem == 0.0) {
1392 backwardmPacked.AppendErrorValue(1.0);
1393 } else {
1394 backwardmPacked.AppendErrorValue(TMath::Sqrt(errorm)/packing);
1395 }
1396 valuep = 0.0;
1397 errorp = 0.0;
1398 valuem = 0.0;
1399 errorm = 0.0;
1400 }
1401 valuep += fBackwardp[i];
1402 errorp += fBackwardpErr[i]*fBackwardpErr[i];
1403 valuem += fBackwardm[i];
1404 errorm += fBackwardmErr[i]*fBackwardmErr[i];
1405 }
1406 }
1407
1408 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1409 UInt_t noOfBins = forwardpPacked.GetValue()->size();
1410 if (forwardpPacked.GetValue()->size() != backwardpPacked.GetValue()->size()) {
1411 if (forwardpPacked.GetValue()->size() > backwardpPacked.GetValue()->size())
1412 noOfBins = backwardpPacked.GetValue()->size();
1413 }
1414
1415 // form asymmetry including error propagation
1416 Double_t asym;
1417 Double_t fp, bp, efp, ebp, alpha, beta = 1.0;
1418 Double_t fm, bm, efm, ebm;
1419 // set data time start, and step
1420 // data start at data_start-t0
1421 fData.SetDataTimeStart(fTimeResolution*(static_cast<Double_t>(start[0])-t0[0]+static_cast<Double_t>(packing-1)/2.0));
1422 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(packing));
1423
1424 // Get estimate for alpha once
1425 alpha = EstimateAlpha();
1426
1427 // get the proper alpha and beta
1428 switch (fAlphaBetaTag) {
1429 case 1: // alpha == 1, beta == 1
1430 alpha = 1.0;
1431 beta = 1.0;
1432 break;
1433 case 2: // alpha != 1, beta == 1
1434 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1435 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1436 } else { // alpha is function
1437 // get function number
1438 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1439 // evaluate function
1440 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1441 }
1442 beta = 1.0;
1443 break;
1444 case 3: // alpha == 1, beta != 1
1445 alpha = 1.0;
1446 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1447 beta = par[fRunInfo->GetBetaParamNo()-1];
1448 } else { // beta is a function
1449 // get function number
1450 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1451 // evaluate function
1452 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1453 }
1454 break;
1455 case 4: // alpha != 1, beta != 1
1456 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1457 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1458 } else { // alpha is function
1459 // get function number
1460 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1461 // evaluate function
1462 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1463 }
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 5: // alpha ?? , beta == 1
1474 // use estimated value
1475 beta = 1.0;
1476 break;
1477 case 6: // alpha ??, beta != 1
1478 // use estimated value
1479 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1480 beta = par[fRunInfo->GetBetaParamNo()-1];
1481 } else { // beta is a function
1482 // get function number
1483 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1484 // evaluate function
1485 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1486 }
1487 break;
1488 default:
1489 break;
1490 }
1491
1492 for (UInt_t i=0; i<forwardpPacked.GetValue()->size(); i++) {
1493 // to make the formulae more readable
1494 fp = forwardpPacked.GetValue()->at(i);
1495 bp = backwardpPacked.GetValue()->at(i);
1496 efp = forwardpPacked.GetError()->at(i);
1497 ebp = backwardpPacked.GetError()->at(i);
1498 fm = forwardmPacked.GetValue()->at(i);
1499 bm = backwardmPacked.GetValue()->at(i);
1500 efm = forwardmPacked.GetError()->at(i);
1501 ebm = backwardmPacked.GetError()->at(i);
1502 // check that there are indeed bins
1503 if (fp+bp != 0.0)
1504 asym = (alpha*fp-bp) / (alpha*beta*fp+bp) - (alpha*fm-bm) / (alpha*beta*fm+bm);
1505 else
1506 asym = 0.0;
1507 fData.AppendValue(asym);
1508 // calculate the error
1509 if (fp+bp != 0.0)
1510 errorp = 2.0/((fp+bp)*(fp+bp))*TMath::Sqrt(bp*bp*efp*efp+ebp*ebp*fp*fp);
1511 else
1512 errorp = 1.0;
1513 if (fm+bm != 0.0)
1514 errorm = 2.0/((fm+bm)*(fm+bm))*TMath::Sqrt(bm*bm*efm*efm+ebm*ebm*fm*fm);
1515 else
1516 errorm = 1.0;
1517 error = TMath::Sqrt(errorp*errorp+errorm*errorm);
1518 fData.AppendErrorValue(error);
1519 }
1520
1522
1523 // clean up
1524 fForwardp.clear();
1525 fForwardpErr.clear();
1526 fBackwardp.clear();
1527 fBackwardpErr.clear();
1528 fForwardm.clear();
1529 fForwardmErr.clear();
1530 fBackwardm.clear();
1531 fBackwardmErr.clear();
1532
1533 // fill theory vector for kView
1534 // calculate functions
1535 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
1536 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
1537 }
1538
1539 // calculate theory
1540 UInt_t size = runData->GetDataBin(histoNo[0])->size();
1541
1542 Int_t factor = 8; // 8 times more points for the theory (if fTheoAsData == false)
1543 fData.SetTheoryTimeStart(fData.GetDataTimeStart());
1544 if (fTheoAsData) { // calculate theory only at the data points
1545 fData.SetTheoryTimeStep(fData.GetDataTimeStep());
1546 } else {
1547 // finer binning for the theory (8 times as many points = factor)
1548 size *= factor;
1549 fData.SetTheoryTimeStep(fData.GetDataTimeStep()/(Double_t)factor);
1550 }
1551
1552 Double_t time;
1553 for (UInt_t i=0; i<size; i++) {
1554 time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
1555 value = fTheory->Func(time, par, fFuncValues);
1556 if (fabs(value) > 10.0) { // dirty hack needs to be fixed!!
1557 value = 0.0;
1558 }
1559 fData.AppendTheoryValue(value);
1560 }
1561
1562 // clean up
1563 par.clear();
1564
1565 return true;
1566}
1567
1568
1569//--------------------------------------------------------------------------
1570// GetProperT0 (private)
1571//--------------------------------------------------------------------------
1590Bool_t PRunAsymmetryBNMR::GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHistoNo, PUIntVector &backwardHistoNo)
1591{
1592 // feed all T0's
1593 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1594 fT0s.clear();
1595 // this strange fT0 size estimate is needed in case #forw histos != #back histos
1596 size_t size = 2*forwardHistoNo.size();
1597 if (backwardHistoNo.size() > forwardHistoNo.size())
1598 size = 2*backwardHistoNo.size();
1599 fT0s.resize(size);
1600 for (UInt_t i=0; i<fT0s.size(); i++) {
1601 fT0s[i] = -1.0;
1602 }
1603
1604 // fill in the T0's from the msr-file (if present)
1605 for (UInt_t i=0; i<fRunInfo->GetT0BinSize(); i++) {
1606 fT0s[i] = fRunInfo->GetT0Bin(i);
1607 }
1608
1609 // fill in the missing T0's from the GLOBAL block section (if present)
1610 for (UInt_t i=0; i<globalBlock->GetT0BinSize(); i++) {
1611 if (fT0s[i] == -1) { // i.e. not given in the RUN block section
1612 fT0s[i] = globalBlock->GetT0Bin(i);
1613 }
1614 }
1615
1616 // fill in the missing T0's from the data file, if not already present in the msr-file
1617 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1618 if (fT0s[2*i] == -1.0) // i.e. not present in the msr-file, try the data file
1619 if (runData->GetT0Bin(forwardHistoNo[i]) > 0.0) {
1620 fT0s[2*i] = runData->GetT0Bin(forwardHistoNo[i]);
1621 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1622 }
1623 }
1624 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1625 if (fT0s[2*i+1] == -1.0) // i.e. not present in the msr-file, try the data file
1626 if (runData->GetT0Bin(backwardHistoNo[i]) > 0.0) {
1627 fT0s[2*i+1] = runData->GetT0Bin(backwardHistoNo[i]);
1628 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1629 }
1630 }
1631
1632 // 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
1633 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1634 if (fT0s[2*i] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1635 fT0s[2*i] = runData->GetT0BinEstimated(forwardHistoNo[i]);
1636 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1637
1638 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1639 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1640 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << runData->GetT0BinEstimated(forwardHistoNo[i]);
1641 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1642 std::cerr << std::endl;
1643 }
1644 }
1645 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1646 if (fT0s[2*i+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1647 fT0s[2*i+1] = runData->GetT0BinEstimated(backwardHistoNo[i]);
1648 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1649
1650 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1651 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1652 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[i]);
1653 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1654 std::cerr << std::endl;
1655 }
1656 }
1657
1658 // check if t0 is within proper bounds
1659 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1660 if ((fT0s[2*i] < 0) || (fT0s[2*i] > static_cast<Int_t>(runData->GetDataBin(forwardHistoNo[i])->size()))) {
1661 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **ERROR** t0 data bin (" << fT0s[2*i] << ") doesn't make any sense!";
1662 std::cerr << std::endl << ">> forwardHistoNo " << forwardHistoNo[i];
1663 std::cerr << std::endl;
1664 return false;
1665 }
1666 }
1667 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1668 if ((fT0s[2*i+1] < 0) || (fT0s[2*i+1] > static_cast<Int_t>(runData->GetDataBin(backwardHistoNo[i])->size()))) {
1669 std::cerr << std::endl << ">> PRunAsymmetryBNMR::PrepareData(): **ERROR** t0 data bin (" << fT0s[2*i+1] << ") doesn't make any sense!";
1670 std::cerr << std::endl << ">> backwardHistoNo " << backwardHistoNo[i];
1671 std::cerr << std::endl;
1672 return false;
1673 }
1674 }
1675
1676 // check if addrun's are present, and if yes add the necessary t0's
1677 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
1678 PRawRunData *addRunData;
1679 fAddT0s.resize(fRunInfo->GetRunNameSize()-1); // resize to the number of addruns
1680 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
1681 // get run to be added to the main one
1682 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
1683 if (addRunData == 0) { // couldn't get run
1684 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
1685 std::cerr << std::endl;
1686 return false;
1687 }
1688
1689 // feed all T0's
1690 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1691 fAddT0s[i-1].clear();
1692 fAddT0s[i-1].resize(2*forwardHistoNo.size());
1693 for (UInt_t j=0; j<fAddT0s[i-1].size(); j++) {
1694 fAddT0s[i-1][j] = -1.0;
1695 }
1696
1697 // fill in the T0's from the msr-file (if present)
1698 for (Int_t j=0; j<fRunInfo->GetAddT0BinSize(i-1); j++) {
1699 fAddT0s[i-1][j] = fRunInfo->GetAddT0Bin(i-1, j);
1700 }
1701
1702 // fill in the T0's from the data file, if not already present in the msr-file
1703 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1704 if (fAddT0s[i-1][2*j] == -1.0) // i.e. not present in the msr-file, try the data file
1705 if (addRunData->GetT0Bin(forwardHistoNo[j]) > 0.0) {
1706 fAddT0s[i-1][2*j] = addRunData->GetT0Bin(forwardHistoNo[j]);
1707 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1708 }
1709 }
1710 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1711 if (fAddT0s[i-1][2*j+1] == -1.0) // i.e. not present in the msr-file, try the data file
1712 if (addRunData->GetT0Bin(backwardHistoNo[j]) > 0.0) {
1713 fAddT0s[i-1][2*j+1] = addRunData->GetT0Bin(backwardHistoNo[j]);
1714 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1715 }
1716 }
1717
1718 // 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
1719 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1720 if (fAddT0s[i-1][2*j] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1721 fAddT0s[i-1][2*j] = addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1722 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1723
1724 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1725 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1726 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1727 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1728 std::cerr << std::endl;
1729 }
1730 }
1731 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1732 if (fAddT0s[i-1][2*j+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1733 fAddT0s[i-1][2*j+1] = addRunData->GetT0BinEstimated(backwardHistoNo[j]);
1734 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1735
1736 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1737 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1738 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[j]);
1739 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1740 std::cerr << std::endl;
1741 }
1742 }
1743 }
1744 }
1745
1746 return true;
1747}
1748
1749//--------------------------------------------------------------------------
1750// GetProperDataRange (private)
1751//--------------------------------------------------------------------------
1765Bool_t PRunAsymmetryBNMR::GetProperDataRange(PRawRunData* runData, UInt_t histoNo[2])
1766{
1767 // first get start/end data
1768 Int_t start[2] = {fRunInfo->GetDataRange(0), fRunInfo->GetDataRange(2)};
1769 Int_t end[2] = {fRunInfo->GetDataRange(1), fRunInfo->GetDataRange(3)};
1770 // check if data range has been provided in the RUN block. If not, try the GLOBAL block
1771 if (start[0] == -1) {
1772 start[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(0);
1773 }
1774 if (start[1] == -1) {
1775 start[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(2);
1776 }
1777 if (end[0] == -1) {
1778 end[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(1);
1779 }
1780 if (end[1] == -1) {
1781 end[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(3);
1782 }
1783
1784 Double_t t0[2] = {fT0s[0], fT0s[1]};
1785 Int_t offset = static_cast<Int_t>((10.0e-3/fTimeResolution)); // needed in case first good bin is not given, default = 10ns
1786
1787 // check if data range has been provided, and if not try to estimate them
1788 if (start[0] < 0) {
1789 start[0] = static_cast<Int_t>(t0[0])+offset;
1790 fRunInfo->SetDataRange(start[0], 0);
1791 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[0] << ".";
1792 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS DOES MAKE ANY SENSE.";
1793 std::cerr << std::endl;
1794 }
1795 if (start[1] < 0) {
1796 start[1] = static_cast<Int_t>(t0[1])+offset;
1797 fRunInfo->SetDataRange(start[1], 2);
1798 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[1] << ".";
1799 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS DOES MAKE ANY SENSE.";
1800 std::cerr << std::endl;
1801 }
1802 if (end[0] < 0) {
1803 end[0] = runData->GetDataBin(histoNo[0])->size();
1804 fRunInfo->SetDataRange(end[0], 1);
1805 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range end = " << end[0] << ".";
1806 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS DOES MAKE ANY SENSE.";
1807 std::cerr << std::endl;
1808 }
1809 if (end[1] < 0) {
1810 end[1] = runData->GetDataBin(histoNo[1])->size();
1811 fRunInfo->SetDataRange(end[1], 3);
1812 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range end = " << end[1] << ".";
1813 std::cerr << std::endl << ">> NO GUARANTEE THAT THIS DOES MAKE ANY SENSE.";
1814 std::cerr << std::endl;
1815 }
1816
1817 // check if start, end, and t0 make any sense
1818 // 1st check if start and end are in proper order
1819 for (UInt_t i=0; i<2; i++) {
1820 if (end[i] < start[i]) { // need to swap them
1821 Int_t keep = end[i];
1822 end[i] = start[i];
1823 start[i] = keep;
1824 }
1825 // 2nd check if start is within proper bounds
1826 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1827 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **ERROR** start data bin doesn't make any sense!";
1828 std::cerr << std::endl;
1829 return false;
1830 }
1831 // 3rd check if end is within proper bounds
1832 if (end[i] < 0) {
1833 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **ERROR** end data bin (" << end[i] << ") doesn't make any sense!";
1834 std::cerr << std::endl;
1835 return false;
1836 }
1837 if (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())) {
1838 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **WARNING** end data bin (" << end[i] << ") > histo length (" << static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()) << ").";
1839 std::cerr << std::endl << ">> Will set end = (histo length - 1). Consider to change it in the msr-file." << std::endl;
1840 std::cerr << std::endl;
1841 end[i] = static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())-1;
1842 }
1843 // 4th check if t0 is within proper bounds
1844 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1845 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange(): **ERROR** t0 data bin doesn't make any sense!";
1846 std::cerr << std::endl;
1847 return false;
1848 }
1849 }
1850
1851 // check that start-t0 is the same for forward as for backward, otherwise take max(start[i]-t0[i])
1852 if (fabs(static_cast<Double_t>(start[0])-t0[0]) > fabs(static_cast<Double_t>(start[1])-t0[1])){
1853 start[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(start[0]) - t0[0]);
1854 end[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(end[0]) - t0[0]);
1855 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange **WARNING** needed to shift backward data range.";
1856 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(2) << ", " << fRunInfo->GetDataRange(3);
1857 std::cerr << std::endl << ">> used : " << start[1] << ", " << end[1];
1858 std::cerr << std::endl;
1859 }
1860 if (fabs(static_cast<Double_t>(start[0])-t0[0]) < fabs(static_cast<Double_t>(start[1])-t0[1])){
1861 start[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(start[1]) - t0[1]);
1862 end[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(end[1]) - t0[1]);
1863 std::cerr << std::endl << ">> PRunAsymmetryBNMR::GetProperDataRange **WARNING** needed to shift forward data range.";
1864 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(0) << ", " << fRunInfo->GetDataRange(1);
1865 std::cerr << std::endl << ">> used : " << start[0] << ", " << end[0];
1866 std::cerr << std::endl;
1867 }
1868
1869 // keep good bins for potential latter use
1870 fGoodBins[0] = start[0];
1871 fGoodBins[1] = end[0];
1872 fGoodBins[2] = start[1];
1873 fGoodBins[3] = end[1];
1874
1875 return true;
1876}
1877
1878//--------------------------------------------------------------------------
1879// GetProperFitRange (private)
1880//--------------------------------------------------------------------------
1898{
1899 // set fit start/end time; first check RUN Block
1900 fFitStartTime = fRunInfo->GetFitRange(0);
1901 fFitEndTime = fRunInfo->GetFitRange(1);
1902 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1903 if (fRunInfo->IsFitRangeInBin()) {
1904 fFitStartTime = (fGoodBins[0] + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1905 fFitEndTime = (fGoodBins[1] - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1906 // write these times back into the data structure. This way it is available when writting the log-file
1907 fRunInfo->SetFitRange(fFitStartTime, 0);
1908 fRunInfo->SetFitRange(fFitEndTime, 1);
1909 }
1910 if (fFitStartTime == PMUSR_UNDEFINED) { // fit start/end NOT found in the RUN block, check GLOBAL block
1911 fFitStartTime = globalBlock->GetFitRange(0);
1912 fFitEndTime = globalBlock->GetFitRange(1);
1913 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1914 if (globalBlock->IsFitRangeInBin()) {
1915 fFitStartTime = (fGoodBins[0] + globalBlock->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1916 fFitEndTime = (fGoodBins[1] - globalBlock->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1917 // write these times back into the data structure. This way it is available when writting the log-file
1918 globalBlock->SetFitRange(fFitStartTime, 0);
1919 globalBlock->SetFitRange(fFitEndTime, 1);
1920 }
1921 }
1923 fFitStartTime = (fGoodBins[0] - fT0s[0]) * fTimeResolution; // (fgb-t0)*dt
1924 fFitEndTime = (fGoodBins[1] - fT0s[0]) * fTimeResolution; // (lgb-t0)*dt
1925 std::cerr << ">> PRunSingleHisto::GetProperFitRange(): **WARNING** Couldn't get fit start/end time!" << std::endl;
1926 std::cerr << ">> Will set it to fgb/lgb which given in time is: " << fFitStartTime << "..." << fFitEndTime << " (usec)" << std::endl;
1927 }
1928}
1929
1930
1931//--------------------------------------------------------------------------
1932// EstimateAlpha (private)
1933//--------------------------------------------------------------------------
1948{
1949
1950 Double_t SumF[2] = {0.0, 0.0};
1951 Double_t SumB[2] = {0.0, 0.0};
1952 Double_t alpha = 1;
1953
1954
1955 // forward
1956 for (Int_t i=0; i<fForwardp.size(); i++) {
1957 SumF[0] += fForwardp[i];
1958 SumF[1] += fForwardm[i];
1959 }
1960
1961 // backward
1962 for (Int_t i=0; i<fBackwardp.size(); i++) {
1963 SumB[0] += fBackwardp[i];
1964 SumB[1] += fBackwardm[i];
1965 }
1966
1967 // Spit out estimated alpha value from total counts (Bp+Bm)/(Fp+Fm)
1968 if ( (SumF[0]+SumF[1]) == 0) {
1969 alpha = 1;
1970 } else {
1971 alpha = (SumB[0]+SumB[1])/(SumF[0]+SumF[1]);
1972 }
1973 std::cout << std::endl << ">> PRunAsymmetryBNMR::EstimateAlpha(): alpha estimate=" << alpha << std::endl;
1974
1975 return alpha;
1976}
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