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