/*************************************************************************** PFourierCanvas.h Author: Andreas Suter e-mail: andreas.suter@psi.ch ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2026 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. * ***************************************************************************/ #ifndef _PFOURIERCANVAS_H_ #define _PFOURIERCANVAS_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "PMusr.h" #include "PFourier.h" // Canvas menu id's #define P_MENU_ID_FOURIER 10001 #define P_MENU_ID_AVERAGE 10002 #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_OPT_REAL 105 #define P_MENU_ID_FOURIER_PHASE_PLUS 106 #define P_MENU_ID_FOURIER_PHASE_MINUS 107 //------------------------------------------------------------------------ /** *

Structure holding all Fourier transform histograms for one data set. * *

This structure bundles all different representations of a single * Fourier transform, including real, imaginary, power, phase, and * phase-optimized spectra. Each μSR run or dataset gets one instance. * *

Purpose: Provides complete Fourier analysis results in one * container for easy access and visualization switching. * * @see PFourierCanvas * @see PFourier */ struct PFourierCanvasDataSet { TH1F *dataFourierRe; ///< Real part Re(F): absorption-mode spectrum (mixed phase if uncorrected) TH1F *dataFourierIm; ///< Imaginary part Im(F): dispersion-mode spectrum TH1F *dataFourierPwr; ///< Power spectrum |F| = √(Re² + Im²): phase-independent amplitude TH1F *dataFourierPhase; ///< Phase spectrum φ = atan2(Im, Re): phase angle in radians TH1F *dataFourierPhaseOptReal; ///< Phase-optimized real spectrum: maximized absorption mode with minimal imaginary component std::vector optPhase; ///< Optimal phase parameters [c₀, c₁] for phase correction: φ(ω) = c₀ + c₁·ω }; //------------------------------------------------------------------------ /** *

Type alias for a collection of Fourier data sets. * *

Represents multiple μSR runs or datasets, each with complete * Fourier transform results. Used for multi-run visualization and * averaging operations. * * @see PFourierCanvasDataSet */ typedef std::vector PFourierCanvasDataList; //-------------------------------------------------------------------------- /** *

Interactive ROOT canvas for visualizing μSR Fourier transform spectra. * *

PFourierCanvas provides a sophisticated GUI for displaying and analyzing * Fourier-transformed μSR data with multiple viewing modes: * - Real spectrum (absorption mode) * - Imaginary spectrum (dispersion mode) * - Real + Imaginary overlay * - Power spectrum (magnitude) * - Phase spectrum * - Phase-optimized real spectrum * *

Key features: * - Multi-run visualization with color/marker coding * - Interactive phase adjustment (±5° increments) * - Automatic averaging across all runs or per dataset * - Export to data files * - Batch mode for non-interactive operation * - Customizable markers and colors * - Menu-driven interface with keyboard shortcuts * *

Usage modes: * - Interactive: Full GUI with menus for exploring spectra * - Batch: Automated plot generation for scripts * - Individual: Display each run separately * - Averaged: Show ensemble average across all data * - Per-dataset average: Average within grouped datasets * *

Architecture: Uses ROOT TQObject for signal/slot mechanism, * enabling clean event handling and timeout functionality. * * @see PFourier * @see PFourierCanvasDataSet */ class PFourierCanvas : public TObject, public TQObject { public: /** *

Default constructor - creates empty canvas. * *

Initializes internal state with default values. Not typically * used directly; prefer constructors with data parameters. */ PFourierCanvas(); /** *

Constructor with automatic marker/color generation. * *

Creates interactive Fourier canvas with randomly generated * markers and colors for each data set. * * @param fourier Vector of PFourier objects containing transformed data * @param dataSetTag Vector of dataset identifiers for grouping runs * @param title Canvas window title * @param showAverage If true, display average across all runs * @param showAveragePerDataSet If true, average within each dataset group * @param fourierPlotOpt Initial plot mode (real/imag/power/phase/etc.) * @param fourierXrange X-axis range [min, max] in output units (G/T/MHz) * @param phase Initial phase offset in degrees for Re/Im display * @param wtopx X position of canvas window (pixels) * @param wtopy Y position of canvas window (pixels) * @param ww Canvas width (pixels) * @param wh Canvas height (pixels) * @param batch If true, run in batch mode (no GUI interaction) */ PFourierCanvas(std::vector &fourier, PIntVector dataSetTag, const Char_t* title, const Bool_t showAverage, const Bool_t showAveragePerDataSet, const Int_t fourierPlotOpt, Double_t fourierXrange[2], Double_t phase, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh, const Bool_t batch); /** *

Constructor with explicit marker/color specification. * *

Creates interactive Fourier canvas with user-defined visual * styling for each data set. Provides full control over plot appearance. * * @param fourier Vector of PFourier objects containing transformed data * @param dataSetTag Vector of dataset identifiers for grouping runs * @param title Canvas window title * @param showAverage If true, display average across all runs * @param showAveragePerDataSet If true, average within each dataset group * @param fourierPlotOpt Initial plot mode (real/imag/power/phase/etc.) * @param fourierXrange X-axis range [min, max] in output units (G/T/MHz) * @param phase Initial phase offset in degrees for Re/Im display * @param wtopx X position of canvas window (pixels) * @param wtopy Y position of canvas window (pixels) * @param ww Canvas width (pixels) * @param wh Canvas height (pixels) * @param markerList ROOT marker styles (20-30) for each dataset * @param colorList ROOT color indices for each dataset * @param batch If true, run in batch mode (no GUI interaction) */ PFourierCanvas(std::vector &fourier, PIntVector dataSetTag, const Char_t* title, const Bool_t showAverage, const Bool_t showAveragePerDataSet, const Int_t fourierPlotOpt, Double_t fourierXrange[2], 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); /** *

Signal emitted when user closes canvas or timeout expires. * *

This signal notifies parent applications that the canvas * is terminating. Used for cleanup and application flow control. * * @param status Exit status code (0 = normal, non-zero = error) */ virtual void Done(Int_t status=0); // *SIGNAL* /** *

Slot for handling keyboard events in the canvas. * *

Processes keyboard shortcuts: * - '+': Increment phase by 5° * - '-': Decrement phase by 5° * - Other keys: Reserved for future use * * @param event ROOT event type identifier * @param x Mouse x-coordinate at event time * @param y Mouse y-coordinate at event time * @param selected ROOT object under cursor (if any) */ virtual void HandleCmdKey(Int_t event, Int_t x, Int_t y, TObject *selected); // SLOT /** *

Slot for handling menu selection events. * *

Processes menu item selections: * - View mode changes (Real/Imag/Power/Phase/etc.) * - Averaging toggles (All/Per-dataset/Off) * - Data export * - Phase adjustments * * @param id Menu item identifier (P_MENU_ID_* constants) */ virtual void HandleMenuPopup(Int_t id); // SLOT /** *

Slot called when canvas window is closed by user. * *

Triggers cleanup and emits Done() signal. Part of ROOT's * window management system. */ virtual void LastCanvasClosed(); // SLOT /** *

Redraws the Fourier spectrum pad with current settings. * *

Updates the main plotting area with current view mode, * phase settings, and averaging options. Called automatically * after parameter changes. */ virtual void UpdateFourierPad(); /** *

Redraws the legend/info pad with current dataset information. * *

Updates the legend showing which datasets are displayed, * with appropriate markers and colors. */ virtual void UpdateInfoPad(); /** *

Checks if canvas initialized successfully. * * @return True if canvas is ready for display, false on initialization errors */ virtual Bool_t IsValid() { return fValid; } /** *

Sets automatic timeout for canvas closure. * *

Useful for batch processing or automated testing. Canvas * emits Done() signal after timeout expires. * * @param ival Timeout in milliseconds (≤0 = no timeout) */ virtual void SetTimeout(Int_t ival); /** *

Saves canvas to graphics file and exits. * *

Exports current canvas view to image file (format determined * by extension: .pdf, .png, .eps, .root, etc.) and closes canvas. * * @param fileName Output file path with extension */ virtual void SaveGraphicsAndQuit(const Char_t *fileName); /** *

Exports Fourier spectrum data to ASCII file. * *

Writes frequency/field values and corresponding spectrum * amplitudes in columnar format for external analysis. * * @param pathFileName Output data file path (typically .dat extension) */ virtual void ExportData(const Char_t *pathFileName); private: Int_t fTimeout; ///< timeout after which the Done signal should be emited. If timeout <= 0, no timeout is taking place Bool_t fBatchMode; ///< musrview in ROOT batch mode Bool_t fValid; ///< if true, everything looks OK Bool_t fAveragedView; ///< tag showing that the averaged view for ALL data or normal view should be presented. Bool_t fAveragedViewPerDataSet; ///< tag showing that the averaged view for individual data sets or normal view should be presented. PIntVector fDataSetTag; ///< vector holding the data set tags Int_t fCurrentPlotView; ///< tag showing what the current plot view is: real, imag, power, phase, ... Double_t fInitialXRange[2]; ///< keeps the initial x-range Double_t fInitialYRange[2]; ///< keeps the initial y-range TString fTitle; TString fXaxisTitle; std::vector fFourier; ///< keeps all the Fourier data, ownership is with the caller PFourierCanvasDataList fFourierHistos; ///< keeps all the Fourier histos PFourierCanvasDataList fFourierAverage; ///< keeps the average of the Fourier histos Double_t fCurrentFourierPhase; ///< keeps the current Fourier phase (real/imag) std::unique_ptr fCurrentFourierPhaseText; ///< used in Re/Im Fourier to show the current phase in the pad std::unique_ptr fStyle; ///< A collection of all graphics attributes std::unique_ptr fTimeoutTimer; ///< timeout timer in order to terminate if no action is taking place for too long PIntVector fMarkerList; ///< list of markers PIntVector fColorList; ///< list of colors // canvas menu related variables TRootCanvas *fImp; ///< ROOT native GUI version of main window with menubar and drawing area TGMenuBar *fBar; ///< menu bar TGPopupMenu *fPopupMain; ///< popup menu MusrFT in the main menu bar std::unique_ptr fPopupFourier; ///< popup menu of the MusrFT/Fourier sub menu // canvas related variables std::unique_ptr fMainCanvas; ///< main canvas std::unique_ptr fTitlePad; ///< title pad used to display a title std::unique_ptr fFourierPad; ///< fourier pad used to display the fourier std::unique_ptr fInfoPad; ///< info pad used to display a legend of the data plotted std::unique_ptr fLegAvgPerDataSet; ///< legend used for averaged per data set view /// Creates X-axis label based on unit type (Gauss/Tesla/MHz/Mc/s) virtual void CreateXaxisTitle(); /// Initializes ROOT plotting style (colors, fonts, margins, etc.) virtual void CreateStyle(); /// Generates all Fourier histograms (Re/Im/Pwr/Phase) from PFourier objects virtual void InitFourierDataSets(); /// Creates ROOT canvas with menu bar, pads, and event connections /// @param title Window title /// @param wtopx Window x-position /// @param wtopy Window y-position /// @param ww Window width /// @param wh Window height virtual void InitFourierCanvas(const Char_t* title, Int_t wtopx, Int_t wtopy, Int_t ww, Int_t wh); /// Deletes averaged histogram data to free memory virtual void CleanupAverage(); /// Computes averaged Fourier spectra across runs or per dataset virtual void HandleAverage(); /// Calculates phase-optimized real Fourier for all datasets virtual void CalcPhaseOptReal(); /// Draws individual Fourier spectra (non-averaged view) virtual void PlotFourier(); /// Displays current phase value as text overlay on canvas virtual void PlotFourierPhaseValue(); /// Draws averaged Fourier spectra (averaged view modes) virtual void PlotAverage(); /// Increases phase by 5° and redraws Re/Im spectra virtual void IncrementFourierPhase(); /// Decreases phase by 5° and redraws Re/Im spectra virtual void DecrementFourierPhase(); /// Finds maximum value in histogram within optional x-range /// @param histo Input histogram /// @param xmin Range minimum (-1.0 = use full range) /// @param xmax Range maximum (-1.0 = use full range) /// @return Maximum y-value in range virtual Double_t GetMaximum(TH1F* histo, Double_t xmin=-1.0, Double_t xmax=-1.0); /// Finds minimum value in histogram within optional x-range /// @param histo Input histogram /// @param xmin Range minimum (-1.0 = use full range) /// @param xmax Range maximum (-1.0 = use full range) /// @return Minimum y-value in range virtual Double_t GetMinimum(TH1F* histo, Double_t xmin=-1.0, Double_t xmax=-1.0); /// Linearly interpolates histogram value at arbitrary x-position /// @param histo Input histogram /// @param xVal X-coordinate for interpolation /// @return Interpolated y-value virtual Double_t GetInterpolatedValue(TH1F* histo, Double_t xVal); /// Extracts dataset name from histogram title /// @param title Full histogram title /// @return Parsed dataset identifier virtual TString GetDataSetName(TString title); ClassDef(PFourierCanvas, 1) }; #endif // _PFOURIERCANVAS_H_