musrfit 1.10.0
PRunAsymmetryRRF.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PRunAsymmetryRRF.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 <fstream>
42#include <string>
43#include <vector>
44
45#include <TString.h>
46
47#include "PMusr.h"
48#include "PStringUtils.h"
49#include "PRunAsymmetryRRF.h"
50
51//--------------------------------------------------------------------------
52// Constructor
53//--------------------------------------------------------------------------
62{
63 fNoOfFitBins = 0;
64 fRRFPacking = -1;
65 fTheoAsData = false;
66
67 // the 2 following variables are need in case fit range is given in bins, and since
68 // the fit range can be changed in the command block, these variables need to be accessible
69 fGoodBins[0] = -1;
70 fGoodBins[1] = -1;
71}
72
73//--------------------------------------------------------------------------
74// Constructor
75//--------------------------------------------------------------------------
102PRunAsymmetryRRF::PRunAsymmetryRRF(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData) :
103 PRunBase(msrInfo, rawData, runNo, tag), fTheoAsData(theoAsData)
104{
105 // the 2 following variables are need in case fit range is given in bins, and since
106 // the fit range can be changed in the command block, these variables need to be accessible
107 fGoodBins[0] = -1;
108 fGoodBins[1] = -1;
109
110 fRRFPacking = fMsrInfo->GetMsrGlobal()->GetRRFPacking();
111 if (fRRFPacking == -1) { // this should NOT happen, somethin is severely wrong
112 std::cerr << std::endl << ">> PRunAsymmetryRRF::PRunAsymmetryRRF(): **SEVERE ERROR**: Couldn't find any RRF packing information!";
113 std::cerr << std::endl << ">> This is very bad :-(, will quit ...";
114 std::cerr << std::endl;
115 fValid = false;
116 return;
117 }
118
119 // check if alpha and/or beta is fixed --------------------
120
121 PMsrParamList *param = msrInfo->GetMsrParamList();
122
123 // check if alpha is given
124 if (fRunInfo->GetAlphaParamNo() == -1) { // no alpha given
125 std::cerr << std::endl << ">> PRunAsymmetryRRF::PRunAsymmetryRRF(): **ERROR** no alpha parameter given! This is needed for an asymmetry fit!";
126 std::cerr << std::endl;
127 fValid = false;
128 return;
129 }
130 // check if alpha parameter is within proper bounds
131 if (fRunInfo->GetAlphaParamNo() >= MSR_PARAM_FUN_OFFSET) { // alpha seems to be a function
132 if ((fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET < 0) ||
133 (fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET > msrInfo->GetNoOfFuncs())) {
134 std::cerr << std::endl << ">> PRunAsymmetryRRF::PRunAsymmetryRRF(): **ERROR** alpha parameter is a function with no = " << fRunInfo->GetAlphaParamNo();
135 std::cerr << std::endl << ">> This is out of bound, since there are only " << msrInfo->GetNoOfFuncs() << " functions.";
136 std::cerr << std::endl;
137 fValid = false;
138 return;
139 }
140 } else if ((fRunInfo->GetAlphaParamNo() < 0) || (fRunInfo->GetAlphaParamNo() > static_cast<Int_t>(param->size()))) {
141 std::cerr << std::endl << ">> PRunAsymmetryRRF::PRunAsymmetryRRF(): **ERROR** alpha parameter no = " << fRunInfo->GetAlphaParamNo();
142 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
143 std::cerr << std::endl;
144 fValid = false;
145 return;
146 }
147 // check if alpha is fixed
148 Bool_t alphaFixedToOne = false;
149 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
150 if (((*param)[fRunInfo->GetAlphaParamNo()-1].fStep == 0.0) &&
151 ((*param)[fRunInfo->GetAlphaParamNo()-1].fValue == 1.0))
152 alphaFixedToOne = true;
153 }
154
155 // check if beta is given
156 Bool_t betaFixedToOne = false;
157 if (fRunInfo->GetBetaParamNo() == -1) { // no beta given hence assuming beta == 1
158 betaFixedToOne = true;
159 } else if (fRunInfo->GetBetaParamNo() >= MSR_PARAM_FUN_OFFSET) { // beta seems to be a function
160 if ((fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET < 0) ||
161 (fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET > msrInfo->GetNoOfFuncs())) {
162 std::cerr << std::endl << ">> PRunAsymmetryRRF::PRunAsymmetryRRF(): **ERROR** beta parameter is a function with no = " << fRunInfo->GetBetaParamNo();
163 std::cerr << std::endl << ">> This is out of bound, since there are only " << msrInfo->GetNoOfFuncs() << " functions.";
164 std::cerr << std::endl;
165 fValid = false;
166 return;
167 }
168 } else if ((fRunInfo->GetBetaParamNo() < 0) || (fRunInfo->GetBetaParamNo() > static_cast<Int_t>(param->size()))) { // check if beta parameter is within proper bounds
169 std::cerr << std::endl << ">> PRunAsymmetryRRF::PRunAsymmetryRRF(): **ERROR** beta parameter no = " << fRunInfo->GetBetaParamNo();
170 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
171 std::cerr << std::endl;
172 fValid = false;
173 return;
174 } else { // check if beta is fixed
175 if (((*param)[fRunInfo->GetBetaParamNo()-1].fStep == 0.0) &&
176 ((*param)[fRunInfo->GetBetaParamNo()-1].fValue == 1.0))
177 betaFixedToOne = true;
178 }
179
180 // set fAlphaBetaTag
181 if (alphaFixedToOne && betaFixedToOne) // alpha == 1, beta == 1
182 fAlphaBetaTag = 1;
183 else if (!alphaFixedToOne && betaFixedToOne) // alpha != 1, beta == 1
184 fAlphaBetaTag = 2;
185 else if (alphaFixedToOne && !betaFixedToOne) // alpha == 1, beta != 1
186 fAlphaBetaTag = 3;
187 else
188 fAlphaBetaTag = 4;
189
190 // calculate fData
191 if (!PrepareData())
192 fValid = false;
193}
194
195//--------------------------------------------------------------------------
196// Destructor
197//--------------------------------------------------------------------------
205{
206 fForward.clear();
207 fForwardErr.clear();
208 fBackward.clear();
209 fBackwardErr.clear();
210}
211
212//--------------------------------------------------------------------------
213// CalcChiSquare (public)
214//--------------------------------------------------------------------------
235Double_t PRunAsymmetryRRF::CalcChiSquare(const std::vector<Double_t>& par)
236{
237 Double_t chisq = 0.0;
238 Double_t diff = 0.0;
239 Double_t asymFcnValue = 0.0;
240 Double_t a, b, f;
241
242 // calculate functions
243 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
244 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
245 }
246
247 // calculate chi square
248 Double_t time(1.0);
249 Int_t i;
250
251 // determine alpha/beta
252 switch (fAlphaBetaTag) {
253 case 1: // alpha == 1, beta == 1
254 a = 1.0;
255 b = 1.0;
256 break;
257 case 2: // alpha != 1, beta == 1
258 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
259 a = par[fRunInfo->GetAlphaParamNo()-1];
260 } else { // alpha is function
261 // get function number
262 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
263 // evaluate function
264 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
265 }
266 b = 1.0;
267 break;
268 case 3: // alpha == 1, beta != 1
269 a = 1.0;
270 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
271 b = par[fRunInfo->GetBetaParamNo()-1];
272 } else { // beta is a function
273 // get function number
274 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
275 // evaluate function
276 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
277 }
278 break;
279 case 4: // alpha != 1, beta != 1
280 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
281 a = par[fRunInfo->GetAlphaParamNo()-1];
282 } else { // alpha is function
283 // get function number
284 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
285 // evaluate function
286 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
287 }
288 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
289 b = par[fRunInfo->GetBetaParamNo()-1];
290 } else { // beta is a function
291 // get function number
292 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
293 // evaluate function
294 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
295 }
296 break;
297 default:
298 a = 1.0;
299 b = 1.0;
300 break;
301 }
302
303 // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
304 // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
305 // for a given set of parameters---which should be done outside of the parallelized loop.
306 // For all other functions it means a tiny and acceptable overhead.
307 asymFcnValue = fTheory->Func(time, par, fFuncValues);
308
309 #ifdef HAVE_GOMP
310 Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
311 if (chunk < 10)
312 chunk = 10;
313 #pragma omp parallel for default(shared) private(i,time,diff,asymFcnValue,f) schedule(dynamic,chunk) reduction(+:chisq)
314 #endif
315 for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
316 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
317 f = fTheory->Func(time, par, fFuncValues);
318 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
319 diff = fData.GetValue()->at(i) - asymFcnValue;
320 chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
321 }
322
323 return chisq;
324}
325
326//--------------------------------------------------------------------------
327// CalcChiSquareExpected (public)
328//--------------------------------------------------------------------------
342Double_t PRunAsymmetryRRF::CalcChiSquareExpected(const std::vector<Double_t>& par)
343{
344 return 0.0;
345}
346
347//--------------------------------------------------------------------------
348// CalcMaxLikelihood (public)
349//--------------------------------------------------------------------------
362Double_t PRunAsymmetryRRF::CalcMaxLikelihood(const std::vector<Double_t>& par)
363{
364 std::cout << std::endl << "PRunAsymmetryRRF::CalcMaxLikelihood(): not implemented yet ..." << std::endl;
365
366 return 1.0;
367}
368
369//--------------------------------------------------------------------------
370// GetNoOfFitBins (public)
371//--------------------------------------------------------------------------
382{
384
385 return fNoOfFitBins;
386}
387
388//--------------------------------------------------------------------------
389// SetFitRangeBin (public)
390//--------------------------------------------------------------------------
415void PRunAsymmetryRRF::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 << ">> PRunSingleHisto::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 << ">> PRunSingleHisto::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
507 else
508 fNoOfFitBins = 0;
509}
510
511//--------------------------------------------------------------------------
512// CalcTheory (protected)
513//--------------------------------------------------------------------------
535{
536 // feed the parameter vector
537 std::vector<Double_t> par;
538 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
539 for (UInt_t i=0; i<paramList->size(); i++)
540 par.push_back((*paramList)[i].fValue);
541
542 // calculate functions
543 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
544 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
545 }
546
547 // calculate asymmetry
548 Double_t asymFcnValue = 0.0;
549 Double_t a, b, f;
550 Double_t time;
551 for (UInt_t i=0; i<fData.GetValue()->size(); i++) {
552 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
553 switch (fAlphaBetaTag) {
554 case 1: // alpha == 1, beta == 1
555 asymFcnValue = fTheory->Func(time, par, fFuncValues);
556 break;
557 case 2: // alpha != 1, beta == 1
558 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
559 a = par[fRunInfo->GetAlphaParamNo()-1];
560 } else { // alpha is function
561 // get function number
562 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
563 // evaluate function
564 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
565 }
566 f = fTheory->Func(time, par, fFuncValues);
567 asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0));
568 break;
569 case 3: // alpha == 1, beta != 1
570 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
571 b = par[fRunInfo->GetBetaParamNo()-1];
572 } else { // beta is a function
573 // get function number
574 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
575 // evaluate function
576 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
577 }
578 f = fTheory->Func(time, par, fFuncValues);
579 asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0));
580 break;
581 case 4: // alpha != 1, beta != 1
582 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
583 a = par[fRunInfo->GetAlphaParamNo()-1];
584 } else { // alpha is function
585 // get function number
586 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
587 // evaluate function
588 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
589 }
590 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
591 b = par[fRunInfo->GetBetaParamNo()-1];
592 } else { // beta is a function
593 // get function number
594 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
595 // evaluate function
596 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
597 }
598 f = fTheory->Func(time, par, fFuncValues);
599 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
600 break;
601 default:
602 asymFcnValue = 0.0;
603 break;
604 }
605 fData.AppendTheoryValue(asymFcnValue);
606 }
607
608 // clean up
609 par.clear();
610}
611
612//--------------------------------------------------------------------------
613// PrepareData (protected)
614//--------------------------------------------------------------------------
645{
646 if (!fValid)
647 return false;
648
649 // keep the Global block info
650 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
651
652 // get forward/backward histo from PRunDataHandler object ------------------------
653 // get the correct run
654 PRawRunData *runData = fRawData->GetRunData(*(fRunInfo->GetRunName()));
655 if (!runData) { // run not found
656 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **ERROR** Couldn't get run " << fRunInfo->GetRunName()->Data() << "!";
657 std::cerr << std::endl;
658 return false;
659 }
660
661 // keep the field from the meta-data from the data-file
662 fMetaData.fField = runData->GetField();
663
664 // keep the energy from the meta-data from the data-file
665 fMetaData.fEnergy = runData->GetEnergy();
666
667 // keep the temperature(s) from the meta-data from the data-file
668 for (unsigned int i=0; i<runData->GetNoOfTemperatures(); i++)
669 fMetaData.fTemp.push_back(runData->GetTemperature(i));
670
671 // collect histogram numbers
672 PUIntVector forwardHistoNo;
673 PUIntVector backwardHistoNo;
674 for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
675 forwardHistoNo.push_back(fRunInfo->GetForwardHistoNo(i));
676
677 if (!runData->IsPresent(forwardHistoNo[i])) {
678 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **PANIC ERROR**:";
679 std::cerr << std::endl << ">> forwardHistoNo found = " << forwardHistoNo[i] << ", which is NOT present in the data file!?!?";
680 std::cerr << std::endl << ">> Will quit :-(";
681 std::cerr << std::endl;
682 // clean up
683 forwardHistoNo.clear();
684 backwardHistoNo.clear();
685 return false;
686 }
687 }
688 for (UInt_t i=0; i<fRunInfo->GetBackwardHistoNoSize(); i++) {
689 backwardHistoNo.push_back(fRunInfo->GetBackwardHistoNo(i));
690
691 if (!runData->IsPresent(backwardHistoNo[i])) {
692 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **PANIC ERROR**:";
693 std::cerr << std::endl << ">> backwardHistoNo found = " << backwardHistoNo[i] << ", which is NOT present in the data file!?!?";
694 std::cerr << std::endl << ">> Will quit :-(";
695 std::cerr << std::endl;
696 // clean up
697 forwardHistoNo.clear();
698 backwardHistoNo.clear();
699 return false;
700 }
701 }
702
703 // keep the time resolution in (us)
704 fTimeResolution = runData->GetTimeResolution()/1.0e3;
705 std::cout.precision(10);
706 std::cout << std::endl << ">> PRunAsymmetryRRF::PrepareData(): time resolution=" << std::fixed << runData->GetTimeResolution() << "(ns)" << std::endl;
707
708 // get all the proper t0's and addt0's for the current RUN block
709 if (!GetProperT0(runData, globalBlock, forwardHistoNo, backwardHistoNo)) {
710 return false;
711 }
712
713 // keep the histo of each group at this point (addruns handled below)
714 std::vector<PDoubleVector> forward, backward;
715 forward.resize(forwardHistoNo.size()); // resize to number of groups
716 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
717 forward[i].resize(runData->GetDataBin(forwardHistoNo[i])->size());
718 forward[i] = *runData->GetDataBin(forwardHistoNo[i]);
719 }
720 // check if a dead time correction has to be done
721 // this will be done automatically in the function itself, which also
722 // checks in the global and run section
723 DeadTimeCorrection(forward, forwardHistoNo);
724
725 backward.resize(backwardHistoNo.size()); // resize to number of groups
726 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
727 backward[i].resize(runData->GetDataBin(backwardHistoNo[i])->size());
728 backward[i] = *runData->GetDataBin(backwardHistoNo[i]);
729 }
730 // check if a dead time correction has to be done
731 // this will be done automatically in the function itself, which also
732 // checks in the global and run section
733 DeadTimeCorrection(forward, forwardHistoNo);
734
735 // check if addrun's are present, and if yes add data
736 // check if there are runs to be added to the current one
737 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
738 PRawRunData *addRunData;
739 std::vector<PDoubleVector> addForward, addBackward;
740 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
741 // get run to be added to the main one
742 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
743 if (addRunData == nullptr) { // couldn't get run
744 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
745 std::cerr << std::endl;
746 return false;
747 }
748
749 // dead time correction handling
750 addForward.clear();
751 addForward.resize(forwardHistoNo.size());
752 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
753 addForward[j].resize(addRunData->GetDataBin(forwardHistoNo[j])->size());
754 addForward[j] = *addRunData->GetDataBin(forwardHistoNo[j]);
755 }
756 DeadTimeCorrection(addForward, forwardHistoNo);
757 addBackward.clear();
758 addBackward.resize(backwardHistoNo.size());
759 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
760 addBackward[j].resize(addRunData->GetDataBin(backwardHistoNo[j])->size());
761 addBackward[j] = *addRunData->GetDataBin(backwardHistoNo[j]);
762 }
763 DeadTimeCorrection(addBackward, backwardHistoNo);
764
765 // add forward run
766 UInt_t addRunSize;
767 for (UInt_t k=0; k<forwardHistoNo.size(); k++) { // fill each group
768 addRunSize = addRunData->GetDataBin(forwardHistoNo[k])->size();
769 for (UInt_t j=0; j<addRunData->GetDataBin(forwardHistoNo[k])->size(); j++) { // loop over the bin indices
770 // make sure that the index stays in the proper range
771 if (((Int_t)j+(Int_t)fAddT0s[i-1][2*k]-(Int_t)fT0s[2*k] >= 0) && (j+(Int_t)fAddT0s[i-1][2*k]-(Int_t)fT0s[2*k] < addRunSize)) {
772 forward[k][j] += addForward[k][j+(Int_t)fAddT0s[i-1][2*k]-(Int_t)fT0s[2*k]];
773 }
774 }
775 }
776
777 // add backward run
778 for (UInt_t k=0; k<backwardHistoNo.size(); k++) { // fill each group
779 addRunSize = addRunData->GetDataBin(backwardHistoNo[k])->size();
780 for (UInt_t j=0; j<addRunData->GetDataBin(backwardHistoNo[k])->size(); j++) { // loop over the bin indices
781 // make sure that the index stays in the proper range
782 if (((Int_t)j+(Int_t)fAddT0s[i-1][2*k+1]-(Int_t)fT0s[2*k+1] >= 0) && (j+(Int_t)fAddT0s[i-1][2*k+1]-(Int_t)fT0s[2*k+1] < addRunSize)) {
783 backward[k][j] += addBackward[k][j+(Int_t)fAddT0s[i-1][2*k+1]-(Int_t)fT0s[2*k+1]];
784 }
785 }
786 }
787 }
788 }
789
790 // set forward/backward histo data of the first group
791 fForward.resize(forward[0].size());
792 fBackward.resize(backward[0].size());
793 for (UInt_t i=0; i<fForward.size(); i++) {
794 fForward[i] = forward[0][i];
795 fBackward[i] = backward[0][i];
796 }
797
798 // group histograms, add all the remaining forward histograms of the group
799 for (UInt_t i=1; i<forwardHistoNo.size(); i++) { // loop over the groupings
800 for (UInt_t j=0; j<runData->GetDataBin(forwardHistoNo[i])->size(); j++) { // loop over the bin indices
801 // make sure that the index stays within proper range
802 if (((Int_t)j+fT0s[2*i]-fT0s[0] >= 0) && (j+fT0s[2*i]-fT0s[0] < runData->GetDataBin(forwardHistoNo[i])->size())) {
803 fForward[j] += forward[i][j+(Int_t)fT0s[2*i]-(Int_t)fT0s[0]];
804 }
805 }
806 }
807
808 // group histograms, add all the remaining backward histograms of the group
809 for (UInt_t i=1; i<backwardHistoNo.size(); i++) { // loop over the groupings
810 for (UInt_t j=0; j<runData->GetDataBin(backwardHistoNo[i])->size(); j++) { // loop over the bin indices
811 // make sure that the index stays within proper range
812 if ((j+fT0s[2*i+1]-fT0s[1] >= 0) && (j+fT0s[2*i+1]-fT0s[1] < runData->GetDataBin(backwardHistoNo[i])->size())) {
813 fBackward[j] += backward[i][j+(Int_t)fT0s[2*i+1]-(Int_t)fT0s[1]];
814 }
815 }
816 }
817
818 // subtract background from histogramms ------------------------------------------
819 if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) { // no fixed background given
820 if (fRunInfo->GetBkgRange(0) >= 0) { // background range given
822 return false;
823 } else { // no background given to do the job, try to estimate it
824 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.1), 0);
825 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.6), 1);
826 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.1), 2);
827 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.6), 3);
828 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **WARNING** Neither fix background nor background bins are given!";
829 std::cerr << std::endl << ">> Will try the following:";
830 std::cerr << std::endl << ">> forward: bkg start = " << fRunInfo->GetBkgRange(0) << ", bkg end = " << fRunInfo->GetBkgRange(1);
831 std::cerr << std::endl << ">> backward: bkg start = " << fRunInfo->GetBkgRange(2) << ", bkg end = " << fRunInfo->GetBkgRange(3);
832 std::cerr << std::endl << ">> NO WARRANTY THAT THIS MAKES ANY SENSE! Better check ...";
833 std::cerr << std::endl;
835 return false;
836 }
837 } else { // fixed background given
838 if (!SubtractFixBkg())
839 return false;
840 }
841
842 UInt_t histoNo[2] = {forwardHistoNo[0], backwardHistoNo[0]};
843
844 // get the data range (fgb/lgb) for the current RUN block
845 if (!GetProperDataRange(runData, histoNo)) {
846 return false;
847 }
848
849 // get the fit range for the current RUN block
850 GetProperFitRange(globalBlock);
851
852 // everything looks fine, hence fill data set
853 Bool_t status;
854 switch(fHandleTag) {
855 case kFit:
857 break;
858 case kView:
859 status = PrepareViewData(runData, histoNo);
860 break;
861 default:
862 status = false;
863 break;
864 }
865
866 // clean up
867 forwardHistoNo.clear();
868 backwardHistoNo.clear();
869
870 return status;
871}
872
873//--------------------------------------------------------------------------
874// SubtractFixBkg (private)
875//--------------------------------------------------------------------------
893{
894 Double_t dval;
895 for (UInt_t i=0; i<fForward.size(); i++) {
896 // keep the error, and make sure that the bin is NOT empty
897 if (fForward[i] != 0.0)
898 dval = TMath::Sqrt(fForward[i]);
899 else
900 dval = 1.0;
901 fForwardErr.push_back(dval);
902 fForward[i] -= fRunInfo->GetBkgFix(0);
903
904 // keep the error, and make sure that the bin is NOT empty
905 if (fBackward[i] != 0.0)
906 dval = TMath::Sqrt(fBackward[i]);
907 else
908 dval = 1.0;
909 fBackwardErr.push_back(dval);
910 fBackward[i] -= fRunInfo->GetBkgFix(1);
911 }
912
913 return true;
914}
915
916//--------------------------------------------------------------------------
917// SubtractEstimatedBkg (private)
918//--------------------------------------------------------------------------
937{
938 Double_t beamPeriod = 0.0;
939
940 // check if data are from PSI, RAL, or TRIUMF
941 if (fRunInfo->GetInstitute()->Contains("psi"))
942 beamPeriod = ACCEL_PERIOD_PSI;
943 else if (fRunInfo->GetInstitute()->Contains("ral"))
944 beamPeriod = ACCEL_PERIOD_RAL;
945 else if (fRunInfo->GetInstitute()->Contains("triumf"))
946 beamPeriod = ACCEL_PERIOD_TRIUMF;
947 else
948 beamPeriod = 0.0;
949
950 // check if start and end are in proper order
951 UInt_t start[2] = {static_cast<UInt_t>(fRunInfo->GetBkgRange(0)), static_cast<UInt_t>(fRunInfo->GetBkgRange(2))};
952 UInt_t end[2] = {static_cast<UInt_t>(fRunInfo->GetBkgRange(1)), static_cast<UInt_t>(fRunInfo->GetBkgRange(3))};
953 for (UInt_t i=0; i<2; i++) {
954 if (end[i] < start[i]) {
955 std::cout << std::endl << "PRunAsymmetryRRF::SubtractEstimatedBkg(): end = " << end[i] << " > start = " << start[i] << "! Will swap them!";
956 UInt_t keep = end[i];
957 end[i] = start[i];
958 start[i] = keep;
959 }
960 }
961
962 // calculate proper background range
963 for (UInt_t i=0; i<2; i++) {
964 if (beamPeriod != 0.0) {
965 Double_t timeBkg = static_cast<Double_t>(end[i]-start[i])*fTimeResolution; // length of the background intervall in time
966 UInt_t fullCycles = static_cast<UInt_t>(timeBkg/beamPeriod); // how many proton beam cylces can be placed within the proposed background intervall
967 // correct the end of the background intervall such that the background is as close as possible to a multiple of the proton cylce
968 end[i] = start[i] + static_cast<UInt_t>((fullCycles*beamPeriod)/fTimeResolution);
969 std::cout << "PRunAsymmetryRRF::SubtractEstimatedBkg(): Background " << start[i] << ", " << end[i] << std::endl;
970 if (end[i] == start[i])
971 end[i] = fRunInfo->GetBkgRange(2*i+1);
972 }
973 }
974
975 // check if start is within histogram bounds
976 if ((start[0] >= fForward.size()) || (start[1] >= fBackward.size())) {
977 std::cerr << std::endl << ">> PRunAsymmetryRRF::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
978 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
979 std::cerr << std::endl << ">> background start (f/b) = (" << start[0] << "/" << start[1] << ").";
980 return false;
981 }
982
983 // check if end is within histogram bounds
984 if ((end[0] >= fForward.size()) || (end[1] >= fBackward.size())) {
985 std::cerr << std::endl << ">> PRunAsymmetryRRF::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
986 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
987 std::cerr << std::endl << ">> background end (f/b) = (" << end[0] << "/" << end[1] << ").";
988 return false;
989 }
990
991 // calculate background
992 Double_t bkg[2] = {0.0, 0.0};
993 Double_t errBkg[2] = {0.0, 0.0};
994
995 // forward
996 for (UInt_t i=start[0]; i<=end[0]; i++)
997 bkg[0] += fForward[i];
998 errBkg[0] = TMath::Sqrt(bkg[0])/(end[0] - start[0] + 1);
999 bkg[0] /= static_cast<Double_t>(end[0] - start[0] + 1);
1000 std::cout << std::endl << ">> estimated forward histo background: " << bkg[0];
1001
1002 // backward
1003 for (UInt_t i=start[1]; i<=end[1]; i++)
1004 bkg[1] += fBackward[i];
1005 errBkg[1] = TMath::Sqrt(bkg[1])/(end[1] - start[1] + 1);
1006 bkg[1] /= static_cast<Double_t>(end[1] - start[1] + 1);
1007 std::cout << std::endl << ">> estimated backward histo background: " << bkg[1] << std::endl;
1008
1009 // correct error for forward, backward
1010 Double_t errVal = 0.0;
1011 for (UInt_t i=0; i<fForward.size(); i++) {
1012 if (fForward[i] > 0.0)
1013 errVal = TMath::Sqrt(fForward[i]+errBkg[0]*errBkg[0]);
1014 else
1015 errVal = 1.0;
1016 fForwardErr.push_back(errVal);
1017 if (fBackward[i] > 0.0)
1018 errVal = TMath::Sqrt(fBackward[i]+errBkg[1]*errBkg[1]);
1019 else
1020 errVal = 1.0;
1021 fBackwardErr.push_back(errVal);
1022 }
1023
1024 // subtract background from data
1025 for (UInt_t i=0; i<fForward.size(); i++) {
1026 fForward[i] -= bkg[0];
1027 fBackward[i] -= bkg[1];
1028 }
1029
1030 fRunInfo->SetBkgEstimated(bkg[0], 0);
1031 fRunInfo->SetBkgEstimated(bkg[1], 1);
1032
1033 return true;
1034}
1035
1036//--------------------------------------------------------------------------
1037// PrepareFitData (protected)
1038//--------------------------------------------------------------------------
1061{
1062 // transform raw histo data. At this point, the raw data are already background corrected.
1063
1064 // 1st: form the asymmetry of the original data
1065
1066 // forward and backward detectors might have different fgb-t0 offset. Take the maximum of both.
1067 Int_t fgbOffset = fGoodBins[0]-static_cast<Int_t>(fT0s[0]);
1068 if (fgbOffset < fGoodBins[2]-static_cast<Int_t>(fT0s[1]))
1069 fgbOffset = fGoodBins[2]-static_cast<Int_t>(fT0s[1]);
1070 // last good bin (lgb) is the minimum of forward/backward lgb
1071 Int_t lgb_offset = fGoodBins[1]-static_cast<Int_t>(fT0s[0])+fgbOffset;
1072 if (lgb_offset < fGoodBins[3]-static_cast<Int_t>(fT0s[1])+fgbOffset)
1073 lgb_offset = fGoodBins[3]-static_cast<Int_t>(fT0s[1])+fgbOffset;
1074
1075 Int_t fgb = static_cast<Int_t>(fT0s[0])+fgbOffset;
1076 if (fgb < 0)
1077 fgb=0;
1078 Int_t lgb = fgb + lgb_offset;
1079 if (lgb > fForward.size())
1080 lgb = fForward.size();
1081 if (lgb > fBackward.size())
1082 lgb = fBackward.size();
1083 Int_t dt0 = static_cast<Int_t>(fT0s[0])-static_cast<Int_t>(fT0s[1]);
1084
1085 PDoubleVector asym;
1086 PDoubleVector asymErr;
1087 Double_t asymVal, asymValErr;
1088 Double_t ff, bb, eff, ebb;
1089 Int_t idx=0;
1090 for (Int_t i=fgb; i<lgb; i++) {
1091 ff = fForward[i];
1092 idx = i-dt0;
1093 if (idx < 0)
1094 idx = 0;
1095 if (idx >= fBackward.size())
1096 idx = fBackward.size()-1;
1097 bb = fBackward[idx];
1098 if (ff+bb != 0.0)
1099 asymVal = (ff-bb)/(ff+bb);
1100 else
1101 asymVal = 0.0;
1102 asym.push_back(asymVal);
1103 eff = fForwardErr[i];
1104 ebb = fBackwardErr[i-dt0];
1105 if ((asymVal != 0.0) && (ff+bb) > 0.0)
1106 asymValErr = 2.0/pow((ff+bb),2.0)*sqrt(bb*bb*eff*eff+ff*ff*ebb*ebb);
1107 else
1108 asymValErr = 1.0;
1109 asymErr.push_back(asymValErr);
1110 }
1111
1112 // 2nd: a_rrf = a * 2*cos(w_rrf*t + phi_rrf)
1113 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
1114 Double_t wRRF = globalBlock->GetRRFFreq("Mc");
1115 Double_t phaseRRF = globalBlock->GetRRFPhase()*TMath::TwoPi()/180.0;
1116
1117 Double_t startTime = fTimeResolution * static_cast<Double_t>(fgbOffset);
1118 Double_t time=0.0;
1119 for (UInt_t i=0; i<asym.size(); i++) {
1120 time = startTime + i*fTimeResolution;
1121 asym[i] *= 2.0*cos(wRRF*time+phaseRRF);
1122 }
1123
1124 // 3rd: rrf packing
1125 PDoubleVector asymRRF;
1126 asymVal = 0.0;
1127 for (UInt_t i=0; i<asym.size(); i++) {
1128 if ((i+1) % fRRFPacking == 0) {
1129 asymRRF.push_back(asymVal/fRRFPacking);
1130 asymVal = 0.0;
1131 }
1132 asymVal += asym[i];
1133 }
1134
1135 // 4th: rrf packing error
1136 PDoubleVector asymRRFErr;
1137 asymValErr = 0.0;
1138 for (UInt_t i=0; i<asymErr.size(); i++) {
1139 if ((i+1) % fRRFPacking == 0) {
1140 asymRRFErr.push_back(sqrt(2.0*asymValErr)/fRRFPacking); // factor of two is needed due to the rescaling
1141 asymValErr = 0.0;
1142 }
1143 asymValErr += asymErr[i]*asymErr[i];
1144 }
1145
1146 fData.SetDataTimeStart(startTime+fTimeResolution*(static_cast<Double_t>(fRRFPacking-1)/2.0));
1147 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(fRRFPacking));
1148
1149 for (UInt_t i=0; i<asymRRF.size(); i++) {
1150 fData.AppendValue(asymRRF[i]);
1151 fData.AppendErrorValue(asymRRFErr[i]);
1152 }
1153
1155
1156 // clean up
1157 fForward.clear();
1158 fForwardErr.clear();
1159 fBackward.clear();
1160 fBackwardErr.clear();
1161 asym.clear();
1162 asymErr.clear();
1163 asymRRF.clear();
1164 asymRRFErr.clear();
1165
1166 return true;
1167}
1168
1169//--------------------------------------------------------------------------
1170// PrepareViewData (protected)
1171//--------------------------------------------------------------------------
1197Bool_t PRunAsymmetryRRF::PrepareViewData(PRawRunData* runData, UInt_t histoNo[2])
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 // first get start data, end data, and t0
1206 Int_t start[2] = {fGoodBins[0], fGoodBins[2]};
1207 Int_t end[2] = {fGoodBins[1], fGoodBins[3]};
1208 Int_t t0[2] = {static_cast<Int_t>(fT0s[0]), static_cast<Int_t>(fT0s[1])};
1209
1210 // check if the data ranges and t0's between forward/backward are compatible
1211 Int_t fgb[2];
1212 if (start[0]-t0[0] != start[1]-t0[1]) { // wrong fgb aligning
1213 if (abs(start[0]-t0[0]) > abs(start[1]-t0[1])) {
1214 fgb[0] = start[0];
1215 fgb[1] = t0[1] + start[0]-t0[0];
1216 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **WARNING** needed to shift backward fgb from ";
1217 std::cerr << start[1] << " to " << fgb[1] << std::endl;
1218 } else {
1219 fgb[0] = t0[0] + start[1]-t0[1];
1220 fgb[1] = start[1];
1221 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **WARNING** needed to shift forward fgb from ";
1222 std::cerr << start[0] << " to " << fgb[0] << std::endl;
1223 }
1224 } else { // fgb aligning is correct
1225 fgb[0] = start[0];
1226 fgb[1] = start[1];
1227 }
1228 start[0] = fgb[0];
1229 start[1] = fgb[1];
1230
1231 // make sure that there are equal number of bins in forward and backward
1232 UInt_t noOfBins0 = runData->GetDataBin(histoNo[0])->size()-start[0];
1233 UInt_t noOfBins1 = runData->GetDataBin(histoNo[1])->size()-start[1];
1234 if (noOfBins0 > noOfBins1)
1235 noOfBins0 = noOfBins1;
1236 end[0] = start[0] + noOfBins0;
1237 end[1] = start[1] + noOfBins0;
1238
1239 // check if start, end, and t0 make any sense
1240 for (UInt_t i=0; i<2; i++) {
1241 // 1st check if start is within proper bounds
1242 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1243 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **ERROR** start data bin doesn't make any sense!";
1244 std::cerr << std::endl;
1245 return false;
1246 }
1247 // 2nd check if end is within proper bounds
1248 if ((end[i] < 0) || (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1249 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **ERROR** end data bin doesn't make any sense!";
1250 std::cerr << std::endl;
1251 return false;
1252 }
1253 // 3rd check if t0 is within proper bounds
1254 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1255 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **ERROR** t0 data bin doesn't make any sense!";
1256 std::cerr << std::endl;
1257 return false;
1258 }
1259 }
1260
1261 // check if forward and backward histo have the same size, otherwise take the minimum size
1262 UInt_t noOfBins = fForward.size();
1263 if (noOfBins > fBackward.size()) {
1264 noOfBins = fBackward.size();
1265 }
1266
1267 // form asymmetry including error propagation
1268 Double_t asym, error;
1269 Double_t f, b, ef, eb, alpha = 1.0, beta = 1.0;
1270
1271 // get the proper alpha and beta
1272 switch (fAlphaBetaTag) {
1273 case 1: // alpha == 1, beta == 1
1274 alpha = 1.0;
1275 beta = 1.0;
1276 break;
1277 case 2: // alpha != 1, beta == 1
1278 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1279 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1280 } else { // alpha is function
1281 // get function number
1282 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1283 // evaluate function
1284 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1285 }
1286 beta = 1.0;
1287 break;
1288 case 3: // alpha == 1, beta != 1
1289 alpha = 1.0;
1290 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1291 beta = par[fRunInfo->GetBetaParamNo()-1];
1292 } else { // beta is a function
1293 // get function number
1294 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1295 // evaluate function
1296 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1297 }
1298 break;
1299 case 4: // alpha != 1, beta != 1
1300 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1301 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1302 } else { // alpha is function
1303 // get function number
1304 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1305 // evaluate function
1306 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1307 }
1308 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1309 beta = par[fRunInfo->GetBetaParamNo()-1];
1310 } else { // beta is a function
1311 // get function number
1312 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1313 // evaluate function
1314 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1315 }
1316 break;
1317 default:
1318 break;
1319 }
1320
1321 PDoubleVector asymVec, asymErr;
1322 Int_t dtBin = start[1]-start[0];
1323 for (Int_t i=start[0]; i<end[0]; i++) {
1324 // to make the formulae more readable
1325 f = fForward[i];
1326 b = fBackward[i+dtBin];
1327 ef = fForwardErr[i];
1328 eb = fBackwardErr[i+dtBin];
1329 // check that there are indeed bins
1330 if (f+b != 0.0)
1331 asym = (alpha*f-b) / (alpha*beta*f+b);
1332 else
1333 asym = 0.0;
1334 asymVec.push_back(asym);
1335 // calculate the error
1336 if (f+b != 0.0)
1337 error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
1338 else
1339 error = 1.0;
1340 asymErr.push_back(error);
1341 }
1342
1343 // RRF transform
1344 // a_rrf = a * 2*cos(w_rrf*t + phi_rrf)
1345 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
1346 Double_t wRRF = globalBlock->GetRRFFreq("Mc");
1347 Double_t phaseRRF = globalBlock->GetRRFPhase()*TMath::TwoPi()/180.0;
1348 Double_t startTime=fTimeResolution*(static_cast<Double_t>(start[0])-t0[0]);
1349 Double_t time = 0.0;
1350 for (UInt_t i=0; i<asymVec.size(); i++) {
1351 time = startTime + i * fTimeResolution;
1352 asymVec[i] *= 2.0*cos(wRRF*time+phaseRRF); // factor of 2 needed to keep the asymmetry
1353 }
1354
1355 Double_t dval = 0.0;
1356 PDoubleVector asymRRF;
1357 for (UInt_t i=0; i<asymVec.size(); i++) {
1358 if ((i+1) % fRRFPacking == 0) {
1359 asymRRF.push_back(dval/fRRFPacking);
1360 dval = 0.0;
1361 }
1362 dval += asymVec[i];
1363 }
1364
1365 // RRF packing error
1366 PDoubleVector asymRRFErr;
1367 dval = 0.0;
1368 for (UInt_t i=0; i<asymErr.size(); i++) {
1369 if ((i+1) % fRRFPacking == 0) {
1370 asymRRFErr.push_back(sqrt(2.0*dval)/fRRFPacking); // factor of two is needed due to the rescaling
1371 dval = 0.0;
1372 }
1373 dval += asymErr[i]*asymErr[i];
1374 }
1375
1376 fData.SetDataTimeStart(startTime+fTimeResolution*(static_cast<Double_t>(fRRFPacking-1)/2.0));
1377 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(fRRFPacking));
1378
1379 for (UInt_t i=0; i<asymRRF.size(); i++) {
1380 fData.AppendValue(asymRRF[i]);
1381 fData.AppendErrorValue(asymRRFErr[i]);
1382 }
1383
1385
1386 // clean up
1387 fForward.clear();
1388 fForwardErr.clear();
1389 fBackward.clear();
1390 fBackwardErr.clear();
1391 asymVec.clear();
1392 asymErr.clear();
1393 asymRRF.clear();
1394 asymRRFErr.clear();
1395
1396 // fill theory vector for kView
1397 // calculate functions
1398 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
1399 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
1400 }
1401
1402 // calculate theory
1403 UInt_t size = runData->GetDataBin(histoNo[0])->size();
1404 Int_t factor = 8; // 8 times more points for the theory (if fTheoAsData == false)
1405 fData.SetTheoryTimeStart(fData.GetDataTimeStart());
1406 if (fTheoAsData) { // calculate theory only at the data points
1407 fData.SetTheoryTimeStep(fData.GetDataTimeStep());
1408 } else {
1409 // finer binning for the theory (8 times as many points = factor)
1410 size *= factor;
1411 fData.SetTheoryTimeStep(fData.GetDataTimeStep()/(Double_t)factor);
1412 }
1413
1414 for (UInt_t i=0; i<size; i++) {
1415 time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
1416 dval = fTheory->Func(time, par, fFuncValues);
1417 if (fabs(dval) > 10.0) { // dirty hack needs to be fixed!!
1418 dval = 0.0;
1419 }
1420 fData.AppendTheoryValue(dval);
1421 }
1422
1423 // clean up
1424 par.clear();
1425
1426 return true;
1427}
1428
1429//--------------------------------------------------------------------------
1430// GetProperT0 (private)
1431//--------------------------------------------------------------------------
1450Bool_t PRunAsymmetryRRF::GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHistoNo, PUIntVector &backwardHistoNo)
1451{
1452 // feed all T0's
1453 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1454 fT0s.clear();
1455 // this strange fT0 size estimate is needed in case #forw histos != #back histos
1456 size_t size = 2*forwardHistoNo.size();
1457 if (backwardHistoNo.size() > forwardHistoNo.size())
1458 size = 2*backwardHistoNo.size();
1459 fT0s.resize(size);
1460 for (UInt_t i=0; i<fT0s.size(); i++) {
1461 fT0s[i] = -1.0;
1462 }
1463
1464 // fill in the T0's from the msr-file (if present)
1465 for (UInt_t i=0; i<fRunInfo->GetT0BinSize(); i++) {
1466 fT0s[i] = fRunInfo->GetT0Bin(i);
1467 }
1468
1469 // fill in the missing T0's from the GLOBAL block section (if present)
1470 for (UInt_t i=0; i<globalBlock->GetT0BinSize(); i++) {
1471 if (fT0s[i] == -1.0) { // i.e. not given in the RUN block section
1472 fT0s[i] = globalBlock->GetT0Bin(i);
1473 }
1474 }
1475
1476 // fill in the missing T0's from the data file, if not already present in the msr-file
1477 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1478 if (fT0s[2*i] == -1.0) // i.e. not present in the msr-file, try the data file
1479 if (runData->GetT0Bin(forwardHistoNo[i]) > 0.0) {
1480 fT0s[2*i] = runData->GetT0Bin(forwardHistoNo[i]);
1481 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1482 }
1483 }
1484 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1485 if (fT0s[2*i+1] == -1.0) // i.e. not present in the msr-file, try the data file
1486 if (runData->GetT0Bin(backwardHistoNo[i]) > 0.0) {
1487 fT0s[2*i+1] = runData->GetT0Bin(backwardHistoNo[i]);
1488 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1489 }
1490 }
1491
1492 // 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
1493 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1494 if (fT0s[2*i] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1495 fT0s[2*i] = runData->GetT0BinEstimated(forwardHistoNo[i]);
1496 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1497
1498 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1499 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1500 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << runData->GetT0BinEstimated(forwardHistoNo[i]);
1501 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1502 std::cerr << std::endl;
1503 }
1504 }
1505 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1506 if (fT0s[2*i+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1507 fT0s[2*i+1] = runData->GetT0BinEstimated(backwardHistoNo[i]);
1508 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1509
1510 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1511 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1512 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[i]);
1513 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1514 std::cerr << std::endl;
1515 }
1516 }
1517
1518 // check if t0 is within proper bounds
1519 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1520 if ((fT0s[2*i] < 0) || (fT0s[2*i] > static_cast<Int_t>(runData->GetDataBin(forwardHistoNo[i])->size()))) {
1521 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **ERROR** t0 data bin (" << fT0s[2*i] << ") doesn't make any sense!";
1522 std::cerr << std::endl << ">> forwardHistoNo " << forwardHistoNo[i];
1523 std::cerr << std::endl;
1524 return false;
1525 }
1526 }
1527 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1528 if ((fT0s[2*i+1] < 0) || (fT0s[2*i+1] > static_cast<Int_t>(runData->GetDataBin(backwardHistoNo[i])->size()))) {
1529 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **ERROR** t0 data bin (" << fT0s[2*i+1] << ") doesn't make any sense!";
1530 std::cerr << std::endl << ">> backwardHistoNo " << backwardHistoNo[i];
1531 std::cerr << std::endl;
1532 return false;
1533 }
1534 }
1535
1536 // check if addrun's are present, and if yes add the necessary t0's
1537 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
1538 PRawRunData *addRunData;
1539 fAddT0s.resize(fRunInfo->GetRunNameSize()-1); // resize to the number of addruns
1540 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
1541 // get run to be added to the main one
1542 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
1543 if (addRunData == nullptr) { // couldn't get run
1544 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
1545 std::cerr << std::endl;
1546 return false;
1547 }
1548
1549 // feed all T0's
1550 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1551 fAddT0s[i-1].clear();
1552 fAddT0s[i-1].resize(2*forwardHistoNo.size());
1553 for (UInt_t j=0; j<fAddT0s[i-1].size(); j++) {
1554 fAddT0s[i-1][j] = -1.0;
1555 }
1556
1557 // fill in the T0's from the msr-file (if present)
1558 for (Int_t j=0; j<fRunInfo->GetAddT0BinSize(i-1); j++) {
1559 fAddT0s[i-1][j] = fRunInfo->GetAddT0Bin(i-1, j);
1560 }
1561
1562 // fill in the T0's from the data file, if not already present in the msr-file
1563 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1564 if (fAddT0s[i-1][2*j] == -1.0) // i.e. not present in the msr-file, try the data file
1565 if (addRunData->GetT0Bin(forwardHistoNo[j]) > 0.0) {
1566 fAddT0s[i-1][2*j] = addRunData->GetT0Bin(forwardHistoNo[j]);
1567 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1568 }
1569 }
1570 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1571 if (fAddT0s[i-1][2*j+1] == -1.0) // i.e. not present in the msr-file, try the data file
1572 if (addRunData->GetT0Bin(backwardHistoNo[j]) > 0.0) {
1573 fAddT0s[i-1][2*j+1] = addRunData->GetT0Bin(backwardHistoNo[j]);
1574 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1575 }
1576 }
1577
1578 // 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
1579 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1580 if (fAddT0s[i-1][2*j] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1581 fAddT0s[i-1][2*j] = addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1582 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1583
1584 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1585 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1586 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1587 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1588 std::cerr << std::endl;
1589 }
1590 }
1591 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1592 if (fAddT0s[i-1][2*j+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1593 fAddT0s[i-1][2*j+1] = addRunData->GetT0BinEstimated(backwardHistoNo[j]);
1594 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1595
1596 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1597 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1598 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[j]);
1599 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1600 std::cerr << std::endl;
1601 }
1602 }
1603 }
1604 }
1605
1606 return true;
1607}
1608
1609//--------------------------------------------------------------------------
1610// GetProperDataRange (private)
1611//--------------------------------------------------------------------------
1625Bool_t PRunAsymmetryRRF::GetProperDataRange(PRawRunData* runData, UInt_t histoNo[2])
1626{
1627 // first get start/end data
1628 Int_t start[2] = {fRunInfo->GetDataRange(0), fRunInfo->GetDataRange(2)};
1629 Int_t end[2] = {fRunInfo->GetDataRange(1), fRunInfo->GetDataRange(3)};
1630 // check if data range has been provided in the RUN block. If not, try the GLOBAL block
1631 if (start[0] == -1) {
1632 start[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(0);
1633 }
1634 if (start[1] == -1) {
1635 start[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(2);
1636 }
1637 if (end[0] == -1) {
1638 end[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(1);
1639 }
1640 if (end[1] == -1) {
1641 end[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(3);
1642 }
1643
1644 Double_t t0[2] = {fT0s[0], fT0s[1]};
1645 Int_t offset = static_cast<Int_t>(10.0e-3/fTimeResolution); // needed in case first good bin is not given, default = 10ns
1646
1647 // check if data range has been provided, and if not try to estimate them
1648 if (start[0] < 0) {
1649 start[0] = static_cast<Int_t>(t0[0])+offset;
1650 fRunInfo->SetDataRange(start[0], 0);
1651 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[0] << ".";
1652 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
1653 std::cerr << std::endl;
1654 }
1655 if (start[1] < 0) {
1656 start[1] = static_cast<Int_t>(t0[1])+offset;
1657 fRunInfo->SetDataRange(start[1], 2);
1658 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[1] << ".";
1659 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
1660 std::cerr << std::endl;
1661 }
1662 if (end[0] < 0) {
1663 end[0] = runData->GetDataBin(histoNo[0])->size();
1664 fRunInfo->SetDataRange(end[0], 1);
1665 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range end = " << end[0] << ".";
1666 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
1667 std::cerr << std::endl;
1668 }
1669 if (end[1] < 0) {
1670 end[1] = runData->GetDataBin(histoNo[1])->size();
1671 fRunInfo->SetDataRange(end[1], 3);
1672 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range end = " << end[1] << ".";
1673 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
1674 std::cerr << std::endl;
1675 }
1676
1677 // check if start, end, and t0 make any sense
1678 // 1st check if start and end are in proper order
1679 for (UInt_t i=0; i<2; i++) {
1680 if (end[i] < start[i]) { // need to swap them
1681 Int_t keep = end[i];
1682 end[i] = start[i];
1683 start[i] = keep;
1684 }
1685 // 2nd check if start is within proper bounds
1686 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1687 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **ERROR** start data bin doesn't make any sense!";
1688 std::cerr << std::endl;
1689 return false;
1690 }
1691 // 3rd check if end is within proper bounds
1692 if (end[i] < 0) {
1693 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **ERROR** end data bin (" << end[i] << ") doesn't make any sense!";
1694 std::cerr << std::endl;
1695 return false;
1696 }
1697 if (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())) {
1698 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** end data bin (" << end[i] << ") > histo length (" << (Int_t)runData->GetDataBin(histoNo[i])->size() << ").";
1699 std::cerr << std::endl << ">> Will set end = (histo length - 1). Consider to change it in the msr-file." << std::endl;
1700 std::cerr << std::endl;
1701 end[i] = static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())-1;
1702 }
1703 // 4th check if t0 is within proper bounds
1704 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1705 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **ERROR** t0 data bin doesn't make any sense!";
1706 std::cerr << std::endl;
1707 return false;
1708 }
1709 }
1710
1711 // check that start-t0 is the same for forward as for backward, otherwise take max(start[i]-t0[i])
1712 if (fabs(static_cast<Double_t>(start[0])-t0[0]) > fabs(static_cast<Double_t>(start[1])-t0[1])){
1713 start[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(start[0]) - t0[0]);
1714 end[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(end[0]) - t0[0]);
1715 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange **WARNING** needed to shift backward data range.";
1716 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(2) << ", " << fRunInfo->GetDataRange(3);
1717 std::cerr << std::endl << ">> used : " << start[1] << ", " << end[1];
1718 std::cerr << std::endl;
1719 }
1720 if (fabs(static_cast<Double_t>(start[0])-t0[0]) < fabs(static_cast<Double_t>(start[1])-t0[1])){
1721 start[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(start[1]) - t0[1]);
1722 end[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(end[1]) - t0[1]);
1723 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange **WARNING** needed to shift forward data range.";
1724 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(0) << ", " << fRunInfo->GetDataRange(1);
1725 std::cerr << std::endl << ">> used : " << start[0] << ", " << end[0];
1726 std::cerr << std::endl;
1727 }
1728
1729 // keep good bins for potential latter use
1730 fGoodBins[0] = start[0];
1731 fGoodBins[1] = end[0];
1732 fGoodBins[2] = start[1];
1733 fGoodBins[3] = end[1];
1734
1735 // make sure that fGoodBins are in proper range for fForward and fBackward
1736 if (fGoodBins[0] < 0)
1737 fGoodBins[0]=0;
1738 if (fGoodBins[1] > fForward.size()) {
1739 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift forward lgb,";
1740 std::cerr << std::endl << ">> from " << fGoodBins[1] << " to " << fForward.size()-1 << std::endl;
1741 fGoodBins[1]=fForward.size()-1;
1742 }
1743 if (fGoodBins[2] < 0)
1744 fGoodBins[2]=0;
1745 if (fGoodBins[3] > fBackward.size()) {
1746 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift backward lgb,";
1747 std::cerr << std::endl << ">> from " << fGoodBins[1] << " to " << fForward.size()-1 << std::endl;
1748 fGoodBins[3]=fBackward.size()-1;
1749 }
1750
1751 return true;
1752}
1753
1754//--------------------------------------------------------------------------
1755// GetProperFitRange (private)
1756//--------------------------------------------------------------------------
1770{
1771 // set fit start/end time; first check RUN Block
1772 fFitStartTime = fRunInfo->GetFitRange(0);
1773 fFitEndTime = fRunInfo->GetFitRange(1);
1774 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1775 if (fRunInfo->IsFitRangeInBin()) {
1776 fFitStartTime = (fGoodBins[0] + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1777 fFitEndTime = (fGoodBins[1] - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1778 // write these times back into the data structure. This way it is available when writting the log-file
1779 fRunInfo->SetFitRange(fFitStartTime, 0);
1780 fRunInfo->SetFitRange(fFitEndTime, 1);
1781 }
1782 if (fFitStartTime == PMUSR_UNDEFINED) { // fit start/end NOT found in the RUN block, check GLOBAL block
1783 fFitStartTime = globalBlock->GetFitRange(0);
1784 fFitEndTime = globalBlock->GetFitRange(1);
1785 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1786 if (globalBlock->IsFitRangeInBin()) {
1787 fFitStartTime = (fGoodBins[0] + globalBlock->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1788 fFitEndTime = (fGoodBins[1] - globalBlock->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1789 // write these times back into the data structure. This way it is available when writting the log-file
1790 globalBlock->SetFitRange(fFitStartTime, 0);
1791 globalBlock->SetFitRange(fFitEndTime, 1);
1792 }
1793 }
1795 fFitStartTime = (fGoodBins[0] - fT0s[0]) * fTimeResolution; // (fgb-t0)*dt
1796 fFitEndTime = (fGoodBins[1] - fT0s[0]) * fTimeResolution; // (lgb-t0)*dt
1797 std::cerr << ">> PRunSingleHisto::GetProperFitRange(): **WARNING** Couldn't get fit start/end time!" << std::endl;
1798 std::cerr << ">> Will set it to fgb/lgb which given in time is: " << fFitStartTime << "..." << fFitEndTime << " (usec)" << std::endl;
1799 }
1800}
std::vector< UInt_t > PUIntVector
Definition PMusr.h:375
#define ACCEL_PERIOD_TRIUMF
TRIUMF accelerator cycle: 43.37 ns.
Definition PMusr.h:156
EPMusrHandleTag
Definition PMusr.h:427
@ kFit
Fitting mode - perform least-squares fit to data.
Definition PMusr.h:429
@ kView
Viewing mode - display data and theory without fitting.
Definition PMusr.h:430
#define PMUSR_UNDEFINED
Definition PMusr.h:177
#define MSR_PARAM_FUN_OFFSET
Offset added to function indices for parameter parsing.
Definition PMusr.h:265
std::vector< PMsrParamStructure > PMsrParamList
Definition PMusr.h:1040
#define ACCEL_PERIOD_PSI
PSI (Paul Scherrer Institute) accelerator cycle: 19.75 ns.
Definition PMusr.h:154
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
virtual Double_t GetRRFPhase()
Definition PMusr.h:1064
virtual Double_t GetRRFFreq(const char *unit)
Definition PMusr.cpp:865
MSR file parser and manager for the musrfit framework.
virtual PMsrParamList * GetMsrParamList()
Returns pointer to fit parameter list.
virtual const PDoubleVector * GetDataBin(const UInt_t histoNo)
Definition PMusr.h:896
virtual const Double_t GetT0Bin(const UInt_t histoNo)
Definition PMusr.h:884
virtual const Double_t GetTimeResolution()
Definition PMusr.h:882
virtual const Bool_t IsPresent(UInt_t histoNo)
Definition PMusr.h:883
virtual const UInt_t GetNoOfTemperatures()
Definition PMusr.h:874
virtual const Double_t GetField()
Definition PMusr.h:873
virtual const Double_t GetEnergy()
Definition PMusr.h:878
virtual const Double_t GetT0BinEstimated(const UInt_t histoNo)
Definition PMusr.h:885
virtual const PDoublePairVector * GetTemperature() const
Definition PMusr.h:875
virtual void GetProperFitRange(PMsrGlobalBlock *globalBlock)
Determines the proper fit range from global block.
PRunAsymmetryRRF()
Default constructor.
virtual UInt_t GetNoOfFitBins()
Returns the number of bins used in the fit.
Int_t fGoodBins[4]
Good bin boundaries: [0]=forward first, [1]=forward last, [2]=backward first, [3]=backward last.
PDoubleVector fForwardErr
Forward detector histogram errors.
virtual Double_t CalcChiSquareExpected(const std::vector< Double_t > &par)
Calculates expected chi-square (for statistical analysis).
virtual Bool_t GetProperDataRange(PRawRunData *runData, UInt_t histoNo[2])
Retrieves proper data range for histograms.
Bool_t fTheoAsData
If true, theory calculated only at data points; if false, extra points for nicer Fourier transforms.
virtual Bool_t PrepareViewData(PRawRunData *runData, UInt_t histoNo[2])
Prepares RRF data for viewing/plotting.
Bool_t SubtractEstimatedBkg()
Estimates and subtracts background from histograms.
virtual ~PRunAsymmetryRRF()
Destructor.
virtual Bool_t PrepareData()
Prepares all data for RRF fitting or viewing.
Int_t fEndTimeBin
Last bin index for fitting (after RRF transformation)
Int_t fRRFPacking
RRF packing factor from GLOBAL block (required for RRF analysis)
Bool_t SubtractFixBkg()
Subtracts fixed background from histograms.
virtual Bool_t GetProperT0(PRawRunData *runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHisto, PUIntVector &backwardHistoNo)
Retrieves proper t0 values for all histograms.
virtual void SetFitRangeBin(const TString fitRange)
Sets the fit range in bins (can be changed dynamically via COMMAND block).
PDoubleVector fForward
Forward detector histogram data.
UInt_t fNoOfFitBins
Number of bins included in the fit after RRF packing.
PDoubleVector fBackward
Backward detector histogram data.
UInt_t fAlphaBetaTag
Tag indicating α/β configuration: 1=both unity, 2=α free/β unity, 3=α unity/β free,...
virtual Bool_t PrepareFitData()
Prepares RRF data specifically for fitting.
virtual void CalcTheory()
Calculates theoretical RRF asymmetry function.
virtual Double_t CalcChiSquare(const std::vector< Double_t > &par)
Calculates chi-square for the RRF asymmetry fit.
virtual void CalcNoOfFitBins()
Calculates the number of bins to be fitted.
virtual Double_t CalcMaxLikelihood(const std::vector< Double_t > &par)
Calculates maximum likelihood estimator.
Int_t fStartTimeBin
First bin index for fitting (after RRF transformation)
PDoubleVector fBackwardErr
Backward detector histogram errors.
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
PRunData fData
Processed data container: background-corrected, packed, with theory values.
Definition PRunBase.h:275
PRunDataHandler * fRawData
Pointer to raw data handler (owned externally, not deleted here)
Definition PRunBase.h:273
PDoubleVector fT0s
Time-zero bin values for all histograms in this run (forward, backward, etc.)
Definition PRunBase.h:278
PRunBase()
Default constructor.
Definition PRunBase.cpp:52
Int_t fRunNo
Run number (0-based index in MSR file RUN blocks)
Definition PRunBase.h:270
PMsrRunBlock * fRunInfo
Pointer to this run's RUN block settings within fMsrInfo.
Definition PRunBase.h:272
Double_t fFitStartTime
Fit range start time in microseconds (μs) relative to t0.
Definition PRunBase.h:281
Raw data file reader and format converter for μSR data.
static std::vector< std::string > Split(const std::string &str, const std::string &delimiters)