musrfit  1.9.2
PRunSingleHistoRRF.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  PRunSingleHistoRRF.cpp
4 
5  Author: Andreas Suter
6  e-mail: andreas.suter@psi.ch
7 
8 ***************************************************************************/
9 
10 /***************************************************************************
11  * Copyright (C) 2007-2023 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 <cmath>
39 #include <iostream>
40 #include <fstream>
41 #include <memory>
42 
43 #include <TString.h>
44 #include <TObjArray.h>
45 #include <TObjString.h>
46 #include <TH1F.h>
47 
48 #include "PMusr.h"
49 #include "PFourier.h"
50 #include "PRunSingleHistoRRF.h"
51 
52 //--------------------------------------------------------------------------
53 // Constructor
54 //--------------------------------------------------------------------------
59 {
60  fNoOfFitBins = 0;
61  fBackground = 0.0;
62  fBkgErr = 1.0;
63  fRRFPacking = -1;
64  fTheoAsData = false;
65 
66  // the 2 following variables are need in case fit range is given in bins, and since
67  // the fit range can be changed in the command block, these variables need to be accessible
68  fGoodBins[0] = -1;
69  fGoodBins[1] = -1;
70 
71  fN0EstimateEndTime = 1.0; // end time in (us) over which N0 is estimated.
72 }
73 
74 //--------------------------------------------------------------------------
75 // Constructor
76 //--------------------------------------------------------------------------
85 PRunSingleHistoRRF::PRunSingleHistoRRF(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData) :
86  PRunBase(msrInfo, rawData, runNo, tag), fTheoAsData(theoAsData)
87 {
88  fNoOfFitBins = 0;
89 
90  PMsrGlobalBlock *global = msrInfo->GetMsrGlobal();
91 
92  if (!global->IsPresent()) {
93  std::cerr << std::endl << ">> PRunSingleHistoRRF::PRunSingleHistoRRF(): **SEVERE ERROR**: no GLOBAL-block present!";
94  std::cerr << std::endl << ">> For Single Histo RRF the GLOBAL-block is mandatory! Please fix this first.";
95  std::cerr << std::endl;
96  fValid = false;
97  return;
98  }
99 
100  if (!global->GetRRFUnit().CompareTo("??")) {
101  std::cerr << std::endl << ">> PRunSingleHistoRRF::PRunSingleHistoRRF(): **SEVERE ERROR**: no RRF-Frequency found!";
102  std::cerr << std::endl;
103  fValid = false;
104  return;
105  }
106 
107  fRRFPacking = global->GetRRFPacking();
108  if (fRRFPacking == -1) {
109  std::cerr << std::endl << ">> PRunSingleHistoRRF::PRunSingleHistoRRF(): **SEVERE ERROR**: no RRF-Packing found!";
110  std::cerr << std::endl;
111  fValid = false;
112  return;
113  }
114 
115  // the 2 following variables are need in case fit range is given in bins, and since
116  // the fit range can be changed in the command block, these variables need to be accessible
117  fGoodBins[0] = -1;
118  fGoodBins[1] = -1;
119 
120  fN0EstimateEndTime = 1.0; // end time in (us) over which N0 is estimated.
121 
122  if (!PrepareData()) {
123  std::cerr << std::endl << ">> PRunSingleHistoRRF::PRunSingleHistoRRF(): **SEVERE ERROR**: Couldn't prepare data for fitting!";
124  std::cerr << std::endl << ">> This is very bad :-(, will quit ...";
125  std::cerr << std::endl;
126  fValid = false;
127  }
128 }
129 
130 //--------------------------------------------------------------------------
131 // Destructor
132 //--------------------------------------------------------------------------
137 {
138  fForward.clear();
139 }
140 
141 //--------------------------------------------------------------------------
142 // CalcChiSquare (public)
143 //--------------------------------------------------------------------------
152 Double_t PRunSingleHistoRRF::CalcChiSquare(const std::vector<Double_t>& par)
153 {
154  Double_t chisq = 0.0;
155  Double_t diff = 0.0;
156 
157  // calculate functions
158  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
159  UInt_t funcNo = fMsrInfo->GetFuncNo(i);
160  fFuncValues[i] = fMsrInfo->EvalFunc(funcNo, *fRunInfo->GetMap(), par, fMetaData);
161  }
162 
163  // calculate chi square
164  Double_t time(1.0);
165  Int_t i;
166 
167  // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
168  // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
169  // for a given set of parameters---which should be done outside of the parallelized loop.
170  // For all other functions it means a tiny and acceptable overhead.
171  time = fTheory->Func(time, par, fFuncValues);
172 
173  #ifdef HAVE_GOMP
174  Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
175  if (chunk < 10)
176  chunk = 10;
177  #pragma omp parallel for default(shared) private(i,time,diff) schedule(dynamic,chunk) reduction(+:chisq)
178  #endif
179  for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
180  time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
181  diff = fData.GetValue()->at(i) - fTheory->Func(time, par, fFuncValues);
182  chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
183  }
184 
185  return chisq;
186 }
187 
188 //--------------------------------------------------------------------------
189 // CalcChiSquareExpected (public)
190 //--------------------------------------------------------------------------
199 Double_t PRunSingleHistoRRF::CalcChiSquareExpected(const std::vector<Double_t>& par)
200 {
201  Double_t chisq = 0.0;
202  Double_t diff = 0.0;
203  Double_t theo = 0.0;
204 
205  // calculate functions
206  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
207  UInt_t funcNo = fMsrInfo->GetFuncNo(i);
208  fFuncValues[i] = fMsrInfo->EvalFunc(funcNo, *fRunInfo->GetMap(), par, fMetaData);
209  }
210 
211  // calculate chi square
212  Double_t time(1.0);
213  Int_t i;
214 
215  // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
216  // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
217  // for a given set of parameters---which should be done outside of the parallelized loop.
218  // For all other functions it means a tiny and acceptable overhead.
219  time = fTheory->Func(time, par, fFuncValues);
220 
221  #ifdef HAVE_GOMP
222  Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
223  if (chunk < 10)
224  chunk = 10;
225  #pragma omp parallel for default(shared) private(i,time,diff) schedule(dynamic,chunk) reduction(+:chisq)
226  #endif
227  for (i=fStartTimeBin; i < fEndTimeBin; ++i) {
228  time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
229  theo = fTheory->Func(time, par, fFuncValues);
230  diff = fData.GetValue()->at(i) - theo;
231  chisq += diff*diff / theo;
232  }
233 
234  return chisq;
235 }
236 
237 //--------------------------------------------------------------------------
238 // CalcMaxLikelihood (public)
239 //--------------------------------------------------------------------------
248 Double_t PRunSingleHistoRRF::CalcMaxLikelihood(const std::vector<Double_t>& par)
249 {
250  // not yet implemented
251 
252  return 0.0;
253 }
254 
255 //--------------------------------------------------------------------------
256 // CalcTheory (public)
257 //--------------------------------------------------------------------------
262 {
263  // feed the parameter vector
264  std::vector<Double_t> par;
265  PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
266  for (UInt_t i=0; i<paramList->size(); i++)
267  par.push_back((*paramList)[i].fValue);
268 
269  // calculate functions
270  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
272  }
273 
274  // calculate theory
275  UInt_t size = fData.GetValue()->size();
276  Double_t start = fData.GetDataTimeStart();
277  Double_t resolution = fData.GetDataTimeStep();
278  Double_t time;
279  for (UInt_t i=0; i<size; i++) {
280  time = start + static_cast<Double_t>(i)*resolution;
281  fData.AppendTheoryValue(fTheory->Func(time, par, fFuncValues));
282  }
283 
284  // clean up
285  par.clear();
286 }
287 
288 //--------------------------------------------------------------------------
289 // GetNoOfFitBins (public)
290 //--------------------------------------------------------------------------
297 {
298  CalcNoOfFitBins();
299 
300  return fNoOfFitBins;
301 }
302 
303 //--------------------------------------------------------------------------
304 // SetFitRangeBin (public)
305 //--------------------------------------------------------------------------
317 void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange)
318 {
319  TObjArray *tok = nullptr;
320  TObjString *ostr = nullptr;
321  TString str;
322  Ssiz_t idx = -1;
323  Int_t offset = 0;
324 
325  tok = fitRange.Tokenize(" \t");
326 
327  if (tok->GetEntries() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1
328  // handle fgb+n0 entry
329  ostr = dynamic_cast<TObjString*>(tok->At(1));
330  str = ostr->GetString();
331  // check if there is an offset present
332  idx = str.First("+");
333  if (idx != -1) { // offset present
334  str.Remove(0, idx+1);
335  if (str.IsFloat()) // if str is a valid number, convert is to an integer
336  offset = str.Atoi();
337  }
338  fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
339 
340  // handle lgb-n1 entry
341  ostr = dynamic_cast<TObjString*>(tok->At(2));
342  str = ostr->GetString();
343  // check if there is an offset present
344  idx = str.First("-");
345  if (idx != -1) { // offset present
346  str.Remove(0, idx+1);
347  if (str.IsFloat()) // if str is a valid number, convert is to an integer
348  offset = str.Atoi();
349  }
350  fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
351  } else if ((tok->GetEntries() > 3) && (tok->GetEntries() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
352  Int_t pos = 2*(fRunNo+1)-1;
353 
354  if (pos + 1 >= tok->GetEntries()) {
355  std::cerr << std::endl << ">> PRunSingleHistoRRF::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
356  std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
357  } else {
358  // handle fgb+n0 entry
359  ostr = dynamic_cast<TObjString*>(tok->At(pos));
360  str = ostr->GetString();
361  // check if there is an offset present
362  idx = str.First("+");
363  if (idx != -1) { // offset present
364  str.Remove(0, idx+1);
365  if (str.IsFloat()) // if str is a valid number, convert is to an integer
366  offset = str.Atoi();
367  }
368  fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
369 
370  // handle lgb-n1 entry
371  ostr = dynamic_cast<TObjString*>(tok->At(pos+1));
372  str = ostr->GetString();
373  // check if there is an offset present
374  idx = str.First("-");
375  if (idx != -1) { // offset present
376  str.Remove(0, idx+1);
377  if (str.IsFloat()) // if str is a valid number, convert is to an integer
378  offset = str.Atoi();
379  }
380  fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
381  }
382  } else { // error
383  std::cerr << std::endl << ">> PRunSingleHistoRRF::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
384  std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
385  }
386 
387  // clean up
388  if (tok) {
389  delete tok;
390  }
391 }
392 
393 //--------------------------------------------------------------------------
394 // CalcNoOfFitBins (public)
395 //--------------------------------------------------------------------------
400 {
401  // In order not having to loop over all bins and to stay consistent with the chisq method, calculate the start and end bins explicitly
402  fStartTimeBin = static_cast<Int_t>(ceil((fFitStartTime - fData.GetDataTimeStart())/fData.GetDataTimeStep()));
403  if (fStartTimeBin < 0)
404  fStartTimeBin = 0;
405  fEndTimeBin = static_cast<Int_t>(floor((fFitEndTime - fData.GetDataTimeStart())/fData.GetDataTimeStep())) + 1;
406  if (fEndTimeBin > static_cast<Int_t>(fData.GetValue()->size()))
407  fEndTimeBin = fData.GetValue()->size();
408 
411  else
412  fNoOfFitBins = 0;
413 }
414 
415 //--------------------------------------------------------------------------
416 // PrepareData (protected)
417 //--------------------------------------------------------------------------
432 {
433  Bool_t success = true;
434 
435  if (!fValid)
436  return false;
437 
438  // keep the Global block info
439  PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
440 
441  // get the proper run
443  if (!runData) { // couldn't get run
444  std::cerr << std::endl << ">> PRunSingleHistoRRF::PrepareData(): **ERROR** Couldn't get run " << fRunInfo->GetRunName()->Data() << "!";
445  std::cerr << std::endl;
446  return false;
447  }
448 
449  // keep the field from the meta-data from the data-file
450  fMetaData.fField = runData->GetField();
451 
452  // keep the energy from the meta-data from the data-file
453  fMetaData.fEnergy = runData->GetEnergy();
454 
455  // keep the temperature(s) from the meta-data from the data-file
456  for (unsigned int i=0; i<runData->GetNoOfTemperatures(); i++)
457  fMetaData.fTemp.push_back(runData->GetTemperature(i));
458 
459  // collect histogram numbers
460  PUIntVector histoNo; // histoNo = msr-file forward + redGreen_offset - 1
461  for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
462  histoNo.push_back(fRunInfo->GetForwardHistoNo(i));
463 
464  if (!runData->IsPresent(histoNo[i])) {
465  std::cerr << std::endl << ">> PRunSingleHistoRRF::PrepareData(): **PANIC ERROR**:";
466  std::cerr << std::endl << ">> histoNo found = " << histoNo[i] << ", which is NOT present in the data file!?!?";
467  std::cerr << std::endl << ">> Will quit :-(";
468  std::cerr << std::endl;
469  histoNo.clear();
470  return false;
471  }
472  }
473 
474  // keep the time resolution in (us)
475  fTimeResolution = runData->GetTimeResolution()/1.0e3;
476  std::cout.precision(10);
477  std::cout << std::endl << ">> PRunSingleHisto::PrepareData(): time resolution=" << std::fixed << runData->GetTimeResolution() << "(ns)" << std::endl;
478 
479  // get all the proper t0's and addt0's for the current RUN block
480  if (!GetProperT0(runData, globalBlock, histoNo)) {
481  return false;
482  }
483 
484  // keep the histo of each group at this point (addruns handled below)
485  std::vector<PDoubleVector> forward;
486  forward.resize(histoNo.size()); // resize to number of groups
487  for (UInt_t i=0; i<histoNo.size(); i++) {
488  forward[i].resize(runData->GetDataBin(histoNo[i])->size());
489  forward[i] = *runData->GetDataBin(histoNo[i]);
490  }
491 
492  // check if there are runs to be added to the current one
493  if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
494  PRawRunData *addRunData;
495  for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
496 
497  // get run to be added to the main one
498  addRunData = fRawData->GetRunData(*fRunInfo->GetRunName(i));
499  if (addRunData == nullptr) { // couldn't get run
500  std::cerr << std::endl << ">> PRunSingleHistoRRF::PrepareData(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
501  std::cerr << std::endl;
502  return false;
503  }
504 
505  // add forward run
506  UInt_t addRunSize;
507  for (UInt_t k=0; k<histoNo.size(); k++) { // fill each group
508  addRunSize = addRunData->GetDataBin(histoNo[k])->size();
509  for (UInt_t j=0; j<addRunData->GetDataBin(histoNo[k])->size(); j++) { // loop over the bin indices
510  // make sure that the index stays in the proper range
511  if ((static_cast<Int_t>(j)+static_cast<Int_t>(fAddT0s[i-1][k])-static_cast<Int_t>(fT0s[k]) >= 0) &&
512  (j+static_cast<Int_t>(fAddT0s[i-1][k])-static_cast<Int_t>(fT0s[k]) < addRunSize)) {
513  forward[k][j] += addRunData->GetDataBin(histoNo[k])->at(j+static_cast<Int_t>(fAddT0s[i-1][k])-static_cast<Int_t>(fT0s[k]));
514  }
515  }
516  }
517  }
518  }
519 
520  // set forward histo data of the first group
521  fForward.resize(forward[0].size());
522  for (UInt_t i=0; i<fForward.size(); i++) {
523  fForward[i] = forward[0][i];
524  }
525 
526  // group histograms, add all the remaining forward histograms of the group
527  for (UInt_t i=1; i<histoNo.size(); i++) { // loop over the groupings
528  for (UInt_t j=0; j<runData->GetDataBin(histoNo[i])->size(); j++) { // loop over the bin indices
529  // make sure that the index stays within proper range
530  if ((static_cast<Int_t>(j)+static_cast<Int_t>(fT0s[i])-static_cast<Int_t>(fT0s[0]) >= 0) &&
531  (j+static_cast<Int_t>(fT0s[i])-static_cast<Int_t>(fT0s[0]) < runData->GetDataBin(histoNo[i])->size())) {
532  fForward[j] += forward[i][j+static_cast<Int_t>(fT0s[i])-static_cast<Int_t>(fT0s[0])];
533  }
534  }
535  }
536 
537  // get the data range (fgb/lgb) for the current RUN block
538  if (!GetProperDataRange()) {
539  return false;
540  }
541 
542  // get the fit range for the current RUN block
543  GetProperFitRange(globalBlock);
544 
545  // do the more fit/view specific stuff
546  if (fHandleTag == kFit)
547  success = PrepareFitData(runData, histoNo[0]);
548  else if (fHandleTag == kView)
549  success = PrepareViewData(runData, histoNo[0]);
550  else
551  success = false;
552 
553  // cleanup
554  histoNo.clear();
555 
556  return success;
557 }
558 
559 //--------------------------------------------------------------------------
560 // PrepareFitData (protected)
561 //--------------------------------------------------------------------------
579 Bool_t PRunSingleHistoRRF::PrepareFitData(PRawRunData* runData, const UInt_t histoNo)
580 {
581  // keep the raw data for the RRF asymmetry error estimate for later
582  PDoubleVector rawNt;
583  for (UInt_t i=0; i<fForward.size(); i++) {
584  rawNt.push_back(fForward[i]); // N(t) without any corrections
585  }
586  Double_t freqMax = GetMainFrequency(rawNt);
587  std::cout << "info> freqMax=" << freqMax << " (MHz)" << std::endl;
588 
589  // "optimal packing"
590  Double_t optNoPoints = 8;
591  if (freqMax < 271.0) // < 271 MHz, i.e ~ 2T
592  optNoPoints = 5;
593  std::cout << "info> optimal packing: " << static_cast<Int_t>(1.0 / (fTimeResolution*(freqMax - fMsrInfo->GetMsrGlobal()->GetRRFFreq("MHz"))) / optNoPoints);
594 
595  // initially fForward is the "raw data set" (i.e. grouped histo and raw runs already added) to be fitted. This means fForward = N(t) at this point.
596 
597  // 1) check how the background shall be handled
598  // subtract background from histogramms ------------------------------------------
599  if (fRunInfo->GetBkgFix(0) == PMUSR_UNDEFINED) { // no fixed background given
600  if (fRunInfo->GetBkgRange(0) >= 0) {
601  if (!EstimateBkg(histoNo))
602  return false;
603  } else { // no background given to do the job, try estimate
604  fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.1), 0);
605  fRunInfo->SetBkgRange(static_cast<Int_t>(fT0s[0]*0.6), 1);
606  std::cerr << std::endl << ">> PRunSingleHistoRRF::PrepareFitData(): **WARNING** Neither fix background nor background bins are given!";
607  std::cerr << std::endl << ">> Will try the following: bkg start = " << fRunInfo->GetBkgRange(0) << ", bkg end = " << fRunInfo->GetBkgRange(1);
608  std::cerr << std::endl << ">> NO WARRANTY THAT THIS MAKES ANY SENSE! Better check ...";
609  std::cerr << std::endl;
610  if (!EstimateBkg(histoNo))
611  return false;
612  }
613  // subtract background from fForward
614  for (UInt_t i=0; i<fForward.size(); i++)
615  fForward[i] -= fBackground;
616  } else { // fixed background given
617  for (UInt_t i=0; i<fForward.size(); i++) {
618  fForward[i] -= fRunInfo->GetBkgFix(0);
619  }
621  }
622  // here fForward = N(t) - Nbkg
623 
624  Int_t t0 = static_cast<Int_t>(fT0s[0]);
625 
626  // 2) N(t) - Nbkg -> exp(+t/tau) [N(t)-Nbkg]
627  Double_t startTime = fTimeResolution * (static_cast<Double_t>(fGoodBins[0]) - static_cast<Double_t>(t0));
628 
629  Double_t time_tau=0.0;
630  Double_t exp_t_tau=0.0;
631  for (Int_t i=fGoodBins[0]; i<fGoodBins[1]; i++) {
632  time_tau = (startTime + fTimeResolution * (i - fGoodBins[0])) / PMUON_LIFETIME;
633  exp_t_tau = exp(time_tau);
634  fForward[i] *= exp_t_tau;
635  fM.push_back(fForward[i]); // i.e. M(t) = [N(t)-Nbkg] exp(+t/tau); needed to estimate N0 later on
636  fMerr.push_back(exp_t_tau*sqrt(rawNt[i]+fBkgErr*fBkgErr));
637  }
638 
639  // calculate weights
640  for (UInt_t i=0; i<fMerr.size(); i++) {
641  if (fMerr[i] > 0.0)
642  fW.push_back(1.0/(fMerr[i]*fMerr[i]));
643  else
644  fW.push_back(1.0);
645  }
646  // now fForward = exp(+t/tau) [N(t)-Nbkg] = M(t)
647 
648  // 3) estimate N0
649  Double_t errN0 = 0.0;
650  Double_t n0 = EstimateN0(errN0, freqMax);
651 
652  // 4a) A(t) = exp(+t/tau) [N(t)-Nbkg] / N0 - 1.0
653  for (Int_t i=fGoodBins[0]; i<=fGoodBins[1]; i++) {
654  fForward[i] = fForward[i] / n0 - 1.0;
655  }
656 
657  // 4b) error estimate of A(t): errA(t) = exp(+t/tau)/N0 sqrt( N(t) + ([N(t)-N_bkg]/N0)^2 errN0^2 )
658  for (Int_t i=fGoodBins[0]; i<=fGoodBins[1]; i++) {
659  time_tau = (startTime + fTimeResolution * (i - fGoodBins[0])) / PMUON_LIFETIME;
660  exp_t_tau = exp(time_tau);
661  fAerr.push_back(exp_t_tau/n0*sqrt(rawNt[i]+pow(((rawNt[i]-fBackground)/n0)*errN0,2.0)));
662  }
663 
664  // 5) rotate A(t): A(t) -> 2* A(t) * cos(wRRF t + phiRRF), the factor 2.0 is needed since the high frequency part is suppressed.
665  PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
666  Double_t wRRF = globalBlock->GetRRFFreq("Mc");
667  Double_t phaseRRF = globalBlock->GetRRFPhase()*TMath::TwoPi()/180.0;
668  Double_t time = 0.0;
669  for (Int_t i=fGoodBins[0]; i<=fGoodBins[1]; i++) {
670  time = startTime + fTimeResolution * (static_cast<Double_t>(i) - static_cast<Double_t>(fGoodBins[0]));
671  fForward[i] *= 2.0*cos(wRRF * time + phaseRRF);
672  }
673 
674  // 6) RRF packing
675  Double_t dval=0.0;
676  for (Int_t i=fGoodBins[0]; i<=fGoodBins[1]; i++) {
677  if (fRRFPacking == 1) {
679  } else { // RRF packing > 1
680  if (((i-fGoodBins[0]) % fRRFPacking == 0) && (i != fGoodBins[0])) { // fill data
681  dval /= fRRFPacking;
682  fData.AppendValue(dval);
683  // reset dval
684  dval = 0.0;
685  }
686  dval += fForward[i];
687  }
688  }
689 
690  // 7) estimate packed RRF errors (see log-book p.204)
691  // the error estimate of the unpacked RRF asymmetry is: errA_RRF(t) \simeq exp(t/tau)/N0 sqrt( [N(t) + ((N(t)-N_bkg)/N0)^2 errN0^2] )
692  dval = 0.0;
693  // the packed RRF asymmetry error
694  for (Int_t i=fGoodBins[0]; i<=fGoodBins[1]; i++) {
695  if (((i-fGoodBins[0]) % fRRFPacking == 0) && (i != fGoodBins[0])) { // fill data
696  fData.AppendErrorValue(sqrt(2.0*dval)/fRRFPacking); // the factor 2.0 is needed since the high frequency part is suppressed.
697  dval = 0.0;
698  }
699  dval += fAerr[i-fGoodBins[0]]*fAerr[i-fGoodBins[0]];
700  }
701 
702  // set start time and time step
703  fData.SetDataTimeStart(fTimeResolution*(static_cast<Double_t>(fGoodBins[0])-static_cast<Double_t>(t0)+static_cast<Double_t>(fRRFPacking-1)/2.0));
705 
706  CalcNoOfFitBins();
707 
708  return true;
709 }
710 
711 //--------------------------------------------------------------------------
712 // PrepareViewData (protected)
713 //--------------------------------------------------------------------------
730 Bool_t PRunSingleHistoRRF::PrepareViewData(PRawRunData* runData, const UInt_t histoNo)
731 {
732  // --------------
733  // prepare data
734  // --------------
735 
736  // prepare RRF single histo
737  PrepareFitData(runData, histoNo);
738 
739  // check for view packing
740  Int_t viewPacking = fMsrInfo->GetMsrPlotList()->at(0).fViewPacking;
741  if (viewPacking > 0) {
742  if (viewPacking < fRRFPacking) {
743  std::cerr << ">> PRunSingleHistoRRF::PrepareViewData(): **WARNING** Found View Packing (" << viewPacking << ") < RRF Packing (" << fRRFPacking << ").";
744  std::cerr << ">> Will ignore View Packing." << std::endl;
745  } else {
746  // STILL MISSING
747  }
748  }
749 
750  // --------------
751  // prepare theory
752  // --------------
753 
754  // feed the parameter vector
755  std::vector<Double_t> par;
756  PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
757  for (UInt_t i=0; i<paramList->size(); i++)
758  par.push_back((*paramList)[i].fValue);
759 
760  // calculate functions
761  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
763  }
764 
765  // check if a finer binning for the theory is needed
766  UInt_t size = fForward.size();
767  Int_t factor = 8; // 8 times more points for the theory (if fTheoAsData == false)
769  if (fTheoAsData) { // calculate theory only at the data points
771  } else {
772  // finer binning for the theory (8 times as many points = factor)
773  size *= factor;
774  fData.SetTheoryTimeStep(fData.GetDataTimeStep()/(Double_t)factor);
775  }
776 
777  // calculate theory
778  Double_t time = 0.0;
779  Double_t theoryValue = 0.0;
780  for (UInt_t i=0; i<size; i++) {
781  time = fData.GetTheoryTimeStart() + static_cast<Double_t>(i)*fData.GetTheoryTimeStep();
782  theoryValue = fTheory->Func(time, par, fFuncValues);
783  if (fabs(theoryValue) > 10.0) { // dirty hack needs to be fixed!!
784  theoryValue = 0.0;
785  }
786  fData.AppendTheoryValue(theoryValue);
787  }
788 
789  return true;
790 }
791 
792 //--------------------------------------------------------------------------
793 // GetProperT0 (private)
794 //--------------------------------------------------------------------------
813 {
814  // feed all T0's
815  // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
816  fT0s.clear();
817  fT0s.resize(histoNo.size());
818  for (UInt_t i=0; i<fT0s.size(); i++) {
819  fT0s[i] = -1.0;
820  }
821 
822  // fill in the T0's from the msr-file (if present)
823  for (UInt_t i=0; i<fRunInfo->GetT0BinSize(); i++) {
824  fT0s[i] = fRunInfo->GetT0Bin(i);
825  }
826 
827  // fill in the T0's from the GLOBAL block section (if present)
828  for (UInt_t i=0; i<globalBlock->GetT0BinSize(); i++) {
829  if (fT0s[i] == -1.0) { // i.e. not given in the RUN block section
830  fT0s[i] = globalBlock->GetT0Bin(i);
831  }
832  }
833 
834  // fill in the T0's from the data file, if not already present in the msr-file
835  for (UInt_t i=0; i<histoNo.size(); i++) {
836  if (fT0s[i] == -1.0) { // i.e. not present in the msr-file, try the data file
837  if (runData->GetT0Bin(histoNo[i]) > 0.0) {
838  fT0s[i] = runData->GetT0Bin(histoNo[i]);
839  fRunInfo->SetT0Bin(fT0s[i], i); // keep value for the msr-file
840  }
841  }
842  }
843 
844  // 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
845  for (UInt_t i=0; i<histoNo.size(); i++) {
846  if (fT0s[i] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
847  fT0s[i] = runData->GetT0BinEstimated(histoNo[i]);
848  fRunInfo->SetT0Bin(fT0s[i], i); // keep value for the msr-file
849 
850  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
851  std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
852  std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << runData->GetT0BinEstimated(histoNo[i]);
853  std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
854  std::cerr << std::endl;
855  }
856  }
857 
858  // check if t0 is within proper bounds
859  for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
860  if ((fT0s[i] < 0.0) || (fT0s[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
861  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperT0(): **ERROR** t0 data bin (" << fT0s[i] << ") doesn't make any sense!";
862  std::cerr << std::endl;
863  return false;
864  }
865  }
866 
867  // check if there are runs to be added to the current one. If yes keep the needed t0's
868  if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
869  PRawRunData *addRunData;
870  fAddT0s.resize(fRunInfo->GetRunNameSize()-1); // resize to the number of addruns
871  for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
872 
873  // get run to be added to the main one
874  addRunData = fRawData->GetRunData(*fRunInfo->GetRunName(i));
875  if (addRunData == nullptr) { // couldn't get run
876  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperT0(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
877  std::cerr << std::endl;
878  return false;
879  }
880 
881  // feed all T0's
882  // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
883  fAddT0s[i-1].resize(histoNo.size());
884  for (UInt_t j=0; j<fAddT0s[i-1].size(); j++) {
885  fAddT0s[i-1][j] = -1.0;
886  }
887 
888  // fill in the T0's from the msr-file (if present)
889  for (UInt_t j=0; j<fRunInfo->GetT0BinSize(); j++) {
890  fAddT0s[i-1][j] = fRunInfo->GetAddT0Bin(i-1,j); // addRunIdx starts at 0
891  }
892 
893  // fill in the T0's from the data file, if not already present in the msr-file
894  for (UInt_t j=0; j<histoNo.size(); j++) {
895  if (fAddT0s[i-1][j] == -1.0) // i.e. not present in the msr-file, try the data file
896  if (addRunData->GetT0Bin(histoNo[j]) > 0.0) {
897  fAddT0s[i-1][j] = addRunData->GetT0Bin(histoNo[j]);
898  fRunInfo->SetAddT0Bin(fAddT0s[i-1][j], i-1, j); // keep value for the msr-file
899  }
900  }
901 
902  // 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
903  for (UInt_t j=0; j<histoNo.size(); j++) {
904  if (fAddT0s[i-1][j] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
905  fAddT0s[i-1][j] = addRunData->GetT0BinEstimated(histoNo[j]);
906  fRunInfo->SetAddT0Bin(fAddT0s[i-1][j], i-1, j); // keep value for the msr-file
907 
908  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
909  std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
910  std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << addRunData->GetT0BinEstimated(histoNo[j]);
911  std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
912  std::cerr << std::endl;
913  }
914  }
915 
916  // check if t0 is within proper bounds
917  for (UInt_t j=0; j<fRunInfo->GetForwardHistoNoSize(); j++) {
918  if ((fAddT0s[i-1][j] < 0) || (fAddT0s[i-1][j] > static_cast<Int_t>(addRunData->GetDataBin(histoNo[j])->size()))) {
919  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperT0(): **ERROR** addt0 data bin (" << fAddT0s[i-1][j] << ") doesn't make any sense!";
920  std::cerr << std::endl;
921  return false;
922  }
923  }
924  }
925  }
926 
927  return true;
928 }
929 
930 //--------------------------------------------------------------------------
931 // GetProperDataRange (private)
932 //--------------------------------------------------------------------------
944 {
945  // get start/end data
946  Int_t start;
947  Int_t end;
948  start = fRunInfo->GetDataRange(0);
949  end = fRunInfo->GetDataRange(1);
950 
951  // check if data range has been given in the RUN block, if not try to get it from the GLOBAL block
952  if (start < 0) {
953  start = fMsrInfo->GetMsrGlobal()->GetDataRange(0);
954  }
955  if (end < 0) {
956  end = fMsrInfo->GetMsrGlobal()->GetDataRange(1);
957  }
958 
959  // check if data range has been provided, and if not try to estimate them
960  if (start < 0) {
961  Int_t offset = static_cast<Int_t>(10.0e-3/fTimeResolution);
962  start = static_cast<Int_t>(fT0s[0])+offset;
963  fRunInfo->SetDataRange(start, 0);
964  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperDataRange(): **WARNING** data range was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start << ".";
965  std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
966  std::cerr << std::endl;
967  }
968  if (end < 0) {
969  end = fForward.size();
970  fRunInfo->SetDataRange(end, 1);
971  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperDataRange(): **WARNING** data range was not provided, will try data range end = " << end << ".";
972  std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
973  std::cerr << std::endl;
974  }
975 
976  // check if start and end make any sense
977  // 1st check if start and end are in proper order
978  if (end < start) { // need to swap them
979  Int_t keep = end;
980  end = start;
981  start = keep;
982  }
983  // 2nd check if start is within proper bounds
984  if ((start < 0) || (start > static_cast<Int_t>(fForward.size()))) {
985  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperDataRange(): **ERROR** start data bin (" << start << ") doesn't make any sense!";
986  std::cerr << std::endl;
987  return false;
988  }
989  // 3rd check if end is within proper bounds
990  if (end < 0) {
991  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperDataRange(): **ERROR** end data bin (" << end << ") doesn't make any sense!";
992  std::cerr << std::endl;
993  return false;
994  }
995  if (end > static_cast<Int_t>(fForward.size())) {
996  std::cerr << std::endl << ">> PRunSingleHistoRRF::GetProperDataRange(): **WARNING** end data bin (" << end << ") > histo length (" << fForward.size() << ").";
997  std::cerr << std::endl << ">> Will set end = (histo length - 1). Consider to change it in the msr-file." << std::endl;
998  std::cerr << std::endl;
999  end = static_cast<Int_t>(fForward.size()-1);
1000  }
1001 
1002  // keep good bins for potential later use
1003  fGoodBins[0] = start;
1004  fGoodBins[1] = end;
1005 
1006  return true;
1007 }
1008 
1009 //--------------------------------------------------------------------------
1010 // GetProperFitRange (private)
1011 //--------------------------------------------------------------------------
1025 {
1026  // set fit start/end time; first check RUN Block
1029  // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1030  if (fRunInfo->IsFitRangeInBin()) {
1031  fFitStartTime = (fGoodBins[0] + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1032  fFitEndTime = (fGoodBins[1] - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1033  // write these times back into the data structure. This way it is available when writting the log-file
1036  }
1037  if (fFitStartTime == PMUSR_UNDEFINED) { // fit start/end NOT found in the RUN block, check GLOBAL block
1038  fFitStartTime = globalBlock->GetFitRange(0);
1039  fFitEndTime = globalBlock->GetFitRange(1);
1040  // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1041  if (globalBlock->IsFitRangeInBin()) {
1042  fFitStartTime = (fGoodBins[0] + globalBlock->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1043  fFitEndTime = (fGoodBins[1] - globalBlock->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1044  // write these times back into the data structure. This way it is available when writting the log-file
1045  globalBlock->SetFitRange(fFitStartTime, 0);
1046  globalBlock->SetFitRange(fFitEndTime, 1);
1047  }
1048  }
1050  fFitStartTime = (fGoodBins[0] - fT0s[0]) * fTimeResolution; // (fgb-t0)*dt
1051  fFitEndTime = (fGoodBins[1] - fT0s[0]) * fTimeResolution; // (lgb-t0)*dt
1052  std::cerr << ">> PRunSingleHistoRRF::GetProperFitRange(): **WARNING** Couldn't get fit start/end time!" << std::endl;
1053  std::cerr << ">> Will set it to fgb/lgb which given in time is: " << fFitStartTime << "..." << fFitEndTime << " (usec)" << std::endl;
1054  }
1055 }
1056 
1057 //--------------------------------------------------------------------------
1058 // GetMainFrequency (private)
1059 //--------------------------------------------------------------------------
1066 {
1067  Double_t freqMax = 0.0;
1068 
1069  // create histo
1070  Double_t startTime = (fGoodBins[0]-fT0s[0]) * fTimeResolution;
1071  Int_t noOfBins = fGoodBins[1]-fGoodBins[0]+1;
1072  std::unique_ptr<TH1F> histo = std::make_unique<TH1F>("data", "data", noOfBins, startTime-fTimeResolution/2.0, startTime+fTimeResolution/2.0+noOfBins*fTimeResolution);
1073  for (Int_t i=fGoodBins[0]; i<=fGoodBins[1]; i++) {
1074  histo->SetBinContent(i-fGoodBins[0]+1, data[i]);
1075  }
1076 
1077  // Fourier transform
1078  std::unique_ptr<PFourier> ft = std::make_unique<PFourier>(histo.get(), FOURIER_UNIT_FREQ);
1079  ft->Transform(F_APODIZATION_STRONG);
1080 
1081  // find frequency maximum
1082  TH1F *power = ft->GetPowerFourier();
1083  Double_t maxFreqVal = 0.0;
1084  for (Int_t i=1; i<power->GetNbinsX(); i++) {
1085  // ignore dc part at 0 frequency
1086  if (i<power->GetNbinsX()-1) {
1087  if (power->GetBinContent(i)>power->GetBinContent(i+1))
1088  continue;
1089  }
1090  // ignore everything below 10 MHz
1091  if (power->GetBinCenter(i) < 10.0)
1092  continue;
1093  // check for maximum
1094  if (power->GetBinContent(i) > maxFreqVal) {
1095  maxFreqVal = power->GetBinContent(i);
1096  freqMax = power->GetBinCenter(i);
1097  }
1098  }
1099 
1100  // clean up
1101  if (power)
1102  delete power;
1103 
1104  return freqMax;
1105 }
1106 
1107 //--------------------------------------------------------------------------
1108 // EstimateN0 (private)
1109 //--------------------------------------------------------------------------
1115 Double_t PRunSingleHistoRRF::EstimateN0(Double_t &errN0, Double_t freqMax)
1116 {
1117  // endBin is estimated such that the number of full cycles (according to the maximum frequency of the data)
1118  // is approximately the time fN0EstimateEndTime.
1119  Int_t endBin = static_cast<Int_t>(round(ceil(fN0EstimateEndTime*freqMax/TMath::TwoPi()) * (TMath::TwoPi()/freqMax) / fTimeResolution));
1120 
1121  Double_t n0 = 0.0;
1122  Double_t wN = 0.0;
1123  for (Int_t i=0; i<endBin; i++) {
1124 // n0 += fW[i]*fM[i];
1125  n0 += fM[i];
1126  wN += fW[i];
1127  }
1128 // n0 /= wN;
1129  n0 /= endBin;
1130 
1131  errN0 = 0.0;
1132  for (Int_t i=0; i<endBin; i++) {
1133  errN0 += fW[i]*fW[i]*fMerr[i]*fMerr[i];
1134  }
1135  errN0 = sqrt(errN0)/wN;
1136 
1137  std::cout << "info> PRunSingleHistoRRF::EstimateN0(): N0=" << n0 << "(" << errN0 << ")" << std::endl;
1138 
1139  return n0;
1140 }
1141 
1142 //--------------------------------------------------------------------------
1143 // EstimatBkg (private)
1144 //--------------------------------------------------------------------------
1154 Bool_t PRunSingleHistoRRF::EstimateBkg(UInt_t histoNo)
1155 {
1156  Double_t beamPeriod = 0.0;
1157 
1158  // check if data are from PSI, RAL, or TRIUMF
1159  if (fRunInfo->GetInstitute()->Contains("psi"))
1160  beamPeriod = ACCEL_PERIOD_PSI;
1161  else if (fRunInfo->GetInstitute()->Contains("ral"))
1162  beamPeriod = ACCEL_PERIOD_RAL;
1163  else if (fRunInfo->GetInstitute()->Contains("triumf"))
1164  beamPeriod = ACCEL_PERIOD_TRIUMF;
1165  else
1166  beamPeriod = 0.0;
1167 
1168  // check if start and end are in proper order
1169  UInt_t start = fRunInfo->GetBkgRange(0);
1170  UInt_t end = fRunInfo->GetBkgRange(1);
1171  if (end < start) {
1172  std::cout << std::endl << "PRunSingleHistoRRF::EstimatBkg(): end = " << end << " > start = " << start << "! Will swap them!";
1173  UInt_t keep = end;
1174  end = start;
1175  start = keep;
1176  }
1177 
1178  // calculate proper background range
1179  if (beamPeriod != 0.0) {
1180  Double_t timeBkg = static_cast<Double_t>(end-start)*fTimeResolution; // length of the background intervall in time
1181  UInt_t fullCycles = static_cast<UInt_t>(timeBkg/beamPeriod); // how many proton beam cylces can be placed within the proposed background intervall
1182  // correct the end of the background intervall such that the background is as close as possible to a multiple of the proton cylce
1183  end = start + static_cast<UInt_t>((fullCycles*beamPeriod)/fTimeResolution);
1184  std::cout << std::endl << "PRunSingleHistoRRF::EstimatBkg(): Background " << start << ", " << end;
1185  if (end == start)
1186  end = fRunInfo->GetBkgRange(1);
1187  }
1188 
1189  // check if start is within histogram bounds
1190  if (start >= fForward.size()) {
1191  std::cerr << std::endl << ">> PRunSingleHistoRRF::EstimatBkg(): **ERROR** background bin values out of bound!";
1192  std::cerr << std::endl << ">> histo lengths = " << fForward.size();
1193  std::cerr << std::endl << ">> background start = " << start;
1194  std::cerr << std::endl;
1195  return false;
1196  }
1197 
1198  // check if end is within histogram bounds
1199  if (end >= fForward.size()) {
1200  std::cerr << std::endl << ">> PRunSingleHistoRRF::EstimatBkg(): **ERROR** background bin values out of bound!";
1201  std::cerr << std::endl << ">> histo lengths = " << fForward.size();
1202  std::cerr << std::endl << ">> background end = " << end;
1203  std::cerr << std::endl;
1204  return false;
1205  }
1206 
1207  // calculate background
1208  Double_t bkg = 0.0;
1209 
1210  // forward
1211  for (UInt_t i=start; i<end; i++)
1212  bkg += fForward[i];
1213  bkg /= static_cast<Double_t>(end - start + 1);
1214 
1215  fBackground = bkg; // keep background (per bin)
1216 
1217  bkg = 0.0;
1218  for (UInt_t i=start; i<end; i++)
1219  bkg += pow(fForward[i]-fBackground, 2.0);
1220  fBkgErr = sqrt(bkg/(static_cast<Double_t>(end - start)));
1221 
1222  std::cout << std::endl << "info> fBackground=" << fBackground << "(" << fBkgErr << ")" << std::endl;
1223 
1225 
1226  return true;
1227 }
Int_t fGoodBins[2]
keep first/last good bins. 0=fgb, 1=lgb
virtual UInt_t GetT0BinSize()
Definition: PMusr.h:583
Bool_t fValid
flag showing if the state of the class is valid
Definition: PRunBase.h:66
virtual TString GetRRFUnit()
Definition: PMusr.cpp:834
virtual void GetProperFitRange(PMsrGlobalBlock *globalBlock)
virtual void SetDataRange(Int_t ival, Int_t idx)
Definition: PMusr.cpp:1672
virtual Double_t CalcMaxLikelihood(const std::vector< Double_t > &par)
virtual Double_t EstimateN0(Double_t &errN0, Double_t freqMax)
virtual const PDoubleVector * GetError()
Definition: PMusr.h:249
PDoubleVector fMerr
vector holding the error of M(t): M_err = exp(+t/tau) sqrt(N(t)).
Definition: PMusr.h:220
Double_t fN0EstimateEndTime
end time in (us) over which N0 is estimated.
virtual Double_t CalcChiSquare(const std::vector< Double_t > &par)
virtual Int_t GetNoOfFuncs()
Definition: PMsrHandler.h:93
virtual Int_t GetDataRange(UInt_t idx)
Definition: PMusr.cpp:895
virtual Double_t GetT0Bin(UInt_t idx=0)
Definition: PMusr.cpp:935
Double_t fBkgErr
estimate error on the estimated background
#define PMUON_LIFETIME
Definition: PMusr.h:68
virtual const Double_t GetTimeResolution()
Definition: PMusr.h:429
virtual UInt_t GetNoOfFitBins()
PRunDataHandler * fRawData
holds the raw run data
Definition: PRunBase.h:73
std::vector< PDoubleVector > fAddT0s
all t0 bins of all addrun&#39;s of a run! The derived classes will handle it.
Definition: PRunBase.h:79
virtual void SetBkgEstimated(Double_t dval, Int_t idx)
Definition: PMusr.cpp:1549
virtual Int_t GetFitRangeOffset(UInt_t idx)
Definition: PMusr.cpp:1088
virtual Bool_t GetProperDataRange()
virtual Bool_t GetProperT0(PRawRunData *runData, PMsrGlobalBlock *globalBlock, PUIntVector &histoNo)
virtual void SetTheoryTimeStart(Double_t dval)
Definition: PMusr.h:255
PMsrHandler * fMsrInfo
msr-file handler
Definition: PRunBase.h:71
virtual Bool_t IsFitRangeInBin()
Definition: PMusr.h:665
virtual const PDoublePairVector * GetTemperature() const
Definition: PMusr.h:422
Double_t fTimeResolution
time resolution in (us)
Definition: PRunBase.h:76
PMetaData fMetaData
keeps the meta data from the data file like field, temperature, energy, ...
Definition: PRunBase.h:77
#define F_APODIZATION_STRONG
Definition: PFourier.h:46
Int_t fEndTimeBin
bin at which the fit ends
virtual PRawRunData * GetRunData(const TString &runName)
PDoubleVector fM
vector holding M(t) = [N(t)-N_bkg] exp(+t/tau). Needed to estimate N0.
virtual Double_t GetAddT0Bin(UInt_t addRunIdx, UInt_t histoIdx)
Definition: PMusr.cpp:1761
virtual Int_t GetRRFPacking()
Definition: PMusr.h:580
virtual UInt_t GetT0BinSize()
Definition: PMusr.h:660
PDoubleVector fAerr
vector holding the errors of estimated A(t)
PDoubleVector fTemp
temperature(s) in (K)
Definition: PMusr.h:229
PDoubleVector fForward
forward histo data
virtual Double_t GetMainFrequency(PDoubleVector &data)
virtual Bool_t EstimateBkg(UInt_t histoNo)
virtual void AppendErrorValue(Double_t dval)
Definition: PMusr.h:260
UInt_t fNoOfFitBins
number of bins to be fitted
virtual Bool_t IsFitRangeInBin()
Definition: PMusr.h:588
virtual Double_t GetTheoryTimeStep()
Definition: PMusr.h:245
std::vector< UInt_t > PUIntVector
Definition: PMusr.h:172
PRunData fData
data to be fitted, viewed, i.e. binned data
Definition: PRunBase.h:75
virtual void SetDataTimeStep(Double_t dval)
Definition: PMusr.h:254
virtual Double_t GetTheoryTimeStart()
Definition: PMusr.h:244
virtual Bool_t IsPresent()
Definition: PMusr.h:575
virtual Double_t GetT0Bin(UInt_t idx=0)
Definition: PMusr.cpp:1695
std::vector< PMsrParamStructure > PMsrParamList
Definition: PMusr.h:564
std::vector< Double_t > PDoubleVector
Definition: PMusr.h:196
virtual Double_t GetRRFFreq(const char *unit)
Definition: PMusr.cpp:762
virtual const Bool_t IsPresent(UInt_t histoNo)
Definition: PMusr.h:430
#define ACCEL_PERIOD_TRIUMF
Definition: PMusr.h:82
virtual Bool_t PrepareData()
#define FOURIER_UNIT_FREQ
Definition: PMusr.h:134
virtual const Double_t GetT0Bin(const UInt_t histoNo)
Definition: PMusr.h:431
virtual Bool_t PrepareViewData(PRawRunData *runData, const UInt_t histoNo)
virtual void SetT0Bin(Double_t dval, Int_t idx=-1)
Definition: PMusr.cpp:1712
virtual void AppendTheoryValue(Double_t dval)
Definition: PMusr.h:262
virtual PMsrGlobalBlock * GetMsrGlobal()
Definition: PMsrHandler.h:62
virtual void SetDataTimeStart(Double_t dval)
Definition: PMusr.h:253
virtual Int_t GetFitRangeOffset(UInt_t idx)
Definition: PMusr.cpp:1848
virtual void AppendValue(Double_t dval)
Definition: PMusr.h:259
virtual const PDoubleVector * GetValue()
Definition: PMusr.h:248
virtual const Double_t GetField()
Definition: PMusr.h:420
virtual void SetAddT0Bin(Double_t dval, UInt_t addRunIdx, UInt_t histoNoIdx)
Definition: PMusr.cpp:1788
Int_t fStartTimeBin
bin at which the fit starts
virtual Bool_t PrepareFitData(PRawRunData *runData, const UInt_t histoNo)
virtual Double_t GetBkgFix(UInt_t idx)
Definition: PMusr.cpp:1572
virtual void SetFitRangeBin(const TString fitRange)
virtual UInt_t GetFuncNo(Int_t idx)
Definition: PMsrHandler.h:94
PDoubleVector fW
vector holding the weight needed to estimate N0, and errN0.
virtual const UInt_t GetNoOfTemperatures()
Definition: PMusr.h:421
#define PMUSR_UNDEFINED
Definition: PMusr.h:89
virtual Int_t GetForwardHistoNo(UInt_t idx=0)
Definition: PMusr.cpp:1400
PDoubleVector fT0s
all t0 bins of a run! The derived classes will handle it.
Definition: PRunBase.h:78
virtual PMsrPlotList * GetMsrPlotList()
Definition: PMsrHandler.h:66
Double_t fEnergy
energy in (keV)
Definition: PMusr.h:228
virtual Int_t GetBkgRange(UInt_t idx)
Definition: PMusr.cpp:1612
EPMusrHandleTag fHandleTag
tag telling whether this is used for fit, view, ...
Definition: PRunBase.h:68
virtual UInt_t GetForwardHistoNoSize()
Definition: PMusr.h:652
EPMusrHandleTag
Definition: PMusr.h:220
virtual Double_t GetRRFPhase()
Definition: PMusr.h:579
PMsrRunBlock * fRunInfo
run info used to filter out needed infos of a run
Definition: PRunBase.h:72
virtual const Double_t GetEnergy()
Definition: PMusr.h:425
virtual void SetBkgRange(Int_t ival, Int_t idx)
Definition: PMusr.cpp:1630
virtual void SetFitRange(Double_t dval, UInt_t idx)
Definition: PMusr.cpp:1828
Double_t fFitEndTime
fit end time
Definition: PRunBase.h:82
virtual void SetTheoryTimeStep(Double_t dval)
Definition: PMusr.h:256
virtual TString * GetInstitute(UInt_t idx=0)
Definition: PMusr.cpp:1316
#define ACCEL_PERIOD_PSI
Definition: PMusr.h:81
virtual void SetFitRange(Double_t dval, UInt_t idx)
Definition: PMusr.cpp:1068
Double_t fFitStartTime
fit start time
Definition: PRunBase.h:81
virtual PMsrParamList * GetMsrParamList()
Definition: PMsrHandler.h:59
virtual PIntVector * GetMap()
Definition: PMusr.h:650
virtual Double_t EvalFunc(UInt_t i, std::vector< Int_t > map, std::vector< Double_t > param, PMetaData metaData)
Definition: PMsrHandler.h:98
virtual const PDoubleVector * GetDataBin(const UInt_t histoNo)
Definition: PMusr.h:438
Bool_t fTheoAsData
true=only calculate the theory points at the data points, false=calculate more points for the theory ...
virtual Double_t GetDataTimeStart()
Definition: PMusr.h:242
virtual UInt_t GetRunNameSize()
Definition: PMusr.h:635
Double_t fBackground
needed if background range is given (units: 1/bin)
virtual Int_t GetDataRange(UInt_t idx)
Definition: PMusr.cpp:1654
virtual const Double_t GetT0BinEstimated(const UInt_t histoNo)
Definition: PMusr.h:432
Int_t fRRFPacking
RRF packing for this particular run. Given in the GLOBAL-block.
virtual void CalcNoOfFitBins()
std::unique_ptr< PTheory > fTheory
theory needed to calculate chi-square
Definition: PRunBase.h:85
virtual Double_t GetFitRange(UInt_t idx)
Definition: PMusr.cpp:1051
virtual Double_t GetDataTimeStep()
Definition: PMusr.h:243
virtual Double_t CalcChiSquareExpected(const std::vector< Double_t > &par)
Int_t fRunNo
number of the run within the msr-file
Definition: PRunBase.h:70
virtual TString * GetRunName(UInt_t idx=0)
Definition: PMusr.cpp:1232
virtual Double_t GetFitRange(UInt_t idx)
Definition: PMusr.cpp:1811
Definition: PMusr.h:220
PDoubleVector fFuncValues
is keeping the values of the functions from the FUNCTIONS block
Definition: PRunBase.h:84
Double_t fField
field in (G)
Definition: PMusr.h:227
#define ACCEL_PERIOD_RAL
Definition: PMusr.h:83