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() >= MSR_PARAM_FUN_OFFSET) { // beta seems to be a function
165 if ((fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET < 0) ||
166 (fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET > msrInfo->GetNoOfFuncs())) {
167 std::cerr << std::endl << ">> PRunAsymmetry::PRunAsymmetry(): **ERROR** beta parameter is a function with no = " << fRunInfo->GetBetaParamNo();
168 std::cerr << std::endl << ">> This is out of bound, since there are only " << msrInfo->GetNoOfFuncs() << " functions.";
169 std::cerr << std::endl;
170 fValid = false;
171 return;
172 }
173 } else if ((fRunInfo->GetBetaParamNo() < 0) || (fRunInfo->GetBetaParamNo() > static_cast<Int_t>(param->size()))) { // check if beta parameter is within proper bounds
174 std::cerr << std::endl << ">> PRunAsymmetry::PRunAsymmetry(): **ERROR** beta parameter no = " << fRunInfo->GetBetaParamNo();
175 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
176 std::cerr << std::endl;
177 fValid = false;
178 return;
179 } else { // check if beta is fixed
180 if (((*param)[fRunInfo->GetBetaParamNo()-1].fStep == 0.0) &&
181 ((*param)[fRunInfo->GetBetaParamNo()-1].fValue == 1.0))
182 betaFixedToOne = true;
183 }
184
185 // set fAlphaBetaTag
186 if (alphaFixedToOne && betaFixedToOne) // alpha == 1, beta == 1
187 fAlphaBetaTag = 1;
188 else if (!alphaFixedToOne && betaFixedToOne) // alpha != 1, beta == 1
189 fAlphaBetaTag = 2;
190 else if (alphaFixedToOne && !betaFixedToOne) // alpha == 1, beta != 1
191 fAlphaBetaTag = 3;
192 else
193 fAlphaBetaTag = 4;
194
195 // calculate fData
196 if (!PrepareData())
197 fValid = false;
198}
199
200//--------------------------------------------------------------------------
201// Destructor
202//--------------------------------------------------------------------------
210{
211 fForward.clear();
212 fForwardErr.clear();
213 fBackward.clear();
214 fBackwardErr.clear();
215}
216
217//--------------------------------------------------------------------------
218// CalcChiSquare (public)
219//--------------------------------------------------------------------------
237Double_t PRunAsymmetry::CalcChiSquare(const std::vector<Double_t>& par)
238{
239 Double_t chisq = 0.0;
240 Double_t diff = 0.0;
241 Double_t asymFcnValue = 0.0;
242 Double_t a, b, f;
243
244 // calculate functions
245 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
246 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
247 }
248
249 // calculate chi square
250 Double_t time(1.0);
251 Int_t i;
252
253 // determine alpha/beta
254 switch (fAlphaBetaTag) {
255 case 1: // alpha == 1, beta == 1
256 a = 1.0;
257 b = 1.0;
258 break;
259 case 2: // alpha != 1, beta == 1
260 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
261 a = par[fRunInfo->GetAlphaParamNo()-1];
262 } else { // alpha is function
263 // get function number
264 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
265 // evaluate function
266 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
267 }
268 b = 1.0;
269 break;
270 case 3: // alpha == 1, beta != 1
271 a = 1.0;
272 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
273 b = par[fRunInfo->GetBetaParamNo()-1];
274 } else { // beta is a function
275 // get function number
276 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
277 // evaluate function
278 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
279 }
280 break;
281 case 4: // alpha != 1, beta != 1
282 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
283 a = par[fRunInfo->GetAlphaParamNo()-1];
284 } else { // alpha is function
285 // get function number
286 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
287 // evaluate function
288 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
289 }
290 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
291 b = par[fRunInfo->GetBetaParamNo()-1];
292 } else { // beta is a function
293 // get function number
294 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
295 // evaluate function
296 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
297 }
298 break;
299 default:
300 a = 1.0;
301 b = 1.0;
302 break;
303 }
304
305 // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
306 // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
307 // for a given set of parameters---which should be done outside of the parallelized loop.
308 // For all other functions it means a tiny and acceptable overhead.
309 asymFcnValue = fTheory->Func(time, par, fFuncValues);
310
311 #ifdef HAVE_GOMP
312 Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
313 if (chunk < 10)
314 chunk = 10;
315 #pragma omp parallel for default(shared) private(i,time,diff,asymFcnValue,f) schedule(dynamic,chunk) reduction(+:chisq)
316 #endif
317 for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
318 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
319 f = fTheory->Func(time, par, fFuncValues);
320 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
321 diff = fData.GetValue()->at(i) - asymFcnValue;
322 chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
323 }
324
325 return chisq;
326}
327
328//--------------------------------------------------------------------------
329// CalcChiSquareExpected (public)
330//--------------------------------------------------------------------------
344Double_t PRunAsymmetry::CalcChiSquareExpected(const std::vector<Double_t>& par)
345{
346 return 0.0;
347}
348
349//--------------------------------------------------------------------------
350// CalcMaxLikelihood (public)
351//--------------------------------------------------------------------------
364Double_t PRunAsymmetry::CalcMaxLikelihood(const std::vector<Double_t>& par)
365{
366 std::cout << std::endl << "PRunAsymmetry::CalcMaxLikelihood(): not implemented yet ..." << std::endl;
367
368 return 1.0;
369}
370
371//--------------------------------------------------------------------------
372// GetNoOfFitBins (public)
373//--------------------------------------------------------------------------
384{
386
387 return fNoOfFitBins;
388}
389
390//--------------------------------------------------------------------------
391// SetFitRangeBin (public)
392//--------------------------------------------------------------------------
415void PRunAsymmetry::SetFitRangeBin(const TString fitRange)
416{
417 TString str;
418 Ssiz_t idx = -1;
419 Int_t offset = 0;
420
421 std::vector<std::string> tok = PStringUtils::Split(fitRange.Data(), " \t");
422
423 if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1
424 // handle fgb+n0 entry
425 str = tok[1];
426 // check if there is an offset present
427 idx = str.First("+");
428 if (idx != -1) { // offset present
429 str.Remove(0, idx+1);
430 if (str.IsFloat()) // if str is a valid number, convert is to an integer
431 offset = str.Atoi();
432 }
433 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
434
435 // handle lgb-n1 entry
436 str = tok[2];
437 // check if there is an offset present
438 idx = str.First("-");
439 if (idx != -1) { // offset present
440 str.Remove(0, idx+1);
441 if (str.IsFloat()) // if str is a valid number, convert is to an integer
442 offset = str.Atoi();
443 }
444 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
445 } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
446 UInt_t pos = 2*(fRunNo+1)-1;
447
448 if (pos + 1 >= tok.size()) {
449 std::cerr << std::endl << ">> PRunAsymmetry::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
450 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
451 } else {
452 // handle fgb+n0 entry
453 str = tok[pos];
454 // check if there is an offset present
455 idx = str.First("+");
456 if (idx != -1) { // offset present
457 str.Remove(0, idx+1);
458 if (str.IsFloat()) // if str is a valid number, convert is to an integer
459 offset = str.Atoi();
460 }
461 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
462
463 // handle lgb-n1 entry
464 str = tok[pos+1];
465 // check if there is an offset present
466 idx = str.First("-");
467 if (idx != -1) { // offset present
468 str.Remove(0, idx+1);
469 if (str.IsFloat()) // if str is a valid number, convert is to an integer
470 offset = str.Atoi();
471 }
472 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
473 }
474 } else { // error
475 std::cerr << std::endl << ">> PRunAsymmetry::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
476 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
477 }
478}
479
480//--------------------------------------------------------------------------
481// CalcNoOfFitBins (public)
482//--------------------------------------------------------------------------
496{
497 // In order not having to loop over all bins and to stay consistent with the chisq method, calculate the start and end bins explicitly
498 fStartTimeBin = static_cast<Int_t>(ceil((fFitStartTime - fData.GetDataTimeStart())/fData.GetDataTimeStep()));
499 if (fStartTimeBin < 0)
500 fStartTimeBin = 0;
501 fEndTimeBin = static_cast<Int_t>(floor((fFitEndTime - fData.GetDataTimeStart())/fData.GetDataTimeStep())) + 1;
502 if (fEndTimeBin > static_cast<Int_t>(fData.GetValue()->size()))
503 fEndTimeBin = fData.GetValue()->size();
504
506 fNoOfFitBins = static_cast<UInt_t>(fEndTimeBin - fStartTimeBin);
507 else
508 fNoOfFitBins = 0;
509}
510
511//--------------------------------------------------------------------------
512// CalcTheory (protected)
513//--------------------------------------------------------------------------
531{
532 // feed the parameter vector
533 std::vector<Double_t> par;
534 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
535 for (UInt_t i=0; i<paramList->size(); i++)
536 par.push_back((*paramList)[i].fValue);
537
538 // calculate functions
539 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
540 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
541 }
542
543 // calculate asymmetry
544 Double_t asymFcnValue = 0.0;
545 Double_t a, b, f;
546 Double_t time;
547 for (UInt_t i=0; i<fData.GetValue()->size(); i++) {
548 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
549 switch (fAlphaBetaTag) {
550 case 1: // alpha == 1, beta == 1
551 asymFcnValue = fTheory->Func(time, par, fFuncValues);
552 break;
553 case 2: // alpha != 1, beta == 1
554 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
555 a = par[fRunInfo->GetAlphaParamNo()-1];
556 } else { // alpha is function
557 // get function number
558 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
559 // evaluate function
560 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
561 }
562 f = fTheory->Func(time, par, fFuncValues);
563 asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0));
564 break;
565 case 3: // alpha == 1, beta != 1
566 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
567 b = par[fRunInfo->GetBetaParamNo()-1];
568 } else { // beta is a function
569 // get function number
570 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
571 // evaluate function
572 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
573 }
574 f = fTheory->Func(time, par, fFuncValues);
575 asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0));
576 break;
577 case 4: // alpha != 1, beta != 1
578 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
579 a = par[fRunInfo->GetAlphaParamNo()-1];
580 } else { // alpha is function
581 // get function number
582 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
583 // evaluate function
584 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
585 }
586 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
587 b = par[fRunInfo->GetBetaParamNo()-1];
588 } else { // beta is a function
589 // get function number
590 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
591 // evaluate function
592 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
593 }
594 f = fTheory->Func(time, par, fFuncValues);
595 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
596 break;
597 default:
598 asymFcnValue = 0.0;
599 break;
600 }
601 fData.AppendTheoryValue(asymFcnValue);
602 }
603
604 // clean up
605 par.clear();
606}
607
608//--------------------------------------------------------------------------
609// PrepareData (protected)
610//--------------------------------------------------------------------------
639{
640 if (!fValid)
641 return false;
642
643 // keep the Global block info
644 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
645
646 // get forward/backward histo from PRunDataHandler object ------------------------
647 // get the correct run
648 PRawRunData *runData = fRawData->GetRunData(*(fRunInfo->GetRunName()));
649 if (!runData) { // run not found
650 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **ERROR** Couldn't get run " << fRunInfo->GetRunName()->Data() << "!";
651 std::cerr << std::endl;
652 return false;
653 }
654
655 // keep the field from the meta-data from the data-file
656 fMetaData.fField = runData->GetField();
657
658 // keep the energy from the meta-data from the data-file
659 fMetaData.fEnergy = runData->GetEnergy();
660
661 // keep the temperature(s) from the meta-data from the data-file
662 for (unsigned int i=0; i<runData->GetNoOfTemperatures(); i++)
663 fMetaData.fTemp.push_back(runData->GetTemperature(i));
664
665 // collect histogram numbers
666 PUIntVector forwardHistoNo;
667 PUIntVector backwardHistoNo;
668 for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
669 forwardHistoNo.push_back(fRunInfo->GetForwardHistoNo(i));
670
671 if (!runData->IsPresent(forwardHistoNo[i])) {
672 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **PANIC ERROR**:";
673 std::cerr << std::endl << ">> forwardHistoNo found = " << forwardHistoNo[i] << ", which is NOT present in the data file!?!?";
674 std::cerr << std::endl << ">> Will quit :-(";
675 std::cerr << std::endl;
676 // clean up
677 forwardHistoNo.clear();
678 backwardHistoNo.clear();
679 return false;
680 }
681 }
682 for (UInt_t i=0; i<fRunInfo->GetBackwardHistoNoSize(); i++) {
683 backwardHistoNo.push_back(fRunInfo->GetBackwardHistoNo(i));
684
685 if (!runData->IsPresent(backwardHistoNo[i])) {
686 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **PANIC ERROR**:";
687 std::cerr << std::endl << ">> backwardHistoNo found = " << backwardHistoNo[i] << ", which is NOT present in the data file!?!?";
688 std::cerr << std::endl << ">> Will quit :-(";
689 std::cerr << std::endl;
690 // clean up
691 forwardHistoNo.clear();
692 backwardHistoNo.clear();
693 return false;
694 }
695 }
696
697 // keep the time resolution in (us)
698 fTimeResolution = runData->GetTimeResolution()/1.0e3;
699 std::cout.precision(10);
700 std::cout << std::endl << ">> PRunAsymmetry::PrepareData(): time resolution=" << std::fixed << runData->GetTimeResolution() << "(ns)" << std::endl;
701
702 // get all the proper t0's and addt0's for the current RUN block
703 if (!GetProperT0(runData, globalBlock, forwardHistoNo, backwardHistoNo)) {
704 return false;
705 }
706
707 // keep the histo of each group at this point (addruns handled below)
708 std::vector<PDoubleVector> forward, backward;
709 forward.resize(forwardHistoNo.size()); // resize to number of groups
710 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
711 forward[i].resize(runData->GetDataBin(forwardHistoNo[i])->size());
712 forward[i] = *runData->GetDataBin(forwardHistoNo[i]);
713 }
714 // check if a dead time correction has to be done
715 // this will be done automatically in the function itself, which also
716 // checks in the global and run section
717 DeadTimeCorrection(forward, forwardHistoNo);
718
719 backward.resize(backwardHistoNo.size()); // resize to number of groups
720 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
721 backward[i].resize(runData->GetDataBin(backwardHistoNo[i])->size());
722 backward[i] = *runData->GetDataBin(backwardHistoNo[i]);
723 }
724 // check if a dead time correction has to be done
725 // this will be done automatically in the function itself, which also
726 // checks in the global and run section
727 DeadTimeCorrection(backward, backwardHistoNo);
728
729 // check if addrun's are present, and if yes add data
730 // check if there are runs to be added to the current one
731 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
732 PRawRunData *addRunData;
733 std::vector<PDoubleVector> addForward, addBackward;
734 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
735 // get run to be added to the main one
736 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
737 if (addRunData == nullptr) { // couldn't get run
738 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
739 std::cerr << std::endl;
740 return false;
741 }
742
743 // dead time correction handling
744 addForward.clear();
745 addForward.resize(forwardHistoNo.size());
746 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
747 addForward[j].resize(addRunData->GetDataBin(forwardHistoNo[j])->size());
748 addForward[j] = *addRunData->GetDataBin(forwardHistoNo[j]);
749 }
750 DeadTimeCorrection(addForward, forwardHistoNo);
751 addBackward.clear();
752 addBackward.resize(backwardHistoNo.size());
753 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
754 addBackward[j].resize(addRunData->GetDataBin(backwardHistoNo[j])->size());
755 addBackward[j] = *addRunData->GetDataBin(backwardHistoNo[j]);
756 }
757 DeadTimeCorrection(addBackward, backwardHistoNo);
758
759 // add forward run
760 UInt_t addRunSize;
761 for (UInt_t k=0; k<forwardHistoNo.size(); k++) { // fill each group
762 addRunSize = addRunData->GetDataBin(forwardHistoNo[k])->size();
763 for (UInt_t j=0; j<addRunData->GetDataBin(forwardHistoNo[k])->size(); j++) { // loop over the bin indices
764 // make sure that the index stays in the proper range
765 if ((static_cast<Int_t>(j)+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]) >= 0) &&
766 (j+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k]) < addRunSize)) {
767 forward[k][j] += addForward[k][j+static_cast<Int_t>(fAddT0s[i-1][2*k])-static_cast<Int_t>(fT0s[2*k])];
768 }
769 }
770 }
771
772 // add backward run
773 for (UInt_t k=0; k<backwardHistoNo.size(); k++) { // fill each group
774 addRunSize = addRunData->GetDataBin(backwardHistoNo[k])->size();
775 for (UInt_t j=0; j<addRunData->GetDataBin(backwardHistoNo[k])->size(); j++) { // loop over the bin indices
776 // make sure that the index stays in the proper range
777 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) &&
778 (j+static_cast<Int_t>(fAddT0s[i-1][2*k+1])-static_cast<Int_t>(fT0s[2*k+1]) < addRunSize)) {
779 backward[k][j] += addBackward[k][j+static_cast<Int_t>(fAddT0s[i-1][2*k+1])-static_cast<Int_t>(fT0s[2*k+1])];
780 }
781 }
782 }
783 }
784 }
785
786 // set forward/backward histo data of the first group
787 fForward.resize(forward[0].size());
788 for (UInt_t i=0; i<fForward.size(); i++) {
789 fForward[i] = forward[0][i];
790 }
791 fBackward.resize(backward[0].size());
792 for (UInt_t i=0; i<fBackward.size(); i++) {
793 fBackward[i] = backward[0][i];
794 }
795
796 // group histograms, add all the remaining forward histograms of the group
797 for (UInt_t i=1; i<forwardHistoNo.size(); i++) { // loop over the groupings
798 for (UInt_t j=0; j<runData->GetDataBin(forwardHistoNo[i])->size(); j++) { // loop over the bin indices
799 // make sure that the index stays within proper range
800 if ((j+fT0s[2*i]-fT0s[0] >= 0) && (j+fT0s[2*i]-fT0s[0] < runData->GetDataBin(forwardHistoNo[i])->size())) {
801 fForward[j] += forward[i][j+static_cast<Int_t>(fT0s[2*i])-static_cast<Int_t>(fT0s[0])];
802 }
803 }
804 }
805
806 // group histograms, add all the remaining backward histograms of the group
807 for (UInt_t i=1; i<backwardHistoNo.size(); i++) { // loop over the groupings
808 for (UInt_t j=0; j<runData->GetDataBin(backwardHistoNo[i])->size(); j++) { // loop over the bin indices
809 // make sure that the index stays within proper range
810 if ((j+fT0s[2*i+1]-fT0s[1] >= 0) && (j+fT0s[2*i+1]-fT0s[1] < runData->GetDataBin(backwardHistoNo[i])->size())) {
811 fBackward[j] += backward[i][j+static_cast<Int_t>(fT0s[2*i+1])-static_cast<Int_t>(fT0s[1])];
812 }
813 }
814 }
815
816 // subtract background from histogramms ------------------------------------------
817 if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) { // no fixed background given
818 if (fRunInfo->GetBkgRange(0) >= 0) { // background range given
820 return false;
821 } else { // no background given to do the job, try to estimate it
822 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.1), 0);
823 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.6), 1);
824 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.1), 2);
825 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.6), 3);
826 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **WARNING** Neither fix background nor background bins are given!";
827 std::cerr << std::endl << ">> Will try the following:";
828 std::cerr << std::endl << ">> forward: bkg start = " << fRunInfo->GetBkgRange(0) << ", bkg end = " << fRunInfo->GetBkgRange(1);
829 std::cerr << std::endl << ">> backward: bkg start = " << fRunInfo->GetBkgRange(2) << ", bkg end = " << fRunInfo->GetBkgRange(3);
830 std::cerr << std::endl << ">> NO WARRANTY THAT THIS MAKES ANY SENSE! Better check ...";
831 std::cerr << std::endl;
833 return false;
834 }
835 } else { // fixed background given
836 if (!SubtractFixBkg())
837 return false;
838 }
839
840 UInt_t histoNo[2] = {forwardHistoNo[0], backwardHistoNo[0]};
841
842 // get the data range (fgb/lgb) for the current RUN block
843 if (!GetProperDataRange(runData, histoNo)) {
844 return false;
845 }
846
847 // get the fit range for the current RUN block
848 GetProperFitRange(globalBlock);
849
850 // everything looks fine, hence fill data set
851 Bool_t status;
852 switch(fHandleTag) {
853 case kFit:
855 break;
856 case kView:
857 if (fMsrInfo->GetMsrPlotList()->at(0).fRRFPacking == 0)
858 status = PrepareViewData(runData, histoNo);
859 else
860 status = PrepareRRFViewData(runData, histoNo);
861 break;
862 default:
863 status = false;
864 break;
865 }
866
867 // clean up
868 forwardHistoNo.clear();
869 backwardHistoNo.clear();
870
871 return status;
872}
873
874//--------------------------------------------------------------------------
875// SubtractFixBkg (private)
876//--------------------------------------------------------------------------
894{
895 if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) {
896 std::cerr << "PRunAsymmetry::SubtractFixBkg(): **ERROR** no fixed bkg for forward set. Will do nothing here." << std::endl;
897 return false;
898 }
899 if (fRunInfo->GetBkgFix(1) == PMUSR_UNDEFINED) {
900 std::cerr << "PRunAsymmetry::SubtractFixBkg(): **ERROR** no fixed bkg for backward set. Will do nothing here." << std::endl;
901 std::cerr << " you need an entry like:" << std::endl;
902 std::cerr << " backgr.fix 2 3" << std::endl;
903 std::cerr << " i.e. two entries for forward and backward." << std::endl;
904 return false;
905 }
906
907
908 Double_t dval;
909
910 for (UInt_t i=0; i<fForward.size(); i++) {
911 // keep the error, and make sure that the bin is NOT empty
912 if (fForward[i] != 0.0)
913 dval = TMath::Sqrt(fForward[i]);
914 else
915 dval = 1.0;
916 fForwardErr.push_back(dval);
917 fForward[i] -= fRunInfo->GetBkgFix(0);
918
919 // keep the error, and make sure that the bin is NOT empty
920 if (fBackward[i] != 0.0)
921 dval = TMath::Sqrt(fBackward[i]);
922 else
923 dval = 1.0;
924 fBackwardErr.push_back(dval);
925 fBackward[i] -= fRunInfo->GetBkgFix(1);
926 }
927
928 return true;
929}
930
931//--------------------------------------------------------------------------
932// SubtractEstimatedBkg (private)
933//--------------------------------------------------------------------------
952{
953 Double_t beamPeriod = 0.0;
954
955 // check if data are from PSI, RAL, or TRIUMF
956 if (fRunInfo->GetInstitute()->Contains("psi"))
957 beamPeriod = ACCEL_PERIOD_PSI;
958 else if (fRunInfo->GetInstitute()->Contains("ral"))
959 beamPeriod = ACCEL_PERIOD_RAL;
960 else if (fRunInfo->GetInstitute()->Contains("triumf"))
961 beamPeriod = ACCEL_PERIOD_TRIUMF;
962 else
963 beamPeriod = 0.0;
964
965 // check if start and end are in proper order
966 Int_t start[2] = {fRunInfo->GetBkgRange(0), fRunInfo->GetBkgRange(2)};
967 Int_t end[2] = {fRunInfo->GetBkgRange(1), fRunInfo->GetBkgRange(3)};
968 for (UInt_t i=0; i<2; i++) {
969 if (end[i] < start[i]) {
970 std::cout << std::endl << ">> PRunAsymmetry::SubtractEstimatedBkg(): end = " << end[i] << " > start = " << start[i] << "! Will swap them!";
971 UInt_t keep = end[i];
972 end[i] = start[i];
973 start[i] = keep;
974 }
975 }
976
977 // calculate proper background range
978 for (UInt_t i=0; i<2; i++) {
979 if (beamPeriod != 0.0) {
980 Double_t timeBkg = static_cast<Double_t>(end[i]-start[i])*(fTimeResolution*fPacking); // length of the background intervall in time
981 UInt_t fullCycles = static_cast<UInt_t>(timeBkg/beamPeriod); // how many proton beam cylces can be placed within the proposed background intervall
982 // correct the end of the background intervall such that the background is as close as possible to a multiple of the proton cylce
983 end[i] = start[i] + static_cast<UInt_t>((fullCycles*beamPeriod)/(fTimeResolution*fPacking));
984 std::cout << ">> PRunAsymmetry::SubtractEstimatedBkg(): Background " << start[i] << ", " << end[i] << std::endl;
985 if (end[i] == start[i])
986 end[i] = fRunInfo->GetBkgRange(2*i+1);
987 }
988 }
989
990 // check if start is within histogram bounds
991 if ((start[0] < 0) || (start[0] >= fForward.size()) ||
992 (start[1] < 0) || (start[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 start (f/b) = (" << start[0] << "/" << start[1] << ").";
996 return false;
997 }
998
999 // check if end is within histogram bounds
1000 if ((end[0] < 0) || (end[0] >= fForward.size()) ||
1001 (end[1] < 0) || (end[1] >= fBackward.size())) {
1002 std::cerr << std::endl << ">> PRunAsymmetry::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
1003 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
1004 std::cerr << std::endl << ">> background end (f/b) = (" << end[0] << "/" << end[1] << ").";
1005 return false;
1006 }
1007
1008 // calculate background
1009 Double_t bkg[2] = {0.0, 0.0};
1010 Double_t errBkg[2] = {0.0, 0.0};
1011
1012 // forward
1013 for (UInt_t i=start[0]; i<=end[0]; i++)
1014 bkg[0] += fForward[i];
1015 errBkg[0] = TMath::Sqrt(bkg[0])/(end[0] - start[0] + 1);
1016 bkg[0] /= static_cast<Double_t>(end[0] - start[0] + 1);
1017 std::cout << std::endl << ">> estimated forward histo background: " << bkg[0];
1018
1019 // backward
1020 for (UInt_t i=start[1]; i<=end[1]; i++)
1021 bkg[1] += fBackward[i];
1022 errBkg[1] = TMath::Sqrt(bkg[1])/(end[1] - start[1] + 1);
1023 bkg[1] /= static_cast<Double_t>(end[1] - start[1] + 1);
1024 std::cout << std::endl << ">> estimated backward histo background: " << bkg[1] << std::endl;
1025
1026 // correct error for forward, backward
1027 Double_t errVal = 0.0;
1028 for (UInt_t i=0; i<fForward.size(); i++) {
1029 if (fForward[i] > 0.0)
1030 errVal = TMath::Sqrt(fForward[i]+errBkg[0]*errBkg[0]);
1031 else
1032 errVal = 1.0;
1033 fForwardErr.push_back(errVal);
1034 if (fBackward[i] > 0.0)
1035 errVal = TMath::Sqrt(fBackward[i]+errBkg[1]*errBkg[1]);
1036 else
1037 errVal = 1.0;
1038 fBackwardErr.push_back(errVal);
1039 }
1040
1041 // subtract background from data
1042 for (UInt_t i=0; i<fForward.size(); i++) {
1043 fForward[i] -= bkg[0];
1044 fBackward[i] -= bkg[1];
1045 }
1046
1047 fRunInfo->SetBkgEstimated(bkg[0], 0);
1048 fRunInfo->SetBkgEstimated(bkg[1], 1);
1049
1050 return true;
1051}
1052
1053//--------------------------------------------------------------------------
1054// PrepareFitData (protected)
1055//--------------------------------------------------------------------------
1077{
1078 // transform raw histo data. This is done the following way (for details see the manual):
1079 // first rebin the data, than calculate the asymmetry
1080
1081 // everything looks fine, hence fill packed forward and backward histo
1082 PRunData forwardPacked;
1083 PRunData backwardPacked;
1084 Double_t value = 0.0;
1085 Double_t error = 0.0;
1086 // forward
1087 for (Int_t i=fGoodBins[0]; i<fGoodBins[1]; i++) {
1088 if (fPacking == 1) {
1089 forwardPacked.AppendValue(fForward[i]);
1090 forwardPacked.AppendErrorValue(fForwardErr[i]);
1091 } else { // packed data, i.e. fPacking > 1
1092 if (((i-fGoodBins[0]) % fPacking == 0) && (i != fGoodBins[0])) { // fill data
1093 // in order that after rebinning the fit does not need to be redone (important for plots)
1094 // the value is normalize to per bin
1095 value /= fPacking;
1096 forwardPacked.AppendValue(value);
1097 if (value == 0.0)
1098 forwardPacked.AppendErrorValue(1.0);
1099 else
1100 forwardPacked.AppendErrorValue(TMath::Sqrt(error)/fPacking);
1101 value = 0.0;
1102 error = 0.0;
1103 }
1104 value += fForward[i];
1105 error += fForwardErr[i]*fForwardErr[i];
1106 }
1107 }
1108 // backward
1109 for (Int_t i=fGoodBins[2]; i<fGoodBins[3]; i++) {
1110 if (fPacking == 1) {
1111 backwardPacked.AppendValue(fBackward[i]);
1112 backwardPacked.AppendErrorValue(fBackwardErr[i]);
1113 } else { // packed data, i.e. fPacking > 1
1114 if (((i-fGoodBins[2]) % fPacking == 0) && (i != fGoodBins[2])) { // fill data
1115 // in order that after rebinning the fit does not need to be redone (important for plots)
1116 // the value is normalize to per bin
1117 value /= fPacking;
1118 backwardPacked.AppendValue(value);
1119 if (value == 0.0)
1120 backwardPacked.AppendErrorValue(1.0);
1121 else
1122 backwardPacked.AppendErrorValue(TMath::Sqrt(error)/fPacking);
1123 value = 0.0;
1124 error = 0.0;
1125 }
1126 value += fBackward[i];
1127 error += fBackwardErr[i]*fBackwardErr[i];
1128 }
1129 }
1130
1131 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1132 UInt_t noOfBins = forwardPacked.GetValue()->size();
1133 if (forwardPacked.GetValue()->size() != backwardPacked.GetValue()->size()) {
1134 if (forwardPacked.GetValue()->size() > backwardPacked.GetValue()->size())
1135 noOfBins = backwardPacked.GetValue()->size();
1136 }
1137
1138 // form asymmetry including error propagation
1139 Double_t asym;
1140 Double_t f, b, ef, eb;
1141 // fill data time start, and step
1142 // data start time = (binStart - 0.5) + pack/2 - t0, with pack and binStart used as double
1143 fData.SetDataTimeStart(fTimeResolution*((static_cast<Double_t>(fGoodBins[0])-0.5) + static_cast<Double_t>(fPacking)/2.0 - static_cast<Double_t>(fT0s[0])));
1144 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(fPacking));
1145 for (UInt_t i=0; i<noOfBins; i++) {
1146 // to make the formulae more readable
1147 f = forwardPacked.GetValue()->at(i);
1148 b = backwardPacked.GetValue()->at(i);
1149 ef = forwardPacked.GetError()->at(i);
1150 eb = backwardPacked.GetError()->at(i);
1151 // check that there are indeed bins
1152 if (f+b != 0.0)
1153 asym = (f-b) / (f+b);
1154 else
1155 asym = 0.0;
1156 fData.AppendValue(asym);
1157 // calculate the error
1158 if (f+b != 0.0)
1159 error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
1160 else
1161 error = 1.0;
1162 fData.AppendErrorValue(error);
1163 }
1164
1166
1167 // clean up
1168 fForward.clear();
1169 fForwardErr.clear();
1170 fBackward.clear();
1171 fBackwardErr.clear();
1172
1173 return true;
1174}
1175
1176//--------------------------------------------------------------------------
1177// PrepareViewData (protected)
1178//--------------------------------------------------------------------------
1200Bool_t PRunAsymmetry::PrepareViewData(PRawRunData* runData, UInt_t histoNo[2])
1201{
1202 // check if view_packing is wished
1203 Int_t packing = fPacking;
1204 if (fMsrInfo->GetMsrPlotList()->at(0).fViewPacking > 0) {
1205 packing = fMsrInfo->GetMsrPlotList()->at(0).fViewPacking;
1206 }
1207
1208 // feed the parameter vector
1209 std::vector<Double_t> par;
1210 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
1211 for (UInt_t i=0; i<paramList->size(); i++)
1212 par.push_back((*paramList)[i].fValue);
1213
1214 // transform raw histo data. This is done the following way (for details see the manual):
1215 // first rebin the data, than calculate the asymmetry
1216
1217 // first get start data, end data, and t0
1218 Int_t start[2] = {fGoodBins[0], fGoodBins[2]};
1219 Int_t end[2] = {fGoodBins[1], fGoodBins[3]};
1220 Int_t t0[2] = {static_cast<Int_t>(fT0s[0]), static_cast<Int_t>(fT0s[1])};
1221
1222 // check if the data ranges and t0's between forward/backward are compatible
1223 Int_t fgb[2];
1224 if (start[0]-t0[0] != start[1]-t0[1]) { // wrong fgb aligning
1225 if (abs(start[0]-t0[0]) > abs(start[1]-t0[1])) {
1226 fgb[0] = start[0];
1227 fgb[1] = t0[1] + start[0]-t0[0];
1228 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **WARNING** needed to shift backward fgb from ";
1229 std::cerr << start[1] << " to " << fgb[1] << std::endl;
1230 } else {
1231 fgb[0] = t0[0] + start[1]-t0[1];
1232 fgb[1] = start[1];
1233 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **WARNING** needed to shift forward fgb from ";
1234 std::cerr << start[0] << " to " << fgb[0] << std::endl;
1235 }
1236 } else { // fgb aligning is correct
1237 fgb[0] = start[0];
1238 fgb[1] = start[1];
1239 }
1240
1241 Int_t val = fgb[0]-packing*(fgb[0]/packing);
1242 do {
1243 if (fgb[1] - fgb[0] < 0)
1244 val += packing;
1245 } while (val + fgb[1] - fgb[0] < 0);
1246
1247 start[0] = val;
1248 start[1] = val + fgb[1] - fgb[0];
1249
1250 // make sure that there are equal number of rebinned bins in forward and backward
1251 UInt_t noOfBins0 = (runData->GetDataBin(histoNo[0])->size()-start[0])/packing;
1252 UInt_t noOfBins1 = (runData->GetDataBin(histoNo[1])->size()-start[1])/packing;
1253 if (noOfBins0 > noOfBins1)
1254 noOfBins0 = noOfBins1;
1255 end[0] = start[0] + noOfBins0 * packing;
1256 end[1] = start[1] + noOfBins0 * packing;
1257
1258 // check if start, end, and t0 make any sense
1259 // 1st check if start and end are in proper order
1260 for (UInt_t i=0; i<2; i++) {
1261 if (end[i] < start[i]) { // need to swap them
1262 Int_t keep = end[i];
1263 end[i] = start[i];
1264 start[i] = keep;
1265 }
1266 // 2nd check if start is within proper bounds
1267 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1268 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **ERROR** start data bin doesn't make any sense!";
1269 std::cerr << std::endl;
1270 return false;
1271 }
1272 // 3rd check if end is within proper bounds
1273 if ((end[i] < 0) || (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1274 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **ERROR** end data bin doesn't make any sense!";
1275 std::cerr << std::endl;
1276 return false;
1277 }
1278 // 4th check if t0 is within proper bounds
1279 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1280 std::cerr << std::endl << ">> PRunAsymmetry::PrepareViewData(): **ERROR** t0 data bin doesn't make any sense!";
1281 std::cerr << std::endl;
1282 return false;
1283 }
1284 }
1285
1286 // everything looks fine, hence fill packed forward and backward histo
1287 PRunData forwardPacked;
1288 PRunData backwardPacked;
1289 Double_t value = 0.0;
1290 Double_t error = 0.0;
1291
1292 // forward
1293 for (Int_t i=start[0]; i<end[0]; i++) {
1294 if (packing == 1) {
1295 forwardPacked.AppendValue(fForward[i]);
1296 forwardPacked.AppendErrorValue(fForwardErr[i]);
1297 } else { // packed data, i.e. packing > 1
1298 if (((i-start[0]) % packing == 0) && (i != start[0])) { // fill data
1299 // in order that after rebinning the fit does not need to be redone (important for plots)
1300 // the value is normalize to per bin
1301 value /= packing;
1302 forwardPacked.AppendValue(value);
1303 if (value == 0.0)
1304 forwardPacked.AppendErrorValue(1.0);
1305 else
1306 forwardPacked.AppendErrorValue(TMath::Sqrt(error)/packing);
1307 value = 0.0;
1308 error = 0.0;
1309 }
1310 value += fForward[i];
1311 error += fForwardErr[i]*fForwardErr[i];
1312 }
1313 }
1314
1315 // backward
1316 for (Int_t i=start[1]; i<end[1]; i++) {
1317 if (packing == 1) {
1318 backwardPacked.AppendValue(fBackward[i]);
1319 backwardPacked.AppendErrorValue(fBackwardErr[i]);
1320 } else { // packed data, i.e. packing > 1
1321 if (((i-start[1]) % packing == 0) && (i != start[1])) { // fill data
1322 // in order that after rebinning the fit does not need to be redone (important for plots)
1323 // the value is normalize to per bin
1324 value /= packing;
1325 backwardPacked.AppendValue(value);
1326 if (value == 0.0)
1327 backwardPacked.AppendErrorValue(1.0);
1328 else
1329 backwardPacked.AppendErrorValue(TMath::Sqrt(error)/packing);
1330 value = 0.0;
1331 error = 0.0;
1332 }
1333 value += fBackward[i];
1334 error += fBackwardErr[i]*fBackwardErr[i];
1335 }
1336 }
1337
1338 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1339 UInt_t noOfBins = forwardPacked.GetValue()->size();
1340 if (forwardPacked.GetValue()->size() != backwardPacked.GetValue()->size()) {
1341 if (forwardPacked.GetValue()->size() > backwardPacked.GetValue()->size())
1342 noOfBins = backwardPacked.GetValue()->size();
1343 }
1344
1345 // form asymmetry including error propagation
1346 Double_t asym;
1347 Double_t f, b, ef, eb, alpha = 1.0, beta = 1.0;
1348 // set data time start, and step
1349 // data start time = (binStart - 0.5) + pack/2 - t0, with pack and binStart used as double
1350 fData.SetDataTimeStart(fTimeResolution*((static_cast<Double_t>(start[0])-0.5) + static_cast<Double_t>(packing)/2.0 - static_cast<Double_t>(t0[0])));
1351 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(packing));
1352
1353 // get the proper alpha and beta
1354 switch (fAlphaBetaTag) {
1355 case 1: // alpha == 1, beta == 1
1356 alpha = 1.0;
1357 beta = 1.0;
1358 break;
1359 case 2: // alpha != 1, beta == 1
1360 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1361 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1362 } else { // alpha is function
1363 // get function number
1364 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1365 // evaluate function
1366 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1367 }
1368 beta = 1.0;
1369 break;
1370 case 3: // alpha == 1, beta != 1
1371 alpha = 1.0;
1372 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1373 beta = par[fRunInfo->GetBetaParamNo()-1];
1374 } else { // beta is a function
1375 // get function number
1376 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1377 // evaluate function
1378 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1379 }
1380 break;
1381 case 4: // alpha != 1, beta != 1
1382 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1383 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1384 } else { // alpha is function
1385 // get function number
1386 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1387 // evaluate function
1388 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1389 }
1390 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1391 beta = par[fRunInfo->GetBetaParamNo()-1];
1392 } else { // beta is a function
1393 // get function number
1394 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1395 // evaluate function
1396 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1397 }
1398 break;
1399 default:
1400 break;
1401 }
1402
1403 for (UInt_t i=0; i<forwardPacked.GetValue()->size(); i++) {
1404 // to make the formulae more readable
1405 f = forwardPacked.GetValue()->at(i);
1406 b = backwardPacked.GetValue()->at(i);
1407 ef = forwardPacked.GetError()->at(i);
1408 eb = backwardPacked.GetError()->at(i);
1409 // check that there are indeed bins
1410 if (f+b != 0.0)
1411 asym = (alpha*f-b) / (alpha*beta*f+b);
1412 else
1413 asym = 0.0;
1414 fData.AppendValue(asym);
1415 // calculate the error
1416 if (f+b != 0.0)
1417 error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
1418 else
1419 error = 1.0;
1420 fData.AppendErrorValue(error);
1421 }
1422
1424
1425 // clean up
1426 fForward.clear();
1427 fForwardErr.clear();
1428 fBackward.clear();
1429 fBackwardErr.clear();
1430
1431 // fill theory vector for kView
1432 // calculate functions
1433 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
1434 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
1435 }
1436
1437 // calculate theory
1438 Double_t time;
1439 UInt_t size = runData->GetDataBin(histoNo[0])->size()/packing;
1440 Int_t factor = 8; // 8 times more points for the theory (if fTheoAsData == false)
1441
1442 fData.SetTheoryTimeStart(fData.GetDataTimeStart());
1443 if (fTheoAsData) { // calculate theory only at the data points
1444 fData.SetTheoryTimeStep(fData.GetDataTimeStep());
1445 } else {
1446 // finer binning for the theory (8 times as many points = factor)
1447 size *= factor;
1448 fData.SetTheoryTimeStep(fData.GetDataTimeStep()/(Double_t)factor);
1449 }
1450
1451 for (UInt_t i=0; i<size; i++) {
1452 time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
1453 value = fTheory->Func(time, par, fFuncValues);
1454 if (fabs(value) > 10.0) { // dirty hack needs to be fixed!!
1455 value = 0.0;
1456 }
1457 fData.AppendTheoryValue(value);
1458 }
1459
1460 // clean up
1461 par.clear();
1462
1463 return true;
1464}
1465
1466//--------------------------------------------------------------------------
1467// PrepareRRFViewData (protected)
1468//--------------------------------------------------------------------------
1492Bool_t PRunAsymmetry::PrepareRRFViewData(PRawRunData* runData, UInt_t histoNo[2])
1493{
1494 // feed the parameter vector
1495 std::vector<Double_t> par;
1496 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
1497 for (UInt_t i=0; i<paramList->size(); i++)
1498 par.push_back((*paramList)[i].fValue);
1499
1500 // ------------------------------------------------------------
1501 // 1. make all necessary checks
1502 // ------------------------------------------------------------
1503
1504 // first get start data, end data, and t0
1505 Int_t start[2] = {fGoodBins[0], fGoodBins[2]};
1506 Int_t end[2] = {fGoodBins[1], fGoodBins[3]};
1507 Int_t t0[2] = {static_cast<Int_t>(fT0s[0]), static_cast<Int_t>(fT0s[1])};
1508 UInt_t packing = fMsrInfo->GetMsrPlotList()->at(0).fRRFPacking;
1509
1510 // check if the data ranges and t0's between forward/backward are compatible
1511 Int_t fgb[2];
1512 if (start[0]-t0[0] != start[1]-t0[1]) { // wrong fgb aligning
1513 if (abs(start[0]-t0[0]) > abs(start[1]-t0[1])) {
1514 fgb[0] = start[0];
1515 fgb[1] = t0[1] + start[0]-t0[0];
1516 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **WARNING** needed to shift backward fgb from ";
1517 std::cerr << start[1] << " to " << fgb[1] << std::endl;
1518 } else {
1519 fgb[0] = t0[0] + start[1]-t0[1];
1520 fgb[1] = start[1];
1521 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **WARNING** needed to shift forward fgb from ";
1522 std::cerr << start[1] << " to " << fgb[0] << std::endl;
1523 }
1524 } else { // fgb aligning is correct
1525 fgb[0] = start[0];
1526 fgb[1] = start[1];
1527 }
1528
1529 Int_t val = fgb[0]-packing*(fgb[0]/packing);
1530 do {
1531 if (fgb[1] - fgb[0] < 0)
1532 val += packing;
1533 } while (val + fgb[1] - fgb[0] < 0);
1534
1535 start[0] = val;
1536 start[1] = val + fgb[1] - fgb[0];
1537
1538 // make sure that there are equal number of rebinned bins in forward and backward
1539 UInt_t noOfBins0 = runData->GetDataBin(histoNo[0])->size()-start[0];
1540 UInt_t noOfBins1 = runData->GetDataBin(histoNo[1])->size()-start[1];
1541 if (noOfBins0 > noOfBins1)
1542 noOfBins0 = noOfBins1;
1543 end[0] = start[0] + noOfBins0;
1544 end[1] = start[1] + noOfBins0;
1545
1546 // check if start, end, and t0 make any sense
1547 // 1st check if start and end are in proper order
1548 for (UInt_t i=0; i<2; i++) {
1549 if (end[i] < start[i]) { // need to swap them
1550 Int_t keep = end[i];
1551 end[i] = start[i];
1552 start[i] = keep;
1553 }
1554 // 2nd check if start is within proper bounds
1555 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1556 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **ERROR** start data bin doesn't make any sense!";
1557 std::cerr << std::endl;
1558 return false;
1559 }
1560 // 3rd check if end is within proper bounds
1561 if ((end[i] < 0) || (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1562 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **ERROR** end data bin doesn't make any sense!";
1563 std::cerr << std::endl;
1564 return false;
1565 }
1566 // 4th check if t0 is within proper bounds
1567 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1568 std::cerr << std::endl << ">> PRunAsymmetry::PrepareRRFViewData(): **ERROR** t0 data bin doesn't make any sense!";
1569 std::cerr << std::endl;
1570 return false;
1571 }
1572 }
1573
1574 // ------------------------------------------------------------
1575 // 2. build the asymmetry [A(t)] WITHOUT packing.
1576 // ------------------------------------------------------------
1577
1578 PDoubleVector forward, forwardErr;
1579 PDoubleVector backward, backwardErr;
1580 Double_t error = 0.0;
1581 // forward
1582 for (Int_t i=start[0]; i<end[0]; i++) {
1583 forward.push_back(fForward[i]);
1584 forwardErr.push_back(fForwardErr[i]);
1585 }
1586 // backward
1587 for (Int_t i=start[1]; i<end[1]; i++) {
1588 backward.push_back(fBackward[i]);
1589 backwardErr.push_back(fBackwardErr[i]);
1590 }
1591
1592 // check if packed forward and backward hist have the same size, otherwise take the minimum size
1593 UInt_t noOfBins = forward.size();
1594 if (forward.size() != backward.size()) {
1595 if (forward.size() > backward.size())
1596 noOfBins = backward.size();
1597 }
1598
1599 // form asymmetry including error propagation
1600 PDoubleVector asymmetry, asymmetryErr;
1601 Double_t asym;
1602 Double_t f, b, ef, eb, alpha = 1.0, beta = 1.0;
1603
1604 // get the proper alpha and beta
1605 switch (fAlphaBetaTag) {
1606 case 1: // alpha == 1, beta == 1
1607 alpha = 1.0;
1608 beta = 1.0;
1609 break;
1610 case 2: // alpha != 1, beta == 1
1611 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1612 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1613 } else { // alpha is function
1614 // get function number
1615 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1616 // evaluate function
1617 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1618 }
1619 beta = 1.0;
1620 break;
1621 case 3: // alpha == 1, beta != 1
1622 alpha = 1.0;
1623 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1624 beta = par[fRunInfo->GetBetaParamNo()-1];
1625 } else { // beta is a function
1626 // get function number
1627 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1628 // evaluate function
1629 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1630 }
1631 break;
1632 case 4: // alpha != 1, beta != 1
1633 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1634 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1635 } else { // alpha is function
1636 // get function number
1637 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1638 // evaluate function
1639 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1640 }
1641 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1642 beta = par[fRunInfo->GetBetaParamNo()-1];
1643 } else { // beta is a function
1644 // get function number
1645 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1646 // evaluate function
1647 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1648 }
1649 break;
1650 default:
1651 break;
1652 }
1653
1654 for (UInt_t i=0; i<noOfBins; i++) {
1655 // to make the formulae more readable
1656 f = forward[i];
1657 b = backward[i];
1658 ef = forwardErr[i];
1659 eb = backwardErr[i];
1660 // check that there are indeed bins
1661 if (f+b != 0.0)
1662 asym = (alpha*f-b) / (alpha*beta*f+b);
1663 else
1664 asym = 0.0;
1665 asymmetry.push_back(asym);
1666 // calculate the error
1667 if (f+b != 0.0)
1668 error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
1669 else
1670 error = 1.0;
1671 asymmetryErr.push_back(error);
1672 }
1673
1674 // clean up
1675 fForward.clear();
1676 fForwardErr.clear();
1677 fBackward.clear();
1678 fBackwardErr.clear();
1679
1680
1681 // ------------------------------------------------------------
1682 // 3. A_R(t) = A(t) * 2 cos(w_R t + phi_R)
1683 // ------------------------------------------------------------
1684
1685 // check which units shall be used
1686 Double_t gammaRRF = 0.0, wRRF = 0.0, phaseRRF = 0.0;
1687 Double_t time;
1688
1689 switch (fMsrInfo->GetMsrPlotList()->at(0).fRRFUnit) {
1690 case RRF_UNIT_kHz:
1691 gammaRRF = TMath::TwoPi()*1.0e-3;
1692 break;
1693 case RRF_UNIT_MHz:
1694 gammaRRF = TMath::TwoPi();
1695 break;
1696 case RRF_UNIT_Mcs:
1697 gammaRRF = 1.0;
1698 break;
1699 case RRF_UNIT_G:
1700 gammaRRF = GAMMA_BAR_MUON*TMath::TwoPi();
1701 break;
1702 case RRF_UNIT_T:
1703 gammaRRF = GAMMA_BAR_MUON*TMath::TwoPi()*1.0e4;
1704 break;
1705 default:
1706 gammaRRF = TMath::TwoPi();
1707 break;
1708 }
1709 wRRF = gammaRRF * fMsrInfo->GetMsrPlotList()->at(0).fRRFFreq;
1710 phaseRRF = fMsrInfo->GetMsrPlotList()->at(0).fRRFPhase / 180.0 * TMath::Pi();
1711
1712 for (UInt_t i=0; i<asymmetry.size(); i++) {
1713 time = fTimeResolution*(static_cast<Double_t>(start[0])-t0[0]+static_cast<Double_t>(i));
1714 asymmetry[i] *= 2.0*TMath::Cos(wRRF*time+phaseRRF);
1715 }
1716
1717 // ------------------------------------------------------------
1718 // 4. do the packing of A_R(t)
1719 // ------------------------------------------------------------
1720 Double_t value = 0.0;
1721 error = 0.0;
1722 for (UInt_t i=0; i<asymmetry.size(); i++) {
1723 if ((i % packing == 0) && (i != 0)) {
1724 value /= packing;
1725 fData.AppendValue(value);
1726 fData.AppendErrorValue(TMath::Sqrt(error)/packing);
1727
1728 value = 0.0;
1729 error = 0.0;
1730 }
1731 value += asymmetry[i];
1732 error += asymmetryErr[i]*asymmetryErr[i];
1733 }
1734
1735 // set data time start, and step
1736 // data start time = (binStart - 0.5) + pack/2 - t0, with pack and binStart used as double
1737 fData.SetDataTimeStart(fTimeResolution*((static_cast<Double_t>(start[0])-0.5) + static_cast<Double_t>(packing)/2.0 - static_cast<Double_t>(t0[0])));
1738 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(packing));
1739
1740 // ------------------------------------------------------------
1741 // 5. calculate theory [T(t)] as close as possible to the time resolution [compatible with the RRF frequency]
1742 // 6. T_R(t) = T(t) * 2 cos(w_R t + phi_R)
1743 // ------------------------------------------------------------
1744 UInt_t rebinRRF = static_cast<UInt_t>((TMath::Pi()/2.0/wRRF)/fTimeResolution); // RRF time resolution / data time resolution
1745 fData.SetTheoryTimeStart(fData.GetDataTimeStart());
1746 fData.SetTheoryTimeStep(TMath::Pi()/2.0/wRRF/rebinRRF); // = theory time resolution as close as possible to the data time resolution compatible with wRRF
1747
1748 // calculate functions
1749 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
1750 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
1751 }
1752
1753 Double_t theoryValue;
1754 for (UInt_t i=0; i<asymmetry.size(); i++) {
1755 time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
1756 theoryValue = fTheory->Func(time, par, fFuncValues);
1757 theoryValue *= 2.0*TMath::Cos(wRRF * time + phaseRRF);
1758
1759 if (fabs(theoryValue) > 10.0) { // dirty hack needs to be fixed!!
1760 theoryValue = 0.0;
1761 }
1762
1763 fData.AppendTheoryValue(theoryValue);
1764 }
1765
1766 // ------------------------------------------------------------
1767 // 7. do the packing of T_R(t)
1768 // ------------------------------------------------------------
1769
1770 PDoubleVector theo;
1771 Double_t dval = 0.0;
1772 for (UInt_t i=0; i<fData.GetTheory()->size(); i++) {
1773 if ((i % rebinRRF == 0) && (i != 0)) {
1774 theo.push_back(dval/rebinRRF);
1775 dval = 0.0;
1776 }
1777 dval += fData.GetTheory()->at(i);
1778 }
1779 fData.ReplaceTheory(theo);
1780 theo.clear();
1781
1782 // set the theory time start and step size
1783 fData.SetTheoryTimeStart(fData.GetTheoryTimeStart()+static_cast<Double_t>(rebinRRF-1)*fData.GetTheoryTimeStep()/2.0);
1784 fData.SetTheoryTimeStep(rebinRRF*fData.GetTheoryTimeStep());
1785
1786 // ------------------------------------------------------------
1787 // 8. calculate the Kaiser FIR filter coefficients
1788 // ------------------------------------------------------------
1789 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)
1790
1791 // ------------------------------------------------------------
1792 // 9. filter T_R(t)
1793 // ------------------------------------------------------------
1794 FilterTheo();
1795
1796 // clean up
1797 par.clear();
1798 forward.clear();
1799 forwardErr.clear();
1800 backward.clear();
1801 backwardErr.clear();
1802 asymmetry.clear();
1803 asymmetryErr.clear();
1804
1805 return true;
1806}
1807
1808//--------------------------------------------------------------------------
1809// GetProperT0 (private)
1810//--------------------------------------------------------------------------
1839Bool_t PRunAsymmetry::GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHistoNo, PUIntVector &backwardHistoNo)
1840{
1841 // feed all T0's
1842 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1843 fT0s.clear();
1844 // this strange fT0 size estimate is needed in case #forw histos != #back histos
1845 size_t size = 2*forwardHistoNo.size();
1846 if (backwardHistoNo.size() > forwardHistoNo.size())
1847 size = 2*backwardHistoNo.size();
1848 fT0s.resize(size);
1849 for (UInt_t i=0; i<fT0s.size(); i++) {
1850 fT0s[i] = -1.0;
1851 }
1852
1853 // fill in the T0's from the msr-file (if present)
1854 for (UInt_t i=0; i<fRunInfo->GetT0BinSize(); i++) {
1855 fT0s[i] = fRunInfo->GetT0Bin(i);
1856 }
1857
1858 // fill in the missing T0's from the GLOBAL block section (if present)
1859 for (UInt_t i=0; i<globalBlock->GetT0BinSize(); i++) {
1860 if (fT0s[i] == -1) { // i.e. not given in the RUN block section
1861 fT0s[i] = globalBlock->GetT0Bin(i);
1862 }
1863 }
1864
1865 // fill in the missing T0's from the data file, if not already present in the msr-file
1866 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1867 if (fT0s[2*i] == -1.0) // i.e. not present in the msr-file, try the data file
1868 if (runData->GetT0Bin(forwardHistoNo[i]) > 0.0) {
1869 fT0s[2*i] = runData->GetT0Bin(forwardHistoNo[i]);
1870 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1871 }
1872 }
1873 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1874 if (fT0s[2*i+1] == -1.0) // i.e. not present in the msr-file, try the data file
1875 if (runData->GetT0Bin(backwardHistoNo[i]) > 0.0) {
1876 fT0s[2*i+1] = runData->GetT0Bin(backwardHistoNo[i]);
1877 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1878 }
1879 }
1880
1881 // 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
1882 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1883 if (fT0s[2*i] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1884 fT0s[2*i] = runData->GetT0BinEstimated(forwardHistoNo[i]);
1885 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1886
1887 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1888 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1889 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << runData->GetT0BinEstimated(forwardHistoNo[i]);
1890 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1891 std::cerr << std::endl;
1892 }
1893 }
1894 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1895 if (fT0s[2*i+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1896 fT0s[2*i+1] = runData->GetT0BinEstimated(backwardHistoNo[i]);
1897 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1898
1899 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1900 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1901 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[i]);
1902 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1903 std::cerr << std::endl;
1904 }
1905 }
1906
1907 // check if t0 is within proper bounds
1908 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1909 if ((fT0s[2*i] < 0) || (fT0s[2*i] > static_cast<Int_t>(runData->GetDataBin(forwardHistoNo[i])->size()))) {
1910 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **ERROR** t0 data bin (" << fT0s[2*i] << ") doesn't make any sense!";
1911 std::cerr << std::endl << ">> forwardHistoNo " << forwardHistoNo[i];
1912 std::cerr << std::endl;
1913 return false;
1914 }
1915 }
1916 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1917 if ((fT0s[2*i+1] < 0) || (fT0s[2*i+1] > static_cast<Int_t>(runData->GetDataBin(backwardHistoNo[i])->size()))) {
1918 std::cerr << std::endl << ">> PRunAsymmetry::PrepareData(): **ERROR** t0 data bin (" << fT0s[2*i+1] << ") doesn't make any sense!";
1919 std::cerr << std::endl << ">> backwardHistoNo " << backwardHistoNo[i];
1920 std::cerr << std::endl;
1921 return false;
1922 }
1923 }
1924
1925 // check if addrun's are present, and if yes add the necessary t0's
1926 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
1927 PRawRunData *addRunData;
1928 fAddT0s.resize(fRunInfo->GetRunNameSize()-1); // resize to the number of addruns
1929 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
1930 // get run to be added to the main one
1931 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
1932 if (addRunData == 0) { // couldn't get run
1933 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
1934 std::cerr << std::endl;
1935 return false;
1936 }
1937
1938 // feed all T0's
1939 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1940 fAddT0s[i-1].clear();
1941 fAddT0s[i-1].resize(2*forwardHistoNo.size());
1942 for (UInt_t j=0; j<fAddT0s[i-1].size(); j++) {
1943 fAddT0s[i-1][j] = -1.0;
1944 }
1945
1946 // fill in the T0's from the msr-file (if present)
1947 for (Int_t j=0; j<fRunInfo->GetAddT0BinSize(i-1); j++) {
1948 fAddT0s[i-1][j] = fRunInfo->GetAddT0Bin(i-1, j);
1949 }
1950
1951 // fill in the T0's from the data file, if not already present in the msr-file
1952 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1953 if (fAddT0s[i-1][2*j] == -1.0) // i.e. not present in the msr-file, try the data file
1954 if (addRunData->GetT0Bin(forwardHistoNo[j]) > 0.0) {
1955 fAddT0s[i-1][2*j] = addRunData->GetT0Bin(forwardHistoNo[j]);
1956 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1957 }
1958 }
1959 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1960 if (fAddT0s[i-1][2*j+1] == -1.0) // i.e. not present in the msr-file, try the data file
1961 if (addRunData->GetT0Bin(backwardHistoNo[j]) > 0.0) {
1962 fAddT0s[i-1][2*j+1] = addRunData->GetT0Bin(backwardHistoNo[j]);
1963 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1964 }
1965 }
1966
1967 // 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
1968 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1969 if (fAddT0s[i-1][2*j] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1970 fAddT0s[i-1][2*j] = addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1971 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1972
1973 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1974 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1975 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1976 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1977 std::cerr << std::endl;
1978 }
1979 }
1980 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1981 if (fAddT0s[i-1][2*j+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1982 fAddT0s[i-1][2*j+1] = addRunData->GetT0BinEstimated(backwardHistoNo[j]);
1983 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1984
1985 std::cerr << std::endl << ">> PRunAsymmetry::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1986 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1987 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[j]);
1988 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1989 std::cerr << std::endl;
1990 }
1991 }
1992 }
1993 }
1994
1995 return true;
1996}
1997
1998//--------------------------------------------------------------------------
1999// GetProperDataRange (private)
2000//--------------------------------------------------------------------------
2027Bool_t PRunAsymmetry::GetProperDataRange(PRawRunData* runData, UInt_t histoNo[2])
2028{
2029 // first get start/end data
2030 Int_t start[2] = {fRunInfo->GetDataRange(0), fRunInfo->GetDataRange(2)};
2031 Int_t end[2] = {fRunInfo->GetDataRange(1), fRunInfo->GetDataRange(3)};
2032 // check if data range has been provided in the RUN block. If not, try the GLOBAL block
2033 if (start[0] == -1) {
2034 start[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(0);
2035 }
2036 if (start[1] == -1) {
2037 start[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(2);
2038 }
2039 if (end[0] == -1) {
2040 end[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(1);
2041 }
2042 if (end[1] == -1) {
2043 end[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(3);
2044 }
2045
2046 Double_t t0[2] = {fT0s[0], fT0s[1]};
2047 Int_t offset = static_cast<Int_t>((10.0e-3/fTimeResolution)); // needed in case first good bin is not given, default = 10ns
2048
2049 // check if data range has been provided, and if not try to estimate them
2050 if (start[0] < 0) {
2051 start[0] = static_cast<Int_t>(t0[0])+offset;
2052 fRunInfo->SetDataRange(start[0], 0);
2053 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[0] << ".";
2054 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
2055 std::cerr << std::endl;
2056 }
2057 if (start[1] < 0) {
2058 start[1] = static_cast<Int_t>(t0[1])+offset;
2059 fRunInfo->SetDataRange(start[1], 2);
2060 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[1] << ".";
2061 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
2062 std::cerr << std::endl;
2063 }
2064 if (end[0] < 0) {
2065 end[0] = runData->GetDataBin(histoNo[0])->size();
2066 fRunInfo->SetDataRange(end[0], 1);
2067 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range end = " << end[0] << ".";
2068 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
2069 std::cerr << std::endl;
2070 }
2071 if (end[1] < 0) {
2072 end[1] = runData->GetDataBin(histoNo[1])->size();
2073 fRunInfo->SetDataRange(end[1], 3);
2074 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range end = " << end[1] << ".";
2075 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
2076 std::cerr << std::endl;
2077 }
2078
2079 // check if start, end, and t0 make any sense
2080 // 1st check if start and end are in proper order
2081 for (UInt_t i=0; i<2; i++) {
2082 if (end[i] < start[i]) { // need to swap them
2083 Int_t keep = end[i];
2084 end[i] = start[i];
2085 start[i] = keep;
2086 }
2087 // 2nd check if start is within proper bounds
2088 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
2089 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **ERROR** start data bin doesn't make any sense!";
2090 std::cerr << std::endl;
2091 return false;
2092 }
2093 // 3rd check if end is within proper bounds
2094 if (end[i] < 0) {
2095 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **ERROR** end data bin (" << end[i] << ") doesn't make any sense!";
2096 std::cerr << std::endl;
2097 return false;
2098 }
2099 if (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())) {
2100 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **WARNING** end data bin (" << end[i] << ") > histo length (" << static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()) << ").";
2101 std::cerr << std::endl << ">> Will set end = (histo length - 1). Consider to change it in the msr-file." << std::endl;
2102 std::cerr << std::endl;
2103 end[i] = static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())-1;
2104 }
2105 // 4th check if t0 is within proper bounds
2106 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
2107 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange(): **ERROR** t0 data bin doesn't make any sense!";
2108 std::cerr << std::endl;
2109 return false;
2110 }
2111 }
2112
2113 // check that start-t0 is the same for forward as for backward, otherwise take max(start[i]-t0[i])
2114 if (fabs(static_cast<Double_t>(start[0])-t0[0]) > fabs(static_cast<Double_t>(start[1])-t0[1])){
2115 start[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(start[0]) - t0[0]);
2116 end[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(end[0]) - t0[0]);
2117 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift backward data range.";
2118 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(2) << ", " << fRunInfo->GetDataRange(3);
2119 std::cerr << std::endl << ">> used : " << start[1] << ", " << end[1];
2120 std::cerr << std::endl;
2121 }
2122 if (fabs(static_cast<Double_t>(start[0])-t0[0]) < fabs(static_cast<Double_t>(start[1])-t0[1])){
2123 start[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(start[1]) - t0[1]);
2124 end[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(end[1]) - t0[1]);
2125 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift forward data range.";
2126 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(0) << ", " << fRunInfo->GetDataRange(1);
2127 std::cerr << std::endl << ">> used : " << start[0] << ", " << end[0];
2128 std::cerr << std::endl;
2129 }
2130
2131 // keep good bins for potential latter use
2132 fGoodBins[0] = start[0];
2133 fGoodBins[1] = end[0];
2134 fGoodBins[2] = start[1];
2135 fGoodBins[3] = end[1];
2136
2137 // make sure that fGoodBins are in proper range for fForward and fBackward
2138 if (fGoodBins[0] < 0)
2139 fGoodBins[0]=0;
2140 if (fGoodBins[1] > fForward.size()) {
2141 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift forward lgb,";
2142 std::cerr << std::endl << ">> from " << fGoodBins[1] << " to " << fForward.size()-1 << std::endl;
2143 fGoodBins[1]=fForward.size()-1;
2144 }
2145 if (fGoodBins[2] < 0)
2146 fGoodBins[2]=0;
2147 if (fGoodBins[3] > fBackward.size()) {
2148 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift backward lgb,";
2149 std::cerr << std::endl << ">> from " << fGoodBins[1] << " to " << fForward.size()-1 << std::endl;
2150 fGoodBins[3]=fBackward.size()-1;
2151 }
2152
2153 return true;
2154}
2155
2156//--------------------------------------------------------------------------
2157// GetProperFitRange (private)
2158//--------------------------------------------------------------------------
2182{
2183 // set fit start/end time; first check RUN Block
2184 fFitStartTime = fRunInfo->GetFitRange(0);
2185 fFitEndTime = fRunInfo->GetFitRange(1);
2186 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
2187 if (fRunInfo->IsFitRangeInBin()) {
2188 fFitStartTime = (fGoodBins[0] + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
2189 fFitEndTime = (fGoodBins[1] - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
2190 // write these times back into the data structure. This way it is available when writting the log-file
2191 fRunInfo->SetFitRange(fFitStartTime, 0);
2192 fRunInfo->SetFitRange(fFitEndTime, 1);
2193 }
2194 if (fFitStartTime == PMUSR_UNDEFINED) { // fit start/end NOT found in the RUN block, check GLOBAL block
2195 fFitStartTime = globalBlock->GetFitRange(0);
2196 fFitEndTime = globalBlock->GetFitRange(1);
2197 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
2198 if (globalBlock->IsFitRangeInBin()) {
2199 fFitStartTime = (fGoodBins[0] + globalBlock->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
2200 fFitEndTime = (fGoodBins[1] - globalBlock->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
2201 // write these times back into the data structure. This way it is available when writting the log-file
2202 globalBlock->SetFitRange(fFitStartTime, 0);
2203 globalBlock->SetFitRange(fFitEndTime, 1);
2204 }
2205 }
2207 fFitStartTime = (fGoodBins[0] - fT0s[0]) * fTimeResolution; // (fgb-t0)*dt
2208 fFitEndTime = (fGoodBins[1] - fT0s[0]) * fTimeResolution; // (lgb-t0)*dt
2209 std::cerr << ">> PRunSingleHisto::GetProperFitRange(): **WARNING** Couldn't get fit start/end time!" << std::endl;
2210 std::cerr << ">> Will set it to fgb/lgb which given in time is: " << fFitStartTime << "..." << fFitEndTime << " (usec)" << std::endl;
2211 }
2212}
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
static std::vector< std::string > Split(const std::string &str, const std::string &delimiters)