/*************************************************************************** PFourierCanvas.cpp Author: Andreas Suter e-mail: andreas.suter@psi.ch ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2015 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 using namespace std; #include #include #include #include #include #include #include "PFourierCanvas.h" #define YINFO 0.2 #define YTITLE 0.95 static const char *gFiletypes[] = { "All files", "*", "Data files", "*.dat", 0, 0 }; ClassImpQ(PFourierCanvas) //--------------------------------------------------------------------------- /** *

Constructor */ PFourierCanvas::PFourierCanvas() { fTimeout = 0; fTimeoutTimer = 0; fBatchMode = false; fValid = false; fAveragedView = false; fCurrentPlotView = FOURIER_PLOT_NOT_GIVEN; fInitialXRange[0] = 0.0; fInitialXRange[1] = 0.0; fTitle = TString(""); fXaxisTitle = TString(""); fCurrentFourierPhase = 0.0; fCurrentFourierPhaseText = 0; fStyle = 0; fImp = 0; fBar = 0; fPopupMain = 0; fPopupFourier = 0; fMainCanvas = 0; fTitlePad = 0; fFourierPad = 0; fInfoPad = 0; } //--------------------------------------------------------------------------- /** *

Constructor * * \param fourier * \param title * \param showAverage * \param fourierPlotOpt * \param fourierXrange * \param phase * \param wtopx * \param wtopy * \param ww * \param wh * \param batch */ PFourierCanvas::PFourierCanvas(vector &fourier, const Char_t* title, const Bool_t showAverage, const Int_t fourierPlotOpt, Double_t fourierXrange[], Double_t phase, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh, const Bool_t batch) : fBatchMode(batch), fAveragedView(showAverage), fCurrentPlotView(fourierPlotOpt), fTitle(title), fFourier(fourier), fCurrentFourierPhase(phase) { fInitialXRange[0] = fourierXrange[0]; fInitialXRange[1] = fourierXrange[1]; fTimeout = 0; fTimeoutTimer = 0; fValid = false; fCurrentFourierPhaseText = 0; CreateXaxisTitle(); CreateStyle(); InitFourierDataSets(); InitFourierCanvas(title, wtopx, wtopy, ww, wh); gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling } //--------------------------------------------------------------------------- /** *

Constructor * * \param fourier * \param title * \param showAverage * \param fourierPlotOpt * \param fourierXrange * \param phase * \param wtopx * \param wtopy * \param ww * \param wh * \param markerList * \param colorList * \param batch */ PFourierCanvas::PFourierCanvas(vector &fourier, const Char_t* title, const Bool_t showAverage, const Int_t fourierPlotOpt, Double_t fourierXrange[], Double_t phase, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh, const PIntVector markerList, const PIntVector colorList, const Bool_t batch) : fBatchMode(batch), fAveragedView(showAverage), fCurrentPlotView(fourierPlotOpt), fTitle(title), fFourier(fourier), fCurrentFourierPhase(phase), fMarkerList(markerList), fColorList(colorList) { fInitialXRange[0] = fourierXrange[0]; fInitialXRange[1] = fourierXrange[1]; fTimeout = 0; fTimeoutTimer = 0; fValid = false; fCurrentFourierPhaseText = 0; CreateXaxisTitle(); CreateStyle(); InitFourierDataSets(); InitFourierCanvas(title, wtopx, wtopy, ww, wh); gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling } //--------------------------------------------------------------------------- /** *

