/*************************************************************************** PMusrCanvas.cpp Author: Andreas Suter e-mail: andreas.suter@psi.ch ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2020 by Andreas Suter * * andreas.suter@psi.ch * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include "PMusrCanvas.h" #include "PFourier.h" static const char *gFiletypes[] = { "Data files", "*.dat", "All files", "*", nullptr, nullptr }; ClassImp(PMusrCanvasPlotRange) //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor */ PMusrCanvasPlotRange::PMusrCanvasPlotRange() { fXRangePresent = false; fYRangePresent = false; fXmin = 0.0; fXmax = 0.0; fYmin = 0.0; fYmax = 0.0; } //-------------------------------------------------------------------------- // SetXRange (public) //-------------------------------------------------------------------------- /** *

Sets the x-range values. * * \param xmin minimum range value * \param xmax maximum range value */ void PMusrCanvasPlotRange::SetXRange(Double_t xmin, Double_t xmax) { if (xmin > xmax) { std::cerr << std::endl << ">> PMusrCanvasPlotRange::SetXRange(): **WARNING** xmin > xmax, will swap them." << std::endl; fXmin = xmax; fXmax = xmin; } else { fXmin = xmin; fXmax = xmax; } fXRangePresent = true; } //-------------------------------------------------------------------------- // SetYRange (public) //-------------------------------------------------------------------------- /** *

Sets the y-range values. * * \param ymin minimum range value * \param ymax maximum range value */ void PMusrCanvasPlotRange::SetYRange(Double_t ymin, Double_t ymax) { if (ymin > ymax) { std::cerr << std::endl << ">> PMusrCanvasPlotRange::SetYRange(): **WARNING** ymin > ymax, will swap them." << std::endl; fYmin = ymax; fYmax = ymin; } else { fYmin = ymin; fYmax = ymax; } fYRangePresent = true; } ClassImpQ(PMusrCanvas) //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor */ PMusrCanvas::PMusrCanvas() { fTimeout = 0; fTimeoutTimer = nullptr; fScaleN0AndBkg = true; fValid = false; fAveragedView = false; fDifferenceView = false; fToggleColor = false; fCurrentPlotView = PV_DATA; fPreviousPlotView = PV_DATA; fPlotType = -1; fPlotNumber = -1; fImp = nullptr; fBar = nullptr; fPopupMain = nullptr; fPopupFourier = nullptr; fStyle = nullptr; fMainCanvas = nullptr; fTitlePad = nullptr; fDataTheoryPad = nullptr; fParameterPad = nullptr; fTheoryPad = nullptr; fInfoPad = nullptr; fMultiGraphLegend = nullptr; fHistoFrame = nullptr; fMultiGraphData = nullptr; fMultiGraphDiff = nullptr; InitFourier(); InitAverage(); fCurrentFourierPhaseText = nullptr; fRRFText = nullptr; fRRFLatexText = nullptr; fXRangePresent = false; fYRangePresent = false; fXmin = 0.0; fXmax = 0.0; fYmin = 0.0; fYmax = 0.0; gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor. * * \param number The plot number of the msr-file PLOT block * \param title Title to be displayed * \param wtopx top x coordinate (in pixels) to place the canvas. * \param wtopy top y coordinate (in pixels) to place the canvas. * \param ww width (in pixels) of the canvas. * \param wh height (in pixels) of the canvas. * \param batch flag: if set true, the canvas will not be displayed. This is used when just dumping of a * graphical output file is wished. * \param fourier flag: if set true, the canvas will present the Fourier view. * \param avg flag: if set true, the canvas will present the averages data/Fourier view. */ PMusrCanvas::PMusrCanvas(const Int_t number, const Char_t* title, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh, const Bool_t batch, const Bool_t fourier, const Bool_t avg, const Bool_t theoAsData) : fTheoAsData(theoAsData), fStartWithFourier(fourier), fStartWithAvg(avg), fBatchMode(batch), fPlotNumber(number) { fTimeout = 0; fTimeoutTimer = nullptr; fAveragedView = false; fMultiGraphData = nullptr; fMultiGraphDiff = nullptr; fHistoFrame = nullptr; InitFourier(); InitAverage(); CreateStyle(); InitMusrCanvas(title, wtopx, wtopy, ww, wh); fCurrentFourierPhaseText = nullptr; fRRFText = nullptr; fRRFLatexText = nullptr; fXRangePresent = false; fYRangePresent = false; fXmin = 0.0; fXmax = 0.0; fYmin = 0.0; fYmax = 0.0; gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor. * * \param number The plot number of the msr-file PLOT block * \param title Title to be displayed * \param wtopx top x coordinate (in pixels) to place the canvas. * \param wtopy top y coordinate (in pixels) to place the canvas. * \param ww width (in pixels) of the canvas. * \param wh height (in pixels) of the canvas. * \param fourierDefault structure holding the pre-defined settings for a Fourier transform * \param markerList pre-defined list of markers * \param colorList pre-defined list of colors * \param batch flag: if set true, the canvas will not be displayed. This is used when just dumping of a * graphical output file is wished. * \param fourier flag: if set true, the canvas will present the Fourier view. * \param avg flag: if set true, the canvas will present the averages data/Fourier view. */ PMusrCanvas::PMusrCanvas(const Int_t number, const Char_t* title, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh, PMsrFourierStructure fourierDefault, const PIntVector markerList, const PIntVector colorList, const Bool_t batch, const Bool_t fourier, const Bool_t avg, const Bool_t theoAsData) : fTheoAsData(theoAsData), fStartWithFourier(fourier), fStartWithAvg(avg), fBatchMode(batch), fPlotNumber(number), fFourier(fourierDefault), fMarkerList(markerList), fColorList(colorList) { fTimeout = 0; fTimeoutTimer = nullptr; fMultiGraphData = nullptr; fMultiGraphDiff = nullptr; fHistoFrame = nullptr; InitAverage(); CreateStyle(); InitMusrCanvas(title, wtopx, wtopy, ww, wh); fCurrentFourierPhaseText = nullptr; fRRFText = nullptr; fRRFLatexText = nullptr; fXRangePresent = false; fYRangePresent = false; fXmin = 0.0; fXmax = 0.0; fYmin = 0.0; fYmax = 0.0; gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling } //-------------------------------------------------------------------------- // Destructor //-------------------------------------------------------------------------- /** *

