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