musrfit  1.9.2
PMusrCanvas.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  PMusrCanvas.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 #include <iostream>
31 #include <iomanip>
32 #include <fstream>
33 
34 #include <TColor.h>
35 #include <TRandom.h>
36 #include <TROOT.h>
37 #include <TObjString.h>
38 #include <TGFileDialog.h>
39 
40 #include "PMusrCanvas.h"
41 #include "PFourier.h"
42 
43 static const char *gFiletypes[] = { "Data files", "*.dat",
44  "All files", "*",
45  nullptr, nullptr };
46 
48 
49 //--------------------------------------------------------------------------
50 // Constructor
51 //--------------------------------------------------------------------------
56 {
57  fXRangePresent = false;
58  fYRangePresent = false;
59 
60  fXmin = 0.0;
61  fXmax = 0.0;
62  fYmin = 0.0;
63  fYmax = 0.0;
64 }
65 
66 //--------------------------------------------------------------------------
67 // SetXRange (public)
68 //--------------------------------------------------------------------------
75 void PMusrCanvasPlotRange::SetXRange(Double_t xmin, Double_t xmax)
76 {
77  if (xmin > xmax) {
78  std::cerr << std::endl << ">> PMusrCanvasPlotRange::SetXRange(): **WARNING** xmin > xmax, will swap them." << std::endl;
79  fXmin = xmax;
80  fXmax = xmin;
81  } else {
82  fXmin = xmin;
83  fXmax = xmax;
84  }
85  fXRangePresent = true;
86 }
87 
88 //--------------------------------------------------------------------------
89 // SetYRange (public)
90 //--------------------------------------------------------------------------
97 void PMusrCanvasPlotRange::SetYRange(Double_t ymin, Double_t ymax)
98 {
99  if (ymin > ymax) {
100  std::cerr << std::endl << ">> PMusrCanvasPlotRange::SetYRange(): **WARNING** ymin > ymax, will swap them." << std::endl;
101  fYmin = ymax;
102  fYmax = ymin;
103  } else {
104  fYmin = ymin;
105  fYmax = ymax;
106  }
107  fYRangePresent = true;
108 }
109 
110 
112 
113 //--------------------------------------------------------------------------
114 // Constructor
115 //--------------------------------------------------------------------------
120 {
121  fTimeout = 0;
122 
123  fScaleN0AndBkg = true;
124  fValid = false;
125  fAveragedView = false;
126  fDifferenceView = false;
127  fToggleColor = false;
130  fPlotType = -1;
131  fPlotNumber = -1;
132 
133  fImp = nullptr;
134  fBar = nullptr;
135  fPopupMain = nullptr;
136 
137  fHistoFrame = nullptr;
138 
139  fMultiGraphData = nullptr;
140  fMultiGraphDiff = nullptr;
141 
142  InitFourier();
143  InitAverage();
144 
145  fXRangePresent = false;
146  fYRangePresent = false;
147  fXmin = 0.0;
148  fXmax = 0.0;
149  fYmin = 0.0;
150  fYmax = 0.0;
151 
152  gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling
153 }
154 
155 //--------------------------------------------------------------------------
156 // Constructor
157 //--------------------------------------------------------------------------
172 PMusrCanvas::PMusrCanvas(const Int_t number, const Char_t* title,
173  Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh,
174  const Bool_t batch, const Bool_t fourier, const Bool_t avg,
175  const Bool_t theoAsData) :
176  fTheoAsData(theoAsData), fStartWithFourier(fourier), fStartWithAvg(avg),
177  fBatchMode(batch), fPlotNumber(number)
178 {
179  fTimeout = 0;
180  fAveragedView = false;
181 
182  fMultiGraphData = nullptr;
183  fMultiGraphDiff = nullptr;
184 
185  fHistoFrame = nullptr;
186 
187  InitFourier();
188  InitAverage();
189  CreateStyle();
190  InitMusrCanvas(title, wtopx, wtopy, ww, wh);
191 
192  fXRangePresent = false;
193  fYRangePresent = false;
194  fXmin = 0.0;
195  fXmax = 0.0;
196  fYmin = 0.0;
197  fYmax = 0.0;
198 
199  gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling
200 }
201 
202 //--------------------------------------------------------------------------
203 // Constructor
204 //--------------------------------------------------------------------------
222 PMusrCanvas::PMusrCanvas(const Int_t number, const Char_t* title,
223  Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh,
224  PMsrFourierStructure fourierDefault,
225  const PIntVector markerList, const PIntVector colorList,
226  const Bool_t batch, const Bool_t fourier, const Bool_t avg,
227  const Bool_t theoAsData) :
228  fTheoAsData(theoAsData), fStartWithFourier(fourier), fStartWithAvg(avg), fBatchMode(batch),
229  fPlotNumber(number), fFourier(fourierDefault),
230  fMarkerList(markerList), fColorList(colorList)
231 {
232  fTimeout = 0;
233 
234  fMultiGraphData = nullptr;
235  fMultiGraphDiff = nullptr;
236 
237  fHistoFrame = nullptr;
238 
239  InitAverage();
240  CreateStyle();
241  InitMusrCanvas(title, wtopx, wtopy, ww, wh);
242 
243  fXRangePresent = false;
244  fYRangePresent = false;
245  fXmin = 0.0;
246  fXmax = 0.0;
247  fYmin = 0.0;
248  fYmax = 0.0;
249 
250  gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling
251 }
252 
253 //--------------------------------------------------------------------------
254 // Destructor
255 //--------------------------------------------------------------------------
260 {
261  // cleanup
262  if (fData.size() > 0) {
263  for (UInt_t i=0; i<fData.size(); i++)
264  CleanupDataSet(fData[i]);
265  fData.clear();
266  }
267  if (fNonMusrData.size() > 0) {
268  for (UInt_t i=0; i<fNonMusrData.size(); i++)
270  fNonMusrData.clear();
271  }
272  if (fMultiGraphData) {
273  delete fMultiGraphData;
274  fMultiGraphData = nullptr;
275  }
276  if (fMultiGraphDiff) {
277  delete fMultiGraphDiff;
278  fMultiGraphDiff = nullptr;
279  }
280 }
281 
282 //--------------------------------------------------------------------------
283 // SetMsrHandler (public)
284 //--------------------------------------------------------------------------
291 {
292  fMsrHandler = msrHandler;
293 
295 
296  // check if a fourier block is present in the msr-file, and if yes extract the given values
301  }
304  }
308  }
311  }
313 
318  }
319  if ((fMsrHandler->GetMsrFourierList()->fPlotRange[0] != -1.0) &&
320  (fMsrHandler->GetMsrFourierList()->fPlotRange[1] != -1.0)) {
323  }
324  }
325 
326  // check if RRF data are present
327  if (((fMsrHandler->GetMsrPlotList()->at(0).fRRFPacking > 0) &&
328  (fMsrHandler->GetMsrPlotList()->at(0).fRRFFreq != 0.0)) ||
330  fMsrHandler->GetMsrGlobal()->GetRRFUnit().CompareTo("??"))) {
331  fRRFLatexText = std::make_unique<TLatex>();
332  fRRFLatexText->SetNDC(kTRUE);
333  fRRFLatexText->SetTextFont(62);
334  fRRFLatexText->SetTextSize(0.03);
335 
336  Int_t rrfUnitTag = -1;
337  Double_t rrfFreq = 0.0;
338  if (fMsrHandler->GetMsrPlotList()->at(0).fRRFPacking > 0) { // RRF single histo PLOT
339  fRRFText = std::make_unique<TString>("RRF: ");
340  rrfUnitTag = fMsrHandler->GetMsrPlotList()->at(0).fRRFUnit;
341  rrfFreq = fMsrHandler->GetMsrPlotList()->at(0).fRRFFreq;
342  TString rrfFreqStr("");
343  rrfFreqStr.Form("%.5g", rrfFreq);
344  if (rrfUnitTag == RRF_UNIT_kHz) {
345  *fRRFText += TString("#nu_{RRF} = ");
346  *fRRFText += rrfFreq;
347  *fRRFText += TString(" (kHz)");
348  } else if (rrfUnitTag == RRF_UNIT_MHz) {
349  *fRRFText += TString("#nu_{RRF} = ");
350  *fRRFText += rrfFreqStr;
351  *fRRFText += TString(" (MHz)");
352  } else if (rrfUnitTag == RRF_UNIT_Mcs) {
353  *fRRFText += TString("#omega_{RRF} = ");
354  *fRRFText += rrfFreqStr;
355  *fRRFText += TString(" (Mc/s)");
356  } else if (rrfUnitTag == RRF_UNIT_G) {
357  *fRRFText += TString("B_{RRF} = ");
358  *fRRFText += rrfFreqStr;
359  *fRRFText += TString(" (G)");
360  } else if (rrfUnitTag == RRF_UNIT_T) {
361  *fRRFText += TString("B_{RRF} = ");
362  *fRRFText += rrfFreqStr;
363  *fRRFText += TString(" (T)");
364  }
365  *fRRFText += TString(", RRF packing = ");
366  *fRRFText += fMsrHandler->GetMsrPlotList()->at(0).fRRFPacking;
367  } else { // RRF single histo FIT
368  fRRFText = std::make_unique<TString>("RRF: ");
369  rrfUnitTag = fMsrHandler->GetMsrGlobal()->GetRRFUnitTag();
371  TString rrfFreqStr("");
372  rrfFreqStr.Form("%.5g", rrfFreq);
373  if (rrfUnitTag == RRF_UNIT_kHz) {
374  *fRRFText += TString("#nu_{RRF} = ");
375  *fRRFText += rrfFreqStr;
376  *fRRFText += TString(" (kHz)");
377  } else if (rrfUnitTag == RRF_UNIT_MHz) {
378  *fRRFText += TString("#nu_{RRF} = ");
379  *fRRFText += rrfFreqStr;
380  *fRRFText += TString(" (MHz)");
381  } else if (rrfUnitTag == RRF_UNIT_Mcs) {
382  *fRRFText += TString("#omega_{RRF} = ");
383  *fRRFText += rrfFreqStr;
384  *fRRFText += TString(" (Mc/s)");
385  } else if (rrfUnitTag == RRF_UNIT_G) {
386  *fRRFText += TString("B_{RRF} = ");
387  *fRRFText += rrfFreqStr;
388  *fRRFText += TString(" (G)");
389  } else if (rrfUnitTag == RRF_UNIT_T) {
390  *fRRFText += TString("B_{RRF} = ");
391  *fRRFText += rrfFreqStr;
392  *fRRFText += TString(" (T)");
393  }
394  *fRRFText += TString(", RRF packing = ");
396  }
397  }
398 }
399 
400 //--------------------------------------------------------------------------
401 // SetTimeout (public)
402 //--------------------------------------------------------------------------
409 {
410  fTimeout = timeout;
411 
412  if (fTimeout <= 0)
413  return;
414 
415  fTimeoutTimer.reset(new TTimer());
416 
417  fTimeoutTimer->Connect("Timeout()", "PMusrCanvas", this, "Done()");
418 
419  fTimeoutTimer->Start(1000*fTimeout, kTRUE);
420 }
421 
422 //--------------------------------------------------------------------------
423 // UpdateParamTheoryPad (public)
424 //--------------------------------------------------------------------------
429 {
430  if (!fValid)
431  return;
432 
433  TString str;
434  Char_t cnum[128];
435  Int_t maxLength = 0;
436  Double_t ypos = 0.0, yoffset = 0.0;
437  Int_t idx = -1;
438 
439  // add parameters ------------------------------------------------------------
441 
442  // get maximal parameter name string length
443  for (UInt_t i=0; i<param.size(); i++) {
444  if (param[i].fName.Length() > maxLength)
445  maxLength = param[i].fName.Length();
446  }
447  maxLength += 2;
448 
449  // calculate yoffset based on the number of parameters
450  if (param.size() > 20)
451  yoffset = 1.0 / (param.size()+1);
452  else
453  yoffset = 0.05;
454 
455  // add parameters to the pad
456  UInt_t accuracy = 6;
457  Char_t accStr[32];
458  for (UInt_t i=0; i<param.size(); i++) {
459  str = "";
460  accuracy = GetNeededAccuracy(param[i]);
461  snprintf(accStr, sizeof(accStr), "%%.%dlf", accuracy);
462  // parameter no
463  str += param[i].fNo;
464  if (param[i].fNo<10)
465  str += " ";
466  else
467  str += " ";
468  // parameter name
469  str += param[i].fName;
470  for (Int_t j=0; j<maxLength-param[i].fName.Length(); j++) // fill spaces
471  str += " ";
472  // parameter value
473  if (round(param[i].fValue)-param[i].fValue==0)
474  snprintf(cnum, sizeof(cnum), "%.1lf", param[i].fValue);
475  else
476  snprintf(cnum, sizeof(cnum), accStr, param[i].fValue);
477  str += cnum;
478  for (Int_t j=0; j<9-(Int_t)strlen(cnum); j++) // fill spaces
479  str += " ";
480  str += " "; // to make sure that at least 1 space is placed
481  // parameter error
482  if (param[i].fPosErrorPresent) { // minos was used
483  // calculate the arithmetic average of the pos. and neg. error
484  Double_t err;
485  err = (param[i].fPosError - param[i].fStep) / 2.0;
486  // check if the pos. and neg. error within 10%
487  if ((fabs(fabs(param[i].fStep) - param[i].fPosError) < 0.1*fabs(param[i].fStep)) &&
488  (fabs(fabs(param[i].fStep) - param[i].fPosError) < 0.1*param[i].fPosError)) {
489  if (round(err)-err==0)
490  snprintf(cnum, sizeof(cnum), "%.1lf", err);
491  else
492  snprintf(cnum, sizeof(cnum), accStr, err);
493  } else {
494  snprintf(accStr, sizeof(accStr), "%%.%dlf!!", accuracy);
495  if (round(err)-err==0)
496  snprintf(cnum, sizeof(cnum), "%.1lf!!", err);
497  else
498  snprintf(cnum, sizeof(cnum), accStr, err);
499  }
500  str += cnum;
501  } else { // minos was not used
502  if (round(param[i].fStep)-param[i].fStep==0)
503  snprintf(cnum, sizeof(cnum), "%.1lf", param[i].fStep);
504  else
505  snprintf(cnum, sizeof(cnum), accStr, param[i].fStep);
506  str += cnum;
507  }
508  ypos = 0.98-i*yoffset;
509  fParameterPad->AddText(0.03, ypos, str.Data());
510  }
511 
512  // add theory ------------------------------------------------------------
513  PMsrLines theory = *fMsrHandler->GetMsrTheory();
514  if (theory.size() > 20)
515  yoffset = 1.0/(theory.size()+1);
516  else
517  yoffset = 0.05;
518  for (UInt_t i=1; i<theory.size(); i++) {
519  // remove comment if present
520  str = theory[i].fLine;
521  idx = str.Index("(");
522  if (idx > 0) { // comment present
523  str.Resize(idx-1);
524  str.Resize(str.Strip().Length());
525  }
526  ypos = 0.98 - i*yoffset;
527  fTheoryPad->AddText(0.03, ypos, str.Data());
528  }
529 
530  // add functions --------------------------------------------------------
531  ypos -= 0.05;
532  PMsrLines functions = *fMsrHandler->GetMsrFunctions();
533  for (UInt_t i=1; i<functions.size(); i++) {
534  ypos -= 0.05;
535  fTheoryPad->AddText(0.03, ypos, functions[i].fLine.Data());
536  }
537 
538 
539  fParameterPad->Draw();
540  fTheoryPad->Draw();
541  fMainCanvas->cd();
542  fMainCanvas->Update();
543 }
544 
545 //--------------------------------------------------------------------------
546 // UpdateDataTheoryPad (public)
547 //--------------------------------------------------------------------------
552 {
553  // some checks first
554  UInt_t runNo;
557  PMsrGlobalBlock *globalBlock = fMsrHandler->GetMsrGlobal();
558 
559  Int_t fitType = globalBlock->GetFitType();
560 
561  fPlotType = plotInfo.fPlotType;
562  for (UInt_t i=0; i<plotInfo.fRuns.size(); i++) {
563  // first check that plot number is smaller than the maximal number of runs
564  if ((Int_t)plotInfo.fRuns[i] > (Int_t)runs.size()) {
565  fValid = false;
566  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** run plot number " << (Int_t)plotInfo.fRuns[i] << " is larger than the number of runs " << runs.size();
567  std::cerr << std::endl;
568  return;
569  }
570  // check that the plottype and the fittype do correspond
571  runNo = (UInt_t)plotInfo.fRuns[i]-1;
572  if (runs[runNo].GetFitType() != -1) { // fit type found in RUN block, hence overwrite the GLOBAL block
573  fitType = runs[runNo].GetFitType();
574  }
575  if (fitType == -1) {
576  fValid = false;
577  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** plottype = " << fPlotType;
578  std::cerr << ", fittype = " << runs[runNo].GetFitType() << "(RUN block)/";
579  std::cerr << "fittype = " << globalBlock->GetFitType() << "(GLOBAL block). However, they have to correspond!";
580  std::cerr << std::endl;
581  return;
582  }
583  }
584 
585  PRunData *data;
586  for (UInt_t i=0; i<plotInfo.fRuns.size(); i++) {
587  // get run data and create a histogram
588  data = nullptr;
589  runNo = (UInt_t)plotInfo.fRuns[i]-1;
590  // get data depending on the fittype
591  if (runs[runNo].GetFitType() != -1) { // fit type found in RUN block, hence overwrite the GLOBAL block
592  fitType = runs[runNo].GetFitType();
593  }
594  switch (fitType) {
597  if (!data) { // something wrong
598  fValid = false;
599  // error message
600  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a single histogram plot";
601  std::cerr << std::endl;
602  return;
603  }
604  // handle data
605  HandleDataSet(i, runNo, data);
606  break;
609  if (!data) { // something wrong
610  fValid = false;
611  // error message
612  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a single histogram RRF plot";
613  std::cerr << std::endl;
614  return;
615  }
616  // handle data
617  HandleDataSet(i, runNo, data);
618  break;
619  case MSR_FITTYPE_ASYM:
621  if (!data) { // something wrong
622  fValid = false;
623  // error message
624  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a asymmetry plot";
625  std::cerr << std::endl;
626  return;
627  }
628  // handle data
629  HandleDataSet(i, runNo, data);
630  break;
631  case MSR_FITTYPE_BNMR:
633  if (!data) { // something wrong
634  fValid = false;
635  // error message
636  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a beta-NMR asymmetry plot";
637  std::cerr << std::endl;
638  return;
639  }
640  // handle data
641  HandleDataSet(i, runNo, data);
642  break;
645  if (!data) { // something wrong
646  fValid = false;
647  // error message
648  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a asymmetry RRF plot";
649  std::cerr << std::endl;
650  return;
651  }
652  // handle data
653  HandleDataSet(i, runNo, data);
654  break;
657  if (!data) { // something wrong
658  fValid = false;
659  // error message
660  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a mu minus single histogram plot";
661  std::cerr << std::endl;
662  return;
663  }
664  // handle data
665  HandleDataSet(i, runNo, data);
666  break;
669  if (!data) { // something wrong
670  fValid = false;
671  // error message
672  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a none musr data plot";
673  std::cerr << std::endl;
674  return;
675  }
676  // handle data
677  HandleNonMusrDataSet(i, runNo, data);
678  if (!fBatchMode) {
679  // disable Fourier menus
687  }
688  break;
689  default:
690  fValid = false;
691  // error message
692  std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** wrong plottype tag?!";
693  std::cerr << std::endl;
694  return;
695  break;
696  }
697  }
698 
699  // generate the histo plot
701  PlotData();
702  } else { // show Fourier straight ahead.
703  // set the menu properly
704  if (!fBatchMode)
706 
707  // filter proper Fourier plot tag, and set the menu tags properly
708  switch (fFourier.fPlotTag) {
709  case FOURIER_PLOT_REAL:
711  if (!fBatchMode) {
715  }
716  break;
717  case FOURIER_PLOT_IMAG:
719  if (!fBatchMode) {
723  }
724  break;
727  if (!fBatchMode) {
731  }
732  break;
733  case FOURIER_PLOT_POWER:
735  if (!fBatchMode) {
737  }
738  break;
739  case FOURIER_PLOT_PHASE:
741  if (!fBatchMode) {
743  }
744  break;
747  if (!fBatchMode) {
749  }
750  break;
751  default:
753  if (!fBatchMode) {
755  }
756  break;
757  }
758 
759  HandleFourier();
760  PlotFourier();
761  }
762 
763  // if fStartWithAvg=true, start with averaged data/Fourier representation
764  // fStartWithAvg is given at the command line level
765  if (fStartWithAvg) {
766  HandleCmdKey(kKeyPress, (Int_t)'a', 0, 0);
767  }
768 }
769 
770 //--------------------------------------------------------------------------
771 // UpdateInfoPad (public)
772 //--------------------------------------------------------------------------
777 {
778  if (!fValid)
779  return;
780 
782  TString tstr, tsubstr;
783 
784  tstr = "musrfit: ";
785 
786  // get fit date
787  tstr += statistic.fDate;
788  tstr += TString(", ");
789 
790  // get chisq if not a max likelihood fit
791  if (statistic.fChisq) { // chisq
792  tstr += TString("chisq = ");
793  } else { // max. likelihood
794  tstr += TString("maxLH = ");
795  }
796  tstr += statistic.fMin;
797  tstr += TString(" , NDF = ");
798  tstr += statistic.fNdf;
799  if (statistic.fChisq) { // chisq
800  tstr += TString(" , chisq/NDF = ");
801  } else { // max. likelihood
802  tstr += TString(" , maxLH/NDF = ");
803  }
804  if (statistic.fNdf != 0) {
805  tstr += statistic.fMin/statistic.fNdf;
806  } else {
807  tstr += TString("undefined");
808  }
809 
810  fInfoPad->SetHeader(tstr);
811 
812  // get/set run plot info
813  double dval;
814  const PDoublePairVector *ddvec;
815  Char_t sval[128];
816  UInt_t runNo;
819  for (UInt_t i=0; i<fData.size(); i++) {
820  // run label = run_name/histo/T=0K/B=0G/E=0keV/...
821  runNo = (UInt_t)plotInfo.fRuns[i]-1;
822  if (runs[runNo].GetRunNameSize() > 1)
823  tstr = "++" + *runs[runNo].GetRunName() + TString(","); // run_name
824  else
825  tstr = *runs[runNo].GetRunName() + TString(","); // run_name
826  // histo info (depending on the fittype
827  if ((runs[runNo].GetFitType() == MSR_FITTYPE_SINGLE_HISTO) ||
828  (runs[runNo].GetFitType() == MSR_FITTYPE_SINGLE_HISTO_RRF)) {
829  tstr += TString("h:");
830  TString grouping;
831  fMsrHandler->GetGroupingString(runNo, "forward", grouping);
832  tstr += grouping;
833  tstr += TString(",");
834  } else if ((runs[runNo].GetFitType() == MSR_FITTYPE_ASYM) ||
835  (runs[runNo].GetFitType() == MSR_FITTYPE_ASYM_RRF) ||
836  (runs[runNo].GetFitType() == MSR_FITTYPE_BNMR)) {
837  tstr += TString("h:");
838  TString grouping;
839  fMsrHandler->GetGroupingString(runNo, "forward", grouping);
840  tstr += grouping;
841  tstr += TString("/");
842  grouping = "";
843  fMsrHandler->GetGroupingString(runNo, "backward", grouping);
844  tstr += grouping;
845  tstr += TString(",");
846  }
847  // temperature if present
848  ddvec = fRunList->GetTemp(*runs[runNo].GetRunName());
849  if (ddvec->empty()) {
850  tstr += TString("T=");
851  tstr += TString("??,");
852  } else if (ddvec->size() == 1){
853  tstr += TString("T=");
854  snprintf(sval, sizeof(sval), "%0.2lf", ddvec->at(0).first);
855  tstr += TString(sval) + TString("K,");
856  } else {
857  for(UInt_t i(0); i<ddvec->size(); ++i){
858  snprintf(sval, sizeof(sval), "T%u=", i);
859  tstr += TString(sval);
860  snprintf(sval, sizeof(sval), "%0.2lf", ddvec->at(i).first);
861  tstr += TString(sval) + TString("K,");
862  }
863  }
864  // field if present
865  tstr += TString("B=");
866  dval = fRunList->GetField(*runs[runNo].GetRunName());
867  if (dval == PMUSR_UNDEFINED) {
868  tstr += TString("??,");
869  } else {
870  if (dval < 1.0e4) { // Gauss makes sense as a unit
871  snprintf(sval, sizeof(sval), "%0.2lf", dval);
872  tstr += TString(sval) + TString("G,");
873  } else { // Tesla makes sense as a unit
874  snprintf(sval, sizeof(sval), "%0.2lf", dval/1.0e4);
875  tstr += TString(sval) + TString("T,");
876  }
877  }
878  // energy if present
879  tstr += TString("E=");
880  dval = fRunList->GetEnergy(*runs[runNo].GetRunName());
881  if (dval == PMUSR_UNDEFINED) {
882  tstr += TString("??,");
883  } else {
884  if (dval < 1.0e3) { // keV makes sense as a unit
885  snprintf(sval, sizeof(sval), "%0.2lf", dval);
886  tstr += TString(sval) + TString("keV,");
887  } else { // MeV makes sense as a unit
888  snprintf(sval, sizeof(sval), "%0.2lf", dval/1.0e3);
889  tstr += TString(sval) + TString("MeV,");
890  }
891  }
892  // setup if present
893  tstr += fRunList->GetSetup(*runs[runNo].GetRunName());
894  // add entry
895  fInfoPad->AddEntry(fData[i].data, tstr.Data(), "p");
896  }
897 
898  fInfoPad->Draw();
899  fMainCanvas->cd();
900  fMainCanvas->Update();
901 }
902 
903 //--------------------------------------------------------------------------
904 // Done (SIGNAL)
905 //--------------------------------------------------------------------------
912 {
913  Emit("Done(Int_t)", status);
914 }
915 
916 //--------------------------------------------------------------------------
917 // HandleCmdKey (SLOT)
918 //--------------------------------------------------------------------------
935 void PMusrCanvas::HandleCmdKey(Int_t event, Int_t x, Int_t y, TObject *selected)
936 {
937  if (event != kKeyPress)
938  return;
939 
940  if (fBatchMode) {
941  if (fStartWithAvg) { // this is needed to get the averaging in the batch mode
942  HandleAverage();
943  PlotAverage(true);
944  }
945  return;
946  }
947 
948  // handle keys and popup menu entries
949  enum eKeySwitch {kNotRelevant, kData, kDiffData, kFourier, kDiffFourier, kFourierDiff};
950  eKeySwitch relevantKeySwitch = kNotRelevant;
951  static eKeySwitch lastKeySwitch = kNotRelevant;
952 
953  if ((lastKeySwitch == kFourierDiff) && (x == 'f')) {
954  std::cout << "**INFO** f-d-f doesn't make any sense, will ignore 'f' ..." << std::endl;
955  return;
956  }
957 
958  if ((lastKeySwitch == kDiffFourier) && (x == 'd')) {
959  std::cout << "**INFO** d-f-d doesn't make any sense, will ignore 'd' ..." << std::endl;
960  return;
961  }
962 
963  if (x == 'q') { // quit
964  Done(0);
965  } else if (x == 'd') { // difference
966  // update previous plot view
968  // toggle difference tag
970  // set the popup menu entry properly
971  if (fDifferenceView) {
973  } else {
975  }
976  // check which relevantKeySwitch is needed
978  relevantKeySwitch = kDiffData;
979  else if ((fCurrentPlotView == PV_DATA) && !fDifferenceView)
980  relevantKeySwitch = kData;
981  else if ((fCurrentPlotView != PV_DATA) && fDifferenceView)
982  relevantKeySwitch = kFourierDiff;
983  else if ((fCurrentPlotView != PV_DATA) && !fDifferenceView)
984  relevantKeySwitch = kFourier;
985  } else if (x == 'u') { // unzoom to the original range
986  // update previous plot view
990  CleanupFourier();
991  PlotData(true);
992  } else if ((fCurrentPlotView == PV_DATA) && fDifferenceView) {
995  PlotDifference(true);
996  } else if ((fCurrentPlotView != PV_DATA) && !fDifferenceView) {
997  HandleFourier();
998  PlotFourier(true);
999  } else if ((fCurrentPlotView != PV_DATA) && fDifferenceView) {
1001  PlotFourierDifference(true);
1002  }
1003  } else if (x == 'f') { // Fourier
1004  // check which relevantKeySwitch is needed
1006  relevantKeySwitch = kDiffFourier;
1007  else if ((fCurrentPlotView == PV_DATA) && !fDifferenceView)
1008  relevantKeySwitch = kFourier;
1009  else if ((fCurrentPlotView != PV_DATA) && fDifferenceView)
1010  relevantKeySwitch = kDiffData;
1011  else if ((fCurrentPlotView != PV_DATA) && !fDifferenceView)
1012  relevantKeySwitch = kData;
1013 
1014  if (fCurrentPlotView == PV_DATA) { // current view is data view
1015  // uncheck data popup entry
1017  // get default fourier tag and update fourier popup menu
1018  switch (fFourier.fPlotTag) {
1019  case FOURIER_PLOT_REAL:
1023  break;
1024  case FOURIER_PLOT_IMAG:
1028  break;
1033  break;
1034  case FOURIER_PLOT_POWER:
1038  break;
1039  case FOURIER_PLOT_PHASE:
1043  break;
1048  break;
1049  default:
1050  break;
1051  }
1052  } else { // current view is one of the Fourier views
1053  // set the current plot view to data
1056  // uncheck all fourier popup menu items
1057  fPopupFourier->UnCheckEntries();
1058  // check the data entry
1060  }
1061  } else if (x == '+') {
1062  if (fCurrentPlotView != PV_DATA)
1064  } else if (x == '-') {
1065  if (fCurrentPlotView != PV_DATA)
1067  } else if (x == 'a') {
1068  if (fData.size() > 1) {
1069  // toggle average view flag
1071  // update menu
1072  if (fAveragedView) {
1074  HandleAverage();
1075  PlotAverage(true);
1076  } else {
1078  CleanupAverage();
1079  }
1080  // check which relevantKeySwitch is needed
1082  relevantKeySwitch = kDiffData;
1083  else if ((fCurrentPlotView == PV_DATA) && !fDifferenceView && !fAveragedView)
1084  relevantKeySwitch = kData;
1086  relevantKeySwitch = kFourierDiff;
1087  else if ((fCurrentPlotView != PV_DATA) && !fDifferenceView && !fAveragedView)
1088  relevantKeySwitch = kFourier;
1089  } else { // with only 1 data set, it doesn't make any sense to average!
1090  std::cout << "**INFO** averaging of a single data set doesn't make any sense, will ignore 'a' ..." << std::endl;
1091  return;
1092  }
1093  } else if (x == 'c') {
1094  Int_t state = fDataTheoryPad->GetCrosshair();
1095  if (state == 0) {
1096  fMainCanvas->ToggleEventStatus();
1097  fDataTheoryPad->SetCrosshair(2);
1098  } else {
1099  fMainCanvas->ToggleEventStatus();
1100  fDataTheoryPad->SetCrosshair(0);
1101  }
1102  fMainCanvas->Update();
1103  } else if (x == 't') { // toggle theory color
1104  if (fData.size() == 1) { // only do something if there is a single data set
1106  if (fToggleColor) {
1107  fData[0].theory->SetLineColor(kRed);
1108  fData[0].theory->SetLineWidth(2);
1109  } else {
1110  fData[0].theory->SetLineColor(fColorList[0]);
1111  fData[0].theory->SetLineWidth(1);
1112  }
1113  fDataTheoryPad->Modified();
1114  fMainCanvas->Update();
1115  }
1116  } else {
1117  fMainCanvas->Update();
1118  }
1119 
1120  lastKeySwitch = relevantKeySwitch;
1121 
1122  // call the apropriate functions if necessary
1123  switch (relevantKeySwitch) {
1124  case kData: // show data
1126  CleanupFourier();
1127  PlotData();
1128  break;
1129  case kDiffData: // show difference between data and theory
1131  HandleDifference();
1132  PlotDifference();
1133  break;
1134  case kFourier: // show Fourier transfrom of the data
1135  HandleFourier();
1136  PlotFourier();
1137  break;
1138  case kDiffFourier: // show Fourier transform of the difference data
1141  break;
1142  case kFourierDiff: // show difference between the Fourier data and the Fourier theory
1145  break;
1146  default:
1147  break;
1148  }
1149 
1150  // check if phase increment/decrement needs to be ghost
1151  if (fCurrentPlotView == PV_DATA) {
1154  } else {
1157  }
1158 }
1159 
1160 //--------------------------------------------------------------------------
1161 // HandleMenuPopup (SLOT)
1162 //--------------------------------------------------------------------------
1169 {
1170  if (fBatchMode)
1171  return;
1172 
1173  static Int_t previousPlotView = PV_DATA;
1174 
1176  // set appropriate plot view
1179  // check data item
1180  fPopupMain->CheckEntry(id);
1181  // uncheck fourier popup items
1182  fPopupFourier->UnCheckEntries();
1183  // call data handling routine
1184  if (!fDifferenceView) {
1186  CleanupFourier();
1187  PlotData();
1188  } else {
1189  HandleDifference();
1190  PlotDifference();
1191  }
1193  // set appropriate plot view
1196  // uncheck data
1198  // check appropriate fourier popup item
1199  fPopupFourier->UnCheckEntries();
1200  fPopupFourier->CheckEntry(id);
1201  // enable phase increment/decrement
1204  // handle fourier real
1205  if (!fDifferenceView) {
1206  HandleFourier();
1207  PlotFourier();
1208  } else {
1209  if (previousPlotView == PV_DATA)
1211  else
1214  }
1216  // set appropriate plot view
1219  // uncheck data
1221  // check appropriate fourier popup item
1222  fPopupFourier->UnCheckEntries();
1223  fPopupFourier->CheckEntry(id);
1224  // enable phase increment/decrement
1227  // handle fourier imag
1228  if (!fDifferenceView) {
1229  HandleFourier();
1230  PlotFourier();
1231  } else {
1232  if (previousPlotView == PV_DATA)
1234  else
1237  }
1239  // set appropriate plot view
1242  // uncheck data
1244  // check appropriate fourier popup item
1245  fPopupFourier->UnCheckEntries();
1246  fPopupFourier->CheckEntry(id);
1247  // enable phase increment/decrement
1250  // handle fourier real and imag
1251  if (!fDifferenceView) {
1252  HandleFourier();
1253  PlotFourier();
1254  } else {
1255  if (previousPlotView == PV_DATA)
1257  else
1260  }
1262  // set appropriate plot view
1265  // uncheck data
1267  // check appropriate fourier popup item
1268  fPopupFourier->UnCheckEntries();
1269  fPopupFourier->CheckEntry(id);
1270  // enable phase increment/decrement
1273  // handle fourier power
1274  if (!fDifferenceView) {
1275  HandleFourier();
1276  PlotFourier();
1277  } else {
1278  if (previousPlotView == PV_DATA)
1280  else
1283  }
1285  // set appropriate plot view
1288  // uncheck data
1290  // check appropriate fourier popup item
1291  fPopupFourier->UnCheckEntries();
1292  fPopupFourier->CheckEntry(id);
1293  // enable phase increment/decrement
1296  // handle fourier phase
1297  if (!fDifferenceView) {
1298  HandleFourier();
1299  PlotFourier();
1300  } else {
1301  if (previousPlotView == PV_DATA)
1303  else
1306  }
1308  // set appropriate plot view
1311  // make sure that phase opt. real indeed exists
1312  if (fData[0].dataFourierPhaseOptReal == nullptr) {
1313  if (fData[0].dataFourierRe == nullptr)
1314  HandleFourier();
1315  else
1316  CalcPhaseOptReFT();
1317  }
1318  // uncheck data
1320  // check appropriate fourier popup item
1321  fPopupFourier->UnCheckEntries();
1322  fPopupFourier->CheckEntry(id);
1323  // enable phase increment/decrement
1326  // handle fourier phase
1327  if (!fDifferenceView) {
1328  HandleFourier();
1329  PlotFourier();
1330  } else {
1331  if (previousPlotView == PV_DATA)
1333  else
1336  }
1342  // toggle difference tag
1344  // set the popup menu entry properly
1345  if (fDifferenceView) {
1346  fPopupMain->CheckEntry(id);
1347  } else {
1348  fPopupMain->UnCheckEntry(id);
1349  }
1350  // handle data, diff, Fourier
1351  if (fDifferenceView) {
1352  switch (fCurrentPlotView) {
1353  case PV_DATA:
1355  HandleDifference();
1356  PlotDifference();
1357  break;
1358  case PV_FOURIER_REAL:
1359  case PV_FOURIER_IMAG:
1361  case PV_FOURIER_PWR:
1362  case PV_FOURIER_PHASE:
1367  } else {
1371  }
1372  break;
1373  default:
1374  break;
1375  }
1376  } else { // not a difference view
1377  switch (fCurrentPlotView) {
1378  case PV_DATA:
1380  CleanupFourier();
1381  PlotData();
1382  break;
1383  case PV_FOURIER_REAL:
1384  case PV_FOURIER_IMAG:
1386  case PV_FOURIER_PWR:
1387  case PV_FOURIER_PHASE:
1388  HandleFourier();
1389  PlotFourier();
1390  break;
1391  default:
1392  break;
1393  }
1394  }
1396  if (fData.size() > 1) {
1398  // set the popup menu entry properly
1399  if (fAveragedView) {
1400  fPopupMain->CheckEntry(id);
1401  HandleAverage();
1402  PlotAverage();
1403  } else {
1404  fPopupMain->UnCheckEntry(id);
1405  CleanupAverage();
1406  }
1407  } else {
1408  std::cout << "**INFO** averaging of a single data set doesn't make any sense, will ignore 'a' ..." << std::endl;
1409  return;
1410  }
1412  static TString dir(".");
1413  TGFileInfo fi;
1414  fi.fFileTypes = gFiletypes;
1415  fi.fIniDir = StrDup(dir);
1416  fi.fOverwrite = true;
1417  new TGFileDialog(0, fImp, kFDSave, &fi);
1418  if (fi.fFilename && strlen(fi.fFilename)) {
1419  ExportData(fi.fFilename);
1420  }
1421  }
1422 
1423  // check if phase increment/decrement needs to be ghost
1424  if (fCurrentPlotView == PV_DATA) {
1427  } else {
1430  }
1431 
1432  // keep plot view setting
1433  previousPlotView = fCurrentPlotView;
1434 }
1435 
1436 //--------------------------------------------------------------------------
1437 // LastCanvasClosed (SLOT)
1438 //--------------------------------------------------------------------------
1444 {
1445 // std::cerr << ">> in last canvas closed check. gROOT->GetListOfCanvases()->GetEntries()=" << gROOT->GetListOfCanvases()->GetEntries() << std::endl;
1446  if (gROOT->GetListOfCanvases()->IsEmpty()) {
1447  Done(0);
1448  }
1449 }
1450 
1451 //--------------------------------------------------------------------------
1452 // WindowClosed (SLOT)
1453 //--------------------------------------------------------------------------
1458 {
1459 // std::cerr << ">> fMainCanvas->GetName()=" << fMainCanvas->GetName() << std::endl;
1460  gROOT->GetListOfCanvases()->Remove(fMainCanvas.get());
1461  LastCanvasClosed();
1462 }
1463 
1464 //--------------------------------------------------------------------------
1465 // SaveGraphicsAndQuit
1466 //--------------------------------------------------------------------------
1473 void PMusrCanvas::SaveGraphicsAndQuit(Char_t *fileName, Char_t *graphicsFormat)
1474 {
1475  std::cout << std::endl << ">> SaveGraphicsAndQuit: will dump the canvas into a graphics output file (" << graphicsFormat << ") ..."<< std::endl;
1476 
1477  TString str(fileName);
1478  Int_t idx = -1;
1479  Int_t size = 0;
1480  Char_t ext[32];
1481 
1482  if (str.Contains(".msr")) {
1483  idx = str.Index(".msr");
1484  size = 4;
1485  }
1486  if (str.Contains(".mlog")) {
1487  idx = str.Index(".mlog");
1488  size = 5;
1489  }
1490 
1491  if (idx == -1) {
1492  std::cerr << std::endl << ">> PMusrCanvas::SaveGraphicsAndQuit(): **ERROR** fileName (" << fileName << ") is invalid." << std::endl;
1493  return;
1494  }
1495 
1496  if (fStartWithFourier)
1497  snprintf(ext, sizeof(ext), "_%d_F", fPlotNumber);
1498  else
1499  snprintf(ext, sizeof(ext), "_%d", fPlotNumber);
1500  str.Replace(idx, size, ext, strlen(ext));
1501  idx += strlen(ext);
1502  size = strlen(ext);
1503  snprintf(ext, sizeof(ext), ".%s", graphicsFormat);
1504  str.Replace(idx, size, ext, strlen(ext));
1505 
1506  std::cout << std::endl << ">> SaveGraphicsAndQuit: " << str.Data() << std::endl;
1507 
1508  fMainCanvas->SaveAs(str.Data());
1509 
1510  if (fPlotNumber == static_cast<Int_t>(fMsrHandler->GetMsrPlotList()->size()) - 1)
1511  Done(0);
1512 }
1513 
1514 //--------------------------------------------------------------------------
1515 // ExportData
1516 //--------------------------------------------------------------------------
1522 void PMusrCanvas::ExportData(const Char_t *fileName)
1523 {
1524  if (fileName == nullptr) { // path file name NOT provided, generate a default path file name
1525  std::cerr << std::endl << ">> PMusrCanvas::ExportData(): **ERROR** NO path file name provided. Will do nothing." << std::endl;
1526  return;
1527  }
1528 
1529  // collect relevant data
1530  PMusrCanvasAsciiDump dump;
1531  PMusrCanvasAsciiDumpVector dumpVector;
1532 
1533  Int_t xminBin;
1534  Int_t xmaxBin;
1535  Double_t xmin;
1536  Double_t xmax;
1537  Double_t xval, yval;
1538 
1539  switch (fPlotType) {
1540  case MSR_PLOT_SINGLE_HISTO:
1542  case MSR_PLOT_ASYM:
1543  case MSR_PLOT_BNMR:
1544  case MSR_PLOT_ASYM_RRF:
1545  case MSR_PLOT_MU_MINUS:
1546  if (fDifferenceView) { // difference view plot
1547  switch (fCurrentPlotView) {
1548  case PV_DATA:
1549  // get current x-range
1550  xminBin = fHistoFrame->GetXaxis()->GetFirst(); // first bin of the zoomed range
1551  xmaxBin = fHistoFrame->GetXaxis()->GetLast(); // last bin of the zoomed range
1552  xmin = fHistoFrame->GetXaxis()->GetBinCenter(xminBin);
1553  xmax = fHistoFrame->GetXaxis()->GetBinCenter(xmaxBin);
1554 
1555  // fill ascii dump data
1556  if (fAveragedView) {
1557  GetExportDataSet(fDataAvg.diff, xmin, xmax, dumpVector);
1558  } else { // go through all the histogramms
1559  for (UInt_t i=0; i<fData.size(); i++) { // go through all the histogramms
1560  GetExportDataSet(fData[i].diff, xmin, xmax, dumpVector);
1561  }
1562  }
1563  break;
1564  case PV_FOURIER_REAL:
1565  // get current x-range
1566  xminBin = fData[0].diffFourierRe->GetXaxis()->GetFirst(); // first bin of the zoomed range
1567  xmaxBin = fData[0].diffFourierRe->GetXaxis()->GetLast(); // last bin of the zoomed range
1568  xmin = fData[0].diffFourierRe->GetXaxis()->GetBinCenter(xminBin);
1569  xmax = fData[0].diffFourierRe->GetXaxis()->GetBinCenter(xmaxBin);
1570 
1571  // fill ascii dump data
1572  if (fAveragedView) {
1573  GetExportDataSet(fDataAvg.diffFourierRe, xmin, xmax, dumpVector, false);
1574  } else { // go through all the histogramms
1575  for (UInt_t i=0; i<fData.size(); i++) { // go through all the histogramms
1576  GetExportDataSet(fData[i].diffFourierRe, xmin, xmax, dumpVector, false);
1577  }
1578  }
1579  break;
1580  case PV_FOURIER_IMAG:
1581  // get current x-range
1582  xminBin = fData[0].diffFourierIm->GetXaxis()->GetFirst(); // first bin of the zoomed range
1583  xmaxBin = fData[0].diffFourierIm->GetXaxis()->GetLast(); // last bin of the zoomed range
1584  xmin = fData[0].diffFourierIm->GetXaxis()->GetBinCenter(xminBin);
1585  xmax = fData[0].diffFourierIm->GetXaxis()->GetBinCenter(xmaxBin);
1586 
1587  // fill ascii dump data
1588  if (fAveragedView) {
1589  GetExportDataSet(fDataAvg.diffFourierIm, xmin, xmax, dumpVector, false);
1590  } else { // go through all the histogramms
1591  for (UInt_t i=0; i<fData.size(); i++) { // go through all the histogramms
1592  GetExportDataSet(fData[i].diffFourierIm, xmin, xmax, dumpVector, false);
1593  }
1594  }
1595  break;
1597  // get current x-range
1598  xminBin = fData[0].diffFourierRe->GetXaxis()->GetFirst(); // first bin of the zoomed range
1599  xmaxBin = fData[0].diffFourierRe->GetXaxis()->GetLast(); // last bin of the zoomed range
1600  xmin = fData[0].diffFourierRe->GetXaxis()->GetBinCenter(xminBin);
1601  xmax = fData[0].diffFourierRe->GetXaxis()->GetBinCenter(xmaxBin);
1602 
1603  // fill ascii dump data
1604  if (fAveragedView) {
1605  GetExportDataSet(fDataAvg.diffFourierRe, xmin, xmax, dumpVector, false);
1606  GetExportDataSet(fDataAvg.diffFourierIm, xmin, xmax, dumpVector, false);
1607  } else { // go through all the histogramms
1608  for (UInt_t i=0; i<fData.size(); i++) { // go through all the histogramms
1609  GetExportDataSet(fData[i].diffFourierRe, xmin, xmax, dumpVector, false);
1610  GetExportDataSet(fData[i].diffFourierIm, xmin, xmax, dumpVector, false);
1611  }
1612  }
1613  break;
1614  case PV_FOURIER_PWR:
1615  // get current x-range
1616  xminBin = fData[0].diffFourierPwr->GetXaxis()->GetFirst(); // first bin of the zoomed range
1617  xmaxBin = fData[0].diffFourierPwr->GetXaxis()->GetLast(); // last bin of the zoomed range
1618  xmin = fData[0].diffFourierPwr->GetXaxis()->GetBinCenter(xminBin);
1619  xmax = fData[0].diffFourierPwr->GetXaxis()->GetBinCenter(xmaxBin);
1620 
1621  // fill ascii dump data
1622  if (fAveragedView) {
1623  GetExportDataSet(fDataAvg.diffFourierPwr, xmin, xmax, dumpVector, false);
1624  } else { // go through all the histogramms
1625  for (UInt_t i=0; i<fData.size(); i++) {
1626  GetExportDataSet(fData[i].diffFourierPwr, xmin, xmax, dumpVector, false);
1627  }
1628  }
1629  break;
1630  case PV_FOURIER_PHASE:
1631  // get current x-range
1632  xminBin = fData[0].diffFourierPhase->GetXaxis()->GetFirst(); // first bin of the zoomed range
1633  xmaxBin = fData[0].diffFourierPhase->GetXaxis()->GetLast(); // last bin of the zoomed range
1634  xmin = fData[0].diffFourierPhase->GetXaxis()->GetBinCenter(xminBin);
1635  xmax = fData[0].diffFourierPhase->GetXaxis()->GetBinCenter(xmaxBin);
1636 
1637  // fill ascii dump data
1638  if (fAveragedView) {
1639  GetExportDataSet(fDataAvg.diffFourierPhase, xmin, xmax, dumpVector, false);
1640  } else { // go through all the histogramms
1641  for (UInt_t i=0; i<fData.size(); i++) {
1642  GetExportDataSet(fData[i].diffFourierPhase, xmin, xmax, dumpVector, false);
1643  }
1644  }
1645  break;
1646  default:
1647  break;
1648  }
1649  } else { // not a difference view plot
1650  switch (fCurrentPlotView) {
1651  case PV_DATA:
1652  // get current x-range
1653  xminBin = fHistoFrame->GetXaxis()->GetFirst(); // first bin of the zoomed range
1654  xmaxBin = fHistoFrame->GetXaxis()->GetLast(); // last bin of the zoomed range
1655  xmin = fHistoFrame->GetXaxis()->GetBinCenter(xminBin);
1656  xmax = fHistoFrame->GetXaxis()->GetBinCenter(xmaxBin);
1657 
1658  // fill ascii dump data
1659  if (fAveragedView) {
1660  GetExportDataSet(fDataAvg.data, xmin, xmax, dumpVector);
1661  GetExportDataSet(fDataAvg.theory, xmin, xmax, dumpVector, false);
1662  } else { // go through all the histogramms
1663  for (UInt_t i=0; i<fData.size(); i++) {
1664  GetExportDataSet(fData[i].data, xmin, xmax, dumpVector);
1665  GetExportDataSet(fData[i].theory, xmin, xmax, dumpVector, false);
1666  }
1667  }
1668 
1669  break;
1670  case PV_FOURIER_REAL:
1671  // get current x-range
1672  xminBin = fData[0].dataFourierRe->GetXaxis()->GetFirst(); // first bin of the zoomed range
1673  xmaxBin = fData[0].dataFourierRe->GetXaxis()->GetLast(); // last bin of the zoomed range
1674  xmin = fData[0].dataFourierRe->GetXaxis()->GetBinCenter(xminBin);
1675  xmax = fData[0].dataFourierRe->GetXaxis()->GetBinCenter(xmaxBin);
1676 
1677  // fill ascii dump data
1678  if (fAveragedView) {
1679  GetExportDataSet(fDataAvg.dataFourierRe, xmin, xmax, dumpVector, false);
1680  GetExportDataSet(fDataAvg.theoryFourierRe, xmin, xmax, dumpVector, false);
1681  } else { // go through all the histogramms
1682  for (UInt_t i=0; i<fData.size(); i++) {
1683  GetExportDataSet(fData[i].dataFourierRe, xmin, xmax, dumpVector, false);
1684  GetExportDataSet(fData[i].theoryFourierRe, xmin, xmax, dumpVector, false);
1685  }
1686  }
1687  break;
1688  case PV_FOURIER_IMAG:
1689  // get current x-range
1690  xminBin = fData[0].dataFourierIm->GetXaxis()->GetFirst(); // first bin of the zoomed range
1691  xmaxBin = fData[0].dataFourierIm->GetXaxis()->GetLast(); // last bin of the zoomed range
1692  xmin = fData[0].dataFourierIm->GetXaxis()->GetBinCenter(xminBin);
1693  xmax = fData[0].dataFourierIm->GetXaxis()->GetBinCenter(xmaxBin);
1694 
1695  // fill ascii dump data
1696  if (fAveragedView) {
1697  GetExportDataSet(fDataAvg.dataFourierIm, xmin, xmax, dumpVector, false);
1698  GetExportDataSet(fDataAvg.theoryFourierIm, xmin, xmax, dumpVector, false);
1699  } else { // go through all the histogramms
1700  for (UInt_t i=0; i<fData.size(); i++) {
1701  GetExportDataSet(fData[i].dataFourierIm, xmin, xmax, dumpVector, false);
1702  GetExportDataSet(fData[i].theoryFourierIm, xmin, xmax, dumpVector, false);
1703  }
1704  }
1705  break;
1707  // get current x-range
1708  xminBin = fData[0].dataFourierRe->GetXaxis()->GetFirst(); // first bin of the zoomed range
1709  xmaxBin = fData[0].dataFourierRe->GetXaxis()->GetLast(); // last bin of the zoomed range
1710  xmin = fData[0].dataFourierRe->GetXaxis()->GetBinCenter(xminBin);
1711  xmax = fData[0].dataFourierRe->GetXaxis()->GetBinCenter(xmaxBin);
1712 
1713  if (fAveragedView) {
1714  GetExportDataSet(fDataAvg.dataFourierRe, xmin, xmax, dumpVector, false);
1715  GetExportDataSet(fDataAvg.theoryFourierRe, xmin, xmax, dumpVector, false);
1716  GetExportDataSet(fDataAvg.dataFourierIm, xmin, xmax, dumpVector, false);
1717  GetExportDataSet(fDataAvg.theoryFourierIm, xmin, xmax, dumpVector, false);
1718  } else { // go through all the histogramms
1719  for (UInt_t i=0; i<fData.size(); i++) {
1720  GetExportDataSet(fData[i].dataFourierRe, xmin, xmax, dumpVector, false);
1721  GetExportDataSet(fData[i].theoryFourierRe, xmin, xmax, dumpVector, false);
1722  GetExportDataSet(fData[i].dataFourierIm, xmin, xmax, dumpVector, false);
1723  GetExportDataSet(fData[i].theoryFourierIm, xmin, xmax, dumpVector, false);
1724  }
1725  }
1726  break;
1727  case PV_FOURIER_PWR:
1728  // get current x-range
1729  xminBin = fData[0].dataFourierPwr->GetXaxis()->GetFirst(); // first bin of the zoomed range
1730  xmaxBin = fData[0].dataFourierPwr->GetXaxis()->GetLast(); // last bin of the zoomed range
1731  xmin = fData[0].dataFourierPwr->GetXaxis()->GetBinCenter(xminBin);
1732  xmax = fData[0].dataFourierPwr->GetXaxis()->GetBinCenter(xmaxBin);
1733 
1734  // fill ascii dump data
1735  if (fAveragedView) {
1736  GetExportDataSet(fDataAvg.dataFourierPwr, xmin, xmax, dumpVector, false);
1737  GetExportDataSet(fDataAvg.theoryFourierPwr, xmin, xmax, dumpVector, false);
1738  } else { // go through all the histogramms
1739  for (UInt_t i=0; i<fData.size(); i++) {
1740  GetExportDataSet(fData[i].dataFourierPwr, xmin, xmax, dumpVector, false);
1741  GetExportDataSet(fData[i].theoryFourierPwr, xmin, xmax, dumpVector, false);
1742  }
1743  }
1744  break;
1745  case PV_FOURIER_PHASE:
1746  // get current x-range
1747  xminBin = fData[0].dataFourierPhase->GetXaxis()->GetFirst(); // first bin of the zoomed range
1748  xmaxBin = fData[0].dataFourierPhase->GetXaxis()->GetLast(); // last bin of the zoomed range
1749  xmin = fData[0].dataFourierPhase->GetXaxis()->GetBinCenter(xminBin);
1750  xmax = fData[0].dataFourierPhase->GetXaxis()->GetBinCenter(xmaxBin);
1751 
1752  // fill ascii dump data
1753  if (fAveragedView) {
1754  GetExportDataSet(fDataAvg.dataFourierPhase, xmin, xmax, dumpVector, false);
1755  GetExportDataSet(fDataAvg.theoryFourierPhase, xmin, xmax, dumpVector, false);
1756  } else { // go through all the histogramms
1757  for (UInt_t i=0; i<fData.size(); i++) {
1758  GetExportDataSet(fData[i].dataFourierPhase, xmin, xmax, dumpVector, false);
1759  GetExportDataSet(fData[i].theoryFourierPhase, xmin, xmax, dumpVector, false);
1760  }
1761  }
1762  break;
1764  // get current x-range
1765  xminBin = fData[0].dataFourierPhaseOptReal->GetXaxis()->GetFirst(); // first bin of the zoomed range
1766  xmaxBin = fData[0].dataFourierPhaseOptReal->GetXaxis()->GetLast(); // last bin of the zoomed range
1767  xmin = fData[0].dataFourierPhaseOptReal->GetXaxis()->GetBinCenter(xminBin);
1768  xmax = fData[0].dataFourierPhaseOptReal->GetXaxis()->GetBinCenter(xmaxBin);
1769 
1770  // fill ascii dump data
1771  if (fAveragedView) {
1772  GetExportDataSet(fDataAvg.dataFourierPhaseOptReal, xmin, xmax, dumpVector, false);
1773  GetExportDataSet(fDataAvg.theoryFourierPhaseOptReal, xmin, xmax, dumpVector, false);
1774  } else { // go through all the histogramms
1775  for (UInt_t i=0; i<fData.size(); i++) {
1776  GetExportDataSet(fData[i].dataFourierPhaseOptReal, xmin, xmax, dumpVector, false);
1777  GetExportDataSet(fData[i].theoryFourierPhaseOptReal, xmin, xmax, dumpVector, false);
1778  }
1779  }
1780  break;
1781  default:
1782  break;
1783  }
1784  }
1785  break;
1786  case MSR_PLOT_NON_MUSR:
1787  if (fDifferenceView) { // difference view plot
1788  switch (fCurrentPlotView) {
1789  case PV_DATA:
1790  // get current x-range
1791  xminBin = fMultiGraphData->GetXaxis()->GetFirst(); // first bin of the zoomed range
1792  xmaxBin = fMultiGraphData->GetXaxis()->GetLast(); // last bin of the zoomed range
1793  xmin = fMultiGraphData->GetXaxis()->GetBinCenter(xminBin);
1794  xmax = fMultiGraphData->GetXaxis()->GetBinCenter(xmaxBin);
1795 
1796  // fill ascii dump data
1797  for (UInt_t i=0; i<fNonMusrData.size(); i++) { // go through all the histogramms
1798  // clean up dump
1799  dump.dataX.clear();
1800  dump.data.clear();
1801  dump.dataErr.clear();
1802 
1803  // go through all data bins
1804  for (Int_t j=0; j<fNonMusrData[i].diff->GetN(); j++) {
1805  // get x and y value
1806  fNonMusrData[i].diff->GetPoint(j,xval,yval);
1807  // check if time is in the current range
1808  if ((xval >= xmin) && (xval <= xmax)) {
1809  dump.dataX.push_back(xval);
1810  dump.data.push_back(yval);
1811  dump.dataErr.push_back(fNonMusrData[i].diff->GetErrorY(j));
1812  }
1813  }
1814 
1815  // if anything found keep it
1816  if (dump.dataX.size() > 0)
1817  dumpVector.push_back(dump);
1818  }
1819 
1820  break;
1821  case PV_FOURIER_REAL:
1822  break;
1823  case PV_FOURIER_IMAG:
1824  break;
1826  break;
1827  case PV_FOURIER_PWR:
1828  break;
1829  case PV_FOURIER_PHASE:
1830  break;
1831  default:
1832  break;
1833  }
1834  } else { // not a difference view plot
1835  switch (fCurrentPlotView) {
1836  case PV_DATA:
1837  // get current x-range
1838  xminBin = fMultiGraphData->GetXaxis()->GetFirst(); // first bin of the zoomed range
1839  xmaxBin = fMultiGraphData->GetXaxis()->GetLast(); // last bin of the zoomed range
1840  xmin = fMultiGraphData->GetXaxis()->GetBinCenter(xminBin);
1841  xmax = fMultiGraphData->GetXaxis()->GetBinCenter(xmaxBin);
1842 
1843  // fill ascii dump data
1844  for (UInt_t i=0; i<fNonMusrData.size(); i++) { // go through all the graphs
1845  // clean up dump
1846  dump.dataX.clear();
1847  dump.data.clear();
1848  dump.dataErr.clear();
1849 
1850  // go through all data bins
1851  for (Int_t j=0; j<fNonMusrData[i].data->GetN(); j++) {
1852  // get x and y value
1853  fNonMusrData[i].data->GetPoint(j,xval,yval);
1854  // check if time is in the current range
1855  if ((xval >= xmin) && (xval <= xmax)) {
1856  dump.dataX.push_back(xval);
1857  dump.data.push_back(yval);
1858  dump.dataErr.push_back(fNonMusrData[i].data->GetErrorY(j));
1859  }
1860  }
1861 
1862  // if anything found keep it
1863  if (dump.dataX.size() > 0)
1864  dumpVector.push_back(dump);
1865 
1866  // clean up dump
1867  dump.dataX.clear();
1868  dump.data.clear();
1869  dump.dataErr.clear();
1870 
1871  // go through all theory bins
1872  for (Int_t j=0; j<fNonMusrData[i].theory->GetN(); j++) {
1873  // get x and y value
1874  fNonMusrData[i].theory->GetPoint(j,xval,yval);
1875  // check if time is in the current range
1876  if ((xval >= xmin) && (xval <= xmax)) {
1877  dump.dataX.push_back(xval);
1878  dump.data.push_back(yval);
1879  }
1880  }
1881 
1882  // if anything found keep it
1883  if (dump.dataX.size() > 0)
1884  dumpVector.push_back(dump);
1885  }
1886 
1887  break;
1888  case PV_FOURIER_REAL:
1889  break;
1890  case PV_FOURIER_IMAG:
1891  break;
1893  break;
1894  case PV_FOURIER_PWR:
1895  break;
1896  case PV_FOURIER_PHASE:
1897  break;
1898  default:
1899  break;
1900  }
1901  }
1902  break;
1903  default:
1904  break;
1905  }
1906 
1907  // open file
1908  std::ofstream fout;
1909 
1910  // open output data-file
1911  fout.open(fileName, std::iostream::out);
1912  if (!fout.is_open()) {
1913  std::cerr << std::endl << ">> PMusrCanvas::ExportData(): **ERROR** couldn't open file " << fileName << " for writing." << std::endl;
1914  return;
1915  }
1916 
1917  // find out what is the longest data/theory vector
1918  UInt_t maxLength = 0;
1919  for (UInt_t i=0; i<dumpVector.size(); i++) {
1920  if (maxLength < dumpVector[i].dataX.size())
1921  maxLength = dumpVector[i].dataX.size();
1922  }
1923 
1924  // write data to file
1925  if (fDifferenceView) { // difference view
1926  // write header
1927  switch (fCurrentPlotView) {
1928  case PV_DATA:
1929  if (fAveragedView) {
1930  fout << "% from averaged view" << std::endl;
1931  fout << "% x, diff, errDiff" << std::endl;
1932  } else {
1933  fout << "% ";
1934  for (UInt_t i=0; i<dumpVector.size()-1; i++) {
1935  fout << "x" << i << " , diff" << i << ", errDiff" << i << ", ";
1936  }
1937  fout << "x" << dumpVector.size()-1 << " , diff" << dumpVector.size()-1 << ", errDiff" << dumpVector.size()-1 << std::endl;
1938  }
1939  break;
1940  case PV_FOURIER_REAL:
1941  if (fAveragedView) {
1942  fout << "% from averaged view" << std::endl;
1943  fout << "% x, F_diffRe" << std::endl;
1944  } else {
1945  fout << "% ";
1946  for (UInt_t i=0; i<dumpVector.size()-1; i++) {
1947  fout << "freq" << i << ", F_diffRe" << i << ", ";
1948  }
1949  fout << "freq" << dumpVector.size()-1 << ", F_diffRe" << dumpVector.size()-1 << std::endl;
1950  }
1951  break;
1952  case PV_FOURIER_IMAG:
1953  if (fAveragedView) {
1954  fout << "% from averaged view" << std::endl;
1955  fout << "% x, F_diffIm" << std::endl;
1956  } else {
1957  fout << "% ";
1958  for (UInt_t i=0; i<dumpVector.size()-1; i++) {
1959  fout << "freq" << i << ", F_diffIm" << i << ", ";
1960  }
1961  fout << "freq" << dumpVector.size()-1 << ", F_diffIm" << dumpVector.size()-1 << std::endl;
1962  }
1963  break;
1965  if (fAveragedView) {
1966  fout << "% from averaged view" << std::endl;
1967  fout << "% x, F_diffRe, F_diffIm" << std::endl;
1968  } else {
1969  fout << "% ";
1970  for (UInt_t i=0; i<dumpVector.size()/2; i++) {
1971  fout << "freq" << i << ", F_diffRe" << i << ", ";
1972  }
1973  for (UInt_t i=0; i<dumpVector.size()/2-1; i++) {
1974  fout << "freq" << i << ", F_diffIm" << i << ", ";
1975  }
1976  fout << "freq" << dumpVector.size()/2-1 << ", F_diffIm" << dumpVector.size()/2-1 << std::endl;
1977  }
1978  break;
1979  case PV_FOURIER_PWR:
1980  if (fAveragedView) {
1981  fout << "% from averaged view" << std::endl;
1982  fout << "% x, F_diffPwr" << std::endl;
1983  } else {
1984  fout << "% ";
1985  for (UInt_t i=0; i<dumpVector.size()-1; i++) {
1986  fout << "freq" << i << ", F_diffPwr" << i << ", ";
1987  }
1988  fout << "freq" << dumpVector.size()-1 << ", F_diffPwr" << dumpVector.size()-1 << std::endl;
1989  }
1990  break;
1991  case PV_FOURIER_PHASE:
1992  if (fAveragedView) {
1993  fout << "% from averaged view" << std::endl;
1994  fout << "% x, F_diffPhase" << std::endl;
1995  } else {
1996  fout << "% ";
1997  for (UInt_t i=0; i<dumpVector.size()-1; i++) {
1998  fout << "freq" << i << ", F_diffPhase" << i << ", ";
1999  }
2000  fout << "freq" << dumpVector.size()-1 << ", F_diffPhase" << dumpVector.size()-1 << std::endl;
2001  }
2002  break;
2003  default:
2004  break;
2005  }
2006 
2007  // write difference data
2008  for (UInt_t i=0; i<maxLength; i++) {
2009  // write difference data
2010  for (UInt_t j=0; j<dumpVector.size()-1; j++) {
2011  if (i<dumpVector[j].dataX.size()) {
2012  fout << dumpVector[j].dataX[i] << ", ";
2013  fout << dumpVector[j].data[i] << ", ";
2014  if (dumpVector[j].dataErr.size() > 0)
2015  fout << dumpVector[j].dataErr[i] << ", ";
2016  } else {
2017  if (dumpVector[j].dataErr.size() > 0)
2018  fout << ", , , ";
2019  else
2020  fout << ", , ";
2021  }
2022  }
2023  // write last difference entry
2024  if (i<dumpVector[dumpVector.size()-1].dataX.size()) {
2025  fout << dumpVector[dumpVector.size()-1].dataX[i] << ", ";
2026  fout << dumpVector[dumpVector.size()-1].data[i] << ", ";
2027  if (dumpVector[dumpVector.size()-1].dataErr.size() > 0)
2028  fout << dumpVector[dumpVector.size()-1].dataErr[i];
2029  } else {
2030  if (dumpVector[dumpVector.size()-1].dataErr.size() > 0)
2031  fout << ", , ";
2032  else
2033  fout << ", ";
2034  }
2035  fout << std::endl;
2036  }
2037  } else { // no difference view
2038  // write header
2039  switch (fCurrentPlotView) {
2040  case PV_DATA:
2041  if (fAveragedView) {
2042  fout << "% from averaged view" << std::endl;
2043  fout << "% xData, data, errData, xTheory, theory" << std::endl;
2044  } else {
2045  fout << "% ";
2046  for (UInt_t i=0; i<dumpVector.size(); i++) {
2047  if (i % 2 == 0)
2048  fout << "xData" << i/2 << " , data" << i/2 << ", errData" << i/2 << ", ";
2049  else
2050  if (i == dumpVector.size()-1)
2051  fout << "xTheory" << (i-1)/2 << " , theory" << (i-1)/2 << std::endl;
2052  else
2053  fout << "xTheory" << (i-1)/2 << " , theory" << (i-1)/2 << ", ";
2054  }
2055  }
2056  break;
2057  case PV_FOURIER_REAL:
2058  if (fAveragedView) {
2059  fout << "% from averaged view" << std::endl;
2060  fout << "% freq, F_Re, freqTheo, F_theoRe" << std::endl;
2061  } else {
2062  fout << "% ";
2063  for (UInt_t i=0; i<dumpVector.size(); i++) {
2064  if (i % 2 == 0)
2065  fout << "freq" << i/2 << ", F_Re" << i/2 << ", ";
2066  else
2067  if (i == dumpVector.size()-1)
2068  fout << "freqTheo" << (i-1)/2 << ", F_theoRe" << (i-1)/2 << std::endl;
2069  else
2070  fout << "freqTheo" << (i-1)/2 << ", F_theoRe" << (i-1)/2 << ", ";
2071  }
2072  }
2073  break;
2074  case PV_FOURIER_IMAG:
2075  if (fAveragedView) {
2076  fout << "% from averaged view" << std::endl;
2077  fout << "% freq, F_Im, freqTheo, F_theoIm" << std::endl;
2078  } else {
2079  fout << "% ";
2080  for (UInt_t i=0; i<dumpVector.size(); i++) {
2081  if (i % 2 == 0)
2082  fout << "freq" << i/2 << ", F_Im" << i/2 << ", ";
2083  else
2084  if (i == dumpVector.size()-1)
2085  fout << "freqTheo" << (i-1)/2 << ", F_theoIm" << (i-1)/2 << std::endl;
2086  else
2087  fout << "freqTheo" << (i-1)/2 << ", F_theoIm" << (i-1)/2 << ", ";
2088  }
2089  }
2090  break;
2092  if (fAveragedView) {
2093  fout << "% from averaged view" << std::endl;
2094  fout << "% freq, F_Re, freqTheo, F_theoRe, freq, F_Im, freqTheo, F_theoIm" << std::endl;
2095  } else {
2096  fout << "% ";
2097  for (UInt_t i=0; i<dumpVector.size(); i++) {
2098  if (i % 4 == 0)
2099  fout << "freq" << i/4 << ", F_Re" << i/4 << ", ";
2100  else if (i % 4 == 1)
2101  fout << "freqTheo" << (i-1)/4 << ", F_theoRe" << (i-1)/4 << ", ";
2102  else if (i % 4 == 2)
2103  fout << "freq" << (i-2)/4 << ", F_Im" << (i-2)/4 << ", ";
2104  else
2105  if (i == dumpVector.size()-1)
2106  fout << "freqTheo" << (i-3)/4 << ", F_theoIm" << (i-3)/4 << std::endl;
2107  else
2108  fout << "freqTheo" << (i-3)/4 << ", F_theoIm" << (i-3)/4 << ", ";
2109  }
2110  }
2111  break;
2112  case PV_FOURIER_PWR:
2113  if (fAveragedView) {
2114  fout << "% from averaged view" << std::endl;
2115  fout << "% freq, F_Pwr, freqTheo, F_theoPwr" << std::endl;
2116  } else {
2117  fout << "% ";
2118  for (UInt_t i=0; i<dumpVector.size(); i++) {
2119  if (i % 2 == 0)
2120  fout << "freq" << i/2 << ", F_Pwr" << i/2 << ", ";
2121  else
2122  if (i == dumpVector.size()-1)
2123  fout << "freqTheo" << (i-1)/2 << ", F_theoPwr" << (i-1)/2 << std::endl;
2124  else
2125  fout << "freqTheo" << (i-1)/2 << ", F_theoPwr" << (i-1)/2 << ", ";
2126  }
2127  }
2128  break;
2129  case PV_FOURIER_PHASE:
2130  if (fAveragedView) {
2131  fout << "% from averaged view" << std::endl;
2132  fout << "% freq, F_Phase, freqTheo, F_theoPhase" << std::endl;
2133  } else {
2134  fout << "% ";
2135  for (UInt_t i=0; i<dumpVector.size(); i++) {
2136  if (i % 2 == 0)
2137  fout << "freq" << i/2 << ", F_Phase" << i/2 << ", ";
2138  else
2139  if (i == dumpVector.size()-1)
2140  fout << "freqTheo" << (i-1)/2 << ", F_theoPhase" << (i-1)/2 << std::endl;
2141  else
2142  fout << "freqTheo" << (i-1)/2 << ", F_theoPhase" << (i-1)/2 << ", ";
2143  }
2144  }
2145  break;
2146  default:
2147  break;
2148  }
2149 
2150  // write data and theory
2151  for (UInt_t i=0; i<maxLength; i++) {
2152  // write data/theory
2153  for (UInt_t j=0; j<dumpVector.size()-1; j++) {
2154  if (i<dumpVector[j].dataX.size()) {
2155  fout << std::setprecision(9) << dumpVector[j].dataX[i] << ", ";
2156  fout << std::setprecision(9) << dumpVector[j].data[i] << ", ";
2157  if (dumpVector[j].dataErr.size() > 0)
2158  fout << std::setprecision(9) << dumpVector[j].dataErr[i] << ", ";
2159  } else {
2160  if (dumpVector[j].dataErr.size() > 0)
2161  fout << " , , , ";
2162  else
2163  fout << " , , ";
2164  }
2165  }
2166  // write last data/theory entry
2167  if (i<dumpVector[dumpVector.size()-1].dataX.size()) {
2168  fout << std::setprecision(9) << dumpVector[dumpVector.size()-1].dataX[i] << ", ";
2169  fout << std::setprecision(9) << dumpVector[dumpVector.size()-1].data[i];
2170  } else {
2171  fout << " , ";
2172  }
2173  fout << std::endl;
2174  }
2175  }
2176 
2177  // close file
2178  fout.close();
2179 
2180  // clean up
2181  for (UInt_t i=0; i<dumpVector.size(); i++) {
2182  dumpVector[i].dataX.clear();
2183  dumpVector[i].data.clear();
2184  dumpVector[i].dataErr.clear();
2185  }
2186  dumpVector.clear();
2187 
2188  std::cout << std::endl << ">> Data windows saved in ascii format ..." << std::endl;
2189  // if (asciiOutput) {
2190  // if (fPlotNumber == static_cast<Int_t>(fMsrHandler->GetMsrPlotList()->size()) - 1)
2191  // Done(0);
2192  // }
2193 }
2194 
2195 //--------------------------------------------------------------------------
2196 // GetExportDataSet (private)
2197 //--------------------------------------------------------------------------
2207 void PMusrCanvas::GetExportDataSet(const TH1F *data, const Double_t xmin, const Double_t xmax,
2208  PMusrCanvasAsciiDumpVector &dumpData, const Bool_t hasError)
2209 {
2210  PMusrCanvasAsciiDump dump;
2211  Double_t x=0.0;
2212 
2213  // go through all difference data bins
2214  for (Int_t j=1; j<data->GetNbinsX(); j++) {
2215  // get time/freq
2216  x = data->GetBinCenter(j);
2217  // check if x is in the current range
2218  if ((x >= xmin) && (x <= xmax)) {
2219  dump.dataX.push_back(x);
2220  dump.data.push_back(data->GetBinContent(j));
2221  if (hasError)
2222  dump.dataErr.push_back(data->GetBinError(j));
2223  }
2224  }
2225 
2226  // if anything found keep it
2227  if (dump.dataX.size() > 0)
2228  dumpData.push_back(dump);
2229 }
2230 
2231 //--------------------------------------------------------------------------
2232 // CreateStyle (private)
2233 //--------------------------------------------------------------------------
2238 {
2239  TString musrStyle("musrStyle");
2240  musrStyle += fPlotNumber;
2241  fStyle = std::make_unique<TStyle>(musrStyle, musrStyle);
2242  fStyle->SetOptStat(0); // no statistics options
2243  fStyle->SetOptTitle(0); // no title
2244  fStyle->cd();
2245 }
2246 
2247 //--------------------------------------------------------------------------
2248 // InitFourier (private)
2249 //--------------------------------------------------------------------------
2254 {
2255  fFourier.fFourierBlockPresent = false; // fourier block present
2256  fFourier.fUnits = FOURIER_UNIT_GAUSS; // fourier untis
2257  fFourier.fFourierPower = 0; // no zero padding
2258  fFourier.fApodization = FOURIER_APOD_NONE; // no apodization
2259  fFourier.fPlotTag = FOURIER_PLOT_REAL_AND_IMAG; // initial plot tag, plot real and imaginary part
2260  fFourier.fPhaseParamNo.clear();
2261  fFourier.fPhase.clear();
2262  for (UInt_t i=0; i<2; i++) {
2263  fFourier.fRangeForPhaseCorrection[i] = -1.0; // frequency range for phase correction, default: {-1, -1} = NOT GIVEN
2264  fFourier.fPlotRange[i] = -1.0; // fourier plot range, default: {-1, -1} = NOT GIVEN
2265  }
2266  fFourier.fPhaseIncrement = 1.0; // fourier phase increment
2267 }
2268 
2269 //--------------------------------------------------------------------------
2270 // InitAverage (private)
2271 //--------------------------------------------------------------------------
2276 {
2277  fDataAvg.data = nullptr;
2278  fDataAvg.dataFourierRe = nullptr;
2279  fDataAvg.dataFourierIm = nullptr;
2280  fDataAvg.dataFourierPwr = nullptr;
2281  fDataAvg.dataFourierPhase = nullptr;
2283  fDataAvg.theory = nullptr;
2284  fDataAvg.theoryFourierRe = nullptr;
2285  fDataAvg.theoryFourierIm = nullptr;
2286  fDataAvg.theoryFourierPwr = nullptr;
2287  fDataAvg.theoryFourierPhase = nullptr;
2289  fDataAvg.diff = nullptr;
2290  fDataAvg.diffFourierRe = nullptr;
2291  fDataAvg.diffFourierIm = nullptr;
2292  fDataAvg.diffFourierPwr = nullptr;
2293  fDataAvg.diffFourierPhase = nullptr;
2295  fDataAvg.dataRange = nullptr;
2297 }
2298 
2299 //--------------------------------------------------------------------------
2300 // InitMusrCanvas (private)
2301 //--------------------------------------------------------------------------
2311 void PMusrCanvas::InitMusrCanvas(const Char_t* title, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh)
2312 {
2313  fScaleN0AndBkg = true;
2314  fValid = false;
2315  fAveragedView = false;
2316  fDifferenceView = false;
2317  fToggleColor = false;
2320  fPlotType = -1;
2321 
2322  fImp = nullptr;
2323  fBar = nullptr;
2324  fPopupMain = nullptr;
2325 
2326  // invoke canvas
2327  TString canvasName = TString("fMainCanvas");
2328  canvasName += fPlotNumber;
2329  fMainCanvas = std::make_unique<TCanvas>(canvasName.Data(), title, wtopx, wtopy, ww, wh);
2330 
2331  fMainCanvas->Connect("Closed()", "PMusrCanvas", this, "LastCanvasClosed()");
2332 
2333  // add canvas menu if not in batch mode
2334  if (!fBatchMode) {
2335  fImp = (TRootCanvas*)fMainCanvas->GetCanvasImp();
2336  fImp->Connect("CloseWindow()", "PMusrCanvas", this, "WindowClosed()");
2337  fBar = fImp->GetMenuBar();
2338  fPopupMain = fBar->AddPopup("&Musrfit");
2339 
2340  fPopupFourier = std::make_unique<TGPopupMenu>();
2342  fPopupMain->AddSeparator();
2343 
2344  fPopupMain->AddPopup("&Fourier", fPopupFourier.get());
2351  fPopupFourier->AddSeparator();
2356 
2358  fPopupMain->AddSeparator();
2359 
2361  fPopupMain->AddSeparator();
2362 
2364  fBar->MapSubwindows();
2365  fBar->Layout();
2366 
2367  fPopupMain->Connect("TGPopupMenu", "Activated(Int_t)", "PMusrCanvas", this, "HandleMenuPopup(Int_t)");
2368 
2370  }
2371 
2372  // divide the canvas into 4 pads
2373  // title pad
2374  fTitlePad = std::make_unique<TPaveText>(0.0, YTITLE, 1.0, 1.0, "NDC");
2375  fTitlePad->SetFillColor(TColor::GetColor(255,255,255));
2376  fTitlePad->SetTextAlign(12); // middle, left
2377  fTitlePad->AddText(title);
2378  fTitlePad->Draw();
2379 
2380  // data/theory pad
2381  fDataTheoryPad = std::make_unique<TPad>("dataTheoryPad", "dataTheoryPad", 0.0, YINFO, XTHEO, YTITLE);
2382  fDataTheoryPad->SetFillColor(TColor::GetColor(255,255,255));
2383  fDataTheoryPad->Draw();
2384 
2385  // parameter pad
2386  fParameterPad = std::make_unique<TPaveText>(XTHEO, 0.5, 1.0, YTITLE, "NDC");
2387  fParameterPad->SetFillColor(TColor::GetColor(255,255,255));
2388  fParameterPad->SetTextAlign(13); // top, left
2389  fParameterPad->SetTextFont(102); // courier bold, scalable so that greek parameters will be plotted properly
2390 
2391  // theory pad
2392  fTheoryPad = std::make_unique<TPaveText>(XTHEO, 0.1, 1.0, 0.5, "NDC");
2393  fTheoryPad->SetFillColor(TColor::GetColor(255,255,255));
2394  fTheoryPad->SetTextAlign(13); // top, left
2395  fTheoryPad->SetTextFont(102); // courier bold, scalable so that greek parameters will be plotted properly
2396 
2397 
2398  // info pad
2399  fInfoPad = std::make_unique<TLegend>(0.0, 0.0, 1.0, YINFO, "NDC");
2400  fInfoPad->SetFillColor(TColor::GetColor(255,255,255));
2401  fInfoPad->SetTextAlign(12); // middle, left
2402 
2403  fValid = true;
2404 
2405  fMainCanvas->cd();
2406 
2407  fMainCanvas->Show();
2408 
2409  fMainCanvas->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", "PMusrCanvas",
2410  this, "HandleCmdKey(Int_t,Int_t,Int_t,TObject*)");
2411 }
2412 
2413 //--------------------------------------------------------------------------
2414 // InitDataSet (private)
2415 //--------------------------------------------------------------------------
2422 {
2423  dataSet.data = nullptr;
2424  dataSet.dataFourierRe = nullptr;
2425  dataSet.dataFourierIm = nullptr;
2426  dataSet.dataFourierPwr = nullptr;
2427  dataSet.dataFourierPhase = nullptr;
2428  dataSet.dataFourierPhaseOptReal = nullptr;
2429  dataSet.theory = nullptr;
2430  dataSet.theoryFourierRe = nullptr;
2431  dataSet.theoryFourierIm = nullptr;
2432  dataSet.theoryFourierPwr = nullptr;
2433  dataSet.theoryFourierPhase = nullptr;
2434  dataSet.theoryFourierPhaseOptReal = nullptr;
2435  dataSet.diff = nullptr;
2436  dataSet.diffFourierRe = nullptr;
2437  dataSet.diffFourierIm = nullptr;
2438  dataSet.diffFourierPwr = nullptr;
2439  dataSet.diffFourierPhase = nullptr;
2440  dataSet.diffFourierPhaseOptReal = nullptr;
2441  dataSet.dataRange = nullptr;
2442 }
2443 
2444 //--------------------------------------------------------------------------
2445 // InitDataSet (private)
2446 //--------------------------------------------------------------------------
2453 {
2454  dataSet.data = nullptr;
2455  dataSet.dataFourierRe = nullptr;
2456  dataSet.dataFourierIm = nullptr;
2457  dataSet.dataFourierPwr = nullptr;
2458  dataSet.dataFourierPhase = nullptr;
2459  dataSet.theory = nullptr;
2460  dataSet.theoryFourierRe = nullptr;
2461  dataSet.theoryFourierIm = nullptr;
2462  dataSet.theoryFourierPwr = nullptr;
2463  dataSet.theoryFourierPhase = nullptr;
2464  dataSet.diff = nullptr;
2465  dataSet.diffFourierRe = nullptr;
2466  dataSet.diffFourierIm = nullptr;
2467  dataSet.diffFourierPwr = nullptr;
2468  dataSet.diffFourierPhase = nullptr;
2469  dataSet.dataRange = nullptr;
2470 }
2471 
2472 //--------------------------------------------------------------------------
2473 // CleanupDataSet (private)
2474 //--------------------------------------------------------------------------
2481 {
2482  if (dataSet.data) {
2483  delete dataSet.data;
2484  dataSet.data = nullptr;
2485  }
2486  if (dataSet.dataFourierRe) {
2487  delete dataSet.dataFourierRe;
2488  dataSet.dataFourierRe = nullptr;
2489  }
2490  if (dataSet.dataFourierIm) {
2491  delete dataSet.dataFourierIm;
2492  dataSet.dataFourierIm = nullptr;
2493  }
2494  if (dataSet.dataFourierPwr) {
2495  delete dataSet.dataFourierPwr;
2496  dataSet.dataFourierPwr = nullptr;
2497  }
2498  if (dataSet.dataFourierPhase) {
2499  delete dataSet.dataFourierPhase;
2500  dataSet.dataFourierPhase = nullptr;
2501  }
2502  if (dataSet.dataFourierPhaseOptReal) {
2503  delete dataSet.dataFourierPhaseOptReal;
2504  dataSet.dataFourierPhaseOptReal = nullptr;
2505  }
2506  if (dataSet.theory) {
2507  delete dataSet.theory;
2508  dataSet.theory = nullptr;
2509  }
2510  if (dataSet.theoryFourierRe) {
2511  delete dataSet.theoryFourierRe;
2512  dataSet.theoryFourierRe = nullptr;
2513  }
2514  if (dataSet.theoryFourierIm) {
2515  delete dataSet.theoryFourierIm;
2516  dataSet.theoryFourierIm = nullptr;
2517  }
2518  if (dataSet.theoryFourierPwr) {
2519  delete dataSet.theoryFourierPwr;
2520  dataSet.theoryFourierPwr = nullptr;
2521  }
2522  if (dataSet.theoryFourierPhase) {
2523  delete dataSet.theoryFourierPhase;
2524  dataSet.theoryFourierPhase = nullptr;
2525  }
2526  if (dataSet.theoryFourierPhaseOptReal) {
2527  delete dataSet.theoryFourierPhaseOptReal;
2528  dataSet.theoryFourierPhaseOptReal = nullptr;
2529  }
2530  if (dataSet.diff) {
2531  delete dataSet.diff;
2532  dataSet.diff = nullptr;
2533  }
2534  if (dataSet.diffFourierRe) {
2535  delete dataSet.diffFourierRe;
2536  dataSet.diffFourierRe = nullptr;
2537  }
2538  if (dataSet.diffFourierIm) {
2539  delete dataSet.diffFourierIm;
2540  dataSet.diffFourierIm = nullptr;
2541  }
2542  if (dataSet.diffFourierPwr) {
2543  delete dataSet.diffFourierPwr;
2544  dataSet.diffFourierPwr = nullptr;
2545  }
2546  if (dataSet.diffFourierPhase) {
2547  delete dataSet.diffFourierPhase;
2548  dataSet.diffFourierPhase = nullptr;
2549  }
2550  if (dataSet.diffFourierPhaseOptReal) {
2551  delete dataSet.diffFourierPhaseOptReal;
2552  dataSet.diffFourierPhaseOptReal = nullptr;
2553  }
2554  if (dataSet.dataRange) {
2555  delete dataSet.dataRange;
2556  dataSet.dataRange = nullptr;
2557  }
2558 }
2559 
2560 //--------------------------------------------------------------------------
2561 // CleanupDataSet (private)
2562 //--------------------------------------------------------------------------
2569 {
2570  if (dataSet.data) {
2571  delete dataSet.data;
2572  dataSet.data = nullptr;
2573  }
2574  if (dataSet.dataFourierRe) {
2575  delete dataSet.dataFourierRe;
2576  dataSet.dataFourierRe = nullptr;
2577  }
2578  if (dataSet.dataFourierIm) {
2579  delete dataSet.dataFourierIm;
2580  dataSet.dataFourierIm = nullptr;
2581  }
2582  if (dataSet.dataFourierPwr) {
2583  delete dataSet.dataFourierPwr;
2584  dataSet.dataFourierPwr = nullptr;
2585  }
2586  if (dataSet.dataFourierPhase) {
2587  delete dataSet.dataFourierPhase;
2588  dataSet.dataFourierPhase = nullptr;
2589  }
2590  if (dataSet.theory) {
2591  delete dataSet.theory;
2592  dataSet.theory = nullptr;
2593  }
2594  if (dataSet.theoryFourierRe) {
2595  delete dataSet.theoryFourierRe;
2596  dataSet.theoryFourierRe = nullptr;
2597  }
2598  if (dataSet.theoryFourierIm) {
2599  delete dataSet.theoryFourierIm;
2600  dataSet.theoryFourierIm = nullptr;
2601  }
2602  if (dataSet.theoryFourierPwr) {
2603  delete dataSet.theoryFourierPwr;
2604  dataSet.theoryFourierPwr = nullptr;
2605  }
2606  if (dataSet.theoryFourierPhase) {
2607  delete dataSet.theoryFourierPhase;
2608  dataSet.theoryFourierPhase = nullptr;
2609  }
2610  if (dataSet.diff) {
2611  delete dataSet.diff;
2612  dataSet.diff = nullptr;
2613  }
2614  if (dataSet.diffFourierRe) {
2615  delete dataSet.diffFourierRe;
2616  dataSet.diffFourierRe = nullptr;
2617  }
2618  if (dataSet.diffFourierIm) {
2619  delete dataSet.diffFourierIm;
2620  dataSet.diffFourierIm = nullptr;
2621  }
2622  if (dataSet.diffFourierPwr) {
2623  delete dataSet.diffFourierPwr;
2624  dataSet.diffFourierPwr = nullptr;
2625  }
2626  if (dataSet.diffFourierPhase) {
2627  delete dataSet.diffFourierPhase;
2628  dataSet.diffFourierPhase = nullptr;
2629  }
2630  if (dataSet.dataRange) {
2631  delete dataSet.dataRange;
2632  dataSet.dataRange = nullptr;
2633  }
2634 }
2635 
2636 //--------------------------------------------------------------------------
2637 // HandleDataSet (private)
2638 //--------------------------------------------------------------------------
2646 void PMusrCanvas::HandleDataSet(UInt_t plotNo, UInt_t runNo, PRunData *data)
2647 {
2648  PMusrCanvasDataSet dataSet;
2649  TH1F *dataHisto;
2650  TH1F *theoHisto;
2651 
2652  TString name;
2653  Double_t start;
2654  Double_t end;
2655  Double_t xmin, xmax, ymin, ymax;
2656  Int_t size;
2657 
2658  InitDataSet(dataSet);
2659 
2660  // create plot range object for the data set
2661  dataSet.dataRange = new PMusrCanvasPlotRange();
2662 
2663  // dataHisto -------------------------------------------------------------
2664  // create histo specific infos
2665  name = *fMsrHandler->GetMsrRunList()->at(runNo).GetRunName() + "_DataRunNo";
2666  name += static_cast<Int_t>(runNo);
2667  name += "_";
2668  name += fPlotNumber;
2669  start = data->GetDataTimeStart() - data->GetDataTimeStep()/2.0;
2670  end = start + data->GetValue()->size()*data->GetDataTimeStep();
2671  size = data->GetValue()->size();
2672  dataSet.dataRange->SetXRange(start, end); // full possible range
2673  // make sure that for asymmetry the y-range is initialized reasonably
2674  if ((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_ASYM) || (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_BNMR))
2675  dataSet.dataRange->SetYRange(-0.4, 0.4);
2676  // extract necessary range information
2677  if ((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() == 0) &&
2678  !fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) { // no range information at all
2679  if (fXRangePresent) {
2680  if (fXmin > start)
2681  fXmin = start;
2682  if (fXmax < end)
2683  fXmax = end;
2684  } else {
2685  fXRangePresent = true;
2686  fXmin = start;
2687  fXmax = end;
2688  }
2689  if ((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_ASYM) ||
2690  (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_BNMR) ||
2691  (fMsrHandler->GetMsrRunList()->at(runNo).IsLifetimeCorrected())) {
2692  fYRangePresent = true;
2693  fYmin = -0.4;
2694  fYmax = 0.4;
2695  }
2696  }
2697 
2698  // check if plot range is given in the msr-file, and if yes keep the values
2699  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() == 1) {
2700  // keep x-range
2701  xmin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[0];
2702  xmax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[0];
2703  dataSet.dataRange->SetXRange(xmin, xmax);
2704  // keep range information
2705  fXRangePresent = true;
2706  fXmin = xmin;
2707  fXmax = xmax;
2708  // check if y-range is given as well
2709  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) {
2710  ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0];
2711  ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0];
2712  dataSet.dataRange->SetYRange(ymin, ymax);
2713  // keep range information
2714  fYRangePresent = true;
2715  fYmin = ymin;
2716  fYmax = ymax;
2717  }
2718  }
2719 
2720  // check if 'use_fit_ranges' plotting is whished
2721  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) {
2722  start = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0); // needed to estimate size
2723  if (start == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry
2724  start = fMsrHandler->GetMsrGlobal()->GetFitRange(0);
2725  }
2726  end = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1); // needed to estimate size
2727  if (end == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry
2728  end = fMsrHandler->GetMsrGlobal()->GetFitRange(1);
2729  }
2730  size = (Int_t) ((end - start) / data->GetDataTimeStep()) + 1;
2731  start = data->GetDataTimeStart() +
2732  (Int_t)((start - data->GetDataTimeStart())/data->GetDataTimeStep()) * data->GetDataTimeStep() -
2733  data->GetDataTimeStep()/2.0; // closesd start value compatible with the user given
2734  end = start + size * data->GetDataTimeStep(); // closesd end value compatible with the user given
2735  dataSet.dataRange->SetXRange(start, end);
2736 
2737  // make sure that for asymmetry the y-range is initialized reasonably
2738  if ((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_ASYM) ||
2739  (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_BNMR) ||
2740  (fMsrHandler->GetMsrRunList()->at(runNo).IsLifetimeCorrected())) {
2741  dataSet.dataRange->SetYRange(-0.4, 0.4);
2742  }
2743 
2744  // keep range information
2745  if (fXRangePresent) {
2746  if (fXmin > start)
2747  fXmin = start;
2748  if (fXmax < end)
2749  fXmax = end;
2750  } else {
2751  fXRangePresent = true;
2752  fXmin = start;
2753  fXmax = end;
2754  }
2755  // check if y-range is given as well
2756  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) {
2757  ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0];
2758  ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0];
2759  dataSet.dataRange->SetYRange(ymin, ymax);
2760  // keep range information
2761  fYRangePresent = true;
2762  fYmin = ymin;
2763  fYmax = ymax;
2764  }
2765  }
2766 
2767  // check if 'sub_ranges' plotting is whished
2768  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) {
2769  start = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo]; // needed to estimate size
2770  end = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo]; // needed to estimate size
2771  size = (Int_t) ((end - start) / data->GetDataTimeStep()) + 1;
2772  start = data->GetDataTimeStart() +
2773  (Int_t)((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] - data->GetDataTimeStart())/data->GetDataTimeStep()) * data->GetDataTimeStep() -
2774  data->GetDataTimeStep()/2.0; // closesd start value compatible with the user given
2775  end = start + size * data->GetDataTimeStep(); // closesd end value compatible with the user given
2776  dataSet.dataRange->SetXRange(start, end);
2777  // keep range information
2778  if (fXRangePresent) {
2779  if (fXmin > start)
2780  fXmin = start;
2781  if (fXmax < end)
2782  fXmax = end;
2783  } else {
2784  fXRangePresent = true;
2785  fXmin = start;
2786  fXmax = end;
2787  }
2788 
2789  // check if y-range is given as well
2790  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) {
2791  ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0];
2792  ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0];
2793  dataSet.dataRange->SetYRange(ymin, ymax);
2794  // keep range information
2795  fYRangePresent = true;
2796  fYmin = ymin;
2797  fYmax = ymax;
2798  }
2799  }
2800 
2801  // invoke histo
2802  dataHisto = new TH1F(name, name, size, start, end);
2803 
2804  // fill histogram
2805  // 1st calculate the bin-range according to the plot options
2806  UInt_t startBin = 0;
2807  UInt_t endBin = data->GetValue()->size();
2808 
2809  // check if 'use_fit_range' plotting is whished
2810  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) {
2811  Double_t startFitRange = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0);
2812  if (startFitRange == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry
2813  startFitRange = fMsrHandler->GetMsrGlobal()->GetFitRange(0);
2814  }
2815  Double_t dval = (startFitRange - data->GetDataTimeStart())/data->GetDataTimeStep();
2816  if (dval < 0.0) { // make sure that startBin >= 0
2817  startBin = 0;
2818  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin data < 0 for 'use_fit_range', will set it to 0" << std::endl << std::endl;
2819  } else if (dval >= (Double_t)data->GetValue()->size()) { // make sure that startBin <= length of data vector
2820  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin data=" << (UInt_t)dval << " >= data vector size=" << data->GetValue()->size() << " for 'use_fit_range',";
2821  std::cerr << std::endl << ">> will set it to data vector size" << std::endl << std::endl;
2822  startBin = data->GetValue()->size();
2823  } else {
2824  startBin = (UInt_t)dval;
2825  }
2826 
2827  Double_t endFitRange = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1);
2828  if (endFitRange == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry
2829  endFitRange = fMsrHandler->GetMsrGlobal()->GetFitRange(1);
2830  }
2831  dval = (endFitRange - data->GetDataTimeStart())/data->GetDataTimeStep();
2832  if (dval < 0.0) { // make sure that endBin >= 0
2833  endBin = 0;
2834  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin data < 0 for 'use_fit_range', will set it to 0" << std::endl << std::endl;
2835  } else if (dval >= (Double_t)data->GetValue()->size()) { // make sure that endBin <= length of data vector
2836  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin data=" << (UInt_t)dval << " >= data vector size=" << data->GetValue()->size() << " for 'use_fit_range',";
2837  std::cerr << std::endl << ">> will set it to data vector size" << std::endl << std::endl;
2838  endBin = data->GetValue()->size();
2839  } else {
2840  endBin = (UInt_t)dval;
2841  }
2842  }
2843 
2844  // check if 'sub_ranges' plotting is whished
2845  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) {
2846  Double_t dval = (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] - data->GetDataTimeStart())/data->GetDataTimeStep();
2847  if (dval < 0.0) { // make sure that startBin >= 0
2848  startBin = 0;
2849  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin data < 0 for 'sub_ranges', will set it to 0" << std::endl << std::endl;
2850  } else if (dval >= (Double_t)data->GetValue()->size()) { // make sure that startBin <= length of data vector
2851  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin data=" << (UInt_t)dval << " >= data vector size=" << data->GetValue()->size() << " for 'sub_ranges',";
2852  std::cerr << std::endl << ">> will set it to data vector size" << std::endl << std::endl;
2853  startBin = data->GetValue()->size();
2854  } else {
2855  startBin = (UInt_t)dval;
2856  }
2857 
2858  dval = (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo] - data->GetDataTimeStart())/data->GetDataTimeStep();
2859  if (dval < 0.0) { // make sure that endBin >= 0
2860  endBin = 0;
2861  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin data < 0 for 'sub_ranges', will set it to 0" << std::endl << std::endl;
2862  } else if (dval >= (Double_t)data->GetValue()->size()) { // make sure that endtBin <= length of data vector
2863  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin data=" << (UInt_t)dval << " >= data vector size=" << data->GetValue()->size() << " for 'sub_ranges',";
2864  std::cerr << std::endl << ">> will set it to data vector size" << std::endl << std::endl;
2865  endBin = data->GetValue()->size();
2866  } else {
2867  endBin = (UInt_t)dval;
2868  }
2869  }
2870 
2871  for (UInt_t i=startBin; i<endBin; i++) {
2872  dataHisto->SetBinContent(i-startBin+1, data->GetValue()->at(i));
2873  dataHisto->SetBinError(i-startBin+1, data->GetError()->at(i));
2874  }
2875 
2876  // set marker and line color
2877  if (plotNo < fColorList.size()) {
2878  dataHisto->SetMarkerColor(fColorList[plotNo]);
2879  dataHisto->SetLineColor(fColorList[plotNo]);
2880  } else {
2881  TRandom rand(plotNo);
2882  Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255));
2883  dataHisto->SetMarkerColor(color);
2884  dataHisto->SetLineColor(color);
2885  }
2886  // set marker size
2887  dataHisto->SetMarkerSize(1);
2888  // set marker type
2889  if (plotNo < fMarkerList.size()) {
2890  dataHisto->SetMarkerStyle(fMarkerList[plotNo]);
2891  } else {
2892  TRandom rand(plotNo);
2893  dataHisto->SetMarkerStyle(20+(Int_t)rand.Integer(10));
2894  }
2895 
2896  // theoHisto -------------------------------------------------------------
2897  // create histo specific infos
2898  name = *fMsrHandler->GetMsrRunList()->at(runNo).GetRunName() + "_TheoRunNo";
2899  name += (Int_t)runNo;
2900  name += "_";
2901  name += fPlotNumber;
2902  start = data->GetTheoryTimeStart() - data->GetTheoryTimeStep()/2.0;
2903  end = start + data->GetTheory()->size()*data->GetTheoryTimeStep();
2904  size = data->GetTheory()->size();
2905 
2906  // check if 'use_fit_range' plotting is whished
2907  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) {
2908  start = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0); // needed to estimate size
2909  if (start == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry
2910  start = fMsrHandler->GetMsrGlobal()->GetFitRange(0);
2911  }
2912  end = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1); // needed to estimate size
2913  if (end == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry
2914  end = fMsrHandler->GetMsrGlobal()->GetFitRange(1);
2915  }
2916  size = (Int_t) ((end - start) / data->GetTheoryTimeStep()) + 1;
2917  start = data->GetTheoryTimeStart() +
2918  (Int_t)((start - data->GetTheoryTimeStart())/data->GetTheoryTimeStep()) * data->GetTheoryTimeStep() -
2919  data->GetTheoryTimeStep()/2.0; // closesd start value compatible with the user given
2920  end = start + size * data->GetTheoryTimeStep(); // closesd end value compatible with the user given
2921  }
2922 
2923  // check if 'sub_ranges' plotting is whished
2924  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) {
2925  start = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo]; // needed to estimate size
2926  end = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo]; // needed to estimate size
2927  size = (Int_t) ((end - start) / data->GetTheoryTimeStep()) + 1;
2928  start = data->GetTheoryTimeStart() +
2929  (Int_t)((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] - data->GetTheoryTimeStart())/data->GetTheoryTimeStep()) * data->GetTheoryTimeStep() -
2930  data->GetTheoryTimeStep()/2.0; // closesd start value compatible with the user given
2931  end = start + size * data->GetTheoryTimeStep(); // closesd end value compatible with the user given
2932 }
2933 
2934  // invoke histo
2935  theoHisto = new TH1F(name, name, size, start, end);
2936 
2937  // fill histogram
2938  startBin = 0;
2939  endBin = data->GetTheory()->size();
2940 
2941  // check if 'use_fit_range' plotting is whished
2942  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) {
2943  Double_t startFitRange = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0);
2944  if (startFitRange == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry
2945  startFitRange = fMsrHandler->GetMsrGlobal()->GetFitRange(0);
2946  }
2947  Double_t dval = (startFitRange - data->GetDataTimeStart())/data->GetTheoryTimeStep();
2948  if (dval < 0.0) { // make sure that startBin >= 0
2949  startBin = 0;
2950  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin theory < 0 for 'use_fit_range', will set it to 0" << std::endl << std::endl;
2951  } else if (dval >= (Double_t)data->GetTheory()->size()) { // make sure that startBin <= length of theory vector
2952  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin theory=" << (UInt_t)dval << " >= theory vector size=" << data->GetTheory()->size() << " for 'use_fit_range',";
2953  std::cerr << std::endl << ">> will set it to theory vector size" << std::endl << std::endl;
2954  startBin = data->GetTheory()->size();
2955  } else {
2956  startBin = (UInt_t)dval;
2957  }
2958 
2959  Double_t endFitRange = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1);
2960  if (endFitRange == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry
2961  endFitRange = fMsrHandler->GetMsrGlobal()->GetFitRange(1);
2962  }
2963  dval = (endFitRange - data->GetDataTimeStart())/data->GetTheoryTimeStep();
2964  if (dval < 0.0) { // make sure that endBin >= 0
2965  endBin = 0;
2966  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin theory < 0 for 'use_fit_range', will set it to 0" << std::endl << std::endl;
2967  } else if (dval >= (Double_t)data->GetTheory()->size()) { // make sure that endBin <= length of theory vector
2968  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin theory=" << (UInt_t)dval << " >= theory vector size=" << data->GetTheory()->size() << " for 'use_fit_range',";
2969  std::cerr << std::endl << ">> will set it to theory vector size" << std::endl << std::endl;
2970  endBin = data->GetTheory()->size();
2971  } else {
2972  endBin = (UInt_t)dval;
2973  }
2974  }
2975 
2976  // check if 'sub_ranges' plotting is whished
2977  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) {
2978  startBin = (UInt_t)((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] -data->GetDataTimeStart())/data->GetTheoryTimeStep());
2979  endBin = (UInt_t)((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo] -data->GetDataTimeStart())/data->GetTheoryTimeStep());
2980 
2981  Double_t dval = (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] -data->GetDataTimeStart())/data->GetTheoryTimeStep();
2982  if (dval < 0.0) { // make sure that startBin >= 0
2983  startBin = 0;
2984  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin theory < 0 for 'sub_ranges', will set it to 0" << std::endl << std::endl;
2985  } else if (dval >= (Double_t)data->GetTheory()->size()) { // make sure that startBin <= length of theory vector
2986  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin theory=" << (UInt_t)dval << " >= theory vector size=" << data->GetTheory()->size() << " for 'sub_ranges',";
2987  std::cerr << std::endl << ">> will set it to theory vector size" << std::endl << std::endl;
2988  startBin = data->GetTheory()->size();
2989  } else {
2990  startBin = (UInt_t)dval;
2991  }
2992 
2993  dval = (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo] -data->GetDataTimeStart())/data->GetTheoryTimeStep();
2994  if (dval < 0.0) { // make sure that endBin >= 0
2995  endBin = 0;
2996  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin theory < 0 for 'sub_ranges', will set it to 0" << std::endl << std::endl;
2997  } else if (dval >= (Double_t)data->GetTheory()->size()) { // make sure that endtBin <= length of theory vector
2998  std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin theory=" << (UInt_t)dval << " >= theory vector size=" << data->GetTheory()->size() << " for 'sub_ranges',";
2999  std::cerr << std::endl << ">> will set it to theory vector size" << std::endl << std::endl;
3000  endBin = data->GetTheory()->size();
3001  } else {
3002  endBin = (UInt_t)dval;
3003  }
3004  }
3005 
3006  for (UInt_t i=startBin; i<endBin; i++) {
3007  theoHisto->SetBinContent(i-startBin+1, data->GetTheory()->at(i));
3008  }
3009 
3010  // set the line color
3011  if (plotNo < fColorList.size()) {
3012  theoHisto->SetLineColor(fColorList[plotNo]);
3013  } else {
3014  TRandom rand(plotNo);
3015  Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255));
3016  theoHisto->SetLineColor(color);
3017  }
3018 
3019  // fill handler list -----------------------------------------------------
3020  dataSet.data = dataHisto;
3021  dataSet.theory = theoHisto;
3022  dataSet.diffFourierTag = 0; // not relevant at this point
3023 
3024  fData.push_back(dataSet);
3025 }
3026 
3027 //--------------------------------------------------------------------------
3028 // HandleNonMusrDataSet (private)
3029 //--------------------------------------------------------------------------
3037 void PMusrCanvas::HandleNonMusrDataSet(UInt_t plotNo, UInt_t runNo, PRunData *data)
3038 {
3039  PMusrCanvasNonMusrDataSet dataSet;
3040  TGraphErrors *dataHisto;
3041  TGraphErrors *theoHisto;
3042 
3043  InitDataSet(dataSet);
3044 
3045  // create plot range object for the data set and fill it
3046  dataSet.dataRange = new PMusrCanvasPlotRange();
3047 
3048  // dataHisto -------------------------------------------------------------
3049 
3050  // invoke graph
3051  dataHisto = new TGraphErrors(data->GetX()->size());
3052 
3053  // fill graph
3054  for (UInt_t i=0; i<data->GetX()->size(); i++) {
3055  dataHisto->SetPoint(i, data->GetX()->at(i), data->GetValue()->at(i));
3056  dataHisto->SetPointError(i, 0.0, data->GetError()->at(i));
3057  }
3058 
3059  // set marker and line color
3060  if (plotNo < fColorList.size()) {
3061  dataHisto->SetMarkerColor(fColorList[plotNo]);
3062  dataHisto->SetLineColor(fColorList[plotNo]);
3063  } else {
3064  TRandom rand(plotNo);
3065  Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255));
3066  dataHisto->SetMarkerColor(color);
3067  dataHisto->SetLineColor(color);
3068  }
3069  // set marker size
3070  dataHisto->SetMarkerSize(1);
3071  // set marker type
3072  if (plotNo < fMarkerList.size()) {
3073  dataHisto->SetMarkerStyle(fMarkerList[plotNo]);
3074  } else {
3075  TRandom rand(plotNo);
3076  dataHisto->SetMarkerStyle(20+(Int_t)rand.Integer(10));
3077  }
3078 
3079  // theoHisto -------------------------------------------------------------
3080 
3081  // invoke graph
3082  theoHisto = new TGraphErrors(data->GetXTheory()->size());
3083 
3084  // fill graph
3085  for (UInt_t i=0; i<data->GetXTheory()->size(); i++) {
3086  theoHisto->SetPoint(i, data->GetXTheory()->at(i), data->GetTheory()->at(i));
3087  theoHisto->SetPointError(i, 0.0, 0.0);
3088  }
3089 
3090  // set the line color
3091  if (plotNo < fColorList.size()) {
3092  theoHisto->SetLineColor(fColorList[plotNo]);
3093  } else {
3094  TRandom rand(plotNo);
3095  Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255));
3096  theoHisto->SetLineColor(color);
3097  }
3098 
3099  // fill handler list -----------------------------------------------------
3100  dataSet.data = dataHisto;
3101  dataSet.theory = theoHisto;
3102  dataSet.diffFourierTag = 0; // not relevant at this point
3103 
3104  // check the plot range options
3105  Double_t xmin=0.0, xmax=0.0, ymin=0.0, ymax=0.0, x=0.0, y=0.0;
3106 
3107  // if no plot-range entry is present, initialize the plot range to the maximal possible given the data
3108  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() == 0) {
3109  dataSet.data->GetPoint(0, xmin, y); // get xmin
3110  dataSet.data->GetPoint(dataSet.data->GetN()-1, xmax, y); // get xmax
3111  dataSet.data->GetPoint(0, x, y); // init ymin/ymax
3112  ymin = y;
3113  ymax = y;
3114  for (Int_t i=1; i<dataSet.data->GetN(); i++) {
3115  dataSet.data->GetPoint(i, x, y);
3116  if (y < ymin)
3117  ymin = y;
3118  if (y > ymax)
3119  ymax = y;
3120  }
3121  Double_t dx = 0.025*(xmax-xmin);
3122  Double_t dy = 0.025*(ymax-ymin);
3123  dataSet.dataRange->SetXRange(xmin-dx, xmax+dx);
3124  dataSet.dataRange->SetYRange(ymin-dy, ymax+dy);
3125  }
3126 
3127  // check if plot range is given in the msr-file, and if yes keep the values
3128  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() == 1) {
3129  // keep x-range
3130  xmin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[0];
3131  xmax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[0];
3132  dataSet.dataRange->SetXRange(xmin, xmax);
3133 
3134  // check if y-range is given as well
3135  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) {
3136  ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0];
3137  ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0];
3138  dataSet.dataRange->SetYRange(ymin, ymax);
3139  }
3140  }
3141 
3142  // check if 'use_fit_range' plotting is whished
3143  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) {
3144  xmin = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0); // needed to estimate size
3145  xmax = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1); // needed to estimate size
3146  dataSet.dataRange->SetXRange(xmin, xmax);
3147 
3148  // check if y-range is given as well
3149  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) {
3150  ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0];
3151  ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0];
3152  dataSet.dataRange->SetYRange(ymin, ymax);
3153  }
3154  }
3155 
3156  // check if 'sub_ranges' plotting is whished
3157  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) {
3158  xmin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo]; // needed to estimate size
3159  xmax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo]; // needed to estimate size
3160  dataSet.dataRange->SetXRange(xmin, xmax);
3161 
3162  // check if y-range is given as well
3163  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) {
3164  ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0];
3165  ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0];
3166  dataSet.dataRange->SetYRange(ymin, ymax);
3167  }
3168  }
3169 
3170  // keep maximal range of all plot present
3171  fXRangePresent = true;
3172  fYRangePresent = true;
3173  if (plotNo == 0) {
3174  fXmin = dataSet.dataRange->GetXmin();
3175  fXmax = dataSet.dataRange->GetXmax();
3176  fYmin = dataSet.dataRange->GetYmin();
3177  fYmax = dataSet.dataRange->GetYmax();
3178  } else {
3179  if (fXmin > dataSet.dataRange->GetXmin())
3180  fXmin = dataSet.dataRange->GetXmin();
3181  if (fXmax < dataSet.dataRange->GetXmax())
3182  fXmax = dataSet.dataRange->GetXmax();
3183  if (fYmin > dataSet.dataRange->GetYmin())
3184  fYmin = dataSet.dataRange->GetYmin();
3185  if (fYmax < dataSet.dataRange->GetYmax())
3186  fYmax = dataSet.dataRange->GetYmax();
3187  }
3188 
3189  fNonMusrData.push_back(dataSet);
3190 }
3191 
3192 //--------------------------------------------------------------------------
3193 // HandleDifference (private)
3194 //--------------------------------------------------------------------------
3201 {
3202  // check if it is necessary to calculate diff data
3203  if ((fPlotType != MSR_PLOT_NON_MUSR) && (fData[0].diff == nullptr)) {
3204  TH1F *diffHisto;
3205  TString name;
3206  // loop over all histos
3207  for (UInt_t i=0; i<fData.size(); i++) {
3208  // create difference histos
3209  name = TString(fData[i].data->GetTitle()) + "_diff";
3210  diffHisto = new TH1F(name, name, fData[i].data->GetNbinsX(),
3211  fData[i].data->GetXaxis()->GetXmin(),
3212  fData[i].data->GetXaxis()->GetXmax());
3213 
3214  // set marker and line color
3215  diffHisto->SetMarkerColor(fData[i].data->GetMarkerColor());
3216  diffHisto->SetLineColor(fData[i].data->GetLineColor());
3217  // set marker size
3218  diffHisto->SetMarkerSize(fData[i].data->GetMarkerSize());
3219  // set marker type
3220  diffHisto->SetMarkerStyle(fData[i].data->GetMarkerStyle());
3221 
3222  // keep difference histo
3223  fData[i].diff = diffHisto;
3224  // calculate diff histo entry
3225  double value;
3226  for (Int_t j=1; j<fData[i].data->GetNbinsX()-1; j++) {
3227  // set diff bin value
3228  value = CalculateDiff(fData[i].data->GetBinCenter(j),
3229  fData[i].data->GetBinContent(j),
3230  fData[i].theory);
3231  fData[i].diff->SetBinContent(j, value);
3232  // set error diff bin value
3233  value = fData[i].data->GetBinError(j);
3234  fData[i].diff->SetBinError(j, value);
3235  }
3236  }
3237  } else if ((fPlotType == MSR_PLOT_NON_MUSR) && (fNonMusrData[0].diff == nullptr)) {
3238  TGraphErrors *diffHisto;
3239  TString name;
3240  // loop over all histos
3241  for (UInt_t i=0; i<fNonMusrData.size(); i++) {
3242  // make sure data exists
3243  assert(fNonMusrData[i].data != nullptr);
3244 
3245  // create difference histos
3246  diffHisto = new TGraphErrors(fNonMusrData[i].data->GetN());
3247 
3248  // create difference histos
3249  name = TString(fNonMusrData[i].data->GetTitle()) + "_diff";
3250  diffHisto->SetNameTitle(name.Data(), name.Data());
3251 
3252  // set marker and line color
3253  diffHisto->SetMarkerColor(fNonMusrData[i].data->GetMarkerColor());
3254  diffHisto->SetLineColor(fNonMusrData[i].data->GetLineColor());
3255  // set marker size
3256  diffHisto->SetMarkerSize(fNonMusrData[i].data->GetMarkerSize());
3257  // set marker type
3258  diffHisto->SetMarkerStyle(fNonMusrData[i].data->GetMarkerStyle());
3259 
3260  // keep difference histo
3261  fNonMusrData[i].diff = diffHisto;
3262  // calculate diff histo entry
3263  double value;
3264  double x, y;
3265  for (Int_t j=0; j<fNonMusrData[i].data->GetN(); j++) {
3266  // set diff bin value
3267  fNonMusrData[i].data->GetPoint(j, x, y);
3268  value = CalculateDiff(x, y, fNonMusrData[i].theory);
3269  fNonMusrData[i].diff->SetPoint(j, x, value);
3270  // set error diff bin value
3271  value = fNonMusrData[i].data->GetErrorY(j);
3272  fNonMusrData[i].diff->SetPointError(j, 0.0, value);
3273  }
3274  }
3275  }
3276 }
3277 
3278 //--------------------------------------------------------------------------
3279 // HandleFourier (private)
3280 //--------------------------------------------------------------------------
3287 {
3288  Double_t re, im;
3289 
3290  // check if plot type is appropriate for fourier
3292  return;
3293 
3294  // check if fourier needs to be calculated
3295  if (fData[0].dataFourierRe == nullptr) {
3296  Int_t bin;
3297  double startTime = fXmin;
3298  double endTime = fXmax;
3299  if (!fStartWithFourier) { // fHistoFrame present, hence get start/end from it
3300  bin = fHistoFrame->GetXaxis()->GetFirst();
3301  startTime = fHistoFrame->GetBinLowEdge(bin);
3302  bin = fHistoFrame->GetXaxis()->GetLast();
3303  endTime = fHistoFrame->GetBinLowEdge(bin)+fHistoFrame->GetBinWidth(bin);
3304  }
3305  for (UInt_t i=0; i<fData.size(); i++) {
3306  // calculate fourier transform of the data
3307  PFourier fourierData(fData[i].data, fFourier.fUnits, startTime, endTime, fFourier.fDCCorrected, fFourier.fFourierPower);
3308  if (!fourierData.IsValid()) {
3309  std::cerr << std::endl << ">> PMusrCanvas::HandleFourier(): **SEVERE ERROR** couldn't invoke PFourier to calculate the Fourier data ..." << std::endl;
3310  return;
3311  }
3312  fourierData.Transform(fFourier.fApodization);
3313  double scale;
3314  scale = sqrt(fData[0].data->GetBinWidth(1)/(endTime-startTime));
3315  // get real part of the data
3316  fData[i].dataFourierRe = fourierData.GetRealFourier(scale);
3317  // get imaginary part of the data
3318  fData[i].dataFourierIm = fourierData.GetImaginaryFourier(scale);
3319  // get power part of the data
3320  fData[i].dataFourierPwr = fourierData.GetPowerFourier(scale);
3321  // get phase part of the data
3322  fData[i].dataFourierPhase = fourierData.GetPhaseFourier();
3323 
3324  // set marker and line color
3325  fData[i].dataFourierRe->SetMarkerColor(fData[i].data->GetMarkerColor());
3326  fData[i].dataFourierRe->SetLineColor(fData[i].data->GetLineColor());
3327  fData[i].dataFourierIm->SetMarkerColor(fData[i].data->GetMarkerColor());
3328  fData[i].dataFourierIm->SetLineColor(fData[i].data->GetLineColor());
3329  fData[i].dataFourierPwr->SetMarkerColor(fData[i].data->GetMarkerColor());
3330  fData[i].dataFourierPwr->SetLineColor(fData[i].data->GetLineColor());
3331  fData[i].dataFourierPhase->SetMarkerColor(fData[i].data->GetMarkerColor());
3332  fData[i].dataFourierPhase->SetLineColor(fData[i].data->GetLineColor());
3333 
3334  // set marker size
3335  fData[i].dataFourierRe->SetMarkerSize(1);
3336  fData[i].dataFourierIm->SetMarkerSize(1);
3337  fData[i].dataFourierPwr->SetMarkerSize(1);
3338  fData[i].dataFourierPhase->SetMarkerSize(1);
3339 
3340  // set marker type
3341  fData[i].dataFourierRe->SetMarkerStyle(fData[i].data->GetMarkerStyle());
3342  fData[i].dataFourierIm->SetMarkerStyle(fData[i].data->GetMarkerStyle());
3343  fData[i].dataFourierPwr->SetMarkerStyle(fData[i].data->GetMarkerStyle());
3344  fData[i].dataFourierPhase->SetMarkerStyle(fData[i].data->GetMarkerStyle());
3345 
3346  // calculate fourier transform of the theory
3347  PFourier *fourierTheory = nullptr;
3348  if (fTheoAsData) { // theory only at the data points
3349  fourierTheory = new PFourier(fData[i].theory, fFourier.fUnits, startTime, endTime, fFourier.fDCCorrected, fFourier.fFourierPower);
3350  } else {
3351  Int_t powerPad = fFourier.fFourierPower+5; // +5 means 8 times more points on theo (+3) + 4 times more points in fourier (+2)
3352  fourierTheory = new PFourier(fData[i].theory, fFourier.fUnits, startTime, endTime, fFourier.fDCCorrected, powerPad);
3353  }
3354  if (!fourierTheory->IsValid()) {
3355  std::cerr << std::endl << ">> PMusrCanvas::HandleFourier(): **SEVERE ERROR** couldn't invoke PFourier to calculate the Fourier theory ..." << std::endl;
3356  return;
3357  }
3358  fourierTheory->Transform(fFourier.fApodization);
3359  scale = sqrt(fData[0].theory->GetBinWidth(1)/(endTime-startTime)*fData[0].theory->GetBinWidth(1)/fData[0].data->GetBinWidth(1));
3360  // get real part of the data
3361  fData[i].theoryFourierRe = fourierTheory->GetRealFourier(scale);
3362  // get imaginary part of the data
3363  fData[i].theoryFourierIm = fourierTheory->GetImaginaryFourier(scale);
3364  // get power part of the data
3365  fData[i].theoryFourierPwr = fourierTheory->GetPowerFourier(scale);
3366  // get phase part of the data
3367  fData[i].theoryFourierPhase = fourierTheory->GetPhaseFourier();
3368 
3369  // clean up
3370  delete fourierTheory;
3371 
3372  // set line colors for the theory
3373  fData[i].theoryFourierRe->SetLineColor(fData[i].theory->GetLineColor());
3374  fData[i].theoryFourierIm->SetLineColor(fData[i].theory->GetLineColor());
3375  fData[i].theoryFourierPwr->SetLineColor(fData[i].theory->GetLineColor());
3376  fData[i].theoryFourierPhase->SetLineColor(fData[i].theory->GetLineColor());
3377  }
3378 
3379  // phase opt. real FT requested initially in the msr-file, hence calculate it here
3381  CalcPhaseOptReFT();
3382  }
3383 
3384  // apply global phase if present
3385  if (fFourier.fPhase.size() != 0.0) {
3386  double cp;
3387  double sp;
3388 
3390 
3391  for (UInt_t i=0; i<fData.size(); i++) { // loop over all data sets
3392  if (fFourier.fPhase.size() == 1) {
3393  cp = TMath::Cos(fFourier.fPhase[0]/180.0*TMath::Pi());
3394  sp = TMath::Sin(fFourier.fPhase[0]/180.0*TMath::Pi());
3395  } else {
3396  cp = TMath::Cos(fFourier.fPhase[i]/180.0*TMath::Pi());
3397  sp = TMath::Sin(fFourier.fPhase[i]/180.0*TMath::Pi());
3398  }
3399  if ((fData[i].dataFourierRe != nullptr) && (fData[i].dataFourierIm != nullptr)) {
3400  for (Int_t j=0; j<fData[i].dataFourierRe->GetNbinsX(); j++) { // loop over a fourier data set
3401  // calculate new fourier data set value
3402  re = fData[i].dataFourierRe->GetBinContent(j) * cp + fData[i].dataFourierIm->GetBinContent(j) * sp;
3403  im = fData[i].dataFourierIm->GetBinContent(j) * cp - fData[i].dataFourierRe->GetBinContent(j) * sp;
3404  // overwrite fourier data set value
3405  fData[i].dataFourierRe->SetBinContent(j, re);
3406  fData[i].dataFourierIm->SetBinContent(j, im);
3407  }
3408  }
3409  if ((fData[i].theoryFourierRe != nullptr) && (fData[i].theoryFourierIm != nullptr)) {
3410  for (Int_t j=0; j<fData[i].theoryFourierRe->GetNbinsX(); j++) { // loop over a fourier data set
3411  // calculate new fourier data set value
3412  re = fData[i].theoryFourierRe->GetBinContent(j) * cp + fData[i].theoryFourierIm->GetBinContent(j) * sp;
3413  im = fData[i].theoryFourierIm->GetBinContent(j) * cp - fData[i].theoryFourierRe->GetBinContent(j) * sp;
3414  // overwrite fourier data set value
3415  fData[i].theoryFourierRe->SetBinContent(j, re);
3416  fData[i].theoryFourierIm->SetBinContent(j, im);
3417  }
3418  }
3419  }
3420  }
3421  }
3422 }
3423 
3424 //--------------------------------------------------------------------------
3425 // HandleDifferenceFourier (private)
3426 //--------------------------------------------------------------------------
3433 {
3434  // check if plot type is appropriate for fourier
3436  return;
3437 
3438  // check if fourier needs to be calculated
3439  if (fData[0].diffFourierRe == nullptr) {
3440  // check if difference has been already calcualted, if not do it
3441  if (fData[0].diff == nullptr)
3442  HandleDifference();
3443 
3444  // get time from the current fHistoFrame
3445  Int_t bin;
3446  bin = fHistoFrame->GetXaxis()->GetFirst();
3447  double startTime = fHistoFrame->GetBinCenter(bin);
3448  bin = fHistoFrame->GetXaxis()->GetLast();
3449  double endTime = fHistoFrame->GetBinCenter(bin);
3450 
3451  for (UInt_t i=0; i<fData.size(); i++) {
3452  // calculate fourier transform of the data
3453  PFourier fourierData(fData[i].diff, fFourier.fUnits, startTime, endTime, fFourier.fDCCorrected, fFourier.fFourierPower);
3454  if (!fourierData.IsValid()) {
3455  std::cerr << std::endl << ">> PMusrCanvas::HandleFourier(): **SEVERE ERROR** couldn't invoke PFourier to calculate the Fourier diff ..." << std::endl;
3456  return;
3457  }
3458  fourierData.Transform(fFourier.fApodization);
3459  double scale;
3460  scale = sqrt(fData[0].diff->GetBinWidth(1)/(endTime-startTime));
3461  // get real part of the data
3462  fData[i].diffFourierRe = fourierData.GetRealFourier(scale);
3463  // get imaginary part of the data
3464  fData[i].diffFourierIm = fourierData.GetImaginaryFourier(scale);
3465  // get power part of the data
3466  fData[i].diffFourierPwr = fourierData.GetPowerFourier(scale);
3467  // get phase part of the data
3468  fData[i].diffFourierPhase = fourierData.GetPhaseFourier();
3469 
3470  // set marker and line color
3471  fData[i].diffFourierRe->SetMarkerColor(fData[i].diff->GetMarkerColor());
3472  fData[i].diffFourierRe->SetLineColor(fData[i].diff->GetLineColor());
3473  fData[i].diffFourierIm->SetMarkerColor(fData[i].diff->GetMarkerColor());
3474  fData[i].diffFourierIm->SetLineColor(fData[i].diff->GetLineColor());
3475  fData[i].diffFourierPwr->SetMarkerColor(fData[i].diff->GetMarkerColor());
3476  fData[i].diffFourierPwr->SetLineColor(fData[i].diff->GetLineColor());
3477  fData[i].diffFourierPhase->SetMarkerColor(fData[i].diff->GetMarkerColor());
3478  fData[i].diffFourierPhase->SetLineColor(fData[i].diff->GetLineColor());
3479 
3480  // set marker size
3481  fData[i].diffFourierRe->SetMarkerSize(1);
3482  fData[i].diffFourierIm->SetMarkerSize(1);
3483  fData[i].diffFourierPwr->SetMarkerSize(1);
3484  fData[i].diffFourierPhase->SetMarkerSize(1);
3485  // set marker type
3486  fData[i].diffFourierRe->SetMarkerStyle(fData[i].diff->GetMarkerStyle());
3487  fData[i].diffFourierIm->SetMarkerStyle(fData[i].diff->GetMarkerStyle());
3488  fData[i].diffFourierPwr->SetMarkerStyle(fData[i].diff->GetMarkerStyle());
3489  fData[i].diffFourierPhase->SetMarkerStyle(fData[i].diff->GetMarkerStyle());
3490 
3491  // set diffFourierTag
3492  fData[i].diffFourierTag = 1; // d-f
3493  }
3494 
3495  // apply phase
3496  if (fFourier.fPhase.size() != 0.0) {
3497  double re, im;
3498  double cp;
3499  double sp;
3500 
3502 
3503  for (UInt_t i=0; i<fData.size(); i++) { // loop over all data sets
3504  if ((fData[i].diffFourierRe != nullptr) && (fData[i].diffFourierIm != nullptr)) {
3505  if (fFourier.fPhase.size() == 1) {
3506  cp = TMath::Cos(fFourier.fPhase[0]/180.0*TMath::Pi());
3507  sp = TMath::Sin(fFourier.fPhase[0]/180.0*TMath::Pi());
3508  } else {
3509  cp = TMath::Cos(fFourier.fPhase[i]/180.0*TMath::Pi());
3510  sp = TMath::Sin(fFourier.fPhase[i]/180.0*TMath::Pi());
3511  }
3512  for (Int_t j=0; j<fData[i].diffFourierRe->GetNbinsX(); j++) { // loop over a fourier data set
3513  // calculate new fourier data set value
3514  re = fData[i].diffFourierRe->GetBinContent(j) * cp + fData[i].diffFourierIm->GetBinContent(j) * sp;
3515  im = fData[i].diffFourierIm->GetBinContent(j) * cp - fData[i].diffFourierRe->GetBinContent(j) * sp;
3516  // overwrite fourier data set value
3517  fData[i].diffFourierRe->SetBinContent(j, re);
3518  fData[i].diffFourierIm->SetBinContent(j, im);
3519  }
3520  }
3521  }
3522  }
3523  }
3524 }
3525 
3526 //--------------------------------------------------------------------------
3527 // HandleFourierDifference (private)
3528 //--------------------------------------------------------------------------
3535 {
3536  // check if plot type is appropriate for fourier
3538  return;
3539 
3540  // check if fourier needs to be calculated
3541  if (fData[0].diffFourierRe == nullptr) {
3542  // calculate all the Fourier differences
3543  Double_t dval, dvalx;
3544  TString name;
3545  Int_t theoBin;
3546  for (UInt_t i=0; i<fData.size(); i++) {
3547  // create difference histos
3548  // real part
3549  name = TString(fData[i].dataFourierRe->GetTitle()) + "_diff";
3550  fData[i].diffFourierRe = new TH1F(name, name, fData[i].dataFourierRe->GetNbinsX(),
3551  fData[i].dataFourierRe->GetXaxis()->GetXmin(),
3552  fData[i].dataFourierRe->GetXaxis()->GetXmax());
3553 
3554  // imaginary part
3555  name = TString(fData[i].dataFourierIm->GetTitle()) + "_diff";
3556  fData[i].diffFourierIm = new TH1F(name, name, fData[i].dataFourierIm->GetNbinsX(),
3557  fData[i].dataFourierIm->GetXaxis()->GetXmin(),
3558  fData[i].dataFourierIm->GetXaxis()->GetXmax());
3559  // power part
3560  name = TString(fData[i].dataFourierPwr->GetTitle()) + "_diff";
3561  fData[i].diffFourierPwr = new TH1F(name, name, fData[i].dataFourierPwr->GetNbinsX(),
3562  fData[i].dataFourierPwr->GetXaxis()->GetXmin(),
3563  fData[i].dataFourierPwr->GetXaxis()->GetXmax());
3564  // phase part
3565  name = TString(fData[i].dataFourierPhase->GetTitle()) + "_diff";
3566  fData[i].diffFourierPhase = new TH1F(name, name, fData[i].dataFourierPhase->GetNbinsX(),
3567  fData[i].dataFourierPhase->GetXaxis()->GetXmin(),
3568  fData[i].dataFourierPhase->GetXaxis()->GetXmax());
3569 
3570  // phase optimized real part
3571  if (fData[i].dataFourierPhaseOptReal != nullptr) {
3572  name = TString(fData[i].dataFourierPhaseOptReal->GetTitle()) + "_diff";
3573  fData[i].diffFourierPhaseOptReal = new TH1F(name, name, fData[i].dataFourierPhaseOptReal->GetNbinsX(),
3574  fData[i].dataFourierPhaseOptReal->GetXaxis()->GetXmin(),
3575  fData[i].dataFourierPhaseOptReal->GetXaxis()->GetXmax());
3576  }
3577 
3578  // calculate difference
3579  for (UInt_t j=1; j<fData[i].dataFourierRe->GetEntries(); j++) {
3580  dvalx = fData[i].dataFourierRe->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j
3581  theoBin = fData[i].theoryFourierRe->FindBin(dvalx); // get the theory x-axis bin
3582  dval = fData[i].dataFourierRe->GetBinContent(j) - fData[i].theoryFourierRe->GetBinContent(theoBin);
3583  fData[i].diffFourierRe->SetBinContent(j, dval);
3584  dvalx = fData[i].dataFourierIm->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j
3585  theoBin = fData[i].theoryFourierIm->FindBin(dvalx); // get the theory x-axis bin
3586  dval = fData[i].dataFourierIm->GetBinContent(j) - fData[i].theoryFourierIm->GetBinContent(theoBin);
3587  fData[i].diffFourierIm->SetBinContent(j, dval);
3588  dvalx = fData[i].dataFourierPwr->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j
3589  theoBin = fData[i].theoryFourierPwr->FindBin(dvalx); // get the theory x-axis bin
3590  dval = fData[i].dataFourierPwr->GetBinContent(j) - fData[i].theoryFourierPwr->GetBinContent(theoBin);
3591  fData[i].diffFourierPwr->SetBinContent(j, dval);
3592  dvalx = fData[i].dataFourierPhase->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j
3593  theoBin = fData[i].theoryFourierPhase->FindBin(dvalx); // get the theory x-axis bin
3594  dval = fData[i].dataFourierPhase->GetBinContent(j) - fData[i].theoryFourierPhase->GetBinContent(theoBin);
3595  fData[i].diffFourierPhase->SetBinContent(j, dval);
3596  if (fData[i].dataFourierPhaseOptReal != nullptr) {
3597  dvalx = fData[i].dataFourierPhaseOptReal->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j
3598  theoBin = fData[i].theoryFourierPhaseOptReal->FindBin(dvalx); // get the theory x-axis bin
3599  dval = fData[i].dataFourierPhaseOptReal->GetBinContent(j) - fData[i].theoryFourierPhaseOptReal->GetBinContent(theoBin);
3600  fData[i].diffFourierPhaseOptReal->SetBinContent(j, dval);
3601  }
3602  }
3603  }
3604 
3605  for (UInt_t i=0; i<fData.size(); i++) {
3606  // set marker and line color
3607  fData[i].diffFourierRe->SetMarkerColor(fData[i].dataFourierRe->GetMarkerColor());
3608  fData[i].diffFourierRe->SetLineColor(fData[i].dataFourierRe->GetLineColor());
3609  fData[i].diffFourierIm->SetMarkerColor(fData[i].dataFourierIm->GetMarkerColor());
3610  fData[i].diffFourierIm->SetLineColor(fData[i].dataFourierIm->GetLineColor());
3611  fData[i].diffFourierPwr->SetMarkerColor(fData[i].dataFourierPwr->GetMarkerColor());
3612  fData[i].diffFourierPwr->SetLineColor(fData[i].dataFourierPwr->GetLineColor());
3613  fData[i].diffFourierPhase->SetMarkerColor(fData[i].dataFourierPhase->GetMarkerColor());
3614  fData[i].diffFourierPhase->SetLineColor(fData[i].dataFourierPhase->GetLineColor());
3615  if (fData[i].dataFourierPhaseOptReal != nullptr) {
3616  fData[i].diffFourierPhaseOptReal->SetMarkerColor(fData[i].dataFourierPhaseOptReal->GetMarkerColor());
3617  fData[i].diffFourierPhaseOptReal->SetLineColor(fData[i].dataFourierPhaseOptReal->GetLineColor());
3618  }
3619 
3620  // set marker size
3621  fData[i].diffFourierRe->SetMarkerSize(1);
3622  fData[i].diffFourierIm->SetMarkerSize(1);
3623  fData[i].diffFourierPwr->SetMarkerSize(1);
3624  fData[i].diffFourierPhase->SetMarkerSize(1);
3625  if (fData[i].dataFourierPhaseOptReal != nullptr) {
3626  fData[i].diffFourierPhaseOptReal->SetMarkerSize(1);
3627  }
3628  // set marker type
3629  fData[i].diffFourierRe->SetMarkerStyle(fData[i].dataFourierRe->GetMarkerStyle());
3630  fData[i].diffFourierIm->SetMarkerStyle(fData[i].dataFourierIm->GetMarkerStyle());
3631  fData[i].diffFourierPwr->SetMarkerStyle(fData[i].dataFourierPwr->GetMarkerStyle());
3632  fData[i].diffFourierPhase->SetMarkerStyle(fData[i].dataFourierPhase->GetMarkerStyle());
3633  if (fData[i].dataFourierPhaseOptReal != nullptr) {
3634  fData[i].diffFourierPhaseOptReal->SetMarkerStyle(fData[i].dataFourierPhaseOptReal->GetMarkerStyle());
3635  }
3636 
3637  // set diffFourierTag
3638  fData[i].diffFourierTag = 2; // f-d
3639  }
3640  }
3641 }
3642 
3643 //--------------------------------------------------------------------------
3644 // HandleAverage (private)
3645 //--------------------------------------------------------------------------
3652 {
3653  // check if plot type is appropriate for average
3655  return;
3656 
3657  // in case there is still some average left over, cleanup first
3658  if (fDataAvg.data != nullptr) {
3659  CleanupAverage();
3660  }
3661 
3662  // create all the needed average data sets
3663  TString name("");
3664  if (fData[0].data != nullptr) {
3665  name = TString(fData[0].data->GetTitle()) + "_avg";
3666  fDataAvg.data = new TH1F(name, name, fData[0].data->GetNbinsX(),
3667  fData[0].data->GetXaxis()->GetXmin(),
3668  fData[0].data->GetXaxis()->GetXmax());
3669  }
3670  if (fData[0].dataFourierRe != nullptr) {
3671  name = TString(fData[0].dataFourierRe->GetTitle()) + "_avg";
3672  fDataAvg.dataFourierRe = new TH1F(name, name, fData[0].dataFourierRe->GetNbinsX(),
3673  fData[0].dataFourierRe->GetXaxis()->GetXmin(),
3674  fData[0].dataFourierRe->GetXaxis()->GetXmax());
3675  }
3676  if (fData[0].dataFourierIm != nullptr) {
3677  name = TString(fData[0].dataFourierIm->GetTitle()) + "_avg";
3678  fDataAvg.dataFourierIm = new TH1F(name, name, fData[0].dataFourierIm->GetNbinsX(),
3679  fData[0].dataFourierIm->GetXaxis()->GetXmin(),
3680  fData[0].dataFourierIm->GetXaxis()->GetXmax());
3681  }
3682  if (fData[0].dataFourierPwr != nullptr) {
3683  name = TString(fData[0].dataFourierPwr->GetTitle()) + "_avg";
3684  fDataAvg.dataFourierPwr = new TH1F(name, name, fData[0].dataFourierPwr->GetNbinsX(),
3685  fData[0].dataFourierPwr->GetXaxis()->GetXmin(),
3686  fData[0].dataFourierPwr->GetXaxis()->GetXmax());
3687  }
3688  if (fData[0].dataFourierPhase != nullptr) {
3689  name = TString(fData[0].dataFourierPhase->GetTitle()) + "_avg";
3690  fDataAvg.dataFourierPhase = new TH1F(name, name, fData[0].dataFourierPhase->GetNbinsX(),
3691  fData[0].dataFourierPhase->GetXaxis()->GetXmin(),
3692  fData[0].dataFourierPhase->GetXaxis()->GetXmax());
3693  }
3694  if (fData[0].dataFourierPhaseOptReal != nullptr) {
3695  name = TString(fData[0].dataFourierPhaseOptReal->GetTitle()) + "_avg";
3696  fDataAvg.dataFourierPhaseOptReal = new TH1F(name, name, fData[0].dataFourierPhaseOptReal->GetNbinsX(),
3697  fData[0].dataFourierPhaseOptReal->GetXaxis()->GetXmin(),
3698  fData[0].dataFourierPhaseOptReal->GetXaxis()->GetXmax());
3699  }
3700  if (fData[0].theory != nullptr) {
3701  name = TString(fData[0].theory->GetTitle()) + "_avg";
3702  fDataAvg.theory = new TH1F(name, name, fData[0].theory->GetNbinsX(),
3703  fData[0].theory->GetXaxis()->GetXmin(),
3704  fData[0].theory->GetXaxis()->GetXmax());
3705  }
3706  if (fData[0].theoryFourierRe != nullptr) {
3707  name = TString(fData[0].theoryFourierRe->GetTitle()) + "_avg";
3708  fDataAvg.theoryFourierRe = new TH1F(name, name, fData[0].theoryFourierRe->GetNbinsX(),
3709  fData[0].theoryFourierRe->GetXaxis()->GetXmin(),
3710  fData[0].theoryFourierRe->GetXaxis()->GetXmax());
3711  }
3712  if (fData[0].theoryFourierIm != nullptr) {
3713  name = TString(fData[0].theoryFourierIm->GetTitle()) + "_avg";
3714  fDataAvg.theoryFourierIm = new TH1F(name, name, fData[0].theoryFourierIm->GetNbinsX(),
3715  fData[0].theoryFourierIm->GetXaxis()->GetXmin(),
3716  fData[0].theoryFourierIm->GetXaxis()->GetXmax());
3717  }
3718  if (fData[0].theoryFourierPwr != nullptr) {
3719  name = TString(fData[0].theoryFourierPwr->GetTitle()) + "_avg";
3720  fDataAvg.theoryFourierPwr = new TH1F(name, name, fData[0].theoryFourierPwr->GetNbinsX(),
3721  fData[0].theoryFourierPwr->GetXaxis()->GetXmin(),
3722  fData[0].theoryFourierPwr->GetXaxis()->GetXmax());
3723  }
3724  if (fData[0].theoryFourierPhase != nullptr) {
3725  name = TString(fData[0].theoryFourierPhase->GetTitle()) + "_avg";
3726  fDataAvg.theoryFourierPhase = new TH1F(name, name, fData[0].theoryFourierPhase->GetNbinsX(),
3727  fData[0].theoryFourierPhase->GetXaxis()->GetXmin(),
3728  fData[0].theoryFourierPhase->GetXaxis()->GetXmax());
3729  }
3730  if (fData[0].theoryFourierPhaseOptReal != nullptr) {
3731  name = TString(fData[0].theoryFourierPhaseOptReal->GetTitle()) + "_avg";
3732  fDataAvg.theoryFourierPhaseOptReal = new TH1F(name, name, fData[0].theoryFourierPhaseOptReal->GetNbinsX(),
3733  fData[0].theoryFourierPhaseOptReal->GetXaxis()->GetXmin(),
3734  fData[0].theoryFourierPhaseOptReal->GetXaxis()->GetXmax());
3735  }
3736  if (fData[0].diff != nullptr) {
3737  name = TString(fData[0].diff->GetTitle()) + "_avg";
3738  fDataAvg.diff = new TH1F(name, name, fData[0].diff->GetNbinsX(),
3739  fData[0].diff->GetXaxis()->GetXmin(),
3740  fData[0].diff->GetXaxis()->GetXmax());
3741  }
3742  if (fData[0].diffFourierRe != nullptr) {
3743  name = TString(fData[0].diffFourierRe->GetTitle()) + "_avg";
3744  fDataAvg.diffFourierRe = new TH1F(name, name, fData[0].diffFourierRe->GetNbinsX(),
3745  fData[0].diffFourierRe->GetXaxis()->GetXmin(),
3746  fData[0].diffFourierRe->GetXaxis()->GetXmax());
3747  }
3748  if (fData[0].diffFourierIm != nullptr) {
3749  name = TString(fData[0].diffFourierIm->GetTitle()) + "_avg";
3750  fDataAvg.diffFourierIm = new TH1F(name, name, fData[0].diffFourierIm->GetNbinsX(),
3751  fData[0].diffFourierIm->GetXaxis()->GetXmin(),
3752  fData[0].diffFourierIm->GetXaxis()->GetXmax());
3753  }
3754  if (fData[0].diffFourierPwr != nullptr) {
3755  name = TString(fData[0].diffFourierPwr->GetTitle()) + "_avg";
3756  fDataAvg.diffFourierPwr = new TH1F(name, name, fData[0].diffFourierPwr->GetNbinsX(),
3757  fData[0].diffFourierPwr->GetXaxis()->GetXmin(),
3758  fData[0].diffFourierPwr->GetXaxis()->GetXmax());
3759  }
3760  if (fData[0].diffFourierPhase != nullptr) {
3761  name = TString(fData[0].diffFourierPhase->GetTitle()) + "_avg";
3762  fDataAvg.diffFourierPhase = new TH1F(name, name, fData[0].diffFourierPhase->GetNbinsX(),
3763  fData[0].diffFourierPhase->GetXaxis()->GetXmin(),
3764  fData[0].diffFourierPhase->GetXaxis()->GetXmax());
3765  }
3766  if (fData[0].diffFourierPhaseOptReal != nullptr) {
3767  name = TString(fData[0].diffFourierPhaseOptReal->GetTitle()) + "_avg";
3768  fDataAvg.diffFourierPhaseOptReal = new TH1F(name, name, fData[0].diffFourierPhaseOptReal->GetNbinsX(),
3769  fData[0].diffFourierPhaseOptReal->GetXaxis()->GetXmin(),
3770  fData[0].diffFourierPhaseOptReal->GetXaxis()->GetXmax());
3771  }
3772 
3773  // calculate all the average data sets
3774  double dval;
3775  if (fDataAvg.data != nullptr) {
3776  for (Int_t i=0; i<fData[0].data->GetNbinsX(); i++) {
3777  dval = 0.0;
3778  for (UInt_t j=0; j<fData.size(); j++) {
3779  dval += GetInterpolatedValue(fData[j].data, fData[0].data->GetBinCenter(i));
3780  }
3781  fDataAvg.data->SetBinContent(i, dval/fData.size());
3782  }
3783  // set marker color, line color, maker size, marker type
3784  fDataAvg.data->SetMarkerColor(fData[0].data->GetMarkerColor());
3785  fDataAvg.data->SetLineColor(fData[0].data->GetLineColor());
3786  fDataAvg.data->SetMarkerSize(fData[0].data->GetMarkerSize());
3787  fDataAvg.data->SetMarkerStyle(fData[0].data->GetMarkerStyle());
3788  }
3789  if (fDataAvg.dataFourierRe != nullptr) {
3790  for (Int_t i=0; i<fData[0].dataFourierRe->GetNbinsX(); i++) {
3791  dval = 0.0;
3792  for (UInt_t j=0; j<fData.size(); j++) {
3793  dval += GetInterpolatedValue(fData[j].dataFourierRe, fData[0].dataFourierRe->GetBinCenter(i));
3794  }
3795  fDataAvg.dataFourierRe->SetBinContent(i, dval/fData.size());
3796  }
3797  // set marker color, line color, maker size, marker type
3798  fDataAvg.dataFourierRe->SetMarkerColor(fData[0].dataFourierRe->GetMarkerColor());
3799  fDataAvg.dataFourierRe->SetLineColor(fData[0].dataFourierRe->GetLineColor());
3800  fDataAvg.dataFourierRe->SetMarkerSize(fData[0].dataFourierRe->GetMarkerSize());
3801  fDataAvg.dataFourierRe->SetMarkerStyle(fData[0].dataFourierRe->GetMarkerStyle());
3802  }
3803  if (fDataAvg.dataFourierIm != nullptr) {
3804  for (Int_t i=0; i<fData[0].dataFourierIm->GetNbinsX(); i++) {
3805  dval = 0.0;
3806  for (UInt_t j=0; j<fData.size(); j++) {
3807  dval += GetInterpolatedValue(fData[j].dataFourierIm, fData[0].dataFourierIm->GetBinCenter(i));
3808  }
3809  fDataAvg.dataFourierIm->SetBinContent(i, dval/fData.size());
3810  }
3811  // set marker color, line color, maker size, marker type
3812  fDataAvg.dataFourierIm->SetMarkerColor(fData[0].dataFourierIm->GetMarkerColor());
3813  fDataAvg.dataFourierIm->SetLineColor(fData[0].dataFourierIm->GetLineColor());
3814  fDataAvg.dataFourierIm->SetMarkerSize(fData[0].dataFourierIm->GetMarkerSize());
3815  fDataAvg.dataFourierIm->SetMarkerStyle(fData[0].dataFourierIm->GetMarkerStyle());
3816  }
3817  if (fDataAvg.dataFourierPwr != nullptr) {
3818  for (Int_t i=0; i<fData[0].dataFourierPwr->GetNbinsX(); i++) {
3819  dval = 0.0;
3820  for (UInt_t j=0; j<fData.size(); j++) {
3821  dval += GetInterpolatedValue(fData[j].dataFourierPwr, fData[0].dataFourierPwr->GetBinCenter(i));
3822  }
3823  fDataAvg.dataFourierPwr->SetBinContent(i, dval/fData.size());
3824  }
3825  // set marker color, line color, maker size, marker type
3826  fDataAvg.dataFourierPwr->SetMarkerColor(fData[0].dataFourierPwr->GetMarkerColor());
3827  fDataAvg.dataFourierPwr->SetLineColor(fData[0].dataFourierPwr->GetLineColor());
3828  fDataAvg.dataFourierPwr->SetMarkerSize(fData[0].dataFourierPwr->GetMarkerSize());
3829  fDataAvg.dataFourierPwr->SetMarkerStyle(fData[0].dataFourierPwr->GetMarkerStyle());
3830  }
3831  if (fDataAvg.dataFourierPhase != nullptr) {
3832  for (Int_t i=0; i<fData[0].dataFourierPhase->GetNbinsX(); i++) {
3833  dval = 0.0;
3834  for (UInt_t j=0; j<fData.size(); j++) {
3835  dval += GetInterpolatedValue(fData[j].dataFourierPhase, fData[0].dataFourierPhase->GetBinCenter(i));
3836  }
3837  fDataAvg.dataFourierPhase->SetBinContent(i, dval/fData.size());
3838  }
3839  // set marker color, line color, maker size, marker type
3840  fDataAvg.dataFourierPhase->SetMarkerColor(fData[0].dataFourierPhase->GetMarkerColor());
3841  fDataAvg.dataFourierPhase->SetLineColor(fData[0].dataFourierPhase->GetLineColor());
3842  fDataAvg.dataFourierPhase->SetMarkerSize(fData[0].dataFourierPhase->GetMarkerSize());
3843  fDataAvg.dataFourierPhase->SetMarkerStyle(fData[0].dataFourierPhase->GetMarkerStyle());
3844  }
3845  if (fDataAvg.dataFourierPhaseOptReal != nullptr) {
3846  for (Int_t i=0; i<fData[0].dataFourierPhaseOptReal->GetNbinsX(); i++) {
3847  dval = 0.0;
3848  for (UInt_t j=0; j<fData.size(); j++) {
3849  dval += GetInterpolatedValue(fData[j].dataFourierPhaseOptReal, fData[0].dataFourierPhaseOptReal->GetBinCenter(i));
3850  }
3851  fDataAvg.dataFourierPhaseOptReal->SetBinContent(i, dval/fData.size());
3852  }
3853  // set marker color, line color, maker size, marker type
3854  fDataAvg.dataFourierPhaseOptReal->SetMarkerColor(fData[0].dataFourierPhaseOptReal->GetMarkerColor());
3855  fDataAvg.dataFourierPhaseOptReal->SetLineColor(fData[0].dataFourierPhaseOptReal->GetLineColor());
3856  fDataAvg.dataFourierPhaseOptReal->SetMarkerSize(fData[0].dataFourierPhaseOptReal->GetMarkerSize());
3857  fDataAvg.dataFourierPhaseOptReal->SetMarkerStyle(fData[0].dataFourierPhaseOptReal->GetMarkerStyle());
3858  }
3859  if (fDataAvg.theory != nullptr) {
3860  for (Int_t i=0; i<fData[0].theory->GetNbinsX(); i++) {
3861  dval = 0.0;
3862  for (UInt_t j=0; j<fData.size(); j++) {
3863  dval += GetInterpolatedValue(fData[j].theory, fData[0].theory->GetBinCenter(i));
3864  }
3865  fDataAvg.theory->SetBinContent(i, dval/fData.size());
3866  }
3867  fDataAvg.theory->SetLineColor(fData[0].theory->GetLineColor());
3868  }
3869  if (fDataAvg.theoryFourierRe != nullptr) {
3870  for (Int_t i=0; i<fData[0].theoryFourierRe->GetNbinsX(); i++) {
3871  dval = 0.0;
3872  for (UInt_t j=0; j<fData.size(); j++) {
3873  dval += GetInterpolatedValue(fData[j].theoryFourierRe, fData[0].theoryFourierRe->GetBinCenter(i));
3874  }
3875  fDataAvg.theoryFourierRe->SetBinContent(i, dval/fData.size());
3876  }
3877  // set marker color, line color, maker size, marker type
3878  fDataAvg.theoryFourierRe->SetMarkerColor(fData[0].theoryFourierRe->GetMarkerColor());
3879  fDataAvg.theoryFourierRe->SetLineColor(fData[0].theoryFourierRe->GetLineColor());
3880  fDataAvg.theoryFourierRe->SetMarkerSize(fData[0].theoryFourierRe->GetMarkerSize());
3881  fDataAvg.theoryFourierRe->SetMarkerStyle(fData[0].theoryFourierRe->GetMarkerStyle());
3882  }
3883  if (fDataAvg.theoryFourierIm != nullptr) {
3884  for (Int_t i=0; i<fData[0].theoryFourierIm->GetNbinsX(); i++) {
3885  dval = 0.0;
3886  for (UInt_t j=0; j<fData.size(); j++) {
3887  dval += GetInterpolatedValue(fData[j].theoryFourierIm, fData[0].theoryFourierIm->GetBinCenter(i));
3888  }
3889  fDataAvg.theoryFourierIm->SetBinContent(i, dval/fData.size());
3890  }
3891  // set marker color, line color, maker size, marker type
3892  fDataAvg.theoryFourierIm->SetMarkerColor(fData[0].theoryFourierIm->GetMarkerColor());
3893  fDataAvg.theoryFourierIm->SetLineColor(fData[0].theoryFourierIm->GetLineColor());
3894  fDataAvg.theoryFourierIm->SetMarkerSize(fData[0].theoryFourierIm->GetMarkerSize());
3895  fDataAvg.theoryFourierIm->SetMarkerStyle(fData[0].theoryFourierIm->GetMarkerStyle());
3896  }
3897  if (fDataAvg.theoryFourierPwr != nullptr) {
3898  for (Int_t i=0; i<fData[0].theoryFourierPwr->GetNbinsX(); i++) {
3899  dval = 0.0;
3900  for (UInt_t j=0; j<fData.size(); j++) {
3901  dval += GetInterpolatedValue(fData[j].theoryFourierPwr, fData[0].theoryFourierPwr->GetBinCenter(i));
3902  }
3903  fDataAvg.theoryFourierPwr->SetBinContent(i, dval/fData.size());
3904  }
3905  // set marker color, line color, maker size, marker type
3906  fDataAvg.theoryFourierPwr->SetMarkerColor(fData[0].theoryFourierPwr->GetMarkerColor());
3907  fDataAvg.theoryFourierPwr->SetLineColor(fData[0].theoryFourierPwr->GetLineColor());
3908  fDataAvg.theoryFourierPwr->SetMarkerSize(fData[0].theoryFourierPwr->GetMarkerSize());
3909  fDataAvg.theoryFourierPwr->SetMarkerStyle(fData[0].theoryFourierPwr->GetMarkerStyle());
3910  }
3911  if (fDataAvg.theoryFourierPhase != nullptr) {
3912  for (Int_t i=0; i<fData[0].theoryFourierPhase->GetNbinsX(); i++) {
3913  dval = 0.0;
3914  for (UInt_t j=0; j<fData.size(); j++) {
3915  dval += GetInterpolatedValue(fData[j].theoryFourierPhase, fData[0].theoryFourierPhase->GetBinCenter(i));
3916  }
3917  fDataAvg.theoryFourierPhase->SetBinContent(i, dval/fData.size());
3918  }
3919  // set marker color, line color, maker size, marker type
3920  fDataAvg.theoryFourierPhase->SetMarkerColor(fData[0].theoryFourierPhase->GetMarkerColor());
3921  fDataAvg.theoryFourierPhase->SetLineColor(fData[0].theoryFourierPhase->GetLineColor());
3922  fDataAvg.theoryFourierPhase->SetMarkerSize(fData[0].theoryFourierPhase->GetMarkerSize());
3923  fDataAvg.theoryFourierPhase->SetMarkerStyle(fData[0].theoryFourierPhase->GetMarkerStyle());
3924  }
3925  if (fDataAvg.theoryFourierPhaseOptReal != nullptr) {
3926  for (Int_t i=0; i<fData[0].theoryFourierPhaseOptReal->GetNbinsX(); i++) {
3927  dval = 0.0;
3928  for (UInt_t j=0; j<fData.size(); j++) {
3929  dval += GetInterpolatedValue(fData[j].theoryFourierPhaseOptReal, fData[0].theoryFourierPhaseOptReal->GetBinCenter(i));
3930  }
3931  fDataAvg.theoryFourierPhaseOptReal->SetBinContent(i, dval/fData.size());
3932  }
3933  // set marker color, line color, maker size, marker type
3934  fDataAvg.theoryFourierPhaseOptReal->SetMarkerColor(fData[0].theoryFourierPhaseOptReal->GetMarkerColor());
3935  fDataAvg.theoryFourierPhaseOptReal->SetLineColor(fData[0].theoryFourierPhaseOptReal->GetLineColor());
3936  fDataAvg.theoryFourierPhaseOptReal->SetMarkerSize(fData[0].theoryFourierPhaseOptReal->GetMarkerSize());
3937  fDataAvg.theoryFourierPhaseOptReal->SetMarkerStyle(fData[0].theoryFourierPhaseOptReal->GetMarkerStyle());
3938  }
3939  if (fDataAvg.diff != nullptr) {
3940  for (Int_t i=0; i<fData[0].diff->GetNbinsX(); i++) {
3941  dval = 0.0;
3942  for (UInt_t j=0; j<fData.size(); j++) {
3943  dval += GetInterpolatedValue(fData[j].diff, fData[0].diff->GetBinCenter(i));
3944  }
3945  fDataAvg.diff->SetBinContent(i, dval/fData.size());
3946  }
3947  // set marker color, line color, maker size, marker type
3948  fDataAvg.diff->SetMarkerColor(fData[0].diff->GetMarkerColor());
3949  fDataAvg.diff->SetLineColor(fData[0].diff->GetLineColor());
3950  fDataAvg.diff->SetMarkerSize(fData[0].diff->GetMarkerSize());
3951  fDataAvg.diff->SetMarkerStyle(fData[0].diff->GetMarkerStyle());
3952  }
3953  if (fDataAvg.diffFourierRe != nullptr) {
3954  for (Int_t i=0; i<fData[0].diffFourierRe->GetNbinsX(); i++) {
3955  dval = 0.0;
3956  for (UInt_t j=0; j<fData.size(); j++) {
3957  dval += GetInterpolatedValue(fData[j].diffFourierRe, fData[0].diffFourierRe->GetBinCenter(i));
3958  }
3959  fDataAvg.diffFourierRe->SetBinContent(i, dval/fData.size());
3960  }
3961  // set marker color, line color, maker size, marker type
3962  fDataAvg.diffFourierRe->SetMarkerColor(fData[0].diffFourierRe->GetMarkerColor());
3963  fDataAvg.diffFourierRe->SetLineColor(fData[0].diffFourierRe->GetLineColor());
3964  fDataAvg.diffFourierRe->SetMarkerSize(fData[0].diffFourierRe->GetMarkerSize());
3965  fDataAvg.diffFourierRe->SetMarkerStyle(fData[0].diffFourierRe->GetMarkerStyle());
3966  }
3967  if (fDataAvg.diffFourierIm != nullptr) {
3968  for (Int_t i=0; i<fData[0].diffFourierIm->GetNbinsX(); i++) {
3969  dval = 0.0;
3970  for (UInt_t j=0; j<fData.size(); j++) {
3971  dval += GetInterpolatedValue(fData[j].diffFourierIm, fData[0].diffFourierIm->GetBinCenter(i));
3972  }
3973  fDataAvg.diffFourierIm->SetBinContent(i, dval/fData.size());
3974  }
3975  // set marker color, line color, maker size, marker type
3976  fDataAvg.diffFourierIm->SetMarkerColor(fData[0].diffFourierIm->GetMarkerColor());
3977  fDataAvg.diffFourierIm->SetLineColor(fData[0].diffFourierIm->GetLineColor());
3978  fDataAvg.diffFourierIm->SetMarkerSize(fData[0].diffFourierIm->GetMarkerSize());
3979  fDataAvg.diffFourierIm->SetMarkerStyle(fData[0].diffFourierIm->GetMarkerStyle());
3980  }
3981  if (fDataAvg.diffFourierPwr != nullptr) {
3982  for (Int_t i=0; i<fData[0].diffFourierPwr->GetNbinsX(); i++) {
3983  dval = 0.0;
3984  for (UInt_t j=0; j<fData.size(); j++) {
3985  dval += GetInterpolatedValue(fData[j].diffFourierPwr, fData[0].diffFourierPwr->GetBinCenter(i));
3986  }
3987  fDataAvg.diffFourierPwr->SetBinContent(i, dval/fData.size());
3988  }
3989  // set marker color, line color, maker size, marker type
3990  fDataAvg.diffFourierPwr->SetMarkerColor(fData[0].diffFourierPwr->GetMarkerColor());
3991  fDataAvg.diffFourierPwr->SetLineColor(fData[0].diffFourierPwr->GetLineColor());
3992  fDataAvg.diffFourierPwr->SetMarkerSize(fData[0].diffFourierPwr->GetMarkerSize());
3993  fDataAvg.diffFourierPwr->SetMarkerStyle(fData[0].diffFourierPwr->GetMarkerStyle());
3994  }
3995  if (fDataAvg.diffFourierPhase != nullptr) {
3996  for (Int_t i=0; i<fData[0].diffFourierPhase->GetNbinsX(); i++) {
3997  dval = 0.0;
3998  for (UInt_t j=0; j<fData.size(); j++) {
3999  dval += GetInterpolatedValue(fData[j].diffFourierPhase, fData[0].diffFourierPhase->GetBinCenter(i));
4000  }
4001  fDataAvg.diffFourierPhase->SetBinContent(i, dval/fData.size());
4002  }
4003  // set marker color, line color, maker size, marker type
4004  fDataAvg.diffFourierPhase->SetMarkerColor(fData[0].diffFourierPhase->GetMarkerColor());
4005  fDataAvg.diffFourierPhase->SetLineColor(fData[0].diffFourierPhase->GetLineColor());
4006  fDataAvg.diffFourierPhase->SetMarkerSize(fData[0].diffFourierPhase->GetMarkerSize());
4007  fDataAvg.diffFourierPhase->SetMarkerStyle(fData[0].diffFourierPhase->GetMarkerStyle());
4008  }
4009  if (fDataAvg.diffFourierPhaseOptReal != nullptr) {
4010  for (Int_t i=0; i<fData[0].diffFourierPhaseOptReal->GetNbinsX(); i++) {
4011  dval = 0.0;
4012  for (UInt_t j=0; j<fData.size(); j++) {
4013  dval += GetInterpolatedValue(fData[j].diffFourierPhaseOptReal, fData[0].diffFourierPhaseOptReal->GetBinCenter(i));
4014  }
4015  fDataAvg.diffFourierPhaseOptReal->SetBinContent(i, dval/fData.size());
4016  }
4017  // set marker color, line color, maker size, marker type
4018  fDataAvg.diffFourierPhaseOptReal->SetMarkerColor(fData[0].dataFourierPhaseOptReal->GetMarkerColor());
4019  fDataAvg.diffFourierPhaseOptReal->SetLineColor(fData[0].dataFourierPhaseOptReal->GetLineColor());
4020  fDataAvg.diffFourierPhaseOptReal->SetMarkerSize(fData[0].dataFourierPhaseOptReal->GetMarkerSize());
4021  fDataAvg.diffFourierPhaseOptReal->SetMarkerStyle(fData[0].dataFourierPhaseOptReal->GetMarkerStyle());
4022  }
4023 }
4024 
4025 //--------------------------------------------------------------------------
4026 // CleanupDifference (private)
4027 //--------------------------------------------------------------------------
4032 {
4033  for (UInt_t i=0; i<fData.size(); i++) {
4034  if (fData[i].diff != nullptr) {
4035  delete fData[i].diff;
4036  fData[i].diff = nullptr;
4037  }
4038  }
4039 }
4040 
4041 //--------------------------------------------------------------------------
4042 // CleanupFourier (private)
4043 //--------------------------------------------------------------------------
4048 {
4049  for (UInt_t i=0; i<fData.size(); i++) {
4050  if (fData[i].dataFourierRe != nullptr) {
4051  delete fData[i].dataFourierRe;
4052  fData[i].dataFourierRe = nullptr;
4053  }
4054  if (fData[i].dataFourierIm != nullptr) {
4055  delete fData[i].dataFourierIm;
4056  fData[i].dataFourierIm = nullptr;
4057  }
4058  if (fData[i].dataFourierPwr != nullptr) {
4059  delete fData[i].dataFourierPwr;
4060  fData[i].dataFourierPwr = nullptr;
4061  }
4062  if (fData[i].dataFourierPhase != nullptr) {
4063  delete fData[i].dataFourierPhase;
4064  fData[i].dataFourierPhase = nullptr;
4065  }
4066  if (fData[i].dataFourierPhaseOptReal != nullptr) {
4067  delete fData[i].dataFourierPhaseOptReal;
4068  fData[i].dataFourierPhaseOptReal = nullptr;
4069  }
4070  if (fData[i].theoryFourierRe != nullptr) {
4071  delete fData[i].theoryFourierRe;
4072  fData[i].theoryFourierRe = nullptr;
4073  }
4074  if (fData[i].theoryFourierIm != nullptr) {
4075  delete fData[i].theoryFourierIm;
4076  fData[i].theoryFourierIm = nullptr;
4077  }
4078  if (fData[i].theoryFourierPwr != nullptr) {
4079  delete fData[i].theoryFourierPwr;
4080  fData[i].theoryFourierPwr = nullptr;
4081  }
4082  if (fData[i].theoryFourierPhase != nullptr) {
4083  delete fData[i].theoryFourierPhase;
4084  fData[i].theoryFourierPhase = nullptr;
4085  }
4086  if (fData[i].theoryFourierPhaseOptReal != nullptr) {
4087  delete fData[i].theoryFourierPhaseOptReal;
4088  fData[i].theoryFourierPhaseOptReal = nullptr;
4089  }
4090  }
4091 }
4092 
4093 //--------------------------------------------------------------------------
4094 // CleanupFourierDifference (private)
4095 //--------------------------------------------------------------------------
4100 {
4101  for (UInt_t i=0; i<fData.size(); i++) {
4102  if (fData[i].diffFourierRe != nullptr) {
4103  delete fData[i].diffFourierRe;
4104  fData[i].diffFourierRe = nullptr;
4105  }
4106  if (fData[i].diffFourierIm != nullptr) {
4107  delete fData[i].diffFourierIm;
4108  fData[i].diffFourierIm = nullptr;
4109  }
4110  if (fData[i].diffFourierPwr != nullptr) {
4111  delete fData[i].diffFourierPwr;
4112  fData[i].diffFourierPwr = nullptr;
4113  }
4114  if (fData[i].diffFourierPhase != nullptr) {
4115  delete fData[i].diffFourierPhase;
4116  fData[i].diffFourierPhase = nullptr;
4117  }
4118  if (fData[i].diffFourierPhaseOptReal != nullptr) {
4119  delete fData[i].diffFourierPhaseOptReal;
4120  fData[i].diffFourierPhaseOptReal = nullptr;
4121  }
4122  }
4123 }
4124 
4125 //--------------------------------------------------------------------------
4126 // CleanupAverage (private)
4127 //--------------------------------------------------------------------------
4132 {
4133  if (fDataAvg.data != nullptr) {
4134  delete fDataAvg.data;
4135  fDataAvg.data = nullptr;
4136  }
4137  if (fDataAvg.dataFourierRe != nullptr) {
4138  delete fDataAvg.dataFourierRe;
4139  fDataAvg.dataFourierRe = nullptr;
4140  }
4141  if (fDataAvg.dataFourierIm != nullptr) {
4142  delete fDataAvg.dataFourierIm;
4143  fDataAvg.dataFourierIm = nullptr;
4144  }
4145  if (fDataAvg.dataFourierPwr != nullptr) {
4146  delete fDataAvg.dataFourierPwr;
4147  fDataAvg.dataFourierPwr = nullptr;
4148  }
4149  if (fDataAvg.dataFourierPhase != nullptr) {
4150  delete fDataAvg.dataFourierPhase;
4151  fDataAvg.dataFourierPhase = nullptr;
4152  }
4153  if (fDataAvg.dataFourierPhaseOptReal != nullptr) {
4156  }
4157  if (fDataAvg.theory != nullptr) {
4158  delete fDataAvg.theory;
4159  fDataAvg.theory = nullptr;
4160  }
4161  if (fDataAvg.theoryFourierRe != nullptr) {
4162  delete fDataAvg.theoryFourierRe;
4163  fDataAvg.theoryFourierRe = nullptr;
4164  }
4165  if (fDataAvg.theoryFourierIm != nullptr) {
4166  delete fDataAvg.theoryFourierIm;
4167  fDataAvg.theoryFourierIm = nullptr;
4168  }
4169  if (fDataAvg.theoryFourierPwr != nullptr) {
4170  delete fDataAvg.theoryFourierPwr;
4171  fDataAvg.theoryFourierPwr = nullptr;
4172  }
4173  if (fDataAvg.theoryFourierPhase != nullptr) {
4175  fDataAvg.theoryFourierPhase = nullptr;
4176  }
4177  if (fDataAvg.theoryFourierPhaseOptReal != nullptr) {
4180  }
4181  if (fDataAvg.diff != nullptr) {
4182  delete fDataAvg.diff;
4183  fDataAvg.diff = nullptr;
4184  }
4185  if (fDataAvg.diffFourierRe != nullptr) {
4186  delete fDataAvg.diffFourierRe;
4187  fDataAvg.diffFourierRe = nullptr;
4188  }
4189  if (fDataAvg.diffFourierIm != nullptr) {
4190  delete fDataAvg.diffFourierIm;
4191  fDataAvg.diffFourierIm = nullptr;
4192  }
4193  if (fDataAvg.diffFourierPwr != nullptr) {
4194  delete fDataAvg.diffFourierPwr;
4195  fDataAvg.diffFourierPwr = nullptr;
4196  }
4197  if (fDataAvg.diffFourierPhase != nullptr) {
4198  delete fDataAvg.diffFourierPhase;
4199  fDataAvg.diffFourierPhase = nullptr;
4200  }
4201  if (fDataAvg.diffFourierPhaseOptReal != nullptr) {
4204  }
4205 }
4206 
4207 //--------------------------------------------------------------------------
4208 // CalculateDiff (private)
4209 //--------------------------------------------------------------------------
4214 {
4217 
4218  if ((min == -1.0) && (max == -1.0)) {
4219  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
4220  min = fFourier.fPlotRange[0];
4221  max = fFourier.fPlotRange[1];
4222  } else {
4223  min = fData[0].dataFourierRe->GetBinLowEdge(1);
4224  max = fData[0].dataFourierRe->GetBinLowEdge(fData[0].dataFourierRe->GetNbinsX())+fData[0].dataFourierRe->GetBinWidth(1);
4225  }
4226  }
4227 
4228  PDoubleVector phaseParam;
4229  Char_t hName[1024];
4230  Double_t ph, re;
4231 
4232  for (UInt_t i=0; i<fData.size(); i++) {
4233  // handle Fourier data part
4234  fData[i].dataFourierPhaseOptReal = PFourier::GetPhaseOptRealFourier(fData[i].dataFourierRe, fData[i].dataFourierIm,
4235  phaseParam, 1.0, min, max);
4236  // set marker and line color
4237  fData[i].dataFourierPhaseOptReal->SetMarkerColor(fData[i].data->GetMarkerColor());
4238  fData[i].dataFourierPhaseOptReal->SetLineColor(fData[i].data->GetLineColor());
4239  // set marker size
4240  fData[i].dataFourierPhaseOptReal->SetMarkerSize(1);
4241  // set marker type
4242  fData[i].dataFourierPhaseOptReal->SetMarkerStyle(fData[i].data->GetMarkerStyle());
4243 
4244  // handle Fourier theory part
4245  // clone theory Re FT
4246  strcpy(hName, fData[i].theoryFourierPhase->GetName());
4247  strcat(hName, "_Opt_Real");
4248  fData[i].theoryFourierPhaseOptReal = (TH1F*) fData[i].theoryFourierRe->Clone(hName);
4249 
4250  // rotate the theory according to the optimized phase parameters
4251  // first find minBin for min of the phase correction
4252  Int_t minBin = fData[i].theoryFourierPhaseOptReal->GetXaxis()->FindFixBin(min);
4253  Int_t maxBin = fData[i].theoryFourierPhaseOptReal->GetXaxis()->FindFixBin(max);
4254 
4255  for (Int_t j=1; j<fData[i].theoryFourierPhaseOptReal->GetNbinsX(); j++) {
4256  ph = phaseParam[0] + phaseParam[1] * (Double_t)(j-minBin+1) / (Double_t)(maxBin-minBin);
4257  re = fData[i].theoryFourierRe->GetBinContent(j) * cos(ph) - fData[i].theoryFourierIm->GetBinContent(j) * sin(ph);
4258  fData[i].theoryFourierPhaseOptReal->SetBinContent(j, re);
4259  }
4260  // set line colors for the theory
4261  fData[i].theoryFourierPhaseOptReal->SetLineColor(fData[i].theory->GetLineColor());
4262  }
4263 }
4264 
4265 //--------------------------------------------------------------------------
4266 // CalculateDiff (private)
4267 //--------------------------------------------------------------------------
4278 double PMusrCanvas::CalculateDiff(const Double_t x, const Double_t y, TH1F *theo)
4279 {
4280  Int_t bin = theo->FindBin(x);
4281 
4282  return y - theo->GetBinContent(bin);
4283 }
4284 
4285 //--------------------------------------------------------------------------
4286 // CalculateDiff (private)
4287 //--------------------------------------------------------------------------
4298 double PMusrCanvas::CalculateDiff(const Double_t x, const Double_t y, TGraphErrors *theo)
4299 {
4300  Int_t bin = 0;
4301  Double_t xVal, yVal;
4302 
4303  bin = FindBin(x, theo);
4304 
4305  theo->GetPoint(bin, xVal, yVal);
4306 
4307  return y - yVal;
4308 }
4309 
4310 //--------------------------------------------------------------------------
4311 // FindBin (private)
4312 //--------------------------------------------------------------------------
4322 Int_t PMusrCanvas::FindBin(const Double_t x, TGraphErrors *graph)
4323 {
4324  Int_t i, bin = 0;
4325  Double_t *xTheo = graph->GetX();
4326 
4327  // find proper bin of the graph
4328  for (i=0; i<graph->GetN(); i++) {
4329  if (*(xTheo+i) >= x) {
4330  bin = i;
4331  break;
4332  }
4333  }
4334  // in case it is the last point
4335  if (i == graph->GetN()) {
4336  bin = i;
4337  }
4338 
4339  return bin;
4340 }
4341 
4342 //--------------------------------------------------------------------------
4343 // GetMaximum (private)
4344 //--------------------------------------------------------------------------
4356 Double_t PMusrCanvas::GetMaximum(TH1F* histo, Double_t xmin, Double_t xmax)
4357 {
4358  if (histo == nullptr)
4359  return 0.0;
4360 
4361  Int_t start=0, end=0;
4362  if (xmin == xmax) {
4363  start = 1;
4364  end = histo->GetNbinsX();
4365  } else {
4366  start = histo->FindBin(xmin);
4367  if ((start==0) || (start==histo->GetNbinsX()+1)) // underflow/overflow
4368  start = 1;
4369  end = histo->FindBin(xmax);
4370  if ((end==0) || (end==histo->GetNbinsX()+1)) // underflow/overflow
4371  end = histo->GetNbinsX();
4372  }
4373 
4374  Double_t max = histo->GetBinContent(start);
4375  Double_t binContent;
4376  for (Int_t i=start; i<end; i++) {
4377  binContent = histo->GetBinContent(i);
4378  if (max < binContent)
4379  max = binContent;
4380  }
4381 
4382  return max;
4383 }
4384 
4385 //--------------------------------------------------------------------------
4386 // GetMinimum (private)
4387 //--------------------------------------------------------------------------
4399 Double_t PMusrCanvas::GetMinimum(TH1F* histo, Double_t xmin, Double_t xmax)
4400 {
4401  if (histo == nullptr)
4402  return 0.0;
4403 
4404  Int_t start=0, end=0;
4405  if (xmin == xmax) {
4406  start = 1;
4407  end = histo->GetNbinsX();
4408  } else {
4409  start = histo->FindBin(xmin);
4410  if ((start==0) || (start==histo->GetNbinsX()+1)) // underflow/overflow
4411  start = 1;
4412  end = histo->FindBin(xmax);
4413  if ((end==0) || (end==histo->GetNbinsX()+1)) // underflow/overflow
4414  end = histo->GetNbinsX();
4415  }
4416 
4417  Double_t min = histo->GetBinContent(start);
4418  Double_t binContent;
4419  for (Int_t i=start; i<end; i++) {
4420  binContent = histo->GetBinContent(i);
4421  if (min > binContent)
4422  min = binContent;
4423  }
4424 
4425  return min;
4426 }
4427 
4428 //--------------------------------------------------------------------------
4429 // GetMaximum (private)
4430 //--------------------------------------------------------------------------
4442 Double_t PMusrCanvas::GetMaximum(TGraphErrors* graph, Double_t xmin, Double_t xmax)
4443 {
4444  if (graph == nullptr)
4445  return 0.0;
4446 
4447  Double_t x, y;
4448  if (xmin == xmax) {
4449  graph->GetPoint(0, x, y);
4450  xmin = x;
4451  graph->GetPoint(graph->GetN()-1, x, y);
4452  xmax = x;
4453  }
4454 
4455  graph->GetPoint(0, x, y);
4456  Double_t max = y;
4457  for (Int_t i=0; i<graph->GetN(); i++) {
4458  graph->GetPoint(i, x, y);
4459  if ((x >= xmin) && (x <= xmax)) {
4460  if (y > max)
4461  max = y;
4462  }
4463  }
4464 
4465  return max;
4466 }
4467 
4468 //--------------------------------------------------------------------------
4469 // GetMinimum (private)
4470 //--------------------------------------------------------------------------
4482 Double_t PMusrCanvas::GetMinimum(TGraphErrors* graph, Double_t xmin, Double_t xmax)
4483 {
4484  if (graph == nullptr)
4485  return 0.0;
4486 
4487  Double_t x, y;
4488  if (xmin == xmax) {
4489  graph->GetPoint(0, x, y);
4490  xmin = x;
4491  graph->GetPoint(graph->GetN()-1, x, y);
4492  xmax = x;
4493  }
4494 
4495  graph->GetPoint(0, x, y);
4496  Double_t min = y;
4497  for (Int_t i=0; i<graph->GetN(); i++) {
4498  graph->GetPoint(i, x, y);
4499  if ((x >= xmin) && (x <= xmax)) {
4500  if (y < min)
4501  min = y;
4502  }
4503  }
4504 
4505  return min;
4506 }
4507 
4508 //--------------------------------------------------------------------------
4509 // PlotData (private)
4510 //--------------------------------------------------------------------------
4516 void PMusrCanvas::PlotData(Bool_t unzoom)
4517 {
4518  fDataTheoryPad->cd();
4519 
4520  if (!fBatchMode) {
4521  // uncheck fourier menu entries
4522  fPopupFourier->UnCheckEntries();
4523  }
4524 
4525  if (fPlotType < 0) // plot type not defined
4526  return;
4527 
4528  Double_t xmin, xmax;
4529  if (fPlotType != MSR_PLOT_NON_MUSR) {
4530  if (fData.size() > 0) {
4531 
4532  // keep the current x-axis range from the data view
4533  if (fHistoFrame && (fPreviousPlotView == PV_DATA)) {
4534  xmin = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetFirst());
4535  xmax = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetLast()) + fHistoFrame->GetXaxis()->GetBinWidth(fHistoFrame->GetXaxis()->GetLast());
4536  } else {
4537  xmin = fXmin;
4538  xmax = fXmax;
4539  }
4540 
4541  // delete old fHistoFrame if present
4542  if (fHistoFrame) {
4543  delete fHistoFrame;
4544  fHistoFrame = nullptr;
4545  }
4546 
4547  // get the histo frame x/y range boundaries
4548  Double_t dataXmin=0.0, dataXmax=0.0, dataYmin=0.0, dataYmax=0.0;
4549  if (unzoom) { // set the x-/y-range back to the original msr-file values
4550  dataXmin = fXmin;
4551  dataXmax = fXmax;
4552  if (fYRangePresent) {
4553  dataYmin = fYmin;
4554  dataYmax = fYmax;
4555  } else {
4556  dataYmin = GetMinimum(fData[0].data, dataXmin, dataXmax);
4557  dataYmax = GetMaximum(fData[0].data, dataXmin, dataXmax);
4558  for (UInt_t i=1; i<fData.size(); i++) {
4559  if (GetMinimum(fData[i].data, dataXmin, dataXmax) < dataYmin)
4560  dataYmin = GetMinimum(fData[i].data, dataXmin, dataXmax);
4561  if (GetMaximum(fData[i].data, dataXmin, dataXmax) > dataYmax)
4562  dataYmax = GetMaximum(fData[i].data, dataXmin, dataXmax);
4563  }
4564  Double_t dd = 0.05*fabs(dataYmax-dataYmin);
4565  dataYmin -= dd;
4566  dataYmax += dd;
4567  }
4568  } else { // set the x-/y-range to the previous fHistoFrame range
4569  dataXmin = xmin;
4570  dataXmax = xmax;
4571  if (fYRangePresent) { // explicit y-range present
4572  dataYmin = fYmin;
4573  dataYmax = fYmax;
4574  } else { // extract global min/max in order to have the proper y-range
4575  dataYmin = GetMinimum(fData[0].data, dataXmin, dataXmax);
4576  dataYmax = GetMaximum(fData[0].data, dataXmin, dataXmax);
4577  for (UInt_t i=1; i<fData.size(); i++) {
4578  if (GetMinimum(fData[i].data, dataXmin, dataXmax) < dataYmin)
4579  dataYmin = GetMinimum(fData[i].data, dataXmin, dataXmax);
4580  if (GetMaximum(fData[i].data, dataXmin, dataXmax) > dataYmax)
4581  dataYmax = GetMaximum(fData[i].data, dataXmin, dataXmax);
4582  }
4583  Double_t dd = 0.05*fabs(dataYmax-dataYmin);
4584  dataYmin -= dd;
4585  dataYmax += dd;
4586  }
4587  }
4588  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) {
4589  dataYmin = 1.0e-4 * dataYmax;
4590  }
4591 
4592  // create histo frame in order to plot histograms possibly with different x-frames
4593  fHistoFrame = fDataTheoryPad->DrawFrame(dataXmin, dataYmin, dataXmax, dataYmax);
4594 
4595  // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one
4596  UInt_t noOfPoints = 1000;
4597  for (UInt_t i=0; i<fData.size(); i++) {
4598  if (fData[i].data->GetNbinsX() > (Int_t)noOfPoints)
4599  noOfPoints = fData[i].data->GetNbinsX();
4600  }
4601  noOfPoints *= 2; // make sure that there are enough points
4602  fHistoFrame->SetBins(noOfPoints, dataXmin, dataXmax);
4603 
4604  // set all histo/theory ranges properly
4605  for (UInt_t i=0; i<fData.size(); i++) {
4606  fData[i].data->GetXaxis()->SetRange(fData[i].data->FindBin(dataXmin), fData[i].data->FindBin(dataXmax));
4607  fData[i].data->GetYaxis()->SetRangeUser(dataYmin, dataYmax);
4608  fData[i].theory->GetXaxis()->SetRange(fData[i].theory->FindBin(dataXmin), fData[i].theory->FindBin(dataXmax));
4609  fData[i].theory->GetYaxis()->SetRangeUser(dataYmin, dataYmax);
4610  }
4611 
4612  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX)
4613  fDataTheoryPad->SetLogx(1);
4614  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY)
4615  fDataTheoryPad->SetLogy(1);
4616 
4617  // set x-axis label
4618  if (fPlotType == MSR_PLOT_BNMR ) {
4619  // For BNMR/BNQR runs use seconds
4620  fHistoFrame->GetXaxis()->SetTitle("time (s)");
4621  } else {
4622  fHistoFrame->GetXaxis()->SetTitle("time (#mus)");
4623  }
4624 
4625  // set y-axis label
4626  TString yAxisTitle;
4627  PMsrRunList *runList = fMsrHandler->GetMsrRunList();
4628  switch (fPlotType) {
4629  case MSR_PLOT_SINGLE_HISTO:
4630  if (runList->at(0).IsLifetimeCorrected()) { // lifetime correction
4631  yAxisTitle = "Asymmetry";
4632  } else { // no liftime correction
4633  if (fScaleN0AndBkg)
4634  yAxisTitle = "N(t) per nsec";
4635  else
4636  yAxisTitle = "N(t) per bin";
4637  }
4638  break;
4640  case MSR_PLOT_ASYM_RRF:
4641  yAxisTitle = "RRF Asymmetry";
4642  break;
4643  case MSR_PLOT_ASYM:
4644  yAxisTitle = "Asymmetry";
4645  break;
4646  case MSR_PLOT_BNMR:
4647  yAxisTitle = "Asymmetry";
4648  break;
4649  case MSR_PLOT_MU_MINUS:
4650  yAxisTitle = "N(t) per bin";
4651  break;
4652  default:
4653  yAxisTitle = "??";
4654  break;
4655  }
4656  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
4657  fHistoFrame->GetYaxis()->SetTitle(yAxisTitle.Data());
4658  // plot all data
4659  for (UInt_t i=0; i<fData.size(); i++) {
4660  fData[i].data->Draw("pesame");
4661  }
4662  // plot all the theory
4663  for (UInt_t i=0; i<fData.size(); i++) {
4664  fData[i].theory->Draw("lsame");
4665  }
4666  }
4667 
4668  // check if RRF and if yes show a label
4669  if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) {
4670  fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data());
4671  }
4672  } else { // fPlotType == MSR_PLOT_NO_MUSR
4673  // keep the current x-axis range from the data view
4675  xmin = fMultiGraphDiff->GetXaxis()->GetBinCenter(fMultiGraphDiff->GetXaxis()->GetFirst());
4676  xmax = fMultiGraphDiff->GetXaxis()->GetBinCenter(fMultiGraphDiff->GetXaxis()->GetLast());
4677  } else {
4678  xmin = fXmin;
4679  xmax = fXmax;
4680  }
4681 
4682  // tell the canvas that the selected object (the one under the mouse pointer) is not your object, before to actually delete it.
4683  fMainCanvas->SetSelected(fMainCanvas->GetPadSave());
4684 
4685  // cleanup if previous fMultiGraphData is present
4686  if (fMultiGraphData) {
4687  delete fMultiGraphData;
4688  fMultiGraphData = nullptr;
4689  }
4690  if (fMultiGraphDiff) {
4691  delete fMultiGraphDiff;
4692  fMultiGraphDiff = nullptr;
4693  }
4694 
4697  UInt_t runNo = (UInt_t)plotInfo.fRuns[0]-1;
4698  TString xAxisTitle = fRunList->GetXAxisTitle(*runs[runNo].GetRunName(), runNo);
4699  TString yAxisTitle = fRunList->GetYAxisTitle(*runs[runNo].GetRunName(), runNo);
4700 
4701  if (fNonMusrData.size() > 0) {
4702 
4703  // get the histo frame x/y range boundaries
4704  Double_t dataXmin=0.0, dataXmax=0.0, dataYmin=0.0, dataYmax=0.0;
4705  if (unzoom) { // set the x-/y-range back to the original msr-file values
4706  dataXmin = fXmin;
4707  dataXmax = fXmax;
4708  if (fYRangePresent) {
4709  dataYmin = fYmin;
4710  dataYmax = fYmax;
4711  } else {
4712  dataYmin = GetMinimum(fNonMusrData[0].data, dataXmin, dataXmax);
4713  dataYmax = GetMaximum(fNonMusrData[0].data, dataXmin, dataXmax);
4714  for (UInt_t i=1; i<fNonMusrData.size(); i++) {
4715  if (GetMinimum(fNonMusrData[i].data, dataXmin, dataXmax) < dataYmin)
4716  dataYmin = GetMinimum(fNonMusrData[i].data, dataXmin, dataXmax);
4717  if (GetMaximum(fNonMusrData[i].data, dataXmin, dataXmax) > dataYmax)
4718  dataYmax = GetMaximum(fNonMusrData[i].data, dataXmin, dataXmax);
4719  }
4720  Double_t dd = 0.05*fabs(dataYmax-dataYmin);
4721  dataYmin -= dd;
4722  dataYmax += dd;
4723  }
4724  } else { // set the x-/y-range to the previous fHistoFrame range
4725  dataXmin = xmin;
4726  dataXmax = xmax;
4727  if (fYRangePresent) { // explicit y-range present
4728  dataYmin = fYmin;
4729  dataYmax = fYmax;
4730  } else { // extract global min/max in order to have the proper y-range
4731  dataYmin = GetMinimum(fNonMusrData[0].data, dataXmin, dataXmax);
4732  dataYmax = GetMaximum(fNonMusrData[0].data, dataXmin, dataXmax);
4733  for (UInt_t i=1; i<fNonMusrData.size(); i++) {
4734  if (GetMinimum(fNonMusrData[i].data, dataXmin, dataXmax) < dataYmin)
4735  dataYmin = GetMinimum(fNonMusrData[i].data, dataXmin, dataXmax);
4736  if (GetMaximum(fNonMusrData[i].data, dataXmin, dataXmax) > dataYmax)
4737  dataYmax = GetMaximum(fNonMusrData[i].data, dataXmin, dataXmax);
4738  }
4739  Double_t dd = 0.05*fabs(dataYmax-dataYmin);
4740  dataYmin -= dd;
4741  dataYmax += dd;
4742  }
4743  }
4744  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) {
4745  if (dataYmin <= 0.0)
4746  dataYmin = 1.0e-4 * dataYmax;
4747  }
4748 
4749  // create fMultiGraphData, and add all data and theory
4750  fMultiGraphData = new TMultiGraph();
4751  assert(fMultiGraphData != nullptr);
4752 
4753  // add all data to fMultiGraphData
4754  for (UInt_t i=0; i<fNonMusrData.size(); i++) {
4755  // the next three lines are ugly but needed for the following reasons:
4756  // TMultiGraph is taking ownership of the TGraphErrors, hence a deep copy is needed.
4757  // This is not resulting in a memory leak, since the TMultiGraph object will do the cleanup
4758  TGraphErrors *ge = new TGraphErrors(*(fNonMusrData[i].data));
4759  // Data points and model curves should be fixed on the graph and not dragged around using, e.g., the mouse.
4760  ge->SetEditable(false);
4761  fMultiGraphData->Add(ge, "p");
4762  }
4763  // add all the theory to fMultiGraphData
4764  for (UInt_t i=0; i<fNonMusrData.size(); i++) {
4765  // the next three lines are ugly but needed for the following reasons:
4766  // TMultiGraph is taking ownership of the TGraphErrors, hence a deep copy is needed.
4767  // This is not resulting in a memory leak, since the TMultiGraph object will do the cleanup
4768  TGraphErrors *ge = new TGraphErrors(*(fNonMusrData[i].theory));
4769  // Data points and model curves should be fixed on the graph and not dragged around using, e.g., the mouse.
4770  ge->SetEditable(false);
4771  fMultiGraphData->Add(ge, "l");
4772  }
4773 
4774  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX)
4775  fDataTheoryPad->SetLogx(1);
4776  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY)
4777  fDataTheoryPad->SetLogy(1);
4778 
4779  fMultiGraphData->Draw("a");
4780 
4781  // set x/y-range
4782  fMultiGraphData->GetXaxis()->SetRangeUser(dataXmin, dataXmax);
4783  fMultiGraphData->GetYaxis()->SetRangeUser(dataYmin, dataYmax);
4784 
4785  // set x-, y-axis label only if there is just one data set
4786  if (fNonMusrData.size() == 1) {
4787  // set x-axis label
4788  fMultiGraphData->GetXaxis()->SetTitle(xAxisTitle.Data());
4789  // set y-axis label
4790  fMultiGraphData->GetYaxis()->SetTitle(yAxisTitle.Data());
4791  } else { // more than one data set present, hence add a legend
4792  fMultiGraphLegend.reset(new TLegend(0.8, 0.8, 1.0, 1.0));
4793  PStringVector legendLabel;
4794  for (UInt_t i=0; i<plotInfo.fRuns.size(); i++) {
4795  runNo = (UInt_t)plotInfo.fRuns[i]-1;
4796  xAxisTitle = fRunList->GetXAxisTitle(*runs[runNo].GetRunName(), runNo);
4797  yAxisTitle = fRunList->GetYAxisTitle(*runs[runNo].GetRunName(), runNo);
4798  legendLabel.push_back(yAxisTitle + " vs. " + xAxisTitle);
4799  }
4800  for (UInt_t i=0; i<fNonMusrData.size(); i++) {
4801  fMultiGraphLegend->AddEntry(fNonMusrData[i].data, legendLabel[i].Data(), "p");
4802  }
4803  legendLabel.clear();
4804  }
4805 
4806  fMultiGraphData->Draw("a");
4807 
4808  if (fMultiGraphLegend)
4809  fMultiGraphLegend->Draw();
4810  }
4811 
4812  // report canvas status events in non-musr plots
4813  if (!fMainCanvas->GetShowEventStatus()) {
4814  fMainCanvas->ToggleEventStatus();
4815  }
4816  }
4817 
4818  fDataTheoryPad->Update();
4819 
4820  fMainCanvas->cd();
4821  fMainCanvas->Update();
4822 }
4823 
4824 //--------------------------------------------------------------------------
4825 // PlotDifference (private)
4826 //--------------------------------------------------------------------------
4832 void PMusrCanvas::PlotDifference(Bool_t unzoom)
4833 {
4834  fDataTheoryPad->cd();
4835 
4836  // check if log scale plotting and if yes switch back to linear
4837  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY)
4838  fDataTheoryPad->SetLogy(0); // switch to linear
4839  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX)
4840  fDataTheoryPad->SetLogx(0); // switch to linear
4841 
4842  if (fPlotType < 0) // plot type not defined
4843  return;
4844 
4845  Double_t xmin, xmax;
4846  if (fPlotType != MSR_PLOT_NON_MUSR) {
4847  // keep the current x-axis range from the data view
4848  if (fHistoFrame && (fPreviousPlotView == PV_DATA)) {
4849  xmin = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetFirst());
4850  xmax = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetLast()) + fHistoFrame->GetXaxis()->GetBinWidth(fHistoFrame->GetXaxis()->GetLast());
4851  } else {
4852  xmin = fXmin;
4853  xmax = fXmax;
4854  }
4855 
4856  // delete old fHistoFrame if present
4857  if (fHistoFrame) {
4858  delete fHistoFrame;
4859  fHistoFrame = nullptr;
4860  }
4861 
4862  Double_t dataXmin=0.0, dataXmax=0.0, dataYmin=0.0, dataYmax=0.0, dd=0.0;
4863  if (unzoom) {
4864  dataXmin = fXmin;
4865  dataXmax = fXmax;
4866  dataYmin = GetMinimum(fData[0].diff, dataXmin, dataXmax);
4867  dataYmax = GetMaximum(fData[0].diff, dataXmin, dataXmax);
4868  for (UInt_t i=1; i<fData.size(); i++) {
4869  if (GetMinimum(fData[i].diff, dataXmin, dataXmax) < dataYmin)
4870  dataYmin = GetMinimum(fData[i].diff, dataXmin, dataXmax);
4871  if (GetMaximum(fData[i].diff, dataXmin, dataXmax) > dataYmax)
4872  dataYmax = GetMaximum(fData[i].diff, dataXmin, dataXmax);
4873  }
4874  // slightly increase y-range
4875  dd = 0.05*fabs(dataYmax-dataYmin);
4876  dataYmin -= dd;
4877  dataYmax += dd;
4878  } else {
4879  dataXmin = xmin;
4880  dataXmax = xmax;
4881  dataYmin = GetMinimum(fData[0].diff, dataXmin, dataXmax);
4882  dataYmax = GetMaximum(fData[0].diff, dataXmin, dataXmax);
4883  for (UInt_t i=1; i<fData.size(); i++) {
4884  if (GetMinimum(fData[i].diff, dataXmin, dataXmax) < dataYmin)
4885  dataYmin = GetMinimum(fData[i].diff, dataXmin, dataXmax);
4886  if (GetMaximum(fData[i].diff, dataXmin, dataXmax) > dataYmax)
4887  dataYmax = GetMaximum(fData[i].diff, dataXmin, dataXmax);
4888  }
4889  // slightly increase y-range
4890  dd = 0.05*fabs(dataYmax-dataYmin);
4891  dataYmin -= dd;
4892  dataYmax += dd;
4893  }
4894 
4895  fHistoFrame = fDataTheoryPad->DrawFrame(dataXmin, dataYmin, dataXmax, dataYmax);
4896 
4897  // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one
4898  UInt_t noOfPoints = 1000;
4899  for (UInt_t i=0; i<fData.size(); i++) {
4900  if (fData[i].diff->GetNbinsX() > (Int_t)noOfPoints)
4901  noOfPoints = fData[i].diff->GetNbinsX();
4902  }
4903  noOfPoints *= 2; // make sure that there are enough points
4904  fHistoFrame->SetBins(noOfPoints, dataXmin, dataXmax);
4905 
4906  // set x-axis label
4907  if (fPlotType == MSR_PLOT_BNMR) {
4908  // For BNMR/BNQR runs use seconds
4909  fHistoFrame->GetXaxis()->SetTitle("time (s)");
4910  } else {
4911  fHistoFrame->GetXaxis()->SetTitle("time (#mus)");
4912  }
4913  // set y-axis label
4914  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
4915  fHistoFrame->GetYaxis()->SetTitle("data-theory");
4916 
4917  // plot all diff data
4918  for (UInt_t i=0; i<fData.size(); i++) {
4919  fData[i].diff->Draw("pesame");
4920  // set all diff ranges properly
4921  if (fData[i].dataRange->IsXRangePresent())
4922  fData[i].diff->GetXaxis()->SetRangeUser(fData[i].dataRange->GetXmin(), fData[i].dataRange->GetXmax());
4923  else
4924  fData[i].diff->GetXaxis()->SetRange(fData[i].diff->FindBin(dataXmin), fData[i].diff->FindBin(dataXmax));
4925 
4926  if (fData[i].dataRange->IsYRangePresent())
4927  fData[i].diff->GetYaxis()->SetRangeUser(fData[i].dataRange->GetYmin(), fData[i].dataRange->GetYmax());
4928  else
4929  fData[i].diff->GetYaxis()->SetRangeUser(dataYmin, dataYmax);
4930  }
4931 
4932 
4933  // check if RRF and if yes show a label
4934  if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) {
4935  fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data());
4936  }
4937  } else { // fPlotType == MSR_PLOT_NON_MUSR
4938  // keep the current x-axis range from the data view
4940  xmin = fMultiGraphData->GetXaxis()->GetBinCenter(fMultiGraphData->GetXaxis()->GetFirst());
4941  xmax = fMultiGraphData->GetXaxis()->GetBinCenter(fMultiGraphData->GetXaxis()->GetLast());
4942  } else {
4943  xmin = fXmin;
4944  xmax = fXmax;
4945  }
4946 
4947  // tell the canvas that the selected object (the one under the mouse pointer) is not your object, before to actually delete it.
4948  fMainCanvas->SetSelected(fMainCanvas->GetPadSave());
4949 
4950  // clean up previous fMultiGraphDiff
4951  if (fMultiGraphDiff) {
4952  delete fMultiGraphDiff;
4953  fMultiGraphDiff = nullptr;
4954  }
4955  if (fMultiGraphData) {
4956  delete fMultiGraphData;
4957  fMultiGraphData = nullptr;
4958  }
4959 
4962  UInt_t runNo = (UInt_t)plotInfo.fRuns[0]-1;
4963  TString xAxisTitle = fRunList->GetXAxisTitle(*runs[runNo].GetRunName(), runNo);
4964 
4965  // if fMultiGraphDiff is not present create it and add the diff data
4966  fMultiGraphDiff = new TMultiGraph();
4967  assert(fMultiGraphDiff != nullptr);
4968 
4969  // get the histo frame x/y range boundaries
4970  Double_t dataXmin=0.0, dataXmax=0.0, dataYmin=0.0, dataYmax=0.0;
4971  if (unzoom) { // set the x-/y-range back to the original msr-file values
4972  dataXmin = fXmin;
4973  dataXmax = fXmax;
4974  dataYmin = GetMinimum(fNonMusrData[0].diff, dataXmin, dataXmax);
4975  dataYmax = GetMaximum(fNonMusrData[0].diff, dataXmin, dataXmax);
4976  for (UInt_t i=1; i<fNonMusrData.size(); i++) {
4977  if (GetMinimum(fNonMusrData[i].diff, dataXmin, dataXmax) < dataYmin)
4978  dataYmin = GetMinimum(fNonMusrData[i].diff, dataXmin, dataXmax);
4979  if (GetMaximum(fNonMusrData[i].diff, dataXmin, dataXmax) > dataYmax)
4980  dataYmax = GetMaximum(fNonMusrData[i].diff, dataXmin, dataXmax);
4981  }
4982  Double_t dd = 0.05*fabs(dataYmax-dataYmin);
4983  dataYmin -= dd;
4984  dataYmax += dd;
4985  } else { // set the x-/y-range to the previous fHistoFrame range
4986  dataXmin = xmin;
4987  dataXmax = xmax;
4988  dataYmin = GetMinimum(fNonMusrData[0].diff, dataXmin, dataXmax);
4989  dataYmax = GetMaximum(fNonMusrData[0].diff, dataXmin, dataXmax);
4990  for (UInt_t i=1; i<fNonMusrData.size(); i++) {
4991  if (GetMinimum(fNonMusrData[i].diff, dataXmin, dataXmax) < dataYmin)
4992  dataYmin = GetMinimum(fNonMusrData[i].diff, dataXmin, dataXmax);
4993  if (GetMaximum(fNonMusrData[i].diff, dataXmin, dataXmax) > dataYmax)
4994  dataYmax = GetMaximum(fNonMusrData[i].diff, dataXmin, dataXmax);
4995  }
4996  Double_t dd = 0.05*fabs(dataYmax-dataYmin);
4997  dataYmin -= dd;
4998  dataYmax += dd;
4999  }
5000 
5001  // add all diff data to fMultiGraphDiff
5002  for (UInt_t i=0; i<fNonMusrData.size(); i++) {
5003  // the next three lines are ugly but needed for the following reasons:
5004  // TMultiGraph is taking ownership of the TGraphErrors, hence a deep copy is needed.
5005  // This is not resulting in a memory leak, since the TMultiGraph object will do the cleaing
5006  TGraphErrors *ge = new TGraphErrors(*(fNonMusrData[i].diff));
5007  // Data points and model curves should be fixed on the graph and not dragged around using, e.g., the mouse.
5008  ge->SetEditable(false);
5009  fMultiGraphDiff->Add(ge, "p");
5010  }
5011 
5012  fMultiGraphDiff->Draw("a");
5013 
5014  // set x-range
5015  fMultiGraphDiff->GetXaxis()->SetRangeUser(dataXmin, dataXmax);
5016  fMultiGraphDiff->GetYaxis()->SetRangeUser(dataYmin, dataYmax);
5017 
5018  // set x-axis label
5019  fMultiGraphDiff->GetXaxis()->SetTitle(xAxisTitle.Data());
5020  // set y-axis label
5021  fMultiGraphDiff->GetYaxis()->SetTitle("data-theory");
5022 
5023  fMultiGraphDiff->Draw("a");
5024 
5025  if (fMultiGraphLegend)
5026  fMultiGraphLegend->Draw();
5027  }
5028 
5029  fDataTheoryPad->Update();
5030 
5031  fMainCanvas->cd();
5032  fMainCanvas->Update();
5033 }
5034 
5035 //--------------------------------------------------------------------------
5036 // PlotFourier (private)
5037 //--------------------------------------------------------------------------
5043 void PMusrCanvas::PlotFourier(Bool_t unzoom)
5044 {
5045  fDataTheoryPad->cd();
5046 
5047  // check if log scale plotting and if yes switch back to linear
5048  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY)
5049  fDataTheoryPad->SetLogy(0); // switch to linear
5050  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX)
5051  fDataTheoryPad->SetLogx(0); // switch to linear
5052 
5053  if (fPlotType < 0) // plot type not defined
5054  return;
5055 
5056  if (fData.size() == 0) // no data to be plotted
5057  return;
5058 
5059  // define x-axis title
5060  TString xAxisTitle("");
5062  xAxisTitle = TString("Field (G)");
5063  } else if (fFourier.fUnits == FOURIER_UNIT_TESLA) {
5064  xAxisTitle = TString("Field (T)");
5065  } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) {
5066  xAxisTitle = TString("Frequency (MHz)");
5067  } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) {
5068  xAxisTitle = TString("Frequency (Mc/s)");
5069  } else {
5070  xAxisTitle = TString("??");
5071  }
5072 
5073  // plot fourier data
5074  Double_t xmin, xmax, ymin, ymax, binContent;
5075  UInt_t noOfPoints = 1000;
5076  switch (fCurrentPlotView) {
5077  case PV_FOURIER_REAL:
5078  // set x-range
5079  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5080  xmin = fFourier.fPlotRange[0];
5081  xmax = fFourier.fPlotRange[1];
5082  } else {
5083  xmin = fData[0].dataFourierRe->GetBinLowEdge(1);
5084  xmax = fData[0].dataFourierRe->GetBinLowEdge(fData[0].dataFourierRe->GetNbinsX())+fData[0].dataFourierRe->GetBinWidth(1);
5085  }
5086 
5087  // set y-range
5088  // first find minimum/maximum of all histos and theories
5089  ymin = GetMinimum(fData[0].dataFourierRe);
5090  ymax = GetMaximum(fData[0].dataFourierRe);
5091  binContent = GetMinimum(fData[0].theoryFourierRe);
5092  if (binContent < ymin)
5093  ymin = binContent;
5094  binContent = GetMaximum(fData[0].theoryFourierRe);
5095  if (binContent > ymax)
5096  ymax = binContent;
5097  for (UInt_t i=1; i<fData.size(); i++) {
5098  binContent = GetMinimum(fData[i].dataFourierRe);
5099  if (binContent < ymin)
5100  ymin = binContent;
5101  binContent = GetMaximum(fData[i].dataFourierRe);
5102  if (binContent > ymax)
5103  ymax = binContent;
5104  binContent = GetMinimum(fData[i].theoryFourierRe);
5105  if (binContent < ymin)
5106  ymin = binContent;
5107  binContent = GetMaximum(fData[i].theoryFourierRe);
5108  if (binContent > ymax)
5109  ymax = binContent;
5110  }
5111 
5112  // delete old fHistoFrame if present
5113  if (fHistoFrame) {
5114  delete fHistoFrame;
5115  fHistoFrame = nullptr;
5116  }
5117 
5118  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5119 
5120  // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one
5121  noOfPoints = 1000;
5122  for (UInt_t i=0; i<fData.size(); i++) {
5123  if (fData[i].dataFourierRe->GetNbinsX() > (Int_t)noOfPoints)
5124  noOfPoints = fData[i].dataFourierRe->GetNbinsX();
5125  }
5126  noOfPoints *= 2; // make sure that there are enough points
5127  fHistoFrame->SetBins(noOfPoints, xmin, xmax);
5128 
5129  // set ranges for Fourier and Fourier theory
5130  for (UInt_t i=0; i<fData.size(); i++) {
5131  fData[i].dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
5132  fData[i].dataFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5133  fData[i].theoryFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
5134  fData[i].theoryFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5135  }
5136 
5137  // set x-axis title
5138  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5139 
5140  // set y-axis title
5141  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5142  fHistoFrame->GetYaxis()->SetTitle("Real Fourier");
5143 
5144  // plot data
5145  for (UInt_t i=0; i<fData.size(); i++) {
5146  fData[i].dataFourierRe->Draw("psame");
5147  }
5148 
5149  // plot theories
5150  for (UInt_t i=0; i<fData.size(); i++) {
5151  fData[i].theoryFourierRe->Draw("same");
5152  }
5153 
5155 
5156  break;
5157  case PV_FOURIER_IMAG:
5158  // set x-range
5159  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5160  xmin = fFourier.fPlotRange[0];
5161  xmax = fFourier.fPlotRange[1];
5162  } else {
5163  xmin = fData[0].dataFourierIm->GetBinLowEdge(1);
5164  xmax = fData[0].dataFourierIm->GetBinLowEdge(fData[0].dataFourierIm->GetNbinsX())+fData[0].dataFourierIm->GetBinWidth(1);
5165  }
5166 
5167  // set y-range
5168  // first find minimum/maximum of all histos
5169  ymin = GetMinimum(fData[0].dataFourierIm);
5170  ymax = GetMaximum(fData[0].dataFourierIm);
5171  binContent = GetMinimum(fData[0].theoryFourierIm);
5172  if (binContent < ymin)
5173  ymin = binContent;
5174  binContent = GetMaximum(fData[0].theoryFourierIm);
5175  if (binContent > ymax)
5176  ymax = binContent;
5177  for (UInt_t i=1; i<fData.size(); i++) {
5178  binContent = GetMinimum(fData[i].dataFourierIm);
5179  if (binContent < ymin)
5180  ymin = binContent;
5181  binContent = GetMaximum(fData[i].dataFourierIm);
5182  if (binContent > ymax)
5183  ymax = binContent;
5184  binContent = GetMinimum(fData[i].theoryFourierIm);
5185  if (binContent < ymin)
5186  ymin = binContent;
5187  binContent = GetMaximum(fData[i].theoryFourierIm);
5188  if (binContent > ymax)
5189  ymax = binContent;
5190  }
5191 
5192  // delete old fHistoFrame if present
5193  if (fHistoFrame) {
5194  delete fHistoFrame;
5195  fHistoFrame = nullptr;
5196  }
5197 
5198  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5199 
5200  // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one
5201  noOfPoints = 1000;
5202  for (UInt_t i=0; i<fData.size(); i++) {
5203  if (fData[i].dataFourierIm->GetNbinsX() > (Int_t)noOfPoints)
5204  noOfPoints = fData[i].dataFourierIm->GetNbinsX();
5205  }
5206  noOfPoints *= 2; // make sure that there are enough points
5207  fHistoFrame->SetBins(noOfPoints, xmin, xmax);
5208 
5209  // set ranges for Fourier and Fourier theory
5210  for (UInt_t i=0; i<fData.size(); i++) {
5211  fData[i].dataFourierIm->GetXaxis()->SetRangeUser(xmin, xmax);
5212  fData[i].dataFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5213  fData[i].theoryFourierIm->GetXaxis()->SetRangeUser(xmin, xmax);
5214  fData[i].theoryFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5215  }
5216 
5217  // set x-axis title
5218  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5219 
5220  // set y-axis title
5221  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5222  fHistoFrame->GetYaxis()->SetTitle("Imaginary Fourier");
5223 
5224  // plot data
5225  for (UInt_t i=0; i<fData.size(); i++) {
5226  fData[i].dataFourierIm->Draw("psame");
5227  }
5228 
5229  // plot theories
5230  for (UInt_t i=0; i<fData.size(); i++) {
5231  fData[i].theoryFourierIm->Draw("same");
5232  }
5233 
5235 
5236  break;
5238  // set x-range
5239  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5240  xmin = fFourier.fPlotRange[0];
5241  xmax = fFourier.fPlotRange[1];
5242  } else {
5243  xmin = fData[0].dataFourierRe->GetBinLowEdge(1);
5244  xmax = fData[0].dataFourierRe->GetBinLowEdge(fData[0].dataFourierRe->GetNbinsX())+fData[0].dataFourierRe->GetBinWidth(1);
5245  }
5246 
5247  // set y-range
5248  // first find minimum/maximum of all histos
5249  // real part first
5250  ymin = GetMinimum(fData[0].dataFourierRe);
5251  ymax = GetMaximum(fData[0].dataFourierRe);
5252  for (UInt_t i=1; i<fData.size(); i++) {
5253  binContent = GetMinimum(fData[i].dataFourierRe);
5254  if (binContent < ymin)
5255  ymin = binContent;
5256  binContent = GetMaximum(fData[i].dataFourierRe);
5257  if (binContent > ymax)
5258  ymax = binContent;
5259  }
5260  // imag part min/max
5261  for (UInt_t i=0; i<fData.size(); i++) {
5262  binContent = GetMinimum(fData[i].dataFourierIm);
5263  if (binContent < ymin)
5264  ymin = binContent;
5265  binContent = GetMaximum(fData[i].dataFourierIm);
5266  if (binContent > ymax)
5267  ymax = binContent;
5268  }
5269  // theory part min/max
5270  for (UInt_t i=0; i<fData.size(); i++) {
5271  binContent = GetMinimum(fData[i].theoryFourierRe);
5272  if (binContent < ymin)
5273  ymin = binContent;
5274  binContent = GetMaximum(fData[i].theoryFourierRe);
5275  if (binContent > ymax)
5276  ymax = binContent;
5277  binContent = GetMinimum(fData[i].theoryFourierIm);
5278  if (binContent < ymin)
5279  ymin = binContent;
5280  binContent = GetMaximum(fData[i].theoryFourierIm);
5281  if (binContent > ymax)
5282  ymax = binContent;
5283  }
5284 
5285  // delete old fHistoFrame if present
5286  if (fHistoFrame) {
5287  delete fHistoFrame;
5288  fHistoFrame = nullptr;
5289  }
5290 
5291  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5292 
5293  // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one
5294  noOfPoints = 1000;
5295  for (UInt_t i=0; i<fData.size(); i++) {
5296  if (fData[i].dataFourierRe->GetNbinsX() > (Int_t)noOfPoints)
5297  noOfPoints = fData[i].dataFourierRe->GetNbinsX();
5298  }
5299  noOfPoints *= 2; // make sure that there are enough points
5300  fHistoFrame->SetBins(noOfPoints, xmin, xmax);
5301 
5302  // set ranges for Fourier and Fourier theory
5303  for (UInt_t i=0; i<fData.size(); i++) {
5304  fData[i].dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
5305  fData[i].dataFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5306  fData[i].theoryFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
5307  fData[i].theoryFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5308  fData[i].dataFourierIm->GetXaxis()->SetRangeUser(xmin, xmax);
5309  fData[i].dataFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5310  fData[i].theoryFourierIm->GetXaxis()->SetRangeUser(xmin, xmax);
5311  fData[i].theoryFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5312  }
5313 
5314  // set x-axis title
5315  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5316 
5317  // set y-axis title
5318  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5319  fHistoFrame->GetYaxis()->SetTitle("Real/Imag Fourier");
5320 
5321  // plot data
5322  for (UInt_t i=0; i<fData.size(); i++) {
5323  fData[i].dataFourierRe->Draw("psame");
5324  fData[i].dataFourierIm->Draw("psame");
5325  }
5326 
5327  // plot theories
5328  for (UInt_t i=0; i<fData.size(); i++) {
5329  fData[i].theoryFourierRe->Draw("same");
5330  fData[i].theoryFourierIm->Draw("same");
5331  }
5332 
5334 
5335  break;
5336  case PV_FOURIER_PWR:
5337  // set x-range
5338  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5339  xmin = fFourier.fPlotRange[0];
5340  xmax = fFourier.fPlotRange[1];
5341  } else {
5342  xmin = fData[0].dataFourierPwr->GetBinLowEdge(1);
5343  xmax = fData[0].dataFourierPwr->GetBinLowEdge(fData[0].dataFourierPwr->GetNbinsX())+fData[0].dataFourierPwr->GetBinWidth(1);
5344  }
5345 
5346  // set y-range
5347  // first find minimum/maximum of all histos and theory
5348  ymin = GetMinimum(fData[0].dataFourierPwr);
5349  ymax = GetMaximum(fData[0].dataFourierPwr);
5350  binContent = GetMinimum(fData[0].theoryFourierPwr);
5351  if (binContent < ymin)
5352  ymin = binContent;
5353  binContent = GetMaximum(fData[0].theoryFourierPwr);
5354  if (binContent > ymax)
5355  ymax = binContent;
5356  for (UInt_t i=1; i<fData.size(); i++) {
5357  binContent = GetMinimum(fData[i].dataFourierPwr);
5358  if (binContent < ymin)
5359  ymin = binContent;
5360  binContent = GetMaximum(fData[i].dataFourierPwr);
5361  if (binContent > ymax)
5362  ymax = binContent;
5363  binContent = GetMinimum(fData[i].theoryFourierPwr);
5364  if (binContent < ymin)
5365  ymin = binContent;
5366  binContent = GetMaximum(fData[i].theoryFourierPwr);
5367  if (binContent > ymax)
5368  ymax = binContent;
5369  }
5370 
5371  // delete old fHistoFrame if present
5372  if (fHistoFrame) {
5373  delete fHistoFrame;
5374  fHistoFrame = nullptr;
5375  }
5376 
5377  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 0.95*ymin, xmax, 1.05*ymax);
5378 
5379  // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one
5380  noOfPoints = 1000;
5381  for (UInt_t i=0; i<fData.size(); i++) {
5382  if (fData[i].dataFourierPwr->GetNbinsX() > (Int_t)noOfPoints)
5383  noOfPoints = fData[i].dataFourierPwr->GetNbinsX();
5384  }
5385  noOfPoints *= 2; // make sure that there are enough points
5386  fHistoFrame->SetBins(noOfPoints, xmin, xmax);
5387 
5388  // set ranges for Fourier and Fourier theory
5389  for (UInt_t i=0; i<fData.size(); i++) {
5390  fData[i].dataFourierPwr->GetXaxis()->SetRangeUser(xmin, xmax);
5391  fData[i].dataFourierPwr->GetYaxis()->SetRangeUser(0.95*ymin, 1.05*ymax);
5392  fData[i].theoryFourierPwr->GetXaxis()->SetRangeUser(xmin, xmax);
5393  fData[i].theoryFourierPwr->GetYaxis()->SetRangeUser(0.95*ymin, 1.05*ymax);
5394  }
5395 
5396  // set x-axis title
5397  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5398 
5399  // set y-axis title
5400  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5401  fHistoFrame->GetYaxis()->SetTitle("Ampl. Fourier");
5402 
5403  // plot data
5404  for (UInt_t i=0; i<fData.size(); i++) {
5405  fData[i].dataFourierPwr->Draw("psame");
5406  }
5407 
5408  // plot theories
5409  for (UInt_t i=0; i<fData.size(); i++) {
5410  fData[i].theoryFourierPwr->Draw("same");
5411  }
5412 
5413  break;
5414  case PV_FOURIER_PHASE:
5415  // set x-range
5416  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5417  xmin = fFourier.fPlotRange[0];
5418  xmax = fFourier.fPlotRange[1];
5419  } else {
5420  xmin = fData[0].dataFourierPhase->GetBinLowEdge(1);
5421  xmax = fData[0].dataFourierPhase->GetBinLowEdge(fData[0].dataFourierPhase->GetNbinsX())+fData[0].dataFourierPhase->GetBinWidth(1);
5422  }
5423 
5424  // set y-range
5425  // first find minimum/maximum of all histos
5426  ymin = GetMinimum(fData[0].dataFourierPhase);
5427  ymax = GetMaximum(fData[0].dataFourierPhase);
5428  binContent = GetMinimum(fData[0].theoryFourierPhase);
5429  if (binContent < ymin)
5430  ymin = binContent;
5431  binContent = GetMaximum(fData[0].theoryFourierPhase);
5432  if (binContent > ymax)
5433  ymax = binContent;
5434  for (UInt_t i=1; i<fData.size(); i++) {
5435  binContent = GetMinimum(fData[i].dataFourierPhase);
5436  if (binContent < ymin)
5437  ymin = binContent;
5438  binContent = GetMaximum(fData[i].dataFourierPhase);
5439  if (binContent > ymax)
5440  ymax = binContent;
5441  binContent = GetMinimum(fData[i].theoryFourierPhase);
5442  if (binContent < ymin)
5443  ymin = binContent;
5444  binContent = GetMaximum(fData[i].theoryFourierPhase);
5445  if (binContent > ymax)
5446  ymax = binContent;
5447  }
5448 
5449  // delete old fHistoFrame if present
5450  if (fHistoFrame) {
5451  delete fHistoFrame;
5452  fHistoFrame = nullptr;
5453  }
5454 
5455  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5456 
5457  // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one
5458  noOfPoints = 1000;
5459  for (UInt_t i=0; i<fData.size(); i++) {
5460  if (fData[i].dataFourierPhase->GetNbinsX() > (Int_t)noOfPoints)
5461  noOfPoints = fData[i].dataFourierPhase->GetNbinsX();
5462  }
5463  noOfPoints *= 2; // make sure that there are enough points
5464  fHistoFrame->SetBins(noOfPoints, xmin, xmax);
5465 
5466  for (UInt_t i=0; i<fData.size(); i++) {
5467  fData[i].dataFourierPhase->GetXaxis()->SetRangeUser(xmin, xmax);
5468  fData[i].dataFourierPhase->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5469  fData[i].theoryFourierPhase->GetXaxis()->SetRangeUser(xmin, xmax);
5470  fData[i].theoryFourierPhase->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5471  }
5472 
5473  // set x-axis title
5474  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5475 
5476  // set y-axis title
5477  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5478  fHistoFrame->GetYaxis()->SetTitle("Phase Fourier");
5479 
5480  // plot data
5481  for (UInt_t i=0; i<fData.size(); i++) {
5482  fData[i].dataFourierPhase->Draw("psame");
5483  }
5484 
5485  // plot theories
5486  for (UInt_t i=0; i<fData.size(); i++) {
5487  fData[i].theoryFourierPhase->Draw("same");
5488  }
5489 
5490  break;
5492  // set x-range
5493  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5494  xmin = fFourier.fPlotRange[0];
5495  xmax = fFourier.fPlotRange[1];
5496  } else {
5497  xmin = fData[0].dataFourierPhaseOptReal->GetBinLowEdge(1);
5498  xmax = fData[0].dataFourierPhaseOptReal->GetBinLowEdge(fData[0].dataFourierPhaseOptReal->GetNbinsX())+fData[0].dataFourierPhaseOptReal->GetBinWidth(1);
5499  }
5500 
5501  // set y-range
5502  // first find minimum/maximum of all histos
5503  ymin = GetMinimum(fData[0].dataFourierPhaseOptReal);
5504  ymax = GetMaximum(fData[0].dataFourierPhaseOptReal);
5505  binContent = GetMinimum(fData[0].theoryFourierPhaseOptReal);
5506  if (binContent < ymin)
5507  ymin = binContent;
5508  binContent = GetMaximum(fData[0].theoryFourierPhaseOptReal);
5509  if (binContent > ymax)
5510  ymax = binContent;
5511  for (UInt_t i=1; i<fData.size(); i++) {
5512  binContent = GetMinimum(fData[i].dataFourierPhaseOptReal);
5513  if (binContent < ymin)
5514  ymin = binContent;
5515  binContent = GetMaximum(fData[i].dataFourierPhaseOptReal);
5516  if (binContent > ymax)
5517  ymax = binContent;
5518  binContent = GetMinimum(fData[i].theoryFourierPhaseOptReal);
5519  if (binContent < ymin)
5520  ymin = binContent;
5521  binContent = GetMaximum(fData[i].theoryFourierPhaseOptReal);
5522  if (binContent > ymax)
5523  ymax = binContent;
5524  }
5525 
5526  // delete old fHistoFrame if present
5527  if (fHistoFrame) {
5528  delete fHistoFrame;
5529  fHistoFrame = nullptr;
5530  }
5531 
5532  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5533 
5534  // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one
5535  noOfPoints = 1000;
5536  for (UInt_t i=0; i<fData.size(); i++) {
5537  if (fData[i].dataFourierPhaseOptReal->GetNbinsX() > (Int_t)noOfPoints)
5538  noOfPoints = fData[i].dataFourierPhaseOptReal->GetNbinsX();
5539  }
5540  noOfPoints *= 2; // make sure that there are enough points
5541  fHistoFrame->SetBins(noOfPoints, xmin, xmax);
5542 
5543  for (UInt_t i=0; i<fData.size(); i++) {
5544  fData[i].dataFourierPhaseOptReal->GetXaxis()->SetRangeUser(xmin, xmax);
5545  fData[i].dataFourierPhaseOptReal->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5546  fData[i].theoryFourierPhaseOptReal->GetXaxis()->SetRangeUser(xmin, xmax);
5547  fData[i].theoryFourierPhaseOptReal->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5548  }
5549 
5550  // set x-axis title
5551  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5552 
5553  // set y-axis title
5554  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5555  fHistoFrame->GetYaxis()->SetTitle("Phase Opt. Real Fourier");
5556 
5557  // plot data
5558  for (UInt_t i=0; i<fData.size(); i++) {
5559  fData[i].dataFourierPhaseOptReal->Draw("psame");
5560  }
5561 
5562  // plot theories
5563  for (UInt_t i=0; i<fData.size(); i++) {
5564  fData[i].theoryFourierPhaseOptReal->Draw("same");
5565  }
5566 
5567  break;
5568  default:
5569  break;
5570  }
5571 
5572  // check if RRF and if yes show a label
5573  if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) {
5574  fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data());
5575  }
5576 
5577  fDataTheoryPad->Update();
5578 
5579  fMainCanvas->cd();
5580  fMainCanvas->Update();
5581 }
5582 
5583 //--------------------------------------------------------------------------
5584 // PlotFourierDifference (private)
5585 //--------------------------------------------------------------------------
5592 {
5593  fDataTheoryPad->cd();
5594 
5595  // check if log scale plotting and if yes switch back to linear
5596  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY)
5597  fDataTheoryPad->SetLogy(0); // switch to linear
5598  if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX)
5599  fDataTheoryPad->SetLogx(0); // switch to linear
5600 
5601  if (fPlotType < 0) // plot type not defined
5602  return;
5603 
5604  if (fData.size() == 0) // no data to be plotted
5605  return;
5606 
5607  // define x-axis title
5608  TString xAxisTitle("");
5610  xAxisTitle = TString("Field (G)");
5611  } else if (fFourier.fUnits == FOURIER_UNIT_TESLA) {
5612  xAxisTitle = TString("Field (T)");
5613  } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) {
5614  xAxisTitle = TString("Frequency (MHz)");
5615  } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) {
5616  xAxisTitle = TString("Frequency (Mc/s)");
5617  } else {
5618  xAxisTitle = TString("??");
5619  }
5620 
5621  // plot data
5622  double xmin, xmax, ymin, ymax, binContent;
5623  switch (fCurrentPlotView) {
5624  case PV_FOURIER_REAL:
5625  // set x-range
5626  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5627  xmin = fFourier.fPlotRange[0];
5628  xmax = fFourier.fPlotRange[1];
5629  } else {
5630  xmin = fData[0].diffFourierRe->GetBinLowEdge(1);
5631  xmax = fData[0].diffFourierRe->GetBinLowEdge(fData[0].diffFourierRe->GetNbinsX())+fData[0].diffFourierRe->GetBinWidth(1);
5632  }
5633 
5634  // set y-range
5635  // first find minimum/maximum of all histos
5636  ymin = GetMinimum(fData[0].diffFourierRe);
5637  ymax = GetMaximum(fData[0].diffFourierRe);
5638  for (UInt_t i=1; i<fData.size(); i++) {
5639  binContent = GetMinimum(fData[i].diffFourierRe);
5640  if (binContent < ymin)
5641  ymin = binContent;
5642  binContent = GetMaximum(fData[i].diffFourierRe);
5643  if (binContent > ymax)
5644  ymax = binContent;
5645  }
5646 
5647  // delete old fHistoFrame if present
5648  if (fHistoFrame) {
5649  delete fHistoFrame;
5650  fHistoFrame = nullptr;
5651  }
5652 
5653  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5654 
5655  // set ranges for Fourier difference
5656  for (UInt_t i=0; i<fData.size(); i++) {
5657  fData[i].diffFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
5658  fData[i].diffFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5659  }
5660 
5661  // set x-axis title
5662  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5663 
5664  // set y-axis title
5665  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5666  if (fData[0].diffFourierTag == 1)
5667  fHistoFrame->GetYaxis()->SetTitle("Real Fourier (d-f: data-theory)");
5668  else
5669  fHistoFrame->GetYaxis()->SetTitle("Real Fourier (f-d: [(F data)-(F theory)]");
5670 
5671  // plot data
5672  for (UInt_t i=0; i<fData.size(); i++) {
5673  fData[i].diffFourierRe->Draw("plsame");
5674  }
5675 
5677 
5678  break;
5679  case PV_FOURIER_IMAG:
5680  // set x-range
5681  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5682  xmin = fFourier.fPlotRange[0];
5683  xmax = fFourier.fPlotRange[1];
5684  } else {
5685  xmin = fData[0].diffFourierIm->GetBinLowEdge(1);
5686  xmax = fData[0].diffFourierIm->GetBinLowEdge(fData[0].diffFourierIm->GetNbinsX())+fData[0].diffFourierIm->GetBinWidth(1);
5687  }
5688 
5689  // set y-range
5690  // first find minimum/maximum of all histos
5691  ymin = GetMinimum(fData[0].diffFourierIm);
5692  ymax = GetMaximum(fData[0].diffFourierIm);
5693  for (UInt_t i=1; i<fData.size(); i++) {
5694  binContent = GetMinimum(fData[i].diffFourierIm);
5695  if (binContent < ymin)
5696  ymin = binContent;
5697  binContent = GetMaximum(fData[i].diffFourierIm);
5698  if (binContent > ymax)
5699  ymax = binContent;
5700  }
5701 
5702  // delete old fHistoFrame if present
5703  if (fHistoFrame) {
5704  delete fHistoFrame;
5705  fHistoFrame = nullptr;
5706  }
5707 
5708  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5709 
5710  // set ranges for Fourier difference
5711  for (UInt_t i=0; i<fData.size(); i++) {
5712  fData[i].diffFourierIm->GetXaxis()->SetRangeUser(xmin, xmax);
5713  fData[i].diffFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5714  }
5715 
5716  // set x-axis title
5717  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5718 
5719  // set y-axis title
5720  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5721  if (fData[0].diffFourierTag == 1)
5722  fHistoFrame->GetYaxis()->SetTitle("Imaginary Fourier (d-f: data-theory)");
5723  else
5724  fHistoFrame->GetYaxis()->SetTitle("Imaginary Fourier (f-d: [(F data)-(F theory)]");
5725 
5726  // plot data
5727  for (UInt_t i=0; i<fData.size(); i++) {
5728  fData[i].diffFourierIm->Draw("plsame");
5729  }
5730 
5732 
5733  break;
5735  // set x-range
5736  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5737  xmin = fFourier.fPlotRange[0];
5738  xmax = fFourier.fPlotRange[1];
5739  } else {
5740  xmin = fData[0].diffFourierRe->GetBinLowEdge(1);
5741  xmax = fData[0].diffFourierRe->GetBinLowEdge(fData[0].diffFourierRe->GetNbinsX())+fData[0].diffFourierRe->GetBinWidth(1);
5742  }
5743 
5744  // set y-range
5745  // first find minimum/maximum of all histos
5746  ymin = GetMinimum(fData[0].diffFourierRe);
5747  ymax = GetMaximum(fData[0].diffFourierRe);
5748  for (UInt_t i=1; i<fData.size(); i++) {
5749  binContent = GetMinimum(fData[i].diffFourierRe);
5750  if (binContent < ymin)
5751  ymin = binContent;
5752  binContent = GetMaximum(fData[i].diffFourierRe);
5753  if (binContent > ymax)
5754  ymax = binContent;
5755  }
5756  for (UInt_t i=0; i<fData.size(); i++) {
5757  binContent = GetMinimum(fData[i].diffFourierIm);
5758  if (binContent < ymin)
5759  ymin = binContent;
5760  binContent = GetMaximum(fData[i].diffFourierIm);
5761  if (binContent > ymax)
5762  ymax = binContent;
5763  }
5764 
5765  // delete old fHistoFrame if present
5766  if (fHistoFrame) {
5767  delete fHistoFrame;
5768  fHistoFrame = nullptr;
5769  }
5770 
5771  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5772 
5773  // set ranges for Fourier difference
5774  for (UInt_t i=0; i<fData.size(); i++) {
5775  fData[i].diffFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
5776  fData[i].diffFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5777  fData[i].diffFourierIm->GetXaxis()->SetRangeUser(xmin, xmax);
5778  fData[i].diffFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5779  }
5780 
5781  // set x-axis title
5782  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5783 
5784  // set y-axis title
5785  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5786  if (fData[0].diffFourierTag == 1)
5787  fHistoFrame->GetYaxis()->SetTitle("Real+Imag Fourier (d-f: data-theory)");
5788  else
5789  fHistoFrame->GetYaxis()->SetTitle("Real+Imag Fourier (f-d: [(F data)-(F theory)]");
5790 
5791  // plot data
5792  for (UInt_t i=0; i<fData.size(); i++) {
5793  fData[i].diffFourierRe->Draw("plsame");
5794  fData[i].diffFourierIm->Draw("plsame");
5795  }
5796 
5798 
5799  break;
5800  case PV_FOURIER_PWR:
5801  // set x-range
5802  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5803  xmin = fFourier.fPlotRange[0];
5804  xmax = fFourier.fPlotRange[1];
5805  } else {
5806  xmin = fData[0].diffFourierPwr->GetBinLowEdge(1);
5807  xmax = fData[0].diffFourierPwr->GetBinLowEdge(fData[0].diffFourierPwr->GetNbinsX())+fData[0].diffFourierPwr->GetBinWidth(1);
5808  }
5809 
5810  // set y-range
5811  // first find minimum/maximum of all histos
5812  ymin = GetMinimum(fData[0].diffFourierPwr);
5813  ymax = GetMaximum(fData[0].diffFourierPwr);
5814  for (UInt_t i=1; i<fData.size(); i++) {
5815  binContent = GetMinimum(fData[i].diffFourierPwr);
5816  if (binContent < ymin)
5817  ymin = binContent;
5818  binContent = GetMaximum(fData[i].diffFourierPwr);
5819  if (binContent > ymax)
5820  ymax = binContent;
5821  }
5822 
5823  // delete old fHistoFrame if present
5824  if (fHistoFrame) {
5825  delete fHistoFrame;
5826  fHistoFrame = nullptr;
5827  }
5828 
5829  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 0.95*ymin, xmax, 1.05*ymax);
5830 
5831  // set x-axis title
5832  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5833 
5834  // set ranges for Fourier difference
5835  for (UInt_t i=0; i<fData.size(); i++) {
5836  fData[i].diffFourierPwr->GetXaxis()->SetRangeUser(xmin, xmax);
5837  fData[i].diffFourierPwr->GetYaxis()->SetRangeUser(0.95*ymin, 1.05*ymax);
5838  }
5839 
5840  // set y-axis title
5841  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5842  if (fData[0].diffFourierTag == 1)
5843  fHistoFrame->GetYaxis()->SetTitle("Ampl. Fourier (d-f: data-theory)");
5844  else
5845  fHistoFrame->GetYaxis()->SetTitle("Ampl. Fourier (f-d: [(F data)-(F theory)]");
5846 
5847  // plot data
5848  for (UInt_t i=0; i<fData.size(); i++) {
5849  fData[i].diffFourierPwr->Draw("plsame");
5850  }
5851 
5852  break;
5853  case PV_FOURIER_PHASE:
5854  // set x-range
5855  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5856  xmin = fFourier.fPlotRange[0];
5857  xmax = fFourier.fPlotRange[1];
5858  } else {
5859  xmin = fData[0].diffFourierPhase->GetBinLowEdge(1);
5860  xmax = fData[0].diffFourierPhase->GetBinLowEdge(fData[0].diffFourierPhase->GetNbinsX())+fData[0].diffFourierPhase->GetBinWidth(1);
5861  }
5862 
5863  // set y-range
5864  // first find minimum/maximum of all histos
5865  ymin = GetMinimum(fData[0].diffFourierPhase);
5866  ymax = GetMaximum(fData[0].diffFourierPhase);
5867  for (UInt_t i=1; i<fData.size(); i++) {
5868  binContent = GetMinimum(fData[i].diffFourierPhase);
5869  if (binContent < ymin)
5870  ymin = binContent;
5871  binContent = GetMaximum(fData[i].diffFourierPhase);
5872  if (binContent > ymax)
5873  ymax = binContent;
5874  }
5875 
5876  // delete old fHistoFrame if present
5877  if (fHistoFrame) {
5878  delete fHistoFrame;
5879  fHistoFrame = nullptr;
5880  }
5881 
5882  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5883 
5884  // set ranges for Fourier difference
5885  for (UInt_t i=0; i<fData.size(); i++) {
5886  fData[i].diffFourierPhase->GetXaxis()->SetRangeUser(xmin, xmax);
5887  fData[i].diffFourierPhase->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5888  }
5889 
5890  // set x-axis title
5891  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5892 
5893  // set y-axis title
5894  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5895  if (fData[0].diffFourierTag == 1)
5896  fHistoFrame->GetYaxis()->SetTitle("Phase Fourier (d-f: data-theory)");
5897  else
5898  fHistoFrame->GetYaxis()->SetTitle("Phase Fourier [f-d: (F data)-(F theory)]");
5899 
5900  // plot data
5901  for (UInt_t i=0; i<fData.size(); i++) {
5902  fData[i].diffFourierPhase->Draw("plsame");
5903  }
5904 
5906 
5907  break;
5909  // set x-range
5910  if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) {
5911  xmin = fFourier.fPlotRange[0];
5912  xmax = fFourier.fPlotRange[1];
5913  } else {
5914  xmin = fData[0].diffFourierPhaseOptReal->GetBinLowEdge(1);
5915  xmax = fData[0].diffFourierPhaseOptReal->GetBinLowEdge(fData[0].diffFourierPhaseOptReal->GetNbinsX())+fData[0].diffFourierPhaseOptReal->GetBinWidth(1);
5916  }
5917 
5918  // set y-range
5919  // first find minimum/maximum of all histos
5920  ymin = GetMinimum(fData[0].diffFourierPhaseOptReal);
5921  ymax = GetMaximum(fData[0].diffFourierPhaseOptReal);
5922  for (UInt_t i=1; i<fData.size(); i++) {
5923  binContent = GetMinimum(fData[i].diffFourierPhaseOptReal);
5924  if (binContent < ymin)
5925  ymin = binContent;
5926  binContent = GetMaximum(fData[i].diffFourierPhaseOptReal);
5927  if (binContent > ymax)
5928  ymax = binContent;
5929  }
5930 
5931  // delete old fHistoFrame if present
5932  if (fHistoFrame) {
5933  delete fHistoFrame;
5934  fHistoFrame = nullptr;
5935  }
5936 
5937  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax);
5938 
5939  // set ranges for phase opt. real Fourier difference
5940  for (UInt_t i=0; i<fData.size(); i++) {
5941  fData[i].diffFourierPhaseOptReal->GetXaxis()->SetRangeUser(xmin, xmax);
5942  fData[i].diffFourierPhaseOptReal->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
5943  }
5944 
5945  // set x-axis title
5946  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
5947 
5948  // set y-axis title
5949  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
5950  if (fData[0].diffFourierTag == 1)
5951  fHistoFrame->GetYaxis()->SetTitle("Real Fourier (d-f: data-theory)");
5952  else
5953  fHistoFrame->GetYaxis()->SetTitle("Real Fourier (f-d: [(F data)-(F theory)]");
5954 
5955  // plot data
5956  for (UInt_t i=0; i<fData.size(); i++) {
5957  fData[i].diffFourierPhaseOptReal->Draw("plsame");
5958  }
5959  break;
5960  default:
5961  break;
5962  }
5963 
5964  // check if RRF and if yes show a label
5965  if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) {
5966  fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data());
5967  }
5968 
5969  fDataTheoryPad->Update();
5970 
5971  fMainCanvas->cd();
5972  fMainCanvas->Update();
5973 }
5974 
5975 //--------------------------------------------------------------------------
5976 // PlotFourierPhaseValue (private)
5977 //--------------------------------------------------------------------------
5984 {
5985  double x, y;
5986  TString str;
5987 
5988  // plot Fourier phase
5989  str = TString("phase = ");
5990  str += fCurrentFourierPhase[0];
5991  if (fFourier.fPhase.size() > 1) { // if more than one phase is present, do NOT plot phase info
5992  str = TString("");
5993  }
5994  x = 0.7;
5995  y = 0.85;
5996  fCurrentFourierPhaseText.reset(new TLatex());
5997  fCurrentFourierPhaseText->SetNDC(kTRUE);
5998  fCurrentFourierPhaseText->SetText(x, y, str.Data());
5999  fCurrentFourierPhaseText->SetTextFont(62);
6000  fCurrentFourierPhaseText->SetTextSize(0.03);
6001 
6002  fDataTheoryPad->cd();
6003 
6004  fCurrentFourierPhaseText->Draw();
6005 
6006  fDataTheoryPad->Update();
6007 }
6008 
6009 //--------------------------------------------------------------------------
6010 // PlotAverage (private)
6011 //--------------------------------------------------------------------------
6017 void PMusrCanvas::PlotAverage(Bool_t unzoom)
6018 {
6019  fDataTheoryPad->cd();
6020 
6021  // define x-axis title
6022  TString xAxisTitle("");
6023  if (fCurrentPlotView == PV_DATA) {
6024  if (fPlotType == MSR_PLOT_BNMR) {
6025  // For BNMR/BNQR runs use seconds
6026  xAxisTitle = TString("time (s)");
6027  } else {
6028  xAxisTitle = TString("time (#mus)");
6029  }
6030  } else { // all the Fourier
6032  xAxisTitle = TString("Field (G)");
6033  } else if (fFourier.fUnits == FOURIER_UNIT_TESLA) {
6034  xAxisTitle = TString("Field (T)");
6035  } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) {
6036  xAxisTitle = TString("Frequency (MHz)");
6037  } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) {
6038  xAxisTitle = TString("Frequency (Mc/s)");
6039  } else {
6040  xAxisTitle = TString("??");
6041  }
6042  }
6043  // define y-axis title
6044  TString yAxisTitle("");
6045  if (fCurrentPlotView == PV_DATA) {
6046  if (!fDifferenceView) {
6047  PMsrRunList *runList = fMsrHandler->GetMsrRunList();
6048  switch (fPlotType) {
6049  case MSR_PLOT_SINGLE_HISTO:
6050  if (runList->at(0).IsLifetimeCorrected()) { // lifetime correction
6051  yAxisTitle = "<asymmetry>";
6052  } else { // no liftime correction
6053  if (fScaleN0AndBkg)
6054  yAxisTitle = "<N(t)> per nsec";
6055  else
6056  yAxisTitle = "<N(t)> per bin";
6057  }
6058  break;
6059  case MSR_PLOT_ASYM:
6060  yAxisTitle = "<asymmetry>";
6061  break;
6062  case MSR_PLOT_BNMR:
6063  yAxisTitle = "<asymmetry>";
6064  break;
6065  case MSR_PLOT_MU_MINUS:
6066  yAxisTitle = "<N(t)> per bin";
6067  break;
6068  default:
6069  yAxisTitle = "??";
6070  break;
6071  }
6072  } else { // DifferenceView
6073  yAxisTitle = "<data-theory>";
6074  }
6075  } else { // all the Fourier
6076  if (!fDifferenceView) {
6077  switch (fCurrentPlotView) {
6078  case PV_FOURIER_REAL:
6079  yAxisTitle = "<Real Fourier>";
6080  break;
6081  case PV_FOURIER_IMAG:
6082  yAxisTitle = "<Imaginary Fourier>";
6083  break;
6085  yAxisTitle = "<Real/Imag Fourier>";
6086  break;
6087  case PV_FOURIER_PWR:
6088  yAxisTitle = "<Ampl. Fourier>";
6089  break;
6090  case PV_FOURIER_PHASE:
6091  yAxisTitle = "<Phase Fourier>";
6092  break;
6094  yAxisTitle = "<Phase Opt. Real Fourier>";
6095  break;
6096  default:
6097  yAxisTitle = "??";
6098  break;
6099  }
6100  } else { // DifferenceView
6101  switch (fCurrentPlotView) {
6102  case PV_FOURIER_REAL:
6103  if (fData[0].diffFourierTag == 1)
6104  yAxisTitle = "<Real Fourier (d-f: data-theory)>";
6105  else
6106  yAxisTitle = "<Real Fourier (f-d: [(F data)-(F theory)]>";
6107  break;
6108  case PV_FOURIER_IMAG:
6109  if (fData[0].diffFourierTag == 1)
6110  yAxisTitle = "<Imag Fourier (d-f: data-theory)>";
6111  else
6112  yAxisTitle = "<Imag Fourier (f-d: [(F data)-(F theory)]>";
6113  break;
6114  break;
6116  if (fData[0].diffFourierTag == 1)
6117  yAxisTitle = "<Real/Imag Fourier (d-f: data-theory)>";
6118  else
6119  yAxisTitle = "<Real/Imag Fourier (f-d: [(F data)-(F theory)]>";
6120  break;
6121  break;
6122  case PV_FOURIER_PWR:
6123  if (fData[0].diffFourierTag == 1)
6124  yAxisTitle = "<Ampl. Fourier (d-f: data-theory)>";
6125  else
6126  yAxisTitle = "<Ampl. Fourier (f-d: [(F data)-(F theory)]>";
6127  break;
6128  break;
6129  case PV_FOURIER_PHASE:
6130  if (fData[0].diffFourierTag == 1)
6131  yAxisTitle = "<Phase Fourier (d-f: data-theory)>";
6132  else
6133  yAxisTitle = "<Phase Fourier (f-d: [(F data)-(F theory)]>";
6134  break;
6135  break;
6136  default:
6137  yAxisTitle = "??";
6138  break;
6139  }
6140  }
6141  }
6142 
6143  // find proper ranges
6144  Double_t xmin, xmax, ymin, ymax;
6145  xmin = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetFirst());
6146  xmax = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetLast()) + fHistoFrame->GetXaxis()->GetBinWidth(fHistoFrame->GetXaxis()->GetLast());
6147  ymin = fHistoFrame->GetMinimum();
6148  ymax = fHistoFrame->GetMaximum();
6149 
6150  // delete old fHistoFrame if present
6151  if (fHistoFrame) {
6152  delete fHistoFrame;
6153  fHistoFrame = nullptr;
6154  }
6155 
6156  fHistoFrame = fDataTheoryPad->DrawFrame(xmin, ymin, xmax, ymax);
6157 
6158  fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data());
6159  fHistoFrame->GetYaxis()->SetTitle(yAxisTitle.Data());
6160  fHistoFrame->GetYaxis()->SetTitleOffset(1.3);
6161 
6162  // find out what to be plotted
6163  switch (fCurrentPlotView) {
6164  case PV_DATA:
6165  if (!fDifferenceView) { // averaged data view
6166  fDataAvg.data->Draw("psame");
6167  fDataAvg.theory->Draw("same");
6168  } else { // averaged diff data view
6169  fDataAvg.diff->Draw("psame");
6170  }
6171  break;
6172  case PV_FOURIER_REAL:
6173  if (!fDifferenceView) { // averaged Fourier Real view
6174  fDataAvg.dataFourierRe->Draw("psame");
6175  fDataAvg.theoryFourierRe->Draw("same");
6176  } else { // averaged diff Fourier Real view
6177  fDataAvg.diffFourierRe->Draw("psame");
6178  }
6179  break;
6180  case PV_FOURIER_IMAG:
6181  if (!fDifferenceView) { // averaged Fourier Imag view
6182  fDataAvg.dataFourierIm->Draw("psame");
6183  fDataAvg.theoryFourierIm->Draw("same");
6184  } else { // averaged diff Fourier Imag view
6185  fDataAvg.diffFourierIm->Draw("psame");
6186  }
6187  break;
6189  if (!fDifferenceView) { // averaged Fourier Real&Imag view
6190  fDataAvg.dataFourierRe->Draw("psame");
6191  fDataAvg.theoryFourierRe->Draw("same");
6192  fDataAvg.dataFourierIm->Draw("psame");
6193  fDataAvg.theoryFourierIm->Draw("same");
6194  } else { // averaged diff Fourier Real&Imag view
6195  fDataAvg.diffFourierRe->Draw("psame");
6196  fDataAvg.diffFourierIm->Draw("psame");
6197  }
6198  break;
6199  case PV_FOURIER_PWR:
6200  if (!fDifferenceView) { // averaged Fourier Power view
6201  fDataAvg.dataFourierPwr->Draw("psame");
6202  fDataAvg.theoryFourierPwr->Draw("same");
6203  } else { // averaged diff Fourier Power view
6204  fDataAvg.diffFourierPwr->Draw("psame");
6205  }
6206  break;
6207  case PV_FOURIER_PHASE:
6208  if (!fDifferenceView) { // averaged Fourier Phase view
6209  fDataAvg.dataFourierPhase->Draw("psame");
6210  fDataAvg.theoryFourierPhase->Draw("same");
6211  } else { // averaged diff Fourier Phase view
6212  fDataAvg.diffFourierPhase->Draw("psame");
6213  }
6214  break;
6216  if (!fDifferenceView) { // averaged Fourier Phase Opt Real view
6217  fDataAvg.dataFourierPhaseOptReal->Draw("psame");
6218  fDataAvg.theoryFourierPhaseOptReal->Draw("same");
6219  } else { // averaged diff Fourier Phase view
6220  fDataAvg.diffFourierPhaseOptReal->Draw("psame");
6221  }
6222  break;
6223  default:
6224  break;
6225  }
6226 
6227  // check if RRF and if yes show a label
6228  if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) {
6229  fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data());
6230  }
6231 
6232  fDataTheoryPad->Update();
6233 
6234  fMainCanvas->cd();
6235  fMainCanvas->Update();
6236 }
6237 
6238 //--------------------------------------------------------------------------
6239 // IncrementFourierPhase (private)
6240 //--------------------------------------------------------------------------
6245 {
6247  return;
6248 
6249  double re, im;
6250  const double cp = TMath::Cos(fFourier.fPhaseIncrement/180.0*TMath::Pi());
6251  const double sp = TMath::Sin(fFourier.fPhaseIncrement/180.0*TMath::Pi());
6252 
6253  for (UInt_t i=0; i<fCurrentFourierPhase.size(); i++)
6256 
6257  for (UInt_t i=0; i<fData.size(); i++) { // loop over all data sets
6258  if ((fData[i].dataFourierRe != nullptr) && (fData[i].dataFourierIm != nullptr)) {
6259  for (Int_t j=0; j<fData[i].dataFourierRe->GetNbinsX(); j++) { // loop over a fourier data set
6260  // calculate new fourier data set value
6261  re = fData[i].dataFourierRe->GetBinContent(j) * cp + fData[i].dataFourierIm->GetBinContent(j) * sp;
6262  im = fData[i].dataFourierIm->GetBinContent(j) * cp - fData[i].dataFourierRe->GetBinContent(j) * sp;
6263  // overwrite fourier data set value
6264  fData[i].dataFourierRe->SetBinContent(j, re);
6265  fData[i].dataFourierIm->SetBinContent(j, im);
6266  }
6267  }
6268  if ((fData[i].theoryFourierRe != nullptr) && (fData[i].theoryFourierIm != nullptr)) {
6269  for (Int_t j=0; j<fData[i].theoryFourierRe->GetNbinsX(); j++) { // loop over a fourier data set
6270  // calculate new fourier data set value
6271  re = fData[i].theoryFourierRe->GetBinContent(j) * cp + fData[i].theoryFourierIm->GetBinContent(j) * sp;
6272  im = fData[i].theoryFourierIm->GetBinContent(j) * cp - fData[i].theoryFourierRe->GetBinContent(j) * sp;
6273  // overwrite fourier data set value
6274  fData[i].theoryFourierRe->SetBinContent(j, re);
6275  fData[i].theoryFourierIm->SetBinContent(j, im);
6276  }
6277  }
6278  if ((fData[i].diffFourierRe != nullptr) && (fData[i].diffFourierIm != nullptr)) {
6279  for (Int_t j=0; j<fData[i].diffFourierRe->GetNbinsX(); j++) { // loop over a fourier diff data set
6280  // calculate new fourier diff data set value
6281  re = fData[i].diffFourierRe->GetBinContent(j) * cp + fData[i].diffFourierIm->GetBinContent(j) * sp;
6282  im = fData[i].diffFourierIm->GetBinContent(j) * cp - fData[i].diffFourierRe->GetBinContent(j) * sp;
6283  // overwrite fourier diff data set value
6284  fData[i].diffFourierRe->SetBinContent(j, re);
6285  fData[i].diffFourierIm->SetBinContent(j, im);
6286  }
6287  }
6288  }
6289 }
6290 
6291 //--------------------------------------------------------------------------
6292 // DecrementFourierPhase (private)
6293 //--------------------------------------------------------------------------
6298 {
6300  return;
6301 
6302  double re, im;
6303  const double cp = TMath::Cos(fFourier.fPhaseIncrement/180.0*TMath::Pi());
6304  const double sp = TMath::Sin(fFourier.fPhaseIncrement/180.0*TMath::Pi());
6305 
6306  for (UInt_t i=0; i<fCurrentFourierPhase.size(); i++)
6309 
6310  for (UInt_t i=0; i<fData.size(); i++) { // loop over all data sets
6311  if ((fData[i].dataFourierRe != nullptr) && (fData[i].dataFourierIm != nullptr)) {
6312  for (Int_t j=0; j<fData[i].dataFourierRe->GetNbinsX(); j++) { // loop over a fourier data set
6313  // calculate new fourier data set value
6314  re = fData[i].dataFourierRe->GetBinContent(j) * cp - fData[i].dataFourierIm->GetBinContent(j) * sp;
6315  im = fData[i].dataFourierIm->GetBinContent(j) * cp + fData[i].dataFourierRe->GetBinContent(j) * sp;
6316  // overwrite fourier data set value
6317  fData[i].dataFourierRe->SetBinContent(j, re);
6318  fData[i].dataFourierIm->SetBinContent(j, im);
6319  }
6320  }
6321  if ((fData[i].theoryFourierRe != nullptr) && (fData[i].theoryFourierIm != nullptr)) {
6322  for (Int_t j=0; j<fData[i].theoryFourierRe->GetNbinsX(); j++) { // loop over a fourier data set
6323  // calculate new fourier data set value
6324  re = fData[i].theoryFourierRe->GetBinContent(j) * cp - fData[i].theoryFourierIm->GetBinContent(j) * sp;
6325  im = fData[i].theoryFourierIm->GetBinContent(j) * cp + fData[i].theoryFourierRe->GetBinContent(j) * sp;
6326  // overwrite fourier data set value
6327  fData[i].theoryFourierRe->SetBinContent(j, re);
6328  fData[i].theoryFourierIm->SetBinContent(j, im);
6329  }
6330  }
6331  if ((fData[i].diffFourierRe != nullptr) && (fData[i].diffFourierIm != nullptr)) {
6332  for (Int_t j=0; j<fData[i].diffFourierRe->GetNbinsX(); j++) { // loop over a fourier diff data set
6333  // calculate new fourier diff data set value
6334  re = fData[i].diffFourierRe->GetBinContent(j) * cp - fData[i].diffFourierIm->GetBinContent(j) * sp;
6335  im = fData[i].diffFourierIm->GetBinContent(j) * cp + fData[i].diffFourierRe->GetBinContent(j) * sp;
6336  // overwrite fourier diff data set value
6337  fData[i].diffFourierRe->SetBinContent(j, re);
6338  fData[i].diffFourierIm->SetBinContent(j, im);
6339  }
6340  }
6341  }
6342 }
6343 
6344 
6345 //--------------------------------------------------------------------------
6346 // IsScaleN0AndBkg (private)
6347 //--------------------------------------------------------------------------
6359 {
6360  Bool_t willScale = true;
6361 
6363  for (UInt_t i=0; i<cmd->size(); i++) {
6364  if (cmd->at(i).fLine.Contains("SCALE_N0_BKG", TString::kIgnoreCase)) {
6365  TObjArray *tokens = nullptr;
6366  TObjString *ostr = nullptr;
6367  TString str;
6368  tokens = cmd->at(i).fLine.Tokenize(" \t");
6369  if (tokens->GetEntries() != 2) {
6370  std::cerr << std::endl << ">> PRunSingleHisto::IsScaleN0AndBkg(): **WARNING** Found uncorrect 'SCALE_N0_BKG' command, will ignore it.";
6371  std::cerr << std::endl << ">> Allowed commands: SCALE_N0_BKG TRUE | FALSE" << std::endl;
6372  return willScale;
6373  }
6374  ostr = dynamic_cast<TObjString*>(tokens->At(1));
6375  str = ostr->GetString();
6376  if (!str.CompareTo("FALSE", TString::kIgnoreCase)) {
6377  willScale = false;
6378  }
6379  // clean up
6380  if (tokens)
6381  delete tokens;
6382  }
6383  }
6384 
6385  return willScale;
6386 }
6387 
6388 //--------------------------------------------------------------------------
6389 // GetNeededAccuracy (private)
6390 //--------------------------------------------------------------------------
6400 {
6401  const UInt_t precLimit = 6;
6402  UInt_t decimalPoint = 0;
6403  UInt_t accuracy = 6;
6404 
6405  if (param.fStep == 0.0) { // check if fit parameter is a constant, i.e. step==0
6406  char str[128];
6407 
6408  snprintf(str, sizeof(str), "%lf", param.fValue);
6409 
6410  // find decimal point
6411  for (UInt_t i=0; i<strlen(str); i++) {
6412  if (str[i] == '.') {
6413  decimalPoint = i;
6414  break;
6415  }
6416  }
6417 
6418  // find last significant digit
6419  for (Int_t i=strlen(str)-1; i>=0; i--) {
6420  if (str[i] != '0') {
6421  if (((UInt_t)i-decimalPoint) < precLimit)
6422  accuracy = (UInt_t)i-decimalPoint;
6423  else
6424  accuracy = precLimit;
6425  break;
6426  }
6427  }
6428 
6429  } else if ((param.fStep != 0) && !param.fPosErrorPresent) { // check if no positive error is given step!=0 but fPosErrorPresent==false
6430 
6431  for (UInt_t i=0; i<precLimit; i++) {
6432  if ((Int_t)(param.fStep*pow(10.0,(Double_t)i)) != 0) {
6433  accuracy = i;
6434  break;
6435  }
6436  }
6437 
6438  if (accuracy+1 <= precLimit)
6439  accuracy += 1;
6440  } else { // positive and negative error present
6441 
6442  // negative error
6443  for (UInt_t i=0; i<precLimit; i++) {
6444  if ((Int_t)(param.fStep*pow(10.0,(Double_t)i)) != 0) {
6445  accuracy = i;
6446  break;
6447  }
6448  }
6449  // positive error
6450  UInt_t accuracy2 = 6;
6451  for (UInt_t i=0; i<precLimit; i++) {
6452  if ((Int_t)(param.fStep*pow(10.0,(Double_t)i)) != 0) {
6453  accuracy2 = i;
6454  break;
6455  }
6456  }
6457 
6458  if (accuracy2 > accuracy)
6459  accuracy = accuracy2;
6460 
6461  if (accuracy+1 <= precLimit)
6462  accuracy += 1;
6463  }
6464 
6465  return accuracy;
6466 }
6467 
6468 
6469 //--------------------------------------------------------------------------
6470 // GetInterpolatedValue (private)
6471 //--------------------------------------------------------------------------
6482 Double_t PMusrCanvas::GetInterpolatedValue(TH1F* histo, Double_t xVal)
6483 {
6484  if (histo == nullptr)
6485  return 0.0;
6486 
6487  Int_t idx = histo->FindBin(xVal);
6488 
6489  // make sure idx is within range
6490  if ((idx < 1) || (idx > histo->GetNbinsX()))
6491  return 0.0;
6492 
6493  // make sure the lower bound idx is found. This is needed since
6494  // FindBin rounds towards the closer idx.
6495  if (histo->GetBinCenter(idx) > xVal)
6496  --idx;
6497 
6498  Double_t x0, x1, y0, y1;
6499  x0 = histo->GetBinCenter(idx);
6500  x1 = histo->GetBinCenter(idx+1);
6501  y0 = histo->GetBinContent(idx);
6502  y1 = histo->GetBinContent(idx+1);
6503 
6504  return (y1-y0)*(xVal-x0)/(x1-x0)+y0;
6505 }
6506 
virtual void InitDataSet(PMusrCanvasDataSet &dataSet)
virtual PRunData * GetAsymmetry(UInt_t index, EDataSwitch tag=kIndex)
Double_t fPhaseIncrement
phase increment for manual phase optimization
Definition: PMusr.h:772
virtual const PDoubleVector * GetXTheory()
Definition: PMusr.h:250
virtual Double_t GetField(const TString &runName) const
Bool_t fValid
if true, everything looks OK
Definition: PMusrCanvas.h:245
virtual TString GetRRFUnit()
Definition: PMusr.cpp:834
Bool_t fYRangePresent
flag indicating if x-/y-range is present
Definition: PMusrCanvas.h:254
std::unique_ptr< TGPopupMenu > fPopupFourier
popup menu of the Musrfit/Fourier sub menu
Definition: PMusrCanvas.h:270
#define MSR_PLOT_ASYM_RRF
Definition: PMusr.h:119
std::unique_ptr< TCanvas > fMainCanvas
main canvas
Definition: PMusrCanvas.h:273
Double_t fYmin
Definition: PMusrCanvas.h:255
UInt_t diffFourierTag
0=not relevant, 1=d-f (Fourier of difference time spectra), 2=f-d (difference of Fourier spectra) ...
Definition: PMusrCanvas.h:172
virtual const PDoubleVector * GetError()
Definition: PMusr.h:249
TH1F * diffFourierIm
imaginary part of the Fourier transform of the diff histogram
Definition: PMusrCanvas.h:136
PMsrFourierStructure fFourier
structure holding all the information necessary to perform the Fourier transform
Definition: PMusrCanvas.h:295
#define MSR_FITTYPE_BNMR
Definition: PMusr.h:111
virtual Int_t FindBin(const Double_t x, TGraphErrors *graph)
virtual void HandleFourierDifference()
TGraphErrors * data
data error graph
Definition: PMusrCanvas.h:156
#define XTHEO
Definition: PMusrCanvas.h:55
virtual Double_t GetEnergy(const TString &runName) const
TGraphErrors * diffFourierRe
real part of the Fourier transform of the diff error graph
Definition: PMusrCanvas.h:167
virtual void PlotFourierPhaseValue(Bool_t unzoom=false)
virtual void HandleNonMusrDataSet(UInt_t plotNo, UInt_t runNo, PRunData *data)
virtual void ExportData(const Char_t *fileName)
TH1F * dataFourierIm
imaginary part of the Fourier transform of the data histogram
Definition: PMusrCanvas.h:124
Bool_t fFourierBlockPresent
flag indicating if a Fourier block is present in the msr-file
Definition: PMusr.h:761
#define P_MENU_ID_FOURIER_PHASE_MINUS
Bool_t fTheoAsData
flag if true, calculate theory points only at the data points
Definition: PMusrCanvas.h:239
virtual void UpdateInfoPad()
Bool_t fScaleN0AndBkg
true=N0 and background is scaled to (1/ns), otherwise (1/bin) for the single histogram case ...
Definition: PMusrCanvas.h:243
virtual void DecrementFourierPhase()
TH1F * theoryFourierPhase
phase spectrum of the Fourier transform of the theory histogram
Definition: PMusrCanvas.h:132
PMusrCanvasNonMusrDataList fNonMusrData
list of all error graphs to be plotted (non-muSR)
Definition: PMusrCanvas.h:291
TGMenuBar * fBar
menu bar
Definition: PMusrCanvas.h:268
TGraphErrors * diffFourierPhase
phase spectrum of the Fourier transform of the diff error graph
Definition: PMusrCanvas.h:170
std::vector< PMsrRunBlock > PMsrRunList
Definition: PMusr.h:754
#define P_MENU_ID_FOURIER_PHASE_PLUS
virtual void HandleDataSet(UInt_t plotNo, UInt_t runNo, PRunData *data)
virtual Bool_t IsScaleN0AndBkg()
virtual Int_t GetRRFUnitTag()
Definition: PMusr.h:578
TH1F * dataFourierRe
real part of the Fourier transform of the data histogram
Definition: PMusrCanvas.h:123
Int_t fPlotTag
tag used for initial plot. 0=real, 1=imaginary, 2=real & imaginary (default), 3=power, 4=phase
Definition: PMusr.h:766
#define MSR_FITTYPE_SINGLE_HISTO_RRF
Definition: PMusr.h:107
#define PV_FOURIER_IMAG
Definition: PMusrCanvas.h:60
virtual Bool_t IsValid()
Definition: PFourier.h:120
#define FOURIER_PLOT_POWER
Definition: PMusr.h:147
ClassImpQ(PMusrCanvas) PMusrCanvas
std::unique_ptr< TStyle > fStyle
A collection of all graphics attributes.
Definition: PMusrCanvas.h:262
#define PV_FOURIER_PHASE
Definition: PMusrCanvas.h:63
#define MSR_FITTYPE_SINGLE_HISTO
Definition: PMusr.h:106
#define P_MENU_ID_FOURIER
TH1F * dataFourierPhaseOptReal
phase optimized real part spectrum Fourier transform of the data histogram
Definition: PMusrCanvas.h:127
virtual const PDoubleVector * GetTheory()
Definition: PMusr.h:251
TGraphErrors * theory
theory histogram belonging to the data error graph
Definition: PMusrCanvas.h:161
TH1F * dataFourierPwr
power spectrum of the Fourier transform of the data histogram
Definition: PMusrCanvas.h:125
virtual void UpdateParamTheoryPad()
#define RRF_UNIT_MHz
Definition: PMusr.h:155
Double_t fValue
value
Definition: PMusr.h:549
virtual void PlotFourier(Bool_t unzoom=false)
TGraphErrors * dataFourierPhase
phase spectrum of the Fourier transform of the data error graph
Definition: PMusrCanvas.h:160
virtual void CreateStyle()
#define RRF_UNIT_kHz
Definition: PMusr.h:154
#define MSR_PLOT_BNMR
Definition: PMusr.h:121
#define MSR_PLOT_SINGLE_HISTO
Definition: PMusr.h:116
Double_t fMin
chisq or max. likelihood
Definition: PMusr.h:813
virtual Int_t GetRRFPacking()
Definition: PMusr.h:580
virtual PRunData * GetMuMinus(UInt_t index, EDataSwitch tag=kIndex)
TH1F * theory
theory histogram belonging to the data histogram
Definition: PMusrCanvas.h:128
virtual PRunData * GetAsymmetryRRF(UInt_t index, EDataSwitch tag=kIndex)
Bool_t fAveragedView
tag showing that the averaged view or normal view should be presented.
Definition: PMusrCanvas.h:246
#define FOURIER_PLOT_IMAG
Definition: PMusr.h:145
TGraphErrors * theoryFourierPhase
phase spectrum of the Fourier transform of the theory error graph
Definition: PMusrCanvas.h:165
TH1F * theoryFourierPhaseOptReal
phase optimized real part spectrum Fourier transform of the theory histogram
Definition: PMusrCanvas.h:133
TH1F * theoryFourierPwr
power spectrum of the Fourier transform of the theory histogram
Definition: PMusrCanvas.h:131
virtual void CleanupDataSet(PMusrCanvasDataSet &dataSet)
#define FOURIER_PLOT_REAL
Definition: PMusr.h:144
Bool_t fDCCorrected
if set true, the dc offset of the signal/theory will be removed before the FFT is made...
Definition: PMusr.h:763
std::vector< Int_t > PIntVector
Definition: PMusr.h:178
ClassImp(PMusrCanvasPlotRange) PMusrCanvasPlotRange
Definition: PMusrCanvas.cpp:47
std::vector< PMusrCanvasAsciiDump > PMusrCanvasAsciiDumpVector
Definition: PMusrCanvas.h:196
TH1F * data
data histogram
Definition: PMusrCanvas.h:122
virtual Double_t GetTheoryTimeStep()
Definition: PMusr.h:245
#define FOURIER_UNIT_CYCLES
Definition: PMusr.h:135
Double_t fYmax
data/theory frame range
Definition: PMusrCanvas.h:255
#define P_MENU_ID_DATA
Definition: PMusrCanvas.h:67
virtual void SetYRange(Double_t ymin, Double_t ymax)
Definition: PMusrCanvas.cpp:97
TGraphErrors * dataFourierPwr
power spectrum of the Fourier transform of the data error graph
Definition: PMusrCanvas.h:159
TH1F * fHistoFrame
fHistoFrame is a &#39;global&#39; frame needed in order to plot histograms with (potentially) different x-fra...
Definition: PMusrCanvas.h:281
virtual void WindowClosed()
virtual Double_t GetTheoryTimeStart()
Definition: PMusr.h:244
std::vector< PMsrParamStructure > PMsrParamList
Definition: PMusr.h:564
Int_t fTimeout
timeout after which the Done signal should be emited. If timeout <= 0, no timeout is taking place ...
Definition: PMusrCanvas.h:242
#define FOURIER_PLOT_REAL_AND_IMAG
Definition: PMusr.h:146
std::vector< Double_t > PDoubleVector
Definition: PMusr.h:196
virtual Double_t GetRRFFreq(const char *unit)
Definition: PMusr.cpp:762
virtual PRunData * GetSingleHisto(UInt_t index, EDataSwitch tag=kIndex)
#define P_MENU_ID_FOURIER_PWR
virtual void Transform(UInt_t apodizationTag=0)
Definition: PFourier.cpp:398
virtual Double_t GetMaximum(TH1F *histo, Double_t xmin=-1.0, Double_t xmax=-1.0)
PIntVector fMarkerList
list of markers
Definition: PMusrCanvas.h:296
virtual PMsrRunList * GetMsrRunList()
Definition: PMsrHandler.h:63
PMusrCanvasDataList fData
list of all histogram data to be plotted (asymmetry/single histogram)
Definition: PMusrCanvas.h:290
#define FOURIER_UNIT_NOT_GIVEN
Definition: PMusr.h:131
TH1F * theoryFourierIm
imaginary part of the Fourier transform of the theory histogram
Definition: PMusrCanvas.h:130
#define FOURIER_UNIT_FREQ
Definition: PMusr.h:134
#define P_MENU_ID_EXPORT_DATA
virtual Double_t GetInterpolatedValue(TH1F *histo, Double_t xVal)
Int_t fPreviousPlotView
tag showing the previous plot view
Definition: PMusrCanvas.h:250
TGraphErrors * theoryFourierIm
imaginary part of the Fourier transform of the theory error graph
Definition: PMusrCanvas.h:163
Int_t fApodization
tag indicating the kind of apodization wished, 0=no appodization (default), 1=weak, 2=medium, 3=strong (for details see the docu)
Definition: PMusr.h:765
virtual PMsrStatisticStructure * GetMsrStatistic()
Definition: PMsrHandler.h:67
#define YTITLE
Definition: PMusrCanvas.h:54
#define PV_FOURIER_REAL_AND_IMAG
Definition: PMusrCanvas.h:61
#define MSR_FITTYPE_NON_MUSR
Definition: PMusr.h:112
std::unique_ptr< TString > fRRFText
RRF information.
Definition: PMusrCanvas.h:259
virtual void InitAverage()
#define PV_FOURIER_PHASE_OPT_REAL
Definition: PMusrCanvas.h:64
virtual void HandleAverage()
#define P_MENU_ID_DIFFERENCE
Definition: PMusrCanvas.h:69
TGraphErrors * dataFourierRe
real part of the Fourier transform of the data error graph
Definition: PMusrCanvas.h:157
virtual Double_t GetYmax()
Definition: PMusrCanvas.h:103
TMultiGraph * fMultiGraphData
fMultiGraphData is a &#39;global&#39; graph needed in order to plot error graphs (data) with (potentially) di...
Definition: PMusrCanvas.h:292
static TH1F * GetPhaseOptRealFourier(const TH1F *re, const TH1F *im, std::vector< Double_t > &phase, const Double_t scale=1.0, const Double_t min=-1.0, const Double_t max=-1.0)
Definition: PFourier.cpp:500
#define MSR_PLOT_NON_MUSR
Definition: PMusr.h:122
std::unique_ptr< TPaveText > fTheoryPad
theory pad used to display the theory and functions
Definition: PMusrCanvas.h:277
#define PV_DATA
Definition: PMusrCanvas.h:58
virtual TH1F * GetRealFourier(const Double_t scale=1.0)
Definition: PFourier.cpp:452
#define RRF_UNIT_T
Definition: PMusr.h:158
virtual const PDoubleVector * GetX()
Definition: PMusr.h:247
TGraphErrors * theoryFourierPwr
power spectrum of the Fourier transform of the theory error graph
Definition: PMusrCanvas.h:164
Bool_t fDifferenceView
tag showing that the shown data, fourier, are the difference between data and theory ...
Definition: PMusrCanvas.h:247
static int timeout
Definition: musrfit.cpp:71
virtual PMsrGlobalBlock * GetMsrGlobal()
Definition: PMsrHandler.h:62
virtual const Char_t * GetXAxisTitle(const TString &runName, const UInt_t idx) const
Double_t fStep
step / error / neg_error, depending on the situation
Definition: PMusr.h:550
std::vector< PMsrLineStructure > PMsrLines
Definition: PMusr.h:539
Double_t fXmax
Definition: PMusrCanvas.h:255
PMusrCanvasDataSet fDataAvg
set of all averaged data to be plotted (asymmetry/single histogram)
Definition: PMusrCanvas.h:288
std::unique_ptr< TLatex > fCurrentFourierPhaseText
used in Re/Im Fourier to show the current phase in the pad
Definition: PMusrCanvas.h:258
PIntVector fPhaseParamNo
parameter number(s) if used instead of a phase value
Definition: PMusr.h:768
#define RRF_UNIT_G
Definition: PMusr.h:157
Double_t fRangeForPhaseCorrection[2]
field/frequency range for automatic phase correction
Definition: PMusr.h:770
virtual const PDoubleVector * GetValue()
Definition: PMusr.h:248
#define RRF_UNIT_Mcs
Definition: PMusr.h:156
std::unique_ptr< TLatex > fRRFLatexText
used to display RRF info
Definition: PMusrCanvas.h:260
virtual void GetExportDataSet(const TH1F *data, const Double_t xmin, const Double_t xmax, PMusrCanvasAsciiDumpVector &dumpData, const Bool_t hasError=true)
virtual Double_t GetXmin()
Definition: PMusrCanvas.h:100
virtual void HandleCmdKey(Int_t event, Int_t x, Int_t y, TObject *selected)
virtual void HandleMenuPopup(Int_t id)
virtual void PlotFourierDifference(Bool_t unzoom=false)
virtual TH1F * GetPowerFourier(const Double_t scale=1.0)
Definition: PFourier.cpp:636
#define MSR_PLOT_SINGLE_HISTO_RRF
Definition: PMusr.h:117
virtual PRunData * GetNonMusr(UInt_t index, EDataSwitch tag=kIndex)
Bool_t fStartWithFourier
flag if true, the Fourier transform will be presented bypassing the time domain representation ...
Definition: PMusrCanvas.h:240
PMusrCanvasPlotRange * dataRange
keep the msr-file plot data range
Definition: PMusrCanvas.h:140
#define YINFO
Definition: PMusrCanvas.h:53
Double_t fXmin
Definition: PMusrCanvas.h:255
TH1F * dataFourierPhase
phase spectrum of the Fourier transform of the data histogram
Definition: PMusrCanvas.h:126
virtual PMsrFourierStructure * GetMsrFourierList()
Definition: PMsrHandler.h:65
PDoubleVector fPhase
phase(s)
Definition: PMusr.h:769
virtual void CleanupFourier()
virtual void CleanupAverage()
virtual TH1F * GetPhaseFourier(const Double_t scale=1.0)
Definition: PFourier.cpp:678
std::unique_ptr< TTimer > fTimeoutTimer
timeout timer in order to terminate if no action is taking place for too long
Definition: PMusrCanvas.h:264
virtual void LastCanvasClosed()
Int_t fUnits
flag used to indicate the units. 1=field units (G); 2=field units (T); 3=frequency units (MHz); 4=Mc/...
Definition: PMusr.h:762
virtual void IncrementFourierPhase()
virtual void PlotAverage(Bool_t unzoom=false)
Int_t fPlotType
plot type
Definition: PMusr.h:780
TH1F * diffFourierRe
real part of the Fourier transform of the diff histogram
Definition: PMusrCanvas.h:135
TGraphErrors * diff
difference error graph, i.e. data-theory
Definition: PMusrCanvas.h:166
UInt_t diffFourierTag
0=not relevant, 1=d-f (Fourier of difference time spectra), 2=f-d (difference of Fourier spectra) ...
Definition: PMusrCanvas.h:141
#define MSR_FITTYPE_MU_MINUS
Definition: PMusr.h:110
TH1F * diff
difference histogram, i.e. data-theory
Definition: PMusrCanvas.h:134
#define PMUSR_UNDEFINED
Definition: PMusr.h:89
virtual UInt_t GetNeededAccuracy(PMsrParamStructure param)
TMultiGraph * fMultiGraphDiff
fMultiGraphDiff is a &#39;global&#39; graph needed in order to plot error graphs (data-theory) with (potentia...
Definition: PMusrCanvas.h:293
virtual PMsrPlotList * GetMsrPlotList()
Definition: PMsrHandler.h:66
#define FOURIER_APOD_NONE
Definition: PMusr.h:138
#define P_MENU_ID_FOURIER_PHASE
virtual void InitMusrCanvas(const Char_t *title, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh)
virtual void SetMsrHandler(PMsrHandler *msrHandler)
virtual void InitFourier()
virtual void HandleDifference()
#define MSR_PLOT_MU_MINUS
Definition: PMusr.h:120
#define FOURIER_PLOT_PHASE
Definition: PMusr.h:148
#define FOURIER_UNIT_GAUSS
Definition: PMusr.h:132
virtual const Char_t * GetYAxisTitle(const TString &runName, const UInt_t idx) const
std::unique_ptr< TLegend > fMultiGraphLegend
used for non-muSR plots to display a legend
Definition: PMusrCanvas.h:279
virtual Int_t GetFitType()
Definition: PMusr.h:581
virtual ~PMusrCanvas()
TGraphErrors * theoryFourierRe
real part of the Fourier transform of the theory error graph
Definition: PMusrCanvas.h:162
Bool_t fChisq
flag telling if min = chi2 or min = max.likelihood
Definition: PMusr.h:812
#define PV_FOURIER_REAL
Definition: PMusrCanvas.h:59
#define FOURIER_APOD_NOT_GIVEN
Definition: PMusr.h:137
PIntVector fRuns
list of runs to be plotted
Definition: PMusr.h:786
virtual Double_t GetMinimum(TH1F *histo, Double_t xmin=-1.0, Double_t xmax=-1.0)
virtual PRunData * GetSingleHistoRRF(UInt_t index, EDataSwitch tag=kIndex)
virtual PMsrLines * GetMsrTheory()
Definition: PMsrHandler.h:60
#define FOURIER_UNIT_TESLA
Definition: PMusr.h:133
PDoubleVector dataErr
error of the y-axis data set
Definition: PMusrCanvas.h:188
PIntVector fColorList
list of colors
Definition: PMusrCanvas.h:297
TH1F * diffFourierPhaseOptReal
phase optimized real part spectrum Fourier transform of the diff histogram
Definition: PMusrCanvas.h:139
std::vector< PDoublePair > PDoublePairVector
Definition: PMusr.h:208
TH1F * theoryFourierRe
real part of the Fourier transform of the theory histogram
Definition: PMusrCanvas.h:129
virtual void Done(Int_t status=0)
Bool_t fBatchMode
musrview in ROOT batch mode
Definition: PMusrCanvas.h:244
PDoubleVector dataX
x-axis data set
Definition: PMusrCanvas.h:186
#define FOURIER_PLOT_PHASE_OPT_REAL
Definition: PMusr.h:149
#define FOURIER_PLOT_NOT_GIVEN
Definition: PMusr.h:143
virtual const Char_t * GetSetup(const TString &runName) const
if(xmlFile.is_open())
std::unique_ptr< TPaveText > fTitlePad
title pad used to display a title
Definition: PMusrCanvas.h:274
TRootCanvas * fImp
ROOT native GUI version of main window with menubar and drawing area.
Definition: PMusrCanvas.h:267
virtual PMsrParamList * GetMsrParamList()
Definition: PMsrHandler.h:59
virtual void GetGroupingString(Int_t runNo, TString detector, TString &groupingStr)
TGPopupMenu * fPopupMain
popup menu Musrfit in the main menu bar
Definition: PMusrCanvas.h:269
virtual void HandleFourier()
TH1F * diffFourierPwr
power spectrum of the Fourier transform of the diff histogram
Definition: PMusrCanvas.h:137
Int_t fFourierPower
i.e. zero padding up to 2^fFourierPower, default = 0 which means NO zero padding
Definition: PMusr.h:764
virtual void CleanupFourierDifference()
PDoubleVector data
y-axis data set
Definition: PMusrCanvas.h:187
#define MSR_FITTYPE_ASYM_RRF
Definition: PMusr.h:109
#define P_MENU_ID_FOURIER_REAL
virtual PRunData * GetAsymmetryBNMR(UInt_t index, EDataSwitch tag=kIndex)
#define P_MENU_ID_FOURIER_PHASE_OPT_REAL
virtual Double_t GetDataTimeStart()
Definition: PMusr.h:242
virtual void PlotDifference(Bool_t unzoom=false)
UInt_t fNdf
number of degrees of freedom
Definition: PMusr.h:815
#define P_MENU_ID_AVERAGE
virtual void UpdateDataTheoryPad()
virtual PMsrLines * GetMsrFunctions()
Definition: PMsrHandler.h:61
#define MSR_FITTYPE_ASYM
Definition: PMusr.h:108
std::vector< TString > PStringVector
Definition: PMusr.h:214
virtual void HandleDifferenceFourier()
Int_t fPlotType
plot type tag: -1 == undefined, MSR_PLOT_SINGLE_HISTO == single histogram, MSR_PLOT_ASYM == asymmetry...
Definition: PMusrCanvas.h:251
virtual Double_t GetXmax()
Definition: PMusrCanvas.h:101
PRunListCollection * fRunList
data handler
Definition: PMusrCanvas.h:285
PDoubleVector fCurrentFourierPhase
holds the current Fourier phase(s)
Definition: PMusrCanvas.h:257
return status
virtual void CalcPhaseOptReFT()
PMusrCanvas::CalcPhaseOptReFT.
#define P_MENU_ID_FOURIER_REAL_AND_IMAG
TGraphErrors * diffFourierIm
imaginary part of the Fourier transform of the diff error graph
Definition: PMusrCanvas.h:168
virtual PMsrLines * GetMsrCommands()
Definition: PMsrHandler.h:64
TH1F * diffFourierPhase
phase spectrum of the Fourier transform of the diff histogram
Definition: PMusrCanvas.h:138
#define P_MENU_ID_FOURIER_IMAG
Double_t fPlotRange[2]
field/frequency plot range
Definition: PMusr.h:771
virtual Double_t CalculateDiff(const Double_t x, const Double_t y, TH1F *theo)
virtual void SetTimeout(Int_t ival)
std::unique_ptr< TLegend > fInfoPad
info pad used to display a legend of the data plotted
Definition: PMusrCanvas.h:278
virtual const PDoublePairVector * GetTemp(const TString &runName) const
virtual Double_t GetFitRange(UInt_t idx)
Definition: PMusr.cpp:1051
virtual void SaveGraphicsAndQuit(Char_t *fileName, Char_t *graphicsFormat)
PMsrHandler * fMsrHandler
msr-file handler
Definition: PMusrCanvas.h:284
TGraphErrors * diffFourierPwr
power spectrum of the Fourier transform of the diff error graph
Definition: PMusrCanvas.h:169
virtual Double_t GetYmin()
Definition: PMusrCanvas.h:102
TString fDate
string holding fitting date and time
Definition: PMusr.h:811
Bool_t fStartWithAvg
flag if true, the averaged data/Fourier will be presented
Definition: PMusrCanvas.h:241
virtual void SetXRange(Double_t xmin, Double_t xmax)
Definition: PMusrCanvas.cpp:75
virtual Double_t GetDataTimeStep()
Definition: PMusr.h:243
Bool_t fToggleColor
tag showing if a single histo theory is color toggled
Definition: PMusrCanvas.h:248
static const char * gFiletypes[]
Definition: PMusrCanvas.cpp:43
std::unique_ptr< TPaveText > fParameterPad
parameter pad used to display the fitting parameters
Definition: PMusrCanvas.h:276
virtual void PlotData(Bool_t unzoom=false)
Bool_t fPosErrorPresent
positive error is defined (as a number)
Definition: PMusr.h:551
std::unique_ptr< TPad > fDataTheoryPad
data/theory pad used to display the data/theory
Definition: PMusrCanvas.h:275
Int_t fCurrentPlotView
tag showing what the current plot view is: data, fourier, ...
Definition: PMusrCanvas.h:249
#define MSR_PLOT_ASYM
Definition: PMusr.h:118
#define P_MENU_PLOT_OFFSET
Definition: PMusrCanvas.h:73
TGraphErrors * dataFourierIm
imaginary part of the Fourier transform of the data error graph
Definition: PMusrCanvas.h:158
virtual TH1F * GetImaginaryFourier(const Double_t scale=1.0)
Definition: PFourier.cpp:594
#define PV_FOURIER_PWR
Definition: PMusrCanvas.h:62
PMusrCanvasPlotRange * dataRange
keep the msr-file plot data range
Definition: PMusrCanvas.h:171
Bool_t fXRangePresent
Definition: PMusrCanvas.h:254
Int_t fPlotNumber
plot number
Definition: PMusrCanvas.h:252
virtual void CleanupDifference()