Destructor. */ PMusrCanvas::~PMusrCanvas() { // cleanup if (fTimeoutTimer) { delete fTimeoutTimer; fTimeoutTimer = nullptr; } if (fCurrentFourierPhaseText) { delete fCurrentFourierPhaseText; fCurrentFourierPhaseText = nullptr; } if (fRRFLatexText) { delete fRRFLatexText; fRRFLatexText = nullptr; } if (fRRFText) { delete fRRFText; fRRFText = nullptr; } if (fStyle) { delete fStyle; fStyle = nullptr; } if (fTitlePad) { fTitlePad->Clear(); delete fTitlePad; fTitlePad = nullptr; } if (fData.size() > 0) { for (UInt_t i=0; i 0) { for (UInt_t i=0; iClear(); delete fMultiGraphLegend; fMultiGraphLegend = nullptr; } if (fMultiGraphData) { delete fMultiGraphData; fMultiGraphData = nullptr; } if (fMultiGraphDiff) { delete fMultiGraphDiff; fMultiGraphDiff = nullptr; } if (fDataTheoryPad) { delete fDataTheoryPad; fDataTheoryPad = nullptr; } if (fParameterPad) { fParameterPad->Clear(); delete fParameterPad; fParameterPad = nullptr; } if (fTheoryPad) { fTheoryPad->Clear(); delete fTheoryPad; fTheoryPad = nullptr; } if (fInfoPad) { fInfoPad->Clear(); delete fInfoPad; fInfoPad = nullptr; } if (fMainCanvas) { delete fMainCanvas; fMainCanvas = nullptr; } } //-------------------------------------------------------------------------- // SetMsrHandler (public) //-------------------------------------------------------------------------- /** *

Keep the msr-handler object pointer and fill the Fourier structure if present. * * \param msrHandler pointer of the msr-file handler. */ void PMusrCanvas::SetMsrHandler(PMsrHandler *msrHandler) { fMsrHandler = msrHandler; fScaleN0AndBkg = IsScaleN0AndBkg(); // check if a fourier block is present in the msr-file, and if yes extract the given values if (fMsrHandler->GetMsrFourierList()->fFourierBlockPresent) { fFourier.fFourierBlockPresent = true; if (fMsrHandler->GetMsrFourierList()->fUnits != FOURIER_UNIT_NOT_GIVEN) { fFourier.fUnits = fMsrHandler->GetMsrFourierList()->fUnits; } if (fMsrHandler->GetMsrFourierList()->fFourierPower != -1) { fFourier.fFourierPower = fMsrHandler->GetMsrFourierList()->fFourierPower; } fFourier.fDCCorrected = fMsrHandler->GetMsrFourierList()->fDCCorrected; if (fMsrHandler->GetMsrFourierList()->fApodization != FOURIER_APOD_NOT_GIVEN) { fFourier.fApodization = fMsrHandler->GetMsrFourierList()->fApodization; } if (fMsrHandler->GetMsrFourierList()->fPlotTag != FOURIER_PLOT_NOT_GIVEN) { fFourier.fPlotTag = fMsrHandler->GetMsrFourierList()->fPlotTag; } fFourier.fPhase = fMsrHandler->GetMsrFourierList()->fPhase; if ((fMsrHandler->GetMsrFourierList()->fRangeForPhaseCorrection[0] != -1.0) && (fMsrHandler->GetMsrFourierList()->fRangeForPhaseCorrection[1] != -1.0)) { fFourier.fRangeForPhaseCorrection[0] = fMsrHandler->GetMsrFourierList()->fRangeForPhaseCorrection[0]; fFourier.fRangeForPhaseCorrection[1] = fMsrHandler->GetMsrFourierList()->fRangeForPhaseCorrection[1]; } if ((fMsrHandler->GetMsrFourierList()->fPlotRange[0] != -1.0) && (fMsrHandler->GetMsrFourierList()->fPlotRange[1] != -1.0)) { fFourier.fPlotRange[0] = fMsrHandler->GetMsrFourierList()->fPlotRange[0]; fFourier.fPlotRange[1] = fMsrHandler->GetMsrFourierList()->fPlotRange[1]; } } // check if RRF data are present if (((fMsrHandler->GetMsrPlotList()->at(0).fRRFPacking > 0) && (fMsrHandler->GetMsrPlotList()->at(0).fRRFFreq != 0.0)) || (fMsrHandler->GetMsrGlobal()->GetRRFPacking() > 0 && fMsrHandler->GetMsrGlobal()->GetRRFUnit().CompareTo("??"))) { fRRFLatexText = new TLatex(); fRRFLatexText->SetNDC(kTRUE); fRRFLatexText->SetTextFont(62); fRRFLatexText->SetTextSize(0.03); Int_t rrfUnitTag = -1; Double_t rrfFreq = 0.0; if (fMsrHandler->GetMsrPlotList()->at(0).fRRFPacking > 0) { // RRF single histo PLOT fRRFText = new TString("RRF: "); rrfUnitTag = fMsrHandler->GetMsrPlotList()->at(0).fRRFUnit; rrfFreq = fMsrHandler->GetMsrPlotList()->at(0).fRRFFreq; TString rrfFreqStr(""); rrfFreqStr.Form("%.5g", rrfFreq); if (rrfUnitTag == RRF_UNIT_kHz) { *fRRFText += TString("#nu_{RRF} = "); *fRRFText += rrfFreq; *fRRFText += TString(" (kHz)"); } else if (rrfUnitTag == RRF_UNIT_MHz) { *fRRFText += TString("#nu_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (MHz)"); } else if (rrfUnitTag == RRF_UNIT_Mcs) { *fRRFText += TString("#omega_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (Mc/s)"); } else if (rrfUnitTag == RRF_UNIT_G) { *fRRFText += TString("B_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (G)"); } else if (rrfUnitTag == RRF_UNIT_T) { *fRRFText += TString("B_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (T)"); } *fRRFText += TString(", RRF packing = "); *fRRFText += fMsrHandler->GetMsrPlotList()->at(0).fRRFPacking; } else { // RRF single histo FIT fRRFText = new TString("RRF: "); rrfUnitTag = fMsrHandler->GetMsrGlobal()->GetRRFUnitTag(); rrfFreq = fMsrHandler->GetMsrGlobal()->GetRRFFreq(fMsrHandler->GetMsrGlobal()->GetRRFUnit().Data()); TString rrfFreqStr(""); rrfFreqStr.Form("%.5g", rrfFreq); if (rrfUnitTag == RRF_UNIT_kHz) { *fRRFText += TString("#nu_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (kHz)"); } else if (rrfUnitTag == RRF_UNIT_MHz) { *fRRFText += TString("#nu_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (MHz)"); } else if (rrfUnitTag == RRF_UNIT_Mcs) { *fRRFText += TString("#omega_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (Mc/s)"); } else if (rrfUnitTag == RRF_UNIT_G) { *fRRFText += TString("B_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (G)"); } else if (rrfUnitTag == RRF_UNIT_T) { *fRRFText += TString("B_{RRF} = "); *fRRFText += rrfFreqStr; *fRRFText += TString(" (T)"); } *fRRFText += TString(", RRF packing = "); *fRRFText += fMsrHandler->GetMsrGlobal()->GetRRFPacking(); } } } //-------------------------------------------------------------------------- // SetTimeout (public) //-------------------------------------------------------------------------- /** *

* * \param timeout after which the done signal shall be emitted. Given in seconds */ void PMusrCanvas::SetTimeout(Int_t timeout) { fTimeout = timeout; if (fTimeout <= 0) return; if (fTimeoutTimer) { delete fTimeoutTimer; fTimeoutTimer = nullptr; } fTimeoutTimer = new TTimer(); fTimeoutTimer->Connect("Timeout()", "PMusrCanvas", this, "Done()"); fTimeoutTimer->Start(1000*fTimeout, kTRUE); } //-------------------------------------------------------------------------- // UpdateParamTheoryPad (public) //-------------------------------------------------------------------------- /** *

Feeds the pad with the fit parameter informations, and refreshes the pad. */ void PMusrCanvas::UpdateParamTheoryPad() { if (!fValid) return; TString str; Char_t cnum[128]; Int_t maxLength = 0; Double_t ypos = 0.0, yoffset = 0.0; Int_t idx = -1; // add parameters ------------------------------------------------------------ PMsrParamList param = *fMsrHandler->GetMsrParamList(); // get maximal parameter name string length for (UInt_t i=0; i maxLength) maxLength = param[i].fName.Length(); } maxLength += 2; // calculate yoffset based on the number of parameters if (param.size() > 20) yoffset = 1.0 / (param.size()+1); else yoffset = 0.05; // add parameters to the pad UInt_t accuracy = 6; Char_t accStr[32]; for (UInt_t i=0; iAddText(0.03, ypos, str.Data()); } // add theory ------------------------------------------------------------ PMsrLines theory = *fMsrHandler->GetMsrTheory(); if (theory.size() > 20) yoffset = 1.0/(theory.size()+1); else yoffset = 0.05; for (UInt_t i=1; i 0) { // comment present str.Resize(idx-1); str.Resize(str.Strip().Length()); } ypos = 0.98 - i*yoffset; fTheoryPad->AddText(0.03, ypos, str.Data()); } // add functions -------------------------------------------------------- ypos -= 0.05; PMsrLines functions = *fMsrHandler->GetMsrFunctions(); for (UInt_t i=1; iAddText(0.03, ypos, functions[i].fLine.Data()); } fParameterPad->Draw(); fTheoryPad->Draw(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // UpdateDataTheoryPad (public) //-------------------------------------------------------------------------- /** *

Feeds the pad with data/theory histograms (error graphs) and refreshes it. */ void PMusrCanvas::UpdateDataTheoryPad() { // some checks first UInt_t runNo; PMsrPlotStructure plotInfo = fMsrHandler->GetMsrPlotList()->at(fPlotNumber); PMsrRunList runs = *fMsrHandler->GetMsrRunList(); PMsrGlobalBlock *globalBlock = fMsrHandler->GetMsrGlobal(); Int_t fitType = globalBlock->GetFitType(); fPlotType = plotInfo.fPlotType; for (UInt_t i=0; i (Int_t)runs.size()) { fValid = false; std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** run plot number " << (Int_t)plotInfo.fRuns[i] << " is larger than the number of runs " << runs.size(); std::cerr << std::endl; return; } // check that the plottype and the fittype do correspond runNo = (UInt_t)plotInfo.fRuns[i]-1; if (runs[runNo].GetFitType() != -1) { // fit type found in RUN block, hence overwrite the GLOBAL block fitType = runs[runNo].GetFitType(); } if (fitType == -1) { fValid = false; std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** plottype = " << fPlotType; std::cerr << ", fittype = " << runs[runNo].GetFitType() << "(RUN block)/"; std::cerr << "fittype = " << globalBlock->GetFitType() << "(GLOBAL block). However, they have to correspond!"; std::cerr << std::endl; return; } } PRunData *data; for (UInt_t i=0; iGetSingleHisto(runNo, PRunListCollection::kRunNo); if (!data) { // something wrong fValid = false; // error message std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a single histogram plot"; std::cerr << std::endl; return; } // handle data HandleDataSet(i, runNo, data); break; case MSR_FITTYPE_SINGLE_HISTO_RRF: data = fRunList->GetSingleHistoRRF(runNo, PRunListCollection::kRunNo); if (!data) { // something wrong fValid = false; // error message std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a single histogram RRF plot"; std::cerr << std::endl; return; } // handle data HandleDataSet(i, runNo, data); break; case MSR_FITTYPE_ASYM: data = fRunList->GetAsymmetry(runNo, PRunListCollection::kRunNo); if (!data) { // something wrong fValid = false; // error message std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a asymmetry plot"; std::cerr << std::endl; return; } // handle data HandleDataSet(i, runNo, data); break; case MSR_FITTYPE_BNMR: data = fRunList->GetAsymmetryBNMR(runNo, PRunListCollection::kRunNo); if (!data) { // something wrong fValid = false; // error message std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a beta-NMR asymmetry plot"; std::cerr << std::endl; return; } // handle data HandleDataSet(i, runNo, data); break; case MSR_FITTYPE_ASYM_RRF: data = fRunList->GetAsymmetryRRF(runNo, PRunListCollection::kRunNo); if (!data) { // something wrong fValid = false; // error message std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a asymmetry RRF plot"; std::cerr << std::endl; return; } // handle data HandleDataSet(i, runNo, data); break; case MSR_FITTYPE_MU_MINUS: data = fRunList->GetMuMinus(runNo, PRunListCollection::kRunNo); if (!data) { // something wrong fValid = false; // error message std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a mu minus single histogram plot"; std::cerr << std::endl; return; } // handle data HandleDataSet(i, runNo, data); break; case MSR_FITTYPE_NON_MUSR: data = fRunList->GetNonMusr(runNo, PRunListCollection::kRunNo); if (!data) { // something wrong fValid = false; // error message std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** couldn't obtain run no " << runNo << " for a none musr data plot"; std::cerr << std::endl; return; } // handle data HandleNonMusrDataSet(i, runNo, data); if (!fBatchMode) { // disable Fourier menus fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_IMAG); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL_AND_IMAG); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PWR); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); } break; default: fValid = false; // error message std::cerr << std::endl << ">> PMusrCanvas::UpdateDataTheoryPad(): **ERROR** wrong plottype tag?!"; std::cerr << std::endl; return; break; } } // generate the histo plot if (!fStartWithFourier || (fPlotType == MSR_PLOT_NON_MUSR)) { PlotData(); } else { // show Fourier straight ahead. // set the menu properly if (!fBatchMode) fPopupMain->UnCheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); // filter proper Fourier plot tag, and set the menu tags properly switch (fFourier.fPlotTag) { case FOURIER_PLOT_REAL: fCurrentPlotView = PV_FOURIER_REAL; if (!fBatchMode) { fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); } break; case FOURIER_PLOT_IMAG: fCurrentPlotView = PV_FOURIER_IMAG; if (!fBatchMode) { fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_IMAG); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); } break; case FOURIER_PLOT_REAL_AND_IMAG: fCurrentPlotView = PV_FOURIER_REAL_AND_IMAG; if (!fBatchMode) { fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL_AND_IMAG); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); } break; case FOURIER_PLOT_POWER: fCurrentPlotView = PV_FOURIER_PWR; if (!fBatchMode) { fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PWR); } break; case FOURIER_PLOT_PHASE: fCurrentPlotView = PV_FOURIER_PHASE; if (!fBatchMode) { fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE); } break; case FOURIER_PLOT_PHASE_OPT_REAL: fCurrentPlotView = PV_FOURIER_PHASE_OPT_REAL; if (!fBatchMode) { fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_OPT_REAL); } break; default: fCurrentPlotView = PV_FOURIER_PWR; if (!fBatchMode) { fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PWR); } break; } HandleFourier(); PlotFourier(); } // if fStartWithAvg=true, start with averaged data/Fourier representation // fStartWithAvg is given at the command line level if (fStartWithAvg) { HandleCmdKey(kKeyPress, (Int_t)'a', 0, 0); } } //-------------------------------------------------------------------------- // UpdateInfoPad (public) //-------------------------------------------------------------------------- /** *

Feeds the pad with the statistics block information and the legend and refreshes it. */ void PMusrCanvas::UpdateInfoPad() { if (!fValid) return; PMsrStatisticStructure statistic = *fMsrHandler->GetMsrStatistic(); TString tstr, tsubstr; tstr = "musrfit: "; // get fit date tstr += statistic.fDate; tstr += TString(", "); // get chisq if not a max likelihood fit if (statistic.fChisq) { // chisq tstr += TString("chisq = "); } else { // max. likelihood tstr += TString("maxLH = "); } tstr += statistic.fMin; tstr += TString(" , NDF = "); tstr += statistic.fNdf; if (statistic.fChisq) { // chisq tstr += TString(" , chisq/NDF = "); } else { // max. likelihood tstr += TString(" , maxLH/NDF = "); } if (statistic.fNdf != 0) { tstr += statistic.fMin/statistic.fNdf; } else { tstr += TString("undefined"); } fInfoPad->SetHeader(tstr); // get/set run plot info double dval; const PDoublePairVector *ddvec; Char_t sval[128]; UInt_t runNo; PMsrPlotStructure plotInfo = fMsrHandler->GetMsrPlotList()->at(fPlotNumber); PMsrRunList runs = *fMsrHandler->GetMsrRunList(); for (UInt_t i=0; i 1) tstr = "++" + *runs[runNo].GetRunName() + TString(","); // run_name else tstr = *runs[runNo].GetRunName() + TString(","); // run_name // histo info (depending on the fittype if ((runs[runNo].GetFitType() == MSR_FITTYPE_SINGLE_HISTO) || (runs[runNo].GetFitType() == MSR_FITTYPE_SINGLE_HISTO_RRF)) { tstr += TString("h:"); TString grouping; fMsrHandler->GetGroupingString(runNo, "forward", grouping); tstr += grouping; tstr += TString(","); } else if ((runs[runNo].GetFitType() == MSR_FITTYPE_ASYM) || (runs[runNo].GetFitType() == MSR_FITTYPE_ASYM_RRF) || (runs[runNo].GetFitType() == MSR_FITTYPE_BNMR)) { tstr += TString("h:"); TString grouping; fMsrHandler->GetGroupingString(runNo, "forward", grouping); tstr += grouping; tstr += TString("/"); grouping = ""; fMsrHandler->GetGroupingString(runNo, "backward", grouping); tstr += grouping; tstr += TString(","); } // temperature if present ddvec = fRunList->GetTemp(*runs[runNo].GetRunName()); if (ddvec->empty()) { tstr += TString("T="); tstr += TString("??,"); } else if (ddvec->size() == 1){ tstr += TString("T="); sprintf(sval, "%0.2lf", ddvec->at(0).first); tstr += TString(sval) + TString("K,"); } else { for(UInt_t i(0); isize(); ++i){ sprintf(sval, "T%u=", i); tstr += TString(sval); sprintf(sval, "%0.2lf", ddvec->at(i).first); tstr += TString(sval) + TString("K,"); } } // field if present tstr += TString("B="); dval = fRunList->GetField(*runs[runNo].GetRunName()); if (dval == PMUSR_UNDEFINED) { tstr += TString("??,"); } else { if (dval < 1.0e4) { // Gauss makes sense as a unit sprintf(sval, "%0.2lf", dval); tstr += TString(sval) + TString("G,"); } else { // Tesla makes sense as a unit sprintf(sval, "%0.2lf", dval/1.0e4); tstr += TString(sval) + TString("T,"); } } // energy if present tstr += TString("E="); dval = fRunList->GetEnergy(*runs[runNo].GetRunName()); if (dval == PMUSR_UNDEFINED) { tstr += TString("??,"); } else { if (dval < 1.0e3) { // keV makes sense as a unit sprintf(sval, "%0.2lf", dval); tstr += TString(sval) + TString("keV,"); } else { // MeV makes sense as a unit sprintf(sval, "%0.2lf", dval/1.0e3); tstr += TString(sval) + TString("MeV,"); } } // setup if present tstr += fRunList->GetSetup(*runs[runNo].GetRunName()); // add entry fInfoPad->AddEntry(fData[i].data, tstr.Data(), "p"); } fInfoPad->Draw(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // Done (SIGNAL) //-------------------------------------------------------------------------- /** *

Signal emitted that the user wants to terminate the application. * * \param status Status info */ void PMusrCanvas::Done(Int_t status) { Emit("Done(Int_t)", status); } //-------------------------------------------------------------------------- // HandleCmdKey (SLOT) //-------------------------------------------------------------------------- /** *

Filters keyboard events, and if they are a command key (see below) carries out the * necessary actions. *

Currently implemented command keys: * - 'q' quit musrview * - 'd' toggle between difference view and data view * - 'u' unzoom to the original plot range given in the msr-file. * - 'f' Fourier transform data. Twice 'f' will switch back to the time domain view. * - '+' increment the phase (real/imaginary Fourier). The phase step is defined in the musrfit_startup.xml * - '-' decrement the phase (real/imaginary Fourier). The phase step is defined in the musrfit_startup.xml * * \param event event type * \param x character key * \param y not used * \param selected not used */ void PMusrCanvas::HandleCmdKey(Int_t event, Int_t x, Int_t y, TObject *selected) { if (event != kKeyPress) return; if (fBatchMode) { if (fStartWithAvg) { // this is needed to get the averaging in the batch mode HandleAverage(); PlotAverage(true); } return; } // handle keys and popup menu entries enum eKeySwitch {kNotRelevant, kData, kDiffData, kFourier, kDiffFourier, kFourierDiff}; eKeySwitch relevantKeySwitch = kNotRelevant; static eKeySwitch lastKeySwitch = kNotRelevant; if ((lastKeySwitch == kFourierDiff) && (x == 'f')) { std::cout << "**INFO** f-d-f doesn't make any sense, will ignore 'f' ..." << std::endl; return; } if ((lastKeySwitch == kDiffFourier) && (x == 'd')) { std::cout << "**INFO** d-f-d doesn't make any sense, will ignore 'd' ..." << std::endl; return; } if (x == 'q') { // quit Done(0); } else if (x == 'd') { // difference // update previous plot view fPreviousPlotView = fCurrentPlotView; // toggle difference tag fDifferenceView = !fDifferenceView; // set the popup menu entry properly if (fDifferenceView) { fPopupMain->CheckEntry(P_MENU_ID_DIFFERENCE+P_MENU_PLOT_OFFSET*fPlotNumber); } else { fPopupMain->UnCheckEntry(P_MENU_ID_DIFFERENCE+P_MENU_PLOT_OFFSET*fPlotNumber); } // check which relevantKeySwitch is needed if ((fCurrentPlotView == PV_DATA) && fDifferenceView) relevantKeySwitch = kDiffData; else if ((fCurrentPlotView == PV_DATA) && !fDifferenceView) relevantKeySwitch = kData; else if ((fCurrentPlotView != PV_DATA) && fDifferenceView) relevantKeySwitch = kFourierDiff; else if ((fCurrentPlotView != PV_DATA) && !fDifferenceView) relevantKeySwitch = kFourier; } else if (x == 'u') { // unzoom to the original range // update previous plot view fPreviousPlotView = fCurrentPlotView; if ((fCurrentPlotView == PV_DATA) && !fDifferenceView) { CleanupDifference(); CleanupFourier(); PlotData(true); } else if ((fCurrentPlotView == PV_DATA) && fDifferenceView) { CleanupFourierDifference(); HandleDifference(); PlotDifference(true); } else if ((fCurrentPlotView != PV_DATA) && !fDifferenceView) { HandleFourier(); PlotFourier(true); } else if ((fCurrentPlotView != PV_DATA) && fDifferenceView) { HandleDifferenceFourier(); PlotFourierDifference(true); } } else if (x == 'f') { // Fourier // check which relevantKeySwitch is needed if ((fCurrentPlotView == PV_DATA) && fDifferenceView) relevantKeySwitch = kDiffFourier; else if ((fCurrentPlotView == PV_DATA) && !fDifferenceView) relevantKeySwitch = kFourier; else if ((fCurrentPlotView != PV_DATA) && fDifferenceView) relevantKeySwitch = kDiffData; else if ((fCurrentPlotView != PV_DATA) && !fDifferenceView) relevantKeySwitch = kData; if (fCurrentPlotView == PV_DATA) { // current view is data view // uncheck data popup entry fPopupMain->UnCheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); // get default fourier tag and update fourier popup menu switch (fFourier.fPlotTag) { case FOURIER_PLOT_REAL: fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_REAL; fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL); break; case FOURIER_PLOT_IMAG: fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_IMAG; fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_IMAG); break; case FOURIER_PLOT_REAL_AND_IMAG: fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_REAL_AND_IMAG; fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL_AND_IMAG); break; case FOURIER_PLOT_POWER: fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_PWR; fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PWR); break; case FOURIER_PLOT_PHASE: fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_PHASE; fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE); break; case FOURIER_PLOT_PHASE_OPT_REAL: fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_PHASE_OPT_REAL; fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_OPT_REAL); break; default: break; } } else { // current view is one of the Fourier views // set the current plot view to data fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_DATA; // uncheck all fourier popup menu items fPopupFourier->UnCheckEntries(); // check the data entry fPopupMain->CheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); } } else if (x == '+') { if (fCurrentPlotView != PV_DATA) IncrementFourierPhase(); } else if (x == '-') { if (fCurrentPlotView != PV_DATA) DecrementFourierPhase(); } else if (x == 'a') { if (fData.size() > 1) { // toggle average view flag fAveragedView = !fAveragedView; // update menu if (fAveragedView) { fPopupMain->CheckEntry(P_MENU_ID_AVERAGE+P_MENU_PLOT_OFFSET*fPlotNumber); HandleAverage(); PlotAverage(true); } else { fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE+P_MENU_PLOT_OFFSET*fPlotNumber); CleanupAverage(); } // check which relevantKeySwitch is needed if ((fCurrentPlotView == PV_DATA) && fDifferenceView && !fAveragedView) relevantKeySwitch = kDiffData; else if ((fCurrentPlotView == PV_DATA) && !fDifferenceView && !fAveragedView) relevantKeySwitch = kData; else if ((fCurrentPlotView != PV_DATA) && fDifferenceView && !fAveragedView) relevantKeySwitch = kFourierDiff; else if ((fCurrentPlotView != PV_DATA) && !fDifferenceView && !fAveragedView) relevantKeySwitch = kFourier; } else { // with only 1 data set, it doesn't make any sense to average! std::cout << "**INFO** averaging of a single data set doesn't make any sense, will ignore 'a' ..." << std::endl; return; } } else if (x == 'c') { Int_t state = fDataTheoryPad->GetCrosshair(); if (state == 0) { fMainCanvas->ToggleEventStatus(); fDataTheoryPad->SetCrosshair(2); } else { fMainCanvas->ToggleEventStatus(); fDataTheoryPad->SetCrosshair(0); } fMainCanvas->Update(); } else if (x == 't') { // toggle theory color if (fData.size() == 1) { // only do something if there is a single data set fToggleColor = !fToggleColor; if (fToggleColor) { fData[0].theory->SetLineColor(kRed); fData[0].theory->SetLineWidth(2); } else { fData[0].theory->SetLineColor(fColorList[0]); fData[0].theory->SetLineWidth(1); } fDataTheoryPad->Modified(); fMainCanvas->Update(); } } else { fMainCanvas->Update(); } lastKeySwitch = relevantKeySwitch; // call the apropriate functions if necessary switch (relevantKeySwitch) { case kData: // show data CleanupDifference(); CleanupFourier(); PlotData(); break; case kDiffData: // show difference between data and theory CleanupFourierDifference(); HandleDifference(); PlotDifference(); break; case kFourier: // show Fourier transfrom of the data HandleFourier(); PlotFourier(); break; case kDiffFourier: // show Fourier transform of the difference data HandleDifferenceFourier(); PlotFourierDifference(); break; case kFourierDiff: // show difference between the Fourier data and the Fourier theory CleanupFourierDifference(); HandleFourierDifference(); PlotFourierDifference(); break; default: break; } // check if phase increment/decrement needs to be ghost if (fCurrentPlotView == PV_DATA) { fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); } else { fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); } } //-------------------------------------------------------------------------- // HandleMenuPopup (SLOT) //-------------------------------------------------------------------------- /** *

Handles the Musrfit menu. * * \param id identification key of the selected menu */ void PMusrCanvas::HandleMenuPopup(Int_t id) { if (fBatchMode) return; static Int_t previousPlotView = PV_DATA; if (id == P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber) { // set appropriate plot view fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_DATA; // check data item fPopupMain->CheckEntry(id); // uncheck fourier popup items fPopupFourier->UnCheckEntries(); // call data handling routine if (!fDifferenceView) { CleanupDifference(); CleanupFourier(); PlotData(); } else { HandleDifference(); PlotDifference(); } } else if (id == P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL) { // set appropriate plot view fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_REAL; // uncheck data fPopupMain->UnCheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); // check appropriate fourier popup item fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(id); // enable phase increment/decrement fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); // handle fourier real if (!fDifferenceView) { HandleFourier(); PlotFourier(); } else { if (previousPlotView == PV_DATA) HandleDifferenceFourier(); else HandleFourierDifference(); PlotFourierDifference(); } } else if (id == P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_IMAG) { // set appropriate plot view fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_IMAG; // uncheck data fPopupMain->UnCheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); // check appropriate fourier popup item fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(id); // enable phase increment/decrement fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); // handle fourier imag if (!fDifferenceView) { HandleFourier(); PlotFourier(); } else { if (previousPlotView == PV_DATA) HandleDifferenceFourier(); else HandleFourierDifference(); PlotFourierDifference(); } } else if (id == P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL_AND_IMAG) { // set appropriate plot view fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_REAL_AND_IMAG; // uncheck data fPopupMain->UnCheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); // check appropriate fourier popup item fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(id); // enable phase increment/decrement fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); // handle fourier real and imag if (!fDifferenceView) { HandleFourier(); PlotFourier(); } else { if (previousPlotView == PV_DATA) HandleDifferenceFourier(); else HandleFourierDifference(); PlotFourierDifference(); } } else if (id == P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PWR) { // set appropriate plot view fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_PWR; // uncheck data fPopupMain->UnCheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); // check appropriate fourier popup item fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(id); // enable phase increment/decrement fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); // handle fourier power if (!fDifferenceView) { HandleFourier(); PlotFourier(); } else { if (previousPlotView == PV_DATA) HandleDifferenceFourier(); else HandleFourierDifference(); PlotFourierDifference(); } } else if (id == P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE) { // set appropriate plot view fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_PHASE; // uncheck data fPopupMain->UnCheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); // check appropriate fourier popup item fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(id); // enable phase increment/decrement fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); // handle fourier phase if (!fDifferenceView) { HandleFourier(); PlotFourier(); } else { if (previousPlotView == PV_DATA) HandleDifferenceFourier(); else HandleFourierDifference(); PlotFourierDifference(); } } else if (id == P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_OPT_REAL) { // set appropriate plot view fPreviousPlotView = fCurrentPlotView; fCurrentPlotView = PV_FOURIER_PHASE_OPT_REAL; // make sure that phase opt. real indeed exists if (fData[0].dataFourierPhaseOptReal == nullptr) { if (fData[0].dataFourierRe == nullptr) HandleFourier(); else CalcPhaseOptReFT(); } // uncheck data fPopupMain->UnCheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); // check appropriate fourier popup item fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(id); // enable phase increment/decrement fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); // handle fourier phase if (!fDifferenceView) { HandleFourier(); PlotFourier(); } else { if (previousPlotView == PV_DATA) HandleDifferenceFourier(); else HandleFourierDifference(); PlotFourierDifference(); } } else if (id == P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS) { IncrementFourierPhase(); } else if (id == P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS) { DecrementFourierPhase(); } else if (id == P_MENU_ID_DIFFERENCE+P_MENU_PLOT_OFFSET*fPlotNumber) { // toggle difference tag fDifferenceView = !fDifferenceView; // set the popup menu entry properly if (fDifferenceView) { fPopupMain->CheckEntry(id); } else { fPopupMain->UnCheckEntry(id); } // handle data, diff, Fourier if (fDifferenceView) { switch (fCurrentPlotView) { case PV_DATA: CleanupFourierDifference(); HandleDifference(); PlotDifference(); break; case PV_FOURIER_REAL: case PV_FOURIER_IMAG: case PV_FOURIER_REAL_AND_IMAG: case PV_FOURIER_PWR: case PV_FOURIER_PHASE: if (fPopupMain->IsEntryChecked(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber)) { CleanupFourierDifference(); HandleDifferenceFourier(); PlotFourierDifference(); } else { CleanupFourierDifference(); HandleFourierDifference(); PlotFourierDifference(); } break; default: break; } } else { // not a difference view switch (fCurrentPlotView) { case PV_DATA: CleanupDifference(); CleanupFourier(); PlotData(); break; case PV_FOURIER_REAL: case PV_FOURIER_IMAG: case PV_FOURIER_REAL_AND_IMAG: case PV_FOURIER_PWR: case PV_FOURIER_PHASE: HandleFourier(); PlotFourier(); break; default: break; } } } else if (id == P_MENU_ID_AVERAGE+P_MENU_PLOT_OFFSET*fPlotNumber) { if (fData.size() > 1) { fAveragedView = !fAveragedView; // set the popup menu entry properly if (fAveragedView) { fPopupMain->CheckEntry(id); HandleAverage(); PlotAverage(); } else { fPopupMain->UnCheckEntry(id); CleanupAverage(); } } else { std::cout << "**INFO** averaging of a single data set doesn't make any sense, will ignore 'a' ..." << std::endl; return; } } else if (id == P_MENU_ID_EXPORT_DATA+P_MENU_PLOT_OFFSET*fPlotNumber) { static TString dir("."); TGFileInfo fi; fi.fFileTypes = gFiletypes; fi.fIniDir = StrDup(dir); fi.fOverwrite = true; new TGFileDialog(0, fImp, kFDSave, &fi); if (fi.fFilename && strlen(fi.fFilename)) { ExportData(fi.fFilename); } } // check if phase increment/decrement needs to be ghost if (fCurrentPlotView == PV_DATA) { fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); } else { fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->EnableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); } // keep plot view setting previousPlotView = fCurrentPlotView; } //-------------------------------------------------------------------------- // LastCanvasClosed (SLOT) //-------------------------------------------------------------------------- /** *

Slot called when the last canvas has been closed. Will emit Done(0) which will * terminate the application. */ void PMusrCanvas::LastCanvasClosed() { // std::cerr << ">> in last canvas closed check. gROOT->GetListOfCanvases()->GetEntries()=" << gROOT->GetListOfCanvases()->GetEntries() << std::endl; if (gROOT->GetListOfCanvases()->IsEmpty()) { Done(0); } } //-------------------------------------------------------------------------- // WindowClosed (SLOT) //-------------------------------------------------------------------------- /** *

Slot called when the canvas is closed. Seems to be necessary on some systems. */ void PMusrCanvas::WindowClosed() { // std::cerr << ">> fMainCanvas->GetName()=" << fMainCanvas->GetName() << std::endl; gROOT->GetListOfCanvases()->Remove(fMainCanvas); LastCanvasClosed(); } //-------------------------------------------------------------------------- // SaveGraphicsAndQuit //-------------------------------------------------------------------------- /** *

Will save the canvas as graphics output. Needed in the batch mode of musrview. * * \param fileName file name under which the canvas shall be saved. * \param graphicsFormat One of the supported graphics formats. */ void PMusrCanvas::SaveGraphicsAndQuit(Char_t *fileName, Char_t *graphicsFormat) { std::cout << std::endl << ">> SaveGraphicsAndQuit: will dump the canvas into a graphics output file (" << graphicsFormat << ") ..."<< std::endl; TString str(fileName); Int_t idx = -1; Int_t size = 0; Char_t ext[32]; if (str.Contains(".msr")) { idx = str.Index(".msr"); size = 4; } if (str.Contains(".mlog")) { idx = str.Index(".mlog"); size = 5; } if (idx == -1) { std::cerr << std::endl << ">> PMusrCanvas::SaveGraphicsAndQuit(): **ERROR** fileName (" << fileName << ") is invalid." << std::endl; return; } if (fStartWithFourier) sprintf(ext, "_%d_F", fPlotNumber); else sprintf(ext, "_%d", fPlotNumber); str.Replace(idx, size, ext, strlen(ext)); idx += strlen(ext); size = strlen(ext); sprintf(ext, ".%s", graphicsFormat); str.Replace(idx, size, ext, strlen(ext)); std::cout << std::endl << ">> SaveGraphicsAndQuit: " << str.Data() << std::endl; fMainCanvas->SaveAs(str.Data()); if (fPlotNumber == static_cast(fMsrHandler->GetMsrPlotList()->size()) - 1) Done(0); } //-------------------------------------------------------------------------- // ExportData //-------------------------------------------------------------------------- /** *

Saves the currently seen data (data, difference, Fourier spectra, ...) in ascii column format. * * \param fileName file name to be used to save the data. */ void PMusrCanvas::ExportData(const Char_t *fileName) { if (fileName == nullptr) { // path file name NOT provided, generate a default path file name std::cerr << std::endl << ">> PMusrCanvas::ExportData(): **ERROR** NO path file name provided. Will do nothing." << std::endl; return; } // collect relevant data PMusrCanvasAsciiDump dump; PMusrCanvasAsciiDumpVector dumpVector; Int_t xminBin; Int_t xmaxBin; Double_t xmin; Double_t xmax; Double_t xval, yval; switch (fPlotType) { case MSR_PLOT_SINGLE_HISTO: case MSR_PLOT_SINGLE_HISTO_RRF: case MSR_PLOT_ASYM: case MSR_PLOT_BNMR: case MSR_PLOT_ASYM_RRF: case MSR_PLOT_MU_MINUS: if (fDifferenceView) { // difference view plot switch (fCurrentPlotView) { case PV_DATA: // get current x-range xminBin = fHistoFrame->GetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fHistoFrame->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fHistoFrame->GetXaxis()->GetBinCenter(xminBin); xmax = fHistoFrame->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.diff, xmin, xmax, dumpVector); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].diffFourierRe->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].diffFourierRe->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].diffFourierRe->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.diffFourierRe, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].diffFourierIm->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].diffFourierIm->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].diffFourierIm->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.diffFourierIm, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].diffFourierRe->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].diffFourierRe->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].diffFourierRe->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.diffFourierRe, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.diffFourierIm, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].diffFourierPwr->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].diffFourierPwr->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].diffFourierPwr->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.diffFourierPwr, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].diffFourierPhase->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].diffFourierPhase->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].diffFourierPhase->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.diffFourierPhase, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fHistoFrame->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fHistoFrame->GetXaxis()->GetBinCenter(xminBin); xmax = fHistoFrame->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.data, xmin, xmax, dumpVector); GetExportDataSet(fDataAvg.theory, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].dataFourierRe->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].dataFourierRe->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].dataFourierRe->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.dataFourierRe, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.theoryFourierRe, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].dataFourierIm->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].dataFourierIm->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].dataFourierIm->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.dataFourierIm, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.theoryFourierIm, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].dataFourierRe->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].dataFourierRe->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].dataFourierRe->GetXaxis()->GetBinCenter(xmaxBin); if (fAveragedView) { GetExportDataSet(fDataAvg.dataFourierRe, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.theoryFourierRe, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.dataFourierIm, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.theoryFourierIm, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].dataFourierPwr->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].dataFourierPwr->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].dataFourierPwr->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.dataFourierPwr, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.theoryFourierPwr, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].dataFourierPhase->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].dataFourierPhase->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].dataFourierPhase->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.dataFourierPhase, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.theoryFourierPhase, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fData[0].dataFourierPhaseOptReal->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fData[0].dataFourierPhaseOptReal->GetXaxis()->GetBinCenter(xminBin); xmax = fData[0].dataFourierPhaseOptReal->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data if (fAveragedView) { GetExportDataSet(fDataAvg.dataFourierPhaseOptReal, xmin, xmax, dumpVector, false); GetExportDataSet(fDataAvg.theoryFourierPhaseOptReal, xmin, xmax, dumpVector, false); } else { // go through all the histogramms for (UInt_t i=0; iGetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fMultiGraphData->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fMultiGraphData->GetXaxis()->GetBinCenter(xminBin); xmax = fMultiGraphData->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data for (UInt_t i=0; iGetN(); j++) { // get x and y value fNonMusrData[i].diff->GetPoint(j,xval,yval); // check if time is in the current range if ((xval >= xmin) && (xval <= xmax)) { dump.dataX.push_back(xval); dump.data.push_back(yval); dump.dataErr.push_back(fNonMusrData[i].diff->GetErrorY(j)); } } // if anything found keep it if (dump.dataX.size() > 0) dumpVector.push_back(dump); } break; case PV_FOURIER_REAL: break; case PV_FOURIER_IMAG: break; case PV_FOURIER_REAL_AND_IMAG: break; case PV_FOURIER_PWR: break; case PV_FOURIER_PHASE: break; default: break; } } else { // not a difference view plot switch (fCurrentPlotView) { case PV_DATA: // get current x-range xminBin = fMultiGraphData->GetXaxis()->GetFirst(); // first bin of the zoomed range xmaxBin = fMultiGraphData->GetXaxis()->GetLast(); // last bin of the zoomed range xmin = fMultiGraphData->GetXaxis()->GetBinCenter(xminBin); xmax = fMultiGraphData->GetXaxis()->GetBinCenter(xmaxBin); // fill ascii dump data for (UInt_t i=0; iGetN(); j++) { // get x and y value fNonMusrData[i].data->GetPoint(j,xval,yval); // check if time is in the current range if ((xval >= xmin) && (xval <= xmax)) { dump.dataX.push_back(xval); dump.data.push_back(yval); dump.dataErr.push_back(fNonMusrData[i].data->GetErrorY(j)); } } // if anything found keep it if (dump.dataX.size() > 0) dumpVector.push_back(dump); // clean up dump dump.dataX.clear(); dump.data.clear(); dump.dataErr.clear(); // go through all theory bins for (Int_t j=0; jGetN(); j++) { // get x and y value fNonMusrData[i].theory->GetPoint(j,xval,yval); // check if time is in the current range if ((xval >= xmin) && (xval <= xmax)) { dump.dataX.push_back(xval); dump.data.push_back(yval); } } // if anything found keep it if (dump.dataX.size() > 0) dumpVector.push_back(dump); } break; case PV_FOURIER_REAL: break; case PV_FOURIER_IMAG: break; case PV_FOURIER_REAL_AND_IMAG: break; case PV_FOURIER_PWR: break; case PV_FOURIER_PHASE: break; default: break; } } break; default: break; } // open file std::ofstream fout; // open output data-file fout.open(fileName, std::iostream::out); if (!fout.is_open()) { std::cerr << std::endl << ">> PMusrCanvas::ExportData(): **ERROR** couldn't open file " << fileName << " for writing." << std::endl; return; } // find out what is the longest data/theory vector UInt_t maxLength = 0; for (UInt_t i=0; i 0) fout << dumpVector[j].dataErr[i] << ", "; } else { if (dumpVector[j].dataErr.size() > 0) fout << ", , , "; else fout << ", , "; } } // write last difference entry if (i 0) fout << dumpVector[dumpVector.size()-1].dataErr[i]; } else { if (dumpVector[dumpVector.size()-1].dataErr.size() > 0) fout << ", , "; else fout << ", "; } fout << std::endl; } } else { // no difference view // write header switch (fCurrentPlotView) { case PV_DATA: if (fAveragedView) { fout << "% from averaged view" << std::endl; fout << "% xData, data, errData, xTheory, theory" << std::endl; } else { fout << "% "; for (UInt_t i=0; i 0) fout << std::setprecision(9) << dumpVector[j].dataErr[i] << ", "; } else { if (dumpVector[j].dataErr.size() > 0) fout << " , , , "; else fout << " , , "; } } // write last data/theory entry if (i> Data windows saved in ascii format ..." << std::endl; // if (asciiOutput) { // if (fPlotNumber == static_cast(fMsrHandler->GetMsrPlotList()->size()) - 1) // Done(0); // } } //-------------------------------------------------------------------------- // GetExportDataSet (private) //-------------------------------------------------------------------------- /** *

extract data for export. * * \param data * \param xmin * \param xmax * \param dumpData * \param hasError */ void PMusrCanvas::GetExportDataSet(const TH1F *data, const Double_t xmin, const Double_t xmax, PMusrCanvasAsciiDumpVector &dumpData, const Bool_t hasError) { PMusrCanvasAsciiDump dump; Double_t x=0.0; // go through all difference data bins for (Int_t j=1; jGetNbinsX(); j++) { // get time/freq x = data->GetBinCenter(j); // check if x is in the current range if ((x >= xmin) && (x <= xmax)) { dump.dataX.push_back(x); dump.data.push_back(data->GetBinContent(j)); if (hasError) dump.dataErr.push_back(data->GetBinError(j)); } } // if anything found keep it if (dump.dataX.size() > 0) dumpData.push_back(dump); } //-------------------------------------------------------------------------- // CreateStyle (private) //-------------------------------------------------------------------------- /** *

Set styles for the canvas. Perhaps one could transfer them to the startup-file in the future. */ void PMusrCanvas::CreateStyle() { TString musrStyle("musrStyle"); musrStyle += fPlotNumber; fStyle = new TStyle(musrStyle, musrStyle); fStyle->SetOptStat(0); // no statistics options fStyle->SetOptTitle(0); // no title fStyle->cd(); } //-------------------------------------------------------------------------- // InitFourier (private) //-------------------------------------------------------------------------- /** *

Initializes the Fourier structure. */ void PMusrCanvas::InitFourier() { fFourier.fFourierBlockPresent = false; // fourier block present fFourier.fUnits = FOURIER_UNIT_GAUSS; // fourier untis fFourier.fFourierPower = 0; // no zero padding fFourier.fApodization = FOURIER_APOD_NONE; // no apodization fFourier.fPlotTag = FOURIER_PLOT_REAL_AND_IMAG; // initial plot tag, plot real and imaginary part fFourier.fPhaseParamNo.clear(); fFourier.fPhase.clear(); for (UInt_t i=0; i<2; i++) { fFourier.fRangeForPhaseCorrection[i] = -1.0; // frequency range for phase correction, default: {-1, -1} = NOT GIVEN fFourier.fPlotRange[i] = -1.0; // fourier plot range, default: {-1, -1} = NOT GIVEN } fFourier.fPhaseIncrement = 1.0; // fourier phase increment } //-------------------------------------------------------------------------- // InitAverage (private) //-------------------------------------------------------------------------- /** *

Initializes the Average structure. */ void PMusrCanvas::InitAverage() { fDataAvg.data = nullptr; fDataAvg.dataFourierRe = nullptr; fDataAvg.dataFourierIm = nullptr; fDataAvg.dataFourierPwr = nullptr; fDataAvg.dataFourierPhase = nullptr; fDataAvg.dataFourierPhaseOptReal = nullptr; fDataAvg.theory = nullptr; fDataAvg.theoryFourierRe = nullptr; fDataAvg.theoryFourierIm = nullptr; fDataAvg.theoryFourierPwr = nullptr; fDataAvg.theoryFourierPhase = nullptr; fDataAvg.theoryFourierPhaseOptReal = nullptr; fDataAvg.diff = nullptr; fDataAvg.diffFourierRe = nullptr; fDataAvg.diffFourierIm = nullptr; fDataAvg.diffFourierPwr = nullptr; fDataAvg.diffFourierPhase = nullptr; fDataAvg.diffFourierPhaseOptReal = nullptr; fDataAvg.dataRange = nullptr; fDataAvg.diffFourierTag = 0; } //-------------------------------------------------------------------------- // InitMusrCanvas (private) //-------------------------------------------------------------------------- /** *

Initialize the class, and sets up the necessary objects. * * \param title Title to be displayed * \param wtopx top x coordinate (in pixels) to place the canvas. * \param wtopy top y coordinate (in pixels) to place the canvas. * \param ww width (in pixels) of the canvas. * \param wh height (in pixels) of the canvas. */ void PMusrCanvas::InitMusrCanvas(const Char_t* title, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh) { fScaleN0AndBkg = true; fValid = false; fAveragedView = false; fDifferenceView = false; fToggleColor = false; fCurrentPlotView = PV_DATA; fPreviousPlotView = PV_DATA; fPlotType = -1; fImp = nullptr; fBar = nullptr; fPopupMain = nullptr; fPopupFourier = nullptr; fMainCanvas = nullptr; fTitlePad = nullptr; fDataTheoryPad = nullptr; fParameterPad = nullptr; fTheoryPad = nullptr; fInfoPad = nullptr; fMultiGraphLegend = nullptr; // invoke canvas TString canvasName = TString("fMainCanvas"); canvasName += fPlotNumber; fMainCanvas = new TCanvas(canvasName.Data(), title, wtopx, wtopy, ww, wh); if (fMainCanvas == nullptr) { std::cerr << std::endl << ">> PMusrCanvas::PMusrCanvas(): **PANIC ERROR** Couldn't invoke " << canvasName.Data(); std::cerr << std::endl; return; } fMainCanvas->Connect("Closed()", "PMusrCanvas", this, "LastCanvasClosed()"); // add canvas menu if not in batch mode if (!fBatchMode) { fImp = (TRootCanvas*)fMainCanvas->GetCanvasImp(); fImp->Connect("CloseWindow()", "PMusrCanvas", this, "WindowClosed()"); fBar = fImp->GetMenuBar(); fPopupMain = fBar->AddPopup("&Musrfit"); fPopupFourier = new TGPopupMenu(); fPopupMain->AddEntry("&Data", P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); fPopupMain->AddSeparator(); fPopupMain->AddPopup("&Fourier", fPopupFourier); fPopupFourier->AddEntry("Show Real", P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL); fPopupFourier->AddEntry("Show Imag", P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_IMAG); fPopupFourier->AddEntry("Show Real+Imag", P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_REAL_AND_IMAG); fPopupFourier->AddEntry("Show Power", P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PWR); fPopupFourier->AddEntry("Show Phase", P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE); fPopupFourier->AddEntry("Show PhaseOptReal", P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_OPT_REAL); fPopupFourier->AddSeparator(); fPopupFourier->AddEntry("Phase +", P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->AddEntry("Phase -", P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_PLOT_OFFSET*fPlotNumber+P_MENU_ID_FOURIER_PHASE_MINUS); fPopupMain->AddEntry("D&ifference", P_MENU_ID_DIFFERENCE+P_MENU_PLOT_OFFSET*fPlotNumber); fPopupMain->AddSeparator(); fPopupMain->AddEntry("Average", P_MENU_ID_AVERAGE+P_MENU_PLOT_OFFSET*fPlotNumber); fPopupMain->AddSeparator(); fPopupMain->AddEntry("Export Data", P_MENU_ID_EXPORT_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); fBar->MapSubwindows(); fBar->Layout(); fPopupMain->Connect("TGPopupMenu", "Activated(Int_t)", "PMusrCanvas", this, "HandleMenuPopup(Int_t)"); fPopupMain->CheckEntry(P_MENU_ID_DATA+P_MENU_PLOT_OFFSET*fPlotNumber); } // divide the canvas into 4 pads // title pad fTitlePad = new TPaveText(0.0, YTITLE, 1.0, 1.0, "NDC"); if (fTitlePad == nullptr) { std::cerr << std::endl << ">> PMusrCanvas::PMusrCanvas(): **PANIC ERROR** Couldn't invoke fTitlePad"; std::cerr << std::endl; return; } fTitlePad->SetFillColor(TColor::GetColor(255,255,255)); fTitlePad->SetTextAlign(12); // middle, left fTitlePad->AddText(title); fTitlePad->Draw(); // data/theory pad fDataTheoryPad = new TPad("dataTheoryPad", "dataTheoryPad", 0.0, YINFO, XTHEO, YTITLE); if (fDataTheoryPad == nullptr) { std::cerr << std::endl << ">> PMusrCanvas::PMusrCanvas(): **PANIC ERROR** Couldn't invoke fDataTheoryPad"; std::cerr << std::endl; return; } fDataTheoryPad->SetFillColor(TColor::GetColor(255,255,255)); fDataTheoryPad->Draw(); // parameter pad fParameterPad = new TPaveText(XTHEO, 0.5, 1.0, YTITLE, "NDC"); if (fParameterPad == nullptr) { std::cerr << std::endl << ">> PMusrCanvas::PMusrCanvas(): **PANIC ERROR** Couldn't invoke fParameterPad"; std::cerr << std::endl; return; } fParameterPad->SetFillColor(TColor::GetColor(255,255,255)); fParameterPad->SetTextAlign(13); // top, left fParameterPad->SetTextFont(102); // courier bold, scalable so that greek parameters will be plotted properly // theory pad fTheoryPad = new TPaveText(XTHEO, 0.1, 1.0, 0.5, "NDC"); if (fTheoryPad == nullptr) { std::cerr << std::endl << ">> PMusrCanvas::PMusrCanvas(): **PANIC ERROR** Couldn't invoke fTheoryPad"; std::cerr << std::endl; return; } fTheoryPad->SetFillColor(TColor::GetColor(255,255,255)); fTheoryPad->SetTextAlign(13); // top, left fTheoryPad->SetTextFont(102); // courier bold, scalable so that greek parameters will be plotted properly // info pad fInfoPad = new TLegend(0.0, 0.0, 1.0, YINFO, "NDC"); if (fInfoPad == nullptr) { std::cerr << std::endl << ">> PMusrCanvas::PMusrCanvas(): **PANIC ERROR** Couldn't invoke fInfoPad"; std::cerr << std::endl; return; } fInfoPad->SetFillColor(TColor::GetColor(255,255,255)); fInfoPad->SetTextAlign(12); // middle, left fValid = true; fMainCanvas->cd(); fMainCanvas->Show(); fMainCanvas->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", "PMusrCanvas", this, "HandleCmdKey(Int_t,Int_t,Int_t,TObject*)"); } //-------------------------------------------------------------------------- // InitDataSet (private) //-------------------------------------------------------------------------- /** *

Initializes the data set (histogram representation). * * \param dataSet data set to be initialized */ void PMusrCanvas::InitDataSet(PMusrCanvasDataSet &dataSet) { dataSet.data = nullptr; dataSet.dataFourierRe = nullptr; dataSet.dataFourierIm = nullptr; dataSet.dataFourierPwr = nullptr; dataSet.dataFourierPhase = nullptr; dataSet.dataFourierPhaseOptReal = nullptr; dataSet.theory = nullptr; dataSet.theoryFourierRe = nullptr; dataSet.theoryFourierIm = nullptr; dataSet.theoryFourierPwr = nullptr; dataSet.theoryFourierPhase = nullptr; dataSet.theoryFourierPhaseOptReal = nullptr; dataSet.diff = nullptr; dataSet.diffFourierRe = nullptr; dataSet.diffFourierIm = nullptr; dataSet.diffFourierPwr = nullptr; dataSet.diffFourierPhase = nullptr; dataSet.diffFourierPhaseOptReal = nullptr; dataSet.dataRange = nullptr; } //-------------------------------------------------------------------------- // InitDataSet (private) //-------------------------------------------------------------------------- /** *

Initializes the data set (error graph representation). * * \param dataSet data set to be initialized */ void PMusrCanvas::InitDataSet(PMusrCanvasNonMusrDataSet &dataSet) { dataSet.data = nullptr; dataSet.dataFourierRe = nullptr; dataSet.dataFourierIm = nullptr; dataSet.dataFourierPwr = nullptr; dataSet.dataFourierPhase = nullptr; dataSet.theory = nullptr; dataSet.theoryFourierRe = nullptr; dataSet.theoryFourierIm = nullptr; dataSet.theoryFourierPwr = nullptr; dataSet.theoryFourierPhase = nullptr; dataSet.diff = nullptr; dataSet.diffFourierRe = nullptr; dataSet.diffFourierIm = nullptr; dataSet.diffFourierPwr = nullptr; dataSet.diffFourierPhase = nullptr; dataSet.dataRange = nullptr; } //-------------------------------------------------------------------------- // CleanupDataSet (private) //-------------------------------------------------------------------------- /** *

Cleans up a data set (histogram representation). * * \param dataSet data set to be cleaned up. */ void PMusrCanvas::CleanupDataSet(PMusrCanvasDataSet &dataSet) { if (dataSet.data) { delete dataSet.data; dataSet.data = nullptr; } if (dataSet.dataFourierRe) { delete dataSet.dataFourierRe; dataSet.dataFourierRe = nullptr; } if (dataSet.dataFourierIm) { delete dataSet.dataFourierIm; dataSet.dataFourierIm = nullptr; } if (dataSet.dataFourierPwr) { delete dataSet.dataFourierPwr; dataSet.dataFourierPwr = nullptr; } if (dataSet.dataFourierPhase) { delete dataSet.dataFourierPhase; dataSet.dataFourierPhase = nullptr; } if (dataSet.dataFourierPhaseOptReal) { delete dataSet.dataFourierPhaseOptReal; dataSet.dataFourierPhaseOptReal = nullptr; } if (dataSet.theory) { delete dataSet.theory; dataSet.theory = nullptr; } if (dataSet.theoryFourierRe) { delete dataSet.theoryFourierRe; dataSet.theoryFourierRe = nullptr; } if (dataSet.theoryFourierIm) { delete dataSet.theoryFourierIm; dataSet.theoryFourierIm = nullptr; } if (dataSet.theoryFourierPwr) { delete dataSet.theoryFourierPwr; dataSet.theoryFourierPwr = nullptr; } if (dataSet.theoryFourierPhase) { delete dataSet.theoryFourierPhase; dataSet.theoryFourierPhase = nullptr; } if (dataSet.theoryFourierPhaseOptReal) { delete dataSet.theoryFourierPhaseOptReal; dataSet.theoryFourierPhaseOptReal = nullptr; } if (dataSet.diff) { delete dataSet.diff; dataSet.diff = nullptr; } if (dataSet.diffFourierRe) { delete dataSet.diffFourierRe; dataSet.diffFourierRe = nullptr; } if (dataSet.diffFourierIm) { delete dataSet.diffFourierIm; dataSet.diffFourierIm = nullptr; } if (dataSet.diffFourierPwr) { delete dataSet.diffFourierPwr; dataSet.diffFourierPwr = nullptr; } if (dataSet.diffFourierPhase) { delete dataSet.diffFourierPhase; dataSet.diffFourierPhase = nullptr; } if (dataSet.diffFourierPhaseOptReal) { delete dataSet.diffFourierPhaseOptReal; dataSet.diffFourierPhaseOptReal = nullptr; } if (dataSet.dataRange) { delete dataSet.dataRange; dataSet.dataRange = nullptr; } } //-------------------------------------------------------------------------- // CleanupDataSet (private) //-------------------------------------------------------------------------- /** *

Cleans up a data set (error graph representation). * * \param dataSet data set to be cleaned up. */ void PMusrCanvas::CleanupDataSet(PMusrCanvasNonMusrDataSet &dataSet) { if (dataSet.data) { delete dataSet.data; dataSet.data = nullptr; } if (dataSet.dataFourierRe) { delete dataSet.dataFourierRe; dataSet.dataFourierRe = nullptr; } if (dataSet.dataFourierIm) { delete dataSet.dataFourierIm; dataSet.dataFourierIm = nullptr; } if (dataSet.dataFourierPwr) { delete dataSet.dataFourierPwr; dataSet.dataFourierPwr = nullptr; } if (dataSet.dataFourierPhase) { delete dataSet.dataFourierPhase; dataSet.dataFourierPhase = nullptr; } if (dataSet.theory) { delete dataSet.theory; dataSet.theory = nullptr; } if (dataSet.theoryFourierRe) { delete dataSet.theoryFourierRe; dataSet.theoryFourierRe = nullptr; } if (dataSet.theoryFourierIm) { delete dataSet.theoryFourierIm; dataSet.theoryFourierIm = nullptr; } if (dataSet.theoryFourierPwr) { delete dataSet.theoryFourierPwr; dataSet.theoryFourierPwr = nullptr; } if (dataSet.theoryFourierPhase) { delete dataSet.theoryFourierPhase; dataSet.theoryFourierPhase = nullptr; } if (dataSet.diff) { delete dataSet.diff; dataSet.diff = nullptr; } if (dataSet.diffFourierRe) { delete dataSet.diffFourierRe; dataSet.diffFourierRe = nullptr; } if (dataSet.diffFourierIm) { delete dataSet.diffFourierIm; dataSet.diffFourierIm = nullptr; } if (dataSet.diffFourierPwr) { delete dataSet.diffFourierPwr; dataSet.diffFourierPwr = nullptr; } if (dataSet.diffFourierPhase) { delete dataSet.diffFourierPhase; dataSet.diffFourierPhase = nullptr; } if (dataSet.dataRange) { delete dataSet.dataRange; dataSet.dataRange = nullptr; } } //-------------------------------------------------------------------------- // HandleDataSet (private) //-------------------------------------------------------------------------- /** *

Generates the necessary histograms for plotting, starting from the pre-processed data. * * \param plotNo The number of the histo within the run list (fPlotNumber is the number of the plot BLOCK) * \param runNo The number of the run * \param data pre-processed data */ void PMusrCanvas::HandleDataSet(UInt_t plotNo, UInt_t runNo, PRunData *data) { PMusrCanvasDataSet dataSet; TH1F *dataHisto; TH1F *theoHisto; TString name; Double_t start; Double_t end; Double_t xmin, xmax, ymin, ymax; Int_t size; InitDataSet(dataSet); // create plot range object for the data set dataSet.dataRange = new PMusrCanvasPlotRange(); // dataHisto ------------------------------------------------------------- // create histo specific infos name = *fMsrHandler->GetMsrRunList()->at(runNo).GetRunName() + "_DataRunNo"; name += static_cast(runNo); name += "_"; name += fPlotNumber; start = data->GetDataTimeStart() - data->GetDataTimeStep()/2.0; end = start + data->GetValue()->size()*data->GetDataTimeStep(); size = data->GetValue()->size(); dataSet.dataRange->SetXRange(start, end); // full possible range // make sure that for asymmetry the y-range is initialized reasonably if ((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_ASYM) || (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_BNMR)) dataSet.dataRange->SetYRange(-0.4, 0.4); // extract necessary range information if ((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() == 0) && !fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) { // no range information at all if (fXRangePresent) { if (fXmin > start) fXmin = start; if (fXmax < end) fXmax = end; } else { fXRangePresent = true; fXmin = start; fXmax = end; } if ((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_ASYM) || (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_BNMR) || (fMsrHandler->GetMsrRunList()->at(runNo).IsLifetimeCorrected())) { fYRangePresent = true; fYmin = -0.4; fYmax = 0.4; } } // check if plot range is given in the msr-file, and if yes keep the values if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() == 1) { // keep x-range xmin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[0]; xmax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[0]; dataSet.dataRange->SetXRange(xmin, xmax); // keep range information fXRangePresent = true; fXmin = xmin; fXmax = xmax; // check if y-range is given as well if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) { ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0]; ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0]; dataSet.dataRange->SetYRange(ymin, ymax); // keep range information fYRangePresent = true; fYmin = ymin; fYmax = ymax; } } // check if 'use_fit_ranges' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) { start = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0); // needed to estimate size if (start == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry start = fMsrHandler->GetMsrGlobal()->GetFitRange(0); } end = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1); // needed to estimate size if (end == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry end = fMsrHandler->GetMsrGlobal()->GetFitRange(1); } size = (Int_t) ((end - start) / data->GetDataTimeStep()) + 1; start = data->GetDataTimeStart() + (Int_t)((start - data->GetDataTimeStart())/data->GetDataTimeStep()) * data->GetDataTimeStep() - data->GetDataTimeStep()/2.0; // closesd start value compatible with the user given end = start + size * data->GetDataTimeStep(); // closesd end value compatible with the user given dataSet.dataRange->SetXRange(start, end); // make sure that for asymmetry the y-range is initialized reasonably if ((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_ASYM) || (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fPlotType == MSR_PLOT_BNMR) || (fMsrHandler->GetMsrRunList()->at(runNo).IsLifetimeCorrected())) { dataSet.dataRange->SetYRange(-0.4, 0.4); } // keep range information if (fXRangePresent) { if (fXmin > start) fXmin = start; if (fXmax < end) fXmax = end; } else { fXRangePresent = true; fXmin = start; fXmax = end; } // check if y-range is given as well if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) { ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0]; ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0]; dataSet.dataRange->SetYRange(ymin, ymax); // keep range information fYRangePresent = true; fYmin = ymin; fYmax = ymax; } } // check if 'sub_ranges' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) { start = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo]; // needed to estimate size end = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo]; // needed to estimate size size = (Int_t) ((end - start) / data->GetDataTimeStep()) + 1; start = data->GetDataTimeStart() + (Int_t)((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] - data->GetDataTimeStart())/data->GetDataTimeStep()) * data->GetDataTimeStep() - data->GetDataTimeStep()/2.0; // closesd start value compatible with the user given end = start + size * data->GetDataTimeStep(); // closesd end value compatible with the user given dataSet.dataRange->SetXRange(start, end); // keep range information if (fXRangePresent) { if (fXmin > start) fXmin = start; if (fXmax < end) fXmax = end; } else { fXRangePresent = true; fXmin = start; fXmax = end; } // check if y-range is given as well if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) { ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0]; ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0]; dataSet.dataRange->SetYRange(ymin, ymax); // keep range information fYRangePresent = true; fYmin = ymin; fYmax = ymax; } } // invoke histo dataHisto = new TH1F(name, name, size, start, end); // fill histogram // 1st calculate the bin-range according to the plot options UInt_t startBin = 0; UInt_t endBin = data->GetValue()->size(); // check if 'use_fit_range' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) { Double_t startFitRange = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0); if (startFitRange == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry startFitRange = fMsrHandler->GetMsrGlobal()->GetFitRange(0); } Double_t dval = (startFitRange - data->GetDataTimeStart())/data->GetDataTimeStep(); if (dval < 0.0) { // make sure that startBin >= 0 startBin = 0; std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin data < 0 for 'use_fit_range', will set it to 0" << std::endl << std::endl; } else if (dval >= (Double_t)data->GetValue()->size()) { // make sure that startBin <= length of data vector std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin data=" << (UInt_t)dval << " >= data vector size=" << data->GetValue()->size() << " for 'use_fit_range',"; std::cerr << std::endl << ">> will set it to data vector size" << std::endl << std::endl; startBin = data->GetValue()->size(); } else { startBin = (UInt_t)dval; } Double_t endFitRange = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1); if (endFitRange == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry endFitRange = fMsrHandler->GetMsrGlobal()->GetFitRange(1); } dval = (endFitRange - data->GetDataTimeStart())/data->GetDataTimeStep(); if (dval < 0.0) { // make sure that endBin >= 0 endBin = 0; std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin data < 0 for 'use_fit_range', will set it to 0" << std::endl << std::endl; } else if (dval >= (Double_t)data->GetValue()->size()) { // make sure that endBin <= length of data vector std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin data=" << (UInt_t)dval << " >= data vector size=" << data->GetValue()->size() << " for 'use_fit_range',"; std::cerr << std::endl << ">> will set it to data vector size" << std::endl << std::endl; endBin = data->GetValue()->size(); } else { endBin = (UInt_t)dval; } } // check if 'sub_ranges' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) { Double_t dval = (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] - data->GetDataTimeStart())/data->GetDataTimeStep(); if (dval < 0.0) { // make sure that startBin >= 0 startBin = 0; std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin data < 0 for 'sub_ranges', will set it to 0" << std::endl << std::endl; } else if (dval >= (Double_t)data->GetValue()->size()) { // make sure that startBin <= length of data vector std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin data=" << (UInt_t)dval << " >= data vector size=" << data->GetValue()->size() << " for 'sub_ranges',"; std::cerr << std::endl << ">> will set it to data vector size" << std::endl << std::endl; startBin = data->GetValue()->size(); } else { startBin = (UInt_t)dval; } dval = (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo] - data->GetDataTimeStart())/data->GetDataTimeStep(); if (dval < 0.0) { // make sure that endBin >= 0 endBin = 0; std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin data < 0 for 'sub_ranges', will set it to 0" << std::endl << std::endl; } else if (dval >= (Double_t)data->GetValue()->size()) { // make sure that endtBin <= length of data vector std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin data=" << (UInt_t)dval << " >= data vector size=" << data->GetValue()->size() << " for 'sub_ranges',"; std::cerr << std::endl << ">> will set it to data vector size" << std::endl << std::endl; endBin = data->GetValue()->size(); } else { endBin = (UInt_t)dval; } } for (UInt_t i=startBin; iSetBinContent(i-startBin+1, data->GetValue()->at(i)); dataHisto->SetBinError(i-startBin+1, data->GetError()->at(i)); } // set marker and line color if (plotNo < fColorList.size()) { dataHisto->SetMarkerColor(fColorList[plotNo]); dataHisto->SetLineColor(fColorList[plotNo]); } else { TRandom rand(plotNo); Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); dataHisto->SetMarkerColor(color); dataHisto->SetLineColor(color); } // set marker size dataHisto->SetMarkerSize(1); // set marker type if (plotNo < fMarkerList.size()) { dataHisto->SetMarkerStyle(fMarkerList[plotNo]); } else { TRandom rand(plotNo); dataHisto->SetMarkerStyle(20+(Int_t)rand.Integer(10)); } // theoHisto ------------------------------------------------------------- // create histo specific infos name = *fMsrHandler->GetMsrRunList()->at(runNo).GetRunName() + "_TheoRunNo"; name += (Int_t)runNo; name += "_"; name += fPlotNumber; start = data->GetTheoryTimeStart() - data->GetTheoryTimeStep()/2.0; end = start + data->GetTheory()->size()*data->GetTheoryTimeStep(); size = data->GetTheory()->size(); // check if 'use_fit_range' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) { start = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0); // needed to estimate size if (start == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry start = fMsrHandler->GetMsrGlobal()->GetFitRange(0); } end = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1); // needed to estimate size if (end == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry end = fMsrHandler->GetMsrGlobal()->GetFitRange(1); } size = (Int_t) ((end - start) / data->GetTheoryTimeStep()) + 1; start = data->GetTheoryTimeStart() + (Int_t)((start - data->GetTheoryTimeStart())/data->GetTheoryTimeStep()) * data->GetTheoryTimeStep() - data->GetTheoryTimeStep()/2.0; // closesd start value compatible with the user given end = start + size * data->GetTheoryTimeStep(); // closesd end value compatible with the user given } // check if 'sub_ranges' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) { start = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo]; // needed to estimate size end = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo]; // needed to estimate size size = (Int_t) ((end - start) / data->GetTheoryTimeStep()) + 1; start = data->GetTheoryTimeStart() + (Int_t)((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] - data->GetTheoryTimeStart())/data->GetTheoryTimeStep()) * data->GetTheoryTimeStep() - data->GetTheoryTimeStep()/2.0; // closesd start value compatible with the user given end = start + size * data->GetTheoryTimeStep(); // closesd end value compatible with the user given } // invoke histo theoHisto = new TH1F(name, name, size, start, end); // fill histogram startBin = 0; endBin = data->GetTheory()->size(); // check if 'use_fit_range' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) { Double_t startFitRange = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0); if (startFitRange == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry startFitRange = fMsrHandler->GetMsrGlobal()->GetFitRange(0); } Double_t dval = (startFitRange - data->GetDataTimeStart())/data->GetTheoryTimeStep(); if (dval < 0.0) { // make sure that startBin >= 0 startBin = 0; std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin theory < 0 for 'use_fit_range', will set it to 0" << std::endl << std::endl; } else if (dval >= (Double_t)data->GetTheory()->size()) { // make sure that startBin <= length of theory vector std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin theory=" << (UInt_t)dval << " >= theory vector size=" << data->GetTheory()->size() << " for 'use_fit_range',"; std::cerr << std::endl << ">> will set it to theory vector size" << std::endl << std::endl; startBin = data->GetTheory()->size(); } else { startBin = (UInt_t)dval; } Double_t endFitRange = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1); if (endFitRange == PMUSR_UNDEFINED) { // not given in the run block, try the global block entry endFitRange = fMsrHandler->GetMsrGlobal()->GetFitRange(1); } dval = (endFitRange - data->GetDataTimeStart())/data->GetTheoryTimeStep(); if (dval < 0.0) { // make sure that endBin >= 0 endBin = 0; std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin theory < 0 for 'use_fit_range', will set it to 0" << std::endl << std::endl; } else if (dval >= (Double_t)data->GetTheory()->size()) { // make sure that endBin <= length of theory vector std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin theory=" << (UInt_t)dval << " >= theory vector size=" << data->GetTheory()->size() << " for 'use_fit_range',"; std::cerr << std::endl << ">> will set it to theory vector size" << std::endl << std::endl; endBin = data->GetTheory()->size(); } else { endBin = (UInt_t)dval; } } // check if 'sub_ranges' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) { startBin = (UInt_t)((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] -data->GetDataTimeStart())/data->GetTheoryTimeStep()); endBin = (UInt_t)((fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo] -data->GetDataTimeStart())/data->GetTheoryTimeStep()); Double_t dval = (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo] -data->GetDataTimeStart())/data->GetTheoryTimeStep(); if (dval < 0.0) { // make sure that startBin >= 0 startBin = 0; std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin theory < 0 for 'sub_ranges', will set it to 0" << std::endl << std::endl; } else if (dval >= (Double_t)data->GetTheory()->size()) { // make sure that startBin <= length of theory vector std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found startBin theory=" << (UInt_t)dval << " >= theory vector size=" << data->GetTheory()->size() << " for 'sub_ranges',"; std::cerr << std::endl << ">> will set it to theory vector size" << std::endl << std::endl; startBin = data->GetTheory()->size(); } else { startBin = (UInt_t)dval; } dval = (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo] -data->GetDataTimeStart())/data->GetTheoryTimeStep(); if (dval < 0.0) { // make sure that endBin >= 0 endBin = 0; std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin theory < 0 for 'sub_ranges', will set it to 0" << std::endl << std::endl; } else if (dval >= (Double_t)data->GetTheory()->size()) { // make sure that endtBin <= length of theory vector std::cerr << std::endl << ">> PMusrCanvas::HandleDataSet(): **WARNING** found endBin theory=" << (UInt_t)dval << " >= theory vector size=" << data->GetTheory()->size() << " for 'sub_ranges',"; std::cerr << std::endl << ">> will set it to theory vector size" << std::endl << std::endl; endBin = data->GetTheory()->size(); } else { endBin = (UInt_t)dval; } } for (UInt_t i=startBin; iSetBinContent(i-startBin+1, data->GetTheory()->at(i)); } // set the line color if (plotNo < fColorList.size()) { theoHisto->SetLineColor(fColorList[plotNo]); } else { TRandom rand(plotNo); Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); theoHisto->SetLineColor(color); } // fill handler list ----------------------------------------------------- dataSet.data = dataHisto; dataSet.theory = theoHisto; dataSet.diffFourierTag = 0; // not relevant at this point fData.push_back(dataSet); } //-------------------------------------------------------------------------- // HandleNonMusrDataSet (private) //-------------------------------------------------------------------------- /** *

Generates the necessary error graphs for plotting, starting from the pre-processed data. * * \param plotNo The number of the histo within the run list (fPlotNumber is the number of the plot BLOCK) * \param runNo The number of the run * \param data pre-processed data */ void PMusrCanvas::HandleNonMusrDataSet(UInt_t plotNo, UInt_t runNo, PRunData *data) { PMusrCanvasNonMusrDataSet dataSet; TGraphErrors *dataHisto; TGraphErrors *theoHisto; InitDataSet(dataSet); // create plot range object for the data set and fill it dataSet.dataRange = new PMusrCanvasPlotRange(); // dataHisto ------------------------------------------------------------- // invoke graph dataHisto = new TGraphErrors(data->GetX()->size()); // fill graph for (UInt_t i=0; iGetX()->size(); i++) { dataHisto->SetPoint(i, data->GetX()->at(i), data->GetValue()->at(i)); dataHisto->SetPointError(i, 0.0, data->GetError()->at(i)); } // set marker and line color if (plotNo < fColorList.size()) { dataHisto->SetMarkerColor(fColorList[plotNo]); dataHisto->SetLineColor(fColorList[plotNo]); } else { TRandom rand(plotNo); Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); dataHisto->SetMarkerColor(color); dataHisto->SetLineColor(color); } // set marker size dataHisto->SetMarkerSize(1); // set marker type if (plotNo < fMarkerList.size()) { dataHisto->SetMarkerStyle(fMarkerList[plotNo]); } else { TRandom rand(plotNo); dataHisto->SetMarkerStyle(20+(Int_t)rand.Integer(10)); } // theoHisto ------------------------------------------------------------- // invoke graph theoHisto = new TGraphErrors(data->GetXTheory()->size()); // fill graph for (UInt_t i=0; iGetXTheory()->size(); i++) { theoHisto->SetPoint(i, data->GetXTheory()->at(i), data->GetTheory()->at(i)); theoHisto->SetPointError(i, 0.0, 0.0); } // set the line color if (plotNo < fColorList.size()) { theoHisto->SetLineColor(fColorList[plotNo]); } else { TRandom rand(plotNo); Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); theoHisto->SetLineColor(color); } // fill handler list ----------------------------------------------------- dataSet.data = dataHisto; dataSet.theory = theoHisto; dataSet.diffFourierTag = 0; // not relevant at this point // check the plot range options Double_t xmin=0.0, xmax=0.0, ymin=0.0, ymax=0.0, x=0.0, y=0.0; // if no plot-range entry is present, initialize the plot range to the maximal possible given the data if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() == 0) { dataSet.data->GetPoint(0, xmin, y); // get xmin dataSet.data->GetPoint(dataSet.data->GetN()-1, xmax, y); // get xmax dataSet.data->GetPoint(0, x, y); // init ymin/ymax ymin = y; ymax = y; for (Int_t i=1; iGetN(); i++) { dataSet.data->GetPoint(i, x, y); if (y < ymin) ymin = y; if (y > ymax) ymax = y; } Double_t dx = 0.025*(xmax-xmin); Double_t dy = 0.025*(ymax-ymin); dataSet.dataRange->SetXRange(xmin-dx, xmax+dx); dataSet.dataRange->SetYRange(ymin-dy, ymax+dy); } // check if plot range is given in the msr-file, and if yes keep the values if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() == 1) { // keep x-range xmin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[0]; xmax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[0]; dataSet.dataRange->SetXRange(xmin, xmax); // check if y-range is given as well if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) { ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0]; ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0]; dataSet.dataRange->SetYRange(ymin, ymax); } } // check if 'use_fit_range' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fUseFitRanges) { xmin = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(0); // needed to estimate size xmax = fMsrHandler->GetMsrRunList()->at(runNo).GetFitRange(1); // needed to estimate size dataSet.dataRange->SetXRange(xmin, xmax); // check if y-range is given as well if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) { ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0]; ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0]; dataSet.dataRange->SetYRange(ymin, ymax); } } // check if 'sub_ranges' plotting is whished if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin.size() > 1) { xmin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmin[runNo]; // needed to estimate size xmax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fTmax[runNo]; // needed to estimate size dataSet.dataRange->SetXRange(xmin, xmax); // check if y-range is given as well if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin.size() != 0) { ymin = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmin[0]; ymax = fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fYmax[0]; dataSet.dataRange->SetYRange(ymin, ymax); } } // keep maximal range of all plot present fXRangePresent = true; fYRangePresent = true; if (plotNo == 0) { fXmin = dataSet.dataRange->GetXmin(); fXmax = dataSet.dataRange->GetXmax(); fYmin = dataSet.dataRange->GetYmin(); fYmax = dataSet.dataRange->GetYmax(); } else { if (fXmin > dataSet.dataRange->GetXmin()) fXmin = dataSet.dataRange->GetXmin(); if (fXmax < dataSet.dataRange->GetXmax()) fXmax = dataSet.dataRange->GetXmax(); if (fYmin > dataSet.dataRange->GetYmin()) fYmin = dataSet.dataRange->GetYmin(); if (fYmax < dataSet.dataRange->GetYmax()) fYmax = dataSet.dataRange->GetYmax(); } fNonMusrData.push_back(dataSet); } //-------------------------------------------------------------------------- // HandleDifference (private) //-------------------------------------------------------------------------- /** *

Handles the calculation of the difference spectra (i.e. data-theory). * It allocates the necessary objects if they are not already present. At the * end it calls the plotting routine. */ void PMusrCanvas::HandleDifference() { // check if it is necessary to calculate diff data if ((fPlotType != MSR_PLOT_NON_MUSR) && (fData[0].diff == nullptr)) { TH1F *diffHisto; TString name; // loop over all histos for (UInt_t i=0; iGetTitle()) + "_diff"; diffHisto = new TH1F(name, name, fData[i].data->GetNbinsX(), fData[i].data->GetXaxis()->GetXmin(), fData[i].data->GetXaxis()->GetXmax()); // set marker and line color diffHisto->SetMarkerColor(fData[i].data->GetMarkerColor()); diffHisto->SetLineColor(fData[i].data->GetLineColor()); // set marker size diffHisto->SetMarkerSize(fData[i].data->GetMarkerSize()); // set marker type diffHisto->SetMarkerStyle(fData[i].data->GetMarkerStyle()); // keep difference histo fData[i].diff = diffHisto; // calculate diff histo entry double value; for (Int_t j=1; jGetNbinsX()-1; j++) { // set diff bin value value = CalculateDiff(fData[i].data->GetBinCenter(j), fData[i].data->GetBinContent(j), fData[i].theory); fData[i].diff->SetBinContent(j, value); // set error diff bin value value = fData[i].data->GetBinError(j); fData[i].diff->SetBinError(j, value); } } } else if ((fPlotType == MSR_PLOT_NON_MUSR) && (fNonMusrData[0].diff == nullptr)) { TGraphErrors *diffHisto; TString name; // loop over all histos for (UInt_t i=0; iGetN()); // create difference histos name = TString(fNonMusrData[i].data->GetTitle()) + "_diff"; diffHisto->SetNameTitle(name.Data(), name.Data()); // set marker and line color diffHisto->SetMarkerColor(fNonMusrData[i].data->GetMarkerColor()); diffHisto->SetLineColor(fNonMusrData[i].data->GetLineColor()); // set marker size diffHisto->SetMarkerSize(fNonMusrData[i].data->GetMarkerSize()); // set marker type diffHisto->SetMarkerStyle(fNonMusrData[i].data->GetMarkerStyle()); // keep difference histo fNonMusrData[i].diff = diffHisto; // calculate diff histo entry double value; double x, y; for (Int_t j=0; jGetN(); j++) { // set diff bin value fNonMusrData[i].data->GetPoint(j, x, y); value = CalculateDiff(x, y, fNonMusrData[i].theory); fNonMusrData[i].diff->SetPoint(j, x, value); // set error diff bin value value = fNonMusrData[i].data->GetErrorY(j); fNonMusrData[i].diff->SetPointError(j, 0.0, value); } } } } //-------------------------------------------------------------------------- // HandleFourier (private) //-------------------------------------------------------------------------- /** *

Handles the calculation of the Fourier transform. * It allocates the necessary objects if they are not already present. At the * end it calls the plotting routine. */ void PMusrCanvas::HandleFourier() { Double_t re, im; // check if plot type is appropriate for fourier if (fPlotType == MSR_PLOT_NON_MUSR) return; // check if fourier needs to be calculated if (fData[0].dataFourierRe == nullptr) { Int_t bin; double startTime = fXmin; double endTime = fXmax; if (!fStartWithFourier) { // fHistoFrame present, hence get start/end from it bin = fHistoFrame->GetXaxis()->GetFirst(); startTime = fHistoFrame->GetBinLowEdge(bin); bin = fHistoFrame->GetXaxis()->GetLast(); endTime = fHistoFrame->GetBinLowEdge(bin)+fHistoFrame->GetBinWidth(bin); } for (UInt_t i=0; i> PMusrCanvas::HandleFourier(): **SEVERE ERROR** couldn't invoke PFourier to calculate the Fourier data ..." << std::endl; return; } fourierData.Transform(fFourier.fApodization); double scale; scale = sqrt(fData[0].data->GetBinWidth(1)/(endTime-startTime)); // get real part of the data fData[i].dataFourierRe = fourierData.GetRealFourier(scale); // get imaginary part of the data fData[i].dataFourierIm = fourierData.GetImaginaryFourier(scale); // get power part of the data fData[i].dataFourierPwr = fourierData.GetPowerFourier(scale); // get phase part of the data fData[i].dataFourierPhase = fourierData.GetPhaseFourier(); // set marker and line color fData[i].dataFourierRe->SetMarkerColor(fData[i].data->GetMarkerColor()); fData[i].dataFourierRe->SetLineColor(fData[i].data->GetLineColor()); fData[i].dataFourierIm->SetMarkerColor(fData[i].data->GetMarkerColor()); fData[i].dataFourierIm->SetLineColor(fData[i].data->GetLineColor()); fData[i].dataFourierPwr->SetMarkerColor(fData[i].data->GetMarkerColor()); fData[i].dataFourierPwr->SetLineColor(fData[i].data->GetLineColor()); fData[i].dataFourierPhase->SetMarkerColor(fData[i].data->GetMarkerColor()); fData[i].dataFourierPhase->SetLineColor(fData[i].data->GetLineColor()); // set marker size fData[i].dataFourierRe->SetMarkerSize(1); fData[i].dataFourierIm->SetMarkerSize(1); fData[i].dataFourierPwr->SetMarkerSize(1); fData[i].dataFourierPhase->SetMarkerSize(1); // set marker type fData[i].dataFourierRe->SetMarkerStyle(fData[i].data->GetMarkerStyle()); fData[i].dataFourierIm->SetMarkerStyle(fData[i].data->GetMarkerStyle()); fData[i].dataFourierPwr->SetMarkerStyle(fData[i].data->GetMarkerStyle()); fData[i].dataFourierPhase->SetMarkerStyle(fData[i].data->GetMarkerStyle()); // calculate fourier transform of the theory PFourier *fourierTheory = nullptr; if (fTheoAsData) { // theory only at the data points fourierTheory = new PFourier(fData[i].theory, fFourier.fUnits, startTime, endTime, fFourier.fDCCorrected, fFourier.fFourierPower); } else { Int_t powerPad = fFourier.fFourierPower+5; // +5 means 8 times more points on theo (+3) + 4 times more points in fourier (+2) fourierTheory = new PFourier(fData[i].theory, fFourier.fUnits, startTime, endTime, fFourier.fDCCorrected, powerPad); } if (!fourierTheory->IsValid()) { std::cerr << std::endl << ">> PMusrCanvas::HandleFourier(): **SEVERE ERROR** couldn't invoke PFourier to calculate the Fourier theory ..." << std::endl; return; } fourierTheory->Transform(fFourier.fApodization); scale = sqrt(fData[0].theory->GetBinWidth(1)/(endTime-startTime)*fData[0].theory->GetBinWidth(1)/fData[0].data->GetBinWidth(1)); // get real part of the data fData[i].theoryFourierRe = fourierTheory->GetRealFourier(scale); // get imaginary part of the data fData[i].theoryFourierIm = fourierTheory->GetImaginaryFourier(scale); // get power part of the data fData[i].theoryFourierPwr = fourierTheory->GetPowerFourier(scale); // get phase part of the data fData[i].theoryFourierPhase = fourierTheory->GetPhaseFourier(); // clean up delete fourierTheory; // set line colors for the theory fData[i].theoryFourierRe->SetLineColor(fData[i].theory->GetLineColor()); fData[i].theoryFourierIm->SetLineColor(fData[i].theory->GetLineColor()); fData[i].theoryFourierPwr->SetLineColor(fData[i].theory->GetLineColor()); fData[i].theoryFourierPhase->SetLineColor(fData[i].theory->GetLineColor()); } // phase opt. real FT requested initially in the msr-file, hence calculate it here if (fCurrentPlotView == PV_FOURIER_PHASE_OPT_REAL) { CalcPhaseOptReFT(); } // apply global phase if present if (fFourier.fPhase.size() != 0.0) { double cp; double sp; fCurrentFourierPhase = fFourier.fPhase; for (UInt_t i=0; iGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fData[i].dataFourierRe->GetBinContent(j) * cp + fData[i].dataFourierIm->GetBinContent(j) * sp; im = fData[i].dataFourierIm->GetBinContent(j) * cp - fData[i].dataFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fData[i].dataFourierRe->SetBinContent(j, re); fData[i].dataFourierIm->SetBinContent(j, im); } } if ((fData[i].theoryFourierRe != nullptr) && (fData[i].theoryFourierIm != nullptr)) { for (Int_t j=0; jGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fData[i].theoryFourierRe->GetBinContent(j) * cp + fData[i].theoryFourierIm->GetBinContent(j) * sp; im = fData[i].theoryFourierIm->GetBinContent(j) * cp - fData[i].theoryFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fData[i].theoryFourierRe->SetBinContent(j, re); fData[i].theoryFourierIm->SetBinContent(j, im); } } } } } } //-------------------------------------------------------------------------- // HandleDifferenceFourier (private) //-------------------------------------------------------------------------- /** *

Handles the calculation of the Fourier transform of the difference spectra (i.e. data-theory). * It allocates the necessary objects if they are not already present. At the * end it calls the plotting routine. */ void PMusrCanvas::HandleDifferenceFourier() { // check if plot type is appropriate for fourier if (fPlotType == MSR_PLOT_NON_MUSR) return; // check if fourier needs to be calculated if (fData[0].diffFourierRe == nullptr) { // check if difference has been already calcualted, if not do it if (fData[0].diff == nullptr) HandleDifference(); // get time from the current fHistoFrame Int_t bin; bin = fHistoFrame->GetXaxis()->GetFirst(); double startTime = fHistoFrame->GetBinCenter(bin); bin = fHistoFrame->GetXaxis()->GetLast(); double endTime = fHistoFrame->GetBinCenter(bin); for (UInt_t i=0; i> PMusrCanvas::HandleFourier(): **SEVERE ERROR** couldn't invoke PFourier to calculate the Fourier diff ..." << std::endl; return; } fourierData.Transform(fFourier.fApodization); double scale; scale = sqrt(fData[0].diff->GetBinWidth(1)/(endTime-startTime)); // get real part of the data fData[i].diffFourierRe = fourierData.GetRealFourier(scale); // get imaginary part of the data fData[i].diffFourierIm = fourierData.GetImaginaryFourier(scale); // get power part of the data fData[i].diffFourierPwr = fourierData.GetPowerFourier(scale); // get phase part of the data fData[i].diffFourierPhase = fourierData.GetPhaseFourier(); // set marker and line color fData[i].diffFourierRe->SetMarkerColor(fData[i].diff->GetMarkerColor()); fData[i].diffFourierRe->SetLineColor(fData[i].diff->GetLineColor()); fData[i].diffFourierIm->SetMarkerColor(fData[i].diff->GetMarkerColor()); fData[i].diffFourierIm->SetLineColor(fData[i].diff->GetLineColor()); fData[i].diffFourierPwr->SetMarkerColor(fData[i].diff->GetMarkerColor()); fData[i].diffFourierPwr->SetLineColor(fData[i].diff->GetLineColor()); fData[i].diffFourierPhase->SetMarkerColor(fData[i].diff->GetMarkerColor()); fData[i].diffFourierPhase->SetLineColor(fData[i].diff->GetLineColor()); // set marker size fData[i].diffFourierRe->SetMarkerSize(1); fData[i].diffFourierIm->SetMarkerSize(1); fData[i].diffFourierPwr->SetMarkerSize(1); fData[i].diffFourierPhase->SetMarkerSize(1); // set marker type fData[i].diffFourierRe->SetMarkerStyle(fData[i].diff->GetMarkerStyle()); fData[i].diffFourierIm->SetMarkerStyle(fData[i].diff->GetMarkerStyle()); fData[i].diffFourierPwr->SetMarkerStyle(fData[i].diff->GetMarkerStyle()); fData[i].diffFourierPhase->SetMarkerStyle(fData[i].diff->GetMarkerStyle()); // set diffFourierTag fData[i].diffFourierTag = 1; // d-f } // apply phase if (fFourier.fPhase.size() != 0.0) { double re, im; double cp; double sp; fCurrentFourierPhase = fFourier.fPhase; for (UInt_t i=0; iGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fData[i].diffFourierRe->GetBinContent(j) * cp + fData[i].diffFourierIm->GetBinContent(j) * sp; im = fData[i].diffFourierIm->GetBinContent(j) * cp - fData[i].diffFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fData[i].diffFourierRe->SetBinContent(j, re); fData[i].diffFourierIm->SetBinContent(j, im); } } } } } } //-------------------------------------------------------------------------- // HandleFourierDifference (private) //-------------------------------------------------------------------------- /** *

Handles the calculation of the difference of the Fourier spectra. * It allocates the necessary objects if they are not already present. At the * end it calls the plotting routine. */ void PMusrCanvas::HandleFourierDifference() { // check if plot type is appropriate for fourier if (fPlotType == MSR_PLOT_NON_MUSR) return; // check if fourier needs to be calculated if (fData[0].diffFourierRe == nullptr) { // calculate all the Fourier differences Double_t dval, dvalx; TString name; Int_t theoBin; for (UInt_t i=0; iGetTitle()) + "_diff"; fData[i].diffFourierRe = new TH1F(name, name, fData[i].dataFourierRe->GetNbinsX(), fData[i].dataFourierRe->GetXaxis()->GetXmin(), fData[i].dataFourierRe->GetXaxis()->GetXmax()); // imaginary part name = TString(fData[i].dataFourierIm->GetTitle()) + "_diff"; fData[i].diffFourierIm = new TH1F(name, name, fData[i].dataFourierIm->GetNbinsX(), fData[i].dataFourierIm->GetXaxis()->GetXmin(), fData[i].dataFourierIm->GetXaxis()->GetXmax()); // power part name = TString(fData[i].dataFourierPwr->GetTitle()) + "_diff"; fData[i].diffFourierPwr = new TH1F(name, name, fData[i].dataFourierPwr->GetNbinsX(), fData[i].dataFourierPwr->GetXaxis()->GetXmin(), fData[i].dataFourierPwr->GetXaxis()->GetXmax()); // phase part name = TString(fData[i].dataFourierPhase->GetTitle()) + "_diff"; fData[i].diffFourierPhase = new TH1F(name, name, fData[i].dataFourierPhase->GetNbinsX(), fData[i].dataFourierPhase->GetXaxis()->GetXmin(), fData[i].dataFourierPhase->GetXaxis()->GetXmax()); // phase optimized real part if (fData[i].dataFourierPhaseOptReal != nullptr) { name = TString(fData[i].dataFourierPhaseOptReal->GetTitle()) + "_diff"; fData[i].diffFourierPhaseOptReal = new TH1F(name, name, fData[i].dataFourierPhaseOptReal->GetNbinsX(), fData[i].dataFourierPhaseOptReal->GetXaxis()->GetXmin(), fData[i].dataFourierPhaseOptReal->GetXaxis()->GetXmax()); } // calculate difference for (UInt_t j=1; jGetEntries(); j++) { dvalx = fData[i].dataFourierRe->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j theoBin = fData[i].theoryFourierRe->FindBin(dvalx); // get the theory x-axis bin dval = fData[i].dataFourierRe->GetBinContent(j) - fData[i].theoryFourierRe->GetBinContent(theoBin); fData[i].diffFourierRe->SetBinContent(j, dval); dvalx = fData[i].dataFourierIm->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j theoBin = fData[i].theoryFourierIm->FindBin(dvalx); // get the theory x-axis bin dval = fData[i].dataFourierIm->GetBinContent(j) - fData[i].theoryFourierIm->GetBinContent(theoBin); fData[i].diffFourierIm->SetBinContent(j, dval); dvalx = fData[i].dataFourierPwr->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j theoBin = fData[i].theoryFourierPwr->FindBin(dvalx); // get the theory x-axis bin dval = fData[i].dataFourierPwr->GetBinContent(j) - fData[i].theoryFourierPwr->GetBinContent(theoBin); fData[i].diffFourierPwr->SetBinContent(j, dval); dvalx = fData[i].dataFourierPhase->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j theoBin = fData[i].theoryFourierPhase->FindBin(dvalx); // get the theory x-axis bin dval = fData[i].dataFourierPhase->GetBinContent(j) - fData[i].theoryFourierPhase->GetBinContent(theoBin); fData[i].diffFourierPhase->SetBinContent(j, dval); if (fData[i].dataFourierPhaseOptReal != nullptr) { dvalx = fData[i].dataFourierPhaseOptReal->GetXaxis()->GetBinCenter(j); // get x-axis value of bin j theoBin = fData[i].theoryFourierPhaseOptReal->FindBin(dvalx); // get the theory x-axis bin dval = fData[i].dataFourierPhaseOptReal->GetBinContent(j) - fData[i].theoryFourierPhaseOptReal->GetBinContent(theoBin); fData[i].diffFourierPhaseOptReal->SetBinContent(j, dval); } } } for (UInt_t i=0; iSetMarkerColor(fData[i].dataFourierRe->GetMarkerColor()); fData[i].diffFourierRe->SetLineColor(fData[i].dataFourierRe->GetLineColor()); fData[i].diffFourierIm->SetMarkerColor(fData[i].dataFourierIm->GetMarkerColor()); fData[i].diffFourierIm->SetLineColor(fData[i].dataFourierIm->GetLineColor()); fData[i].diffFourierPwr->SetMarkerColor(fData[i].dataFourierPwr->GetMarkerColor()); fData[i].diffFourierPwr->SetLineColor(fData[i].dataFourierPwr->GetLineColor()); fData[i].diffFourierPhase->SetMarkerColor(fData[i].dataFourierPhase->GetMarkerColor()); fData[i].diffFourierPhase->SetLineColor(fData[i].dataFourierPhase->GetLineColor()); if (fData[i].dataFourierPhaseOptReal != nullptr) { fData[i].diffFourierPhaseOptReal->SetMarkerColor(fData[i].dataFourierPhaseOptReal->GetMarkerColor()); fData[i].diffFourierPhaseOptReal->SetLineColor(fData[i].dataFourierPhaseOptReal->GetLineColor()); } // set marker size fData[i].diffFourierRe->SetMarkerSize(1); fData[i].diffFourierIm->SetMarkerSize(1); fData[i].diffFourierPwr->SetMarkerSize(1); fData[i].diffFourierPhase->SetMarkerSize(1); if (fData[i].dataFourierPhaseOptReal != nullptr) { fData[i].diffFourierPhaseOptReal->SetMarkerSize(1); } // set marker type fData[i].diffFourierRe->SetMarkerStyle(fData[i].dataFourierRe->GetMarkerStyle()); fData[i].diffFourierIm->SetMarkerStyle(fData[i].dataFourierIm->GetMarkerStyle()); fData[i].diffFourierPwr->SetMarkerStyle(fData[i].dataFourierPwr->GetMarkerStyle()); fData[i].diffFourierPhase->SetMarkerStyle(fData[i].dataFourierPhase->GetMarkerStyle()); if (fData[i].dataFourierPhaseOptReal != nullptr) { fData[i].diffFourierPhaseOptReal->SetMarkerStyle(fData[i].dataFourierPhaseOptReal->GetMarkerStyle()); } // set diffFourierTag fData[i].diffFourierTag = 2; // f-d } } } //-------------------------------------------------------------------------- // HandleAverage (private) //-------------------------------------------------------------------------- /** *

Handles the calculation of the average of the ploted data. * It allocates the necessary objects if they are not already present. At the * end it calls the plotting routine. */ void PMusrCanvas::HandleAverage() { // check if plot type is appropriate for average if (fPlotType == MSR_PLOT_NON_MUSR) return; // in case there is still some average left over, cleanup first if (fDataAvg.data != nullptr) { CleanupAverage(); } // create all the needed average data sets TString name(""); if (fData[0].data != nullptr) { name = TString(fData[0].data->GetTitle()) + "_avg"; fDataAvg.data = new TH1F(name, name, fData[0].data->GetNbinsX(), fData[0].data->GetXaxis()->GetXmin(), fData[0].data->GetXaxis()->GetXmax()); } if (fData[0].dataFourierRe != nullptr) { name = TString(fData[0].dataFourierRe->GetTitle()) + "_avg"; fDataAvg.dataFourierRe = new TH1F(name, name, fData[0].dataFourierRe->GetNbinsX(), fData[0].dataFourierRe->GetXaxis()->GetXmin(), fData[0].dataFourierRe->GetXaxis()->GetXmax()); } if (fData[0].dataFourierIm != nullptr) { name = TString(fData[0].dataFourierIm->GetTitle()) + "_avg"; fDataAvg.dataFourierIm = new TH1F(name, name, fData[0].dataFourierIm->GetNbinsX(), fData[0].dataFourierIm->GetXaxis()->GetXmin(), fData[0].dataFourierIm->GetXaxis()->GetXmax()); } if (fData[0].dataFourierPwr != nullptr) { name = TString(fData[0].dataFourierPwr->GetTitle()) + "_avg"; fDataAvg.dataFourierPwr = new TH1F(name, name, fData[0].dataFourierPwr->GetNbinsX(), fData[0].dataFourierPwr->GetXaxis()->GetXmin(), fData[0].dataFourierPwr->GetXaxis()->GetXmax()); } if (fData[0].dataFourierPhase != nullptr) { name = TString(fData[0].dataFourierPhase->GetTitle()) + "_avg"; fDataAvg.dataFourierPhase = new TH1F(name, name, fData[0].dataFourierPhase->GetNbinsX(), fData[0].dataFourierPhase->GetXaxis()->GetXmin(), fData[0].dataFourierPhase->GetXaxis()->GetXmax()); } if (fData[0].dataFourierPhaseOptReal != nullptr) { name = TString(fData[0].dataFourierPhaseOptReal->GetTitle()) + "_avg"; fDataAvg.dataFourierPhaseOptReal = new TH1F(name, name, fData[0].dataFourierPhaseOptReal->GetNbinsX(), fData[0].dataFourierPhaseOptReal->GetXaxis()->GetXmin(), fData[0].dataFourierPhaseOptReal->GetXaxis()->GetXmax()); } if (fData[0].theory != nullptr) { name = TString(fData[0].theory->GetTitle()) + "_avg"; fDataAvg.theory = new TH1F(name, name, fData[0].theory->GetNbinsX(), fData[0].theory->GetXaxis()->GetXmin(), fData[0].theory->GetXaxis()->GetXmax()); } if (fData[0].theoryFourierRe != nullptr) { name = TString(fData[0].theoryFourierRe->GetTitle()) + "_avg"; fDataAvg.theoryFourierRe = new TH1F(name, name, fData[0].theoryFourierRe->GetNbinsX(), fData[0].theoryFourierRe->GetXaxis()->GetXmin(), fData[0].theoryFourierRe->GetXaxis()->GetXmax()); } if (fData[0].theoryFourierIm != nullptr) { name = TString(fData[0].theoryFourierIm->GetTitle()) + "_avg"; fDataAvg.theoryFourierIm = new TH1F(name, name, fData[0].theoryFourierIm->GetNbinsX(), fData[0].theoryFourierIm->GetXaxis()->GetXmin(), fData[0].theoryFourierIm->GetXaxis()->GetXmax()); } if (fData[0].theoryFourierPwr != nullptr) { name = TString(fData[0].theoryFourierPwr->GetTitle()) + "_avg"; fDataAvg.theoryFourierPwr = new TH1F(name, name, fData[0].theoryFourierPwr->GetNbinsX(), fData[0].theoryFourierPwr->GetXaxis()->GetXmin(), fData[0].theoryFourierPwr->GetXaxis()->GetXmax()); } if (fData[0].theoryFourierPhase != nullptr) { name = TString(fData[0].theoryFourierPhase->GetTitle()) + "_avg"; fDataAvg.theoryFourierPhase = new TH1F(name, name, fData[0].theoryFourierPhase->GetNbinsX(), fData[0].theoryFourierPhase->GetXaxis()->GetXmin(), fData[0].theoryFourierPhase->GetXaxis()->GetXmax()); } if (fData[0].theoryFourierPhaseOptReal != nullptr) { name = TString(fData[0].theoryFourierPhaseOptReal->GetTitle()) + "_avg"; fDataAvg.theoryFourierPhaseOptReal = new TH1F(name, name, fData[0].theoryFourierPhaseOptReal->GetNbinsX(), fData[0].theoryFourierPhaseOptReal->GetXaxis()->GetXmin(), fData[0].theoryFourierPhaseOptReal->GetXaxis()->GetXmax()); } if (fData[0].diff != nullptr) { name = TString(fData[0].diff->GetTitle()) + "_avg"; fDataAvg.diff = new TH1F(name, name, fData[0].diff->GetNbinsX(), fData[0].diff->GetXaxis()->GetXmin(), fData[0].diff->GetXaxis()->GetXmax()); } if (fData[0].diffFourierRe != nullptr) { name = TString(fData[0].diffFourierRe->GetTitle()) + "_avg"; fDataAvg.diff = new TH1F(name, name, fData[0].diffFourierRe->GetNbinsX(), fData[0].diffFourierRe->GetXaxis()->GetXmin(), fData[0].diffFourierRe->GetXaxis()->GetXmax()); } if (fData[0].diffFourierIm != nullptr) { name = TString(fData[0].diffFourierIm->GetTitle()) + "_avg"; fDataAvg.diffFourierIm = new TH1F(name, name, fData[0].diffFourierIm->GetNbinsX(), fData[0].diffFourierIm->GetXaxis()->GetXmin(), fData[0].diffFourierIm->GetXaxis()->GetXmax()); } if (fData[0].diffFourierPwr != nullptr) { name = TString(fData[0].diffFourierPwr->GetTitle()) + "_avg"; fDataAvg.diffFourierPwr = new TH1F(name, name, fData[0].diffFourierPwr->GetNbinsX(), fData[0].diffFourierPwr->GetXaxis()->GetXmin(), fData[0].diffFourierPwr->GetXaxis()->GetXmax()); } if (fData[0].diffFourierPhase != nullptr) { name = TString(fData[0].diffFourierPhase->GetTitle()) + "_avg"; fDataAvg.diffFourierPhase = new TH1F(name, name, fData[0].diffFourierPhase->GetNbinsX(), fData[0].diffFourierPhase->GetXaxis()->GetXmin(), fData[0].diffFourierPhase->GetXaxis()->GetXmax()); } if (fData[0].diffFourierPhaseOptReal != nullptr) { name = TString(fData[0].diffFourierPhaseOptReal->GetTitle()) + "_avg"; fDataAvg.diffFourierPhaseOptReal = new TH1F(name, name, fData[0].diffFourierPhaseOptReal->GetNbinsX(), fData[0].diffFourierPhaseOptReal->GetXaxis()->GetXmin(), fData[0].diffFourierPhaseOptReal->GetXaxis()->GetXmax()); } // calculate all the average data sets double dval; if (fDataAvg.data != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.data->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.data->SetMarkerColor(fData[0].data->GetMarkerColor()); fDataAvg.data->SetLineColor(fData[0].data->GetLineColor()); fDataAvg.data->SetMarkerSize(fData[0].data->GetMarkerSize()); fDataAvg.data->SetMarkerStyle(fData[0].data->GetMarkerStyle()); } if (fDataAvg.dataFourierRe != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.dataFourierRe->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.dataFourierRe->SetMarkerColor(fData[0].dataFourierRe->GetMarkerColor()); fDataAvg.dataFourierRe->SetLineColor(fData[0].dataFourierRe->GetLineColor()); fDataAvg.dataFourierRe->SetMarkerSize(fData[0].dataFourierRe->GetMarkerSize()); fDataAvg.dataFourierRe->SetMarkerStyle(fData[0].dataFourierRe->GetMarkerStyle()); } if (fDataAvg.dataFourierIm != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.dataFourierIm->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.dataFourierIm->SetMarkerColor(fData[0].dataFourierIm->GetMarkerColor()); fDataAvg.dataFourierIm->SetLineColor(fData[0].dataFourierIm->GetLineColor()); fDataAvg.dataFourierIm->SetMarkerSize(fData[0].dataFourierIm->GetMarkerSize()); fDataAvg.dataFourierIm->SetMarkerStyle(fData[0].dataFourierIm->GetMarkerStyle()); } if (fDataAvg.dataFourierPwr != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.dataFourierPwr->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.dataFourierPwr->SetMarkerColor(fData[0].dataFourierPwr->GetMarkerColor()); fDataAvg.dataFourierPwr->SetLineColor(fData[0].dataFourierPwr->GetLineColor()); fDataAvg.dataFourierPwr->SetMarkerSize(fData[0].dataFourierPwr->GetMarkerSize()); fDataAvg.dataFourierPwr->SetMarkerStyle(fData[0].dataFourierPwr->GetMarkerStyle()); } if (fDataAvg.dataFourierPhase != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.dataFourierPhase->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.dataFourierPhase->SetMarkerColor(fData[0].dataFourierPhase->GetMarkerColor()); fDataAvg.dataFourierPhase->SetLineColor(fData[0].dataFourierPhase->GetLineColor()); fDataAvg.dataFourierPhase->SetMarkerSize(fData[0].dataFourierPhase->GetMarkerSize()); fDataAvg.dataFourierPhase->SetMarkerStyle(fData[0].dataFourierPhase->GetMarkerStyle()); } if (fDataAvg.dataFourierPhaseOptReal != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.dataFourierPhaseOptReal->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.dataFourierPhaseOptReal->SetMarkerColor(fData[0].dataFourierPhaseOptReal->GetMarkerColor()); fDataAvg.dataFourierPhaseOptReal->SetLineColor(fData[0].dataFourierPhaseOptReal->GetLineColor()); fDataAvg.dataFourierPhaseOptReal->SetMarkerSize(fData[0].dataFourierPhaseOptReal->GetMarkerSize()); fDataAvg.dataFourierPhaseOptReal->SetMarkerStyle(fData[0].dataFourierPhaseOptReal->GetMarkerStyle()); } if (fDataAvg.theory != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.theory->SetBinContent(i, dval/fData.size()); } fDataAvg.theory->SetLineColor(fData[0].theory->GetLineColor()); } if (fDataAvg.theoryFourierRe != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.theoryFourierRe->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.theoryFourierRe->SetMarkerColor(fData[0].theoryFourierRe->GetMarkerColor()); fDataAvg.theoryFourierRe->SetLineColor(fData[0].theoryFourierRe->GetLineColor()); fDataAvg.theoryFourierRe->SetMarkerSize(fData[0].theoryFourierRe->GetMarkerSize()); fDataAvg.theoryFourierRe->SetMarkerStyle(fData[0].theoryFourierRe->GetMarkerStyle()); } if (fDataAvg.theoryFourierIm != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.theoryFourierIm->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.theoryFourierIm->SetMarkerColor(fData[0].theoryFourierIm->GetMarkerColor()); fDataAvg.theoryFourierIm->SetLineColor(fData[0].theoryFourierIm->GetLineColor()); fDataAvg.theoryFourierIm->SetMarkerSize(fData[0].theoryFourierIm->GetMarkerSize()); fDataAvg.theoryFourierIm->SetMarkerStyle(fData[0].theoryFourierIm->GetMarkerStyle()); } if (fDataAvg.theoryFourierPwr != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.theoryFourierPwr->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.theoryFourierPwr->SetMarkerColor(fData[0].theoryFourierPwr->GetMarkerColor()); fDataAvg.theoryFourierPwr->SetLineColor(fData[0].theoryFourierPwr->GetLineColor()); fDataAvg.theoryFourierPwr->SetMarkerSize(fData[0].theoryFourierPwr->GetMarkerSize()); fDataAvg.theoryFourierPwr->SetMarkerStyle(fData[0].theoryFourierPwr->GetMarkerStyle()); } if (fDataAvg.theoryFourierPhase != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.theoryFourierPhase->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.theoryFourierPhase->SetMarkerColor(fData[0].theoryFourierPhase->GetMarkerColor()); fDataAvg.theoryFourierPhase->SetLineColor(fData[0].theoryFourierPhase->GetLineColor()); fDataAvg.theoryFourierPhase->SetMarkerSize(fData[0].theoryFourierPhase->GetMarkerSize()); fDataAvg.theoryFourierPhase->SetMarkerStyle(fData[0].theoryFourierPhase->GetMarkerStyle()); } if (fDataAvg.theoryFourierPhaseOptReal != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.theoryFourierPhaseOptReal->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.theoryFourierPhaseOptReal->SetMarkerColor(fData[0].theoryFourierPhaseOptReal->GetMarkerColor()); fDataAvg.theoryFourierPhaseOptReal->SetLineColor(fData[0].theoryFourierPhaseOptReal->GetLineColor()); fDataAvg.theoryFourierPhaseOptReal->SetMarkerSize(fData[0].theoryFourierPhaseOptReal->GetMarkerSize()); fDataAvg.theoryFourierPhaseOptReal->SetMarkerStyle(fData[0].theoryFourierPhaseOptReal->GetMarkerStyle()); } if (fDataAvg.diff != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.diff->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.diff->SetMarkerColor(fData[0].diff->GetMarkerColor()); fDataAvg.diff->SetLineColor(fData[0].diff->GetLineColor()); fDataAvg.diff->SetMarkerSize(fData[0].diff->GetMarkerSize()); fDataAvg.diff->SetMarkerStyle(fData[0].diff->GetMarkerStyle()); } if (fDataAvg.diffFourierRe != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.diffFourierRe->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.diffFourierRe->SetMarkerColor(fData[0].diffFourierRe->GetMarkerColor()); fDataAvg.diffFourierRe->SetLineColor(fData[0].diffFourierRe->GetLineColor()); fDataAvg.diffFourierRe->SetMarkerSize(fData[0].diffFourierRe->GetMarkerSize()); fDataAvg.diffFourierRe->SetMarkerStyle(fData[0].diffFourierRe->GetMarkerStyle()); } if (fDataAvg.diffFourierIm != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.diffFourierIm->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.diffFourierIm->SetMarkerColor(fData[0].diffFourierIm->GetMarkerColor()); fDataAvg.diffFourierIm->SetLineColor(fData[0].diffFourierIm->GetLineColor()); fDataAvg.diffFourierIm->SetMarkerSize(fData[0].diffFourierIm->GetMarkerSize()); fDataAvg.diffFourierIm->SetMarkerStyle(fData[0].diffFourierIm->GetMarkerStyle()); } if (fDataAvg.diffFourierPwr != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.diffFourierPwr->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.diffFourierPwr->SetMarkerColor(fData[0].diffFourierPwr->GetMarkerColor()); fDataAvg.diffFourierPwr->SetLineColor(fData[0].diffFourierPwr->GetLineColor()); fDataAvg.diffFourierPwr->SetMarkerSize(fData[0].diffFourierPwr->GetMarkerSize()); fDataAvg.diffFourierPwr->SetMarkerStyle(fData[0].diffFourierPwr->GetMarkerStyle()); } if (fDataAvg.diffFourierPhase != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.diffFourierPhase->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.diffFourierPhase->SetMarkerColor(fData[0].dataFourierPhase->GetMarkerColor()); fDataAvg.diffFourierPhase->SetLineColor(fData[0].dataFourierPhase->GetLineColor()); fDataAvg.diffFourierPhase->SetMarkerSize(fData[0].dataFourierPhase->GetMarkerSize()); fDataAvg.diffFourierPhase->SetMarkerStyle(fData[0].dataFourierPhase->GetMarkerStyle()); } if (fDataAvg.diffFourierPhaseOptReal != nullptr) { for (Int_t i=0; iGetNbinsX(); i++) { dval = 0.0; for (UInt_t j=0; jGetBinCenter(i)); } fDataAvg.diffFourierPhaseOptReal->SetBinContent(i, dval/fData.size()); } // set marker color, line color, maker size, marker type fDataAvg.diffFourierPhaseOptReal->SetMarkerColor(fData[0].dataFourierPhaseOptReal->GetMarkerColor()); fDataAvg.diffFourierPhaseOptReal->SetLineColor(fData[0].dataFourierPhaseOptReal->GetLineColor()); fDataAvg.diffFourierPhaseOptReal->SetMarkerSize(fData[0].dataFourierPhaseOptReal->GetMarkerSize()); fDataAvg.diffFourierPhaseOptReal->SetMarkerStyle(fData[0].dataFourierPhaseOptReal->GetMarkerStyle()); } } //-------------------------------------------------------------------------- // CleanupDifference (private) //-------------------------------------------------------------------------- /** *

Cleans up (deallocate) difference data. */ void PMusrCanvas::CleanupDifference() { for (UInt_t i=0; iCleans up (deallocate) Fourier transform data. */ void PMusrCanvas::CleanupFourier() { for (UInt_t i=0; iCleans up (deallocate) Fourier difference spectra. */ void PMusrCanvas::CleanupFourierDifference() { for (UInt_t i=0; iCleans up (deallocate) averaged data set. */ void PMusrCanvas::CleanupAverage() { if (fDataAvg.data != nullptr) { delete fDataAvg.data; fDataAvg.data = nullptr; } if (fDataAvg.dataFourierRe != nullptr) { delete fDataAvg.dataFourierRe; fDataAvg.dataFourierRe = nullptr; } if (fDataAvg.dataFourierIm != nullptr) { delete fDataAvg.dataFourierIm; fDataAvg.dataFourierIm = nullptr; } if (fDataAvg.dataFourierPwr != nullptr) { delete fDataAvg.dataFourierPwr; fDataAvg.dataFourierPwr = nullptr; } if (fDataAvg.dataFourierPhase != nullptr) { delete fDataAvg.dataFourierPhase; fDataAvg.dataFourierPhase = nullptr; } if (fDataAvg.dataFourierPhaseOptReal != nullptr) { delete fDataAvg.dataFourierPhaseOptReal; fDataAvg.dataFourierPhaseOptReal = nullptr; } if (fDataAvg.theory != nullptr) { delete fDataAvg.theory; fDataAvg.theory = nullptr; } if (fDataAvg.theoryFourierRe != nullptr) { delete fDataAvg.theoryFourierRe; fDataAvg.theoryFourierRe = nullptr; } if (fDataAvg.theoryFourierIm != nullptr) { delete fDataAvg.theoryFourierIm; fDataAvg.theoryFourierIm = nullptr; } if (fDataAvg.theoryFourierPwr != nullptr) { delete fDataAvg.theoryFourierPwr; fDataAvg.theoryFourierPwr = nullptr; } if (fDataAvg.theoryFourierPhase != nullptr) { delete fDataAvg.theoryFourierPhase; fDataAvg.theoryFourierPhase = nullptr; } if (fDataAvg.theoryFourierPhaseOptReal != nullptr) { delete fDataAvg.theoryFourierPhaseOptReal; fDataAvg.theoryFourierPhaseOptReal = nullptr; } if (fDataAvg.diff != nullptr) { delete fDataAvg.diff; fDataAvg.diff = nullptr; } if (fDataAvg.diffFourierRe != nullptr) { delete fDataAvg.diffFourierRe; fDataAvg.diffFourierRe = nullptr; } if (fDataAvg.diffFourierIm != nullptr) { delete fDataAvg.diffFourierIm; fDataAvg.diffFourierIm = nullptr; } if (fDataAvg.diffFourierPwr != nullptr) { delete fDataAvg.diffFourierPwr; fDataAvg.diffFourierPwr = nullptr; } if (fDataAvg.diffFourierPhase != nullptr) { delete fDataAvg.diffFourierPhase; fDataAvg.diffFourierPhase = nullptr; } if (fDataAvg.diffFourierPhaseOptReal != nullptr) { delete fDataAvg.diffFourierPhaseOptReal; fDataAvg.diffFourierPhaseOptReal = nullptr; } } //-------------------------------------------------------------------------- // CalculateDiff (private) //-------------------------------------------------------------------------- /** * @brief PMusrCanvas::CalcPhaseOptReFT */ void PMusrCanvas::CalcPhaseOptReFT() { Double_t min = fMsrHandler->GetMsrFourierList()->fRangeForPhaseCorrection[0]; Double_t max = fMsrHandler->GetMsrFourierList()->fRangeForPhaseCorrection[1]; if ((min == -1.0) && (max == -1.0)) { if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { min = fFourier.fPlotRange[0]; max = fFourier.fPlotRange[1]; } else { min = fData[0].dataFourierRe->GetBinLowEdge(1); max = fData[0].dataFourierRe->GetBinLowEdge(fData[0].dataFourierRe->GetNbinsX())+fData[0].dataFourierRe->GetBinWidth(1); } } PDoubleVector phaseParam; Char_t hName[1024]; Double_t ph, re; for (UInt_t i=0; iSetMarkerColor(fData[i].data->GetMarkerColor()); fData[i].dataFourierPhaseOptReal->SetLineColor(fData[i].data->GetLineColor()); // set marker size fData[i].dataFourierPhaseOptReal->SetMarkerSize(1); // set marker type fData[i].dataFourierPhaseOptReal->SetMarkerStyle(fData[i].data->GetMarkerStyle()); // handle Fourier theory part // clone theory Re FT strcpy(hName, fData[i].theoryFourierPhase->GetName()); strcat(hName, "_Opt_Real"); fData[i].theoryFourierPhaseOptReal = (TH1F*) fData[i].theoryFourierRe->Clone(hName); // rotate the theory according to the optimized phase parameters // first find minBin for min of the phase correction Int_t minBin = fData[i].theoryFourierPhaseOptReal->GetXaxis()->FindFixBin(min); Int_t maxBin = fData[i].theoryFourierPhaseOptReal->GetXaxis()->FindFixBin(max); for (Int_t j=1; jGetNbinsX(); j++) { ph = phaseParam[0] + phaseParam[1] * (Double_t)(j-minBin+1) / (Double_t)(maxBin-minBin); re = fData[i].theoryFourierRe->GetBinContent(j) * cos(ph) - fData[i].theoryFourierIm->GetBinContent(j) * sin(ph); fData[i].theoryFourierPhaseOptReal->SetBinContent(j, re); } // set line colors for the theory fData[i].theoryFourierPhaseOptReal->SetLineColor(fData[i].theory->GetLineColor()); } } //-------------------------------------------------------------------------- // CalculateDiff (private) //-------------------------------------------------------------------------- /** *

Calculates the difference between data and theory for histograms. * * return: * - (data - theory) value * * \param x x-value of the data * \param y y-value of the data * \param theo theory histogram */ double PMusrCanvas::CalculateDiff(const Double_t x, const Double_t y, TH1F *theo) { Int_t bin = theo->FindBin(x); return y - theo->GetBinContent(bin); } //-------------------------------------------------------------------------- // CalculateDiff (private) //-------------------------------------------------------------------------- /** *

Calculates the difference between data and theory for error graphs. * * return: * - (data - theory) value * * \param x x-value of the data * \param y y-value of the data * \param theo theory error graphs */ double PMusrCanvas::CalculateDiff(const Double_t x, const Double_t y, TGraphErrors *theo) { Int_t bin = 0; Double_t xVal, yVal; bin = FindBin(x, theo); theo->GetPoint(bin, xVal, yVal); return y - yVal; } //-------------------------------------------------------------------------- // FindBin (private) //-------------------------------------------------------------------------- /** *

Analog to FindBin for histograms (TH1F) but here for TGraphErrors. * * return: * - bin closest to a given x value. * * \param x x-value of the data * \param graph TGraphErrors which should be searched */ Int_t PMusrCanvas::FindBin(const Double_t x, TGraphErrors *graph) { Int_t i, bin = 0; Double_t *xTheo = graph->GetX(); // find proper bin of the graph for (i=0; iGetN(); i++) { if (*(xTheo+i) >= x) { bin = i; break; } } // in case it is the last point if (i == graph->GetN()) { bin = i; } return bin; } //-------------------------------------------------------------------------- // GetMaximum (private) //-------------------------------------------------------------------------- /** *

returns the maximum of a histogram in the range [xmin, xmax]. * If xmin = xmax = -1.0, the whole histogram range is used. * * return: * - maximum, or 0.0 if the histo pointer is the null pointer. * * \param histo pointer of the histogram * \param xmin lower edge for the search interval. * \param xmax upper edge for the search interval. */ Double_t PMusrCanvas::GetMaximum(TH1F* histo, Double_t xmin, Double_t xmax) { if (histo == nullptr) return 0.0; Int_t start=0, end=0; if (xmin == xmax) { start = 1; end = histo->GetNbinsX(); } else { start = histo->FindBin(xmin); if ((start==0) || (start==histo->GetNbinsX()+1)) // underflow/overflow start = 1; end = histo->FindBin(xmax); if ((end==0) || (end==histo->GetNbinsX()+1)) // underflow/overflow end = histo->GetNbinsX(); } Double_t max = histo->GetBinContent(start); Double_t binContent; for (Int_t i=start; iGetBinContent(i); if (max < binContent) max = binContent; } return max; } //-------------------------------------------------------------------------- // GetMinimum (private) //-------------------------------------------------------------------------- /** *

returns the minimum of a histogram in the range [xmin, xmax]. * If xmin = xmax = -1.0, the whole histogram range is used. * * return: * - minimum, or 0.0 if the histo pointer is the null pointer. * * \param histo pointer of the histogram * \param xmin lower edge for the search interval. * \param xmax upper edge for the search interval. */ Double_t PMusrCanvas::GetMinimum(TH1F* histo, Double_t xmin, Double_t xmax) { if (histo == nullptr) return 0.0; Int_t start=0, end=0; if (xmin == xmax) { start = 1; end = histo->GetNbinsX(); } else { start = histo->FindBin(xmin); if ((start==0) || (start==histo->GetNbinsX()+1)) // underflow/overflow start = 1; end = histo->FindBin(xmax); if ((end==0) || (end==histo->GetNbinsX()+1)) // underflow/overflow end = histo->GetNbinsX(); } Double_t min = histo->GetBinContent(start); Double_t binContent; for (Int_t i=start; iGetBinContent(i); if (min > binContent) min = binContent; } return min; } //-------------------------------------------------------------------------- // GetMaximum (private) //-------------------------------------------------------------------------- /** *

returns the maximum of a TGraphErrors object in the range [xmin, xmax]. * If xmin = xmax = -1.0, the whole histogram range is used. * * return: * - maximum, or 0.0 if the histo pointer is the null pointer. * * \param graph pointer of the histogram * \param xmin lower edge for the search interval. * \param xmax upper edge for the search interval. */ Double_t PMusrCanvas::GetMaximum(TGraphErrors* graph, Double_t xmin, Double_t xmax) { if (graph == nullptr) return 0.0; Double_t x, y; if (xmin == xmax) { graph->GetPoint(0, x, y); xmin = x; graph->GetPoint(graph->GetN()-1, x, y); xmax = x; } graph->GetPoint(0, x, y); Double_t max = y; for (Int_t i=0; iGetN(); i++) { graph->GetPoint(i, x, y); if ((x >= xmin) && (x <= xmax)) { if (y > max) max = y; } } return max; } //-------------------------------------------------------------------------- // GetMinimum (private) //-------------------------------------------------------------------------- /** *

returns the minimum of a TGraphErrors object in the range [xmin, xmax]. * If xmin = xmax = -1.0, the whole histogram range is used. * * return: * - minimum, or 0.0 if the histo pointer is the null pointer. * * \param graph pointer of the histogram * \param xmin lower edge for the search interval. * \param xmax upper edge for the search interval. */ Double_t PMusrCanvas::GetMinimum(TGraphErrors* graph, Double_t xmin, Double_t xmax) { if (graph == nullptr) return 0.0; Double_t x, y; if (xmin == xmax) { graph->GetPoint(0, x, y); xmin = x; graph->GetPoint(graph->GetN()-1, x, y); xmax = x; } graph->GetPoint(0, x, y); Double_t min = y; for (Int_t i=0; iGetN(); i++) { graph->GetPoint(i, x, y); if ((x >= xmin) && (x <= xmax)) { if (y < min) min = y; } } return min; } //-------------------------------------------------------------------------- // PlotData (private) //-------------------------------------------------------------------------- /** *

Plots the data. * * \param unzoom if true, rescale to the original msr-file ranges */ void PMusrCanvas::PlotData(Bool_t unzoom) { fDataTheoryPad->cd(); if (!fBatchMode) { // uncheck fourier menu entries fPopupFourier->UnCheckEntries(); } if (fPlotType < 0) // plot type not defined return; Double_t xmin, xmax; if (fPlotType != MSR_PLOT_NON_MUSR) { if (fData.size() > 0) { // keep the current x-axis range from the data view if (fHistoFrame && (fPreviousPlotView == PV_DATA)) { xmin = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetFirst()); xmax = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetLast()) + fHistoFrame->GetXaxis()->GetBinWidth(fHistoFrame->GetXaxis()->GetLast()); } else { xmin = fXmin; xmax = fXmax; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } // get the histo frame x/y range boundaries Double_t dataXmin=0.0, dataXmax=0.0, dataYmin=0.0, dataYmax=0.0; if (unzoom) { // set the x-/y-range back to the original msr-file values dataXmin = fXmin; dataXmax = fXmax; if (fYRangePresent) { dataYmin = fYmin; dataYmax = fYmax; } else { dataYmin = GetMinimum(fData[0].data, dataXmin, dataXmax); dataYmax = GetMaximum(fData[0].data, dataXmin, dataXmax); for (UInt_t i=1; i dataYmax) dataYmax = GetMaximum(fData[i].data, dataXmin, dataXmax); } Double_t dd = 0.05*fabs(dataYmax-dataYmin); dataYmin -= dd; dataYmax += dd; } } else { // set the x-/y-range to the previous fHistoFrame range dataXmin = xmin; dataXmax = xmax; if (fYRangePresent) { // explicit y-range present dataYmin = fYmin; dataYmax = fYmax; } else { // extract global min/max in order to have the proper y-range dataYmin = GetMinimum(fData[0].data, dataXmin, dataXmax); dataYmax = GetMaximum(fData[0].data, dataXmin, dataXmax); for (UInt_t i=1; i dataYmax) dataYmax = GetMaximum(fData[i].data, dataXmin, dataXmax); } Double_t dd = 0.05*fabs(dataYmax-dataYmin); dataYmin -= dd; dataYmax += dd; } } if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) { dataYmin = 1.0e-4 * dataYmax; } // create histo frame in order to plot histograms possibly with different x-frames fHistoFrame = fDataTheoryPad->DrawFrame(dataXmin, dataYmin, dataXmax, dataYmax); // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one UInt_t noOfPoints = 1000; for (UInt_t i=0; iGetNbinsX() > (Int_t)noOfPoints) noOfPoints = fData[i].data->GetNbinsX(); } noOfPoints *= 2; // make sure that there are enough points fHistoFrame->SetBins(noOfPoints, dataXmin, dataXmax); // set all histo/theory ranges properly for (UInt_t i=0; iGetXaxis()->SetRange(fData[i].data->FindBin(dataXmin), fData[i].data->FindBin(dataXmax)); fData[i].data->GetYaxis()->SetRangeUser(dataYmin, dataYmax); fData[i].theory->GetXaxis()->SetRange(fData[i].theory->FindBin(dataXmin), fData[i].theory->FindBin(dataXmax)); fData[i].theory->GetYaxis()->SetRangeUser(dataYmin, dataYmax); } if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX) fDataTheoryPad->SetLogx(1); if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) fDataTheoryPad->SetLogy(1); // set x-axis label if (fPlotType == MSR_PLOT_BNMR ) { // For BNMR/BNQR runs use seconds fHistoFrame->GetXaxis()->SetTitle("time (s)"); } else { fHistoFrame->GetXaxis()->SetTitle("time (#mus)"); } // set y-axis label TString yAxisTitle; PMsrRunList *runList = fMsrHandler->GetMsrRunList(); switch (fPlotType) { case MSR_PLOT_SINGLE_HISTO: if (runList->at(0).IsLifetimeCorrected()) { // lifetime correction yAxisTitle = "Asymmetry"; } else { // no liftime correction if (fScaleN0AndBkg) yAxisTitle = "N(t) per nsec"; else yAxisTitle = "N(t) per bin"; } break; case MSR_PLOT_SINGLE_HISTO_RRF: case MSR_PLOT_ASYM_RRF: yAxisTitle = "RRF Asymmetry"; break; case MSR_PLOT_ASYM: yAxisTitle = "Asymmetry"; break; case MSR_PLOT_BNMR: yAxisTitle = "Asymmetry"; break; case MSR_PLOT_MU_MINUS: yAxisTitle = "N(t) per bin"; break; default: yAxisTitle = "??"; break; } fHistoFrame->GetYaxis()->SetTitleOffset(1.3); fHistoFrame->GetYaxis()->SetTitle(yAxisTitle.Data()); // plot all data for (UInt_t i=0; iDraw("pesame"); } // plot all the theory for (UInt_t i=0; iDraw("lsame"); } } // check if RRF and if yes show a label if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) { fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data()); } } else { // fPlotType == MSR_PLOT_NO_MUSR // keep the current x-axis range from the data view if (fMultiGraphDiff && (fPreviousPlotView == PV_DATA)) { xmin = fMultiGraphDiff->GetXaxis()->GetBinCenter(fMultiGraphDiff->GetXaxis()->GetFirst()); xmax = fMultiGraphDiff->GetXaxis()->GetBinCenter(fMultiGraphDiff->GetXaxis()->GetLast()); } else { xmin = fXmin; xmax = fXmax; } // tell the canvas that the selected object (the one under the mouse pointer) is not your object, before to actually delete it. fMainCanvas->SetSelected(fMainCanvas->GetPadSave()); // cleanup if previous fMultiGraphData is present if (fMultiGraphData) { delete fMultiGraphData; fMultiGraphData = nullptr; } if (fMultiGraphDiff) { delete fMultiGraphDiff; fMultiGraphDiff = nullptr; } PMsrRunList runs = *fMsrHandler->GetMsrRunList(); PMsrPlotStructure plotInfo = fMsrHandler->GetMsrPlotList()->at(fPlotNumber); UInt_t runNo = (UInt_t)plotInfo.fRuns[0]-1; TString xAxisTitle = fRunList->GetXAxisTitle(*runs[runNo].GetRunName(), runNo); TString yAxisTitle = fRunList->GetYAxisTitle(*runs[runNo].GetRunName(), runNo); if (fNonMusrData.size() > 0) { // get the histo frame x/y range boundaries Double_t dataXmin=0.0, dataXmax=0.0, dataYmin=0.0, dataYmax=0.0; if (unzoom) { // set the x-/y-range back to the original msr-file values dataXmin = fXmin; dataXmax = fXmax; if (fYRangePresent) { dataYmin = fYmin; dataYmax = fYmax; } else { dataYmin = GetMinimum(fNonMusrData[0].data, dataXmin, dataXmax); dataYmax = GetMaximum(fNonMusrData[0].data, dataXmin, dataXmax); for (UInt_t i=1; i dataYmax) dataYmax = GetMaximum(fNonMusrData[i].data, dataXmin, dataXmax); } Double_t dd = 0.05*fabs(dataYmax-dataYmin); dataYmin -= dd; dataYmax += dd; } } else { // set the x-/y-range to the previous fHistoFrame range dataXmin = xmin; dataXmax = xmax; if (fYRangePresent) { // explicit y-range present dataYmin = fYmin; dataYmax = fYmax; } else { // extract global min/max in order to have the proper y-range dataYmin = GetMinimum(fNonMusrData[0].data, dataXmin, dataXmax); dataYmax = GetMaximum(fNonMusrData[0].data, dataXmin, dataXmax); for (UInt_t i=1; i dataYmax) dataYmax = GetMaximum(fNonMusrData[i].data, dataXmin, dataXmax); } Double_t dd = 0.05*fabs(dataYmax-dataYmin); dataYmin -= dd; dataYmax += dd; } } if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) { if (dataYmin <= 0.0) dataYmin = 1.0e-4 * dataYmax; } // create fMultiGraphData, and add all data and theory fMultiGraphData = new TMultiGraph(); assert(fMultiGraphData != nullptr); // add all data to fMultiGraphData for (UInt_t i=0; iSetEditable(false); fMultiGraphData->Add(ge, "p"); } // add all the theory to fMultiGraphData for (UInt_t i=0; iSetEditable(false); fMultiGraphData->Add(ge, "l"); } if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX) fDataTheoryPad->SetLogx(1); if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) fDataTheoryPad->SetLogy(1); fMultiGraphData->Draw("a"); // set x/y-range fMultiGraphData->GetXaxis()->SetRangeUser(dataXmin, dataXmax); fMultiGraphData->GetYaxis()->SetRangeUser(dataYmin, dataYmax); // set x-, y-axis label only if there is just one data set if (fNonMusrData.size() == 1) { // set x-axis label fMultiGraphData->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis label fMultiGraphData->GetYaxis()->SetTitle(yAxisTitle.Data()); } else { // more than one data set present, hence add a legend if (fMultiGraphLegend) { delete fMultiGraphLegend; } fMultiGraphLegend = new TLegend(0.8, 0.8, 1.0, 1.0); assert(fMultiGraphLegend != nullptr); PStringVector legendLabel; for (UInt_t i=0; iGetXAxisTitle(*runs[runNo].GetRunName(), runNo); yAxisTitle = fRunList->GetYAxisTitle(*runs[runNo].GetRunName(), runNo); legendLabel.push_back(yAxisTitle + " vs. " + xAxisTitle); } for (UInt_t i=0; iAddEntry(fNonMusrData[i].data, legendLabel[i].Data(), "p"); } legendLabel.clear(); } fMultiGraphData->Draw("a"); if (fMultiGraphLegend) fMultiGraphLegend->Draw(); } // report canvas status events in non-musr plots if (!fMainCanvas->GetShowEventStatus()) { fMainCanvas->ToggleEventStatus(); } } fDataTheoryPad->Update(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // PlotDifference (private) //-------------------------------------------------------------------------- /** *

Plots the difference data, i.e. data-theory * * \param unzoom if true, rescale to the original msr-file ranges */ void PMusrCanvas::PlotDifference(Bool_t unzoom) { fDataTheoryPad->cd(); // check if log scale plotting and if yes switch back to linear if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) fDataTheoryPad->SetLogy(0); // switch to linear if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX) fDataTheoryPad->SetLogx(0); // switch to linear if (fPlotType < 0) // plot type not defined return; Double_t xmin, xmax; if (fPlotType != MSR_PLOT_NON_MUSR) { // keep the current x-axis range from the data view if (fHistoFrame && (fPreviousPlotView == PV_DATA)) { xmin = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetFirst()); xmax = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetLast()) + fHistoFrame->GetXaxis()->GetBinWidth(fHistoFrame->GetXaxis()->GetLast()); } else { xmin = fXmin; xmax = fXmax; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } Double_t dataXmin=0.0, dataXmax=0.0, dataYmin=0.0, dataYmax=0.0, dd=0.0; if (unzoom) { dataXmin = fXmin; dataXmax = fXmax; dataYmin = GetMinimum(fData[0].diff, dataXmin, dataXmax); dataYmax = GetMaximum(fData[0].diff, dataXmin, dataXmax); for (UInt_t i=1; i dataYmax) dataYmax = GetMaximum(fData[i].diff, dataXmin, dataXmax); } // slightly increase y-range dd = 0.05*fabs(dataYmax-dataYmin); dataYmin -= dd; dataYmax += dd; } else { dataXmin = xmin; dataXmax = xmax; dataYmin = GetMinimum(fData[0].diff, dataXmin, dataXmax); dataYmax = GetMaximum(fData[0].diff, dataXmin, dataXmax); for (UInt_t i=1; i dataYmax) dataYmax = GetMaximum(fData[i].diff, dataXmin, dataXmax); } // slightly increase y-range dd = 0.05*fabs(dataYmax-dataYmin); dataYmin -= dd; dataYmax += dd; } fHistoFrame = fDataTheoryPad->DrawFrame(dataXmin, dataYmin, dataXmax, dataYmax); // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one UInt_t noOfPoints = 1000; for (UInt_t i=0; iGetNbinsX() > (Int_t)noOfPoints) noOfPoints = fData[i].diff->GetNbinsX(); } noOfPoints *= 2; // make sure that there are enough points fHistoFrame->SetBins(noOfPoints, dataXmin, dataXmax); // set x-axis label if (fPlotType == MSR_PLOT_BNMR) { // For BNMR/BNQR runs use seconds fHistoFrame->GetXaxis()->SetTitle("time (s)"); } else { fHistoFrame->GetXaxis()->SetTitle("time (#mus)"); } // set y-axis label fHistoFrame->GetYaxis()->SetTitleOffset(1.3); fHistoFrame->GetYaxis()->SetTitle("data-theory"); // plot all diff data for (UInt_t i=0; iDraw("pesame"); // set all diff ranges properly if (fData[i].dataRange->IsXRangePresent()) fData[i].diff->GetXaxis()->SetRangeUser(fData[i].dataRange->GetXmin(), fData[i].dataRange->GetXmax()); else fData[i].diff->GetXaxis()->SetRange(fData[i].diff->FindBin(dataXmin), fData[i].diff->FindBin(dataXmax)); if (fData[i].dataRange->IsYRangePresent()) fData[i].diff->GetYaxis()->SetRangeUser(fData[i].dataRange->GetYmin(), fData[i].dataRange->GetYmax()); else fData[i].diff->GetYaxis()->SetRangeUser(dataYmin, dataYmax); } // check if RRF and if yes show a label if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) { fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data()); } } else { // fPlotType == MSR_PLOT_NON_MUSR // keep the current x-axis range from the data view if (fMultiGraphData && (fPreviousPlotView == PV_DATA)) { xmin = fMultiGraphData->GetXaxis()->GetBinCenter(fMultiGraphData->GetXaxis()->GetFirst()); xmax = fMultiGraphData->GetXaxis()->GetBinCenter(fMultiGraphData->GetXaxis()->GetLast()); } else { xmin = fXmin; xmax = fXmax; } // tell the canvas that the selected object (the one under the mouse pointer) is not your object, before to actually delete it. fMainCanvas->SetSelected(fMainCanvas->GetPadSave()); // clean up previous fMultiGraphDiff if (fMultiGraphDiff) { delete fMultiGraphDiff; fMultiGraphDiff = nullptr; } if (fMultiGraphData) { delete fMultiGraphData; fMultiGraphData = nullptr; } PMsrRunList runs = *fMsrHandler->GetMsrRunList(); PMsrPlotStructure plotInfo = fMsrHandler->GetMsrPlotList()->at(fPlotNumber); UInt_t runNo = (UInt_t)plotInfo.fRuns[0]-1; TString xAxisTitle = fRunList->GetXAxisTitle(*runs[runNo].GetRunName(), runNo); // if fMultiGraphDiff is not present create it and add the diff data fMultiGraphDiff = new TMultiGraph(); assert(fMultiGraphDiff != nullptr); // get the histo frame x/y range boundaries Double_t dataXmin=0.0, dataXmax=0.0, dataYmin=0.0, dataYmax=0.0; if (unzoom) { // set the x-/y-range back to the original msr-file values dataXmin = fXmin; dataXmax = fXmax; dataYmin = GetMinimum(fNonMusrData[0].diff, dataXmin, dataXmax); dataYmax = GetMaximum(fNonMusrData[0].diff, dataXmin, dataXmax); for (UInt_t i=1; i dataYmax) dataYmax = GetMaximum(fNonMusrData[i].diff, dataXmin, dataXmax); } Double_t dd = 0.05*fabs(dataYmax-dataYmin); dataYmin -= dd; dataYmax += dd; } else { // set the x-/y-range to the previous fHistoFrame range dataXmin = xmin; dataXmax = xmax; dataYmin = GetMinimum(fNonMusrData[0].diff, dataXmin, dataXmax); dataYmax = GetMaximum(fNonMusrData[0].diff, dataXmin, dataXmax); for (UInt_t i=1; i dataYmax) dataYmax = GetMaximum(fNonMusrData[i].diff, dataXmin, dataXmax); } Double_t dd = 0.05*fabs(dataYmax-dataYmin); dataYmin -= dd; dataYmax += dd; } // add all diff data to fMultiGraphDiff for (UInt_t i=0; iSetEditable(false); fMultiGraphDiff->Add(ge, "p"); } fMultiGraphDiff->Draw("a"); // set x-range fMultiGraphDiff->GetXaxis()->SetRangeUser(dataXmin, dataXmax); fMultiGraphDiff->GetYaxis()->SetRangeUser(dataYmin, dataYmax); // set x-axis label fMultiGraphDiff->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis label fMultiGraphDiff->GetYaxis()->SetTitle("data-theory"); fMultiGraphDiff->Draw("a"); if (fMultiGraphLegend) fMultiGraphLegend->Draw(); } fDataTheoryPad->Update(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // PlotFourier (private) //-------------------------------------------------------------------------- /** *

Plot the Fourier spectra. * * \param unzoom if true, rescale to the original Fourier range */ void PMusrCanvas::PlotFourier(Bool_t unzoom) { fDataTheoryPad->cd(); // check if log scale plotting and if yes switch back to linear if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) fDataTheoryPad->SetLogy(0); // switch to linear if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX) fDataTheoryPad->SetLogx(0); // switch to linear if (fPlotType < 0) // plot type not defined return; if (fData.size() == 0) // no data to be plotted return; // define x-axis title TString xAxisTitle(""); if (fFourier.fUnits == FOURIER_UNIT_GAUSS) { xAxisTitle = TString("Field (G)"); } else if (fFourier.fUnits == FOURIER_UNIT_TESLA) { xAxisTitle = TString("Field (T)"); } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) { xAxisTitle = TString("Frequency (MHz)"); } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) { xAxisTitle = TString("Frequency (Mc/s)"); } else { xAxisTitle = TString("??"); } // plot fourier data Double_t xmin, xmax, ymin, ymax, binContent; UInt_t noOfPoints = 1000; switch (fCurrentPlotView) { case PV_FOURIER_REAL: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].dataFourierRe->GetBinLowEdge(1); xmax = fData[0].dataFourierRe->GetBinLowEdge(fData[0].dataFourierRe->GetNbinsX())+fData[0].dataFourierRe->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos and theories ymin = GetMinimum(fData[0].dataFourierRe); ymax = GetMaximum(fData[0].dataFourierRe); binContent = GetMinimum(fData[0].theoryFourierRe); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[0].theoryFourierRe); if (binContent > ymax) ymax = binContent; for (UInt_t i=1; i ymax) ymax = binContent; binContent = GetMinimum(fData[i].theoryFourierRe); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[i].theoryFourierRe); if (binContent > ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one noOfPoints = 1000; for (UInt_t i=0; iGetNbinsX() > (Int_t)noOfPoints) noOfPoints = fData[i].dataFourierRe->GetNbinsX(); } noOfPoints *= 2; // make sure that there are enough points fHistoFrame->SetBins(noOfPoints, xmin, xmax); // set ranges for Fourier and Fourier theory for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].dataFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fData[i].theoryFourierRe->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].theoryFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); fHistoFrame->GetYaxis()->SetTitle("Real Fourier"); // plot data for (UInt_t i=0; iDraw("psame"); } // plot theories for (UInt_t i=0; iDraw("same"); } PlotFourierPhaseValue(); break; case PV_FOURIER_IMAG: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].dataFourierIm->GetBinLowEdge(1); xmax = fData[0].dataFourierIm->GetBinLowEdge(fData[0].dataFourierIm->GetNbinsX())+fData[0].dataFourierIm->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].dataFourierIm); ymax = GetMaximum(fData[0].dataFourierIm); binContent = GetMinimum(fData[0].theoryFourierIm); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[0].theoryFourierIm); if (binContent > ymax) ymax = binContent; for (UInt_t i=1; i ymax) ymax = binContent; binContent = GetMinimum(fData[i].theoryFourierIm); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[i].theoryFourierIm); if (binContent > ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one noOfPoints = 1000; for (UInt_t i=0; iGetNbinsX() > (Int_t)noOfPoints) noOfPoints = fData[i].dataFourierIm->GetNbinsX(); } noOfPoints *= 2; // make sure that there are enough points fHistoFrame->SetBins(noOfPoints, xmin, xmax); // set ranges for Fourier and Fourier theory for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].dataFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fData[i].theoryFourierIm->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].theoryFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); fHistoFrame->GetYaxis()->SetTitle("Imaginary Fourier"); // plot data for (UInt_t i=0; iDraw("psame"); } // plot theories for (UInt_t i=0; iDraw("same"); } PlotFourierPhaseValue(); break; case PV_FOURIER_REAL_AND_IMAG: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].dataFourierRe->GetBinLowEdge(1); xmax = fData[0].dataFourierRe->GetBinLowEdge(fData[0].dataFourierRe->GetNbinsX())+fData[0].dataFourierRe->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos // real part first ymin = GetMinimum(fData[0].dataFourierRe); ymax = GetMaximum(fData[0].dataFourierRe); for (UInt_t i=1; i ymax) ymax = binContent; } // imag part min/max for (UInt_t i=0; i ymax) ymax = binContent; } // theory part min/max for (UInt_t i=0; i ymax) ymax = binContent; binContent = GetMinimum(fData[i].theoryFourierIm); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[i].theoryFourierIm); if (binContent > ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one noOfPoints = 1000; for (UInt_t i=0; iGetNbinsX() > (Int_t)noOfPoints) noOfPoints = fData[i].dataFourierRe->GetNbinsX(); } noOfPoints *= 2; // make sure that there are enough points fHistoFrame->SetBins(noOfPoints, xmin, xmax); // set ranges for Fourier and Fourier theory for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].dataFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fData[i].theoryFourierRe->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].theoryFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fData[i].dataFourierIm->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].dataFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fData[i].theoryFourierIm->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].theoryFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); fHistoFrame->GetYaxis()->SetTitle("Real/Imag Fourier"); // plot data for (UInt_t i=0; iDraw("psame"); fData[i].dataFourierIm->Draw("psame"); } // plot theories for (UInt_t i=0; iDraw("same"); fData[i].theoryFourierIm->Draw("same"); } PlotFourierPhaseValue(); break; case PV_FOURIER_PWR: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].dataFourierPwr->GetBinLowEdge(1); xmax = fData[0].dataFourierPwr->GetBinLowEdge(fData[0].dataFourierPwr->GetNbinsX())+fData[0].dataFourierPwr->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos and theory ymin = GetMinimum(fData[0].dataFourierPwr); ymax = GetMaximum(fData[0].dataFourierPwr); binContent = GetMinimum(fData[0].theoryFourierPwr); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[0].theoryFourierPwr); if (binContent > ymax) ymax = binContent; for (UInt_t i=1; i ymax) ymax = binContent; binContent = GetMinimum(fData[i].theoryFourierPwr); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[i].theoryFourierPwr); if (binContent > ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 0.95*ymin, xmax, 1.05*ymax); // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one noOfPoints = 1000; for (UInt_t i=0; iGetNbinsX() > (Int_t)noOfPoints) noOfPoints = fData[i].dataFourierPwr->GetNbinsX(); } noOfPoints *= 2; // make sure that there are enough points fHistoFrame->SetBins(noOfPoints, xmin, xmax); // set ranges for Fourier and Fourier theory for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].dataFourierPwr->GetYaxis()->SetRangeUser(0.95*ymin, 1.05*ymax); fData[i].theoryFourierPwr->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].theoryFourierPwr->GetYaxis()->SetRangeUser(0.95*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); fHistoFrame->GetYaxis()->SetTitle("Ampl. Fourier"); // plot data for (UInt_t i=0; iDraw("psame"); } // plot theories for (UInt_t i=0; iDraw("same"); } break; case PV_FOURIER_PHASE: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].dataFourierPhase->GetBinLowEdge(1); xmax = fData[0].dataFourierPhase->GetBinLowEdge(fData[0].dataFourierPhase->GetNbinsX())+fData[0].dataFourierPhase->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].dataFourierPhase); ymax = GetMaximum(fData[0].dataFourierPhase); binContent = GetMinimum(fData[0].theoryFourierPhase); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[0].theoryFourierPhase); if (binContent > ymax) ymax = binContent; for (UInt_t i=1; i ymax) ymax = binContent; binContent = GetMinimum(fData[i].theoryFourierPhase); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[i].theoryFourierPhase); if (binContent > ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one noOfPoints = 1000; for (UInt_t i=0; iGetNbinsX() > (Int_t)noOfPoints) noOfPoints = fData[i].dataFourierPhase->GetNbinsX(); } noOfPoints *= 2; // make sure that there are enough points fHistoFrame->SetBins(noOfPoints, xmin, xmax); for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].dataFourierPhase->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fData[i].theoryFourierPhase->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].theoryFourierPhase->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); fHistoFrame->GetYaxis()->SetTitle("Phase Fourier"); // plot data for (UInt_t i=0; iDraw("psame"); } // plot theories for (UInt_t i=0; iDraw("same"); } break; case PV_FOURIER_PHASE_OPT_REAL: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].dataFourierPhaseOptReal->GetBinLowEdge(1); xmax = fData[0].dataFourierPhaseOptReal->GetBinLowEdge(fData[0].dataFourierPhaseOptReal->GetNbinsX())+fData[0].dataFourierPhaseOptReal->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].dataFourierPhaseOptReal); ymax = GetMaximum(fData[0].dataFourierPhaseOptReal); binContent = GetMinimum(fData[0].theoryFourierPhaseOptReal); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[0].theoryFourierPhaseOptReal); if (binContent > ymax) ymax = binContent; for (UInt_t i=1; i ymax) ymax = binContent; binContent = GetMinimum(fData[i].theoryFourierPhaseOptReal); if (binContent < ymin) ymin = binContent; binContent = GetMaximum(fData[i].theoryFourierPhaseOptReal); if (binContent > ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // find the maximal number of points present in the histograms and increase the default number of points of fHistoFrame (1000) to the needed one noOfPoints = 1000; for (UInt_t i=0; iGetNbinsX() > (Int_t)noOfPoints) noOfPoints = fData[i].dataFourierPhaseOptReal->GetNbinsX(); } noOfPoints *= 2; // make sure that there are enough points fHistoFrame->SetBins(noOfPoints, xmin, xmax); for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].dataFourierPhaseOptReal->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fData[i].theoryFourierPhaseOptReal->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].theoryFourierPhaseOptReal->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); fHistoFrame->GetYaxis()->SetTitle("Phase Opt. Real Fourier"); // plot data for (UInt_t i=0; iDraw("psame"); } // plot theories for (UInt_t i=0; iDraw("same"); } break; default: break; } // check if RRF and if yes show a label if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) { fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data()); } fDataTheoryPad->Update(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // PlotFourierDifference (private) //-------------------------------------------------------------------------- /** *

Plot the Fourier difference, i.e. F(data)-F(theory). * * \param unzoom if true, rescale to the original Fourier range */ void PMusrCanvas::PlotFourierDifference(Bool_t unzoom) { fDataTheoryPad->cd(); // check if log scale plotting and if yes switch back to linear if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogY) fDataTheoryPad->SetLogy(0); // switch to linear if (fMsrHandler->GetMsrPlotList()->at(fPlotNumber).fLogX) fDataTheoryPad->SetLogx(0); // switch to linear if (fPlotType < 0) // plot type not defined return; if (fData.size() == 0) // no data to be plotted return; // define x-axis title TString xAxisTitle(""); if (fFourier.fUnits == FOURIER_UNIT_GAUSS) { xAxisTitle = TString("Field (G)"); } else if (fFourier.fUnits == FOURIER_UNIT_TESLA) { xAxisTitle = TString("Field (T)"); } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) { xAxisTitle = TString("Frequency (MHz)"); } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) { xAxisTitle = TString("Frequency (Mc/s)"); } else { xAxisTitle = TString("??"); } // plot data double xmin, xmax, ymin, ymax, binContent; switch (fCurrentPlotView) { case PV_FOURIER_REAL: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].diffFourierRe->GetBinLowEdge(1); xmax = fData[0].diffFourierRe->GetBinLowEdge(fData[0].diffFourierRe->GetNbinsX())+fData[0].diffFourierRe->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].diffFourierRe); ymax = GetMaximum(fData[0].diffFourierRe); for (UInt_t i=1; i ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // set ranges for Fourier difference for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].diffFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); if (fData[0].diffFourierTag == 1) fHistoFrame->GetYaxis()->SetTitle("Real Fourier (d-f: data-theory)"); else fHistoFrame->GetYaxis()->SetTitle("Real Fourier (f-d: [(F data)-(F theory)]"); // plot data for (UInt_t i=0; iDraw("plsame"); } PlotFourierPhaseValue(); break; case PV_FOURIER_IMAG: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].diffFourierIm->GetBinLowEdge(1); xmax = fData[0].diffFourierIm->GetBinLowEdge(fData[0].diffFourierIm->GetNbinsX())+fData[0].diffFourierIm->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].diffFourierIm); ymax = GetMaximum(fData[0].diffFourierIm); for (UInt_t i=1; i ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // set ranges for Fourier difference for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].diffFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); if (fData[0].diffFourierTag == 1) fHistoFrame->GetYaxis()->SetTitle("Imaginary Fourier (d-f: data-theory)"); else fHistoFrame->GetYaxis()->SetTitle("Imaginary Fourier (f-d: [(F data)-(F theory)]"); // plot data for (UInt_t i=0; iDraw("plsame"); } PlotFourierPhaseValue(); break; case PV_FOURIER_REAL_AND_IMAG: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].diffFourierRe->GetBinLowEdge(1); xmax = fData[0].diffFourierRe->GetBinLowEdge(fData[0].diffFourierRe->GetNbinsX())+fData[0].diffFourierRe->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].diffFourierRe); ymax = GetMaximum(fData[0].diffFourierRe); for (UInt_t i=1; i ymax) ymax = binContent; } for (UInt_t i=0; i ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // set ranges for Fourier difference for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].diffFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fData[i].diffFourierIm->GetXaxis()->SetRangeUser(xmin, xmax); fData[i].diffFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); if (fData[0].diffFourierTag == 1) fHistoFrame->GetYaxis()->SetTitle("Real+Imag Fourier (d-f: data-theory)"); else fHistoFrame->GetYaxis()->SetTitle("Real+Imag Fourier (f-d: [(F data)-(F theory)]"); // plot data for (UInt_t i=0; iDraw("plsame"); fData[i].diffFourierIm->Draw("plsame"); } PlotFourierPhaseValue(); break; case PV_FOURIER_PWR: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].diffFourierPwr->GetBinLowEdge(1); xmax = fData[0].diffFourierPwr->GetBinLowEdge(fData[0].diffFourierPwr->GetNbinsX())+fData[0].diffFourierPwr->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].diffFourierPwr); ymax = GetMaximum(fData[0].diffFourierPwr); for (UInt_t i=1; i ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 0.95*ymin, xmax, 1.05*ymax); // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set ranges for Fourier difference for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].diffFourierPwr->GetYaxis()->SetRangeUser(0.95*ymin, 1.05*ymax); } // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); if (fData[0].diffFourierTag == 1) fHistoFrame->GetYaxis()->SetTitle("Ampl. Fourier (d-f: data-theory)"); else fHistoFrame->GetYaxis()->SetTitle("Ampl. Fourier (f-d: [(F data)-(F theory)]"); // plot data for (UInt_t i=0; iDraw("plsame"); } break; case PV_FOURIER_PHASE: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].diffFourierPhase->GetBinLowEdge(1); xmax = fData[0].diffFourierPhase->GetBinLowEdge(fData[0].diffFourierPhase->GetNbinsX())+fData[0].diffFourierPhase->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].diffFourierPhase); ymax = GetMaximum(fData[0].diffFourierPhase); for (UInt_t i=1; i ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // set ranges for Fourier difference for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].diffFourierPhase->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); if (fData[0].diffFourierTag == 1) fHistoFrame->GetYaxis()->SetTitle("Phase Fourier (d-f: data-theory)"); else fHistoFrame->GetYaxis()->SetTitle("Phase Fourier [f-d: (F data)-(F theory)]"); // plot data for (UInt_t i=0; iDraw("plsame"); } PlotFourierPhaseValue(); break; case PV_FOURIER_PHASE_OPT_REAL: // set x-range if ((fFourier.fPlotRange[0] != -1) && (fFourier.fPlotRange[1] != -1)) { xmin = fFourier.fPlotRange[0]; xmax = fFourier.fPlotRange[1]; } else { xmin = fData[0].diffFourierPhaseOptReal->GetBinLowEdge(1); xmax = fData[0].diffFourierPhaseOptReal->GetBinLowEdge(fData[0].diffFourierPhaseOptReal->GetNbinsX())+fData[0].diffFourierPhaseOptReal->GetBinWidth(1); } // set y-range // first find minimum/maximum of all histos ymin = GetMinimum(fData[0].diffFourierPhaseOptReal); ymax = GetMaximum(fData[0].diffFourierPhaseOptReal); for (UInt_t i=1; i ymax) ymax = binContent; } // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, 1.05*ymin, xmax, 1.05*ymax); // set ranges for phase opt. real Fourier difference for (UInt_t i=0; iGetXaxis()->SetRangeUser(xmin, xmax); fData[i].diffFourierPhaseOptReal->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); } // set x-axis title fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); // set y-axis title fHistoFrame->GetYaxis()->SetTitleOffset(1.3); if (fData[0].diffFourierTag == 1) fHistoFrame->GetYaxis()->SetTitle("Real Fourier (d-f: data-theory)"); else fHistoFrame->GetYaxis()->SetTitle("Real Fourier (f-d: [(F data)-(F theory)]"); // plot data for (UInt_t i=0; iDraw("plsame"); } break; default: break; } // check if RRF and if yes show a label if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) { fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data()); } fDataTheoryPad->Update(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // PlotFourierPhaseValue (private) //-------------------------------------------------------------------------- /** *

Writes the Fourier phase value into the data window. * * \param unzoom if true, rescale to the original Fourier range */ void PMusrCanvas::PlotFourierPhaseValue(Bool_t unzoom) { // check if phase TLatex object is present if (fCurrentFourierPhaseText) { delete fCurrentFourierPhaseText; fCurrentFourierPhaseText = nullptr; } double x, y; TString str; // plot Fourier phase str = TString("phase = "); str += fCurrentFourierPhase[0]; if (fFourier.fPhase.size() > 1) { // if more than one phase is present, do NOT plot phase info str = TString(""); } x = 0.7; y = 0.85; fCurrentFourierPhaseText = new TLatex(); fCurrentFourierPhaseText->SetNDC(kTRUE); fCurrentFourierPhaseText->SetText(x, y, str.Data()); fCurrentFourierPhaseText->SetTextFont(62); fCurrentFourierPhaseText->SetTextSize(0.03); fDataTheoryPad->cd(); fCurrentFourierPhaseText->Draw(); fDataTheoryPad->Update(); } //-------------------------------------------------------------------------- // PlotAverage (private) //-------------------------------------------------------------------------- /** *

Plot the average of the given data sets. * * \param unzoom if true, rescale to the original average range. */ void PMusrCanvas::PlotAverage(Bool_t unzoom) { fDataTheoryPad->cd(); // define x-axis title TString xAxisTitle(""); if (fCurrentPlotView == PV_DATA) { if (fPlotType == MSR_PLOT_BNMR) { // For BNMR/BNQR runs use seconds xAxisTitle = TString("time (s)"); } else { xAxisTitle = TString("time (#mus)"); } } else { // all the Fourier if (fFourier.fUnits == FOURIER_UNIT_GAUSS) { xAxisTitle = TString("Field (G)"); } else if (fFourier.fUnits == FOURIER_UNIT_TESLA) { xAxisTitle = TString("Field (T)"); } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) { xAxisTitle = TString("Frequency (MHz)"); } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) { xAxisTitle = TString("Frequency (Mc/s)"); } else { xAxisTitle = TString("??"); } } // define y-axis title TString yAxisTitle(""); if (fCurrentPlotView == PV_DATA) { if (!fDifferenceView) { PMsrRunList *runList = fMsrHandler->GetMsrRunList(); switch (fPlotType) { case MSR_PLOT_SINGLE_HISTO: if (runList->at(0).IsLifetimeCorrected()) { // lifetime correction yAxisTitle = ""; } else { // no liftime correction if (fScaleN0AndBkg) yAxisTitle = " per nsec"; else yAxisTitle = " per bin"; } break; case MSR_PLOT_ASYM: yAxisTitle = ""; break; case MSR_PLOT_BNMR: yAxisTitle = ""; break; case MSR_PLOT_MU_MINUS: yAxisTitle = " per bin"; break; default: yAxisTitle = "??"; break; } } else { // DifferenceView yAxisTitle = ""; } } else { // all the Fourier if (!fDifferenceView) { switch (fCurrentPlotView) { case PV_FOURIER_REAL: yAxisTitle = ""; break; case PV_FOURIER_IMAG: yAxisTitle = ""; break; case PV_FOURIER_REAL_AND_IMAG: yAxisTitle = ""; break; case PV_FOURIER_PWR: yAxisTitle = ""; break; case PV_FOURIER_PHASE: yAxisTitle = ""; break; case PV_FOURIER_PHASE_OPT_REAL: yAxisTitle = ""; break; default: yAxisTitle = "??"; break; } } else { // DifferenceView switch (fCurrentPlotView) { case PV_FOURIER_REAL: if (fData[0].diffFourierTag == 1) yAxisTitle = ""; else yAxisTitle = ""; break; case PV_FOURIER_IMAG: if (fData[0].diffFourierTag == 1) yAxisTitle = ""; else yAxisTitle = ""; break; break; case PV_FOURIER_REAL_AND_IMAG: if (fData[0].diffFourierTag == 1) yAxisTitle = ""; else yAxisTitle = ""; break; break; case PV_FOURIER_PWR: if (fData[0].diffFourierTag == 1) yAxisTitle = ""; else yAxisTitle = ""; break; break; case PV_FOURIER_PHASE: if (fData[0].diffFourierTag == 1) yAxisTitle = ""; else yAxisTitle = ""; break; break; default: yAxisTitle = "??"; break; } } } // find proper ranges Double_t xmin, xmax, ymin, ymax; xmin = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetFirst()); xmax = fHistoFrame->GetXaxis()->GetBinLowEdge(fHistoFrame->GetXaxis()->GetLast()) + fHistoFrame->GetXaxis()->GetBinWidth(fHistoFrame->GetXaxis()->GetLast()); ymin = fHistoFrame->GetMinimum(); ymax = fHistoFrame->GetMaximum(); // delete old fHistoFrame if present if (fHistoFrame) { delete fHistoFrame; fHistoFrame = nullptr; } fHistoFrame = fDataTheoryPad->DrawFrame(xmin, ymin, xmax, ymax); fHistoFrame->GetXaxis()->SetTitle(xAxisTitle.Data()); fHistoFrame->GetYaxis()->SetTitle(yAxisTitle.Data()); fHistoFrame->GetYaxis()->SetTitleOffset(1.3); // find out what to be plotted switch (fCurrentPlotView) { case PV_DATA: if (!fDifferenceView) { // averaged data view fDataAvg.data->Draw("psame"); fDataAvg.theory->Draw("same"); } else { // averaged diff data view fDataAvg.diff->Draw("psame"); } break; case PV_FOURIER_REAL: if (!fDifferenceView) { // averaged Fourier Real view fDataAvg.dataFourierRe->Draw("psame"); fDataAvg.theoryFourierRe->Draw("same"); } else { // averaged diff Fourier Real view fDataAvg.diffFourierRe->Draw("psame"); } break; case PV_FOURIER_IMAG: if (!fDifferenceView) { // averaged Fourier Imag view fDataAvg.dataFourierIm->Draw("psame"); fDataAvg.theoryFourierIm->Draw("same"); } else { // averaged diff Fourier Imag view fDataAvg.diffFourierIm->Draw("psame"); } break; case PV_FOURIER_REAL_AND_IMAG: if (!fDifferenceView) { // averaged Fourier Real&Imag view fDataAvg.dataFourierRe->Draw("psame"); fDataAvg.theoryFourierRe->Draw("same"); fDataAvg.dataFourierIm->Draw("psame"); fDataAvg.theoryFourierIm->Draw("same"); } else { // averaged diff Fourier Real&Imag view fDataAvg.diffFourierRe->Draw("psame"); fDataAvg.diffFourierIm->Draw("psame"); } break; case PV_FOURIER_PWR: if (!fDifferenceView) { // averaged Fourier Power view fDataAvg.dataFourierPwr->Draw("psame"); fDataAvg.theoryFourierPwr->Draw("same"); } else { // averaged diff Fourier Power view fDataAvg.diffFourierPwr->Draw("psame"); } break; case PV_FOURIER_PHASE: if (!fDifferenceView) { // averaged Fourier Phase view fDataAvg.dataFourierPhase->Draw("psame"); fDataAvg.theoryFourierPhase->Draw("same"); } else { // averaged diff Fourier Phase view fDataAvg.diffFourierPhase->Draw("psame"); } break; case PV_FOURIER_PHASE_OPT_REAL: if (!fDifferenceView) { // averaged Fourier Phase Opt Real view fDataAvg.dataFourierPhaseOptReal->Draw("psame"); fDataAvg.theoryFourierPhaseOptReal->Draw("same"); } else { // averaged diff Fourier Phase view fDataAvg.diffFourierPhaseOptReal->Draw("psame"); } break; default: break; } // check if RRF and if yes show a label if ((fRRFText != nullptr) && (fRRFLatexText != nullptr)) { fRRFLatexText->DrawLatex(0.1, 0.92, fRRFText->Data()); } fDataTheoryPad->Update(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // IncrementFourierPhase (private) //-------------------------------------------------------------------------- /** *

Increments the Fourier phase and recalculate the real/imaginary part of the Fourier transform. */ void PMusrCanvas::IncrementFourierPhase() { if (fCurrentPlotView == PV_FOURIER_PWR) return; double re, im; const double cp = TMath::Cos(fFourier.fPhaseIncrement/180.0*TMath::Pi()); const double sp = TMath::Sin(fFourier.fPhaseIncrement/180.0*TMath::Pi()); for (UInt_t i=0; iGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fData[i].dataFourierRe->GetBinContent(j) * cp + fData[i].dataFourierIm->GetBinContent(j) * sp; im = fData[i].dataFourierIm->GetBinContent(j) * cp - fData[i].dataFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fData[i].dataFourierRe->SetBinContent(j, re); fData[i].dataFourierIm->SetBinContent(j, im); } } if ((fData[i].theoryFourierRe != nullptr) && (fData[i].theoryFourierIm != nullptr)) { for (Int_t j=0; jGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fData[i].theoryFourierRe->GetBinContent(j) * cp + fData[i].theoryFourierIm->GetBinContent(j) * sp; im = fData[i].theoryFourierIm->GetBinContent(j) * cp - fData[i].theoryFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fData[i].theoryFourierRe->SetBinContent(j, re); fData[i].theoryFourierIm->SetBinContent(j, im); } } if ((fData[i].diffFourierRe != nullptr) && (fData[i].diffFourierIm != nullptr)) { for (Int_t j=0; jGetNbinsX(); j++) { // loop over a fourier diff data set // calculate new fourier diff data set value re = fData[i].diffFourierRe->GetBinContent(j) * cp + fData[i].diffFourierIm->GetBinContent(j) * sp; im = fData[i].diffFourierIm->GetBinContent(j) * cp - fData[i].diffFourierRe->GetBinContent(j) * sp; // overwrite fourier diff data set value fData[i].diffFourierRe->SetBinContent(j, re); fData[i].diffFourierIm->SetBinContent(j, im); } } } } //-------------------------------------------------------------------------- // DecrementFourierPhase (private) //-------------------------------------------------------------------------- /** *

Decrements the Fourier phase and recalculate the real/imaginary part of the Fourier transform. */ void PMusrCanvas::DecrementFourierPhase() { if (fCurrentPlotView == PV_FOURIER_PWR) return; double re, im; const double cp = TMath::Cos(fFourier.fPhaseIncrement/180.0*TMath::Pi()); const double sp = TMath::Sin(fFourier.fPhaseIncrement/180.0*TMath::Pi()); for (UInt_t i=0; iGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fData[i].dataFourierRe->GetBinContent(j) * cp - fData[i].dataFourierIm->GetBinContent(j) * sp; im = fData[i].dataFourierIm->GetBinContent(j) * cp + fData[i].dataFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fData[i].dataFourierRe->SetBinContent(j, re); fData[i].dataFourierIm->SetBinContent(j, im); } } if ((fData[i].theoryFourierRe != nullptr) && (fData[i].theoryFourierIm != nullptr)) { for (Int_t j=0; jGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fData[i].theoryFourierRe->GetBinContent(j) * cp - fData[i].theoryFourierIm->GetBinContent(j) * sp; im = fData[i].theoryFourierIm->GetBinContent(j) * cp + fData[i].theoryFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fData[i].theoryFourierRe->SetBinContent(j, re); fData[i].theoryFourierIm->SetBinContent(j, im); } } if ((fData[i].diffFourierRe != nullptr) && (fData[i].diffFourierIm != nullptr)) { for (Int_t j=0; jGetNbinsX(); j++) { // loop over a fourier diff data set // calculate new fourier diff data set value re = fData[i].diffFourierRe->GetBinContent(j) * cp - fData[i].diffFourierIm->GetBinContent(j) * sp; im = fData[i].diffFourierIm->GetBinContent(j) * cp + fData[i].diffFourierRe->GetBinContent(j) * sp; // overwrite fourier diff data set value fData[i].diffFourierRe->SetBinContent(j, re); fData[i].diffFourierIm->SetBinContent(j, im); } } } } //-------------------------------------------------------------------------- // IsScaleN0AndBkg (private) //-------------------------------------------------------------------------- /** *

Checks if N0/Bkg normalization to 1/ns is whished. The default is yes, since most of the users want to have it that way. * To overwrite this, one should add the line 'SCALE_N0_BKG FALSE' to the command block of the msr-file. * * return: * - true, if scaling of N0 and Bkg to 1/ns is whished * - false, otherwise * * \param histoNo forward histogram number of the run */ Bool_t PMusrCanvas::IsScaleN0AndBkg() { Bool_t willScale = true; PMsrLines *cmd = fMsrHandler->GetMsrCommands(); for (UInt_t i=0; isize(); i++) { if (cmd->at(i).fLine.Contains("SCALE_N0_BKG", TString::kIgnoreCase)) { TObjArray *tokens = nullptr; TObjString *ostr = nullptr; TString str; tokens = cmd->at(i).fLine.Tokenize(" \t"); if (tokens->GetEntries() != 2) { std::cerr << std::endl << ">> PRunSingleHisto::IsScaleN0AndBkg(): **WARNING** Found uncorrect 'SCALE_N0_BKG' command, will ignore it."; std::cerr << std::endl << ">> Allowed commands: SCALE_N0_BKG TRUE | FALSE" << std::endl; return willScale; } ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (!str.CompareTo("FALSE", TString::kIgnoreCase)) { willScale = false; } // clean up if (tokens) delete tokens; } } return willScale; } //-------------------------------------------------------------------------- // GetNeededAccuracy (private) //-------------------------------------------------------------------------- /** *

Calculates the needed accuracy of the parameter value based on the given errors. * * return: * - needed accuracy * * \param param fit parameter with its additional informations, like errors etc. */ UInt_t PMusrCanvas::GetNeededAccuracy(PMsrParamStructure param) { const UInt_t precLimit = 6; UInt_t decimalPoint = 0; UInt_t accuracy = 6; if (param.fStep == 0.0) { // check if fit parameter is a constant, i.e. step==0 char str[128]; sprintf(str, "%lf", param.fValue); // find decimal point for (UInt_t i=0; i=0; i--) { if (str[i] != '0') { if (((UInt_t)i-decimalPoint) < precLimit) accuracy = (UInt_t)i-decimalPoint; else accuracy = precLimit; break; } } } else if ((param.fStep != 0) && !param.fPosErrorPresent) { // check if no positive error is given step!=0 but fPosErrorPresent==false for (UInt_t i=0; i accuracy) accuracy = accuracy2; if (accuracy+1 <= precLimit) accuracy += 1; } return accuracy; } //-------------------------------------------------------------------------- // GetInterpolatedValue (private) //-------------------------------------------------------------------------- /** *

search for xVal in histo. If xVal is not found exactly, interpolate and * return the interpolated y-value. * * return: * - interpolated value if xVal is within histo range, 0 otherwise. * * \param histo pointer of the histogram * \param xVal x-value to be looked for */ Double_t PMusrCanvas::GetInterpolatedValue(TH1F* histo, Double_t xVal) { if (histo == nullptr) return 0.0; Int_t idx = histo->FindBin(xVal); // make sure idx is within range if ((idx < 1) || (idx > histo->GetNbinsX())) return 0.0; // make sure the lower bound idx is found. This is needed since // FindBin rounds towards the closer idx. if (histo->GetBinCenter(idx) > xVal) --idx; Double_t x0, x1, y0, y1; x0 = histo->GetBinCenter(idx); x1 = histo->GetBinCenter(idx+1); y0 = histo->GetBinContent(idx); y1 = histo->GetBinContent(idx+1); return (y1-y0)*(xVal-x0)/(x1-x0)+y0; }