diff --git a/ChangeLog b/ChangeLog
index ac0e3904..7576b4bd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,8 +4,15 @@
changes since 0.14.0
===================================
+NEW 2015-09-24 adding a phase optimized real Fourier to musrFT. This is still VERY
+ experimental, and hence only available from within musrFT. Eventually
+ it should make its way into musrview as well. Furthermore the
+ documentation needs to be written yet. There is only a short not in
+ the command line present.
NEW 2015-02-23 implemented an average-per-data-set option for musrFT.
NEW 2015-02-21 add proper Mac icon to musredit
+FIXED 2015-09-22 generating global fit msr-files including a GLOBAL block is working
+ now as expected.
FIXED 2015-09-17 in PMsr2Data::PrepareGlobalInputFile() there seem to be 'unmotivated'
break; commands in some loops. They prevent a proper map handling.
Since this is a real puzzle I contacted BMW for clarification.
diff --git a/src/classes/PFourier.cpp b/src/classes/PFourier.cpp
index 38f94d12..ea08370b 100644
--- a/src/classes/PFourier.cpp
+++ b/src/classes/PFourier.cpp
@@ -8,7 +8,7 @@
***************************************************************************/
/***************************************************************************
- * Copyright (C) 2007-2014 by Andreas Suter *
+ * Copyright (C) 2007-2015 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -163,7 +163,7 @@ PFourier::~PFourier()
}
//--------------------------------------------------------------------------
-// Transform
+// Transform (public)
//--------------------------------------------------------------------------
/**
*
Carries out the Fourier transform. It is assumed that fStartTime is the time zero
@@ -201,7 +201,7 @@ void PFourier::Transform(UInt_t apodizationTag)
}
//--------------------------------------------------------------------------
-// GetMaxFreq
+// GetMaxFreq (public)
//--------------------------------------------------------------------------
/**
*
returns the maximal frequency in units choosen, i.e. Gauss, Tesla, MHz, Mc/s
@@ -218,7 +218,7 @@ Double_t PFourier::GetMaxFreq()
}
//--------------------------------------------------------------------------
-// GetRealFourier
+// GetRealFourier (public)
//--------------------------------------------------------------------------
/**
*
returns the real part Fourier as a histogram.
@@ -259,7 +259,108 @@ TH1F* PFourier::GetRealFourier(const Double_t scale)
}
//--------------------------------------------------------------------------
-// GetImaginaryFourier
+// GetPhaseOptRealFourier (public)
+//--------------------------------------------------------------------------
+/**
+ *
returns the phase corrected real Fourier transform. The correction angle is
+ * past back as well.
+ *
Currently it simply does the following thing: (i) rotate the complex Fourier
+ * transform through all angles in 1/2° steps, i.e.
+ * \f$ f_{\rm rot} = (f_{\rm real} + i f_{\rm imag}) \exp(- \alpha)\f$,
+ * hence \f$ f_{\rm rot} = f_{\rm real} \cos(\alpha) + f_{\rm imag} \sin(\alpha)\f$.
+ * (ii) search the maximum of \f$ sum_{\alpha} {\cal R}\{f_{\rm rot}\}\f$ for all
+ * \f$\alpha\f$. From this one gets \f$\alpha_{\rm opt}\f$. (iii) The 'optimal'
+ * real Fourier transform is \f$f_{\rm opt} = (f_{\rm real} + i f_{\rm imag})
+ * \exp(- \alpha_{\rm opt})\f$.
+ *
+ * \return the TH1F histo of the phase 'optimzed' real Fourier transform.
+ *
+ * \param phase return value of the optimal phase
+ * \param scale normalisation factor
+ * \param min minimal freq / field from which to optimise. Given in the choosen unit.
+ * \param max maximal freq / field up to which to optimise. Given in the choosen unit.
+ */
+TH1F* PFourier::GetPhaseOptRealFourier(Double_t &phase, const Double_t scale, const Double_t min, const Double_t max)
+{
+ UInt_t noOfFourierBins = 0;
+ if (fNoOfBins % 2 == 0)
+ noOfFourierBins = fNoOfBins/2;
+ else
+ noOfFourierBins = (fNoOfBins+1)/2;
+
+ UInt_t minBin = 0;
+ UInt_t maxBin = noOfFourierBins;
+
+ // check if minimum frequency is given. If yes, get the proper minBin
+ if (min != -1.0) {
+ minBin = (UInt_t)(min/fResolution);
+ }
+
+ // check if maximum frequency is given. If yes, get the proper maxBin
+ if (max != -1.0) {
+ maxBin = (UInt_t)(max/fResolution);
+ }
+
+ // copy the real/imag Fourier from min to max
+ vector realF, imagF;
+ for (UInt_t i=minBin; i<=maxBin; i++) {
+ realF.push_back(fOut[i][0]);
+ imagF.push_back(fOut[i][1]);
+ }
+
+ // rotate trough real/imag Fourier through 360° with a 1/2° resolution and keep the integral
+ Double_t rotRealIntegral[720];
+ Double_t sum = 0.0;
+ Double_t da = 8.72664625997164774e-03; // pi / 360
+ for (UInt_t i=0; i<720; i++) {
+ sum = 0.0;
+ for (UInt_t j=0; jGetName());
+ snprintf(title, sizeof(title), "%s_Fourier_PhOptRe", fData->GetTitle());
+
+ TH1F *realPhaseOptFourier = new TH1F(name, title, noOfFourierBins, -fResolution/2.0, (Double_t)(noOfFourierBins-1)*fResolution+fResolution/2.0);
+ if (realPhaseOptFourier == 0) {
+ fValid = false;
+ cerr << endl << "**SEVERE ERROR** couldn't allocate memory for the real part of the Fourier transform." << endl;
+ return 0;
+ }
+
+ // fill realFourier vector
+ for (UInt_t i=0; iSetBinContent(i+1, scale*(fOut[i][0]*cos(phase) + fOut[i][1]*sin(phase)));
+ realPhaseOptFourier->SetBinError(i+1, 0.0);
+ }
+
+ return realPhaseOptFourier;
+}
+
+//--------------------------------------------------------------------------
+// GetImaginaryFourier (public)
//--------------------------------------------------------------------------
/**
* returns the imaginary part Fourier as a histogram.
@@ -301,7 +402,7 @@ TH1F* PFourier::GetImaginaryFourier(const Double_t scale)
}
//--------------------------------------------------------------------------
-// GetPowerFourier
+// GetPowerFourier (public)
//--------------------------------------------------------------------------
/**
*
returns the Fourier power spectrum as a histogram.
@@ -343,7 +444,7 @@ TH1F* PFourier::GetPowerFourier(const Double_t scale)
}
//--------------------------------------------------------------------------
-// GetPhaseFourier
+// GetPhaseFourier (public)
//--------------------------------------------------------------------------
/**
*
returns the Fourier phase spectrum as a histogram.
@@ -402,7 +503,7 @@ TH1F* PFourier::GetPhaseFourier(const Double_t scale)
}
//--------------------------------------------------------------------------
-// PrepareFFTwInputData
+// PrepareFFTwInputData (private)
//--------------------------------------------------------------------------
/**
*
Feeds the Fourier data and apply the apodization.
@@ -451,7 +552,7 @@ void PFourier::PrepareFFTwInputData(UInt_t apodizationTag)
}
//--------------------------------------------------------------------------
-// ApodizeData
+// ApodizeData (private)
//--------------------------------------------------------------------------
/**
*
Carries out the appodization of the data.
diff --git a/src/classes/PFourierCanvas.cpp b/src/classes/PFourierCanvas.cpp
index e163fe68..f83da656 100644
--- a/src/classes/PFourierCanvas.cpp
+++ b/src/classes/PFourierCanvas.cpp
@@ -227,6 +227,7 @@ PFourierCanvas::~PFourierCanvas()
delete fFourierHistos[i].dataFourierIm;
delete fFourierHistos[i].dataFourierPwr;
delete fFourierHistos[i].dataFourierPhase;
+ delete fFourierHistos[i].dataFourierPhaseOptReal;
}
fFourierHistos.clear();
}
@@ -386,6 +387,11 @@ void PFourierCanvas::HandleMenuPopup(Int_t id)
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) {
@@ -590,6 +596,12 @@ void PFourierCanvas::ExportData(const Char_t *pathFileName)
yAxis = TString("");
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("");
+ xMinBin = fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetFirst();
+ xMaxBin = fFourierHistos[0].dataFourierPhaseOptReal->GetXaxis()->GetLast();
break;
default:
xAxis = TString("??");
@@ -624,6 +636,12 @@ void PFourierCanvas::ExportData(const Char_t *pathFileName)
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("??");
@@ -659,6 +677,9 @@ void PFourierCanvas::ExportData(const Char_t *pathFileName)
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;
}
@@ -693,6 +714,9 @@ void PFourierCanvas::ExportData(const Char_t *pathFileName)
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;
}
@@ -710,6 +734,9 @@ void PFourierCanvas::ExportData(const Char_t *pathFileName)
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;
}
@@ -777,6 +804,8 @@ void PFourierCanvas::InitFourierDataSets()
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
@@ -796,6 +825,7 @@ void PFourierCanvas::InitFourierDataSets()
fFourierHistos[i].dataFourierRe->SetBinContent(j, fFourierHistos[i].dataFourierRe->GetBinContent(j)/fabs(max));
}
}
+
// imaginary
for (UInt_t i=0; iSetBinContent(j, fFourierHistos[i].dataFourierIm->GetBinContent(j)/fabs(max));
}
}
+
// power
max = 0.0;
for (UInt_t i=0; iSetBinContent(j, fFourierHistos[i].dataFourierPwr->GetBinContent(j)/fabs(max));
}
}
+
// phase
max = 0.0;
for (UInt_t i=0; iGetBinContent(j);
+ if (fabs(dval) > max)
+ max = dval;
+ }
+ }
+ for (UInt_t i=0; iGetNbinsX(); j++) {
+ fFourierHistos[i].dataFourierPhaseOptReal->SetBinContent(j, fFourierHistos[i].dataFourierPhaseOptReal->GetBinContent(j)/fabs(max));
+ }
+ }
+
// set the marker and line color
for (UInt_t i=0; iSetMarkerColor(fColorList[i]);
@@ -848,6 +894,8 @@ void PFourierCanvas::InitFourierDataSets()
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
@@ -860,6 +908,8 @@ void PFourierCanvas::InitFourierDataSets()
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
@@ -913,6 +963,7 @@ void PFourierCanvas::InitFourierCanvas(const Char_t* title, Int_t wtopx, Int_t w
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);
@@ -935,6 +986,9 @@ void PFourierCanvas::InitFourierCanvas(const Char_t* title, Int_t wtopx, Int_t w
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;
}
@@ -1029,6 +1083,10 @@ void PFourierCanvas::CleanupAverage()
delete fFourierAverage[i].dataFourierPhase;
fFourierAverage[i].dataFourierPhase = 0;
}
+ if (fFourierAverage[i].dataFourierPhaseOptReal) {
+ delete fFourierAverage[i].dataFourierPhaseOptReal;
+ fFourierAverage[i].dataFourierPhaseOptReal = 0;
+ }
}
fFourierAverage.clear();
}
@@ -1074,6 +1132,11 @@ void PFourierCanvas::HandleAverage()
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; jGetNbinsX(); j++) {
dval = 0.0;
@@ -1133,6 +1196,21 @@ void PFourierCanvas::HandleAverage()
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; jGetNbinsX(); j++) {
+ dval = 0.0;
+ for (UInt_t i=0; iGetNbinsX())
+ 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
@@ -1196,6 +1274,11 @@ void PFourierCanvas::HandleAverage()
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; jGetNbinsX(); j++) {
dval = 0.0;
@@ -1255,6 +1338,21 @@ void PFourierCanvas::HandleAverage()
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; jGetNbinsX(); 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
}
}
}
@@ -1381,6 +1479,26 @@ void PFourierCanvas::PlotFourier()
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 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; iDraw("psame");
+ }
+ break;
default:
break;
}
@@ -1541,6 +1659,24 @@ void PFourierCanvas::PlotAverage()
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 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("");
+ fFourierAverage[0].dataFourierPhaseOptReal->GetXaxis()->SetTitle(fXaxisTitle.Data());
+ fFourierAverage[0].dataFourierPhaseOptReal->GetXaxis()->SetRangeUser(xmin, xmax);
+ fFourierAverage[0].dataFourierPhaseOptReal->Draw("p");
+ break;
default:
break;
}
@@ -1568,6 +1704,9 @@ void PFourierCanvas::PlotAverage()
case FOURIER_PLOT_PHASE:
fFourierAverage[i].dataFourierPhase->Draw("psame");
break;
+ case FOURIER_PLOT_PHASE_OPT_REAL:
+ fFourierAverage[i].dataFourierPhaseOptReal->Draw("psame");
+ break;
default:
break;
}
diff --git a/src/classes/PMsrHandler.cpp b/src/classes/PMsrHandler.cpp
index 67c59201..8ce87844 100644
--- a/src/classes/PMsrHandler.cpp
+++ b/src/classes/PMsrHandler.cpp
@@ -8,7 +8,7 @@
***************************************************************************/
/***************************************************************************
- * Copyright (C) 2007-2014 by Andreas Suter *
+ * Copyright (C) 2007-2015 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -242,7 +242,7 @@ Int_t PMsrHandler::ReadMsrFile()
if (result == PMUSR_SUCCESS)
if (!HandleFunctionsEntry(functions))
result = PMUSR_MSR_SYNTAX_ERROR;
- if (result == PMUSR_SUCCESS)
+ if ((result == PMUSR_SUCCESS) && (global.size()>0))
if (!HandleGlobalEntry(global))
result = PMUSR_MSR_SYNTAX_ERROR;
if (result == PMUSR_SUCCESS)
@@ -1595,7 +1595,106 @@ Int_t PMsrHandler::WriteMsrFile(const Char_t *filename, map *co
// write GLOBAL block
if (fGlobal.IsPresent()) {
- // not sure that anything needs to be done here ...
+ fout << "GLOBAL" << endl;
+
+ // fittype
+ if (fGlobal.GetFitType() != -1) {
+ fout.width(16);
+ switch (fGlobal.GetFitType()) {
+ case MSR_FITTYPE_SINGLE_HISTO:
+ fout << left << "fittype" << MSR_FITTYPE_SINGLE_HISTO << " (single histogram fit)" << endl;
+ break;
+ case MSR_FITTYPE_ASYM:
+ fout << left << "fittype" << MSR_FITTYPE_ASYM << " (asymmetry fit)" << endl ;
+ break;
+ case MSR_FITTYPE_MU_MINUS:
+ fout << left << "fittype" << MSR_FITTYPE_MU_MINUS << " (mu minus fit)" << endl ;
+ break;
+ case MSR_FITTYPE_NON_MUSR:
+ fout << left << "fittype" << MSR_FITTYPE_NON_MUSR << " (non muSR fit)" << endl ;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // data range
+ if ((fGlobal.GetDataRange(0) != -1) || (fGlobal.GetDataRange(1) != -1) || (fGlobal.GetDataRange(2) != -1) || (fGlobal.GetDataRange(3) != -1)) {
+ fout.width(16);
+ fout << left << "data";
+ for (UInt_t j=0; j<4; ++j) {
+ if (fGlobal.GetDataRange(j) > 0) {
+ fout.width(8);
+ fout << left << fGlobal.GetDataRange(j);
+ }
+ }
+ fout << endl;
+ }
+
+ // t0
+ if (fGlobal.GetT0BinSize() > 0) {
+ fout.width(16);
+ fout << left << "t0";
+ for (UInt_t j=0; j 0) {
+ fout.width(16);
+ fout << left << "addt0";
+ for (Int_t k=0; k 0)
+ fout << "+" << fGlobal.GetFitRangeOffset(0);
+ fout << " lgb";
+ if (fGlobal.GetFitRangeOffset(1) > 0)
+ fout << "-" << fGlobal.GetFitRangeOffset(1);
+ } else { // fit range given in time
+ for (UInt_t j=0; j<2; j++) {
+ if (fGlobal.GetFitRange(j) == -1)
+ break;
+ UInt_t neededWidth = 7;
+ UInt_t neededPrec = LastSignificant(fRuns[i].GetFitRange(j));
+ fout.width(neededWidth);
+ fout.precision(neededPrec);
+ fout << left << fixed << fGlobal.GetFitRange(j);
+ if (j==0)
+ fout << " ";
+ }
+ }
+ fout << endl;
+ }
+
+ // packing
+ if (fGlobal.GetPacking() != -1) {
+ fout.width(16);
+ fout << left << "packing";
+ fout << fGlobal.GetPacking() << endl;
+ }
+
+ fout << endl << hline.Data() << endl;
}
// write RUN blocks
@@ -1660,22 +1759,24 @@ Int_t PMsrHandler::WriteMsrFile(const Char_t *filename, map *co
}
// fittype
- fout.width(16);
- switch (fRuns[i].GetFitType()) {
- case MSR_FITTYPE_SINGLE_HISTO:
- fout << left << "fittype" << MSR_FITTYPE_SINGLE_HISTO << " (single histogram fit)" << endl;
- break;
- case MSR_FITTYPE_ASYM:
- fout << left << "fittype" << MSR_FITTYPE_ASYM << " (asymmetry fit)" << endl ;
- break;
- case MSR_FITTYPE_MU_MINUS:
- fout << left << "fittype" << MSR_FITTYPE_MU_MINUS << " (mu minus fit)" << endl ;
- break;
- case MSR_FITTYPE_NON_MUSR:
- fout << left << "fittype" << MSR_FITTYPE_NON_MUSR << " (non muSR fit)" << endl ;
- break;
- default:
- break;
+ if (fRuns[i].GetFitType() != -1) {
+ fout.width(16);
+ switch (fRuns[i].GetFitType()) {
+ case MSR_FITTYPE_SINGLE_HISTO:
+ fout << left << "fittype" << MSR_FITTYPE_SINGLE_HISTO << " (single histogram fit)" << endl;
+ break;
+ case MSR_FITTYPE_ASYM:
+ fout << left << "fittype" << MSR_FITTYPE_ASYM << " (asymmetry fit)" << endl ;
+ break;
+ case MSR_FITTYPE_MU_MINUS:
+ fout << left << "fittype" << MSR_FITTYPE_MU_MINUS << " (mu minus fit)" << endl ;
+ break;
+ case MSR_FITTYPE_NON_MUSR:
+ fout << left << "fittype" << MSR_FITTYPE_NON_MUSR << " (non muSR fit)" << endl ;
+ break;
+ default:
+ break;
+ }
}
// alpha
@@ -1815,17 +1916,19 @@ Int_t PMsrHandler::WriteMsrFile(const Char_t *filename, map *co
}
// addt0
- for (UInt_t j = 0; j < fRuns[i].GetRunNameSize() - 1; ++j) {
- if (fRuns[i].GetAddT0BinSize(j) > 0) {
- fout.width(16);
- fout << left << "addt0";
- for (Int_t k=0; k 0) {
+ for (UInt_t j = 0; j < fRuns[i].GetRunNameSize() - 1; ++j) {
+ if (fRuns[i].GetAddT0BinSize(j) > 0) {
+ fout.width(16);
+ fout << left << "addt0";
+ for (Int_t k=0; k *co
}
// fit
- fout.width(16);
- fout << left << "fit";
- if (fRuns[i].IsFitRangeInBin()) { // fit range given in bins
- fout << "fgb";
- if (fRuns[i].GetFitRangeOffset(0) > 0)
- fout << "+" << fRuns[i].GetFitRangeOffset(0);
- fout << " lgb";
- if (fRuns[i].GetFitRangeOffset(1) > 0)
- fout << "-" << fRuns[i].GetFitRangeOffset(1);
- } else { // fit range given in time
- for (UInt_t j=0; j<2; j++) {
- if (fRuns[i].GetFitRange(j) == -1)
- break;
- UInt_t neededWidth = 7;
- UInt_t neededPrec = LastSignificant(fRuns[i].GetFitRange(j));
- fout.width(neededWidth);
- fout.precision(neededPrec);
- fout << left << fixed << fRuns[i].GetFitRange(j);
- if (j==0)
- fout << " ";
+ if ( (fRuns[i].IsFitRangeInBin() && fRuns[i].GetFitRangeOffset(0) != -1) ||
+ (fRuns[i].GetFitRange(0) != PMUSR_UNDEFINED) ) {
+ fout.width(16);
+ fout << left << "fit";
+ if (fRuns[i].IsFitRangeInBin()) { // fit range given in bins
+ fout << "fgb";
+ if (fRuns[i].GetFitRangeOffset(0) > 0)
+ fout << "+" << fRuns[i].GetFitRangeOffset(0);
+ fout << " lgb";
+ if (fRuns[i].GetFitRangeOffset(1) > 0)
+ fout << "-" << fRuns[i].GetFitRangeOffset(1);
+ } else { // fit range given in time
+ for (UInt_t j=0; j<2; j++) {
+ if (fRuns[i].GetFitRange(j) == -1)
+ break;
+ UInt_t neededWidth = 7;
+ UInt_t neededPrec = LastSignificant(fRuns[i].GetFitRange(j));
+ fout.width(neededWidth);
+ fout.precision(neededPrec);
+ fout << left << fixed << fRuns[i].GetFitRange(j);
+ if (j==0)
+ fout << " ";
+ }
}
+ fout << endl;
}
- fout << endl;
// packing
- fout.width(16);
- fout << left << "packing";
- fout << fRuns[i].GetPacking() << endl;
+ if (fRuns[i].GetPacking() != -1) {
+ fout.width(16);
+ fout << left << "packing";
+ fout << fRuns[i].GetPacking() << endl;
+ }
+
fout << endl;
}
diff --git a/src/include/PFourier.h b/src/include/PFourier.h
index 868b1d09..3e120b7c 100644
--- a/src/include/PFourier.h
+++ b/src/include/PFourier.h
@@ -57,6 +57,7 @@ class PFourier
virtual Double_t GetResolution() { return fResolution; }
virtual Double_t GetMaxFreq();
virtual TH1F* GetRealFourier(const Double_t scale = 1.0);
+ virtual TH1F* GetPhaseOptRealFourier(Double_t &phase, const Double_t scale = 1.0, const Double_t min = -1.0, const Double_t max = -1.0);
virtual TH1F* GetImaginaryFourier(const Double_t scale = 1.0);
virtual TH1F* GetPowerFourier(const Double_t scale = 1.0);
virtual TH1F* GetPhaseFourier(const Double_t scale = 1.0);
diff --git a/src/include/PFourierCanvas.h b/src/include/PFourierCanvas.h
index 634abde4..096097c1 100644
--- a/src/include/PFourierCanvas.h
+++ b/src/include/PFourierCanvas.h
@@ -43,23 +43,26 @@
#define P_MENU_ID_AVERAGE_PER_DATA_SET 10003
#define P_MENU_ID_EXPORT_DATA 10004
-#define P_MENU_ID_FOURIER_REAL 100
-#define P_MENU_ID_FOURIER_IMAG 101
-#define P_MENU_ID_FOURIER_REAL_AND_IMAG 102
-#define P_MENU_ID_FOURIER_PWR 103
-#define P_MENU_ID_FOURIER_PHASE 104
-#define P_MENU_ID_FOURIER_PHASE_PLUS 105
-#define P_MENU_ID_FOURIER_PHASE_MINUS 106
+#define P_MENU_ID_FOURIER_REAL 100
+#define P_MENU_ID_FOURIER_IMAG 101
+#define P_MENU_ID_FOURIER_REAL_AND_IMAG 102
+#define P_MENU_ID_FOURIER_PWR 103
+#define P_MENU_ID_FOURIER_PHASE 104
+#define P_MENU_ID_FOURIER_PHASE_OPT_REAL 105
+#define P_MENU_ID_FOURIER_PHASE_PLUS 106
+#define P_MENU_ID_FOURIER_PHASE_MINUS 107
//------------------------------------------------------------------------
/**
* Structure holding all necessary Fourier histograms.
*/
typedef struct {
- TH1F *dataFourierRe; ///< real part of the Fourier transform of the data histogram
- TH1F *dataFourierIm; ///< imaginary part of the Fourier transform of the data histogram
- TH1F *dataFourierPwr; ///< power spectrum of the Fourier transform of the data histogram
- TH1F *dataFourierPhase; ///< phase spectrum of the Fourier transform of the data histogram
+ TH1F *dataFourierRe; ///< real part of the Fourier transform of the data histogram
+ TH1F *dataFourierIm; ///< imaginary part of the Fourier transform of the data histogram
+ TH1F *dataFourierPwr; ///< power spectrum of the Fourier transform of the data histogram
+ TH1F *dataFourierPhase; ///< phase spectrum of the Fourier transform of the data histogram
+ TH1F *dataFourierPhaseOptReal; ///< phase otpimized real Fourier transform of the data histogram
+ Double_t optPhase; ///< optimal phase which maximizes the real Fourier
} PFourierCanvasDataSet;
//------------------------------------------------------------------------
diff --git a/src/include/PMusr.h b/src/include/PMusr.h
index 8d2683c3..9074a34b 100644
--- a/src/include/PMusr.h
+++ b/src/include/PMusr.h
@@ -123,12 +123,13 @@ typedef struct { char a[7]; } __float128; // needed since cint doesn't know it
#define FOURIER_APOD_MEDIUM 3
#define FOURIER_APOD_STRONG 4
-#define FOURIER_PLOT_NOT_GIVEN 0
-#define FOURIER_PLOT_REAL 1
-#define FOURIER_PLOT_IMAG 2
-#define FOURIER_PLOT_REAL_AND_IMAG 3
-#define FOURIER_PLOT_POWER 4
-#define FOURIER_PLOT_PHASE 5
+#define FOURIER_PLOT_NOT_GIVEN 0
+#define FOURIER_PLOT_REAL 1
+#define FOURIER_PLOT_IMAG 2
+#define FOURIER_PLOT_REAL_AND_IMAG 3
+#define FOURIER_PLOT_POWER 4
+#define FOURIER_PLOT_PHASE 5
+#define FOURIER_PLOT_PHASE_OPT_REAL 6
//-------------------------------------------------------------
// RRF related tags
diff --git a/src/musrFT.cpp b/src/musrFT.cpp
index 37c931c3..84bc5991 100644
--- a/src/musrFT.cpp
+++ b/src/musrFT.cpp
@@ -67,7 +67,7 @@ typedef struct {
TString msrFlnOut; ///< dump file name for msr-file generation
Int_t bkg_range[2]; ///< background range
PDoubleVector bkg; ///< background value
- TString fourierOpt; ///< Fourier options, i.e. real, imag, power, phase
+ TString fourierOpt; ///< Fourier options, i.e. real, imag, power, phase, phaseOptReal
TString apodization; ///< apodization setting: none, weak, medium, strong
Int_t fourierPower; ///< Fourier power for zero padding, i.e. 2^fourierPower points
TString fourierUnits; ///< wished Fourier units: Gauss, Tesla, MHz, Mc/s
@@ -111,7 +111,7 @@ void musrFT_syntax()
cout << endl << " -br, --background-range : background interval used to estimate the background to be";
cout << endl << " subtracted before the Fourier transform. , to be given in bins.";
cout << endl << " -bg, --background : gives the background explicit for each histogram.";
- cout << endl << " -fo, --fourier-option : can be 'real', 'imag', 'real+imag', 'power', or 'phase'.";
+ cout << endl << " -fo, --fourier-option : can be 'real', 'imag', 'real+imag', 'power', 'phase', or 'phaseOptReal'.";
cout << endl << " If this is not defined (neither on the command line nor in the musrfit_startup.xml),";
cout << endl << " default will be 'power'.";
cout << endl << " -ap, --apodization : can be either 'none', 'weak', 'medium', 'strong'.";
@@ -370,7 +370,8 @@ Int_t musrFT_parse_options(Int_t argc, Char_t *argv[], musrFT_startup_param &sta
return 2;
}
TString topt(argv[i+1]);
- if (!topt.BeginsWith("real") && !topt.BeginsWith("imag") && !topt.BeginsWith("power") && !topt.BeginsWith("phase")) {
+ if (!topt.BeginsWith("real") && !topt.BeginsWith("imag") && !topt.BeginsWith("power") &&
+ !topt.BeginsWith("phase") && !topt.BeginsWith("phaseOptReal")) {
cerr << endl << ">> musrFT **ERROR** found option --fourier-option with unrecognized argument '" << topt << "'." << endl;
return 2;
}
@@ -941,9 +942,9 @@ void musrFT_dumpMsrFile(musrFT_startup_param ¶m)
fout << "units " << param.fourierUnits << " # units either 'Gauss', 'MHz', or 'Mc/s'" << endl;
}
if (param.fourierOpt.BeginsWith("??")) { // Fourier plot option not given, hence choose POWER
- fout << "plot POWER # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE" << endl;
+ fout << "plot POWER # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE, PHASE_OPT_REAL" << endl;
} else {
- fout << "plot " << param.fourierOpt << " # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE" << endl;
+ fout << "plot " << param.fourierOpt << " # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE, PHASE_OPT_REAL" << endl;
}
if (param.fourierPower > 1) {
fout << "fourier_power " << param.fourierPower << endl;
@@ -1368,6 +1369,8 @@ Int_t main(Int_t argc, Char_t *argv[])
fourierPlotTag = FOURIER_PLOT_POWER;
else if (!startupParam.fourierOpt.CompareTo("phase", TString::kIgnoreCase))
fourierPlotTag = FOURIER_PLOT_PHASE;
+ else if (!startupParam.fourierOpt.CompareTo("phaseoptreal", TString::kIgnoreCase))
+ fourierPlotTag = FOURIER_PLOT_PHASE_OPT_REAL;
else
fourierPlotTag = FOURIER_PLOT_POWER;
}
diff --git a/src/musredit/PGetMusrFTOptionsDialog.cpp b/src/musredit/PGetMusrFTOptionsDialog.cpp
index 5be9bc08..cdf15e3f 100644
--- a/src/musredit/PGetMusrFTOptionsDialog.cpp
+++ b/src/musredit/PGetMusrFTOptionsDialog.cpp
@@ -36,12 +36,13 @@
#include "PGetMusrFTOptionsDialog.h"
-#define MUSRFT_OPT_UNDEF 0
-#define MUSRFT_OPT_REAL 1
-#define MUSRFT_OPT_IMAG 2
-#define MUSRFT_OPT_REAL_AND_IMAG 3
-#define MUSRFT_OPT_POWER 4
-#define MUSRFT_OPT_PHASE 5
+#define MUSRFT_OPT_UNDEF 0
+#define MUSRFT_OPT_REAL 1
+#define MUSRFT_OPT_IMAG 2
+#define MUSRFT_OPT_REAL_AND_IMAG 3
+#define MUSRFT_OPT_POWER 4
+#define MUSRFT_OPT_PHASE 5
+#define MUSRFT_OPT_PHASE_OPT_REAL 6
#define MUSRFT_APOD_UNDEF 0
#define MUSRFT_APOD_WEAK 1
@@ -139,6 +140,8 @@ PGetMusrFTOptionsDialog::PGetMusrFTOptionsDialog(QString currentMsrFile, QString
fFourierOption_comboBox->setCurrentIndex(MUSRFT_OPT_POWER);
else if (prevCmd[i+1] == "phase")
fFourierOption_comboBox->setCurrentIndex(MUSRFT_OPT_PHASE);
+ else if (prevCmd[i+1] == "phaseOptReal")
+ fFourierOption_comboBox->setCurrentIndex(MUSRFT_OPT_PHASE_OPT_REAL);
else
fFourierOption_comboBox->setCurrentIndex(MUSRFT_OPT_UNDEF);
i++;
diff --git a/src/musredit/forms/PGetMusrFTOptionsDialog.ui b/src/musredit/forms/PGetMusrFTOptionsDialog.ui
index 75966be9..6935f643 100644
--- a/src/musredit/forms/PGetMusrFTOptionsDialog.ui
+++ b/src/musredit/forms/PGetMusrFTOptionsDialog.ui
@@ -34,7 +34,7 @@
Fourier
-
+
21
@@ -91,6 +91,11 @@ p, li { white-space: pre-wrap; }
phase
+ -
+
+ phaseOptReal
+
+