musrfit/src/classes/PFourierCanvas.cpp

1939 lines
76 KiB
C++

/***************************************************************************
PFourierCanvas.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007-2016 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 <iostream>
#include <fstream>
using namespace std;
#include <TColor.h>
#include <TRandom.h>
#include <TROOT.h>
#include <TDatime.h>
#include <TMath.h>
#include <TGFileDialog.h>
#include "PFourierCanvas.h"
#define YINFO 0.2
#define YTITLE 0.95
static const Char_t *gFiletypes[] = { "Data files", "*.dat",
"All files", "*",
0, 0 };
ClassImpQ(PFourierCanvas)
//---------------------------------------------------------------------------
/**
* <p>Constructor
*/
PFourierCanvas::PFourierCanvas()
{
fTimeout = 0;
fTimeoutTimer = 0;
fBatchMode = false;
fValid = false;
fAveragedView = false;
fAveragedViewPerDataSet = 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;
}
//---------------------------------------------------------------------------
/**
* <p>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<PFourier*> &fourier, PIntVector dataSetTag, const Char_t* title,
const Bool_t showAverage, const Bool_t showAveragePerDataSet,
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), fAveragedViewPerDataSet(showAveragePerDataSet),
fDataSetTag(dataSetTag), fCurrentPlotView(fourierPlotOpt), fTitle(title), fFourier(fourier),
fCurrentFourierPhase(phase)
{
fInitialXRange[0] = fourierXrange[0];
fInitialXRange[1] = fourierXrange[1];
fTimeout = 0;
fTimeoutTimer = 0;
fValid = false;
fCurrentFourierPhaseText = 0;
// generate fMarkerList and fColorList, since they are not provided
TRandom rand;
Int_t style, color;
for (UInt_t i=0; i<fourier.size(); i++) {
rand.SetSeed(i);
style = 20+(Int_t)rand.Integer(10);
fMarkerList.push_back(style);
color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255));
fColorList.push_back(color);
}
CreateXaxisTitle();
CreateStyle();
InitFourierDataSets();
InitFourierCanvas(fTitle, wtopx, wtopy, ww, wh);
gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling
}
//---------------------------------------------------------------------------
/**
* <p>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<PFourier*> &fourier, PIntVector dataSetTag, const Char_t* title,
const Bool_t showAverage, const Bool_t showAveragePerDataSet,
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), fAveragedViewPerDataSet(showAveragePerDataSet),
fDataSetTag(dataSetTag), 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;
// generate fMarkerList and fColorList, since they are not provided
TRandom rand;
Int_t style, color;
for (UInt_t i=fMarkerList.size(); i<fourier.size(); i++) {
rand.SetSeed(i);
style = 20+(Int_t)rand.Integer(10);
fMarkerList.push_back(style);
}
for (UInt_t i=fColorList.size(); i<fourier.size(); i++) {
rand.SetSeed(i);
color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255));
fColorList.push_back(color);
}
CreateXaxisTitle();
CreateStyle();
InitFourierDataSets();
InitFourierCanvas(fTitle, wtopx, wtopy, ww, wh);
gStyle->SetHistMinimumZero(kTRUE); // needed to enforce proper bar option handling
}
//---------------------------------------------------------------------------
/**
* <p>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 (UInt_t i=0; i<fFourierHistos.size(); i++) {
delete fFourierHistos[i].dataFourierRe;
delete fFourierHistos[i].dataFourierIm;
delete fFourierHistos[i].dataFourierPwr;
delete fFourierHistos[i].dataFourierPhase;
delete fFourierHistos[i].dataFourierPhaseOptReal;
}
fFourierHistos.clear();
}
CleanupAverage();
/*
if (fFourierPad) {
fFourierPad->Clear();
delete fFourierPad;
fFourierPad = 0;
}
*/
if (fInfoPad) {
fInfoPad->Clear();
delete fInfoPad;
fInfoPad = 0;
}
if (fLegAvgPerDataSet) {
fLegAvgPerDataSet->Clear();
delete fLegAvgPerDataSet;
fLegAvgPerDataSet = 0;
}
/*
if (fMainCanvas) {
delete fMainCanvas;
fMainCanvas = 0;
}
*/
}
//--------------------------------------------------------------------------
// Done (SIGNAL)
//--------------------------------------------------------------------------
/**
* <p>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)
//--------------------------------------------------------------------------
/**
* <p>Filters keyboard events, and if they are a command key (see below) carries out the
* necessary actions.
* <p>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 || fAveragedViewPerDataSet)
PlotAverage();
else
PlotFourier();
} else if (x == 'a') { // toggle between average view and single histo view
// toggle average view flag
fAveragedView = !fAveragedView;
// unset average per data set view flag
fAveragedViewPerDataSet = false;
// update menu
if (fAveragedView) {
fPopupMain->CheckEntry(P_MENU_ID_AVERAGE);
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
HandleAverage();
PlotAverage();
} else {
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE);
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
CleanupAverage();
PlotFourier();
}
} else if (x == 'd') { // toggle between average view per data set and single histo view
// toggle average per data set view flag
fAveragedViewPerDataSet = !fAveragedViewPerDataSet;
// unset average view flag
fAveragedView = false;
// update menu
if (fAveragedViewPerDataSet) {
fPopupMain->CheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE);
HandleAverage();
PlotAverage();
} else {
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
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)
//--------------------------------------------------------------------------
/**
* <p>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_OPT_REAL) {
fPopupFourier->UnCheckEntries();
fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_OPT_REAL);
fCurrentPlotView = FOURIER_PLOT_PHASE_OPT_REAL;
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;
// unset average per data set view flag
fAveragedViewPerDataSet = false;
// update menu
if (fAveragedView) {
fPopupMain->CheckEntry(P_MENU_ID_AVERAGE);
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
HandleAverage();
PlotAverage();
} else {
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE);
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
CleanupAverage();
PlotFourier();
}
} else if (id == P_MENU_ID_AVERAGE_PER_DATA_SET) {
// toggle average per data set view flag
fAveragedViewPerDataSet = !fAveragedViewPerDataSet;
// unset average view flag
fAveragedView = false;
// update menu
if (fAveragedViewPerDataSet) {
fPopupMain->CheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE);
HandleAverage();
PlotAverage();
} else {
fPopupMain->UnCheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
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)
//--------------------------------------------------------------------------
/**
* <p>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)
//--------------------------------------------------------------------------
/**
* <p>Feeds the pad with the Fourier data sets and refreshes it.
*/
void PFourierCanvas::UpdateFourierPad()
{
if (!fValid)
return;
if (fAveragedView || fAveragedViewPerDataSet)
PlotAverage();
else
PlotFourier();
fFourierPad->Draw();
fMainCanvas->cd();
fMainCanvas->Update();
}
//--------------------------------------------------------------------------
// UpdateInfoPad (public)
//--------------------------------------------------------------------------
/**
* <p>Feeds the pad with the legend and refreshes it.
*/
void PFourierCanvas::UpdateInfoPad()
{
if (!fValid)
return;
// write header line
TDatime dt;
Char_t dtStr[128];
strncpy(dtStr, dt.AsSQLString(), sizeof(dtStr));
TString str("musrFT: ");
str += dtStr;
fInfoPad->SetHeader(str);
Char_t title[1024];
for (UInt_t i=0; i<fFourier.size(); i++) {
strncpy(title, fFourier[i]->GetDataTitle(), sizeof(title));
// add entry
fInfoPad->AddEntry(fFourierHistos[i].dataFourierRe, title, "p");
}
fInfoPad->Draw();
fMainCanvas->cd();
fMainCanvas->Update();
}
//--------------------------------------------------------------------------
// SetTimeout (public)
//--------------------------------------------------------------------------
/**
* <p>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
//--------------------------------------------------------------------------
/**
* <p>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
//--------------------------------------------------------------------------
/**
* <p>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("<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;
case FOURIER_PLOT_PHASE_OPT_REAL:
xAxis = fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetTitle();
yAxis = TString("<Phase>");
xMinBin = fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetFirst();
xMaxBin = fFourierHistos[0].dataFourierPhaseOptReal->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;
case FOURIER_PLOT_PHASE_OPT_REAL:
xAxis = fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetTitle();
yAxis = TString("Phase");
xMinBin = fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetFirst();
xMaxBin = fFourierHistos[0].dataFourierPhaseOptReal->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 (UInt_t i=0; i<fFourierHistos.size(); i++) {
fout << "% " << fFourierHistos[i].dataFourierRe->GetTitle() << endl;
}
fout << "%------------" << endl;
fout << "% " << xAxis << ", " << yAxis << endl;
for (Int_t i=xMinBin; i<xMaxBin; i++) {
switch (fCurrentPlotView) {
case FOURIER_PLOT_REAL:
fout << fFourierAverage[0].dataFourierRe->GetBinCenter(i) << ", " << fFourierAverage[0].dataFourierRe->GetBinContent(i) << endl;
break;
case FOURIER_PLOT_IMAG:
fout << fFourierAverage[0].dataFourierIm->GetBinCenter(i) << ", " << fFourierAverage[0].dataFourierIm->GetBinContent(i) << endl;
break;
case FOURIER_PLOT_POWER:
fout << fFourierAverage[0].dataFourierPwr->GetBinCenter(i) << ", " << fFourierAverage[0].dataFourierPwr->GetBinContent(i) << endl;
break;
case FOURIER_PLOT_PHASE:
fout << fFourierAverage[0].dataFourierPhase->GetBinCenter(i) << ", " << fFourierAverage[0].dataFourierPhase->GetBinContent(i) << endl;
break;
case FOURIER_PLOT_PHASE_OPT_REAL:
fout << fFourierAverage[0].dataFourierPhaseOptReal->GetBinCenter(i) << ", " << fFourierAverage[0].dataFourierPhaseOptReal->GetBinContent(i) << endl;
break;
default:
break;
}
}
} else {
// write header
fout << "% " << pfn << endl;
fout << "% data of:" << endl;
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
fout << "% " << fFourierHistos[i].dataFourierRe->GetTitle() << endl;
}
fout << "%------------" << endl;
fout << "% ";
for (UInt_t i=0; i<fFourierHistos.size()-1; i++) {
fout << xAxis << i << ", " << yAxis << i << ", ";
}
fout << xAxis << fFourierHistos.size()-1 << ", " << yAxis << fFourierHistos.size()-1 << endl;
// write data
for (Int_t i=xMinBin; i<xMaxBin; i++) {
for (UInt_t j=0; j<fFourierHistos.size()-1; j++) {
switch (fCurrentPlotView) {
case FOURIER_PLOT_REAL:
fout << fFourierHistos[j].dataFourierRe->GetBinCenter(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;
case FOURIER_PLOT_PHASE_OPT_REAL:
fout << fFourierHistos[j].dataFourierPhaseOptReal->GetBinCenter(i) << ", " << fFourierHistos[j].dataFourierPhaseOptReal->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;
case FOURIER_PLOT_PHASE_OPT_REAL:
fout << fFourierHistos[fFourierHistos.size()-1].dataFourierPhaseOptReal->GetBinCenter(i) << ", " << fFourierHistos[fFourierHistos.size()-1].dataFourierPhaseOptReal->GetBinContent(i) << endl;
break;
default:
break;
}
}
}
fout.close();
}
//--------------------------------------------------------------------------
// CreateXaxisTitle (private)
//--------------------------------------------------------------------------
/**
* <p>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)
//--------------------------------------------------------------------------
/**
* <p> 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)
//--------------------------------------------------------------------------
/**
* <p>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 (UInt_t i=0; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierRe = fFourier[i]->GetRealFourier();
fFourierHistos[i].dataFourierIm = fFourier[i]->GetImaginaryFourier();
fFourierHistos[i].dataFourierPwr = fFourier[i]->GetPowerFourier();
fFourierHistos[i].dataFourierPhase = fFourier[i]->GetPhaseFourier();
fFourierHistos[i].dataFourierPhaseOptReal = fFourier[i]->GetPhaseOptRealFourier(fFourierHistos[i].optPhase, 1.0, fInitialXRange[0], fInitialXRange[1]);
cout << "debug> histo[" << i << "]: opt. phase = " << fFourierHistos[i].optPhase * 180.0 / TMath::Pi() << "°" << endl;
}
// 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 (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierRe->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=1; j<fFourierHistos[i].dataFourierRe->GetNbinsX(); j++) {
fFourierHistos[i].dataFourierRe->SetBinContent(j, fFourierHistos[i].dataFourierRe->GetBinContent(j)/fabs(max));
}
}
// imaginary
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierIm->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=1; j<fFourierHistos[i].dataFourierIm->GetNbinsX(); j++) {
fFourierHistos[i].dataFourierIm->SetBinContent(j, fFourierHistos[i].dataFourierIm->GetBinContent(j)/fabs(max));
}
}
// power
max = 0.0;
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierPwr->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=1; j<fFourierHistos[i].dataFourierPwr->GetNbinsX(); j++) {
fFourierHistos[i].dataFourierPwr->SetBinContent(j, fFourierHistos[i].dataFourierPwr->GetBinContent(j)/fabs(max));
}
}
// phase
max = 0.0;
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierPhase->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=1; j<fFourierHistos[i].dataFourierPhase->GetNbinsX(); j++) {
fFourierHistos[i].dataFourierPhase->SetBinContent(j, fFourierHistos[i].dataFourierPhase->GetBinContent(j)/fabs(max));
}
}
// phase opt real
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierPhaseOptReal->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
for (Int_t j=1; j<fFourierHistos[i].dataFourierPhaseOptReal->GetNbinsX(); j++) {
fFourierHistos[i].dataFourierPhaseOptReal->SetBinContent(j, fFourierHistos[i].dataFourierPhaseOptReal->GetBinContent(j)/fabs(max));
}
}
// set the marker and line color
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierRe->SetMarkerColor(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]);
fFourierHistos[i].dataFourierPhaseOptReal->SetMarkerColor(fColorList[i]);
fFourierHistos[i].dataFourierPhaseOptReal->SetLineColor(fColorList[i]);
}
// set the marker symbol and size
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierRe->SetMarkerStyle(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);
fFourierHistos[i].dataFourierPhaseOptReal->SetMarkerStyle(fMarkerList[i]);
fFourierHistos[i].dataFourierPhaseOptReal->SetMarkerSize(0.7);
}
// initialize average histos
CleanupAverage();
}
//--------------------------------------------------------------------------
// InitFourierCanvas (private)
//--------------------------------------------------------------------------
/**
* <p>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->AddEntry("Show Phase Opt Fourier", P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_OPT_REAL);
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;
case FOURIER_PLOT_PHASE_OPT_REAL:
fPopupFourier->CheckEntry(P_MENU_ID_FOURIER+P_MENU_ID_FOURIER_PHASE_OPT_REAL);
break;
default:
break;
}
fPopupMain->AddEntry("Average", P_MENU_ID_AVERAGE);
if (fAveragedView)
fPopupMain->CheckEntry(P_MENU_ID_AVERAGE);
fPopupMain->AddEntry("Average per Data Set", P_MENU_ID_AVERAGE_PER_DATA_SET);
if (fAveragedViewPerDataSet)
fPopupMain->CheckEntry(P_MENU_ID_AVERAGE_PER_DATA_SET);
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("fFourierPad", "fFourierPad", 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
fLegAvgPerDataSet = 0;
fValid = true;
if ((fFourier.size() != fDataSetTag.size()) && fAveragedViewPerDataSet) {
fValid = false;
cerr << endl << "PFourierCanvas::PFourierCanvas: **PANIC ERROR**: # Fourier != # Data Set Tags." << endl;
}
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)
//--------------------------------------------------------------------------
/**
* <p>Cleanup average Fourier data sets.
*/
void PFourierCanvas::CleanupAverage()
{
for (UInt_t i=0; i<fFourierAverage.size(); i++) {
if (fFourierAverage[i].dataFourierRe != 0) {
delete fFourierAverage[i].dataFourierRe;
fFourierAverage[i].dataFourierRe = 0;
}
if (fFourierAverage[i].dataFourierIm) {
delete fFourierAverage[i].dataFourierIm;
fFourierAverage[i].dataFourierIm = 0;
}
if (fFourierAverage[i].dataFourierPwr) {
delete fFourierAverage[i].dataFourierPwr;
fFourierAverage[i].dataFourierPwr = 0;
}
if (fFourierAverage[i].dataFourierPhase) {
delete fFourierAverage[i].dataFourierPhase;
fFourierAverage[i].dataFourierPhase = 0;
}
if (fFourierAverage[i].dataFourierPhaseOptReal) {
delete fFourierAverage[i].dataFourierPhaseOptReal;
fFourierAverage[i].dataFourierPhaseOptReal = 0;
}
}
fFourierAverage.clear();
}
//--------------------------------------------------------------------------
// HandleAverage (private)
//--------------------------------------------------------------------------
/**
* <p>Average Fourier data sets.
*/
void PFourierCanvas::HandleAverage()
{
if (fFourierHistos.size() == 0)
return;
CleanupAverage();
TString name("");
Double_t dval=0.0;
// check if ALL data shall be averaged
if (fAveragedView) {
fFourierAverage.resize(1);
// create average histograms
name = TString(fFourierHistos[0].dataFourierRe->GetTitle()) + "_avg";
fFourierAverage[0].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[0].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[0].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[0].dataFourierPhase = new TH1F(name, name, fFourierHistos[0].dataFourierPhase->GetNbinsX(),
fFourierHistos[0].dataFourierPhase->GetXaxis()->GetXmin(),
fFourierHistos[0].dataFourierPhase->GetXaxis()->GetXmax());
name = TString(fFourierHistos[0].dataFourierPhaseOptReal->GetTitle()) + "_avg";
fFourierAverage[0].dataFourierPhaseOptReal = new TH1F(name, name, fFourierHistos[0].dataFourierPhaseOptReal->GetNbinsX(),
fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetXmin(),
fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetXmax());
// real average
for (Int_t j=0; j<fFourierHistos[0].dataFourierRe->GetNbinsX(); j++) {
dval = 0.0;
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierRe->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[i].dataFourierRe, fFourierHistos[0].dataFourierRe->GetBinCenter(j));
}
fFourierAverage[0].dataFourierRe->SetBinContent(j, dval/fFourierHistos.size());
}
// set marker color, line color, maker size, marker type
fFourierAverage[0].dataFourierRe->SetMarkerColor(kBlack);
fFourierAverage[0].dataFourierRe->SetLineColor(kBlack);
fFourierAverage[0].dataFourierRe->SetMarkerSize(0.8);
fFourierAverage[0].dataFourierRe->SetMarkerStyle(22); // closed up triangle
// imaginary average
for (Int_t j=0; j<fFourierHistos[0].dataFourierIm->GetNbinsX(); j++) {
dval = 0.0;
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierIm->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[i].dataFourierIm, fFourierHistos[0].dataFourierIm->GetBinCenter(j));
}
fFourierAverage[0].dataFourierIm->SetBinContent(j, dval/fFourierHistos.size());
}
// set marker color, line color, maker size, marker type
fFourierAverage[0].dataFourierIm->SetMarkerColor(kBlack);
fFourierAverage[0].dataFourierIm->SetLineColor(kBlack);
fFourierAverage[0].dataFourierIm->SetMarkerSize(0.8);
fFourierAverage[0].dataFourierIm->SetMarkerStyle(22); // closed up triangle
// power average
for (Int_t j=0; j<fFourierHistos[0].dataFourierPwr->GetNbinsX(); j++) {
dval = 0.0;
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierPwr->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[i].dataFourierPwr, fFourierHistos[0].dataFourierPwr->GetBinCenter(j));
}
fFourierAverage[0].dataFourierPwr->SetBinContent(j, dval/fFourierHistos.size());
}
// set marker color, line color, maker size, marker type
fFourierAverage[0].dataFourierPwr->SetMarkerColor(kBlack);
fFourierAverage[0].dataFourierPwr->SetLineColor(kBlack);
fFourierAverage[0].dataFourierPwr->SetMarkerSize(0.8);
fFourierAverage[0].dataFourierPwr->SetMarkerStyle(22); // closed up triangle
// phase average
for (Int_t j=0; j<fFourierHistos[0].dataFourierPhase->GetNbinsX(); j++) {
dval = 0.0;
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierPhase->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[i].dataFourierPhase, fFourierHistos[0].dataFourierPhase->GetBinCenter(j));
}
fFourierAverage[0].dataFourierPhase->SetBinContent(j, dval/fFourierHistos.size());
}
// set marker color, line color, maker size, marker type
fFourierAverage[0].dataFourierPhase->SetMarkerColor(kBlack);
fFourierAverage[0].dataFourierPhase->SetLineColor(kBlack);
fFourierAverage[0].dataFourierPhase->SetMarkerSize(0.8);
fFourierAverage[0].dataFourierPhase->SetMarkerStyle(22);
// phase optimised real average
for (Int_t j=0; j<fFourierHistos[0].dataFourierPhaseOptReal->GetNbinsX(); j++) {
dval = 0.0;
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierPhaseOptReal->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[i].dataFourierPhaseOptReal, fFourierHistos[0].dataFourierPhaseOptReal->GetBinCenter(j));
}
fFourierAverage[0].dataFourierPhaseOptReal->SetBinContent(j, dval/fFourierHistos.size());
}
// set marker color, line color, maker size, marker type
fFourierAverage[0].dataFourierPhaseOptReal->SetMarkerColor(kBlack);
fFourierAverage[0].dataFourierPhaseOptReal->SetLineColor(kBlack);
fFourierAverage[0].dataFourierPhaseOptReal->SetMarkerSize(0.8);
fFourierAverage[0].dataFourierPhaseOptReal->SetMarkerStyle(22);
}
// check if per data set shall be averaged
if (fAveragedViewPerDataSet) {
// check what size is required
UInt_t count = 1;
Int_t currentTag = fDataSetTag[0];
for (UInt_t i=1; i<fDataSetTag.size(); i++) {
if (fDataSetTag[i] != currentTag) {
currentTag = fDataSetTag[i];
count++;
}
}
fFourierAverage.resize(count);
Int_t start=0, end=0;
for (UInt_t i=0; i<fFourierAverage.size(); i++) {
// get data set range
count = 0;
currentTag = fDataSetTag[0];
start = -1, end = -1;
for (UInt_t j=0; j<fDataSetTag.size(); j++) {
if ((count == i) && (start == -1)) {
if (j > 0)
start = j-1;
else
start = 0;
}
if (currentTag != fDataSetTag[j]) {
if (count == i) {
end = j-1;
break;
}
count++;
currentTag = fDataSetTag[j];
}
}
if (start == -1)
start = fDataSetTag.size()-1;
if (end == -1)
end = fDataSetTag.size()-1;
// create average histograms
name = TString(fFourierHistos[start].dataFourierRe->GetTitle()) + "_avg";
fFourierAverage[i].dataFourierRe = new TH1F(name, name, fFourierHistos[0].dataFourierRe->GetNbinsX(),
fFourierHistos[0].dataFourierRe->GetXaxis()->GetXmin(),
fFourierHistos[0].dataFourierRe->GetXaxis()->GetXmax());
name = TString(fFourierHistos[start].dataFourierIm->GetTitle()) + "_avg";
fFourierAverage[i].dataFourierIm = new TH1F(name, name, fFourierHistos[0].dataFourierIm->GetNbinsX(),
fFourierHistos[0].dataFourierIm->GetXaxis()->GetXmin(),
fFourierHistos[0].dataFourierIm->GetXaxis()->GetXmax());
name = TString(fFourierHistos[start].dataFourierPwr->GetTitle()) + "_avg";
fFourierAverage[i].dataFourierPwr = new TH1F(name, name, fFourierHistos[0].dataFourierPwr->GetNbinsX(),
fFourierHistos[0].dataFourierPwr->GetXaxis()->GetXmin(),
fFourierHistos[0].dataFourierPwr->GetXaxis()->GetXmax());
name = TString(fFourierHistos[start].dataFourierPhase->GetTitle()) + "_avg";
fFourierAverage[i].dataFourierPhase = new TH1F(name, name, fFourierHistos[0].dataFourierPhase->GetNbinsX(),
fFourierHistos[0].dataFourierPhase->GetXaxis()->GetXmin(),
fFourierHistos[0].dataFourierPhase->GetXaxis()->GetXmax());
name = TString(fFourierHistos[start].dataFourierPhaseOptReal->GetTitle()) + "_avg";
fFourierAverage[i].dataFourierPhaseOptReal = new TH1F(name, name, fFourierHistos[0].dataFourierPhaseOptReal->GetNbinsX(),
fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetXmin(),
fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetXmax());
// real average
for (Int_t j=0; j<fFourierHistos[0].dataFourierRe->GetNbinsX(); j++) {
dval = 0.0;
for (Int_t k=start; k<=end; k++) {
if (j < fFourierHistos[k].dataFourierRe->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[k].dataFourierRe, fFourierHistos[0].dataFourierRe->GetBinCenter(j));
}
fFourierAverage[i].dataFourierRe->SetBinContent(j, dval/(end-start+1));
}
// set marker color, line color, maker size, marker type
fFourierAverage[i].dataFourierRe->SetMarkerColor(fColorList[i]);
fFourierAverage[i].dataFourierRe->SetLineColor(fColorList[i]);
fFourierAverage[i].dataFourierRe->SetMarkerSize(0.8);
fFourierAverage[i].dataFourierRe->SetMarkerStyle(22); // closed up triangle
// imaginary average
for (Int_t j=0; j<fFourierHistos[0].dataFourierIm->GetNbinsX(); j++) {
dval = 0.0;
for (Int_t k=start; k<=end; k++) {
if (j < fFourierHistos[k].dataFourierIm->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[k].dataFourierIm, fFourierHistos[0].dataFourierIm->GetBinCenter(j));
}
fFourierAverage[i].dataFourierIm->SetBinContent(j, dval/(end-start+1));
}
// set marker color, line color, maker size, marker type
fFourierAverage[i].dataFourierIm->SetMarkerColor(fColorList[i]);
fFourierAverage[i].dataFourierIm->SetLineColor(fColorList[i]);
fFourierAverage[i].dataFourierIm->SetMarkerSize(0.8);
fFourierAverage[i].dataFourierIm->SetMarkerStyle(22); // closed up triangle
// power average
for (Int_t j=0; j<fFourierHistos[0].dataFourierPwr->GetNbinsX(); j++) {
dval = 0.0;
for (Int_t k=start; k<=end; k++) {
if (j < fFourierHistos[k].dataFourierPwr->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[k].dataFourierPwr, fFourierHistos[0].dataFourierPwr->GetBinCenter(j));
}
fFourierAverage[i].dataFourierPwr->SetBinContent(j, dval/(end-start+1));
}
// set marker color, line color, maker size, marker type
fFourierAverage[i].dataFourierPwr->SetMarkerColor(fColorList[i]);
fFourierAverage[i].dataFourierPwr->SetLineColor(fColorList[i]);
fFourierAverage[i].dataFourierPwr->SetMarkerSize(0.8);
fFourierAverage[i].dataFourierPwr->SetMarkerStyle(22); // closed up triangle
// phase average
for (Int_t j=0; j<fFourierHistos[0].dataFourierPhase->GetNbinsX(); j++) {
dval = 0.0;
for (Int_t k=start; k<=end; k++) {
if (j < fFourierHistos[k].dataFourierPhase->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[k].dataFourierPhase, fFourierHistos[0].dataFourierPhase->GetBinCenter(j));
}
fFourierAverage[i].dataFourierPhase->SetBinContent(j, dval/(end-start+1));
}
// set marker color, line color, maker size, marker type
fFourierAverage[i].dataFourierPhase->SetMarkerColor(fColorList[i]);
fFourierAverage[i].dataFourierPhase->SetLineColor(fColorList[i]);
fFourierAverage[i].dataFourierPhase->SetMarkerSize(0.8);
fFourierAverage[i].dataFourierPhase->SetMarkerStyle(22); // closed up triangle
// phase optimised real average
for (Int_t j=0; j<fFourierHistos[0].dataFourierPhaseOptReal->GetNbinsX(); j++) {
dval = 0.0;
for (Int_t k=start; k<=end; k++) {
if (j < fFourierHistos[k].dataFourierPhaseOptReal->GetNbinsX())
dval += GetInterpolatedValue(fFourierHistos[k].dataFourierPhaseOptReal, fFourierHistos[0].dataFourierPhaseOptReal->GetBinCenter(j));
}
fFourierAverage[i].dataFourierPhaseOptReal->SetBinContent(j, dval/(end-start+1));
}
// set marker color, line color, maker size, marker type
fFourierAverage[i].dataFourierPhaseOptReal->SetMarkerColor(fColorList[i]);
fFourierAverage[i].dataFourierPhaseOptReal->SetLineColor(fColorList[i]);
fFourierAverage[i].dataFourierPhaseOptReal->SetMarkerSize(0.8);
fFourierAverage[i].dataFourierPhaseOptReal->SetMarkerStyle(22); // closed up triangle
}
}
}
//--------------------------------------------------------------------------
// PlotFourier (private)
//--------------------------------------------------------------------------
/**
* <p>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 (UInt_t i=1; i<fFourierHistos.size(); i++) {
if (GetMaximum(fFourierHistos[i].dataFourierRe, xmin, xmax) > 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->GetYaxis()->SetTitleOffset(1.3);
fFourierHistos[0].dataFourierRe->GetYaxis()->SetDecimals(kTRUE);
fFourierHistos[0].dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierRe->Draw("p");
for (UInt_t i=1; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierRe->Draw("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 (UInt_t i=1; i<fFourierHistos.size(); i++) {
if (GetMaximum(fFourierHistos[i].dataFourierIm, xmin, xmax) > 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()->SetTitleOffset(1.3);
fFourierHistos[0].dataFourierIm->GetYaxis()->SetDecimals(kTRUE);
fFourierHistos[0].dataFourierIm->GetYaxis()->SetTitle("Imag");
fFourierHistos[0].dataFourierIm->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierIm->Draw("p");
for (UInt_t i=1; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierIm->Draw("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 (UInt_t i=1; i<fFourierHistos.size(); i++) {
if (GetMaximum(fFourierHistos[i].dataFourierRe, xmin, xmax) > 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()->SetTitleOffset(1.3);
fFourierHistos[0].dataFourierRe->GetYaxis()->SetDecimals(kTRUE);
fFourierHistos[0].dataFourierRe->GetYaxis()->SetTitle("Real");
fFourierHistos[0].dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierRe->Draw("p");
for (UInt_t i=1; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierRe->Draw("psame");
}
for (UInt_t i=0; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierIm->Draw("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 (UInt_t i=1; i<fFourierHistos.size(); i++) {
if (GetMaximum(fFourierHistos[i].dataFourierPwr, xmin, xmax) > 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->GetYaxis()->SetTitleOffset(1.3);
fFourierHistos[0].dataFourierPwr->GetYaxis()->SetDecimals(kTRUE);
fFourierHistos[0].dataFourierPwr->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierPwr->Draw("p");
for (UInt_t i=1; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierPwr->Draw("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 (UInt_t i=1; i<fFourierHistos.size(); i++) {
if (GetMaximum(fFourierHistos[i].dataFourierPhase, xmin, xmax) > 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].dataFourierPhase->GetYaxis()->SetRangeUser(1.05*ymin, 1.05*ymax);
fFourierHistos[0].dataFourierPhase->GetYaxis()->SetTitleOffset(1.3);
fFourierHistos[0].dataFourierPhase->GetYaxis()->SetDecimals(kTRUE);
fFourierHistos[0].dataFourierPhase->GetYaxis()->SetTitle("Phase");
fFourierHistos[0].dataFourierPhase->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierPhase->Draw("p");
for (UInt_t i=1; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierPhase->Draw("psame");
}
break;
case FOURIER_PLOT_PHASE_OPT_REAL:
fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->SetRangeUser(xmin, xmax);
ymin = GetMinimum(fFourierHistos[0].dataFourierPhaseOptReal, xmin, xmax);
ymax = GetMaximum(fFourierHistos[0].dataFourierPhaseOptReal, xmin, xmax);
for (UInt_t i=1; i<fFourierHistos.size(); i++) {
if (GetMaximum(fFourierHistos[i].dataFourierPhaseOptReal, xmin, xmax) > ymax)
ymax = GetMaximum(fFourierHistos[i].dataFourierPhaseOptReal, xmin, xmax);
if (GetMinimum(fFourierHistos[i].dataFourierPhaseOptReal, xmin, xmax) < ymin)
ymin = GetMinimum(fFourierHistos[i].dataFourierPhaseOptReal, xmin, xmax);
}
fFourierHistos[0].dataFourierPhaseOptReal->GetYaxis()->SetRangeUser(ymin, 1.05*ymax);
fFourierHistos[0].dataFourierPhaseOptReal->GetYaxis()->SetTitleOffset(1.3);
fFourierHistos[0].dataFourierPhaseOptReal->GetYaxis()->SetDecimals(kTRUE);
fFourierHistos[0].dataFourierPhaseOptReal->GetYaxis()->SetTitle("Phase Opt. Real");
fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierPhaseOptReal->Draw("p");
for (UInt_t i=1; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierPhaseOptReal->Draw("psame");
}
break;
default:
break;
}
fFourierPad->Update();
fMainCanvas->cd();
fMainCanvas->Update();
}
//--------------------------------------------------------------------------
// PlotFourierPhaseValue (private)
//--------------------------------------------------------------------------
/**
* <p>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_t 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)
//--------------------------------------------------------------------------
/**
* <p>Plot the average of the given Fourier data sets.
*/
void PFourierCanvas::PlotAverage()
{
fFourierPad->cd();
if (fFourierAverage.size() == 0) { // ups, HandleAverage never called!
HandleAverage();
}
Double_t xmin=0.0, xmax=0.0;
xmin = fInitialXRange[0];
xmax = fInitialXRange[1];
Double_t ymin=0.0, ymax=0.0;
if (fLegAvgPerDataSet) {
fLegAvgPerDataSet->Clear();
delete fLegAvgPerDataSet;
fLegAvgPerDataSet = 0;
}
switch (fCurrentPlotView) {
case FOURIER_PLOT_REAL:
fFourierAverage[0].dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
ymin = GetMinimum(fFourierAverage[0].dataFourierRe, xmin, xmax);
ymax = GetMaximum(fFourierAverage[0].dataFourierRe, xmin, xmax);
for (UInt_t i=1; i<fFourierAverage.size(); i++) {
if (GetMaximum(fFourierAverage[i].dataFourierRe, xmin, xmax) > ymax)
ymax = GetMaximum(fFourierAverage[i].dataFourierRe, xmin, xmax);
if (GetMinimum(fFourierAverage[i].dataFourierRe, xmin, xmax) < ymin)
ymin = GetMinimum(fFourierAverage[i].dataFourierRe, xmin, xmax);
}
fFourierAverage[0].dataFourierRe->GetYaxis()->SetRangeUser(1.03*ymin, 1.03*ymax);
fFourierAverage[0].dataFourierRe->GetYaxis()->SetTitleOffset(1.3);
fFourierAverage[0].dataFourierRe->GetYaxis()->SetDecimals(kTRUE);
fFourierAverage[0].dataFourierRe->GetYaxis()->SetTitle("<Real>");
fFourierAverage[0].dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierAverage[0].dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
fFourierAverage[0].dataFourierRe->Draw("p");
break;
case FOURIER_PLOT_IMAG:
fFourierAverage[0].dataFourierIm->GetXaxis()->SetRangeUser(xmin, xmax);
ymin = GetMinimum(fFourierAverage[0].dataFourierIm, xmin, xmax);
ymax = GetMaximum(fFourierAverage[0].dataFourierIm, xmin, xmax);
for (UInt_t i=1; i<fFourierAverage.size(); i++) {
if (GetMaximum(fFourierAverage[i].dataFourierIm, xmin, xmax) > ymax)
ymax = GetMaximum(fFourierAverage[i].dataFourierIm, xmin, xmax);
if (GetMinimum(fFourierAverage[i].dataFourierIm, xmin, xmax) < ymin)
ymin = GetMinimum(fFourierAverage[i].dataFourierIm, xmin, xmax);
}
fFourierAverage[0].dataFourierIm->GetYaxis()->SetRangeUser(1.03*ymin, 1.03*ymax);
fFourierAverage[0].dataFourierIm->GetYaxis()->SetTitleOffset(1.3);
fFourierAverage[0].dataFourierIm->GetYaxis()->SetDecimals(kTRUE);
fFourierAverage[0].dataFourierIm->GetYaxis()->SetTitle("<Imag>");
fFourierAverage[0].dataFourierIm->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierAverage[0].dataFourierIm->GetXaxis()->SetRangeUser(xmin, xmax);
fFourierAverage[0].dataFourierIm->Draw("p");
break;
case FOURIER_PLOT_REAL_AND_IMAG:
fFourierAverage[0].dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
ymin = GetMinimum(fFourierAverage[0].dataFourierRe, xmin, xmax);
ymax = GetMaximum(fFourierAverage[0].dataFourierRe, xmin, xmax);
for (UInt_t i=1; i<fFourierAverage.size(); i++) {
if (GetMaximum(fFourierAverage[i].dataFourierRe, xmin, xmax) > ymax)
ymax = GetMaximum(fFourierAverage[i].dataFourierRe, xmin, xmax);
if (GetMinimum(fFourierAverage[i].dataFourierRe, xmin, xmax) < ymin)
ymin = GetMinimum(fFourierAverage[i].dataFourierRe, xmin, xmax);
}
fFourierAverage[0].dataFourierRe->GetYaxis()->SetRangeUser(1.03*ymin, 1.03*ymax);
fFourierAverage[0].dataFourierRe->GetYaxis()->SetTitleOffset(1.3);
fFourierAverage[0].dataFourierRe->GetYaxis()->SetDecimals(kTRUE);
fFourierAverage[0].dataFourierRe->GetYaxis()->SetTitle("<Real+Imag>");
fFourierAverage[0].dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierAverage[0].dataFourierRe->GetXaxis()->SetRangeUser(xmin, xmax);
fFourierAverage[0].dataFourierRe->Draw("p");
fFourierAverage[0].dataFourierIm->Draw("psame");
break;
case FOURIER_PLOT_POWER:
// get maximum of Fourier data in the range
fFourierAverage[0].dataFourierPwr->GetXaxis()->SetRangeUser(xmin, xmax);
ymin = 0.0;
ymax = GetMaximum(fFourierAverage[0].dataFourierPwr, xmin, xmax);
for (UInt_t i=1; i<fFourierAverage.size(); i++) {
if (GetMaximum(fFourierAverage[i].dataFourierPwr, xmin, xmax) > ymax)
ymax = GetMaximum(fFourierAverage[i].dataFourierPwr, xmin, xmax);
}
fFourierAverage[0].dataFourierPwr->GetYaxis()->SetRangeUser(ymin, 1.03*ymax);
fFourierAverage[0].dataFourierPwr->GetYaxis()->SetTitleOffset(1.3);
fFourierAverage[0].dataFourierPwr->GetYaxis()->SetDecimals(kTRUE);
fFourierAverage[0].dataFourierPwr->GetYaxis()->SetTitle("<Power>");
fFourierAverage[0].dataFourierPwr->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierAverage[0].dataFourierPwr->Draw("p");
break;
case FOURIER_PLOT_PHASE:
fFourierAverage[0].dataFourierPhase->GetXaxis()->SetRangeUser(xmin, xmax);
ymin = GetMinimum(fFourierAverage[0].dataFourierPhase, xmin, xmax);
ymax = GetMaximum(fFourierAverage[0].dataFourierPhase, xmin, xmax);
for (UInt_t i=1; i<fFourierAverage.size(); i++) {
if (GetMaximum(fFourierAverage[i].dataFourierPhase, xmin, xmax) > ymax)
ymax = GetMaximum(fFourierAverage[i].dataFourierPhase, xmin, xmax);
if (GetMinimum(fFourierAverage[i].dataFourierPhase, xmin, xmax) < ymin)
ymin = GetMinimum(fFourierAverage[i].dataFourierPhase, xmin, xmax);
}
fFourierAverage[0].dataFourierPhase->GetYaxis()->SetRangeUser(1.03*ymin, 1.03*ymax);
fFourierAverage[0].dataFourierPhase->GetYaxis()->SetTitleOffset(1.3);
fFourierAverage[0].dataFourierPhase->GetYaxis()->SetDecimals(kTRUE);
fFourierAverage[0].dataFourierPhase->GetYaxis()->SetTitle("<Phase>");
fFourierAverage[0].dataFourierPhase->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierAverage[0].dataFourierPhase->GetXaxis()->SetRangeUser(xmin, xmax);
fFourierAverage[0].dataFourierPhase->Draw("p");
break;
case FOURIER_PLOT_PHASE_OPT_REAL:
fFourierAverage[0].dataFourierPhaseOptReal->GetXaxis()->SetRangeUser(xmin, xmax);
ymin = GetMinimum(fFourierAverage[0].dataFourierPhaseOptReal, xmin, xmax);
ymax = GetMaximum(fFourierAverage[0].dataFourierPhaseOptReal, xmin, xmax);
for (UInt_t i=1; i<fFourierAverage.size(); i++) {
if (GetMaximum(fFourierAverage[i].dataFourierPhaseOptReal, xmin, xmax) > ymax)
ymax = GetMaximum(fFourierAverage[i].dataFourierPhaseOptReal, xmin, xmax);
if (GetMinimum(fFourierAverage[i].dataFourierPhaseOptReal, xmin, xmax) < ymin)
ymin = GetMinimum(fFourierAverage[i].dataFourierPhaseOptReal, xmin, xmax);
}
fFourierAverage[0].dataFourierPhaseOptReal->GetYaxis()->SetRangeUser(ymin, 1.03*ymax);
fFourierAverage[0].dataFourierPhaseOptReal->GetYaxis()->SetTitleOffset(1.3);
fFourierAverage[0].dataFourierPhaseOptReal->GetYaxis()->SetDecimals(kTRUE);
fFourierAverage[0].dataFourierPhaseOptReal->GetYaxis()->SetTitle("<Phase Opt. Real>");
fFourierAverage[0].dataFourierPhaseOptReal->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierAverage[0].dataFourierPhaseOptReal->GetXaxis()->SetRangeUser(xmin, xmax);
fFourierAverage[0].dataFourierPhaseOptReal->Draw("p");
break;
default:
break;
}
if (fAveragedViewPerDataSet) { // plot all the rest
fLegAvgPerDataSet = new TLegend(0.55, 0.4, 0.85, 0.6);
TString str = GetDataSetName(fFourierAverage[0].dataFourierPwr->GetTitle());
TString label = TString::Format("<%s>", str.Data());
fLegAvgPerDataSet->AddEntry(fFourierAverage[0].dataFourierPwr, label.Data());
for (UInt_t i=1; i<fFourierAverage.size(); i++) {
switch (fCurrentPlotView) {
case FOURIER_PLOT_REAL:
fFourierAverage[i].dataFourierRe->Draw("psame");
break;
case FOURIER_PLOT_IMAG:
fFourierAverage[i].dataFourierIm->Draw("psame");
break;
case FOURIER_PLOT_REAL_AND_IMAG:
fFourierAverage[i].dataFourierRe->Draw("psame");
fFourierAverage[i].dataFourierIm->Draw("psame");
break;
case FOURIER_PLOT_POWER:
fFourierAverage[i].dataFourierPwr->Draw("psame");
break;
case FOURIER_PLOT_PHASE:
fFourierAverage[i].dataFourierPhase->Draw("psame");
break;
case FOURIER_PLOT_PHASE_OPT_REAL:
fFourierAverage[i].dataFourierPhaseOptReal->Draw("psame");
break;
default:
break;
}
// add legend ?!?!
str = GetDataSetName(fFourierAverage[i].dataFourierPwr->GetTitle());
label = TString::Format("<%s>", str.Data());
fLegAvgPerDataSet->AddEntry(fFourierAverage[i].dataFourierPwr, label.Data());
}
fLegAvgPerDataSet->Draw();
}
fFourierPad->Update();
fMainCanvas->cd();
fMainCanvas->Update();
}
//--------------------------------------------------------------------------
// IncrementFourierPhase (private)
//--------------------------------------------------------------------------
/**
* <p>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_t re, im;
Double_t inc = 1.0;
const Double_t cp = TMath::Cos(inc/180.0*TMath::Pi());
const Double_t sp = TMath::Sin(inc/180.0*TMath::Pi());
fCurrentFourierPhase += inc;
PlotFourierPhaseValue();
for (UInt_t i=0; i<fFourierHistos.size(); i++) { // loop over all data sets
if ((fFourierHistos[i].dataFourierRe != 0) && (fFourierHistos[i].dataFourierIm != 0)) {
for (Int_t j=0; j<fFourierHistos[i].dataFourierRe->GetNbinsX(); 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)
//--------------------------------------------------------------------------
/**
* <p>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_t re, im;
Double_t inc = 1.0;
const Double_t cp = TMath::Cos(inc/180.0*TMath::Pi());
const Double_t sp = TMath::Sin(inc/180.0*TMath::Pi());
fCurrentFourierPhase -= inc;
PlotFourierPhaseValue();
for (UInt_t i=0; i<fFourierHistos.size(); i++) { // loop over all data sets
if ((fFourierHistos[i].dataFourierRe != 0) && (fFourierHistos[i].dataFourierIm != 0)) {
for (Int_t j=0; j<fFourierHistos[i].dataFourierRe->GetNbinsX(); 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)
//--------------------------------------------------------------------------
/**
* <p>returns the maximum of a histogram in the range [xmin, xmax].
* If xmin = xmax = -1.0, the whole histogram range is used.
*
* <b>return:</b>
* - 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; i<end; i++) {
binContent = histo->GetBinContent(i);
if (max < binContent)
max = binContent;
}
return max;
}
//--------------------------------------------------------------------------
// GetMinimum (private)
//--------------------------------------------------------------------------
/**
* <p>returns the minimum of a histogram in the range [xmin, xmax].
* If xmin = xmax = -1.0, the whole histogram range is used.
*
* <b>return:</b>
* - 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; i<end; i++) {
binContent = histo->GetBinContent(i);
if (min > binContent)
min = binContent;
}
return min;
}
//--------------------------------------------------------------------------
// GetInterpolatedValue (private)
//--------------------------------------------------------------------------
/**
* <p>search for xVal in histo. If xVal is not found exactly, interpolate and
* return the interpolated y-value.
*
* <b>return:</b>
* - 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;
}
//--------------------------------------------------------------------------
// GetDataSetName (private)
//--------------------------------------------------------------------------
/**
* <p>filters out the data set name from the title
*
* <b>return:</b>
* - data set name
*
* \param title title of the Fourier histogram
*/
TString PFourierCanvas::GetDataSetName(TString title)
{
TString str(title);
Ssiz_t idx = str.First(':');
str.Remove(0, idx+1);
idx = str.First(',');
str.Remove(idx);
return str;
}