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() < 0) || (fRunInfo->GetAlphaParamNo() > static_cast<Int_t>(param->size()))) {
132 std::cerr << std::endl << ">> PRunAsymmetryRRF::PRunAsymmetryRRF(): **ERROR** alpha parameter no = " << fRunInfo->GetAlphaParamNo();
133 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
134 std::cerr << std::endl;
135 fValid = false;
136 return;
137 }
138 // check if alpha is fixed
139 Bool_t alphaFixedToOne = false;
140 if (((*param)[fRunInfo->GetAlphaParamNo()-1].fStep == 0.0) &&
141 ((*param)[fRunInfo->GetAlphaParamNo()-1].fValue == 1.0))
142 alphaFixedToOne = true;
143
144 // check if beta is given
145 Bool_t betaFixedToOne = false;
146 if (fRunInfo->GetBetaParamNo() == -1) { // no beta given hence assuming beta == 1
147 betaFixedToOne = true;
148 } else if ((fRunInfo->GetBetaParamNo() < 0) || (fRunInfo->GetBetaParamNo() > static_cast<Int_t>(param->size()))) { // check if beta parameter is within proper bounds
149 std::cerr << std::endl << ">> PRunAsymmetryRRF::PRunAsymmetryRRF(): **ERROR** beta parameter no = " << fRunInfo->GetBetaParamNo();
150 std::cerr << std::endl << ">> This is out of bound, since there are only " << param->size() << " parameters.";
151 std::cerr << std::endl;
152 fValid = false;
153 return;
154 } else { // check if beta is fixed
155 if (((*param)[fRunInfo->GetBetaParamNo()-1].fStep == 0.0) &&
156 ((*param)[fRunInfo->GetBetaParamNo()-1].fValue == 1.0))
157 betaFixedToOne = true;
158 }
159
160 // set fAlphaBetaTag
161 if (alphaFixedToOne && betaFixedToOne) // alpha == 1, beta == 1
162 fAlphaBetaTag = 1;
163 else if (!alphaFixedToOne && betaFixedToOne) // alpha != 1, beta == 1
164 fAlphaBetaTag = 2;
165 else if (alphaFixedToOne && !betaFixedToOne) // alpha == 1, beta != 1
166 fAlphaBetaTag = 3;
167 else
168 fAlphaBetaTag = 4;
169
170 // calculate fData
171 if (!PrepareData())
172 fValid = false;
173}
174
175//--------------------------------------------------------------------------
176// Destructor
177//--------------------------------------------------------------------------
185{
186 fForward.clear();
187 fForwardErr.clear();
188 fBackward.clear();
189 fBackwardErr.clear();
190}
191
192//--------------------------------------------------------------------------
193// CalcChiSquare (public)
194//--------------------------------------------------------------------------
215Double_t PRunAsymmetryRRF::CalcChiSquare(const std::vector<Double_t>& par)
216{
217 Double_t chisq = 0.0;
218 Double_t diff = 0.0;
219 Double_t asymFcnValue = 0.0;
220 Double_t a, b, f;
221
222 // calculate functions
223 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
224 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
225 }
226
227 // calculate chi square
228 Double_t time(1.0);
229 Int_t i;
230
231 // determine alpha/beta
232 switch (fAlphaBetaTag) {
233 case 1: // alpha == 1, beta == 1
234 a = 1.0;
235 b = 1.0;
236 break;
237 case 2: // alpha != 1, beta == 1
238 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
239 a = par[fRunInfo->GetAlphaParamNo()-1];
240 } else { // alpha is function
241 // get function number
242 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
243 // evaluate function
244 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
245 }
246 b = 1.0;
247 break;
248 case 3: // alpha == 1, beta != 1
249 a = 1.0;
250 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
251 b = par[fRunInfo->GetBetaParamNo()-1];
252 } else { // beta is a function
253 // get function number
254 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
255 // evaluate function
256 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
257 }
258 break;
259 case 4: // 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 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
269 b = par[fRunInfo->GetBetaParamNo()-1];
270 } else { // beta is a function
271 // get function number
272 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
273 // evaluate function
274 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
275 }
276 break;
277 default:
278 a = 1.0;
279 b = 1.0;
280 break;
281 }
282
283 // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
284 // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
285 // for a given set of parameters---which should be done outside of the parallelized loop.
286 // For all other functions it means a tiny and acceptable overhead.
287 asymFcnValue = fTheory->Func(time, par, fFuncValues);
288
289 #ifdef HAVE_GOMP
290 Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
291 if (chunk < 10)
292 chunk = 10;
293 #pragma omp parallel for default(shared) private(i,time,diff,asymFcnValue,f) schedule(dynamic,chunk) reduction(+:chisq)
294 #endif
295 for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
296 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
297 f = fTheory->Func(time, par, fFuncValues);
298 asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
299 diff = fData.GetValue()->at(i) - asymFcnValue;
300 chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
301 }
302
303 return chisq;
304}
305
306//--------------------------------------------------------------------------
307// CalcChiSquareExpected (public)
308//--------------------------------------------------------------------------
322Double_t PRunAsymmetryRRF::CalcChiSquareExpected(const std::vector<Double_t>& par)
323{
324 return 0.0;
325}
326
327//--------------------------------------------------------------------------
328// CalcMaxLikelihood (public)
329//--------------------------------------------------------------------------
342Double_t PRunAsymmetryRRF::CalcMaxLikelihood(const std::vector<Double_t>& par)
343{
344 std::cout << std::endl << "PRunAsymmetryRRF::CalcMaxLikelihood(): not implemented yet ..." << std::endl;
345
346 return 1.0;
347}
348
349//--------------------------------------------------------------------------
350// GetNoOfFitBins (public)
351//--------------------------------------------------------------------------
362{
364
365 return fNoOfFitBins;
366}
367
368//--------------------------------------------------------------------------
369// SetFitRangeBin (public)
370//--------------------------------------------------------------------------
395void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange)
396{
397 TString str;
398 Ssiz_t idx = -1;
399 Int_t offset = 0;
400
401 std::vector<std::string> tok = PStringUtils::Split(fitRange.Data(), " \t");
402
403 if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1
404 // handle fgb+n0 entry
405 str = tok[1];
406 // check if there is an offset present
407 idx = str.First("+");
408 if (idx != -1) { // offset present
409 str.Remove(0, idx+1);
410 if (str.IsFloat()) // if str is a valid number, convert is to an integer
411 offset = str.Atoi();
412 }
413 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
414
415 // handle lgb-n1 entry
416 str = tok[2];
417 // check if there is an offset present
418 idx = str.First("-");
419 if (idx != -1) { // offset present
420 str.Remove(0, idx+1);
421 if (str.IsFloat()) // if str is a valid number, convert is to an integer
422 offset = str.Atoi();
423 }
424 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
425 } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
426 UInt_t pos = 2*(fRunNo+1)-1;
427
428 if (pos + 1 >= tok.size()) {
429 std::cerr << std::endl << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
430 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
431 } else {
432 // handle fgb+n0 entry
433 str = tok[pos];
434 // check if there is an offset present
435 idx = str.First("+");
436 if (idx != -1) { // offset present
437 str.Remove(0, idx+1);
438 if (str.IsFloat()) // if str is a valid number, convert is to an integer
439 offset = str.Atoi();
440 }
441 fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
442
443 // handle lgb-n1 entry
444 str = tok[pos+1];
445 // check if there is an offset present
446 idx = str.First("-");
447 if (idx != -1) { // offset present
448 str.Remove(0, idx+1);
449 if (str.IsFloat()) // if str is a valid number, convert is to an integer
450 offset = str.Atoi();
451 }
452 fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
453 }
454 } else { // error
455 std::cerr << std::endl << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
456 std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
457 }
458}
459
460//--------------------------------------------------------------------------
461// CalcNoOfFitBins (public)
462//--------------------------------------------------------------------------
476{
477 // In order not having to loop over all bins and to stay consistent with the chisq method, calculate the start and end bins explicitly
478 fStartTimeBin = static_cast<Int_t>(ceil((fFitStartTime - fData.GetDataTimeStart())/fData.GetDataTimeStep()));
479 if (fStartTimeBin < 0)
480 fStartTimeBin = 0;
481 fEndTimeBin = static_cast<Int_t>(floor((fFitEndTime - fData.GetDataTimeStart())/fData.GetDataTimeStep())) + 1;
482 if (fEndTimeBin > static_cast<Int_t>(fData.GetValue()->size()))
483 fEndTimeBin = fData.GetValue()->size();
484
487 else
488 fNoOfFitBins = 0;
489}
490
491//--------------------------------------------------------------------------
492// CalcTheory (protected)
493//--------------------------------------------------------------------------
515{
516 // feed the parameter vector
517 std::vector<Double_t> par;
518 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
519 for (UInt_t i=0; i<paramList->size(); i++)
520 par.push_back((*paramList)[i].fValue);
521
522 // calculate functions
523 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
524 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
525 }
526
527 // calculate asymmetry
528 Double_t asymFcnValue = 0.0;
529 Double_t a, b, f;
530 Double_t time;
531 for (UInt_t i=0; i<fData.GetValue()->size(); i++) {
532 time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
533 switch (fAlphaBetaTag) {
534 case 1: // alpha == 1, beta == 1
535 asymFcnValue = fTheory->Func(time, par, fFuncValues);
536 break;
537 case 2: // alpha != 1, beta == 1
538 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
539 a = par[fRunInfo->GetAlphaParamNo()-1];
540 } else { // alpha is function
541 // get function number
542 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
543 // evaluate function
544 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
545 }
546 f = fTheory->Func(time, par, fFuncValues);
547 asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0));
548 break;
549 case 3: // alpha == 1, beta != 1
550 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
551 b = par[fRunInfo->GetBetaParamNo()-1];
552 } else { // beta is a function
553 // get function number
554 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
555 // evaluate function
556 b = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
557 }
558 f = fTheory->Func(time, par, fFuncValues);
559 asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0));
560 break;
561 case 4: // alpha != 1, beta != 1
562 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
563 a = par[fRunInfo->GetAlphaParamNo()-1];
564 } else { // alpha is function
565 // get function number
566 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
567 // evaluate function
568 a = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
569 }
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*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
580 break;
581 default:
582 asymFcnValue = 0.0;
583 break;
584 }
585 fData.AppendTheoryValue(asymFcnValue);
586 }
587
588 // clean up
589 par.clear();
590}
591
592//--------------------------------------------------------------------------
593// PrepareData (protected)
594//--------------------------------------------------------------------------
625{
626 if (!fValid)
627 return false;
628
629 // keep the Global block info
630 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
631
632 // get forward/backward histo from PRunDataHandler object ------------------------
633 // get the correct run
634 PRawRunData *runData = fRawData->GetRunData(*(fRunInfo->GetRunName()));
635 if (!runData) { // run not found
636 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **ERROR** Couldn't get run " << fRunInfo->GetRunName()->Data() << "!";
637 std::cerr << std::endl;
638 return false;
639 }
640
641 // keep the field from the meta-data from the data-file
642 fMetaData.fField = runData->GetField();
643
644 // keep the energy from the meta-data from the data-file
645 fMetaData.fEnergy = runData->GetEnergy();
646
647 // keep the temperature(s) from the meta-data from the data-file
648 for (unsigned int i=0; i<runData->GetNoOfTemperatures(); i++)
649 fMetaData.fTemp.push_back(runData->GetTemperature(i));
650
651 // collect histogram numbers
652 PUIntVector forwardHistoNo;
653 PUIntVector backwardHistoNo;
654 for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
655 forwardHistoNo.push_back(fRunInfo->GetForwardHistoNo(i));
656
657 if (!runData->IsPresent(forwardHistoNo[i])) {
658 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **PANIC ERROR**:";
659 std::cerr << std::endl << ">> forwardHistoNo found = " << forwardHistoNo[i] << ", which is NOT present in the data file!?!?";
660 std::cerr << std::endl << ">> Will quit :-(";
661 std::cerr << std::endl;
662 // clean up
663 forwardHistoNo.clear();
664 backwardHistoNo.clear();
665 return false;
666 }
667 }
668 for (UInt_t i=0; i<fRunInfo->GetBackwardHistoNoSize(); i++) {
669 backwardHistoNo.push_back(fRunInfo->GetBackwardHistoNo(i));
670
671 if (!runData->IsPresent(backwardHistoNo[i])) {
672 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **PANIC ERROR**:";
673 std::cerr << std::endl << ">> backwardHistoNo found = " << backwardHistoNo[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
683 // keep the time resolution in (us)
684 fTimeResolution = runData->GetTimeResolution()/1.0e3;
685 std::cout.precision(10);
686 std::cout << std::endl << ">> PRunAsymmetryRRF::PrepareData(): time resolution=" << std::fixed << runData->GetTimeResolution() << "(ns)" << std::endl;
687
688 // get all the proper t0's and addt0's for the current RUN block
689 if (!GetProperT0(runData, globalBlock, forwardHistoNo, backwardHistoNo)) {
690 return false;
691 }
692
693 // keep the histo of each group at this point (addruns handled below)
694 std::vector<PDoubleVector> forward, backward;
695 forward.resize(forwardHistoNo.size()); // resize to number of groups
696 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
697 forward[i].resize(runData->GetDataBin(forwardHistoNo[i])->size());
698 forward[i] = *runData->GetDataBin(forwardHistoNo[i]);
699 }
700 // check if a dead time correction has to be done
701 // this will be done automatically in the function itself, which also
702 // checks in the global and run section
703 DeadTimeCorrection(forward, forwardHistoNo);
704
705 backward.resize(backwardHistoNo.size()); // resize to number of groups
706 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
707 backward[i].resize(runData->GetDataBin(backwardHistoNo[i])->size());
708 backward[i] = *runData->GetDataBin(backwardHistoNo[i]);
709 }
710 // check if a dead time correction has to be done
711 // this will be done automatically in the function itself, which also
712 // checks in the global and run section
713 DeadTimeCorrection(forward, forwardHistoNo);
714
715 // check if addrun's are present, and if yes add data
716 // check if there are runs to be added to the current one
717 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
718 PRawRunData *addRunData;
719 std::vector<PDoubleVector> addForward, addBackward;
720 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
721 // get run to be added to the main one
722 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
723 if (addRunData == nullptr) { // couldn't get run
724 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
725 std::cerr << std::endl;
726 return false;
727 }
728
729 // dead time correction handling
730 addForward.clear();
731 addForward.resize(forwardHistoNo.size());
732 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
733 addForward[j].resize(addRunData->GetDataBin(forwardHistoNo[j])->size());
734 addForward[j] = *addRunData->GetDataBin(forwardHistoNo[j]);
735 }
736 DeadTimeCorrection(addForward, forwardHistoNo);
737 addBackward.clear();
738 addBackward.resize(backwardHistoNo.size());
739 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
740 addBackward[j].resize(addRunData->GetDataBin(backwardHistoNo[j])->size());
741 addBackward[j] = *addRunData->GetDataBin(backwardHistoNo[j]);
742 }
743 DeadTimeCorrection(addBackward, backwardHistoNo);
744
745 // add forward run
746 UInt_t addRunSize;
747 for (UInt_t k=0; k<forwardHistoNo.size(); k++) { // fill each group
748 addRunSize = addRunData->GetDataBin(forwardHistoNo[k])->size();
749 for (UInt_t j=0; j<addRunData->GetDataBin(forwardHistoNo[k])->size(); j++) { // loop over the bin indices
750 // make sure that the index stays in the proper range
751 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)) {
752 forward[k][j] += addForward[k][j+(Int_t)fAddT0s[i-1][2*k]-(Int_t)fT0s[2*k]];
753 }
754 }
755 }
756
757 // add backward run
758 for (UInt_t k=0; k<backwardHistoNo.size(); k++) { // fill each group
759 addRunSize = addRunData->GetDataBin(backwardHistoNo[k])->size();
760 for (UInt_t j=0; j<addRunData->GetDataBin(backwardHistoNo[k])->size(); j++) { // loop over the bin indices
761 // make sure that the index stays in the proper range
762 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)) {
763 backward[k][j] += addBackward[k][j+(Int_t)fAddT0s[i-1][2*k+1]-(Int_t)fT0s[2*k+1]];
764 }
765 }
766 }
767 }
768 }
769
770 // set forward/backward histo data of the first group
771 fForward.resize(forward[0].size());
772 fBackward.resize(backward[0].size());
773 for (UInt_t i=0; i<fForward.size(); i++) {
774 fForward[i] = forward[0][i];
775 fBackward[i] = backward[0][i];
776 }
777
778 // group histograms, add all the remaining forward histograms of the group
779 for (UInt_t i=1; i<forwardHistoNo.size(); i++) { // loop over the groupings
780 for (UInt_t j=0; j<runData->GetDataBin(forwardHistoNo[i])->size(); j++) { // loop over the bin indices
781 // make sure that the index stays within proper range
782 if (((Int_t)j+fT0s[2*i]-fT0s[0] >= 0) && (j+fT0s[2*i]-fT0s[0] < runData->GetDataBin(forwardHistoNo[i])->size())) {
783 fForward[j] += forward[i][j+(Int_t)fT0s[2*i]-(Int_t)fT0s[0]];
784 }
785 }
786 }
787
788 // group histograms, add all the remaining backward histograms of the group
789 for (UInt_t i=1; i<backwardHistoNo.size(); i++) { // loop over the groupings
790 for (UInt_t j=0; j<runData->GetDataBin(backwardHistoNo[i])->size(); j++) { // loop over the bin indices
791 // make sure that the index stays within proper range
792 if ((j+fT0s[2*i+1]-fT0s[1] >= 0) && (j+fT0s[2*i+1]-fT0s[1] < runData->GetDataBin(backwardHistoNo[i])->size())) {
793 fBackward[j] += backward[i][j+(Int_t)fT0s[2*i+1]-(Int_t)fT0s[1]];
794 }
795 }
796 }
797
798 // subtract background from histogramms ------------------------------------------
799 if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) { // no fixed background given
800 if (fRunInfo->GetBkgRange(0) >= 0) { // background range given
802 return false;
803 } else { // no background given to do the job, try to estimate it
804 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.1), 0);
805 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.6), 1);
806 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.1), 2);
807 fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[1]*0.6), 3);
808 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **WARNING** Neither fix background nor background bins are given!";
809 std::cerr << std::endl << ">> Will try the following:";
810 std::cerr << std::endl << ">> forward: bkg start = " << fRunInfo->GetBkgRange(0) << ", bkg end = " << fRunInfo->GetBkgRange(1);
811 std::cerr << std::endl << ">> backward: bkg start = " << fRunInfo->GetBkgRange(2) << ", bkg end = " << fRunInfo->GetBkgRange(3);
812 std::cerr << std::endl << ">> NO WARRANTY THAT THIS MAKES ANY SENSE! Better check ...";
813 std::cerr << std::endl;
815 return false;
816 }
817 } else { // fixed background given
818 if (!SubtractFixBkg())
819 return false;
820 }
821
822 UInt_t histoNo[2] = {forwardHistoNo[0], backwardHistoNo[0]};
823
824 // get the data range (fgb/lgb) for the current RUN block
825 if (!GetProperDataRange(runData, histoNo)) {
826 return false;
827 }
828
829 // get the fit range for the current RUN block
830 GetProperFitRange(globalBlock);
831
832 // everything looks fine, hence fill data set
833 Bool_t status;
834 switch(fHandleTag) {
835 case kFit:
837 break;
838 case kView:
839 status = PrepareViewData(runData, histoNo);
840 break;
841 default:
842 status = false;
843 break;
844 }
845
846 // clean up
847 forwardHistoNo.clear();
848 backwardHistoNo.clear();
849
850 return status;
851}
852
853//--------------------------------------------------------------------------
854// SubtractFixBkg (private)
855//--------------------------------------------------------------------------
873{
874 Double_t dval;
875 for (UInt_t i=0; i<fForward.size(); i++) {
876 // keep the error, and make sure that the bin is NOT empty
877 if (fForward[i] != 0.0)
878 dval = TMath::Sqrt(fForward[i]);
879 else
880 dval = 1.0;
881 fForwardErr.push_back(dval);
882 fForward[i] -= fRunInfo->GetBkgFix(0);
883
884 // keep the error, and make sure that the bin is NOT empty
885 if (fBackward[i] != 0.0)
886 dval = TMath::Sqrt(fBackward[i]);
887 else
888 dval = 1.0;
889 fBackwardErr.push_back(dval);
890 fBackward[i] -= fRunInfo->GetBkgFix(1);
891 }
892
893 return true;
894}
895
896//--------------------------------------------------------------------------
897// SubtractEstimatedBkg (private)
898//--------------------------------------------------------------------------
917{
918 Double_t beamPeriod = 0.0;
919
920 // check if data are from PSI, RAL, or TRIUMF
921 if (fRunInfo->GetInstitute()->Contains("psi"))
922 beamPeriod = ACCEL_PERIOD_PSI;
923 else if (fRunInfo->GetInstitute()->Contains("ral"))
924 beamPeriod = ACCEL_PERIOD_RAL;
925 else if (fRunInfo->GetInstitute()->Contains("triumf"))
926 beamPeriod = ACCEL_PERIOD_TRIUMF;
927 else
928 beamPeriod = 0.0;
929
930 // check if start and end are in proper order
931 UInt_t start[2] = {static_cast<UInt_t>(fRunInfo->GetBkgRange(0)), static_cast<UInt_t>(fRunInfo->GetBkgRange(2))};
932 UInt_t end[2] = {static_cast<UInt_t>(fRunInfo->GetBkgRange(1)), static_cast<UInt_t>(fRunInfo->GetBkgRange(3))};
933 for (UInt_t i=0; i<2; i++) {
934 if (end[i] < start[i]) {
935 std::cout << std::endl << "PRunAsymmetryRRF::SubtractEstimatedBkg(): end = " << end[i] << " > start = " << start[i] << "! Will swap them!";
936 UInt_t keep = end[i];
937 end[i] = start[i];
938 start[i] = keep;
939 }
940 }
941
942 // calculate proper background range
943 for (UInt_t i=0; i<2; i++) {
944 if (beamPeriod != 0.0) {
945 Double_t timeBkg = static_cast<Double_t>(end[i]-start[i])*fTimeResolution; // length of the background intervall in time
946 UInt_t fullCycles = static_cast<UInt_t>(timeBkg/beamPeriod); // how many proton beam cylces can be placed within the proposed background intervall
947 // correct the end of the background intervall such that the background is as close as possible to a multiple of the proton cylce
948 end[i] = start[i] + static_cast<UInt_t>((fullCycles*beamPeriod)/fTimeResolution);
949 std::cout << "PRunAsymmetryRRF::SubtractEstimatedBkg(): Background " << start[i] << ", " << end[i] << std::endl;
950 if (end[i] == start[i])
951 end[i] = fRunInfo->GetBkgRange(2*i+1);
952 }
953 }
954
955 // check if start is within histogram bounds
956 if ((start[0] >= fForward.size()) || (start[1] >= fBackward.size())) {
957 std::cerr << std::endl << ">> PRunAsymmetryRRF::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
958 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
959 std::cerr << std::endl << ">> background start (f/b) = (" << start[0] << "/" << start[1] << ").";
960 return false;
961 }
962
963 // check if end is within histogram bounds
964 if ((end[0] >= fForward.size()) || (end[1] >= fBackward.size())) {
965 std::cerr << std::endl << ">> PRunAsymmetryRRF::SubtractEstimatedBkg(): **ERROR** background bin values out of bound!";
966 std::cerr << std::endl << ">> histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
967 std::cerr << std::endl << ">> background end (f/b) = (" << end[0] << "/" << end[1] << ").";
968 return false;
969 }
970
971 // calculate background
972 Double_t bkg[2] = {0.0, 0.0};
973 Double_t errBkg[2] = {0.0, 0.0};
974
975 // forward
976 for (UInt_t i=start[0]; i<=end[0]; i++)
977 bkg[0] += fForward[i];
978 errBkg[0] = TMath::Sqrt(bkg[0])/(end[0] - start[0] + 1);
979 bkg[0] /= static_cast<Double_t>(end[0] - start[0] + 1);
980 std::cout << std::endl << ">> estimated forward histo background: " << bkg[0];
981
982 // backward
983 for (UInt_t i=start[1]; i<=end[1]; i++)
984 bkg[1] += fBackward[i];
985 errBkg[1] = TMath::Sqrt(bkg[1])/(end[1] - start[1] + 1);
986 bkg[1] /= static_cast<Double_t>(end[1] - start[1] + 1);
987 std::cout << std::endl << ">> estimated backward histo background: " << bkg[1] << std::endl;
988
989 // correct error for forward, backward
990 Double_t errVal = 0.0;
991 for (UInt_t i=0; i<fForward.size(); i++) {
992 if (fForward[i] > 0.0)
993 errVal = TMath::Sqrt(fForward[i]+errBkg[0]*errBkg[0]);
994 else
995 errVal = 1.0;
996 fForwardErr.push_back(errVal);
997 if (fBackward[i] > 0.0)
998 errVal = TMath::Sqrt(fBackward[i]+errBkg[1]*errBkg[1]);
999 else
1000 errVal = 1.0;
1001 fBackwardErr.push_back(errVal);
1002 }
1003
1004 // subtract background from data
1005 for (UInt_t i=0; i<fForward.size(); i++) {
1006 fForward[i] -= bkg[0];
1007 fBackward[i] -= bkg[1];
1008 }
1009
1010 fRunInfo->SetBkgEstimated(bkg[0], 0);
1011 fRunInfo->SetBkgEstimated(bkg[1], 1);
1012
1013 return true;
1014}
1015
1016//--------------------------------------------------------------------------
1017// PrepareFitData (protected)
1018//--------------------------------------------------------------------------
1041{
1042 // transform raw histo data. At this point, the raw data are already background corrected.
1043
1044 // 1st: form the asymmetry of the original data
1045
1046 // forward and backward detectors might have different fgb-t0 offset. Take the maximum of both.
1047 Int_t fgbOffset = fGoodBins[0]-static_cast<Int_t>(fT0s[0]);
1048 if (fgbOffset < fGoodBins[2]-static_cast<Int_t>(fT0s[1]))
1049 fgbOffset = fGoodBins[2]-static_cast<Int_t>(fT0s[1]);
1050 // last good bin (lgb) is the minimum of forward/backward lgb
1051 Int_t lgb_offset = fGoodBins[1]-static_cast<Int_t>(fT0s[0])+fgbOffset;
1052 if (lgb_offset < fGoodBins[3]-static_cast<Int_t>(fT0s[1])+fgbOffset)
1053 lgb_offset = fGoodBins[3]-static_cast<Int_t>(fT0s[1])+fgbOffset;
1054
1055 Int_t fgb = static_cast<Int_t>(fT0s[0])+fgbOffset;
1056 if (fgb < 0)
1057 fgb=0;
1058 Int_t lgb = fgb + lgb_offset;
1059 if (lgb > fForward.size())
1060 lgb = fForward.size();
1061 if (lgb > fBackward.size())
1062 lgb = fBackward.size();
1063 Int_t dt0 = static_cast<Int_t>(fT0s[0])-static_cast<Int_t>(fT0s[1]);
1064
1065 PDoubleVector asym;
1066 PDoubleVector asymErr;
1067 Double_t asymVal, asymValErr;
1068 Double_t ff, bb, eff, ebb;
1069 Int_t idx=0;
1070 for (Int_t i=fgb; i<lgb; i++) {
1071 ff = fForward[i];
1072 idx = i-dt0;
1073 if (idx < 0)
1074 idx = 0;
1075 if (idx >= fBackward.size())
1076 idx = fBackward.size()-1;
1077 bb = fBackward[idx];
1078 if (ff+bb != 0.0)
1079 asymVal = (ff-bb)/(ff+bb);
1080 else
1081 asymVal = 0.0;
1082 asym.push_back(asymVal);
1083 eff = fForwardErr[i];
1084 ebb = fBackwardErr[i-dt0];
1085 if ((asymVal != 0.0) && (ff+bb) > 0.0)
1086 asymValErr = 2.0/pow((ff+bb),2.0)*sqrt(bb*bb*eff*eff+ff*ff*ebb*ebb);
1087 else
1088 asymValErr = 1.0;
1089 asymErr.push_back(asymValErr);
1090 }
1091
1092 // 2nd: a_rrf = a * 2*cos(w_rrf*t + phi_rrf)
1093 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
1094 Double_t wRRF = globalBlock->GetRRFFreq("Mc");
1095 Double_t phaseRRF = globalBlock->GetRRFPhase()*TMath::TwoPi()/180.0;
1096
1097 Double_t startTime = fTimeResolution * static_cast<Double_t>(fgbOffset);
1098 Double_t time=0.0;
1099 for (UInt_t i=0; i<asym.size(); i++) {
1100 time = startTime + i*fTimeResolution;
1101 asym[i] *= 2.0*cos(wRRF*time+phaseRRF);
1102 }
1103
1104 // 3rd: rrf packing
1105 PDoubleVector asymRRF;
1106 asymVal = 0.0;
1107 for (UInt_t i=0; i<asym.size(); i++) {
1108 if ((i+1) % fRRFPacking == 0) {
1109 asymRRF.push_back(asymVal/fRRFPacking);
1110 asymVal = 0.0;
1111 }
1112 asymVal += asym[i];
1113 }
1114
1115 // 4th: rrf packing error
1116 PDoubleVector asymRRFErr;
1117 asymValErr = 0.0;
1118 for (UInt_t i=0; i<asymErr.size(); i++) {
1119 if ((i+1) % fRRFPacking == 0) {
1120 asymRRFErr.push_back(sqrt(2.0*asymValErr)/fRRFPacking); // factor of two is needed due to the rescaling
1121 asymValErr = 0.0;
1122 }
1123 asymValErr += asymErr[i]*asymErr[i];
1124 }
1125
1126 fData.SetDataTimeStart(startTime+fTimeResolution*(static_cast<Double_t>(fRRFPacking-1)/2.0));
1127 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(fRRFPacking));
1128
1129 for (UInt_t i=0; i<asymRRF.size(); i++) {
1130 fData.AppendValue(asymRRF[i]);
1131 fData.AppendErrorValue(asymRRFErr[i]);
1132 }
1133
1135
1136 // clean up
1137 fForward.clear();
1138 fForwardErr.clear();
1139 fBackward.clear();
1140 fBackwardErr.clear();
1141 asym.clear();
1142 asymErr.clear();
1143 asymRRF.clear();
1144 asymRRFErr.clear();
1145
1146 return true;
1147}
1148
1149//--------------------------------------------------------------------------
1150// PrepareViewData (protected)
1151//--------------------------------------------------------------------------
1177Bool_t PRunAsymmetryRRF::PrepareViewData(PRawRunData* runData, UInt_t histoNo[2])
1178{
1179 // feed the parameter vector
1180 std::vector<Double_t> par;
1181 PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
1182 for (UInt_t i=0; i<paramList->size(); i++)
1183 par.push_back((*paramList)[i].fValue);
1184
1185 // first get start data, end data, and t0
1186 Int_t start[2] = {fGoodBins[0], fGoodBins[2]};
1187 Int_t end[2] = {fGoodBins[1], fGoodBins[3]};
1188 Int_t t0[2] = {static_cast<Int_t>(fT0s[0]), static_cast<Int_t>(fT0s[1])};
1189
1190 // check if the data ranges and t0's between forward/backward are compatible
1191 Int_t fgb[2];
1192 if (start[0]-t0[0] != start[1]-t0[1]) { // wrong fgb aligning
1193 if (abs(start[0]-t0[0]) > abs(start[1]-t0[1])) {
1194 fgb[0] = start[0];
1195 fgb[1] = t0[1] + start[0]-t0[0];
1196 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **WARNING** needed to shift backward fgb from ";
1197 std::cerr << start[1] << " to " << fgb[1] << std::endl;
1198 } else {
1199 fgb[0] = t0[0] + start[1]-t0[1];
1200 fgb[1] = start[1];
1201 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **WARNING** needed to shift forward fgb from ";
1202 std::cerr << start[0] << " to " << fgb[0] << std::endl;
1203 }
1204 } else { // fgb aligning is correct
1205 fgb[0] = start[0];
1206 fgb[1] = start[1];
1207 }
1208 start[0] = fgb[0];
1209 start[1] = fgb[1];
1210
1211 // make sure that there are equal number of bins in forward and backward
1212 UInt_t noOfBins0 = runData->GetDataBin(histoNo[0])->size()-start[0];
1213 UInt_t noOfBins1 = runData->GetDataBin(histoNo[1])->size()-start[1];
1214 if (noOfBins0 > noOfBins1)
1215 noOfBins0 = noOfBins1;
1216 end[0] = start[0] + noOfBins0;
1217 end[1] = start[1] + noOfBins0;
1218
1219 // check if start, end, and t0 make any sense
1220 for (UInt_t i=0; i<2; i++) {
1221 // 1st check if start is within proper bounds
1222 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1223 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **ERROR** start data bin doesn't make any sense!";
1224 std::cerr << std::endl;
1225 return false;
1226 }
1227 // 2nd check if end is within proper bounds
1228 if ((end[i] < 0) || (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1229 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **ERROR** end data bin doesn't make any sense!";
1230 std::cerr << std::endl;
1231 return false;
1232 }
1233 // 3rd check if t0 is within proper bounds
1234 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1235 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareViewData(): **ERROR** t0 data bin doesn't make any sense!";
1236 std::cerr << std::endl;
1237 return false;
1238 }
1239 }
1240
1241 // check if forward and backward histo have the same size, otherwise take the minimum size
1242 UInt_t noOfBins = fForward.size();
1243 if (noOfBins > fBackward.size()) {
1244 noOfBins = fBackward.size();
1245 }
1246
1247 // form asymmetry including error propagation
1248 Double_t asym, error;
1249 Double_t f, b, ef, eb, alpha = 1.0, beta = 1.0;
1250
1251 // get the proper alpha and beta
1252 switch (fAlphaBetaTag) {
1253 case 1: // alpha == 1, beta == 1
1254 alpha = 1.0;
1255 beta = 1.0;
1256 break;
1257 case 2: // alpha != 1, beta == 1
1258 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1259 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1260 } else { // alpha is function
1261 // get function number
1262 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1263 // evaluate function
1264 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1265 }
1266 beta = 1.0;
1267 break;
1268 case 3: // alpha == 1, beta != 1
1269 alpha = 1.0;
1270 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1271 beta = par[fRunInfo->GetBetaParamNo()-1];
1272 } else { // beta is a function
1273 // get function number
1274 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1275 // evaluate function
1276 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1277 }
1278 break;
1279 case 4: // alpha != 1, beta != 1
1280 if (fRunInfo->GetAlphaParamNo() < MSR_PARAM_FUN_OFFSET) { // alpha is a parameter
1281 alpha = par[fRunInfo->GetAlphaParamNo()-1];
1282 } else { // alpha is function
1283 // get function number
1284 UInt_t funNo = fRunInfo->GetAlphaParamNo()-MSR_PARAM_FUN_OFFSET;
1285 // evaluate function
1286 alpha = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1287 }
1288 if (fRunInfo->GetBetaParamNo() < MSR_PARAM_FUN_OFFSET) { // beta is a parameter
1289 beta = par[fRunInfo->GetBetaParamNo()-1];
1290 } else { // beta is a function
1291 // get function number
1292 UInt_t funNo = fRunInfo->GetBetaParamNo()-MSR_PARAM_FUN_OFFSET;
1293 // evaluate function
1294 beta = fMsrInfo->EvalFunc(funNo, *fRunInfo->GetMap(), par, fMetaData);
1295 }
1296 break;
1297 default:
1298 break;
1299 }
1300
1301 PDoubleVector asymVec, asymErr;
1302 Int_t dtBin = start[1]-start[0];
1303 for (Int_t i=start[0]; i<end[0]; i++) {
1304 // to make the formulae more readable
1305 f = fForward[i];
1306 b = fBackward[i+dtBin];
1307 ef = fForwardErr[i];
1308 eb = fBackwardErr[i+dtBin];
1309 // check that there are indeed bins
1310 if (f+b != 0.0)
1311 asym = (alpha*f-b) / (alpha*beta*f+b);
1312 else
1313 asym = 0.0;
1314 asymVec.push_back(asym);
1315 // calculate the error
1316 if (f+b != 0.0)
1317 error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
1318 else
1319 error = 1.0;
1320 asymErr.push_back(error);
1321 }
1322
1323 // RRF transform
1324 // a_rrf = a * 2*cos(w_rrf*t + phi_rrf)
1325 PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
1326 Double_t wRRF = globalBlock->GetRRFFreq("Mc");
1327 Double_t phaseRRF = globalBlock->GetRRFPhase()*TMath::TwoPi()/180.0;
1328 Double_t startTime=fTimeResolution*(static_cast<Double_t>(start[0])-t0[0]);
1329 Double_t time = 0.0;
1330 for (UInt_t i=0; i<asymVec.size(); i++) {
1331 time = startTime + i * fTimeResolution;
1332 asymVec[i] *= 2.0*cos(wRRF*time+phaseRRF); // factor of 2 needed to keep the asymmetry
1333 }
1334
1335 Double_t dval = 0.0;
1336 PDoubleVector asymRRF;
1337 for (UInt_t i=0; i<asymVec.size(); i++) {
1338 if ((i+1) % fRRFPacking == 0) {
1339 asymRRF.push_back(dval/fRRFPacking);
1340 dval = 0.0;
1341 }
1342 dval += asymVec[i];
1343 }
1344
1345 // RRF packing error
1346 PDoubleVector asymRRFErr;
1347 dval = 0.0;
1348 for (UInt_t i=0; i<asymErr.size(); i++) {
1349 if ((i+1) % fRRFPacking == 0) {
1350 asymRRFErr.push_back(sqrt(2.0*dval)/fRRFPacking); // factor of two is needed due to the rescaling
1351 dval = 0.0;
1352 }
1353 dval += asymErr[i]*asymErr[i];
1354 }
1355
1356 fData.SetDataTimeStart(startTime+fTimeResolution*(static_cast<Double_t>(fRRFPacking-1)/2.0));
1357 fData.SetDataTimeStep(fTimeResolution*static_cast<Double_t>(fRRFPacking));
1358
1359 for (UInt_t i=0; i<asymRRF.size(); i++) {
1360 fData.AppendValue(asymRRF[i]);
1361 fData.AppendErrorValue(asymRRFErr[i]);
1362 }
1363
1365
1366 // clean up
1367 fForward.clear();
1368 fForwardErr.clear();
1369 fBackward.clear();
1370 fBackwardErr.clear();
1371 asymVec.clear();
1372 asymErr.clear();
1373 asymRRF.clear();
1374 asymRRFErr.clear();
1375
1376 // fill theory vector for kView
1377 // calculate functions
1378 for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
1379 fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), *fRunInfo->GetMap(), par, fMetaData);
1380 }
1381
1382 // calculate theory
1383 UInt_t size = runData->GetDataBin(histoNo[0])->size();
1384 Int_t factor = 8; // 8 times more points for the theory (if fTheoAsData == false)
1385 fData.SetTheoryTimeStart(fData.GetDataTimeStart());
1386 if (fTheoAsData) { // calculate theory only at the data points
1387 fData.SetTheoryTimeStep(fData.GetDataTimeStep());
1388 } else {
1389 // finer binning for the theory (8 times as many points = factor)
1390 size *= factor;
1391 fData.SetTheoryTimeStep(fData.GetDataTimeStep()/(Double_t)factor);
1392 }
1393
1394 for (UInt_t i=0; i<size; i++) {
1395 time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
1396 dval = fTheory->Func(time, par, fFuncValues);
1397 if (fabs(dval) > 10.0) { // dirty hack needs to be fixed!!
1398 dval = 0.0;
1399 }
1400 fData.AppendTheoryValue(dval);
1401 }
1402
1403 // clean up
1404 par.clear();
1405
1406 return true;
1407}
1408
1409//--------------------------------------------------------------------------
1410// GetProperT0 (private)
1411//--------------------------------------------------------------------------
1430Bool_t PRunAsymmetryRRF::GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHistoNo, PUIntVector &backwardHistoNo)
1431{
1432 // feed all T0's
1433 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1434 fT0s.clear();
1435 // this strange fT0 size estimate is needed in case #forw histos != #back histos
1436 size_t size = 2*forwardHistoNo.size();
1437 if (backwardHistoNo.size() > forwardHistoNo.size())
1438 size = 2*backwardHistoNo.size();
1439 fT0s.resize(size);
1440 for (UInt_t i=0; i<fT0s.size(); i++) {
1441 fT0s[i] = -1.0;
1442 }
1443
1444 // fill in the T0's from the msr-file (if present)
1445 for (UInt_t i=0; i<fRunInfo->GetT0BinSize(); i++) {
1446 fT0s[i] = fRunInfo->GetT0Bin(i);
1447 }
1448
1449 // fill in the missing T0's from the GLOBAL block section (if present)
1450 for (UInt_t i=0; i<globalBlock->GetT0BinSize(); i++) {
1451 if (fT0s[i] == -1.0) { // i.e. not given in the RUN block section
1452 fT0s[i] = globalBlock->GetT0Bin(i);
1453 }
1454 }
1455
1456 // fill in the missing T0's from the data file, if not already present in the msr-file
1457 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1458 if (fT0s[2*i] == -1.0) // i.e. not present in the msr-file, try the data file
1459 if (runData->GetT0Bin(forwardHistoNo[i]) > 0.0) {
1460 fT0s[2*i] = runData->GetT0Bin(forwardHistoNo[i]);
1461 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1462 }
1463 }
1464 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1465 if (fT0s[2*i+1] == -1.0) // i.e. not present in the msr-file, try the data file
1466 if (runData->GetT0Bin(backwardHistoNo[i]) > 0.0) {
1467 fT0s[2*i+1] = runData->GetT0Bin(backwardHistoNo[i]);
1468 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1469 }
1470 }
1471
1472 // 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
1473 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1474 if (fT0s[2*i] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1475 fT0s[2*i] = runData->GetT0BinEstimated(forwardHistoNo[i]);
1476 fRunInfo->SetT0Bin(fT0s[2*i], 2*i);
1477
1478 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1479 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1480 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << runData->GetT0BinEstimated(forwardHistoNo[i]);
1481 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1482 std::cerr << std::endl;
1483 }
1484 }
1485 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1486 if (fT0s[2*i+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1487 fT0s[2*i+1] = runData->GetT0BinEstimated(backwardHistoNo[i]);
1488 fRunInfo->SetT0Bin(fT0s[2*i+1], 2*i+1);
1489
1490 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1491 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
1492 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[i]);
1493 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1494 std::cerr << std::endl;
1495 }
1496 }
1497
1498 // check if t0 is within proper bounds
1499 for (UInt_t i=0; i<forwardHistoNo.size(); i++) {
1500 if ((fT0s[2*i] < 0) || (fT0s[2*i] > static_cast<Int_t>(runData->GetDataBin(forwardHistoNo[i])->size()))) {
1501 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **ERROR** t0 data bin (" << fT0s[2*i] << ") doesn't make any sense!";
1502 std::cerr << std::endl << ">> forwardHistoNo " << forwardHistoNo[i];
1503 std::cerr << std::endl;
1504 return false;
1505 }
1506 }
1507 for (UInt_t i=0; i<backwardHistoNo.size(); i++) {
1508 if ((fT0s[2*i+1] < 0) || (fT0s[2*i+1] > static_cast<Int_t>(runData->GetDataBin(backwardHistoNo[i])->size()))) {
1509 std::cerr << std::endl << ">> PRunAsymmetryRRF::PrepareData(): **ERROR** t0 data bin (" << fT0s[2*i+1] << ") doesn't make any sense!";
1510 std::cerr << std::endl << ">> backwardHistoNo " << backwardHistoNo[i];
1511 std::cerr << std::endl;
1512 return false;
1513 }
1514 }
1515
1516 // check if addrun's are present, and if yes add the necessary t0's
1517 if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
1518 PRawRunData *addRunData;
1519 fAddT0s.resize(fRunInfo->GetRunNameSize()-1); // resize to the number of addruns
1520 for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
1521 // get run to be added to the main one
1522 addRunData = fRawData->GetRunData(*(fRunInfo->GetRunName(i)));
1523 if (addRunData == nullptr) { // couldn't get run
1524 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
1525 std::cerr << std::endl;
1526 return false;
1527 }
1528
1529 // feed all T0's
1530 // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
1531 fAddT0s[i-1].clear();
1532 fAddT0s[i-1].resize(2*forwardHistoNo.size());
1533 for (UInt_t j=0; j<fAddT0s[i-1].size(); j++) {
1534 fAddT0s[i-1][j] = -1.0;
1535 }
1536
1537 // fill in the T0's from the msr-file (if present)
1538 for (Int_t j=0; j<fRunInfo->GetAddT0BinSize(i-1); j++) {
1539 fAddT0s[i-1][j] = fRunInfo->GetAddT0Bin(i-1, j);
1540 }
1541
1542 // fill in the T0's from the data file, if not already present in the msr-file
1543 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1544 if (fAddT0s[i-1][2*j] == -1.0) // i.e. not present in the msr-file, try the data file
1545 if (addRunData->GetT0Bin(forwardHistoNo[j]) > 0.0) {
1546 fAddT0s[i-1][2*j] = addRunData->GetT0Bin(forwardHistoNo[j]);
1547 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1548 }
1549 }
1550 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1551 if (fAddT0s[i-1][2*j+1] == -1.0) // i.e. not present in the msr-file, try the data file
1552 if (addRunData->GetT0Bin(backwardHistoNo[j]) > 0.0) {
1553 fAddT0s[i-1][2*j+1] = addRunData->GetT0Bin(backwardHistoNo[j]);
1554 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1555 }
1556 }
1557
1558 // 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
1559 for (UInt_t j=0; j<forwardHistoNo.size(); j++) {
1560 if (fAddT0s[i-1][2*j] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1561 fAddT0s[i-1][2*j] = addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1562 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j], i-1, 2*j);
1563
1564 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1565 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1566 std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << addRunData->GetT0BinEstimated(forwardHistoNo[j]);
1567 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1568 std::cerr << std::endl;
1569 }
1570 }
1571 for (UInt_t j=0; j<backwardHistoNo.size(); j++) {
1572 if (fAddT0s[i-1][2*j+1] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
1573 fAddT0s[i-1][2*j+1] = addRunData->GetT0BinEstimated(backwardHistoNo[j]);
1574 fRunInfo->SetAddT0Bin(fAddT0s[i-1][2*j+1], i-1, 2*j+1);
1575
1576 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
1577 std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
1578 std::cerr << std::endl << ">> will try the estimated one: backward t0 = " << runData->GetT0BinEstimated(backwardHistoNo[j]);
1579 std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
1580 std::cerr << std::endl;
1581 }
1582 }
1583 }
1584 }
1585
1586 return true;
1587}
1588
1589//--------------------------------------------------------------------------
1590// GetProperDataRange (private)
1591//--------------------------------------------------------------------------
1605Bool_t PRunAsymmetryRRF::GetProperDataRange(PRawRunData* runData, UInt_t histoNo[2])
1606{
1607 // first get start/end data
1608 Int_t start[2] = {fRunInfo->GetDataRange(0), fRunInfo->GetDataRange(2)};
1609 Int_t end[2] = {fRunInfo->GetDataRange(1), fRunInfo->GetDataRange(3)};
1610 // check if data range has been provided in the RUN block. If not, try the GLOBAL block
1611 if (start[0] == -1) {
1612 start[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(0);
1613 }
1614 if (start[1] == -1) {
1615 start[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(2);
1616 }
1617 if (end[0] == -1) {
1618 end[0] = fMsrInfo->GetMsrGlobal()->GetDataRange(1);
1619 }
1620 if (end[1] == -1) {
1621 end[1] = fMsrInfo->GetMsrGlobal()->GetDataRange(3);
1622 }
1623
1624 Double_t t0[2] = {fT0s[0], fT0s[1]};
1625 Int_t offset = static_cast<Int_t>(10.0e-3/fTimeResolution); // needed in case first good bin is not given, default = 10ns
1626
1627 // check if data range has been provided, and if not try to estimate them
1628 if (start[0] < 0) {
1629 start[0] = static_cast<Int_t>(t0[0])+offset;
1630 fRunInfo->SetDataRange(start[0], 0);
1631 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[0] << ".";
1632 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
1633 std::cerr << std::endl;
1634 }
1635 if (start[1] < 0) {
1636 start[1] = static_cast<Int_t>(t0[1])+offset;
1637 fRunInfo->SetDataRange(start[1], 2);
1638 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start[1] << ".";
1639 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
1640 std::cerr << std::endl;
1641 }
1642 if (end[0] < 0) {
1643 end[0] = runData->GetDataBin(histoNo[0])->size();
1644 fRunInfo->SetDataRange(end[0], 1);
1645 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** data range (forward) was not provided, will try data range end = " << end[0] << ".";
1646 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
1647 std::cerr << std::endl;
1648 }
1649 if (end[1] < 0) {
1650 end[1] = runData->GetDataBin(histoNo[1])->size();
1651 fRunInfo->SetDataRange(end[1], 3);
1652 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** data range (backward) was not provided, will try data range end = " << end[1] << ".";
1653 std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
1654 std::cerr << std::endl;
1655 }
1656
1657 // check if start, end, and t0 make any sense
1658 // 1st check if start and end are in proper order
1659 for (UInt_t i=0; i<2; i++) {
1660 if (end[i] < start[i]) { // need to swap them
1661 Int_t keep = end[i];
1662 end[i] = start[i];
1663 start[i] = keep;
1664 }
1665 // 2nd check if start is within proper bounds
1666 if ((start[i] < 0) || (start[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1667 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **ERROR** start data bin doesn't make any sense!";
1668 std::cerr << std::endl;
1669 return false;
1670 }
1671 // 3rd check if end is within proper bounds
1672 if (end[i] < 0) {
1673 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **ERROR** end data bin (" << end[i] << ") doesn't make any sense!";
1674 std::cerr << std::endl;
1675 return false;
1676 }
1677 if (end[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())) {
1678 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **WARNING** end data bin (" << end[i] << ") > histo length (" << (Int_t)runData->GetDataBin(histoNo[i])->size() << ").";
1679 std::cerr << std::endl << ">> Will set end = (histo length - 1). Consider to change it in the msr-file." << std::endl;
1680 std::cerr << std::endl;
1681 end[i] = static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size())-1;
1682 }
1683 // 4th check if t0 is within proper bounds
1684 if ((t0[i] < 0) || (t0[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
1685 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange(): **ERROR** t0 data bin doesn't make any sense!";
1686 std::cerr << std::endl;
1687 return false;
1688 }
1689 }
1690
1691 // check that start-t0 is the same for forward as for backward, otherwise take max(start[i]-t0[i])
1692 if (fabs(static_cast<Double_t>(start[0])-t0[0]) > fabs(static_cast<Double_t>(start[1])-t0[1])){
1693 start[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(start[0]) - t0[0]);
1694 end[1] = static_cast<Int_t>(t0[1] + static_cast<Double_t>(end[0]) - t0[0]);
1695 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange **WARNING** needed to shift backward data range.";
1696 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(2) << ", " << fRunInfo->GetDataRange(3);
1697 std::cerr << std::endl << ">> used : " << start[1] << ", " << end[1];
1698 std::cerr << std::endl;
1699 }
1700 if (fabs(static_cast<Double_t>(start[0])-t0[0]) < fabs(static_cast<Double_t>(start[1])-t0[1])){
1701 start[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(start[1]) - t0[1]);
1702 end[0] = static_cast<Int_t>(t0[0] + static_cast<Double_t>(end[1]) - t0[1]);
1703 std::cerr << std::endl << ">> PRunAsymmetryRRF::GetProperDataRange **WARNING** needed to shift forward data range.";
1704 std::cerr << std::endl << ">> given: " << fRunInfo->GetDataRange(0) << ", " << fRunInfo->GetDataRange(1);
1705 std::cerr << std::endl << ">> used : " << start[0] << ", " << end[0];
1706 std::cerr << std::endl;
1707 }
1708
1709 // keep good bins for potential latter use
1710 fGoodBins[0] = start[0];
1711 fGoodBins[1] = end[0];
1712 fGoodBins[2] = start[1];
1713 fGoodBins[3] = end[1];
1714
1715 // make sure that fGoodBins are in proper range for fForward and fBackward
1716 if (fGoodBins[0] < 0)
1717 fGoodBins[0]=0;
1718 if (fGoodBins[1] > fForward.size()) {
1719 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift forward lgb,";
1720 std::cerr << std::endl << ">> from " << fGoodBins[1] << " to " << fForward.size()-1 << std::endl;
1721 fGoodBins[1]=fForward.size()-1;
1722 }
1723 if (fGoodBins[2] < 0)
1724 fGoodBins[2]=0;
1725 if (fGoodBins[3] > fBackward.size()) {
1726 std::cerr << std::endl << ">> PRunAsymmetry::GetProperDataRange **WARNING** needed to shift backward lgb,";
1727 std::cerr << std::endl << ">> from " << fGoodBins[1] << " to " << fForward.size()-1 << std::endl;
1728 fGoodBins[3]=fBackward.size()-1;
1729 }
1730
1731 return true;
1732}
1733
1734//--------------------------------------------------------------------------
1735// GetProperFitRange (private)
1736//--------------------------------------------------------------------------
1750{
1751 // set fit start/end time; first check RUN Block
1752 fFitStartTime = fRunInfo->GetFitRange(0);
1753 fFitEndTime = fRunInfo->GetFitRange(1);
1754 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1755 if (fRunInfo->IsFitRangeInBin()) {
1756 fFitStartTime = (fGoodBins[0] + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1757 fFitEndTime = (fGoodBins[1] - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1758 // write these times back into the data structure. This way it is available when writting the log-file
1759 fRunInfo->SetFitRange(fFitStartTime, 0);
1760 fRunInfo->SetFitRange(fFitEndTime, 1);
1761 }
1762 if (fFitStartTime == PMUSR_UNDEFINED) { // fit start/end NOT found in the RUN block, check GLOBAL block
1763 fFitStartTime = globalBlock->GetFitRange(0);
1764 fFitEndTime = globalBlock->GetFitRange(1);
1765 // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1766 if (globalBlock->IsFitRangeInBin()) {
1767 fFitStartTime = (fGoodBins[0] + globalBlock->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1768 fFitEndTime = (fGoodBins[1] - globalBlock->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1769 // write these times back into the data structure. This way it is available when writting the log-file
1770 globalBlock->SetFitRange(fFitStartTime, 0);
1771 globalBlock->SetFitRange(fFitEndTime, 1);
1772 }
1773 }
1775 fFitStartTime = (fGoodBins[0] - fT0s[0]) * fTimeResolution; // (fgb-t0)*dt
1776 fFitEndTime = (fGoodBins[1] - fT0s[0]) * fTimeResolution; // (lgb-t0)*dt
1777 std::cerr << ">> PRunSingleHisto::GetProperFitRange(): **WARNING** Couldn't get fit start/end time!" << std::endl;
1778 std::cerr << ">> Will set it to fgb/lgb which given in time is: " << fFitStartTime << "..." << fFitEndTime << " (usec)" << std::endl;
1779 }
1780}
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.