Destructor */ PFourierCanvas::~PFourierCanvas() { if (fTimeoutTimer) delete fTimeoutTimer; if (fCurrentFourierPhaseText) delete fCurrentFourierPhaseText; /* if (fStyle) { delete fStyle; fStyle = 0; } */ if (fTitlePad) { fTitlePad->Clear(); delete fTitlePad; fTitlePad = 0; } if (fFourierHistos.size() > 0) { for (unsigned int i=0; iClear(); delete fFourierPad; fFourierPad = 0; } */ if (fInfoPad) { fInfoPad->Clear(); delete fInfoPad; fInfoPad = 0; } /* if (fMainCanvas) { delete fMainCanvas; fMainCanvas = 0; } */ } //-------------------------------------------------------------------------- // Done (SIGNAL) //-------------------------------------------------------------------------- /** *

Signal emitted that the user wants to terminate the application. * * \param status Status info */ void PFourierCanvas::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 * - 'u' unzoom to the original plot range given in the msr-file. * - 'a' toggle between average view and single Fourier histo 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 PFourierCanvas::HandleCmdKey(Int_t event, Int_t x, Int_t y, TObject *selected) { if (event != kKeyPress) return; if (fBatchMode) return; if (x == 'q') { // quit Done(0); } else if (x == 'u') { // unzoom if (fAveragedView) PlotAverage(); else PlotFourier(); } else if (x == 'a') { // toggle between average view and single histo view // toggle average view flag fAveragedView = !fAveragedView; // update menu if (fAveragedView) { fPopupMain->CheckEntry(P_MENU_ID_AVERAGE); HandleAverage(); PlotAverage(); } else { fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE); CleanupAverage(); PlotFourier(); } } else if (x == '+') { // increment phase (Fourier real/imag) IncrementFourierPhase(); } else if (x == '-') { // decrement phase (Fourier real/imag) DecrementFourierPhase(); } } //-------------------------------------------------------------------------- // HandleMenuPopup (SLOT) //-------------------------------------------------------------------------- /** *

Handles the MusrFT menu. * * \param id identification key of the selected menu */ void PFourierCanvas::HandleMenuPopup(Int_t id) { if (fBatchMode) return; if (id == P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_REAL) { // uncheck fourier popup items fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_REAL); fCurrentPlotView = FOURIER_PLOT_REAL; PlotFourier(); } else if (id == P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_IMAG) { fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_IMAG); fCurrentPlotView = FOURIER_PLOT_IMAG; PlotFourier(); } else if (id == P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_REAL_AND_IMAG) { fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_REAL_AND_IMAG); fCurrentPlotView = P_MENU_ID_FOURIER_REAL_AND_IMAG; PlotFourier(); } else if (id == P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PWR) { fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PWR); fCurrentPlotView = FOURIER_PLOT_POWER; PlotFourier(); } else if (id == P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE) { fPopupFourier->UnCheckEntries(); fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE); fCurrentPlotView = FOURIER_PLOT_PHASE; PlotFourier(); } else if (id == P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_PLUS) { IncrementFourierPhase(); } else if (id == P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_MINUS) { DecrementFourierPhase(); } else if (id == P_MENU_ID_AVERAGE) { // toggle average view flag fAveragedView = !fAveragedView; // update menu if (fAveragedView) { fPopupMain->CheckEntry(P_MENU_ID_AVERAGE); HandleAverage(); PlotAverage(); } else { fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE); CleanupAverage(); PlotFourier(); } } else if (id == P_MENU_ID_EXPORT_DATA) { 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); } } } //-------------------------------------------------------------------------- // LastCanvasClosed (SLOT) //-------------------------------------------------------------------------- /** *

Slot called when the last canvas has been closed. Will emit Done(0) which will * terminate the application. */ void PFourierCanvas::LastCanvasClosed() { if (gROOT->GetListOfCanvases()->IsEmpty()) { Done(0); } } //-------------------------------------------------------------------------- // UpdateFourierPad (public) //-------------------------------------------------------------------------- /** *

Feeds the pad with the Fourier data sets and refreshes it. */ void PFourierCanvas::UpdateFourierPad() { if (!fValid) return; if (fAveragedView) PlotAverage(); else PlotFourier(); fFourierPad->Draw(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // UpdateInfoPad (public) //-------------------------------------------------------------------------- /** *

Feeds the pad with the legend and refreshes it. */ void PFourierCanvas::UpdateInfoPad() { if (!fValid) return; // write header line TDatime dt; char dtStr[128]; strncpy(dtStr, dt.AsSQLString(), sizeof(dtStr)); TString str("musrFT: "); str += dtStr; fInfoPad->SetHeader(str); char title[1024]; for (unsigned int i=0; iGetDataTitle(), sizeof(title)); // add entry fInfoPad->AddEntry(fFourierHistos[i].dataFourierRe, title, "p"); } fInfoPad->Draw(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // SetTimeout (public) //-------------------------------------------------------------------------- /** *

sets the timeout after which the program shall terminate. * * \param timeout after which the done signal shall be emitted. Given in seconds */ void PFourierCanvas::SetTimeout(Int_t timeout) { fTimeout = timeout; if (fTimeout <= 0) return; if (fTimeoutTimer) { delete fTimeoutTimer; fTimeoutTimer = 0; } fTimeoutTimer = new TTimer(); fTimeoutTimer->Connect("Timeout()", "PFourierCanvas", this, "Done()"); fTimeoutTimer->Start(1000*fTimeout, kTRUE); } //-------------------------------------------------------------------------- // 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. */ void PFourierCanvas::SaveGraphicsAndQuit(const Char_t *fileName) { cout << endl << ">> SaveGraphicsAndQuit: will dump the canvas into a graphics output file: " << fileName << " ..." << endl; fMainCanvas->SaveAs(fileName); Done(0); } //-------------------------------------------------------------------------- // ExportData //-------------------------------------------------------------------------- /** *

Exports the currently displayed Fourier data set in ascii column format. */ void PFourierCanvas::ExportData(const Char_t *pathFileName) { TString pfn(""); if (pathFileName) { // path file name provided pfn = TString(pathFileName); } else { // path file name NOT provided, generate a default path file name cerr << endl << ">> PFourierCanvas::ExportData **ERROR** NO path file name provided. Will do nothing." << endl; return; } TString xAxis(""), yAxis(""); Int_t xMinBin, xMaxBin; if (fAveragedView) { switch (fCurrentPlotView) { case FOURIER_PLOT_REAL: xAxis = fFourierHistos[0].dataFourierRe->GetXaxis()->GetTitle(); yAxis = TString(""); xMinBin = fFourierHistos[0].dataFourierRe->GetXaxis()->GetFirst(); xMaxBin = fFourierHistos[0].dataFourierRe->GetXaxis()->GetLast(); break; case FOURIER_PLOT_IMAG: xAxis = fFourierHistos[0].dataFourierIm->GetXaxis()->GetTitle(); yAxis = TString(""); xMinBin = fFourierHistos[0].dataFourierIm->GetXaxis()->GetFirst(); xMaxBin = fFourierHistos[0].dataFourierIm->GetXaxis()->GetLast(); break; case FOURIER_PLOT_POWER: xAxis = fFourierHistos[0].dataFourierPwr->GetXaxis()->GetTitle(); yAxis = TString(""); xMinBin = fFourierHistos[0].dataFourierPwr->GetXaxis()->GetFirst(); xMaxBin = fFourierHistos[0].dataFourierPwr->GetXaxis()->GetLast(); break; case FOURIER_PLOT_PHASE: xAxis = fFourierHistos[0].dataFourierPhase->GetXaxis()->GetTitle(); yAxis = TString(""); xMinBin = fFourierHistos[0].dataFourierPhase->GetXaxis()->GetFirst(); xMaxBin = fFourierHistos[0].dataFourierPhase->GetXaxis()->GetLast(); break; default: xAxis = TString("??"); yAxis = TString("??"); xMinBin = 0; xMaxBin = 0; break; } } else { switch (fCurrentPlotView) { case FOURIER_PLOT_REAL: xAxis = fFourierHistos[0].dataFourierRe->GetXaxis()->GetTitle(); yAxis = TString("Real"); xMinBin = fFourierHistos[0].dataFourierRe->GetXaxis()->GetFirst(); xMaxBin = fFourierHistos[0].dataFourierRe->GetXaxis()->GetLast(); break; case FOURIER_PLOT_IMAG: xAxis = fFourierHistos[0].dataFourierIm->GetXaxis()->GetTitle(); yAxis = TString("Imag"); xMinBin = fFourierHistos[0].dataFourierIm->GetXaxis()->GetFirst(); xMaxBin = fFourierHistos[0].dataFourierIm->GetXaxis()->GetLast(); break; case FOURIER_PLOT_POWER: xAxis = fFourierHistos[0].dataFourierPwr->GetXaxis()->GetTitle(); yAxis = TString("Power"); xMinBin = fFourierHistos[0].dataFourierPwr->GetXaxis()->GetFirst(); xMaxBin = fFourierHistos[0].dataFourierPwr->GetXaxis()->GetLast(); break; case FOURIER_PLOT_PHASE: xAxis = fFourierHistos[0].dataFourierPhase->GetXaxis()->GetTitle(); yAxis = TString("Phase"); xMinBin = fFourierHistos[0].dataFourierPhase->GetXaxis()->GetFirst(); xMaxBin = fFourierHistos[0].dataFourierPhase->GetXaxis()->GetLast(); break; default: xAxis = TString("??"); yAxis = TString("??"); xMinBin = 0; xMaxBin = 0; break; } } // write data to file ofstream fout(pfn.Data(), ofstream::out); if (fAveragedView) { // write header fout << "% " << pfn << endl; fout << "% averaged data of:" << endl; for (unsigned int i=0; iGetTitle() << endl; } fout << "%------------" << endl; fout << "% " << xAxis << ", " << yAxis << endl; for (int i=xMinBin; iGetBinCenter(i) << ", " << fFourierAverage.dataFourierRe->GetBinContent(i) << endl; break; case FOURIER_PLOT_IMAG: fout << fFourierAverage.dataFourierIm->GetBinCenter(i) << ", " << fFourierAverage.dataFourierIm->GetBinContent(i) << endl; break; case FOURIER_PLOT_POWER: fout << fFourierAverage.dataFourierPwr->GetBinCenter(i) << ", " << fFourierAverage.dataFourierPwr->GetBinContent(i) << endl; break; case FOURIER_PLOT_PHASE: fout << fFourierAverage.dataFourierPhase->GetBinCenter(i) << ", " << fFourierAverage.dataFourierPhase->GetBinContent(i) << endl; break; default: break; } } } else { // write header fout << "% " << pfn << endl; fout << "% data of:" << endl; for (unsigned int i=0; iGetTitle() << endl; } fout << "%------------" << endl; fout << "% "; for (unsigned int i=0; iGetBinCenter(i) << ", " << fFourierHistos[j].dataFourierRe->GetBinContent(i) << ", "; break; case FOURIER_PLOT_IMAG: fout << fFourierHistos[j].dataFourierIm->GetBinCenter(i) << ", " << fFourierHistos[j].dataFourierIm->GetBinContent(i) << ", "; break; case FOURIER_PLOT_POWER: fout << fFourierHistos[j].dataFourierPwr->GetBinCenter(i) << ", " << fFourierHistos[j].dataFourierPwr->GetBinContent(i) << ", "; break; case FOURIER_PLOT_PHASE: fout << fFourierHistos[j].dataFourierPhase->GetBinCenter(i) << ", " << fFourierHistos[j].dataFourierPhase->GetBinContent(i) << ", "; break; default: break; } } switch (fCurrentPlotView) { case FOURIER_PLOT_REAL: fout << fFourierHistos[fFourierHistos.size()-1].dataFourierRe->GetBinCenter(i) << ", " << fFourierHistos[fFourierHistos.size()-1].dataFourierRe->GetBinContent(i) << endl; break; case FOURIER_PLOT_IMAG: fout << fFourierHistos[fFourierHistos.size()-1].dataFourierIm->GetBinCenter(i) << ", " << fFourierHistos[fFourierHistos.size()-1].dataFourierIm->GetBinContent(i) << endl; break; case FOURIER_PLOT_POWER: fout << fFourierHistos[fFourierHistos.size()-1].dataFourierPwr->GetBinCenter(i) << ", " << fFourierHistos[fFourierHistos.size()-1].dataFourierPwr->GetBinContent(i) << endl; break; case FOURIER_PLOT_PHASE: fout << fFourierHistos[fFourierHistos.size()-1].dataFourierPhase->GetBinCenter(i) << ", " << fFourierHistos[fFourierHistos.size()-1].dataFourierPhase->GetBinContent(i) << endl; break; default: break; } } } fout.close(); } //-------------------------------------------------------------------------- // CreateXaxisTitle (private) //-------------------------------------------------------------------------- /** *

Creates the x-axis title based on the Fourier units used. */ void PFourierCanvas::CreateXaxisTitle() { switch (fFourier[0]->GetUnitTag()) { case FOURIER_UNIT_GAUSS: fXaxisTitle = TString("Field (Gauss)"); break; case FOURIER_UNIT_TESLA: fXaxisTitle = TString("Field (Tesla)"); break; case FOURIER_UNIT_FREQ: fXaxisTitle = TString("Frequency (MHz)"); break; case FOURIER_UNIT_CYCLES: fXaxisTitle = TString("Angular Frequency (Mc/s)"); break; default: fXaxisTitle = TString("??"); break; } } //-------------------------------------------------------------------------- // CreateStyle (private) //-------------------------------------------------------------------------- /** *

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

Initialize the Fourier data sets, i.e. get the TH1F objects, set markers, * set colors, ... */ void PFourierCanvas::InitFourierDataSets() { // get all the Fourier histos fFourierHistos.resize(fFourier.size()); for (unsigned int i=0; iGetRealFourier(); fFourierHistos[i].dataFourierIm = fFourier[i]->GetImaginaryFourier(); fFourierHistos[i].dataFourierPwr = fFourier[i]->GetPowerFourier(); fFourierHistos[i].dataFourierPhase = fFourier[i]->GetPhaseFourier(); } // rescale histo to abs(maximum) == 1 Double_t max = 0.0, dval = 0.0; Int_t start = fFourierHistos[0].dataFourierRe->FindBin(fInitialXRange[0]); Int_t end = fFourierHistos[0].dataFourierRe->FindBin(fInitialXRange[1]); // real for (unsigned int i=0; iGetBinContent(j); if (fabs(dval) > max) max = dval; } } for (unsigned int i=0; iGetNbinsX(); j++) { fFourierHistos[i].dataFourierRe->SetBinContent(j, fFourierHistos[i].dataFourierRe->GetBinContent(j)/fabs(max)); } } // imaginary for (unsigned int i=0; iGetBinContent(j); if (fabs(dval) > max) max = dval; } } for (unsigned int i=0; iGetNbinsX(); j++) { fFourierHistos[i].dataFourierIm->SetBinContent(j, fFourierHistos[i].dataFourierIm->GetBinContent(j)/fabs(max)); } } // power max = 0.0; for (unsigned int i=0; iGetBinContent(j); if (fabs(dval) > max) max = dval; } } for (unsigned int i=0; iGetNbinsX(); j++) { fFourierHistos[i].dataFourierPwr->SetBinContent(j, fFourierHistos[i].dataFourierPwr->GetBinContent(j)/fabs(max)); } } // phase max = 0.0; for (unsigned int i=0; iGetBinContent(j); if (fabs(dval) > max) max = dval; } } for (unsigned int i=0; iGetNbinsX(); j++) { fFourierHistos[i].dataFourierPhase->SetBinContent(j, fFourierHistos[i].dataFourierPhase->GetBinContent(j)/fabs(max)); } } // set the marker and line color for (unsigned int i=0; iSetMarkerColor(fColorList[i]); fFourierHistos[i].dataFourierRe->SetLineColor(fColorList[i]); fFourierHistos[i].dataFourierIm->SetMarkerColor(fColorList[i]); fFourierHistos[i].dataFourierIm->SetLineColor(fColorList[i]); fFourierHistos[i].dataFourierPwr->SetMarkerColor(fColorList[i]); fFourierHistos[i].dataFourierPwr->SetLineColor(fColorList[i]); fFourierHistos[i].dataFourierPhase->SetMarkerColor(fColorList[i]); fFourierHistos[i].dataFourierPhase->SetLineColor(fColorList[i]); } else { TRandom rand(i); Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); fFourierHistos[i].dataFourierRe->SetMarkerColor(color); fFourierHistos[i].dataFourierRe->SetLineColor(color); fFourierHistos[i].dataFourierIm->SetMarkerColor(color); fFourierHistos[i].dataFourierIm->SetLineColor(color); fFourierHistos[i].dataFourierPwr->SetMarkerColor(color); fFourierHistos[i].dataFourierPwr->SetLineColor(color); fFourierHistos[i].dataFourierPhase->SetMarkerColor(color); fFourierHistos[i].dataFourierPhase->SetLineColor(color); } } // set the marker symbol and size Int_t style; for (unsigned int i=0; iSetMarkerStyle(fMarkerList[i]); fFourierHistos[i].dataFourierRe->SetMarkerSize(0.7); fFourierHistos[i].dataFourierIm->SetMarkerStyle(fMarkerList[i]); fFourierHistos[i].dataFourierIm->SetMarkerSize(0.7); fFourierHistos[i].dataFourierPwr->SetMarkerStyle(fMarkerList[i]); fFourierHistos[i].dataFourierPwr->SetMarkerSize(0.7); fFourierHistos[i].dataFourierPhase->SetMarkerStyle(fMarkerList[i]); fFourierHistos[i].dataFourierPhase->SetMarkerSize(0.7); } else { TRandom rand(i); style = 20+(Int_t)rand.Integer(10); fFourierHistos[i].dataFourierRe->SetMarkerStyle(style); fFourierHistos[i].dataFourierRe->SetMarkerSize(0.7); fFourierHistos[i].dataFourierIm->SetMarkerStyle(style); fFourierHistos[i].dataFourierIm->SetMarkerSize(0.7); fFourierHistos[i].dataFourierPwr->SetMarkerStyle(style); fFourierHistos[i].dataFourierPwr->SetMarkerSize(0.7); fFourierHistos[i].dataFourierPhase->SetMarkerStyle(style); fFourierHistos[i].dataFourierPhase->SetMarkerSize(0.7); } } // initialize average histos fFourierAverage.dataFourierRe = 0; fFourierAverage.dataFourierIm = 0; fFourierAverage.dataFourierPwr = 0; fFourierAverage.dataFourierPhase = 0; } //-------------------------------------------------------------------------- // InitFourierCanvas (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 PFourierCanvas::InitFourierCanvas(const Char_t* title, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh) { fImp = 0; fBar = 0; fPopupMain = 0; fPopupFourier = 0; fMainCanvas = 0; fTitlePad = 0; fFourierPad = 0; fInfoPad = 0; // invoke canvas TString canvasName = TString("fMainCanvas"); fMainCanvas = new TCanvas(canvasName.Data(), title, wtopx, wtopy, ww, wh); if (fMainCanvas == 0) { cerr << endl << "PFourierCanvas::PFourierCanvas: **PANIC ERROR**: Couldn't invoke " << canvasName.Data(); cerr << endl; return; } // add canvas menu if not in batch mode if (!fBatchMode) { fImp = (TRootCanvas*)fMainCanvas->GetCanvasImp(); fBar = fImp->GetMenuBar(); fPopupMain = fBar->AddPopup("&MusrFT"); fPopupFourier = new TGPopupMenu(); fPopupMain->AddPopup("&Fourier", fPopupFourier); fPopupFourier->AddEntry("Show Real", P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_REAL); fPopupFourier->AddEntry("Show Imag", P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_IMAG); fPopupFourier->AddEntry("Show Real+Imag", P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_REAL_AND_IMAG); fPopupFourier->AddEntry("Show Power", P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PWR); fPopupFourier->AddEntry("Show Phase", P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE); fPopupFourier->AddSeparator(); fPopupFourier->AddEntry("Phase +", P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->AddEntry("Phase -", P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_MINUS); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_PLUS); fPopupFourier->DisableEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_MINUS); switch (fCurrentPlotView) { case FOURIER_PLOT_REAL: fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_REAL); break; case FOURIER_PLOT_IMAG: fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_IMAG); break; case FOURIER_PLOT_REAL_AND_IMAG: fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_REAL_AND_IMAG); break; case FOURIER_PLOT_POWER: fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PWR); break; case FOURIER_PLOT_PHASE: fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE); break; default: break; } fPopupMain->AddEntry("Average", P_MENU_ID_AVERAGE); if (fAveragedView) fPopupMain->CheckEntry(P_MENU_ID_AVERAGE); fPopupMain->AddSeparator(); fPopupMain->AddEntry("Export Data", P_MENU_ID_EXPORT_DATA); fBar->MapSubwindows(); fBar->Layout(); fPopupMain->Connect("TGPopupMenu", "Activated(Int_t)", "PFourierCanvas", this, "HandleMenuPopup(Int_t)"); } // divide the canvas into sub pads // title pad fTitlePad = new TPaveText(0.0, YTITLE, 1.0, 1.0, "NDC"); if (fTitlePad == 0) { cerr << endl << "PFourierCanvas::PFourierCanvas: **PANIC ERROR**: Couldn't invoke fTitlePad"; cerr << endl; return; } fTitlePad->SetFillColor(TColor::GetColor(255,255,255)); fTitlePad->SetTextAlign(12); // middle, left fTitlePad->AddText(title); fTitlePad->Draw(); // fourier pad fFourierPad = new TPad("fourierPad", "fourierPad", 0.0, YINFO, 1.0, YTITLE); if (fFourierPad == 0) { cerr << endl << "PFourierCanvas::PFourierCanvas: **PANIC ERROR**: Couldn't invoke fFourierPad"; cerr << endl; return; } fFourierPad->SetFillColor(TColor::GetColor(255,255,255)); fFourierPad->Draw(); // info pad fInfoPad = new TLegend(0.0, 0.0, 1.0, YINFO, "NDC"); if (fInfoPad == 0) { cerr << endl << "PFourierCanvas::PFourierCanvas: **PANIC ERROR**: Couldn't invoke fInfoPad"; cerr << 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*)", "PFourierCanvas", this, "HandleCmdKey(Int_t,Int_t,Int_t,TObject*)"); } //-------------------------------------------------------------------------- // CleanupAverage (private) //-------------------------------------------------------------------------- /** *

Cleanup average Fourier data sets. */ void PFourierCanvas::CleanupAverage() { if (fFourierAverage.dataFourierRe != 0) { delete fFourierAverage.dataFourierRe; fFourierAverage.dataFourierRe = 0; } if (fFourierAverage.dataFourierIm) { delete fFourierAverage.dataFourierIm; fFourierAverage.dataFourierIm = 0; } if (fFourierAverage.dataFourierPwr) { delete fFourierAverage.dataFourierPwr; fFourierAverage.dataFourierPwr = 0; } if (fFourierAverage.dataFourierPhase) { delete fFourierAverage.dataFourierPhase; fFourierAverage.dataFourierPhase = 0; } } //-------------------------------------------------------------------------- // HandleAverage (private) //-------------------------------------------------------------------------- /** *

Average Fourier data sets. */ void PFourierCanvas::HandleAverage() { if (fFourierHistos.size() == 0) return; CleanupAverage(); TString name(""); // create average histograms name = TString(fFourierHistos[0].dataFourierRe->GetTitle()) + "_avg"; fFourierAverage.dataFourierRe = new TH1F(name, name, fFourierHistos[0].dataFourierRe->GetNbinsX(), fFourierHistos[0].dataFourierRe->GetXaxis()->GetXmin(), fFourierHistos[0].dataFourierRe->GetXaxis()->GetXmax()); name = TString(fFourierHistos[0].dataFourierIm->GetTitle()) + "_avg"; fFourierAverage.dataFourierIm = new TH1F(name, name, fFourierHistos[0].dataFourierIm->GetNbinsX(), fFourierHistos[0].dataFourierIm->GetXaxis()->GetXmin(), fFourierHistos[0].dataFourierIm->GetXaxis()->GetXmax()); name = TString(fFourierHistos[0].dataFourierPwr->GetTitle()) + "_avg"; fFourierAverage.dataFourierPwr = new TH1F(name, name, fFourierHistos[0].dataFourierPwr->GetNbinsX(), fFourierHistos[0].dataFourierPwr->GetXaxis()->GetXmin(), fFourierHistos[0].dataFourierPwr->GetXaxis()->GetXmax()); name = TString(fFourierHistos[0].dataFourierPhase->GetTitle()) + "_avg"; fFourierAverage.dataFourierPhase = new TH1F(name, name, fFourierHistos[0].dataFourierPhase->GetNbinsX(), fFourierHistos[0].dataFourierPhase->GetXaxis()->GetXmin(), fFourierHistos[0].dataFourierPhase->GetXaxis()->GetXmax()); Double_t dval=0.0; // real average for (Int_t j=0; jGetNbinsX(); j++) { dval = 0.0; for (unsigned int i=0; iGetNbinsX()) dval += GetInterpolatedValue(fFourierHistos[i].dataFourierRe, fFourierHistos[0].dataFourierRe->GetBinCenter(j)); } fFourierAverage.dataFourierRe->SetBinContent(j, dval/fFourierHistos.size()); } // set marker color, line color, maker size, marker type fFourierAverage.dataFourierRe->SetMarkerColor(kBlack); fFourierAverage.dataFourierRe->SetLineColor(kBlack); fFourierAverage.dataFourierRe->SetMarkerSize(0.8); fFourierAverage.dataFourierRe->SetMarkerStyle(22); // closed up triangle // imaginary average for (Int_t j=0; jGetNbinsX(); j++) { dval = 0.0; for (unsigned int i=0; iGetNbinsX()) dval += GetInterpolatedValue(fFourierHistos[i].dataFourierIm, fFourierHistos[0].dataFourierIm->GetBinCenter(j)); } fFourierAverage.dataFourierIm->SetBinContent(j, dval/fFourierHistos.size()); } // set marker color, line color, maker size, marker type fFourierAverage.dataFourierIm->SetMarkerColor(kBlack); fFourierAverage.dataFourierIm->SetLineColor(kBlack); fFourierAverage.dataFourierIm->SetMarkerSize(0.8); fFourierAverage.dataFourierIm->SetMarkerStyle(22); // closed up triangle // power average for (Int_t j=0; jGetNbinsX(); j++) { dval = 0.0; for (unsigned int i=0; iGetNbinsX()) dval += GetInterpolatedValue(fFourierHistos[i].dataFourierPwr, fFourierHistos[0].dataFourierPwr->GetBinCenter(j)); } fFourierAverage.dataFourierPwr->SetBinContent(j, dval/fFourierHistos.size()); } // set marker color, line color, maker size, marker type fFourierAverage.dataFourierPwr->SetMarkerColor(kBlack); fFourierAverage.dataFourierPwr->SetLineColor(kBlack); fFourierAverage.dataFourierPwr->SetMarkerSize(0.8); fFourierAverage.dataFourierPwr->SetMarkerStyle(22); // closed up triangle // phase average for (Int_t j=0; jGetNbinsX(); j++) { dval = 0.0; for (unsigned int i=0; iGetNbinsX()) dval += GetInterpolatedValue(fFourierHistos[i].dataFourierPhase, fFourierHistos[0].dataFourierPhase->GetBinCenter(j)); } fFourierAverage.dataFourierPhase->SetBinContent(j, dval/fFourierHistos.size()); } // set marker color, line color, maker size, marker type fFourierAverage.dataFourierPhase->SetMarkerColor(kBlack); fFourierAverage.dataFourierPhase->SetLineColor(kBlack); fFourierAverage.dataFourierPhase->SetMarkerSize(0.8); fFourierAverage.dataFourierPhase->SetMarkerStyle(22); } //-------------------------------------------------------------------------- // PlotFourier (private) //-------------------------------------------------------------------------- /** *

Plot the Fourier spectra. */ void PFourierCanvas::PlotFourier() { fFourierPad->cd(); Double_t xmin=0, xmax=0; xmin = fInitialXRange[0]; xmax = fInitialXRange[1]; Double_t ymin=0, ymax=0; switch (fCurrentPlotView) { case FOURIER_PLOT_REAL: fFourierHistos[0].dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax); ymin = GetMinimum(fFourierHistos[0].dataFourierRe, xmin, xmax); ymax = GetMaximum(fFourierHistos[0].dataFourierRe, xmin, xmax); for (unsigned int i=1; i ymax) ymax = GetMaximum(fFourierHistos[i].dataFourierRe, xmin, xmax); if (GetMinimum(fFourierHistos[i].dataFourierRe, xmin, xmax) < ymin) ymin = GetMinimum(fFourierHistos[i].dataFourierRe, xmin, xmax); } fFourierHistos[0].dataFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fFourierHistos[0].dataFourierRe->GetYaxis()->SetTitle("Real"); fFourierHistos[0].dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierHistos[0].dataFourierRe->Draw("p"); for (unsigned int i=1; iDraw("psame"); } break; case FOURIER_PLOT_IMAG: fFourierHistos[0].dataFourierIm->GetXaxis()->SetRangeUser(xmin, xmax); ymin = GetMinimum(fFourierHistos[0].dataFourierIm, xmin, xmax); ymax = GetMaximum(fFourierHistos[0].dataFourierIm, xmin, xmax); for (unsigned int i=1; i ymax) ymax = GetMaximum(fFourierHistos[i].dataFourierIm, xmin, xmax); if (GetMinimum(fFourierHistos[i].dataFourierIm, xmin, xmax) < ymin) ymin = GetMinimum(fFourierHistos[i].dataFourierIm, xmin, xmax); } fFourierHistos[0].dataFourierIm->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fFourierHistos[0].dataFourierIm->GetYaxis()->SetTitle("Imag"); fFourierHistos[0].dataFourierIm->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierHistos[0].dataFourierIm->Draw("p"); for (unsigned int i=1; iDraw("psame"); } break; case FOURIER_PLOT_REAL_AND_IMAG: fFourierHistos[0].dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax); ymin = GetMinimum(fFourierHistos[0].dataFourierRe, xmin, xmax); ymax = GetMaximum(fFourierHistos[0].dataFourierRe, xmin, xmax); for (unsigned int i=1; i ymax) ymax = GetMaximum(fFourierHistos[i].dataFourierRe, xmin, xmax); if (GetMaximum(fFourierHistos[i].dataFourierIm, xmin, xmax) > ymax) ymax = GetMaximum(fFourierHistos[i].dataFourierIm, xmin, xmax); if (GetMinimum(fFourierHistos[i].dataFourierRe, xmin, xmax) < ymin) ymin = GetMinimum(fFourierHistos[i].dataFourierRe, xmin, xmax); if (GetMinimum(fFourierHistos[i].dataFourierIm, xmin, xmax) < ymin) ymin = GetMinimum(fFourierHistos[i].dataFourierIm, xmin, xmax); } fFourierHistos[0].dataFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fFourierHistos[0].dataFourierRe->GetYaxis()->SetTitle("Real"); fFourierHistos[0].dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierHistos[0].dataFourierRe->Draw("p"); for (unsigned int i=1; iDraw("psame"); } for (unsigned int i=0; iDraw("psame"); } break; case FOURIER_PLOT_POWER: // get maximum of Fourier data in the range fFourierHistos[0].dataFourierPwr->GetXaxis()->SetRangeUser(xmin, xmax); ymin = 0.0; ymax = GetMaximum(fFourierHistos[0].dataFourierPwr, xmin, xmax); for (unsigned int i=1; i ymax) ymax = GetMaximum(fFourierHistos[i].dataFourierPwr, xmin, xmax); } fFourierHistos[0].dataFourierPwr->GetYaxis()->SetRangeUser(ymin, 1.03*ymax); fFourierHistos[0].dataFourierPwr->GetYaxis()->SetTitle("Power"); fFourierHistos[0].dataFourierPwr->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierHistos[0].dataFourierPwr->Draw("p"); for (unsigned int i=1; iDraw("psame"); } break; case FOURIER_PLOT_PHASE: fFourierHistos[0].dataFourierPhase->GetXaxis()->SetRangeUser(xmin, xmax); ymin = GetMinimum(fFourierHistos[0].dataFourierPhase, xmin, xmax); ymax = GetMaximum(fFourierHistos[0].dataFourierPhase, xmin, xmax); for (unsigned int i=1; i ymax) ymax = GetMaximum(fFourierHistos[i].dataFourierPhase, xmin, xmax); if (GetMinimum(fFourierHistos[i].dataFourierPhase, xmin, xmax) < ymin) ymin = GetMinimum(fFourierHistos[i].dataFourierPhase, xmin, xmax); } fFourierHistos[0].dataFourierRe->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax); fFourierHistos[0].dataFourierPhase->GetYaxis()->SetTitle("Phase"); fFourierHistos[0].dataFourierPhase->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierHistos[0].dataFourierPhase->Draw("p"); for (unsigned int i=1; iDraw("psame"); } break; default: break; } fFourierPad->Update(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // PlotFourierPhaseValue (private) //-------------------------------------------------------------------------- /** *

Writes the Fourier phase value into the data window. */ void PFourierCanvas::PlotFourierPhaseValue() { // check if phase TLatex object is present if (fCurrentFourierPhaseText) { delete fCurrentFourierPhaseText; fCurrentFourierPhaseText = 0; } double x, y; TString str; // plot Fourier phase str = TString("phase = "); str += fCurrentFourierPhase; 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); fFourierPad->cd(); fCurrentFourierPhaseText->Draw(); fFourierPad->Update(); } //-------------------------------------------------------------------------- // PlotAverage (private) //-------------------------------------------------------------------------- /** *

Plot the average of the given Fourier data sets. */ void PFourierCanvas::PlotAverage() { fFourierPad->cd(); if (fFourierAverage.dataFourierRe == 0) { // ups, HandlerAverage never called! HandleAverage(); } Double_t xmin=0, xmax=0; xmin = fInitialXRange[0]; xmax = fInitialXRange[1]; switch (fCurrentPlotView) { case FOURIER_PLOT_REAL: fFourierAverage.dataFourierRe->GetYaxis()->SetTitle(""); fFourierAverage.dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierAverage.dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax); fFourierAverage.dataFourierRe->Draw("p"); break; case FOURIER_PLOT_IMAG: fFourierAverage.dataFourierIm->GetYaxis()->SetTitle(""); fFourierAverage.dataFourierIm->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierAverage.dataFourierIm->GetXaxis()->SetRangeUser(xmin, xmax); fFourierAverage.dataFourierIm->Draw("p"); break; case FOURIER_PLOT_REAL_AND_IMAG: fFourierAverage.dataFourierRe->GetYaxis()->SetTitle(""); fFourierAverage.dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierAverage.dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax); fFourierAverage.dataFourierRe->Draw("p"); fFourierAverage.dataFourierIm->Draw("psame"); break; case FOURIER_PLOT_POWER: // get maximum of Fourier data in the range fFourierAverage.dataFourierPwr->GetXaxis()->SetRangeUser(xmin, xmax); fFourierAverage.dataFourierPwr->GetYaxis()->SetTitle(""); fFourierAverage.dataFourierPwr->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierAverage.dataFourierPwr->Draw("p"); break; case FOURIER_PLOT_PHASE: fFourierAverage.dataFourierPhase->GetYaxis()->SetTitle(""); fFourierAverage.dataFourierPhase->GetXaxis()->SetTitle(fXaxisTitle.Data()); fFourierAverage.dataFourierPhase->GetXaxis()->SetRangeUser(xmin, xmax); fFourierAverage.dataFourierPhase->Draw("p"); break; default: break; } fFourierPad->Update(); fMainCanvas->cd(); fMainCanvas->Update(); } //-------------------------------------------------------------------------- // IncrementFourierPhase (private) //-------------------------------------------------------------------------- /** *

Increments the Fourier phase and recalculate the real/imaginary part of the Fourier transform. */ void PFourierCanvas::IncrementFourierPhase() { if ((fCurrentPlotView == FOURIER_PLOT_POWER) || (fCurrentPlotView == FOURIER_PLOT_PHASE)) return; double re, im; double inc = 1.0; const double cp = TMath::Cos(inc/180.0*TMath::Pi()); const double sp = TMath::Sin(inc/180.0*TMath::Pi()); fCurrentFourierPhase += inc; PlotFourierPhaseValue(); for (UInt_t i=0; iGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fFourierHistos[i].dataFourierRe->GetBinContent(j) * cp + fFourierHistos[i].dataFourierIm->GetBinContent(j) * sp; im = fFourierHistos[i].dataFourierIm->GetBinContent(j) * cp - fFourierHistos[i].dataFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fFourierHistos[i].dataFourierRe->SetBinContent(j, re); fFourierHistos[i].dataFourierIm->SetBinContent(j, im); } } } } //-------------------------------------------------------------------------- // DecrementFourierPhase (private) //-------------------------------------------------------------------------- /** *

Decrements the Fourier phase and recalculate the real/imaginary part of the Fourier transform. */ void PFourierCanvas::DecrementFourierPhase() { if ((fCurrentPlotView == FOURIER_PLOT_POWER) || (fCurrentPlotView == FOURIER_PLOT_PHASE)) return; double re, im; double inc = 1.0; const double cp = TMath::Cos(inc/180.0*TMath::Pi()); const double sp = TMath::Sin(inc/180.0*TMath::Pi()); fCurrentFourierPhase -= inc; PlotFourierPhaseValue(); for (UInt_t i=0; iGetNbinsX(); j++) { // loop over a fourier data set // calculate new fourier data set value re = fFourierHistos[i].dataFourierRe->GetBinContent(j) * cp + fFourierHistos[i].dataFourierIm->GetBinContent(j) * sp; im = fFourierHistos[i].dataFourierIm->GetBinContent(j) * cp - fFourierHistos[i].dataFourierRe->GetBinContent(j) * sp; // overwrite fourier data set value fFourierHistos[i].dataFourierRe->SetBinContent(j, re); fFourierHistos[i].dataFourierIm->SetBinContent(j, im); } } } } //-------------------------------------------------------------------------- // 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 PFourierCanvas::GetMaximum(TH1F* histo, Double_t xmin, Double_t xmax) { if (histo == 0) 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 PFourierCanvas::GetMinimum(TH1F* histo, Double_t xmin, Double_t xmax) { if (histo == 0) 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; } //-------------------------------------------------------------------------- // 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 PFourierCanvas::GetInterpolatedValue(TH1F* histo, Double_t xVal) { if (histo == 0) 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; }