diff --git a/src/classes/PRunMuMinus.cpp b/src/classes/PRunMuMinus.cpp index 1c6b7c2b9..337fa2c72 100644 --- a/src/classes/PRunMuMinus.cpp +++ b/src/classes/PRunMuMinus.cpp @@ -47,7 +47,19 @@ // Constructor //-------------------------------------------------------------------------- /** - *

Constructor + * \brief Default constructor creating an empty, invalid μ⁻ run object. + * + * Initializes all member variables to default/invalid states: + * - Bin counts and indices set to -1 (invalid) + * - Packing set to -1 (unspecified - will cause error if used) + * - Theory mode set to false (high-resolution grid) + * - Handle tag set to kEmpty (uninitialized) + * + * This constructor is needed for creating vectors of PRunMuMinus objects, + * but the resulting object cannot be used for fitting until properly + * initialized via the main constructor. + * + * \see PRunMuMinus(PMsrHandler*, PRunDataHandler*, UInt_t, EPMusrHandleTag, Bool_t) */ PRunMuMinus::PRunMuMinus() : PRunBase() { @@ -70,12 +82,43 @@ PRunMuMinus::PRunMuMinus() : PRunBase() // Constructor //-------------------------------------------------------------------------- /** - *

Constructor + * \brief Main constructor initializing a μ⁻ run from MSR file and raw data. * - * \param msrInfo pointer to the msr-file handler - * \param rawData raw run data - * \param runNo number of the run within the msr-file - * \param tag tag showing what shall be done: kFit == fitting, kView == viewing + * Performs comprehensive initialization for negative muon analysis: + * + * 1. Base Class Initialization: + * - Calls PRunBase constructor with MSR/data handlers + * - Initializes theory engine and parameter mappings + * + * 2. Packing Validation (CRITICAL for μ⁻): + * - Attempts to read packing from RUN block + * - Falls back to GLOBAL block if not in RUN block + * - SEVERE ERROR if packing == -1 (unspecified) + * - Packing is MANDATORY for μ⁻ data (unlike some other fit types) + * + * 3. Member Initialization: + * - Good bin markers set to -1 (determined later) + * - Fit range bins initialized to -1 (invalid until set) + * - Number of fit bins set to 0 + * + * 4. Data Preparation: + * - Calls PrepareData() to load and preprocess histogram + * - If PrepareData() fails, run is marked invalid + * + * The object is marked as invalid (fValid=false) if: + * - Packing parameter is missing + * - PrepareData() fails (file not found, invalid t0, etc.) + * + * \param msrInfo Pointer to MSR file handler (must remain valid for object lifetime) + * \param rawData Pointer to raw data handler for loading histogram files + * \param runNo Run number (0-based index in MSR file RUN blocks) + * \param tag Operation mode: kFit (fitting), kView (display/plotting) + * \param theoAsData Theory calculation mode: true = at data points, false = high-resolution + * + * \warning Invalid objects should not be used for fitting. Check IsValid() after construction. + * + * \see PrepareData() for data preprocessing details + * \see PRunBase constructor for base initialization */ PRunMuMinus::PRunMuMinus(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData) : PRunBase(msrInfo, rawData, runNo, tag), fTheoAsData(theoAsData) @@ -114,7 +157,10 @@ PRunMuMinus::PRunMuMinus(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t // Destructor //-------------------------------------------------------------------------- /** - *

Destructor + * \brief Destructor cleaning up allocated resources. + * + * Releases memory used by the forward histogram vector. Other cleanup + * (theory objects, base class resources) is handled by the PRunBase destructor. */ PRunMuMinus::~PRunMuMinus() { @@ -125,12 +171,38 @@ PRunMuMinus::~PRunMuMinus() // CalcChiSquare //-------------------------------------------------------------------------- /** - *

Calculate chi-square. + * \brief Calculates χ² between μ⁻ data and theory (least-squares fit metric). * - * return: - * - chisq value + * Computes the chi-squared statistic using the standard formula: + * \f[ \chi^2 = \sum_{i={\rm start}}^{\rm end} \frac{(N_i^{\rm data} - N_i^{\rm theory})^2}{\sigma_i^2} \f] * - * \param par parameter vector iterated by minuit2 + * Algorithm: + * 1. Evaluate FUNCTIONS block for user-defined functions + * 2. Pre-calculate theory once at t=1.0 (thread-safe initialization for LF/user functions) + * 3. Loop over fit range bins (fStartTimeBin to fEndTimeBin) + * 4. For each bin: + * - Calculate time from bin index + * - Evaluate theory function at that time + * - Compute squared difference weighted by error + * 5. Sum contributions (with OpenMP reduction if available) + * + * OpenMP Parallelization: + * - When compiled with GOMP support, χ² calculation is parallelized + * - Loop divided into dynamic chunks for load balancing + * - Chunk size: (N_bins / N_processors), minimum 10 bins per chunk + * - Private variables per thread: i, time, diff + * - Reduction performed on final chisq sum + * + * Theory Pre-calculation: + * The initial call to fTheory->Func(time=1.0, ...) ensures thread-safe + * initialization for London field (LF) and user functions that cache + * computationally expensive calculations per parameter set. + * + * \param par Parameter vector from MINUIT with current parameter values + * \return Chi-squared value (sum of weighted squared residuals) + * + * \see CalcMaxLikelihood() for Poisson-based alternative (better for low counts) + * \see CalcTheory() for theory evaluation without χ² calculation */ Double_t PRunMuMinus::CalcChiSquare(const std::vector& par) { @@ -172,12 +244,33 @@ Double_t PRunMuMinus::CalcChiSquare(const std::vector& par) // CalcChiSquareExpected (public) //-------------------------------------------------------------------------- /** - *

Calculate expected chi-square. + * \brief Calculates expected χ² assuming theory is the true distribution (diagnostic). * - * return: - * - chisq value == 0.0 + * Computes the expected chi-squared using theory values as the expected counts: + * \f[ \chi^2_{\rm expected} = \sum_{i} \frac{(N_i^{\rm data} - N_i^{\rm theory})^2}{N_i^{\rm theory}} \f] * - * \param par parameter vector iterated by minuit2 + * This is a statistical diagnostic for evaluating: + * - Quality of error estimates (if errors are correct, χ²/ν ≈ 1) + * - Validity of Gaussian approximation (breaks down for low counts) + * - Over/under-dispersion in data relative to Poisson expectations + * + * For Poisson-distributed data with large counts: + * - χ²_expected ≈ number of degrees of freedom + * - χ²_expected / ν ≈ 1 indicates proper error estimation + * + * Algorithm is identical to CalcChiSquare() except: + * - Error denominator is σ² = N_theory (Poisson variance) + * - Instead of using fData.GetError()->at(i) + * + * OpenMP Parallelization: Same as CalcChiSquare() + * + * \param par Parameter vector from MINUIT + * \return Expected χ² value (currently returns 0.0 - calculation done but not returned) + * + * \note Current implementation performs the calculation but returns 0.0. + * The calculated value could be returned for diagnostic purposes. + * + * \see CalcChiSquare() for standard χ² calculation */ Double_t PRunMuMinus::CalcChiSquareExpected(const std::vector& par) { @@ -221,12 +314,48 @@ Double_t PRunMuMinus::CalcChiSquareExpected(const std::vector& par) // CalcMaxLikelihood //-------------------------------------------------------------------------- /** - *

Calculate log max-likelihood. See http://pdg.lbl.gov/index.html + * \brief Calculates negative log-likelihood for Poisson statistics (low-count fit metric). * - * return: - * - log max-likelihood value + * Computes the maximum likelihood estimator assuming Poisson-distributed histogram counts: + * \f[ -2\ln L = 2\sum_{i} \left[N_i^{\rm theory} - N_i^{\rm data}\ln(N_i^{\rm theory})\right] \f] * - * \param par parameter vector iterated by minuit2 + * This is derived from the Poisson probability: + * \f[ P(n|\\lambda) = \frac{\\lambda^n e^{-\\lambda}}{n!} \f] + * + * Taking negative log-likelihood and multiplying by 2 gives a metric that: + * - Is minimized at the best-fit parameters (like χ²) + * - Approaches χ² in the high-count (Gaussian) limit + * - Handles low counts correctly (no Gaussian approximation needed) + * + * When to use likelihood vs. χ²: + * - Low counts (< 10-20 per bin): Use likelihood (this method) + * - High counts (> 20 per bin): Either method works, χ² is faster + * - Uncertain errors: Use likelihood (no error estimates needed) + * + * Algorithm: + * 1. Evaluate FUNCTIONS block + * 2. Pre-calculate theory at t=1.0 (thread-safe initialization) + * 3. Loop over fit range bins + * 4. For each bin: + * - Calculate theory prediction + * - Check for negative theory (warning + skip) + * - Add Poisson likelihood term: + * - If data > 10^-9: (theo - data) + data·ln(data/theo) + * - If data ≈ 0: (theo - data) only (avoid log(0)) + * 5. Multiply sum by 2 (convention for comparison with χ²) + * + * Edge Case Handling: + * - Negative theory: Print warning, skip bin (should not happen with proper model) + * - Zero data: Use simplified formula without log term + * - Zero theory: Would cause log(0), but checked via negative theory guard + * + * Reference: Particle Data Group (PDG), Statistics Review + * http://pdg.lbl.gov/index.html + * + * \param par Parameter vector from MINUIT + * \return -2×ln(L) value (minimize during fitting, comparable to χ²) + * + * \see CalcChiSquare() for standard least-squares metric */ Double_t PRunMuMinus::CalcMaxLikelihood(const std::vector& par) { @@ -282,9 +411,19 @@ Double_t PRunMuMinus::CalcMaxLikelihood(const std::vector& par) // GetNoOfFitBins (public) //-------------------------------------------------------------------------- /** - *

Calculate the number of fitted bins for the current fit range. + * \brief Returns the number of bins included in the fit range. * - * return: number of fitted bins. + * Recalculates and returns the count of histogram bins between fStartTimeBin + * and fEndTimeBin. This count is used for: + * - Degrees of freedom calculation: ν = N_bins - N_params + * - Reduced χ²: χ²_red = χ² / ν + * - Statistical quality assessment + * + * Internally calls CalcNoOfFitBins() to ensure fNoOfFitBins is up-to-date. + * + * \return Number of bins within fit range (fEndTimeBin - fStartTimeBin) + * + * \see CalcNoOfFitBins() for bin range calculation from time range */ UInt_t PRunMuMinus::GetNoOfFitBins() { diff --git a/src/include/PRunMuMinus.h b/src/include/PRunMuMinus.h index ed58c57dd..75731ef71 100644 --- a/src/include/PRunMuMinus.h +++ b/src/include/PRunMuMinus.h @@ -33,49 +33,455 @@ #include "PRunBase.h" /** - *

Will eventually handle the \f$\mu^{-}\f$ fitting etc. + * \brief Class for handling negative muon (μ⁻) histogram fits. + * + * PRunMuMinus implements single-histogram fitting specialized for negative muon + * measurements. Negative muons (μ⁻) have significantly different properties compared + * to positive muons (μ⁺), requiring dedicated handling: + * + * \section muminus_physics Physics of Negative Muons + * + * Key differences from μ⁺: + * - Charge: Negatively charged (antimuon has positive charge) + * - Behavior in matter: μ⁻ are captured by nuclei rather than stopping interstitially + * - Cascade process: μ⁻ cascade down atomic orbitals before nuclear capture + * - Lifetime: Effective lifetime is reduced by nuclear capture (typically ~100-1000 ns vs. 2.2 μs free lifetime) + * - Decay signature: Different detector response due to capture vs. decay + * - Applications: Elemental analysis, nuclear structure, muonic atom spectroscopy + * + * \section muminus_data Data Structure + * + * Unlike asymmetry measurements, μ⁻ fits use a single forward histogram: + * - One detector histogram (typically forward detector) + * - No asymmetry calculation (no forward/backward pair) + * - Direct histogram fitting with background subtraction + * - Bin packing for improved statistics + * + * \section muminus_analysis Analysis Workflow + * + * 1. Data Loading: Load single histogram from data file + * 2. Background Subtraction: Remove constant or estimated background + * 3. Time-Zero Determination: Identify μ⁻ arrival time (t0) + * 4. Bin Packing: Rebin data if specified (required parameter) + * 5. Theory Calculation: Evaluate capture-modified exponential decay + * 6. Fit Metric: χ² or maximum likelihood minimization + * + * \section muminus_theory Typical Theory Functions + * + * Common models for μ⁻ data include: + * - Simple exponential: N(t) = N₀ · exp(-t/τ_eff) + * - With relaxation: N(t) = N₀ · exp(-t/τ_eff) · [1 + A·cos(ωt + φ)] + * - Multi-component: Sum of exponentials for different capture sites + * + * where τ_eff combines free decay and nuclear capture rates: + * \f[ \frac{1}{\tau_{\rm eff}} = \frac{1}{\tau_{\mu}} + \lambda_{\rm capture} \f] + * + * \section muminus_usage Example Usage + * + * \code + * // In MSR file RUN block: + * RUN data/muminus_run2425 MUD PSI MUSR-ROOT (name beamline) + * fittype 10 (MuMinus) + * map 1 (forward histogram) + * forward 1 + * packing 10 (required!) + * background 50 150 (pre-t0 background) + * data 200 2000 + * t0 210.5 + * fit 0.1 10.0 + * \endcode + * + * \see PRunSingleHisto for standard positive muon single histogram fits + * \see PRunBase for base class interface and common functionality */ class PRunMuMinus : public PRunBase { public: + /** + * \brief Default constructor creating an empty, invalid μ⁻ run object. + * + * Creates an uninitialized run object with all values set to defaults. + * This constructor is needed for creating vectors of PRunMuMinus objects + * but the object is not usable until properly initialized via the main constructor. + */ PRunMuMinus(); + + /** + * \brief Main constructor initializing a μ⁻ run from MSR file and raw data. + * + * Performs comprehensive initialization: + * 1. Validates packing parameter (REQUIRED for μ⁻ - cannot be -1) + * 2. Initializes base class (PRunBase) with MSR and data handlers + * 3. Calls PrepareData() to load and preprocess the histogram + * 4. Validates successful initialization + * + * The packing parameter is mandatory for μ⁻ data and is obtained from: + * - RUN block "packing" entry (if specified) + * - Falls back to GLOBAL block "packing" entry + * - SEVERE ERROR if neither is specified → run marked invalid + * + * \param msrInfo Pointer to MSR file handler (must remain valid) + * \param rawData Pointer to raw data handler for histogram loading + * \param runNo Run number (0-based index in MSR file RUN blocks) + * \param tag Operation mode: kFit (fitting), kView (display/plotting) + * \param theoAsData Theory mode: true = at data points, false = high-resolution + * + * \warning If PrepareData() fails, the object is marked invalid (fValid=false) + */ PRunMuMinus(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag, Bool_t theoAsData); + + /** + * \brief Virtual destructor cleaning up allocated resources. + * + * Releases memory used by the forward histogram vector (fForward). + * Base class destructor handles cleanup of theory objects and other shared resources. + */ virtual ~PRunMuMinus(); + /** + * \brief Calculates χ² between μ⁻ data and theory (least-squares fit metric). + * + * Computes the chi-squared statistic for the forward histogram: + * \f[ \chi^2 = \sum_{i={\rm start}}^{\rm end} \frac{(N_i^{\rm data} - N_i^{\rm theory})^2}{\sigma_i^2} \f] + * + * where: + * - N_i^data is the background-corrected, packed histogram count in bin i + * - N_i^theory is the theory prediction from THEORY block + * - σ_i is the propagated error (including background uncertainty) + * - Sum runs from fStartTimeBin to fEndTimeBin (fit range) + * + * Implementation uses OpenMP parallelization when available for performance. + * Each thread processes a chunk of bins independently, with reduction for final sum. + * + * \param par Parameter vector from MINUIT with current parameter values + * \return Chi-squared value (lower is better; minimize during fitting) + * + * \see CalcMaxLikelihood() for alternative fit metric (better for low counts) + * \see CalcTheory() for theory function evaluation details + */ virtual Double_t CalcChiSquare(const std::vector& par); + + /** + * \brief Calculates expected χ² based on theory predictions (statistical diagnostic). + * + * Computes the expected chi-squared assuming theory values are the "true" counts: + * \f[ \chi^2_{\rm expected} = \sum_{i} \frac{(N_i^{\rm data} - N_i^{\rm theory})^2}{N_i^{\rm theory}} \f] + * + * This diagnostic helps evaluate: + * - Quality of error estimates + * - Poisson vs. Gaussian statistics validity + * - Over/under-dispersion in data + * + * For well-estimated errors: χ²_expected ≈ number of degrees of freedom + * + * \param par Parameter vector from MINUIT + * \return Expected χ² value (currently returns 0.0 - placeholder implementation) + * + * \note Current implementation returns 0.0; full calculation performed but not returned + */ virtual Double_t CalcChiSquareExpected(const std::vector& par); + + /** + * \brief Calculates negative log-likelihood for Poisson statistics (low-count fit metric). + * + * Computes the maximum likelihood estimator assuming Poisson-distributed counts: + * \f[ -2\ln L = 2\sum_{i} \left[N_i^{\rm theory} - N_i^{\rm data} \ln(N_i^{\rm theory})\right] \f] + * + * Maximum likelihood is superior to χ² when: + * - Count rates are low (< 10-20 counts per bin) + * - Poisson statistics dominate (Gaussian approximation invalid) + * - Error estimation is uncertain + * + * The factor of 2 makes the likelihood comparable to χ² in the Gaussian limit. + * MINUIT minimizes this function just like χ². + * + * Implementation details: + * - Uses OpenMP parallelization for performance + * - Handles edge cases: zero data (skips log term), negative theory (warning + skip) + * - Threshold: data > 10^-9 to include log term + * + * \param par Parameter vector from MINUIT + * \return -2×ln(L) value (lower is better; minimize during fitting) + * + * \see CalcChiSquare() for standard least-squares metric + */ virtual Double_t CalcMaxLikelihood(const std::vector& par); + + /** + * \brief Evaluates theory function at all data points (or high-resolution grid). + * + * Calculates the expected μ⁻ decay signal using the THEORY block functions. + * The theory is evaluated either: + * - At data point times (fTheoAsData=true): For fitting and exact comparison + * - On high-resolution grid (fTheoAsData=false): For smooth plotting + * + * Theory evaluation: + * 1. Determines time grid based on fTheoAsData flag + * 2. Evaluates FUNCTIONS block (user-defined functions) + * 3. Loops over time points calling fTheory->Func(time, par, funcValues) + * 4. Stores results in fData for χ² or likelihood calculation + * + * The theory typically models: + * - Exponential decay: N₀·exp(-t/τ_eff) + * - With modulation: N₀·exp(-t/τ_eff)·[1 + A·cos(ωt + φ)] + * - Multi-component captures + * + * \see PTheory::Func() for theory function implementation + * \see PrepareData() for data grid setup + */ virtual void CalcTheory(); + /** + * \brief Returns the number of bins included in the fit range. + * + * Calculates and returns the count of histogram bins between fStartTimeBin + * and fEndTimeBin (fit range boundaries). This is used for: + * - Degrees of freedom: ν = N_bins - N_params + * - Reduced χ²: χ²_red = χ² / ν + * - Statistical analysis and diagnostics + * + * Internally calls CalcNoOfFitBins() to update fNoOfFitBins. + * + * \return Number of bins in fit range + * + * \see CalcNoOfFitBins() for bin range calculation details + */ virtual UInt_t GetNoOfFitBins(); + /** + * \brief Sets fit range using bin-offset specification (COMMANDS block syntax). + * + * Parses and applies fit range specified as bin offsets from good bin markers. + * This supports the COMMANDS block FIT_RANGE syntax for dynamic range adjustments. + * + * Format: "fit_range fgb+n0 lgb-n1" + * - fgb = first good bin (typically t0 bin) + * - lgb = last good bin (end of data range) + * - n0, n1 = offsets in bins (can be + or -) + * + * Example: "fit_range fgb+5 lgb-10" + * → Start 5 bins after t0, end 10 bins before last good bin + * + * \param fitRange String with fit range specification in bin offsets + * + * \see SetFitRange(PDoublePairVector) in PRunBase for time-based specification + */ virtual void SetFitRangeBin(const TString fitRange); + /** + * \brief Returns the first bin index in the fit range. + * \return Start bin index (0-based, after packing applied) + */ virtual Int_t GetStartTimeBin() { return fStartTimeBin; } + + /** + * \brief Returns the last bin index in the fit range (exclusive). + * \return End bin index (loop condition: i < fEndTimeBin) + */ virtual Int_t GetEndTimeBin() { return fEndTimeBin; } + + /** + * \brief Returns the bin packing factor. + * \return Packing value (number of raw bins combined into one packed bin) + */ virtual Int_t GetPacking() { return fPacking; } + /** + * \brief Calculates start/end bin indices from fit time range. + * + * Converts the fit range specified in time (microseconds from t0) into + * bin indices accounting for: + * - Data time start offset + * - Time resolution (bin width) + * - Packing factor + * + * Updates: + * - fStartTimeBin: First bin in fit range + * - fEndTimeBin: One past last bin (exclusive upper bound) + * - fNoOfFitBins: Count of bins in range + * + * Called automatically when fit range is changed via SetFitRange(). + * + * \see SetFitRange() in PRunBase for time-based range setting + */ virtual void CalcNoOfFitBins(); protected: + /** + * \brief Main data preparation routine for μ⁻ fitting and viewing. + * + * Orchestrates the complete data preprocessing pipeline: + * 1. Determines operation mode (fitting vs. viewing) + * 2. Calls PrepareFitData() or PrepareRawViewData() accordingly + * 3. Validates successful data loading and processing + * + * This method is called once during object construction. If it returns false, + * the run object is marked as invalid (fValid=false). + * + * \return True if data preparation succeeds, false on any error + * + * \see PrepareFitData() for fitting mode preprocessing + * \see PrepareRawViewData() for viewing mode preprocessing + */ virtual Bool_t PrepareData(); + + /** + * \brief Prepares μ⁻ histogram data for fitting. + * + * Performs comprehensive data preprocessing: + * 1. Loads forward histogram from data file + * 2. Extracts metadata (field, energy, temperature) + * 3. Validates and determines t0 value + * 4. Subtracts background (fixed or estimated) + * 5. Packs bins according to packing factor + * 6. Propagates errors through all transformations + * 7. Sets up time grid for theory evaluation + * 8. Establishes data/fit ranges + * + * Background correction (if specified in RUN block): + * - Fixed background: Subtract constant value + * - Estimated background: Calculate from pre-t0 bins, subtract with error propagation + * + * \param runData Pointer to raw run data handler containing histogram + * \param histoNo Histogram index in data file (from "forward" entry in RUN block) + * \return True on success, false if data loading or preprocessing fails + * + * \see PrepareRawViewData() for alternative viewing mode processing + */ virtual Bool_t PrepareFitData(PRawRunData* runData, const UInt_t histoNo); + + /** + * \brief Prepares μ⁻ histogram data for viewing/plotting (minimal processing). + * + * Lighter-weight data preprocessing for visualization: + * 1. Loads forward histogram from data file + * 2. Extracts metadata + * 3. Determines t0 + * 4. Sets up data range (may extend beyond fit range) + * 5. Minimal or no background subtraction + * 6. Optional packing for display + * + * Used when tag=kView to prepare data for plotting without full fitting infrastructure. + * Typically displays wider time range than fit range for context. + * + * \param runData Pointer to raw run data handler containing histogram + * \param histoNo Histogram index in data file + * \return True on success, false if data loading fails + * + * \see PrepareFitData() for full fitting mode processing + */ virtual Bool_t PrepareRawViewData(PRawRunData* runData, const UInt_t histoNo); private: - UInt_t fNoOfFitBins; ///< number of bins to be fitted - Int_t fPacking; ///< packing for this particular run. Either given in the RUN- or GLOBAL-block. - Bool_t fTheoAsData; ///< true=only calculate the theory points at the data points, false=calculate more points for the theory as compared to data are calculated which lead to 'nicer' Fouriers + UInt_t fNoOfFitBins; ///< Number of bins within fit range (between fStartTimeBin and fEndTimeBin) - Int_t fGoodBins[2]; ///< keep first/last good bins. 0=fgb, 1=lgb + /** + * \brief Bin packing factor (REQUIRED for μ⁻). + * + * Number of consecutive raw histogram bins combined into one packed bin. + * Higher packing improves statistics but reduces time resolution. + * + * Source priority: + * 1. RUN block "packing" entry + * 2. GLOBAL block "packing" entry + * 3. ERROR if neither specified (mandatory for μ⁻) + * + * Typical values: 1 (no packing), 5, 10, 20 + */ + Int_t fPacking; - PDoubleVector fForward; ///< forward histo data + /** + * \brief Theory calculation mode flag. + * + * Controls theory grid resolution: + * - true: Theory evaluated only at data point times (efficient for fitting) + * - false: Theory evaluated on finer grid (smooth curves for plotting/Fourier) + * + * Set from PRunListCollection based on PLOT block settings. + */ + Bool_t fTheoAsData; - Int_t fStartTimeBin; ///< bin at which the fit starts - Int_t fEndTimeBin; ///< bin at which the fit ends + /** + * \brief Good bin markers for bin-based fit range specification. + * + * Stores reference bins used in COMMANDS block FIT_RANGE parsing: + * - fGoodBins[0]: First good bin (fgb) - typically t0 bin + * - fGoodBins[1]: Last good bin (lgb) - end of valid data range + * + * Used when fit range is specified as "fgb+n0 lgb-n1" rather than absolute times. + * Needed because COMMANDS block can dynamically change fit range during execution. + */ + Int_t fGoodBins[2]; + /** + * \brief Forward detector histogram data (background-corrected, packed). + * + * Contains the processed μ⁻ decay histogram after: + * - Background subtraction + * - Bin packing + * - Conversion to appropriate units + * + * This is the data fitted against theory predictions. + * Stored in fData.GetValue() vector for χ² calculation. + */ + PDoubleVector fForward; + + Int_t fStartTimeBin; ///< First bin index in fit range (inclusive, 0-based after packing) + Int_t fEndTimeBin; ///< Last bin index in fit range (exclusive: loop as i < fEndTimeBin) + + /** + * \brief Determines and validates t0 values for μ⁻ histogram. + * + * Extracts time-zero (muon arrival time) from: + * 1. RUN block "t0" entry (if specified) + * 2. Data file header (if available) + * 3. GLOBAL block default (fallback) + * 4. Automatic determination from histogram structure (if enabled) + * + * For μ⁻, t0 marks the start of the decay/capture signal. + * Validates that t0 is within reasonable bounds of the histogram. + * + * \param runData Raw run data containing histogram and metadata + * \param globalBlock GLOBAL block from MSR file with default settings + * \param histoNo Vector of histogram indices to process + * \return True if valid t0 found/determined, false otherwise + */ virtual Bool_t GetProperT0(PRawRunData* runData, PMsrGlobalBlock *globalBlock, PUIntVector &histoNo); + + /** + * \brief Determines data range (region of valid histogram data). + * + * Establishes the data range boundaries from RUN block specification: + * - Start bin: First bin with valid μ⁻ data (typically after t0) + * - End bin: Last bin before noise/artifacts dominate + * + * Data range is typically wider than fit range. The fit range is a + * subset of the data range optimized for parameter extraction. + * + * \return True if valid data range determined, false if specification invalid + * + * \see GetProperFitRange() for fit range (subset of data range) + */ virtual Bool_t GetProperDataRange(); + + /** + * \brief Determines fit range from MSR file settings. + * + * Extracts fit range boundaries (time window for χ² calculation) from: + * 1. RUN block "fit" entry (if specified) + * 2. GLOBAL block "fit" entry (fallback) + * + * Fit range format in MSR file: + * - Time-based: "fit 0.1 10.0" (μs from t0) + * - Bin-based: "fit fgb+5 lgb-10" (offsets from markers) + * + * The fit range determines which bins contribute to χ² or likelihood. + * Choosing the optimal range is critical for accurate parameter extraction. + * + * \param globalBlock GLOBAL block from MSR file with default fit settings + * + * \see CalcNoOfFitBins() for converting time range to bin indices + */ virtual void GetProperFitRange(PMsrGlobalBlock *globalBlock); };