musrfit 1.10.0
PRunAsymmetry.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PRunAsymmetry.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2007-2026 by Andreas Suter *
12 * andreas.suter@psi.ch *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#ifdef HAVE_GOMP
35#include <omp.h>
36#endif
37
38#include <stdio.h>
39
40#include <iostream>
41#include <string>
42#include <vector>
43
44#include <TString.h>
45
46#include "PMusr.h"
47#include "PStringUtils.h"
48#include "PRunAsymmetry.h"
49
50//--------------------------------------------------------------------------
51// Constructor
52//--------------------------------------------------------------------------
61{
62 fNoOfFitBins = 0;
63 fPacking = -1;
64 fTheoAsData = false;
65
66 // the 2 following variables are need in case fit range is given in bins, and since
67 // the fit range can be changed in the command block, these variables need to be accessible
68 fGoodBins[0] = -1;
69 fGoodBins[1] = -1;
70
71 fStartTimeBin = -1;
72 fEndTimeBin = -1;
73}
74
75//--------------------------------------------------------------------------
76// Constructor
77//--------------------------------------------------------------------------
100PRunAsymmetry::PRunAsymmetry(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData) :
101 PRunBase(msrInfo, rawData, runNo, tag), fTheoAsData(theoAsData)
102{
103 // the following variables are need in case fit range is given in bins, and since
104 // the fit range can be changed in the command block, these variables need to be accessible
105 fGoodBins[0] = -1;
106 fGoodBins[1] = -1;
107 fGoodBins[2] = -1;
108 fGoodBins[3] = -1;
109
110 fStartTimeBin = -1;
111 fEndTimeBin = -1;
112
113 fPacking = fRunInfo->GetPacking();
114 if (fPacking == -1) { // i.e. packing is NOT given in the RUN-block, it must be given in the GLOBAL-block
115 fPacking = fMsrInfo->GetMsrGlobal()->GetPacking();
116 }
117 if (fPacking == -1) { // this should NOT happen, somethin is severely wrong
118 std::cerr << std::endl << ">> PRunAsymmetry::PRunAsymmetry(): **SEVERE ERROR**: Couldn't find any packing information!";
119 std::cerr << std::endl << ">> This is very bad :-(, will quit ...";
120 std::cerr << std::endl;
121 fValid = false;
122 return;
123 }
124
125 // check if alpha and/or beta is fixed --------------------
126
127 PMsrParamList *param = msrInfo->GetMsrParamList();
128
129 // check if alpha is given
130 if (fRunInfo->GetAlphaParamNo() == -1) { // no alpha given
131 std::cerr << std::endl << ">> PRunAsymmetry::PRunAsymmetry(): **ERROR** no alpha parameter given! This is needed for an asymmetry fit!";
132 std::cerr << std::endl;
133 fValid = false;
134 return;
135 }
136 // check if alpha parameter is within proper bounds
137 if (fRunInfo->GetAlphaParamNo() >= MSR_PARAM_FUN_OFFSET) { // alpha seems to be a function
138 if ((fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET < 0) ||
139 (fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET > msrInfo->GetNoOfFuncs())) {
140 std::cerr << std::endl << ">> PRunAsymmetry::PRunAsymmetry(): **ERROR** alpha parameter is a function with no = " << fRunInfo->GetAlphaParamNo();
141 std::cerr << std::endl << ">> This is out of bound, since there are only " << msrInfo->GetNoOfFuncs() << " functions.";
142 std::cerr << std::endl;
143 fValid = false;
144 return;
145 }
146 } else if ((fRunInfo->GetAlphaParamNo() < 0) || (fRunInfo->GetAlphaParamNo() > static_cast<Int_t>(param->size()))) {
147 std::cerr << std::endl << ">> PRunAsymmetry::PRunAsymmetry(): **ERROR** alpha parameter no = " << fRunInfo->GetAlphaParamNo();
148 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
149 std::cerr << std::endl;
150 fValid = false;
151 return;
152 }
153 // check if alpha is fixed
154 Bool_t alphaFixedToOne = false;
155 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is parameter
156 if (((*param)[fRunInfo->GetAlphaParamNo()-1].fStep == 0.0) &&
157 ((*param)[fRunInfo->GetAlphaParamNo()-1].fValue == 1.0))
158 alphaFixedToOne = true;
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() < 0) || (fRunInfo->GetBetaParamNo() > static_cast<Int_t>(param->size()))) { // check if beta parameter is within proper bounds
165 std::cerr << std::endl << ">> PRunAsymmetry::PRunAsymmetry(): **ERROR** beta parameter no = " << fRunInfo->GetBetaParamNo();
166 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
167 std::cerr << std::endl;
168 fValid = false;
169 return;
170 } else { // check if beta is fixed
171 if (((*param)[fRunInfo->GetBetaParamNo()-1].fStep == 0.0) &&
172 ((*param)[fRunInfo->GetBetaParamNo()-1].fValue == 1.0))
173 betaFixedToOne = true;
174 }
175
176 // set fAlphaBetaTag
177 if (alphaFixedToOne && betaFixedToOne) // alpha == 1, beta == 1
178 fAlphaBetaTag = 1;
179 else if (!alphaFixedToOne && betaFixedToOne) // alpha != 1, beta == 1
180 fAlphaBetaTag = 2;
181 else if (alphaFixedToOne && !betaFixedToOne) // alpha == 1, beta != 1
182 fAlphaBetaTag = 3;
183 else
184 fAlphaBetaTag = 4;
185
186 // calculate fData
187 if (!PrepareData())
188 fValid = false;
189}
190
191//--------------------------------------------------------------------------
192// Destructor
193//--------------------------------------------------------------------------
201{
202 fForward.clear();
203 fForwardErr.clear();
204 fBackward.clear();
205 fBackwardErr.clear();
206}
207
208//--------------------------------------------------------------------------
209// CalcChiSquare (public)
210//--------------------------------------------------------------------------
228Double_t PRunAsymmetry::CalcChiSquare(const std::vector<Double_t>& par)
229{
230 Double_t chisq = 0.0;
231 Double_t diff = 0.0;
232 Double_t asymFcnValue = 0.0;
233 Double_t a, b, f;
234
235 // calculate functions
236 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
237 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
238 }
239
240 // calculate chi square
241 Double_t time(1.0);
242 Int_t i;
243
244 // determine alpha/beta
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 default:
291 a = 1.0;
292 b = 1.0;
293 break;
294 }
295
296 // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
297 // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
298 // for a given set of parameters---which should be done outside of the parallelized loop.
299 // For all other functions it means a tiny and acceptable overhead.
300 asymFcnValue = fTheory->Func(time, par, fFuncValues);
301
302 #ifdef HAVE_GOMP
303 Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
304 if (chunk < 10)
305 chunk = 10;
306 #pragma omp parallel for default(shared) private(i,time,diff,asymFcnValue,f) schedule(dynamic,chunk) reduction(+:chisq)
307 #endif
308 for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
309 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
310 f = fTheory->Func(time, par, fFuncValues);
311 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
312 diff = fData.GetValue()->at(i) - asymFcnValue;
313 chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
314 }
315
316 return chisq;
317}
318
319//--------------------------------------------------------------------------
320// CalcChiSquareExpected (public)
321//--------------------------------------------------------------------------
335Double_t PRunAsymmetry::CalcChiSquareExpected(const std::vector<Double_t>& par)
336{
337 return 0.0;
338}
339
340//--------------------------------------------------------------------------
341// CalcMaxLikelihood (public)
342//--------------------------------------------------------------------------
355Double_t PRunAsymmetry::CalcMaxLikelihood(const std::vector<Double_t>& par)
356{
357 std::cout << std::endl << "PRunAsymmetry::CalcMaxLikelihood(): not implemented yet ..." << std::endl;
358
359 return 1.0;
360}
361
362//--------------------------------------------------------------------------
363// GetNoOfFitBins (public)
364//--------------------------------------------------------------------------
375{
377
378 return fNoOfFitBins;
379}
380
381//--------------------------------------------------------------------------
382// SetFitRangeBin (public)
383//--------------------------------------------------------------------------
406void PRunAsymmetry::SetFitRangeBin(const TString fitRange)
407{
408 TString str;
409 Ssiz_t idx = -1;
410 Int_t offset = 0;
411
412 std::vector<std::string> tok = PStringUtils::Split(fitRange.Data(), " \t");
413
414 if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1
415 // handle fgb+n0 entry
416 str = tok[1];
417 // check if there is an offset present
418 idx = str.First("+");
419 if (idx != -1) { // offset present
420 str.Remove(0, idx+1);
421 if (str.IsFloat()) // if str is a valid number, convert is to an integer
422 offset = str.Atoi();
423 }
424 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
425
426 // handle lgb-n1 entry
427 str = tok[2];
428 // check if there is an offset present
429 idx = str.First("-");
430 if (idx != -1) { // offset present
431 str.Remove(0, idx+1);
432 if (str.IsFloat()) // if str is a valid number, convert is to an integer
433 offset = str.Atoi();
434 }
435 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
436 } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
437 UInt_t pos = 2*(fRunNo+1)-1;
438
439 if (pos + 1 >= tok.size()) {
440 std::cerr << std::endl << ">> PRunAsymmetry::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
441 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
442 } else {
443 // handle fgb+n0 entry
444 str = tok[pos];
445 // check if there is an offset present
446 idx = str.First("+");
447 if (idx != -1) { // offset present
448 str.Remove(0, idx+1);
449 if (str.IsFloat()) // if str is a valid number, convert is to an integer
450 offset = str.Atoi();
451 }
452 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
453
454 // handle lgb-n1 entry
455 str = tok[pos+1];
456 // check if there is an offset present
457 idx = str.First("-");
458 if (idx != -1) { // offset present
459 str.Remove(0, idx+1);
460 if (str.IsFloat()) // if str is a valid number, convert is to an integer
461 offset = str.Atoi();
462 }
463 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
464 }
465 } else { // error
466 std::cerr << std::endl << ">> PRunAsymmetry::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
467 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
468 }
469}
470
471//--------------------------------------------------------------------------
472// CalcNoOfFitBins (public)
473//--------------------------------------------------------------------------
487{
488 // In order not having to loop over all bins and to stay consistent with the chisq method, calculate the start and end bins explicitly
489 fStartTimeBin = static_cast<Int_t>(ceil((fFitStartTime - fData.GetDataTimeStart())/fData.GetDataTimeStep()));
490 if (fStartTimeBin < 0)
491 fStartTimeBin = 0;
492 fEndTimeBin = static_cast<Int_t>(floor((fFitEndTime - fData.GetDataTimeStart())/fData.GetDataTimeStep())) + 1;
493 if (fEndTimeBin > static_cast<Int_t>(fData.GetValue()->size()))
494 fEndTimeBin = fData.GetValue()->size();
495
497 fNoOfFitBins = static_cast<UInt_t>(fEndTimeBin - fStartTimeBin);
498 else
499 fNoOfFitBins = 0;
500}
501
502//--------------------------------------------------------------------------
503// CalcTheory (protected)
504//--------------------------------------------------------------------------
522{
523 // feed the parameter vector
524 std::vector<Double_t> par;
525 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
526 for (UInt_t i=0; i<paramList->size(); i++)
527 par.push_back((*paramList)[i].fValue);
528
529 // calculate functions
530 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
531 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
532 }
533
534 // calculate asymmetry
535 Double_t asymFcnValue = 0.0;
536 Double_t a, b, f;
537 Double_t time;
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));
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));
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));
587 break;
588 default:
589 asymFcnValue = 0.0;
590 break;
591 }
592 fData.AppendTheoryValue(asymFcnValue);
593 }
594
595 // clean up
596 par.clear();
597}
598
599//--------------------------------------------------------------------------
600// PrepareData (protected)
601//--------------------------------------------------------------------------
630{
631 if (!fValid)
632 return false;
633
634 // keep the Global block info
635 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
636
637 // get forward/backward histo from PRunDataHandler object ------------------------
638 // get the correct run
639 PRawRunData *runData = fRawData->GetRunData(*(fRunInfo->GetRunName()));
640 if (!runData) { // run not found
641 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **ERROR** Couldn't get run " << fRunInfo->GetRunName()->Data() << "!";
642 std::cerr << std::endl;
643 return false;
644 }
645
646 // keep the field from the meta-data from the data-file
647 fMetaData.fField = runData->GetField();
648
649 // keep the energy from the meta-data from the data-file
650 fMetaData.fEnergy = runData->GetEnergy();
651
652 // keep the temperature(s) from the meta-data from the data-file
653 for (unsigned int i=0; i<runData->GetNoOfTemperatures(); i++)
654 fMetaData.fTemp.push_back(runData->GetTemperature(i));
655
656 // collect histogram numbers
657 PUIntVector forwardHistoNo;
658 PUIntVector backwardHistoNo;
659 for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
660 forwardHistoNo.push_back(fRunInfo->GetForwardHistoNo(i));
661
662 if (!runData->IsPresent(forwardHistoNo[i])) {
663 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **PANIC ERROR**:";
664 std::cerr << std::endl << ">> forwardHistoNo found = " << forwardHistoNo[i] << ", which is NOT present in the data file!?!?";
665 std::cerr << std::endl << ">> Will quit :-(";
666 std::cerr << std::endl;
667 // clean up
668 forwardHistoNo.clear();
669 backwardHistoNo.clear();
670 return false;
671 }
672 }
673 for (UInt_t i=0; i<fRunInfo->GetBackwardHistoNoSize(); i++) {
674 backwardHistoNo.push_back(fRunInfo->GetBackwardHistoNo(i));
675
676 if (!runData->IsPresent(backwardHistoNo[i])) {
677 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **PANIC ERROR**:";
678 std::cerr << std::endl << ">> backwardHistoNo found = " << backwardHistoNo[i] << ", which is NOT present in the data file!?!?";
679 std::cerr << std::endl << ">> Will quit :-(";
680 std::cerr << std::endl;
681 // clean up
682 forwardHistoNo.clear();
683 backwardHistoNo.clear();
684 return false;
685 }
686 }
687
688 // keep the time resolution in (us)
689 fTimeResolution = runData->GetTimeResolution()/1.0e3;
690 std::cout.precision(10);
691 std::cout << std::endl << ">> PRunAsymmetry::PrepareData(): time resolution=" << std::fixed << runData->GetTimeResolution() << "(ns)" << std::endl;
692
693 // get all the proper t0's and addt0's for the current RUN block
694 if (!GetProperT0(runData, globalBlock, forwardHistoNo, backwardHistoNo)) {
695 return false;
696 }
697
698 // keep the histo of each group at this point (addruns handled below)
699 std::vector<PDoubleVector> forward, backward;
700 forward.resize(forwardHistoNo.size()); // resize to number of groups
701 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
702 forward[i].resize(runData->GetDataBin(forwardHistoNo[i])->size());
703 forward[i] = *runData->GetDataBin(forwardHistoNo[i]);
704 }
705 // check if a dead time correction has to be done
706 // this will be done automatically in the function itself, which also
707 // checks in the global and run section
708 DeadTimeCorrection(forward, forwardHistoNo);
709
710 backward.resize(backwardHistoNo.size()); // resize to number of groups
711 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
712 backward[i].resize(runData->GetDataBin(backwardHistoNo[i])->size());
713 backward[i] = *runData->GetDataBin(backwardHistoNo[i]);
714 }
715 // check if a dead time correction has to be done
716 // this will be done automatically in the function itself, which also
717 // checks in the global and run section
718 DeadTimeCorrection(backward, backwardHistoNo);
719
720 // check if addrun's are present, and if yes add data
721 // check if there are runs to be added to the current one
722 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
723 PRawRunData *addRunData;
724 std::vector<PDoubleVector> addForward, addBackward;
725 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
726 // get run to be added to the main one
727 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
728 if (addRunData == nullptr) { // couldn't get run
729 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
730 std::cerr << std::endl;
731 return false;
732 }
733
734 // dead time correction handling
735 addForward.clear();
736 addForward.resize(forwardHistoNo.size());
737 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
738 addForward[j].resize(addRunData->GetDataBin(forwardHistoNo[j])->size());
739 addForward[j] = *addRunData->GetDataBin(forwardHistoNo[j]);
740 }
741 DeadTimeCorrection(addForward, forwardHistoNo);
742 addBackward.clear();
743 addBackward.resize(backwardHistoNo.size());
744 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
745 addBackward[j].resize(addRunData->GetDataBin(backwardHistoNo[j])->size());
746 addBackward[j] = *addRunData->GetDataBin(backwardHistoNo[j]);
747 }
748 DeadTimeCorrection(addBackward, backwardHistoNo);
749
750 // add forward run
751 UInt_t addRunSize;
752 for (UInt_t k=0; k<forwardHistoNo.size(); k++) { // fill each group
753 addRunSize = addRunData->GetDataBin(forwardHistoNo[k])->size();
754 for (UInt_t j=0; j<addRunData->GetDataBin(forwardHistoNo[k])->size(); j++) { // loop over the bin indices
755 // make sure that the index stays in the proper range
756 if ((static_cast<Int_t>(j)+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]) >= 0) &&
757 (j+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]) < addRunSize)) {
758 forward[k][j] += addForward[k][j+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k])];
759 }
760 }
761 }
762
763 // add backward run
764 for (UInt_t k=0; k<backwardHistoNo.size(); k++) { // fill each group
765 addRunSize = addRunData->GetDataBin(backwardHistoNo[k])->size();
766 for (UInt_t j=0; j<addRunData->GetDataBin(backwardHistoNo[k])->size(); j++) { // loop over the bin indices
767 // make sure that the index stays in the proper range
768 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) &&
769 (j+static_cast<Int_t>(fAddT0s[i-1][2*k+1])-static_cast<Int_t>(fT0s[2*k+1]) < addRunSize)) {
770 backward[k][j] += addBackward[k][j+static_cast<Int_t>(fAddT0s[i-1][2*k+1])-static_cast<Int_t>(fT0s[2*k+1])];
771 }
772 }
773 }
774 }
775 }
776
777 // set forward/backward histo data of the first group
778 fForward.resize(forward[0].size());
779 for (UInt_t i=0; i<fForward.size(); i++) {
780 fForward[i] = forward[0][i];
781 }
782 fBackward.resize(backward[0].size());
783 for (UInt_t i=0; i<fBackward.size(); i++) {
784 fBackward[i] = backward[0][i];
785 }
786
787 // group histograms, add all the remaining forward histograms of the group
788 for (UInt_t i=1; i<forwardHistoNo.size(); i++) { // loop over the groupings
789 for (UInt_t j=0; j<runData->GetDataBin(forwardHistoNo[i])->size(); j++) { // loop over the bin indices
790 // make sure that the index stays within proper range
791 if ((j+fT0s[2*i]-fT0s[0] >= 0) && (j+fT0s[2*i]-fT0s[0] < runData->GetDataBin(forwardHistoNo[i])->size())) {
792 fForward[j] += forward[i][j+static_cast<Int_t>(fT0s[2*i])-static_cast<Int_t>(fT0s[0])];
793 }
794 }
795 }
796
797 // group histograms, add all the remaining backward histograms of the group
798 for (UInt_t i=1; i<backwardHistoNo.size(); i++) { // loop over the groupings
799 for (UInt_t j=0; j<runData->GetDataBin(backwardHistoNo[i])->size(); j++) { // loop over the bin indices
800 // make sure that the index stays within proper range
801 if ((j+fT0s[2*i+1]-fT0s[1] >= 0) && (j+fT0s[2*i+1]-fT0s[1] < runData->GetDataBin(backwardHistoNo[i])->size())) {
802 fBackward[j] += backward[i][j+static_cast<Int_t>(fT0s[2*i+1])-static_cast<Int_t>(fT0s[1])];
803 }
804 }
805 }
806
807 // subtract background from histogramms ------------------------------------------
808 if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) { // no fixed background given
809 if (fRunInfo->GetBkgRange(0) >= 0) { // background range given
811 return false;
812 } else { // no background given to do the job, try to estimate it
813 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.1), 0);
814 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.6), 1);
815 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.1), 2);
816 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.6), 3);
817 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **WARNING** Neither fix background nor background bins are given!";
818 std::cerr << std::endl << ">> Will try the following:";
819 std::cerr << std::endl << ">> forward: bkg start = " << fRunInfo->GetBkgRange(0) << ", bkg end = " << fRunInfo->GetBkgRange(1);
820 std::cerr << std::endl << ">> backward: bkg start = " << fRunInfo->GetBkgRange(2) << ", bkg end = " << fRunInfo->GetBkgRange(3);
821 std::cerr << std::endl << ">> NO WARRANTY THAT THIS MAKES ANY SENSE! Better check ...";
822 std::cerr << std::endl;
824 return false;
825 }
826 } else { // fixed background given
827 if (!SubtractFixBkg())
828 return false;
829 }
830
831 UInt_t histoNo[2] = {forwardHistoNo[0], backwardHistoNo[0]};
832
833 // get the data range (fgb/lgb) for the current RUN block
834 if (!GetProperDataRange(runData, histoNo)) {
835 return false;
836 }
837
838 // get the fit range for the current RUN block
839 GetProperFitRange(globalBlock);
840
841 // everything looks fine, hence fill data set
842 Bool_t status;
843 switch(fHandleTag) {
844 case kFit:
846 break;
847 case kView:
848 if (fMsrInfo->GetMsrPlotList()->at(0).fRRFPacking == 0)
849 status = PrepareViewData(runData, histoNo);
850 else
851 status = PrepareRRFViewData(runData, histoNo);
852 break;
853 default:
854 status = false;
855 break;
856 }
857
858 // clean up
859 forwardHistoNo.clear();
860 backwardHistoNo.clear();
861
862 return status;
863}
864
865//--------------------------------------------------------------------------
866// SubtractFixBkg (private)
867//--------------------------------------------------------------------------
885{
886 if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) {
887 std::cerr << "PRunAsymmetry::SubtractFixBkg(): **ERROR** no fixed bkg for forward set. Will do nothing here." << std::endl;
888 return false;
889 }
890 if (fRunInfo->GetBkgFix(1) == PMUSR_UNDEFINED) {
891 std::cerr << "PRunAsymmetry::SubtractFixBkg(): **ERROR** no fixed bkg for backward set. Will do nothing here." << std::endl;
892 std::cerr << " you need an entry like:" << std::endl;
893 std::cerr << " backgr.fix 2 3" << std::endl;
894 std::cerr << " i.e. two entries for forward and backward." << std::endl;
895 return false;
896 }
897
898
899 Double_t dval;
900
901 for (UInt_t i=0; i<fForward.size(); i++) {
902 // keep the error, and make sure that the bin is NOT empty
903 if (fForward[i] != 0.0)
904 dval = TMath::Sqrt(fForward[i]);
905 else
906 dval = 1.0;
907 fForwardErr.push_back(dval);
908 fForward[i] -= fRunInfo->GetBkgFix(0);
909
910 // keep the error, and make sure that the bin is NOT empty
911 if (fBackward[i] != 0.0)
912 dval = TMath::Sqrt(fBackward[i]);
913 else
914 dval = 1.0;
915 fBackwardErr.push_back(dval);
916 fBackward[i] -= fRunInfo->GetBkgFix(1);
917 }
918
919 return true;
920}
921
922//--------------------------------------------------------------------------
923// SubtractEstimatedBkg (private)
924//--------------------------------------------------------------------------
943{
944 Double_t beamPeriod = 0.0;
945
946 // check if data are from PSI, RAL, or TRIUMF
947 if (fRunInfo->GetInstitute()->Contains("psi"))
948 beamPeriod = ACCEL_PERIOD_PSI;
949 else if (fRunInfo->GetInstitute()->Contains("ral"))
950 beamPeriod = ACCEL_PERIOD_RAL;
951 else if (fRunInfo->GetInstitute()->Contains("triumf"))
952 beamPeriod = ACCEL_PERIOD_TRIUMF;
953 else
954 beamPeriod = 0.0;
955
956 // check if start and end are in proper order
957 Int_t start[2] = {fRunInfo->GetBkgRange(0), fRunInfo->GetBkgRange(2)};
958 Int_t end[2] = {fRunInfo->GetBkgRange(1), fRunInfo->GetBkgRange(3)};
959 for (UInt_t i=0; i<2; i++) {
960 if (end[i] < start[i]) {
961 std::cout << std::endl << ">> PRunAsymmetry::SubtractEstimatedBkg(): end = " << end[i] << " > start = " << start[i] << "! Will swap them!";
962 UInt_t keep = end[i];
963 end[i] = start[i];
964 start[i] = keep;
965 }
966 }
967
968 // calculate proper background range
969 for (UInt_t i=0; i<2; i++) {
970 if (beamPeriod != 0.0) {
971 Double_t timeBkg = static_cast<Double_t>(end[i]-start[i])*(fTimeResolution*fPacking); // length of the background intervall in time
972 UInt_t fullCycles = static_cast<UInt_t>(timeBkg/beamPeriod); // how many proton beam cylces can be placed within the proposed background intervall
973 // correct the end of the background intervall such that the background is as close as possible to a multiple of the proton cylce
974 end[i] = start[i] + static_cast<UInt_t>((fullCycles*beamPeriod)/(fTimeResolution*fPacking));
975 std::cout << ">> PRunAsymmetry::SubtractEstimatedBkg(): Background " << start[i] << ", " << end[i] << std::endl;
976 if (end[i] == start[i])
977 end[i] = fRunInfo->GetBkgRange(2*i+1);
978 }
979 }
980
981 // check if start is within histogram bounds
982 if ((start[0] < 0) || (start[0] >= fForward.size()) ||
983 (start[1] < 0) || (start[1] >= fBackward.size())) {
984 std::cerr << std::endl << ">> PRunAsymmetry::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
985 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
986 std::cerr << std::endl << ">> background start (f/b) = (" << start[0] << "/" << start[1] << ").";
987 return false;
988 }
989
990 // check if end is within histogram bounds
991 if ((end[0] < 0) || (end[0] >= fForward.size()) ||
992 (end[1] < 0) || (end[1] >= fBackward.size())) {
993 std::cerr << std::endl << ">> PRunAsymmetry::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
994 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
995 std::cerr << std::endl << ">> background end (f/b) = (" << end[0] << "/" << end[1] << ").";
996 return false;
997 }
998
999 // calculate background
1000 Double_t bkg[2] = {0.0, 0.0};
1001 Double_t errBkg[2] = {0.0, 0.0};
1002
1003 // forward
1004 for (UInt_t i=start[0]; i<=end[0]; i++)
1005 bkg[0] += fForward[i];
1006 errBkg[0] = TMath::Sqrt(bkg[0])/(end[0] - start[0] + 1);
1007 bkg[0] /= static_cast<Double_t>(end[0] - start[0] + 1);
1008 std::cout << std::endl << ">> estimated forward histo background: " << bkg[0];
1009
1010 // backward
1011 for (UInt_t i=start[1]; i<=end[1]; i++)
1012 bkg[1] += fBackward[i];
1013 errBkg[1] = TMath::Sqrt(bkg[1])/(end[1] - start[1] + 1);
1014 bkg[1] /= static_cast<Double_t>(end[1] - start[1] + 1);
1015 std::cout << std::endl << ">> estimated backward histo background: " << bkg[1] << std::endl;
1016
1017 // correct error for forward, backward
1018 Double_t errVal = 0.0;
1019 for (UInt_t i=0; i<fForward.size(); i++) {
1020 if (fForward[i] > 0.0)
1021 errVal = TMath::Sqrt(fForward[i]+errBkg[0]*errBkg[0]);
1022 else
1023 errVal = 1.0;
1024 fForwardErr.push_back(errVal);
1025 if (fBackward[i] > 0.0)
1026 errVal = TMath::Sqrt(fBackward[i]+errBkg[1]*errBkg[1]);
1027 else
1028 errVal = 1.0;
1029 fBackwardErr.push_back(errVal);
1030 }
1031
1032 // subtract background from data
1033 for (UInt_t i=0; i<fForward.size(); i++) {
1034 fForward[i] -= bkg[0];
1035 fBackward[i] -= bkg[1];
1036 }
1037
1038 fRunInfo->SetBkgEstimated(bkg[0], 0);
1039 fRunInfo->SetBkgEstimated(bkg[1], 1);
1040
1041 return true;
1042}
1043
1044//--------------------------------------------------------------------------
1045// PrepareFitData (protected)
1046//--------------------------------------------------------------------------
1068{
1069 // transform raw histo data. This is done the following way (for details see the manual):
1070 // first rebin the data, than calculate the asymmetry
1071
1072 // everything looks fine, hence fill packed forward and backward histo
1073 PRunData forwardPacked;
1074 PRunData backwardPacked;
1075 Double_t value = 0.0;
1076 Double_t error = 0.0;
1077 // forward
1078 for (Int_t i=fGoodBins[0]; i<fGoodBins[1]; i++) {
1079 if (fPacking == 1) {
1080 forwardPacked.AppendValue(fForward[i]);
1081 forwardPacked.AppendErrorValue(fForwardErr[i]);
1082 } else { // packed data, i.e. fPacking > 1
1083 if (((i-fGoodBins[0]) % fPacking == 0) && (i != fGoodBins[0])) { // fill data
1084 // in order that after rebinning the fit does not need to be redone (important for plots)
1085 // the value is normalize to per bin
1086 value /= fPacking;
1087 forwardPacked.AppendValue(value);
1088 if (value == 0.0)
1089 forwardPacked.AppendErrorValue(1.0);
1090 else
1091 forwardPacked.AppendErrorValue(TMath::Sqrt(error)/fPacking);
1092 value = 0.0;
1093 error = 0.0;
1094 }
1095 value += fForward[i];
1096 error += fForwardErr[i]*fForwardErr[i];
1097 }
1098 }
1099 // backward
1100 for (Int_t i=fGoodBins[2]; i<fGoodBins[3]; i++) {
1101 if (fPacking == 1) {
1102 backwardPacked.AppendValue(fBackward[i]);
1103 backwardPacked.AppendErrorValue(fBackwardErr[i]);
1104 } else { // packed data, i.e. fPacking > 1
1105 if (((i-fGoodBins[2]) % fPacking == 0) && (i != fGoodBins[2])) { // fill data
1106 // in order that after rebinning the fit does not need to be redone (important for plots)
1107 // the value is normalize to per bin
1108 value /= fPacking;
1109 backwardPacked.AppendValue(value);
1110 if (value == 0.0)
1111 backwardPacked.AppendErrorValue(1.0);
1112 else
1113 backwardPacked.AppendErrorValue(TMath::Sqrt(error)/fPacking);
1114 value = 0.0;
1115 error = 0.0;
1116 }
1117 value += fBackward[i];
1118 error += fBackwardErr[i]*fBackwardErr[i];
1119 }
1120 }
1121
1122 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1123 UInt_t noOfBins = forwardPacked.GetValue()->size();
1124 if (forwardPacked.GetValue()->size() != backwardPacked.GetValue()->size()) {
1125 if (forwardPacked.GetValue()->size() > backwardPacked.GetValue()->size())
1126 noOfBins = backwardPacked.GetValue()->size();
1127 }
1128
1129 // form asymmetry including error propagation
1130 Double_t asym;
1131 Double_t f, b, ef, eb;
1132 // fill data time start, and step
1133 // data start time = (binStart - 0.5) + pack/2 - t0, with pack and binStart used as double
1134 fData.SetDataTimeStart(fTimeResolution*((static_cast<Double_t>(fGoodBins[0])-0.5) + static_cast<Double_t>(fPacking)/2.0 - static_cast<Double_t>(fT0s[0])));
1135 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(fPacking));
1136 for (UInt_t i=0; i<noOfBins; i++) {
1137 // to make the formulae more readable
1138 f = forwardPacked.GetValue()->at(i);
1139 b = backwardPacked.GetValue()->at(i);
1140 ef = forwardPacked.GetError()->at(i);
1141 eb = backwardPacked.GetError()->at(i);
1142 // check that there are indeed bins
1143 if (f+b != 0.0)
1144 asym = (f-b) / (f+b);
1145 else
1146 asym = 0.0;
1147 fData.AppendValue(asym);
1148 // calculate the error
1149 if (f+b != 0.0)
1150 error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
1151 else
1152 error = 1.0;
1153 fData.AppendErrorValue(error);
1154 }
1155
1157
1158 // clean up
1159 fForward.clear();
1160 fForwardErr.clear();
1161 fBackward.clear();
1162 fBackwardErr.clear();
1163
1164 return true;
1165}
1166
1167//--------------------------------------------------------------------------
1168// PrepareViewData (protected)
1169//--------------------------------------------------------------------------
1191Bool_t PRunAsymmetry::PrepareViewData(PRawRunData* runData, UInt_t histoNo[2])
1192{
1193 // check if view_packing is wished
1194 Int_t packing = fPacking;
1195 if (fMsrInfo->GetMsrPlotList()->at(0).fViewPacking > 0) {
1196 packing = fMsrInfo->GetMsrPlotList()->at(0).fViewPacking;
1197 }
1198
1199 // feed the parameter vector
1200 std::vector<Double_t> par;
1201 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
1202 for (UInt_t i=0; i<paramList->size(); i++)
1203 par.push_back((*paramList)[i].fValue);
1204
1205 // transform raw histo data. This is done the following way (for details see the manual):
1206 // first rebin the data, than calculate the asymmetry
1207
1208 // first get start data, end data, and t0
1209 Int_t start[2] = {fGoodBins[0], fGoodBins[2]};
1210 Int_t end[2] = {fGoodBins[1], fGoodBins[3]};
1211 Int_t t0[2] = {static_cast<Int_t>(fT0s[0]), static_cast<Int_t>(fT0s[1])};
1212
1213 // check if the data ranges and t0's between forward/backward are compatible
1214 Int_t fgb[2];
1215 if (start[0]-t0[0] != start[1]-t0[1]) { // wrong fgb aligning
1216 if (abs(start[0]-t0[0]) > abs(start[1]-t0[1])) {
1217 fgb[0] = start[0];
1218 fgb[1] = t0[1] + start[0]-t0[0];
1219 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **WARNING** needed to shift backward fgb from ";
1220 std::cerr << start[1] << " to " << fgb[1] << std::endl;
1221 } else {
1222 fgb[0] = t0[0] + start[1]-t0[1];
1223 fgb[1] = start[1];
1224 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **WARNING** needed to shift forward fgb from ";
1225 std::cerr << start[0] << " to " << fgb[0] << std::endl;
1226 }
1227 } else { // fgb aligning is correct
1228 fgb[0] = start[0];
1229 fgb[1] = start[1];
1230 }
1231
1232 Int_t val = fgb[0]-packing*(fgb[0]/packing);
1233 do {
1234 if (fgb[1] - fgb[0] < 0)
1235 val += packing;
1236 } while (val + fgb[1] - fgb[0] < 0);
1237
1238 start[0] = val;
1239 start[1] = val + fgb[1] - fgb[0];
1240
1241 // make sure that there are equal number of rebinned bins in forward and backward
1242 UInt_t noOfBins0 = (runData->GetDataBin(histoNo[0])->size()-start[0])/packing;
1243 UInt_t noOfBins1 = (runData->GetDataBin(histoNo[1])->size()-start[1])/packing;
1244 if (noOfBins0 > noOfBins1)
1245 noOfBins0 = noOfBins1;
1246 end[0] = start[0] + noOfBins0 * packing;
1247 end[1] = start[1] + noOfBins0 * packing;
1248
1249 // check if start, end, and t0 make any sense
1250 // 1st check if start and end are in proper order
1251 for (UInt_t i=0; i<2; i++) {
1252 if (end[i] < start[i]) { // need to swap them
1253 Int_t keep = end[i];
1254 end[i] = start[i];
1255 start[i] = keep;
1256 }
1257 // 2nd check if start is within proper bounds
1258 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1259 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **ERROR** start data bin doesn't make any sense!";
1260 std::cerr << std::endl;
1261 return false;
1262 }
1263 // 3rd check if end is within proper bounds
1264 if ((end[i] < 0) || (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1265 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **ERROR** end data bin doesn't make any sense!";
1266 std::cerr << std::endl;
1267 return false;
1268 }
1269 // 4th check if t0 is within proper bounds
1270 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1271 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **ERROR** t0 data bin doesn't make any sense!";
1272 std::cerr << std::endl;
1273 return false;
1274 }
1275 }
1276
1277 // everything looks fine, hence fill packed forward and backward histo
1278 PRunData forwardPacked;
1279 PRunData backwardPacked;
1280 Double_t value = 0.0;
1281 Double_t error = 0.0;
1282
1283 // forward
1284 for (Int_t i=start[0]; i<end[0]; i++) {
1285 if (packing == 1) {
1286 forwardPacked.AppendValue(fForward[i]);
1287 forwardPacked.AppendErrorValue(fForwardErr[i]);
1288 } else { // packed data, i.e. packing > 1
1289 if (((i-start[0]) % packing == 0) && (i != start[0])) { // fill data
1290 // in order that after rebinning the fit does not need to be redone (important for plots)
1291 // the value is normalize to per bin
1292 value /= packing;
1293 forwardPacked.AppendValue(value);
1294 if (value == 0.0)
1295 forwardPacked.AppendErrorValue(1.0);
1296 else
1297 forwardPacked.AppendErrorValue(TMath::Sqrt(error)/packing);
1298 value = 0.0;
1299 error = 0.0;
1300 }
1301 value += fForward[i];
1302 error += fForwardErr[i]*fForwardErr[i];
1303 }
1304 }
1305
1306 // backward
1307 for (Int_t i=start[1]; i<end[1]; i++) {
1308 if (packing == 1) {
1309 backwardPacked.AppendValue(fBackward[i]);
1310 backwardPacked.AppendErrorValue(fBackwardErr[i]);
1311 } else { // packed data, i.e. packing > 1
1312 if (((i-start[1]) % packing == 0) && (i != start[1])) { // fill data
1313 // in order that after rebinning the fit does not need to be redone (important for plots)
1314 // the value is normalize to per bin
1315 value /= packing;
1316 backwardPacked.AppendValue(value);
1317 if (value == 0.0)
1318 backwardPacked.AppendErrorValue(1.0);
1319 else
1320 backwardPacked.AppendErrorValue(TMath::Sqrt(error)/packing);
1321 value = 0.0;
1322 error = 0.0;
1323 }
1324 value += fBackward[i];
1325 error += fBackwardErr[i]*fBackwardErr[i];
1326 }
1327 }
1328
1329 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1330 UInt_t noOfBins = forwardPacked.GetValue()->size();
1331 if (forwardPacked.GetValue()->size() != backwardPacked.GetValue()->size()) {
1332 if (forwardPacked.GetValue()->size() > backwardPacked.GetValue()->size())
1333 noOfBins = backwardPacked.GetValue()->size();
1334 }
1335
1336 // form asymmetry including error propagation
1337 Double_t asym;
1338 Double_t f, b, ef, eb, alpha = 1.0, beta = 1.0;
1339 // set data time start, and step
1340 // data start time = (binStart - 0.5) + pack/2 - t0, with pack and binStart used as double
1341 fData.SetDataTimeStart(fTimeResolution*((static_cast<Double_t>(start[0])-0.5) + static_cast<Double_t>(packing)/2.0 - static_cast<Double_t>(t0[0])));
1342 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(packing));
1343
1344 // get the proper alpha and beta
1345 switch (fAlphaBetaTag) {
1346 case 1: // alpha == 1, beta == 1
1347 alpha = 1.0;
1348 beta = 1.0;
1349 break;
1350 case 2: // alpha != 1, beta == 1
1351 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1352 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1353 } else { // alpha is function
1354 // get function number
1355 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1356 // evaluate function
1357 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1358 }
1359 beta = 1.0;
1360 break;
1361 case 3: // alpha == 1, beta != 1
1362 alpha = 1.0;
1363 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1364 beta = par[fRunInfo->GetBetaParamNo()-1];
1365 } else { // beta is a function
1366 // get function number
1367 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1368 // evaluate function
1369 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1370 }
1371 break;
1372 case 4: // alpha != 1, beta != 1
1373 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1374 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1375 } else { // alpha is function
1376 // get function number
1377 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1378 // evaluate function
1379 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1380 }
1381 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1382 beta = par[fRunInfo->GetBetaParamNo()-1];
1383 } else { // beta is a function
1384 // get function number
1385 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1386 // evaluate function
1387 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1388 }
1389 break;
1390 default:
1391 break;
1392 }
1393
1394 for (UInt_t i=0; i<forwardPacked.GetValue()->size(); i++) {
1395 // to make the formulae more readable
1396 f = forwardPacked.GetValue()->at(i);
1397 b = backwardPacked.GetValue()->at(i);
1398 ef = forwardPacked.GetError()->at(i);
1399 eb = backwardPacked.GetError()->at(i);
1400 // check that there are indeed bins
1401 if (f+b != 0.0)
1402 asym = (alpha*f-b) / (alpha*beta*f+b);
1403 else
1404 asym = 0.0;
1405 fData.AppendValue(asym);
1406 // calculate the error
1407 if (f+b != 0.0)
1408 error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
1409 else
1410 error = 1.0;
1411 fData.AppendErrorValue(error);
1412 }
1413
1415
1416 // clean up
1417 fForward.clear();
1418 fForwardErr.clear();
1419 fBackward.clear();
1420 fBackwardErr.clear();
1421
1422 // fill theory vector for kView
1423 // calculate functions
1424 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
1425 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
1426 }
1427
1428 // calculate theory
1429 Double_t time;
1430 UInt_t size = runData->GetDataBin(histoNo[0])->size()/packing;
1431 Int_t factor = 8; // 8 times more points for the theory (if fTheoAsData == false)
1432
1433 fData.SetTheoryTimeStart(fData.GetDataTimeStart());
1434 if (fTheoAsData) { // calculate theory only at the data points
1435 fData.SetTheoryTimeStep(fData.GetDataTimeStep());
1436 } else {
1437 // finer binning for the theory (8 times as many points = factor)
1438 size *= factor;
1439 fData.SetTheoryTimeStep(fData.GetDataTimeStep()/(Double_t)factor);
1440 }
1441
1442 for (UInt_t i=0; i<size; i++) {
1443 time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
1444 value = fTheory->Func(time, par, fFuncValues);
1445 if (fabs(value) > 10.0) { // dirty hack needs to be fixed!!
1446 value = 0.0;
1447 }
1448 fData.AppendTheoryValue(value);
1449 }
1450
1451 // clean up
1452 par.clear();
1453
1454 return true;
1455}
1456
1457//--------------------------------------------------------------------------
1458// PrepareRRFViewData (protected)
1459//--------------------------------------------------------------------------
1483Bool_t PRunAsymmetry::PrepareRRFViewData(PRawRunData* runData, UInt_t histoNo[2])
1484{
1485 // feed the parameter vector
1486 std::vector<Double_t> par;
1487 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
1488 for (UInt_t i=0; i<paramList->size(); i++)
1489 par.push_back((*paramList)[i].fValue);
1490
1491 // ------------------------------------------------------------
1492 // 1. make all necessary checks
1493 // ------------------------------------------------------------
1494
1495 // first get start data, end data, and t0
1496 Int_t start[2] = {fGoodBins[0], fGoodBins[2]};
1497 Int_t end[2] = {fGoodBins[1], fGoodBins[3]};
1498 Int_t t0[2] = {static_cast<Int_t>(fT0s[0]), static_cast<Int_t>(fT0s[1])};
1499 UInt_t packing = fMsrInfo->GetMsrPlotList()->at(0).fRRFPacking;
1500
1501 // check if the data ranges and t0's between forward/backward are compatible
1502 Int_t fgb[2];
1503 if (start[0]-t0[0] != start[1]-t0[1]) { // wrong fgb aligning
1504 if (abs(start[0]-t0[0]) > abs(start[1]-t0[1])) {
1505 fgb[0] = start[0];
1506 fgb[1] = t0[1] + start[0]-t0[0];
1507 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **WARNING** needed to shift backward fgb from ";
1508 std::cerr << start[1] << " to " << fgb[1] << std::endl;
1509 } else {
1510 fgb[0] = t0[0] + start[1]-t0[1];
1511 fgb[1] = start[1];
1512 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **WARNING** needed to shift forward fgb from ";
1513 std::cerr << start[1] << " to " << fgb[0] << std::endl;
1514 }
1515 } else { // fgb aligning is correct
1516 fgb[0] = start[0];
1517 fgb[1] = start[1];
1518 }
1519
1520 Int_t val = fgb[0]-packing*(fgb[0]/packing);
1521 do {
1522 if (fgb[1] - fgb[0] < 0)
1523 val += packing;
1524 } while (val + fgb[1] - fgb[0] < 0);
1525
1526 start[0] = val;
1527 start[1] = val + fgb[1] - fgb[0];
1528
1529 // make sure that there are equal number of rebinned bins in forward and backward
1530 UInt_t noOfBins0 = runData->GetDataBin(histoNo[0])->size()-start[0];
1531 UInt_t noOfBins1 = runData->GetDataBin(histoNo[1])->size()-start[1];
1532 if (noOfBins0 > noOfBins1)
1533 noOfBins0 = noOfBins1;
1534 end[0] = start[0] + noOfBins0;
1535 end[1] = start[1] + noOfBins0;
1536
1537 // check if start, end, and t0 make any sense
1538 // 1st check if start and end are in proper order
1539 for (UInt_t i=0; i<2; i++) {
1540 if (end[i] < start[i]) { // need to swap them
1541 Int_t keep = end[i];
1542 end[i] = start[i];
1543 start[i] = keep;
1544 }
1545 // 2nd check if start is within proper bounds
1546 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1547 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **ERROR** start data bin doesn't make any sense!";
1548 std::cerr << std::endl;
1549 return false;
1550 }
1551 // 3rd check if end is within proper bounds
1552 if ((end[i] < 0) || (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1553 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **ERROR** end data bin doesn't make any sense!";
1554 std::cerr << std::endl;
1555 return false;
1556 }
1557 // 4th check if t0 is within proper bounds
1558 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1559 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **ERROR** t0 data bin doesn't make any sense!";
1560 std::cerr << std::endl;
1561 return false;
1562 }
1563 }
1564
1565 // ------------------------------------------------------------
1566 // 2. build the asymmetry [A(t)] WITHOUT packing.
1567 // ------------------------------------------------------------
1568
1569 PDoubleVector forward, forwardErr;
1570 PDoubleVector backward, backwardErr;
1571 Double_t error = 0.0;
1572 // forward
1573 for (Int_t i=start[0]; i<end[0]; i++) {
1574 forward.push_back(fForward[i]);
1575 forwardErr.push_back(fForwardErr[i]);
1576 }
1577 // backward
1578 for (Int_t i=start[1]; i<end[1]; i++) {
1579 backward.push_back(fBackward[i]);
1580 backwardErr.push_back(fBackwardErr[i]);
1581 }
1582
1583 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1584 UInt_t noOfBins = forward.size();
1585 if (forward.size() != backward.size()) {
1586 if (forward.size() > backward.size())
1587 noOfBins = backward.size();
1588 }
1589
1590 // form asymmetry including error propagation
1591 PDoubleVector asymmetry, asymmetryErr;
1592 Double_t asym;
1593 Double_t f, b, ef, eb, alpha = 1.0, beta = 1.0;
1594
1595 // get the proper alpha and beta
1596 switch (fAlphaBetaTag) {
1597 case 1: // alpha == 1, beta == 1
1598 alpha = 1.0;
1599 beta = 1.0;
1600 break;
1601 case 2: // alpha != 1, beta == 1
1602 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1603 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1604 } else { // alpha is function
1605 // get function number
1606 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1607 // evaluate function
1608 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1609 }
1610 beta = 1.0;
1611 break;
1612 case 3: // alpha == 1, beta != 1
1613 alpha = 1.0;
1614 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1615 beta = par[fRunInfo->GetBetaParamNo()-1];
1616 } else { // beta is a function
1617 // get function number
1618 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1619 // evaluate function
1620 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1621 }
1622 break;
1623 case 4: // alpha != 1, beta != 1
1624 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1625 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1626 } else { // alpha is function
1627 // get function number
1628 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1629 // evaluate function
1630 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1631 }
1632 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1633 beta = par[fRunInfo->GetBetaParamNo()-1];
1634 } else { // beta is a function
1635 // get function number
1636 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1637 // evaluate function
1638 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1639 }
1640 break;
1641 default:
1642 break;
1643 }
1644
1645 for (UInt_t i=0; i<noOfBins; i++) {
1646 // to make the formulae more readable
1647 f = forward[i];
1648 b = backward[i];
1649 ef = forwardErr[i];
1650 eb = backwardErr[i];
1651 // check that there are indeed bins
1652 if (f+b != 0.0)
1653 asym = (alpha*f-b) / (alpha*beta*f+b);
1654 else
1655 asym = 0.0;
1656 asymmetry.push_back(asym);
1657 // calculate the error
1658 if (f+b != 0.0)
1659 error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
1660 else
1661 error = 1.0;
1662 asymmetryErr.push_back(error);
1663 }
1664
1665 // clean up
1666 fForward.clear();
1667 fForwardErr.clear();
1668 fBackward.clear();
1669 fBackwardErr.clear();
1670
1671
1672 // ------------------------------------------------------------
1673 // 3. A_R(t) = A(t) * 2 cos(w_R t + phi_R)
1674 // ------------------------------------------------------------
1675
1676 // check which units shall be used
1677 Double_t gammaRRF = 0.0, wRRF = 0.0, phaseRRF = 0.0;
1678 Double_t time;
1679
1680 switch (fMsrInfo->GetMsrPlotList()->at(0).fRRFUnit) {
1681 case RRF_UNIT_kHz:
1682 gammaRRF = TMath::TwoPi()*1.0e-3;
1683 break;
1684 case RRF_UNIT_MHz:
1685 gammaRRF = TMath::TwoPi();
1686 break;
1687 case RRF_UNIT_Mcs:
1688 gammaRRF = 1.0;
1689 break;
1690 case RRF_UNIT_G:
1691 gammaRRF = GAMMA_BAR_MUON*TMath::TwoPi();
1692 break;
1693 case RRF_UNIT_T:
1694 gammaRRF = GAMMA_BAR_MUON*TMath::TwoPi()*1.0e4;
1695 break;
1696 default:
1697 gammaRRF = TMath::TwoPi();
1698 break;
1699 }
1700 wRRF = gammaRRF * fMsrInfo->GetMsrPlotList()->at(0).fRRFFreq;
1701 phaseRRF = fMsrInfo->GetMsrPlotList()->at(0).fRRFPhase / 180.0 * TMath::Pi();
1702
1703 for (UInt_t i=0; i<asymmetry.size(); i++) {
1704 time = fTimeResolution*(static_cast<Double_t>(start[0])-t0[0]+static_cast<Double_t>(i));
1705 asymmetry[i] *= 2.0*TMath::Cos(wRRF*time+phaseRRF);
1706 }
1707
1708 // ------------------------------------------------------------
1709 // 4. do the packing of A_R(t)
1710 // ------------------------------------------------------------
1711 Double_t value = 0.0;
1712 error = 0.0;
1713 for (UInt_t i=0; i<asymmetry.size(); i++) {
1714 if ((i % packing == 0) && (i != 0)) {
1715 value /= packing;
1716 fData.AppendValue(value);
1717 fData.AppendErrorValue(TMath::Sqrt(error)/packing);
1718
1719 value = 0.0;
1720 error = 0.0;
1721 }
1722 value += asymmetry[i];
1723 error += asymmetryErr[i]*asymmetryErr[i];
1724 }
1725
1726 // set data time start, and step
1727 // data start time = (binStart - 0.5) + pack/2 - t0, with pack and binStart used as double
1728 fData.SetDataTimeStart(fTimeResolution*((static_cast<Double_t>(start[0])-0.5) + static_cast<Double_t>(packing)/2.0 - static_cast<Double_t>(t0[0])));
1729 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(packing));
1730
1731 // ------------------------------------------------------------
1732 // 5. calculate theory [T(t)] as close as possible to the time resolution [compatible with the RRF frequency]
1733 // 6. T_R(t) = T(t) * 2 cos(w_R t + phi_R)
1734 // ------------------------------------------------------------
1735 UInt_t rebinRRF = static_cast<UInt_t>((TMath::Pi()/2.0/wRRF)/fTimeResolution); // RRF time resolution / data time resolution
1736 fData.SetTheoryTimeStart(fData.GetDataTimeStart());
1737 fData.SetTheoryTimeStep(TMath::Pi()/2.0/wRRF/rebinRRF); // = theory time resolution as close as possible to the data time resolution compatible with wRRF
1738
1739 // calculate functions
1740 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
1741 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
1742 }
1743
1744 Double_t theoryValue;
1745 for (UInt_t i=0; i<asymmetry.size(); i++) {
1746 time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
1747 theoryValue = fTheory->Func(time, par, fFuncValues);
1748 theoryValue *= 2.0*TMath::Cos(wRRF * time + phaseRRF);
1749
1750 if (fabs(theoryValue) > 10.0) { // dirty hack needs to be fixed!!
1751 theoryValue = 0.0;
1752 }
1753
1754 fData.AppendTheoryValue(theoryValue);
1755 }
1756
1757 // ------------------------------------------------------------
1758 // 7. do the packing of T_R(t)
1759 // ------------------------------------------------------------
1760
1761 PDoubleVector theo;
1762 Double_t dval = 0.0;
1763 for (UInt_t i=0; i<fData.GetTheory()->size(); i++) {
1764 if ((i % rebinRRF == 0) && (i != 0)) {
1765 theo.push_back(dval/rebinRRF);
1766 dval = 0.0;
1767 }
1768 dval += fData.GetTheory()->at(i);
1769 }
1770 fData.ReplaceTheory(theo);
1771 theo.clear();
1772
1773 // set the theory time start and step size
1774 fData.SetTheoryTimeStart(fData.GetTheoryTimeStart()+static_cast<Double_t>(rebinRRF-1)*fData.GetTheoryTimeStep()/2.0);
1775 fData.SetTheoryTimeStep(rebinRRF*fData.GetTheoryTimeStep());
1776
1777 // ------------------------------------------------------------
1778 // 8. calculate the Kaiser FIR filter coefficients
1779 // ------------------------------------------------------------
1780 CalculateKaiserFilterCoeff(wRRF, 60.0, 0.2); // w_c = wRRF, A = -20 log_10(delta), Delta w / w_c = (w_s - w_p) / (2 w_c)
1781
1782 // ------------------------------------------------------------
1783 // 9. filter T_R(t)
1784 // ------------------------------------------------------------
1785 FilterTheo();
1786
1787 // clean up
1788 par.clear();
1789 forward.clear();
1790 forwardErr.clear();
1791 backward.clear();
1792 backwardErr.clear();
1793 asymmetry.clear();
1794 asymmetryErr.clear();
1795
1796 return true;
1797}
1798
1799//--------------------------------------------------------------------------
1800// GetProperT0 (private)
1801//--------------------------------------------------------------------------
1830Bool_t PRunAsymmetry::GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHistoNo, PUIntVector &backwardHistoNo)
1831{
1832 // feed all T0's
1833 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1834 fT0s.clear();
1835 // this strange fT0 size estimate is needed in case #forw histos != #back histos
1836 size_t size = 2*forwardHistoNo.size();
1837 if (backwardHistoNo.size() > forwardHistoNo.size())
1838 size = 2*backwardHistoNo.size();
1839 fT0s.resize(size);
1840 for (UInt_t i=0; i<fT0s.size(); i++) {
1841 fT0s[i] = -1.0;
1842 }
1843
1844 // fill in the T0's from the msr-file (if present)
1845 for (UInt_t i=0; i<fRunInfo->GetT0BinSize(); i++) {
1846 fT0s[i] = fRunInfo->GetT0Bin(i);
1847 }
1848
1849 // fill in the missing T0's from the GLOBAL block section (if present)
1850 for (UInt_t i=0; i<globalBlock->GetT0BinSize(); i++) {
1851 if (fT0s[i] == -1) { // i.e. not given in the RUN block section
1852 fT0s[i] = globalBlock->GetT0Bin(i);
1853 }
1854 }
1855
1856 // fill in the missing T0's from the data file, if not already present in the msr-file
1857 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1858 if (fT0s[2*i] == -1.0) // i.e. not present in the msr-file, try the data file
1859 if (runData->GetT0Bin(forwardHistoNo[i]) > 0.0) {
1860 fT0s[2*i] = runData->GetT0Bin(forwardHistoNo[i]);
1861 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1862 }
1863 }
1864 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1865 if (fT0s[2*i+1] == -1.0) // i.e. not present in the msr-file, try the data file
1866 if (runData->GetT0Bin(backwardHistoNo[i]) > 0.0) {
1867 fT0s[2*i+1] = runData->GetT0Bin(backwardHistoNo[i]);
1868 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1869 }
1870 }
1871
1872 // 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
1873 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1874 if (fT0s[2*i] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1875 fT0s[2*i] = runData->GetT0BinEstimated(forwardHistoNo[i]);
1876 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1877
1878 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1879 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1880 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << runData->GetT0BinEstimated(forwardHistoNo[i]);
1881 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1882 std::cerr << std::endl;
1883 }
1884 }
1885 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1886 if (fT0s[2*i+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1887 fT0s[2*i+1] = runData->GetT0BinEstimated(backwardHistoNo[i]);
1888 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1889
1890 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1891 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1892 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[i]);
1893 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1894 std::cerr << std::endl;
1895 }
1896 }
1897
1898 // check if t0 is within proper bounds
1899 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1900 if ((fT0s[2*i] < 0) || (fT0s[2*i] > static_cast<Int_t>(runData->GetDataBin(forwardHistoNo[i])->size()))) {
1901 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **ERROR** t0 data bin (" << fT0s[2*i] << ") doesn't make any sense!";
1902 std::cerr << std::endl << ">> forwardHistoNo " << forwardHistoNo[i];
1903 std::cerr << std::endl;
1904 return false;
1905 }
1906 }
1907 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1908 if ((fT0s[2*i+1] < 0) || (fT0s[2*i+1] > static_cast<Int_t>(runData->GetDataBin(backwardHistoNo[i])->size()))) {
1909 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **ERROR** t0 data bin (" << fT0s[2*i+1] << ") doesn't make any sense!";
1910 std::cerr << std::endl << ">> backwardHistoNo " << backwardHistoNo[i];
1911 std::cerr << std::endl;
1912 return false;
1913 }
1914 }
1915
1916 // check if addrun's are present, and if yes add the necessary t0's
1917 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
1918 PRawRunData *addRunData;
1919 fAddT0s.resize(fRunInfo->GetRunNameSize()-1); // resize to the number of addruns
1920 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
1921 // get run to be added to the main one
1922 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
1923 if (addRunData == 0) { // couldn't get run
1924 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
1925 std::cerr << std::endl;
1926 return false;
1927 }
1928
1929 // feed all T0's
1930 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1931 fAddT0s[i-1].clear();
1932 fAddT0s[i-1].resize(2*forwardHistoNo.size());
1933 for (UInt_t j=0; j<fAddT0s[i-1].size(); j++) {
1934 fAddT0s[i-1][j] = -1.0;
1935 }
1936
1937 // fill in the T0's from the msr-file (if present)
1938 for (Int_t j=0; j<fRunInfo->GetAddT0BinSize(i-1); j++) {
1939 fAddT0s[i-1][j] = fRunInfo->GetAddT0Bin(i-1, j);
1940 }
1941
1942 // fill in the T0's from the data file, if not already present in the msr-file
1943 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1944 if (fAddT0s[i-1][2*j] == -1.0) // i.e. not present in the msr-file, try the data file
1945 if (addRunData->GetT0Bin(forwardHistoNo[j]) > 0.0) {
1946 fAddT0s[i-1][2*j] = addRunData->GetT0Bin(forwardHistoNo[j]);
1947 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1948 }
1949 }
1950 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1951 if (fAddT0s[i-1][2*j+1] == -1.0) // i.e. not present in the msr-file, try the data file
1952 if (addRunData->GetT0Bin(backwardHistoNo[j]) > 0.0) {
1953 fAddT0s[i-1][2*j+1] = addRunData->GetT0Bin(backwardHistoNo[j]);
1954 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1955 }
1956 }
1957
1958 // 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
1959 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1960 if (fAddT0s[i-1][2*j] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1961 fAddT0s[i-1][2*j] = addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1962 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1963
1964 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1965 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1966 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1967 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1968 std::cerr << std::endl;
1969 }
1970 }
1971 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1972 if (fAddT0s[i-1][2*j+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1973 fAddT0s[i-1][2*j+1] = addRunData->GetT0BinEstimated(backwardHistoNo[j]);
1974 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1975
1976 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1977 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1978 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[j]);
1979 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1980 std::cerr << std::endl;
1981 }
1982 }
1983 }
1984 }
1985
1986 return true;
1987}
1988
1989//--------------------------------------------------------------------------
1990// GetProperDataRange (private)
1991//--------------------------------------------------------------------------
2018Bool_t PRunAsymmetry::GetProperDataRange(PRawRunData* runData, UInt_t histoNo[2])
2019{
2020 // first get start/end data
2021 Int_t start[2] = {fRunInfo->GetDataRange(0), fRunInfo->GetDataRange(2)};
2022 Int_t end[2] = {fRunInfo->GetDataRange(1), fRunInfo->GetDataRange(3)};
2023 // check if data range has been provided in the RUN block. If not, try the GLOBAL block
2024 if (start[0] == -1) {
2025 start[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(0);
2026 }
2027 if (start[1] == -1) {
2028 start[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(2);
2029 }
2030 if (end[0] == -1) {
2031 end[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(1);
2032 }
2033 if (end[1] == -1) {
2034 end[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(3);
2035 }
2036
2037 Double_t t0[2] = {fT0s[0], fT0s[1]};
2038 Int_t offset = static_cast<Int_t>((10.0e-3/fTimeResolution)); // needed in case first good bin is not given, default = 10ns
2039
2040 // check if data range has been provided, and if not try to estimate them
2041 if (start[0] < 0) {
2042 start[0] = static_cast<Int_t>(t0[0])+offset;
2043 fRunInfo->SetDataRange(start[0], 0);
2044 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[0] << ".";
2045 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
2046 std::cerr << std::endl;
2047 }
2048 if (start[1] < 0) {
2049 start[1] = static_cast<Int_t>(t0[1])+offset;
2050 fRunInfo->SetDataRange(start[1], 2);
2051 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[1] << ".";
2052 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
2053 std::cerr << std::endl;
2054 }
2055 if (end[0] < 0) {
2056 end[0] = runData->GetDataBin(histoNo[0])->size();
2057 fRunInfo->SetDataRange(end[0], 1);
2058 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range end = " << end[0] << ".";
2059 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
2060 std::cerr << std::endl;
2061 }
2062 if (end[1] < 0) {
2063 end[1] = runData->GetDataBin(histoNo[1])->size();
2064 fRunInfo->SetDataRange(end[1], 3);
2065 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range end = " << end[1] << ".";
2066 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
2067 std::cerr << std::endl;
2068 }
2069
2070 // check if start, end, and t0 make any sense
2071 // 1st check if start and end are in proper order
2072 for (UInt_t i=0; i<2; i++) {
2073 if (end[i] < start[i]) { // need to swap them
2074 Int_t keep = end[i];
2075 end[i] = start[i];
2076 start[i] = keep;
2077 }
2078 // 2nd check if start is within proper bounds
2079 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
2080 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **ERROR** start data bin doesn't make any sense!";
2081 std::cerr << std::endl;
2082 return false;
2083 }
2084 // 3rd check if end is within proper bounds
2085 if (end[i] < 0) {
2086 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **ERROR** end data bin (" << end[i] << ") doesn't make any sense!";
2087 std::cerr << std::endl;
2088 return false;
2089 }
2090 if (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())) {
2091 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** end data bin (" << end[i] << ") > histo length (" << static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()) << ").";
2092 std::cerr << std::endl << ">> Will set end = (histo length - 1). Consider to change it in the msr-file." << std::endl;
2093 std::cerr << std::endl;
2094 end[i] = static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())-1;
2095 }
2096 // 4th check if t0 is within proper bounds
2097 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
2098 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **ERROR** t0 data bin doesn't make any sense!";
2099 std::cerr << std::endl;
2100 return false;
2101 }
2102 }
2103
2104 // check that start-t0 is the same for forward as for backward, otherwise take max(start[i]-t0[i])
2105 if (fabs(static_cast<Double_t>(start[0])-t0[0]) > fabs(static_cast<Double_t>(start[1])-t0[1])){
2106 start[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(start[0]) - t0[0]);
2107 end[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(end[0]) - t0[0]);
2108 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift backward data range.";
2109 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(2) << ", " << fRunInfo->GetDataRange(3);
2110 std::cerr << std::endl << ">> used : " << start[1] << ", " << end[1];
2111 std::cerr << std::endl;
2112 }
2113 if (fabs(static_cast<Double_t>(start[0])-t0[0]) < fabs(static_cast<Double_t>(start[1])-t0[1])){
2114 start[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(start[1]) - t0[1]);
2115 end[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(end[1]) - t0[1]);
2116 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift forward data range.";
2117 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(0) << ", " << fRunInfo->GetDataRange(1);
2118 std::cerr << std::endl << ">> used : " << start[0] << ", " << end[0];
2119 std::cerr << std::endl;
2120 }
2121
2122 // keep good bins for potential latter use
2123 fGoodBins[0] = start[0];
2124 fGoodBins[1] = end[0];
2125 fGoodBins[2] = start[1];
2126 fGoodBins[3] = end[1];
2127
2128 // make sure that fGoodBins are in proper range for fForward and fBackward
2129 if (fGoodBins[0] < 0)
2130 fGoodBins[0]=0;
2131 if (fGoodBins[1] > fForward.size()) {
2132 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift forward lgb,";
2133 std::cerr << std::endl << ">> from " << fGoodBins[1] << " to " << fForward.size()-1 << std::endl;
2134 fGoodBins[1]=fForward.size()-1;
2135 }
2136 if (fGoodBins[2] < 0)
2137 fGoodBins[2]=0;
2138 if (fGoodBins[3] > fBackward.size()) {
2139 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift backward lgb,";
2140 std::cerr << std::endl << ">> from " << fGoodBins[1] << " to " << fForward.size()-1 << std::endl;
2141 fGoodBins[3]=fBackward.size()-1;
2142 }
2143
2144 return true;
2145}
2146
2147//--------------------------------------------------------------------------
2148// GetProperFitRange (private)
2149//--------------------------------------------------------------------------
2173{
2174 // set fit start/end time; first check RUN Block
2175 fFitStartTime = fRunInfo->GetFitRange(0);
2176 fFitEndTime = fRunInfo->GetFitRange(1);
2177 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
2178 if (fRunInfo->IsFitRangeInBin()) {
2179 fFitStartTime = (fGoodBins[0] + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
2180 fFitEndTime = (fGoodBins[1] - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
2181 // write these times back into the data structure. This way it is available when writting the log-file
2182 fRunInfo->SetFitRange(fFitStartTime, 0);
2183 fRunInfo->SetFitRange(fFitEndTime, 1);
2184 }
2185 if (fFitStartTime == PMUSR_UNDEFINED) { // fit start/end NOT found in the RUN block, check GLOBAL block
2186 fFitStartTime = globalBlock->GetFitRange(0);
2187 fFitEndTime = globalBlock->GetFitRange(1);
2188 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
2189 if (globalBlock->IsFitRangeInBin()) {
2190 fFitStartTime = (fGoodBins[0] + globalBlock->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
2191 fFitEndTime = (fGoodBins[1] - globalBlock->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
2192 // write these times back into the data structure. This way it is available when writting the log-file
2193 globalBlock->SetFitRange(fFitStartTime, 0);
2194 globalBlock->SetFitRange(fFitEndTime, 1);
2195 }
2196 }
2198 fFitStartTime = (fGoodBins[0] - fT0s[0]) * fTimeResolution; // (fgb-t0)*dt
2199 fFitEndTime = (fGoodBins[1] - fT0s[0]) * fTimeResolution; // (lgb-t0)*dt
2200 std::cerr << ">> PRunSingleHisto::GetProperFitRange(): **WARNING** Couldn't get fit start/end time!" << std::endl;
2201 std::cerr << ">> Will set it to fgb/lgb which given in time is: " << fFitStartTime << "..." << fFitEndTime << " (usec)" << std::endl;
2202 }
2203}
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 RRF_UNIT_MHz
Frequency in MHz (megahertz)
Definition PMusr.h:349
#define PMUSR_UNDEFINED
Definition PMusr.h:177
#define GAMMA_BAR_MUON
Definition PMusr.h:143
#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 RRF_UNIT_Mcs
Angular frequency in Mc/s (Mega-cycles per second)
Definition PMusr.h:351
#define RRF_UNIT_G
Equivalent magnetic field in Gauss (G)
Definition PMusr.h:353
#define RRF_UNIT_kHz
Frequency in kHz (kilohertz)
Definition PMusr.h:347
#define ACCEL_PERIOD_PSI
PSI (Paul Scherrer Institute) accelerator cycle: 19.75 ns.
Definition PMusr.h:154
#define RRF_UNIT_T
Equivalent magnetic field in Tesla (T)
Definition PMusr.h:355
std::vector< Double_t > PDoubleVector
Definition PMusr.h:399
#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
UInt_t fNoOfFitBins
Number of bins included in the fit.
PRunAsymmetry()
Default constructor.
Int_t fPacking
Bin packing factor from RUN or GLOBAL block.
PDoubleVector fForwardErr
Forward detector histogram errors.
virtual void GetProperFitRange(PMsrGlobalBlock *globalBlock)
Determines the proper fit range from global block.
virtual Bool_t GetProperT0(PRawRunData *runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHisto, PUIntVector &backwardHistoNo)
Retrieves proper t0 values for all histograms.
Bool_t SubtractFixBkg()
Subtracts fixed background from histograms.
PDoubleVector fBackwardErr
Backward detector histogram errors.
virtual void CalcNoOfFitBins()
Calculates the number of bins to be fitted.
virtual Double_t CalcChiSquareExpected(const std::vector< Double_t > &par)
Calculates expected chi-square (for statistical analysis).
virtual void CalcTheory()
Calculates theoretical asymmetry function.
virtual Bool_t PrepareViewData(PRawRunData *runData, UInt_t histoNo[2])
Prepares data for viewing/plotting.
UInt_t fAlphaBetaTag
Tag indicating α/β configuration: 1=both unity, 2=α free/β unity, 3=α unity/β free,...
virtual Bool_t PrepareFitData()
Prepares data specifically for fitting.
Int_t fGoodBins[4]
Good bin boundaries: [0]=forward first, [1]=forward last, [2]=backward first, [3]=backward last.
Int_t fEndTimeBin
Last bin index for fitting.
virtual Double_t CalcChiSquare(const std::vector< Double_t > &par)
Calculates chi-square for the current parameter set.
virtual ~PRunAsymmetry()
Destructor.
virtual Double_t CalcMaxLikelihood(const std::vector< Double_t > &par)
Calculates maximum likelihood estimator.
virtual Bool_t PrepareRRFViewData(PRawRunData *runData, UInt_t histoNo[2])
Prepares rotating reference frame (RRF) data for viewing.
virtual UInt_t GetNoOfFitBins()
Returns the number of bins used in the fit.
virtual Bool_t GetProperDataRange(PRawRunData *runData, UInt_t histoNo[2])
Retrieves proper data range for histograms.
virtual Bool_t PrepareData()
Prepares all data for fitting or viewing.
PDoubleVector fForward
Forward detector histogram data.
Bool_t SubtractEstimatedBkg()
Estimates and subtracts background from histograms.
PDoubleVector fBackward
Backward detector histogram data.
Int_t fStartTimeBin
First bin index for fitting.
Bool_t fTheoAsData
If true, theory calculated only at data points; if false, extra points for nicer Fourier transforms.
virtual void SetFitRangeBin(const TString fitRange)
Sets the fit range in bins.
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
virtual void DeadTimeCorrection(std::vector< PDoubleVector > &histos, PUIntVector &histoNo)
carry out dead time correction
Definition PRunBase.cpp:169
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
virtual void CalculateKaiserFilterCoeff(Double_t wc, Double_t A, Double_t dw)
Calculates Kaiser window FIR filter coefficients for RRF smoothing.
Definition PRunBase.cpp:337
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
virtual void FilterTheo()
Applies Kaiser FIR filter to theory values for RRF fits.
Definition PRunBase.cpp:403
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