/*************************************************************************** PRunAsymmetryRRF.h Author: Andreas Suter e-mail: andreas.suter@psi.ch ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2025 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 _PRUNASYMMETRYRRF_H_ #define _PRUNASYMMETRYRRF_H_ #include "PRunBase.h" //--------------------------------------------------------------------------- /** * \brief Class for handling μSR asymmetry fits in the Rotating Reference Frame (RRF). * * PRunAsymmetryRRF extends PRunBase to handle asymmetry fitting where data is transformed * into a rotating reference frame. This technique is particularly useful for analyzing * high-frequency oscillations in μSR spectra by mixing the signal with a reference frequency. * * The RRF transformation: * \f[ A_{\rm RRF}(t) = A(t) \cdot 2\cos(\omega_{\rm RRF} t + \phi_{\rm RRF}) \f] * * where: * - \f$ A(t) \f$ is the standard asymmetry: \f$ A(t) = \frac{F(t) - \alpha B(t)}{F(t) + \alpha B(t)} \f$ * - \f$ \omega_{\rm RRF} \f$ is the RRF frequency (specified in PLOT block) * - \f$ \phi_{\rm RRF} \f$ is the RRF phase (specified in PLOT block) * * Key features: * - Transforms high-frequency oscillations to lower frequencies * - Requires special RRF packing parameter from GLOBAL block * - Supports α/β correction parameters (same as PRunAsymmetry) * - Applies Kaiser FIR filtering to theory curves for smooth visualization * * The RRF technique is essential for: * - High transverse field (TF) measurements * - Analyzing fast precession frequencies * - Improving signal-to-noise in specific frequency ranges * * \see PRunAsymmetry for standard (non-RRF) asymmetry fitting * \see PRunBase for the base class providing common functionality */ class PRunAsymmetryRRF : public PRunBase { public: /// Default constructor PRunAsymmetryRRF(); /** * \brief Main constructor for RRF asymmetry fitting. * \param msrInfo Pointer to MSR file handler * \param rawData Pointer to raw run data handler * \param runNo Run number within the MSR file * \param tag Operation mode (kFit for fitting, kView for viewing) * \param theoAsData If true, calculate theory only at data points; if false, calculate additional points for Fourier */ PRunAsymmetryRRF(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData); /// Destructor virtual ~PRunAsymmetryRRF(); /** * \brief Calculates chi-square for the RRF asymmetry fit. * \param par Parameter vector from MINUIT * \return Chi-square value */ virtual Double_t CalcChiSquare(const std::vector& par); /** * \brief Calculates expected chi-square (for statistical analysis). * \param par Parameter vector from MINUIT * \return Expected chi-square value */ virtual Double_t CalcChiSquareExpected(const std::vector& par); /** * \brief Calculates maximum likelihood estimator. * \param par Parameter vector from MINUIT * \return Maximum likelihood value */ virtual Double_t CalcMaxLikelihood(const std::vector& par); /** * \brief Calculates theoretical RRF asymmetry function. * * Computes the theory values in the rotating reference frame based on * current parameters and applies the RRF transformation. */ virtual void CalcTheory(); /** * \brief Returns the number of bins used in the fit. * \return Number of fit bins */ virtual UInt_t GetNoOfFitBins(); /** * \brief Sets the fit range in bins (can be changed dynamically via COMMAND block). * \param fitRange Fit range string specification */ virtual void SetFitRangeBin(const TString fitRange); /** * \brief Returns the first bin used in the fit. * \return Start time bin index */ virtual Int_t GetStartTimeBin() { return fStartTimeBin; } /** * \brief Returns the last bin used in the fit. * \return End time bin index */ virtual Int_t GetEndTimeBin() { return fEndTimeBin; } /** * \brief Calculates the number of bins to be fitted. * * Determines fNoOfFitBins based on the fit range and RRF-packed data availability. */ virtual void CalcNoOfFitBins(); protected: /** * \brief Prepares all data for RRF fitting or viewing. * \return True on success, false on error * * Main data preparation routine that handles background subtraction, * RRF packing, and asymmetry calculation from forward/backward histograms. */ virtual Bool_t PrepareData(); /** * \brief Prepares RRF data specifically for fitting. * \return True on success, false on error * * Processes data for fitting, including RRF transformation, packing, * and asymmetry calculation with proper error propagation. */ virtual Bool_t PrepareFitData(); /** * \brief Prepares RRF data for viewing/plotting. * \param runData Pointer to raw run data * \param histoNo Array of histogram numbers [0]=forward, [1]=backward * \return True on success, false on error * * Similar to PrepareFitData but includes theory calculation and * Kaiser FIR filtering for smooth visualization of RRF curves. */ virtual Bool_t PrepareViewData(PRawRunData* runData, UInt_t histoNo[2]); private: UInt_t fAlphaBetaTag; ///< Tag indicating α/β configuration: 1=both unity, 2=α free/β unity, 3=α unity/β free, 4=both free UInt_t fNoOfFitBins; ///< Number of bins included in the fit after RRF packing Int_t fRRFPacking; ///< RRF packing factor from GLOBAL block (required for RRF analysis) Bool_t fTheoAsData; ///< If true, theory calculated only at data points; if false, extra points for nicer Fourier transforms PDoubleVector fForward; ///< Forward detector histogram data PDoubleVector fForwardErr; ///< Forward detector histogram errors PDoubleVector fBackward; ///< Backward detector histogram data PDoubleVector fBackwardErr; ///< Backward detector histogram errors Int_t fGoodBins[4]; ///< Good bin boundaries: [0]=forward first, [1]=forward last, [2]=backward first, [3]=backward last Int_t fStartTimeBin; ///< First bin index for fitting (after RRF transformation) Int_t fEndTimeBin; ///< Last bin index for fitting (after RRF transformation) /** * \brief Subtracts fixed background from histograms. * * Subtracts user-specified fixed background values from forward and backward histograms. * Background values are read from the MSR file (e.g., "backgr.fix 2 3" for forward/backward). * * Error propagation: * \f[ \Delta f_i^{\rm c} = \pm\sqrt{(\Delta f_i)^2 + (\Delta \mathrm{bkg})^2} = \pm\sqrt{f_i + \mathrm{bkg}} \f] * * \return True on success, false if background values are missing */ Bool_t SubtractFixBkg(); /** * \brief Estimates and subtracts background from histograms. * * Calculates background from a specified bin range (typically before t0) and subtracts it. * The background range is adjusted to align with accelerator beam cycles when applicable. * * \return True on success, false if background range is out of bounds */ Bool_t SubtractEstimatedBkg(); /** * \brief Retrieves proper t0 values for all histograms. * * Determines t0 (time zero) values for forward and backward histograms from * RUN block, GLOBAL block, or data file (in priority order). * * \param runData Pointer to raw run data containing histogram information * \param globalBlock Pointer to global MSR block with default t0 values * \param forwardHisto Vector of forward histogram indices * \param backwardHistoNo Vector of backward histogram indices * \return True on success, false if t0 values cannot be determined */ virtual Bool_t GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &forwardHisto, PUIntVector &backwardHistoNo); /** * \brief Retrieves proper data range for histograms. * * Determines the "good bins" range for data analysis from RUN block, * GLOBAL block, or estimates (in priority order). * * \param runData Pointer to raw run data * \param histoNo Array of histogram numbers [0]=forward, [1]=backward * \return True on success, false on error */ virtual Bool_t GetProperDataRange(PRawRunData* runData, UInt_t histoNo[2]); /** * \brief Determines the proper fit range from global block. * * Extracts fit range settings from the GLOBAL block if not specified in the RUN block. * The fit range defines the time window used for χ² minimization. * * \param globalBlock Pointer to global MSR block containing default fit range */ virtual void GetProperFitRange(PMsrGlobalBlock *globalBlock); }; #endif // _PRUNASYMMETRYRRF_H_