musrfit/src/classes/PFourierCanvas.cpp

1481 lines
53 KiB
C++

/***************************************************************************
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 <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 *gFiletypes[] = { "All files", "*",
"Data files", "*.dat",
0, 0 };
ClassImpQ(PFourierCanvas)
//---------------------------------------------------------------------------
/**
* <p>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;
}
//---------------------------------------------------------------------------
/**
* <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, 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
}
//---------------------------------------------------------------------------
/**
* <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, 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
}
//---------------------------------------------------------------------------
/**
* <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 (unsigned int i=0; i<fFourierHistos.size(); i++) {
delete fFourierHistos[i].dataFourierRe;
delete fFourierHistos[i].dataFourierIm;
delete fFourierHistos[i].dataFourierPwr;
delete fFourierHistos[i].dataFourierPhase;
}
fFourierHistos.clear();
}
CleanupAverage();
/*
if (fFourierPad) {
fFourierPad->Clear();
delete fFourierPad;
fFourierPad = 0;
}
*/
if (fInfoPad) {
fInfoPad->Clear();
delete fInfoPad;
fInfoPad = 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)
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)
//--------------------------------------------------------------------------
/**
* <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_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)
//--------------------------------------------------------------------------
/**
* <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)
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 dtStr[128];
strncpy(dtStr, dt.AsSQLString(), sizeof(dtStr));
TString str("musrFT: ");
str += dtStr;
fInfoPad->SetHeader(str);
char title[1024];
for (unsigned int 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;
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; i<fFourierHistos.size(); i++) {
fout << "% " << fFourierHistos[i].dataFourierRe->GetTitle() << endl;
}
fout << "%------------" << endl;
fout << "% " << xAxis << ", " << yAxis << endl;
for (int i=xMinBin; i<xMaxBin; i++) {
switch (fCurrentPlotView) {
case FOURIER_PLOT_REAL:
fout << fFourierAverage.dataFourierRe->GetBinCenter(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; i<fFourierHistos.size(); i++) {
fout << "% " << fFourierHistos[i].dataFourierRe->GetTitle() << endl;
}
fout << "%------------" << endl;
fout << "% ";
for (unsigned int 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 i=xMinBin; i<xMaxBin; i++) {
for (unsigned int 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;
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)
//--------------------------------------------------------------------------
/**
* <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 (unsigned int 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();
}
// 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; i<fFourierHistos.size(); i++) {
for (int j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierRe->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
for (int j=1; j<fFourierHistos[i].dataFourierRe->GetNbinsX(); j++) {
fFourierHistos[i].dataFourierRe->SetBinContent(j, fFourierHistos[i].dataFourierRe->GetBinContent(j)/fabs(max));
}
}
// imaginary
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
for (int j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierIm->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
for (int 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 (unsigned int i=0; i<fFourierHistos.size(); i++) {
for (int j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierPwr->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
for (int 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 (unsigned int i=0; i<fFourierHistos.size(); i++) {
for (int j=start; j<=end; j++) {
dval = fFourierHistos[i].dataFourierPhase->GetBinContent(j);
if (fabs(dval) > max)
max = dval;
}
}
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
for (int j=1; j<fFourierHistos[i].dataFourierPhase->GetNbinsX(); j++) {
fFourierHistos[i].dataFourierPhase->SetBinContent(j, fFourierHistos[i].dataFourierPhase->GetBinContent(j)/fabs(max));
}
}
// set the marker and line color
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
if (i < fColorList.size()) {
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]);
} 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; i<fFourierHistos.size(); i++) {
if (i < fMarkerList.size()) {
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);
} 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)
//--------------------------------------------------------------------------
/**
* <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->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)
//--------------------------------------------------------------------------
/**
* <p>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)
//--------------------------------------------------------------------------
/**
* <p>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; j<fFourierHistos[0].dataFourierRe->GetNbinsX(); j++) {
dval = 0.0;
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierRe->GetNbinsX())
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; j<fFourierHistos[0].dataFourierIm->GetNbinsX(); j++) {
dval = 0.0;
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierIm->GetNbinsX())
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; j<fFourierHistos[0].dataFourierPwr->GetNbinsX(); j++) {
dval = 0.0;
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierPwr->GetNbinsX())
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; j<fFourierHistos[0].dataFourierPhase->GetNbinsX(); j++) {
dval = 0.0;
for (unsigned int i=0; i<fFourierHistos.size(); i++) {
if (j < fFourierHistos[i].dataFourierPhase->GetNbinsX())
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)
//--------------------------------------------------------------------------
/**
* <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 (unsigned int 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->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierRe->Draw("p");
for (unsigned int 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 (unsigned int 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()->SetTitle("Imag");
fFourierHistos[0].dataFourierIm->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierIm->Draw("p");
for (unsigned int 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 (unsigned int 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()->SetTitle("Real");
fFourierHistos[0].dataFourierRe->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierRe->Draw("p");
for (unsigned int i=1; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierRe->Draw("psame");
}
for (unsigned int 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 (unsigned int 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->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierHistos[0].dataFourierPwr->Draw("p");
for (unsigned int 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 (unsigned int 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].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; i<fFourierHistos.size(); i++) {
fFourierHistos[i].dataFourierPhase->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 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.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("<Real>");
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("<Imag>");
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("<Real+Imag>");
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("<Power>");
fFourierAverage.dataFourierPwr->GetXaxis()->SetTitle(fXaxisTitle.Data());
fFourierAverage.dataFourierPwr->Draw("p");
break;
case FOURIER_PLOT_PHASE:
fFourierAverage.dataFourierPhase->GetYaxis()->SetTitle("<Phase>");
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)
//--------------------------------------------------------------------------
/**
* <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 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; 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 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; 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;
}