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