musrfit  1.9.2
PRunMuMinus.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  PRunMuMinus.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 <iostream>
39 
40 #include <TString.h>
41 #include <TObjArray.h>
42 #include <TObjString.h>
43 
44 #include "PRunMuMinus.h"
45 
46 //--------------------------------------------------------------------------
47 // Constructor
48 //--------------------------------------------------------------------------
53 {
54  fNoOfFitBins = 0;
55  fPacking = -1;
56  fTheoAsData = false;
57 
58  // the 2 following variables are need in case fit range is given in bins, and since
59  // the fit range can be changed in the command block, these variables need to be accessible
60  fGoodBins[0] = -1;
61  fGoodBins[1] = -1;
62 
63  fStartTimeBin = -1;
64  fEndTimeBin = -1;
65 
67 }
68 
69 //--------------------------------------------------------------------------
70 // Constructor
71 //--------------------------------------------------------------------------
80 PRunMuMinus::PRunMuMinus(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData) :
81  PRunBase(msrInfo, rawData, runNo, tag), fTheoAsData(theoAsData)
82 {
83  fNoOfFitBins = 0;
84 
86  if (fPacking == -1) { // i.e. packing is NOT given in the RUN-block, it must be given in the GLOBAL-block
88  }
89  if (fPacking == -1) { // this should NOT happen, somethin is severely wrong
90  std::cerr << std::endl << ">> PRunMuMinus::PRunMuMinus: **SEVERE ERROR**: Couldn't find any packing information!";
91  std::cerr << std::endl << ">> This is very bad :-(, will quit ...";
92  std::cerr << std::endl;
93  fValid = false;
94  return;
95  }
96 
97  // the 2 following variables are need in case fit range is given in bins, and since
98  // the fit range can be changed in the command block, these variables need to be accessible
99  fGoodBins[0] = -1;
100  fGoodBins[1] = -1;
101 
102  fStartTimeBin = -1;
103  fEndTimeBin = -1;
104 
105  if (!PrepareData()) {
106  std::cerr << std::endl << ">> PRunMuMinus::PRunMuMinus: **SEVERE ERROR**: Couldn't prepare data for fitting!";
107  std::cerr << std::endl << ">> This is very bad :-(, will quit ...";
108  std::cerr << std::endl;
109  fValid = false;
110  }
111 }
112 
113 //--------------------------------------------------------------------------
114 // Destructor
115 //--------------------------------------------------------------------------
120 {
121  fForward.clear();
122 }
123 
124 //--------------------------------------------------------------------------
125 // CalcChiSquare
126 //--------------------------------------------------------------------------
135 Double_t PRunMuMinus::CalcChiSquare(const std::vector<Double_t>& par)
136 {
137  Double_t chisq = 0.0;
138  Double_t diff = 0.0;
139 
140  // calculate functions
141  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
142  Int_t funcNo = fMsrInfo->GetFuncNo(i);
143  fFuncValues[i] = fMsrInfo->EvalFunc(funcNo, *fRunInfo->GetMap(), par, fMetaData);
144  }
145 
146  // calculate chi square
147  Double_t time(1.0);
148  Int_t i;
149 
150  // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
151  // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
152  // for a given set of parameters---which should be done outside of the parallelized loop.
153  // For all other functions it means a tiny and acceptable overhead.
154  time = fTheory->Func(time, par, fFuncValues);
155 
156  #ifdef HAVE_GOMP
157  Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
158  if (chunk < 10)
159  chunk = 10;
160  #pragma omp parallel for default(shared) private(i,time,diff) schedule(dynamic,chunk) reduction(+:chisq)
161  #endif
162  for (i=fStartTimeBin; i < fEndTimeBin; ++i) {
163  time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
164  diff = fData.GetValue()->at(i) - fTheory->Func(time, par, fFuncValues);
165  chisq += diff*diff / (fData.GetError()->at(i)*fData.GetError()->at(i));
166  }
167 
168  return chisq;
169 }
170 
171 //--------------------------------------------------------------------------
172 // CalcChiSquareExpected (public)
173 //--------------------------------------------------------------------------
182 Double_t PRunMuMinus::CalcChiSquareExpected(const std::vector<Double_t>& par)
183 {
184  Double_t chisq = 0.0;
185  Double_t diff = 0.0;
186  Double_t theo = 0.0;
187 
188  // calculate functions
189  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
190  Int_t funcNo = fMsrInfo->GetFuncNo(i);
191  fFuncValues[i] = fMsrInfo->EvalFunc(funcNo, *fRunInfo->GetMap(), par, fMetaData);
192  }
193 
194  // calculate chi square
195  Double_t time(1.0);
196  Int_t i;
197 
198  // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
199  // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
200  // for a given set of parameters---which should be done outside of the parallelized loop.
201  // For all other functions it means a tiny and acceptable overhead.
202  time = fTheory->Func(time, par, fFuncValues);
203 
204  #ifdef HAVE_GOMP
205  Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
206  if (chunk < 10)
207  chunk = 10;
208  #pragma omp parallel for default(shared) private(i,time,diff) schedule(dynamic,chunk) reduction(+:chisq)
209  #endif
210  for (i=fStartTimeBin; i < fEndTimeBin; ++i) {
211  time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
212  theo = fTheory->Func(time, par, fFuncValues);
213  diff = fData.GetValue()->at(i) - theo;
214  chisq += diff*diff / theo;
215  }
216 
217  return 0.0;
218 }
219 
220 //--------------------------------------------------------------------------
221 // CalcMaxLikelihood
222 //--------------------------------------------------------------------------
231 Double_t PRunMuMinus::CalcMaxLikelihood(const std::vector<Double_t>& par)
232 {
233  Double_t mllh = 0.0; // maximum log likelihood assuming poisson distribution for the single bin
234 
235  // calculate functions
236  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
237  Int_t funcNo = fMsrInfo->GetFuncNo(i);
238  fFuncValues[i] = fMsrInfo->EvalFunc(funcNo, *fRunInfo->GetMap(), par, fMetaData);
239  }
240 
241  // calculate maximum log likelihood
242  Double_t theo;
243  Double_t data;
244  Double_t time(1.0);
245  Int_t i;
246 
247  // Calculate the theory function once to ensure one function evaluation for the current set of parameters.
248  // This is needed for the LF and user functions where some non-thread-save calculations only need to be calculated once
249  // for a given set of parameters---which should be done outside of the parallelized loop.
250  // For all other functions it means a tiny and acceptable overhead.
251  time = fTheory->Func(time, par, fFuncValues);
252 
253  #ifdef HAVE_GOMP
254  Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
255  if (chunk < 10)
256  chunk = 10;
257  #pragma omp parallel for default(shared) private(i,time,theo,data) schedule(dynamic,chunk) reduction(-:mllh)
258  #endif
259  for (i=fStartTimeBin; i < fEndTimeBin; ++i) {
260  time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
261  // calculate theory for the given parameter set
262  theo = fTheory->Func(time, par, fFuncValues);
263 
264  data = fData.GetValue()->at(i);
265 
266  if (theo <= 0.0) {
267  std::cerr << ">> PRunMuMinus::CalcMaxLikelihood: **WARNING** NEGATIVE theory!!" << std::endl;
268  continue;
269  }
270 
271  if (data > 1.0e-9) {
272  mllh += (theo-data) + data*log(data/theo);
273  } else {
274  mllh += (theo-data);
275  }
276  }
277 
278  return 2.0*mllh;
279 }
280 
281 //--------------------------------------------------------------------------
282 // GetNoOfFitBins (public)
283 //--------------------------------------------------------------------------
290 {
291  CalcNoOfFitBins();
292 
293  return fNoOfFitBins;
294 }
295 
296 //--------------------------------------------------------------------------
297 // SetFitRangeBin (public)
298 //--------------------------------------------------------------------------
310 void PRunMuMinus::SetFitRangeBin(const TString fitRange)
311 {
312  TObjArray *tok = nullptr;
313  TObjString *ostr = nullptr;
314  TString str;
315  Ssiz_t idx = -1;
316  Int_t offset = 0;
317 
318  tok = fitRange.Tokenize(" \t");
319 
320  if (tok->GetEntries() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1
321  // handle fgb+n0 entry
322  ostr = dynamic_cast<TObjString*>(tok->At(1));
323  str = ostr->GetString();
324  // check if there is an offset present
325  idx = str.First("+");
326  if (idx != -1) { // offset present
327  str.Remove(0, idx+1);
328  if (str.IsFloat()) // if str is a valid number, convert is to an integer
329  offset = str.Atoi();
330  }
331  fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
332 
333  // handle lgb-n1 entry
334  ostr = dynamic_cast<TObjString*>(tok->At(2));
335  str = ostr->GetString();
336  // check if there is an offset present
337  idx = str.First("-");
338  if (idx != -1) { // offset present
339  str.Remove(0, idx+1);
340  if (str.IsFloat()) // if str is a valid number, convert is to an integer
341  offset = str.Atoi();
342  }
343  fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
344  } else if ((tok->GetEntries() > 3) && (tok->GetEntries() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
345  Int_t pos = 2*(fRunNo+1)-1;
346 
347  if (pos + 1 >= tok->GetEntries()) {
348  std::cerr << std::endl << ">> PRunMuMinus::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
349  std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
350  } else {
351  // handle fgb+n0 entry
352  ostr = dynamic_cast<TObjString*>(tok->At(pos));
353  str = ostr->GetString();
354  // check if there is an offset present
355  idx = str.First("+");
356  if (idx != -1) { // offset present
357  str.Remove(0, idx+1);
358  if (str.IsFloat()) // if str is a valid number, convert is to an integer
359  offset = str.Atoi();
360  }
361  fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
362 
363  // handle lgb-n1 entry
364  ostr = dynamic_cast<TObjString*>(tok->At(pos+1));
365  str = ostr->GetString();
366  // check if there is an offset present
367  idx = str.First("-");
368  if (idx != -1) { // offset present
369  str.Remove(0, idx+1);
370  if (str.IsFloat()) // if str is a valid number, convert is to an integer
371  offset = str.Atoi();
372  }
373  fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution;
374  }
375  } else { // error
376  std::cerr << std::endl << ">> PRunMuMinus::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
377  std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
378  }
379 
380  // clean up
381  if (tok) {
382  delete tok;
383  }
384 }
385 
386 //--------------------------------------------------------------------------
387 // CalcNoOfFitBins (public)
388 //--------------------------------------------------------------------------
393 {
394  // In order not having to loop over all bins and to stay consistent with the chisq method, calculate the start and end bins explicitly
395  fStartTimeBin = static_cast<Int_t>(ceil((fFitStartTime - fData.GetDataTimeStart())/fData.GetDataTimeStep()));
396  if (fStartTimeBin < 0)
397  fStartTimeBin = 0;
398  fEndTimeBin = static_cast<Int_t>(floor((fFitEndTime - fData.GetDataTimeStart())/fData.GetDataTimeStep())) + 1;
399  if (fEndTimeBin > static_cast<Int_t>(fData.GetValue()->size()))
400  fEndTimeBin = fData.GetValue()->size();
401 
404  else
405  fNoOfFitBins = 0;
406 }
407 
408 //--------------------------------------------------------------------------
409 // CalcTheory
410 //--------------------------------------------------------------------------
415 {
416  // feed the parameter vector
417  std::vector<Double_t> par;
418  PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
419  for (UInt_t i=0; i<paramList->size(); i++)
420  par.push_back((*paramList)[i].fValue);
421 
422  // calculate functions
423  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
425  }
426 
427  // calculate theory
428  UInt_t size = fData.GetValue()->size();
429  Double_t start = fData.GetDataTimeStart();
430  Double_t resolution = fData.GetDataTimeStep();
431  Double_t time;
432  for (UInt_t i=0; i<size; i++) {
433  time = start + static_cast<Double_t>(i)*resolution;
434  fData.AppendTheoryValue(fTheory->Func(time, par, fFuncValues));
435  }
436 
437  // clean up
438  par.clear();
439 }
440 
441 //--------------------------------------------------------------------------
442 // PrepareData
443 //--------------------------------------------------------------------------
458 {
459  Bool_t success = true;
460 
461  if (!fValid)
462  return false;
463 
464  // keep the Global block info
465  PMsrGlobalBlock *globalBlock = fMsrInfo->GetMsrGlobal();
466 
467  // get the proper run
469  if (!runData) { // couldn't get run
470  std::cerr << std::endl << ">> PRunMuMinus::PrepareData(): **ERROR** Couldn't get run " << fRunInfo->GetRunName()->Data() << "!";
471  std::cerr << std::endl;
472  return false;
473  }
474 
475  // keep the field from the meta-data from the data-file
476  fMetaData.fField = runData->GetField();
477 
478  // keep the energy from the meta-data from the data-file
479  fMetaData.fEnergy = runData->GetEnergy();
480 
481  // keep the temperature(s) from the meta-data from the data-file
482  for (unsigned int i=0; i<runData->GetNoOfTemperatures(); i++)
483  fMetaData.fTemp.push_back(runData->GetTemperature(i));
484 
485  // collect histogram numbers
486  PUIntVector histoNo; // histoNo = msr-file forward + redGreen_offset - 1
487  for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
488  histoNo.push_back(fRunInfo->GetForwardHistoNo(i));
489 
490  if (!runData->IsPresent(histoNo[i])) {
491  std::cerr << std::endl << ">> PRunMuMinus::PrepareData(): **PANIC ERROR**:";
492  std::cerr << std::endl << ">> histoNo found = " << histoNo[i] << ", which is NOT present in the data file!?!?";
493  std::cerr << std::endl << ">> Will quit :-(";
494  std::cerr << std::endl;
495  histoNo.clear();
496  return false;
497  }
498  }
499 
500  // keep the time resolution in (us)
501  fTimeResolution = runData->GetTimeResolution()/1.0e3;
502  std::cout.precision(10);
503  std::cout << std::endl << ">> PRunMuMinus::PrepareData(): time resolution=" << std::fixed << runData->GetTimeResolution() << "(ns)" << std::endl;
504 
505  // get all the proper t0's and addt0's for the current RUN block
506  if (!GetProperT0(runData, globalBlock, histoNo)) {
507  return false;
508  }
509 
510  // keep the histo of each group at this point (addruns handled below)
511  std::vector<PDoubleVector> forward;
512  forward.resize(histoNo.size()); // resize to number of groups
513  for (UInt_t i=0; i<histoNo.size(); i++) {
514  forward[i].resize(runData->GetDataBin(histoNo[i])->size());
515  forward[i] = *runData->GetDataBin(histoNo[i]);
516  }
517 
518  // check if there are runs to be added to the current one
519  if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
520  PRawRunData *addRunData;
521  for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
522 
523  // get run to be added to the main one
524  addRunData = fRawData->GetRunData(*fRunInfo->GetRunName(i));
525  if (addRunData == nullptr) { // couldn't get run
526  std::cerr << std::endl << ">> PRunMuMinus::PrepareData(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
527  std::cerr << std::endl;
528  return false;
529  }
530 
531  // add forward run
532  UInt_t addRunSize;
533  for (UInt_t k=0; k<histoNo.size(); k++) { // fill each group
534  addRunSize = addRunData->GetDataBin(histoNo[k])->size();
535  for (UInt_t j=0; j<addRunData->GetDataBin(histoNo[k])->size(); j++) { // loop over the bin indices
536  // make sure that the index stays in the proper range
537  if ((static_cast<Int_t>(j)+static_cast<Int_t>(fAddT0s[i-1][k])-static_cast<Int_t>(fT0s[k]) >= 0) &&
538  (j+static_cast<Int_t>(fAddT0s[i-1][k])-static_cast<Int_t>(fT0s[k]) < addRunSize)) {
539  forward[k][j] += addRunData->GetDataBin(histoNo[k])->at(j+static_cast<Int_t>(fAddT0s[i-1][k])-static_cast<Int_t>(fT0s[k]));
540  }
541  }
542  }
543  }
544  }
545 
546  // set forward/backward histo data of the first group
547  fForward.resize(forward[0].size());
548  for (UInt_t i=0; i<fForward.size(); i++) {
549  fForward[i] = forward[0][i];
550  }
551 
552  // group histograms, add all the remaining forward histograms of the group
553  for (UInt_t i=1; i<histoNo.size(); i++) { // loop over the groupings
554  for (UInt_t j=0; j<runData->GetDataBin(histoNo[i])->size(); j++) { // loop over the bin indices
555  // make sure that the index stays within proper range
556  if ((static_cast<Int_t>(j)+fT0s[i]-fT0s[0] >= 0) && (j+fT0s[i]-fT0s[0] < runData->GetDataBin(histoNo[i])->size())) {
557  fForward[j] += forward[i][j+static_cast<Int_t>(fT0s[i])-static_cast<Int_t>(fT0s[0])];
558  }
559  }
560  }
561 
562  // get the data range (fgb/lgb) for the current RUN block
563  if (!GetProperDataRange()) {
564  return false;
565  }
566 
567  // get the fit range for the current RUN block
568  GetProperFitRange(globalBlock);
569 
570  // do the more fit/view specific stuff
571  if (fHandleTag == kFit)
572  success = PrepareFitData(runData, histoNo[0]);
573  else if (fHandleTag == kView)
574  success = PrepareRawViewData(runData, histoNo[0]);
575  else
576  success = false;
577 
578  // cleanup
579  histoNo.clear();
580 
581  return success;
582 }
583 
584 //--------------------------------------------------------------------------
585 // PrepareFitData (private)
586 //--------------------------------------------------------------------------
601 Bool_t PRunMuMinus::PrepareFitData(PRawRunData* runData, const UInt_t histoNo)
602 {
603  // transform raw histo data. This is done the following way (for details see the manual):
604  // for the single histo fit, just the rebinned raw data are copied
605 
606  // fill data set
607  Int_t t0 = static_cast<Int_t>(fT0s[0]);
608  Double_t value = 0.0;
609  // data start at data_start-t0
610  // data start time = (binStart - 0.5) + pack/2 - t0, with pack and binStart used as double
611  fData.SetDataTimeStart(fTimeResolution*((static_cast<Double_t>(fGoodBins[0])-0.5) + static_cast<Double_t>(fPacking)/2.0 - static_cast<Double_t>(t0)));
613  for (Int_t i=fGoodBins[0]; i<fGoodBins[1]; i++) {
614  if (fPacking == 1) {
615  value = fForward[i];
616  fData.AppendValue(value);
617  if (value == 0.0)
618  fData.AppendErrorValue(1.0);
619  else
620  fData.AppendErrorValue(TMath::Sqrt(value));
621  } else { // packed data, i.e. fPacking > 1
622  if (((i-fGoodBins[0]) % fPacking == 0) && (i != fGoodBins[0])) { // fill data
623  fData.AppendValue(value);
624  if (value == 0.0)
625  fData.AppendErrorValue(1.0);
626  else
627  fData.AppendErrorValue(TMath::Sqrt(value));
628  // reset values
629  value = 0.0;
630  }
631  value += fForward[i];
632  }
633  }
634 
635  CalcNoOfFitBins();
636 
637  return true;
638 }
639 
640 //--------------------------------------------------------------------------
641 // PrepareRawViewData (private)
642 //--------------------------------------------------------------------------
659 Bool_t PRunMuMinus::PrepareRawViewData(PRawRunData* runData, const UInt_t histoNo)
660 {
661  // check if view_packing is wished
662  Int_t packing = fPacking;
663  if (fMsrInfo->GetMsrPlotList()->at(0).fViewPacking > 0) {
664  packing = fMsrInfo->GetMsrPlotList()->at(0).fViewPacking;
665  }
666 
667  // calculate necessary norms
668  Double_t theoryNorm = 1.0;
669  if (fMsrInfo->GetMsrPlotList()->at(0).fViewPacking > 0) {
670  theoryNorm = static_cast<Double_t>(fMsrInfo->GetMsrPlotList()->at(0).fViewPacking)/static_cast<Double_t>(fPacking);
671  }
672 
673  // raw data, since PMusrCanvas is doing ranging etc.
674  // start = the first bin which is a multiple of packing backward from first good data bin
675  Int_t start = fGoodBins[0] - (fGoodBins[0]/packing)*packing;
676  // end = last bin starting from start which is a multipl of packing and still within the data
677  Int_t end = start + ((fForward.size()-start)/packing)*packing;
678  // check if data range has been provided, and if not try to estimate them
679  if (start < 0) {
680  Int_t offset = static_cast<Int_t>(10.0e-3/fTimeResolution);
681  start = (static_cast<Int_t>(fT0s[0])+offset) - ((static_cast<Int_t>(fT0s[0])+offset)/packing)*packing;
682  end = start + ((fForward.size()-start)/packing)*packing;
683  std::cerr << std::endl << ">> PRunMuMinus::PrepareData(): **WARNING** data range was not provided, will try data range start = " << start << ".";
684  std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
685  std::cerr << std::endl;
686  }
687  // check if start, end, and t0 make any sense
688  // 1st check if start and end are in proper order
689  if (end < start) { // need to swap them
690  Int_t keep = end;
691  end = start;
692  start = keep;
693  }
694  // 2nd check if start is within proper bounds
695  if ((start < 0) || (start > static_cast<Int_t>(fForward.size()))) {
696  std::cerr << std::endl << ">> PRunMuMinus::PrepareRawViewData(): **ERROR** start data bin doesn't make any sense!";
697  std::cerr << std::endl;
698  return false;
699  }
700  // 3rd check if end is within proper bounds
701  if ((end < 0) || (end > static_cast<Int_t>(fForward.size()))) {
702  std::cerr << std::endl << ">> PRunMuMinus::PrepareRawViewData(): **ERROR** end data bin doesn't make any sense!";
703  std::cerr << std::endl;
704  return false;
705  }
706 
707  // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
708  if (fRunInfo->IsFitRangeInBin()) {
709  fFitStartTime = (fRunInfo->GetDataRange(0) + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
710  fFitEndTime = (fRunInfo->GetDataRange(1) - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
711  }
712 
713  // everything looks fine, hence fill data set
714  Int_t t0 = static_cast<Int_t>(fT0s[0]);
715  Double_t value = 0.0;
716  // data start time = (binStart - 0.5) + pack/2 - t0, with pack and binStart used as double
717  fData.SetDataTimeStart(fTimeResolution*((static_cast<Double_t>(start)-0.5) + static_cast<Double_t>(packing)/2.0 - static_cast<Double_t>(t0)));
719 
720  for (Int_t i=start; i<end; i++) {
721  if (((i-start) % packing == 0) && (i != start)) { // fill data
722  fData.AppendValue(value);
723  if (value == 0.0)
724  fData.AppendErrorValue(1.0);
725  else
726  fData.AppendErrorValue(TMath::Sqrt(value));
727  // reset values
728  value = 0.0;
729  }
730  value += fForward[i];
731  }
732 
733  CalcNoOfFitBins();
734 
735  // fill theory vector for kView
736  // feed the parameter vector
737  std::vector<Double_t> par;
738  PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
739  for (UInt_t i=0; i<paramList->size(); i++)
740  par.push_back((*paramList)[i].fValue);
741 
742  // calculate functions
743  for (Int_t i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
745  }
746 
747  // calculate theory
748  UInt_t size = fForward.size();
749 /* //as35
750  Double_t factor = 1.0;
751  if (fData.GetValue()->size() * 10 > fForward.size()) {
752  size = fData.GetValue()->size() * 10;
753  factor = static_cast<Double_t>(fForward.size()) / static_cast<Double_t>(size);
754  }
755  Double_t time;
756  Double_t theoryValue;
757  fData.SetTheoryTimeStart(fData.GetDataTimeStart());
758  fData.SetTheoryTimeStep(fTimeResolution*factor);
759 */ //as35
760 
761  Int_t factor = 8; // 8 times more points for the theory (if fTheoAsData == false)
763  if (fTheoAsData) { // calculate theory only at the data points
765  } else {
766  // finer binning for the theory (8 times as many points = factor)
767  size *= factor;
768  fData.SetTheoryTimeStep(fData.GetDataTimeStep()/(Double_t)factor);
769  }
770 
771  Double_t time;
772  Double_t theoryValue;
773  for (UInt_t i=0; i<size; i++) {
775  theoryValue = fTheory->Func(time, par, fFuncValues);
776  if (fabs(theoryValue) > 1.0e10) { // dirty hack needs to be fixed!!
777  theoryValue = 0.0;
778  }
779  fData.AppendTheoryValue(theoryNorm*theoryValue);
780  }
781 
782  // clean up
783  par.clear();
784 
785  return true;
786 }
787 
788 //--------------------------------------------------------------------------
789 // GetProperT0 (private)
790 //--------------------------------------------------------------------------
806 Bool_t PRunMuMinus::GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &histoNo)
807 {
808  // feed all T0's
809  // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
810  fT0s.clear();
811  fT0s.resize(histoNo.size());
812  for (UInt_t i=0; i<fT0s.size(); i++) {
813  fT0s[i] = -1.0;
814  }
815 
816  // fill in the T0's from the msr-file (if present)
817  for (UInt_t i=0; i<fRunInfo->GetT0BinSize(); i++) {
818  fT0s[i] = fRunInfo->GetT0Bin(i);
819  }
820 
821  // fill in the T0's from the GLOBAL block section (if present)
822  for (UInt_t i=0; i<globalBlock->GetT0BinSize(); i++) {
823  if (fT0s[i] == -1.0) { // i.e. not given in the RUN block section
824  fT0s[i] = globalBlock->GetT0Bin(i);
825  }
826  }
827 
828  // fill in the T0's from the data file, if not already present in the msr-file
829  for (UInt_t i=0; i<histoNo.size(); i++) {
830  if (fT0s[i] == -1.0) { // i.e. not present in the msr-file, try the data file
831  if (runData->GetT0Bin(histoNo[i]) > 0.0) {
832  fT0s[i] = runData->GetT0Bin(histoNo[i]);
833  fRunInfo->SetT0Bin(fT0s[i], i); // keep value for the msr-file
834  }
835  }
836  }
837 
838  // 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
839  for (UInt_t i=0; i<histoNo.size(); i++) {
840  if (fT0s[i] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
841  fT0s[i] = runData->GetT0BinEstimated(histoNo[i]);
842  fRunInfo->SetT0Bin(fT0s[i], i); // keep value for the msr-file
843 
844  std::cerr << std::endl << ">> PRunMuMinus::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
845  std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName()->Data();
846  std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << runData->GetT0BinEstimated(histoNo[i]);
847  std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
848  std::cerr << std::endl;
849  }
850  }
851 
852  // check if t0 is within proper bounds
853  for (UInt_t i=0; i<fRunInfo->GetForwardHistoNoSize(); i++) {
854  if ((fT0s[i] < 0) || (fT0s[i] > static_cast<Int_t>(runData->GetDataBin(histoNo[i])->size()))) {
855  std::cerr << std::endl << ">> PRunMuMinus::GetProperT0(): **ERROR** t0 data bin (" << fT0s[i] << ") doesn't make any sense!";
856  std::cerr << std::endl;
857  return false;
858  }
859  }
860 
861  // check if there are runs to be added to the current one
862  if (fRunInfo->GetRunNameSize() > 1) { // runs to be added present
863  PRawRunData *addRunData;
864  fAddT0s.resize(fRunInfo->GetRunNameSize()-1); // resize to the number of addruns
865  for (UInt_t i=1; i<fRunInfo->GetRunNameSize(); i++) {
866 
867  // get run to be added to the main one
868  addRunData = fRawData->GetRunData(*fRunInfo->GetRunName(i));
869  if (addRunData == nullptr) { // couldn't get run
870  std::cerr << std::endl << ">> PRunMuMinus::GetProperT0(): **ERROR** Couldn't get addrun " << fRunInfo->GetRunName(i)->Data() << "!";
871  std::cerr << std::endl;
872  return false;
873  }
874 
875  // feed all T0's
876  // first init T0's, T0's are stored as (forward T0, backward T0, etc.)
877  fAddT0s[i-1].resize(histoNo.size());
878  for (UInt_t j=0; j<fAddT0s[i-1].size(); j++) {
879  fAddT0s[i-1][j] = -1.0;
880  }
881 
882  // fill in the T0's from the msr-file (if present)
883  for (UInt_t j=0; j<fRunInfo->GetT0BinSize(); j++) {
884  fAddT0s[i-1][j] = fRunInfo->GetAddT0Bin(i-1,j); // addRunIdx starts at 0
885  }
886 
887  // fill in the T0's from the data file, if not already present in the msr-file
888  for (UInt_t j=0; j<histoNo.size(); j++) {
889  if (fAddT0s[i-1][j] == -1.0) // i.e. not present in the msr-file, try the data file
890  if (addRunData->GetT0Bin(histoNo[j]) > 0.0) {
891  fAddT0s[i-1][j] = addRunData->GetT0Bin(histoNo[j]);
892  fRunInfo->SetAddT0Bin(fAddT0s[i-1][j], i-1, j); // keep value for the msr-file
893  }
894  }
895 
896  // 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
897  for (UInt_t j=0; j<histoNo.size(); j++) {
898  if (fAddT0s[i-1][j] == -1.0) { // i.e. not present in the msr-file and data file, use the estimated T0
899  fAddT0s[i-1][j] = addRunData->GetT0BinEstimated(histoNo[j]);
900  fRunInfo->SetAddT0Bin(fAddT0s[i-1][j], i-1, j); // keep value for the msr-file
901 
902  std::cerr << std::endl << ">> PRunMuMinus::GetProperT0(): **WARRNING** NO t0's found, neither in the run data nor in the msr-file!";
903  std::cerr << std::endl << ">> run: " << fRunInfo->GetRunName(i)->Data();
904  std::cerr << std::endl << ">> will try the estimated one: forward t0 = " << addRunData->GetT0BinEstimated(histoNo[j]);
905  std::cerr << std::endl << ">> NO WARRANTY THAT THIS OK!! For instance for LEM this is almost for sure rubbish!";
906  std::cerr << std::endl;
907  }
908  }
909 
910  // check if t0 is within proper bounds
911  for (UInt_t j=0; j<fRunInfo->GetForwardHistoNoSize(); j++) {
912  if ((fAddT0s[i-1][j] < 0) || (fAddT0s[i-1][j] > static_cast<Int_t>(addRunData->GetDataBin(histoNo[j])->size()))) {
913  std::cerr << std::endl << ">> PRunMuMinus::GetProperT0(): **ERROR** addt0 data bin (" << fAddT0s[i-1][j] << ") doesn't make any sense!";
914  std::cerr << std::endl;
915  return false;
916  }
917  }
918  }
919  }
920 
921  return true;
922 }
923 
924 //--------------------------------------------------------------------------
925 // GetProperDataRange (private)
926 //--------------------------------------------------------------------------
938 {
939  // get start/end data
940  Int_t start;
941  Int_t end;
942  start = fRunInfo->GetDataRange(0);
943  end = fRunInfo->GetDataRange(1);
944 
945  // check if data range has been given in the RUN block, if not try to get it from the GLOBAL block
946  if (start < 0) {
947  start = fMsrInfo->GetMsrGlobal()->GetDataRange(0);
948  }
949  if (end < 0) {
950  end = fMsrInfo->GetMsrGlobal()->GetDataRange(1);
951  }
952 
953  // check if data range has been provided, and if not try to estimate them
954  if (start < 0) {
955  Int_t offset = static_cast<Int_t>(10.0e-3/fTimeResolution);
956  start = static_cast<Int_t>(fT0s[0])+offset;
957  fRunInfo->SetDataRange(start, 0);
958  std::cerr << std::endl << ">> PRunMuMinus::GetProperDataRange(): **WARNING** data range was not provided, will try data range start = t0+" << offset << "(=10ns) = " << start << ".";
959  std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
960  std::cerr << std::endl;
961  }
962  if (end < 0) {
963  end = fForward.size();
964  fRunInfo->SetDataRange(end, 1);
965  std::cerr << std::endl << ">> PRunMuMinus::GetProperDataRange(): **WARNING** data range was not provided, will try data range end = " << end << ".";
966  std::cerr << std::endl << ">> NO WARRANTY THAT THIS DOES MAKE ANY SENSE.";
967  std::cerr << std::endl;
968  }
969 
970  // check if start and end make any sense
971  // 1st check if start and end are in proper order
972  if (end < start) { // need to swap them
973  Int_t keep = end;
974  end = start;
975  start = keep;
976  }
977  // 2nd check if start is within proper bounds
978  if ((start < 0) || (start > static_cast<Int_t>(fForward.size()))) {
979  std::cerr << std::endl << ">> PRunMuMinus::GetProperDataRange(): **ERROR** start data bin (" << start << ") doesn't make any sense!";
980  std::cerr << std::endl;
981  return false;
982  }
983  // 3rd check if end is within proper bounds
984  if ((end < 0) || (end > static_cast<Int_t>(fForward.size()))) {
985  std::cerr << std::endl << ">> PRunMuMinus::GetProperDataRange(): **ERROR** end data bin (" << end << ") doesn't make any sense!";
986  std::cerr << std::endl;
987  return false;
988  }
989 
990  // keep good bins for potential later use
991  fGoodBins[0] = start;
992  fGoodBins[1] = end;
993 
994  return true;
995 }
996 
997 //--------------------------------------------------------------------------
998 // GetProperFitRange (private)
999 //--------------------------------------------------------------------------
1013 {
1014  // set fit start/end time; first check RUN Block
1017  // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1018  if (fRunInfo->IsFitRangeInBin()) {
1019  fFitStartTime = (fGoodBins[0] + fRunInfo->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1020  fFitEndTime = (fGoodBins[1] - fRunInfo->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1021  // write these times back into the data structure. This way it is available when writting the log-file
1024  }
1025  if (fFitStartTime == PMUSR_UNDEFINED) { // fit start/end NOT found in the RUN block, check GLOBAL block
1026  fFitStartTime = globalBlock->GetFitRange(0);
1027  fFitEndTime = globalBlock->GetFitRange(1);
1028  // if fit range is given in bins (and not time), the fit start/end time can be calculated at this point now
1029  if (globalBlock->IsFitRangeInBin()) {
1030  fFitStartTime = (fGoodBins[0] + globalBlock->GetFitRangeOffset(0) - fT0s[0]) * fTimeResolution; // (fgb+n0-t0)*dt
1031  fFitEndTime = (fGoodBins[1] - globalBlock->GetFitRangeOffset(1) - fT0s[0]) * fTimeResolution; // (lgb-n1-t0)*dt
1032  // write these times back into the data structure. This way it is available when writting the log-file
1033  globalBlock->SetFitRange(fFitStartTime, 0);
1034  globalBlock->SetFitRange(fFitEndTime, 1);
1035  }
1036  }
1038  fFitStartTime = (fGoodBins[0] - fT0s[0]) * fTimeResolution; // (fgb-t0)*dt
1039  fFitEndTime = (fGoodBins[1] - fT0s[0]) * fTimeResolution; // (lgb-t0)*dt
1040  std::cerr << ">> PRunMuMinus::GetProperFitRange(): **WARNING** Couldn't get fit start/end time!" << std::endl;
1041  std::cerr << ">> Will set it to fgb/lgb which given in time is: " << fFitStartTime << "..." << fFitEndTime << " (usec)" << std::endl;
1042  }
1043 }
virtual void GetProperFitRange(PMsrGlobalBlock *globalBlock)
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
Definition: PMusr.h:220
virtual void SetDataRange(Int_t ival, Int_t idx)
Definition: PMusr.cpp:1672
virtual const PDoubleVector * GetError()
Definition: PMusr.h:249
virtual Double_t CalcChiSquare(const std::vector< Double_t > &par)
Definition: PMusr.h:220
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
virtual const Double_t GetTimeResolution()
Definition: PMusr.h:429
virtual void CalcNoOfFitBins()
virtual Int_t GetPacking()
Definition: PMusr.h:668
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 Int_t GetFitRangeOffset(UInt_t idx)
Definition: PMusr.cpp:1088
virtual void CalcTheory()
virtual void SetTheoryTimeStart(Double_t dval)
Definition: PMusr.h:255
Int_t fPacking
packing for this particular run. Either given in the RUN- or GLOBAL-block.
Definition: PRunMuMinus.h:67
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
virtual Bool_t PrepareRawViewData(PRawRunData *runData, const UInt_t histoNo)
virtual PRawRunData * GetRunData(const TString &runName)
virtual Double_t GetAddT0Bin(UInt_t addRunIdx, UInt_t histoIdx)
Definition: PMusr.cpp:1761
virtual UInt_t GetT0BinSize()
Definition: PMusr.h:660
PDoubleVector fTemp
temperature(s) in (K)
Definition: PMusr.h:229
virtual void AppendErrorValue(Double_t dval)
Definition: PMusr.h:260
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 Double_t GetT0Bin(UInt_t idx=0)
Definition: PMusr.cpp:1695
std::vector< PMsrParamStructure > PMsrParamList
Definition: PMusr.h:564
virtual const Bool_t IsPresent(UInt_t histoNo)
Definition: PMusr.h:430
virtual const Double_t GetT0Bin(const UInt_t histoNo)
Definition: PMusr.h:431
virtual Bool_t PrepareFitData(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
virtual UInt_t GetFuncNo(Int_t idx)
Definition: PMsrHandler.h:94
virtual Bool_t PrepareData()
Int_t fEndTimeBin
bin at which the fit ends
Definition: PRunMuMinus.h:75
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
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 UInt_t GetNoOfFitBins()
UInt_t fNoOfFitBins
number of bins to be fitted
Definition: PRunMuMinus.h:66
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
Int_t fGoodBins[2]
keep first/last good bins. 0=fgb, 1=lgb
Definition: PRunMuMinus.h:70
Int_t fStartTimeBin
bin at which the fit starts
Definition: PRunMuMinus.h:74
virtual void SetFitRange(Double_t dval, UInt_t idx)
Definition: PMusr.cpp:1828
PDoubleVector fForward
forward histo data
Definition: PRunMuMinus.h:72
Double_t fFitEndTime
fit end time
Definition: PRunBase.h:82
virtual void SetTheoryTimeStep(Double_t dval)
Definition: PMusr.h:256
virtual void SetFitRange(Double_t dval, UInt_t idx)
Definition: PMusr.cpp:1068
Double_t fFitStartTime
fit start time
Definition: PRunBase.h:81
virtual ~PRunMuMinus()
virtual PMsrParamList * GetMsrParamList()
Definition: PMsrHandler.h:59
virtual Double_t CalcChiSquareExpected(const std::vector< Double_t > &par)
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
virtual Double_t GetDataTimeStart()
Definition: PMusr.h:242
virtual UInt_t GetRunNameSize()
Definition: PMusr.h:635
virtual Int_t GetDataRange(UInt_t idx)
Definition: PMusr.cpp:1654
Bool_t fTheoAsData
true=only calculate the theory points at the data points, false=calculate more points for the theory ...
Definition: PRunMuMinus.h:68
virtual const Double_t GetT0BinEstimated(const UInt_t histoNo)
Definition: PMusr.h:432
virtual Bool_t GetProperT0(PRawRunData *runData, PMsrGlobalBlock *globalBlock, PUIntVector &histoNo)
std::unique_ptr< PTheory > fTheory
theory needed to calculate chi-square
Definition: PRunBase.h:85
virtual Int_t GetPacking()
Definition: PMusr.h:591
virtual void SetFitRangeBin(const TString fitRange)
virtual Double_t GetFitRange(UInt_t idx)
Definition: PMusr.cpp:1051
virtual Double_t GetDataTimeStep()
Definition: PMusr.h:243
Int_t fRunNo
number of the run within the msr-file
Definition: PRunBase.h:70
virtual Double_t CalcMaxLikelihood(const std::vector< Double_t > &par)
virtual TString * GetRunName(UInt_t idx=0)
Definition: PMusr.cpp:1232
virtual Bool_t GetProperDataRange()
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