Files
musrfit/src/include/PRunListCollection.h

791 lines
33 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/***************************************************************************
PRunListCollection.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 _PRUNLISTCOLLECTION_H_
#define _PRUNLISTCOLLECTION_H_
#include <vector>
#include "PMusr.h"
#include "PMsrHandler.h"
#include "PRunDataHandler.h"
#include "PRunSingleHisto.h"
#include "PRunSingleHistoRRF.h"
#include "PRunAsymmetry.h"
#include "PRunAsymmetryRRF.h"
#include "PRunAsymmetryBNMR.h"
#include "PRunMuMinus.h"
#include "PRunNonMusr.h"
/**
* \brief Manager class for all processed μSR run data during fitting.
*
* PRunListCollection is the central orchestrator for musrfit, managing all processed
* run data and serving as the interface between the MINUIT minimizer and the various
* run types. It acts as a container and dispatcher for different fit types, routing
* χ² and maximum likelihood calculations to the appropriate run objects.
*
* \section architecture Architecture
*
* The collection maintains separate lists for each fit type:
* - <b>Single Histogram:</b> Basic time-differential μSR (one detector)
* - <b>Single Histogram RRF:</b> Single detector in rotating reference frame
* - <b>Asymmetry:</b> Forward-backward asymmetry fits
* - <b>Asymmetry RRF:</b> Asymmetry in rotating reference frame
* - <b>Asymmetry β-NMR:</b> Beta-detected NMR asymmetry
* - <b>Mu-Minus:</b> Negative muon fits (different lifetime)
* - <b>Non-μSR:</b> General time-series data fits
*
* \section responsibilities Core Responsibilities
*
* <b>Run management:</b>
* - Creating and storing PRunBase-derived objects for each run
* - Organizing runs by fit type for efficient access
* - Managing run lifetime and cleanup
*
* <b>MINUIT interface:</b>
* - Aggregating χ² from all runs of each type
* - Providing maximum likelihood calculations
* - Supporting both global fits (all runs) and single run evaluation
* - Calculating degrees of freedom (total bins fitted)
*
* <b>Fit range management:</b>
* - Dynamically updating fit ranges via COMMAND block
* - Supporting both time-based and bin-based range specifications
* - Applying ranges to appropriate run lists
*
* <b>Data access:</b>
* - Retrieving processed data for plotting
* - Accessing metadata (field, temperature, energy)
* - Supporting access by index or run number
*
* \section workflow Typical Workflow
*
* 1. <b>Construction:</b> Pass MSR handler and data handler
* 2. <b>Add runs:</b> Call Add() for each RUN block to create appropriate run objects
* 3. <b>Fitting:</b> MINUIT calls Get*Chisq() methods to evaluate fit quality
* 4. <b>Visualization:</b> Retrieve processed data via Get*() methods for plotting
*
* \section fit_types Fit Type Dispatching
*
* The collection routes operations based on fit type:
* - <b>fittype 0:</b> Single histogram → fRunSingleHistoList
* - <b>fittype 1:</b> Asymmetry → fRunAsymmetryList
* - <b>fittype 2:</b> Single histogram RRF → fRunSingleHistoRRFList
* - <b>fittype 3:</b> Asymmetry RRF → fRunAsymmetryRRFList
* - <b>fittype 4:</b> Mu-minus → fRunMuMinusList
* - <b>fittype 5:</b> β-NMR asymmetry → fRunAsymmetryBNMRList
* - <b>fittype 6:</b> Non-μSR → fRunNonMusrList
*
* \section global_fits Global Fitting
*
* For global fits (multiple runs sharing parameters):
* - Get*Chisq() methods sum χ² over all runs of that type
* - Each run is fitted with the same parameter set
* - Total χ² = Σ χ²_i across all runs
* - Degrees of freedom = Σ N_bins,i - N_parameters
*
* \section example_usage Example Usage
*
* \code
* // Create collection
* PRunListCollection collection(msrInfo, dataHandler);
*
* // Add all runs from MSR file
* for (UInt_t i = 0; i < msrInfo->GetMsrRunList()->size(); i++) {
* collection.Add(i, kFit);
* }
*
* // MINUIT minimization (called internally)
* Double_t chisq = collection.GetAsymmetryChisq(parameters);
*
* // Retrieve data for plotting
* PRunData *data = collection.GetAsymmetry(0);
* \endcode
*
* \section thread_safety Thread Safety
* NOT thread-safe. MINUIT evaluation must be serialized. For parallel fitting
* of independent datasets, create separate PRunListCollection instances.
*
* \see PRunBase for individual run processing
* \see PMsrHandler for MSR file configuration
* \see PRunDataHandler for raw data access
*/
class PRunListCollection
{
public:
/**
* \brief Constructor that initializes the collection.
*
* Creates an empty collection ready to receive runs via Add(). Does not
* automatically load runs - caller must explicitly add each run.
*
* \param msrInfo Pointer to MSR file handler (must remain valid for object lifetime)
* \param data Pointer to raw data handler (must remain valid for object lifetime)
* \param theoAsData If true, theory calculated only at data points; if false, extra points for visualization
*/
PRunListCollection(PMsrHandler *msrInfo, PRunDataHandler *data, Bool_t theoAsdata=false);
/**
* \brief Virtual destructor that cleans up all run objects.
*
* Calls CleanUp() and destructor for all run objects in all lists.
* Clears all run vectors. Does NOT delete fMsrInfo or fData (owned externally).
*/
virtual ~PRunListCollection();
/**
* \brief Enumeration for data access mode.
*
* Controls how runs are retrieved by Get*() methods:
* - <b>kIndex:</b> Retrieve by position in the list (0-based)
* - <b>kRunNo:</b> Retrieve by run number from MSR file
*/
enum EDataSwitch { kIndex, kRunNo };
/**
* \brief Adds a run to the appropriate list based on fit type.
*
* Creates a PRunBase-derived object matching the fit type specified in the
* MSR file RUN block, processes the data, and adds it to the corresponding
* internal list. This is the primary method for populating the collection.
*
* The method:
* 1. Determines fit type from MSR RUN block (fittype 0-6)
* 2. Creates appropriate PRunBase-derived object (PRunAsymmetry, etc.)
* 3. Object loads and processes data in its constructor
* 4. Adds object to correct list (fRunAsymmetryList, etc.)
*
* \param runNo Run number (0-based index into MSR file RUN blocks)
* \param tag Operation mode: kFit (fitting), kView (visualization only)
* \return True if run added successfully, false if creation/processing failed
*
* \note Invalid runs (failed data loading) are still added but marked invalid
*/
virtual Bool_t Add(Int_t runNo, EPMusrHandleTag tag);
/**
* \brief Sets fit range for all runs (time-based or bin-based).
*
* Updates the fitting window for all runs in the collection. Supports:
* - Single range applied to all runs
* - Individual ranges per run
*
* \param fitRange Vector of (start, end) pairs in microseconds
*
* If one pair: applies to all runs. If multiple: fitRange[i] applies to run i.
*/
virtual void SetFitRange(const PDoublePairVector fitRange);
/**
* \brief Sets fit range from string specification (bin-based).
*
* Parses and applies bin-based fit ranges from FIT_RANGE command.
* Format: "fgb[+offset] lgb[-offset]" for each run.
*
* \param fitRange String with fit range specification
*
* Example: "10+5 200-10" → bins [15, 190]
*/
virtual void SetFitRange(const TString fitRange);
//--- Chi-square calculation methods (for global fits) ---
/**
* \brief Calculates total χ² for all single histogram runs.
*
* Sums χ² over all runs in fRunSingleHistoList. Each run compares its
* measured data with theory at the given parameters.
*
* \param par Parameter vector from MINUIT
* \return Σ χ²_i for all single histogram runs
*/
virtual Double_t GetSingleHistoChisq(const std::vector<Double_t>& par) const;
/** \brief Calculates total χ² for all single histogram RRF runs.
* \param par Parameter vector from MINUIT
* \return Σ χ²_i for all RRF single histogram runs */
virtual Double_t GetSingleHistoRRFChisq(const std::vector<Double_t>& par) const;
/** \brief Calculates total χ² for all asymmetry runs.
* \param par Parameter vector from MINUIT
* \return Σ χ²_i for all asymmetry runs */
virtual Double_t GetAsymmetryChisq(const std::vector<Double_t>& par) const;
/** \brief Calculates total χ² for all asymmetry RRF runs.
* \param par Parameter vector from MINUIT
* \return Σ χ²_i for all RRF asymmetry runs */
virtual Double_t GetAsymmetryRRFChisq(const std::vector<Double_t>& par) const;
/** \brief Calculates total χ² for all β-NMR asymmetry runs.
* \param par Parameter vector from MINUIT
* \return Σ χ²_i for all β-NMR runs */
virtual Double_t GetAsymmetryBNMRChisq(const std::vector<Double_t>& par) const;
/** \brief Calculates total χ² for all mu-minus runs.
* \param par Parameter vector from MINUIT
* \return Σ χ²_i for all mu-minus runs */
virtual Double_t GetMuMinusChisq(const std::vector<Double_t>& par) const;
/** \brief Calculates total χ² for all non-μSR runs.
* \param par Parameter vector from MINUIT
* \return Σ χ²_i for all non-μSR runs */
virtual Double_t GetNonMusrChisq(const std::vector<Double_t>& par) const;
//--- Single run chi-square methods ---
/**
* \brief Calculates expected χ² for a single run by index.
*
* Returns expected χ² based on theory and error estimates for one run.
* Useful for evaluating fit quality and error bar estimation.
*
* \param par Parameter vector from MINUIT
* \param idx Run index (searches all lists sequentially)
* \return Expected χ² for the specified run
*/
virtual Double_t GetSingleRunChisqExpected(const std::vector<Double_t>& par, const UInt_t idx) const;
/**
* \brief Calculates χ² for a single run by index.
*
* Evaluates χ² for one specific run, searching across all fit type lists.
* Used for individual run analysis or diagnostics.
*
* \param par Parameter vector from MINUIT
* \param idx Run index (absolute index across all run lists)
* \return χ² for the specified run
*/
virtual Double_t GetSingleRunChisq(const std::vector<Double_t>& par, const UInt_t idx) const;
//! \name Maximum Likelihood Calculation Methods (Global Fits)
//@{
/**
* \brief Calculates total maximum likelihood for all single histogram runs.
*
* Computes the negative 2×log-likelihood summed over all single histogram runs:
* \f[ -2\ln L_{\rm total} = \sum_{i=1}^{N_{\rm runs}} (-2\ln L_i) \f]
*
* For each run, the maximum likelihood is calculated using Poisson statistics:
* \f[ -2\ln L = 2\sum_{j=1}^{N_{\rm bins}} \left[y_j^{\rm theory} - y_j^{\rm data} \ln(y_j^{\rm theory})\right] \f]
*
* Maximum likelihood fitting is preferred over χ² for low-count data (< 10-20 counts/bin)
* where Gaussian approximations break down. It naturally handles Poisson statistics
* without requiring error estimates.
*
* \param par Parameter vector from MINUIT
* \return Total -2×ln(L) summed over all single histogram runs
*
* \see CalcMaxLikelihood() in PRunBase for implementation details
*/
virtual Double_t GetSingleHistoMaximumLikelihood(const std::vector<Double_t>& par) const;
/**
* \brief Calculates total maximum likelihood for all single histogram RRF runs.
*
* Computes -2×ln(L) summed over all single histogram rotating reference frame runs.
* Uses the same Poisson likelihood formula as GetSingleHistoMaximumLikelihood(),
* but applied to RRF-transformed data.
*
* \param par Parameter vector from MINUIT
* \return Total -2×ln(L) summed over all single histogram RRF runs
*/
virtual Double_t GetSingleHistoRRFMaximumLikelihood(const std::vector<Double_t>& par) const;
/**
* \brief Calculates total maximum likelihood for all asymmetry runs.
*
* Computes -2×ln(L) summed over all asymmetry runs. For asymmetry data,
* the likelihood is applied to the reconstructed forward/backward histograms
* rather than directly to the asymmetry values.
*
* \param par Parameter vector from MINUIT
* \return Total -2×ln(L) summed over all asymmetry runs
*/
virtual Double_t GetAsymmetryMaximumLikelihood(const std::vector<Double_t>& par) const;
/**
* \brief Calculates total maximum likelihood for all asymmetry RRF runs.
*
* Computes -2×ln(L) summed over all asymmetry rotating reference frame runs.
* Combines RRF transformation with asymmetry analysis in likelihood calculation.
*
* \param par Parameter vector from MINUIT
* \return Total -2×ln(L) summed over all asymmetry RRF runs
*/
virtual Double_t GetAsymmetryRRFMaximumLikelihood(const std::vector<Double_t>& par) const;
/**
* \brief Calculates total maximum likelihood for all β-NMR asymmetry runs.
*
* Computes -2×ln(L) summed over all beta-detected NMR asymmetry runs.
* Handles helicity-dependent measurements with appropriate likelihood formula.
*
* \param par Parameter vector from MINUIT
* \return Total -2×ln(L) summed over all β-NMR asymmetry runs
*/
virtual Double_t GetAsymmetryBNMRMaximumLikelihood(const std::vector<Double_t>& par) const;
/**
* \brief Calculates total maximum likelihood for all μ⁻ runs.
*
* Computes -2×ln(L) summed over all negative muon runs. Negative muons have
* different decay characteristics than positive muons.
*
* \param par Parameter vector from MINUIT
* \return Total -2×ln(L) summed over all μ⁻ runs
*/
virtual Double_t GetMuMinusMaximumLikelihood(const std::vector<Double_t>& par) const;
/**
* \brief Calculates total maximum likelihood for all non-μSR runs.
*
* Computes -2×ln(L) summed over all general time-series (non-μSR) data runs.
* Uses the same Poisson likelihood framework applied to generic x-y data.
*
* \param par Parameter vector from MINUIT
* \return Total -2×ln(L) summed over all non-μSR runs
*/
virtual Double_t GetNonMusrMaximumLikelihood(const std::vector<Double_t>& par) const;
//@}
//! \name Single Run Maximum Likelihood Methods
//@{
/**
* \brief Calculates expected maximum likelihood for a single run (theoretical expectation).
*
* Computes the expected -2×ln(L) value based on the theory predictions and error
* estimates for a specific run. Useful for statistical diagnostics and validating
* error bars. For properly estimated errors and valid model, expected likelihood
* should be comparable to actual likelihood.
*
* \param par Parameter vector from MINUIT
* \param idx Run index (absolute index across all run lists)
* \return Expected -2×ln(L) for the specified run
*
* \note Not all run types implement this method; some may return 0.0
*/
virtual Double_t GetSingleRunMaximumLikelihoodExpected(const std::vector<Double_t>& par, const UInt_t idx) const;
/**
* \brief Calculates maximum likelihood for a single run.
*
* Computes -2×ln(L) for a specific run identified by absolute index.
* This is useful for identifying problematic runs in a global fit or
* for analyzing individual run contributions to the total likelihood.
*
* \param par Parameter vector from MINUIT
* \param idx Run index (absolute index across all run lists)
* \return -2×ln(L) for the specified run
*/
virtual Double_t GetSingleRunMaximumLikelihood(const std::vector<Double_t>& par, const UInt_t idx) const;
//@}
//! \name Fit Statistics Methods
//@{
/**
* \brief Returns the number of bins fitted for a specific run.
*
* Queries a single run to determine how many data bins fall within its
* fit range. This depends on:
* - The fit time range (start/end times from FIT block)
* - Time resolution and bin packing settings
* - Valid data range after background subtraction
*
* Used for calculating degrees of freedom: ν = N_bins_total - N_params
*
* \param idx Run index (absolute index across all run lists)
* \return Number of bins included in the fit for this run
*
* \see GetTotalNoOfBinsFitted() for total across all runs
*/
virtual UInt_t GetNoOfBinsFitted(const UInt_t idx) const;
/**
* \brief Returns total number of bins fitted across all runs.
*
* Sums the number of fitted bins over all runs in the collection:
* \f[ N_{\rm bins,total} = \sum_{i=1}^{N_{\rm runs}} N_{\rm bins,i} \f]
*
* This is the numerator for calculating reduced chi-squared:
* \f[ \chi^2_{\rm red} = \frac{\chi^2}{N_{\rm bins,total} - N_{\rm params}} \f]
*
* For a good fit: χ²_red ≈ 1.0
*
* \return Total number of bins across all runs within fit ranges
*
* \see GetNoOfBinsFitted() for single run bin count
*/
virtual UInt_t GetTotalNoOfBinsFitted() const;
//@}
//! \name Run Count Accessors
//@{
/**
* \brief Returns the number of single histogram runs in the collection.
* \return Count of single histogram data sets from MSR file
*/
virtual UInt_t GetNoOfSingleHisto() const { return fRunSingleHistoList.size(); }
/**
* \brief Returns the number of single histogram RRF runs in the collection.
* \return Count of single histogram rotating reference frame data sets from MSR file
*/
virtual UInt_t GetNoOfSingleHistoRRF() const { return fRunSingleHistoRRFList.size(); }
/**
* \brief Returns the number of asymmetry runs in the collection.
* \return Count of asymmetry data sets from MSR file
*/
virtual UInt_t GetNoOfAsymmetry() const { return fRunAsymmetryList.size(); }
/**
* \brief Returns the number of asymmetry RRF runs in the collection.
* \return Count of asymmetry rotating reference frame data sets from MSR file
*/
virtual UInt_t GetNoOfAsymmetryRRF() const { return fRunAsymmetryRRFList.size(); }
/**
* \brief Returns the number of β-NMR asymmetry runs in the collection.
* \return Count of beta-detected NMR asymmetry data sets from MSR file
*/
virtual UInt_t GetNoOfAsymmetryBNMR() const { return fRunAsymmetryBNMRList.size(); }
/**
* \brief Returns the number of μ⁻ runs in the collection.
* \return Count of negative muon data sets from MSR file
*/
virtual UInt_t GetNoOfMuMinus() const { return fRunMuMinusList.size(); }
/**
* \brief Returns the number of non-μSR runs in the collection.
* \return Count of general time-series (non-μSR) data sets from MSR file
*/
virtual UInt_t GetNoOfNonMusr() const { return fRunNonMusrList.size(); }
//@}
//! \name Processed Data Accessors
//@{
/**
* \brief Retrieves processed data for a single histogram run.
*
* Provides access to the PRunData object containing background-corrected,
* packed histogram data with theory values and error bars.
*
* \param index Run identifier (interpretation depends on tag parameter)
* \param tag Access mode:
* - kIndex (default): Direct index into single histogram list (0-based)
* - kRunNumber: MSR file run number
* \return Pointer to PRunData object, or nullptr if index is invalid
*
* \see PRunData for data structure contents
*/
virtual PRunData* GetSingleHisto(UInt_t index, EDataSwitch tag=kIndex);
/**
* \brief Retrieves processed data for a single histogram RRF run.
*
* Provides access to RRF-transformed single histogram data including
* filtered theory curves and RRF-specific metadata.
*
* \param index Run identifier (interpretation depends on tag parameter)
* \param tag Access mode:
* - kIndex (default): Direct index into single histogram RRF list
* - kRunNumber: MSR file run number
* \return Pointer to PRunData object, or nullptr if index is invalid
*/
virtual PRunData* GetSingleHistoRRF(UInt_t index, EDataSwitch tag=kIndex);
/**
* \brief Retrieves processed data for an asymmetry run.
*
* Provides access to calculated asymmetry data with proper error propagation,
* including α-corrected forward/backward combinations.
*
* \param index Run identifier (interpretation depends on tag parameter)
* \param tag Access mode:
* - kIndex (default): Direct index into asymmetry list
* - kRunNumber: MSR file run number
* \return Pointer to PRunData object, or nullptr if index is invalid
*/
virtual PRunData* GetAsymmetry(UInt_t index, EDataSwitch tag=kIndex);
/**
* \brief Retrieves processed data for an asymmetry RRF run.
*
* Provides access to RRF-transformed asymmetry data combining asymmetry
* calculation with rotating reference frame analysis.
*
* \param index Run identifier (interpretation depends on tag parameter)
* \param tag Access mode:
* - kIndex (default): Direct index into asymmetry RRF list
* - kRunNumber: MSR file run number
* \return Pointer to PRunData object, or nullptr if index is invalid
*/
virtual PRunData* GetAsymmetryRRF(UInt_t index, EDataSwitch tag=kIndex);
/**
* \brief Retrieves processed data for a β-NMR asymmetry run.
*
* Provides access to beta-detected NMR asymmetry data with helicity-dependent
* analysis and appropriate error handling.
*
* \param index Run identifier (interpretation depends on tag parameter)
* \param tag Access mode:
* - kIndex (default): Direct index into β-NMR asymmetry list
* - kRunNumber: MSR file run number
* \return Pointer to PRunData object, or nullptr if index is invalid
*/
virtual PRunData* GetAsymmetryBNMR(UInt_t index, EDataSwitch tag=kIndex);
/**
* \brief Retrieves processed data for a μ⁻ run.
*
* Provides access to negative muon data accounting for different decay
* properties compared to positive muons.
*
* \param index Run identifier (interpretation depends on tag parameter)
* \param tag Access mode:
* - kIndex (default): Direct index into μ⁻ list
* - kRunNumber: MSR file run number
* \return Pointer to PRunData object, or nullptr if index is invalid
*/
virtual PRunData* GetMuMinus(UInt_t index, EDataSwitch tag=kIndex);
/**
* \brief Retrieves processed data for a non-μSR run.
*
* Provides access to general time-series data (x-y pairs) processed through
* the same framework as μSR data but without μSR-specific assumptions.
*
* \param index Run identifier (interpretation depends on tag parameter)
* \param tag Access mode:
* - kIndex (default): Direct index into non-μSR list
* - kRunNumber: MSR file run number
* \return Pointer to PRunData object, or nullptr if index is invalid
*/
virtual PRunData* GetNonMusr(UInt_t index, EDataSwitch tag=kIndex);
//@}
//! \name Experimental Metadata Accessors
//@{
/**
* \brief Retrieves temperature information for a specific run.
*
* Returns temperature data extracted from the raw data file header.
* Temperature may be recorded as a time-series (multiple values) or
* a single value depending on the data acquisition system.
*
* \param runName Run identifier string (e.g., "2425" or "/path/to/run2425.root")
* \return Pointer to vector of (time, temperature) pairs, or nullptr if not available
*
* \note Temperature units depend on the data file format (typically Kelvin or Celsius)
*/
virtual const PDoublePairVector *GetTemp(const TString &runName) const;
/**
* \brief Retrieves magnetic field value for a specific run.
*
* Returns the applied magnetic field extracted from the raw data file header.
* This is typically the field measured at the sample position.
*
* \param runName Run identifier string (e.g., "2425" or "/path/to/run2425.root")
* \return Magnetic field value in Gauss, or PMUSR_UNDEFINED if not available
*
* \note Field values may be recorded in various units (G, T, Oe) depending on facility
*/
virtual Double_t GetField(const TString &runName) const;
/**
* \brief Retrieves beam energy for a specific run.
*
* Returns the muon beam implantation energy extracted from the raw data file header.
* Energy determines the stopping profile (implantation depth) in the sample.
*
* \param runName Run identifier string (e.g., "2425" or "/path/to/run2425.root")
* \return Beam energy in keV, or PMUSR_UNDEFINED if not available
*
* \note Low-energy muons (LE-μSR) typically: 1-30 keV; surface muons: ~4 MeV
*/
virtual Double_t GetEnergy(const TString &runName) const;
/**
* \brief Retrieves experimental setup identifier for a specific run.
*
* Returns the beamline or spectrometer name extracted from the raw data file header.
* This identifies the experimental station where data was collected.
*
* \param runName Run identifier string (e.g., "2425" or "/path/to/run2425.root")
* \return Setup name string (e.g., "GPS", "LTF", "DOLLY"), or nullptr if not available
*
* \note Setup names are facility-specific (PSI: GPS, LTF, HAL-9500; ISIS: EMU, ARGUS, etc.)
*/
virtual const Char_t* GetSetup(const TString &runName) const;
/**
* \brief Retrieves x-axis label for plotting.
*
* Returns the appropriate x-axis title based on fit type and run settings.
* Typically "Time (μs)" for time-domain fits, "Frequency (MHz)" for Fourier transforms,
* or custom labels for non-μSR data.
*
* \param runName Run identifier string (e.g., "2425" or "/path/to/run2425.root")
* \param idx Run index within the specified fit type
* \return X-axis title string, or nullptr if not available
*
* \see PRunData for plot axis information storage
*/
virtual const Char_t* GetXAxisTitle(const TString &runName, const UInt_t idx) const;
/**
* \brief Retrieves y-axis label for plotting.
*
* Returns the appropriate y-axis title based on fit type:
* - Single histogram: "Counts" or "Positron Rate (MHz)"
* - Asymmetry: "Asymmetry" or "Asymmetry (%)"
* - Custom labels for non-μSR data
*
* \param runName Run identifier string (e.g., "2425" or "/path/to/run2425.root")
* \param idx Run index within the specified fit type
* \return Y-axis title string, or nullptr if not available
*
* \see PRunData for plot axis information storage
*/
virtual const Char_t* GetYAxisTitle(const TString &runName, const UInt_t idx) const;
//@}
private:
/**
* \brief Theory calculation mode flag.
*
* Controls whether theory is calculated at:
* - true: Only at data point times (efficient for fitting, exact data-theory comparison)
* - false: On a high-resolution grid (smooth curves for visualization)
*
* Set from MSR PLOT block. For fitting, always uses fTheoAsData=true internally
* regardless of this setting. This flag primarily affects plotting and export.
*/
Bool_t fTheoAsData;
/**
* \brief Pointer to MSR file handler (not owned).
*
* Provides access to all MSR file content including PARAMETER, THEORY, FUNCTIONS,
* RUN, COMMANDS, FOURIER, and PLOT blocks. Must remain valid for the lifetime
* of this PRunListCollection object.
*
* \warning This pointer is NOT owned by PRunListCollection and will not be deleted.
*/
PMsrHandler *fMsrInfo;
/**
* \brief Pointer to raw data handler (not owned).
*
* Provides access to raw histogram data files via unified interface supporting
* multiple formats (ROOT, NeXus, MUD, PSI-BIN, etc.). Used during Add() calls
* to load data for each run.
*
* \warning This pointer is NOT owned by PRunListCollection and will not be deleted.
*/
PRunDataHandler *fData;
/**
* \brief Collection of single histogram run objects.
*
* Each element is a PRunSingleHisto object containing processed data for one
* single-detector histogram fit. Objects are heap-allocated and owned by this
* vector; deleted in destructor.
*
* \see PRunSingleHisto for single histogram fit implementation
*/
std::vector<PRunSingleHisto*> fRunSingleHistoList;
/**
* \brief Collection of single histogram RRF run objects.
*
* Each element is a PRunSingleHistoRRF object containing RRF-transformed
* single histogram data with Kaiser filtering. Objects are owned by this vector.
*
* \see PRunSingleHistoRRF for RRF single histogram implementation
*/
std::vector<PRunSingleHistoRRF*> fRunSingleHistoRRFList;
/**
* \brief Collection of asymmetry run objects.
*
* Each element is a PRunAsymmetry object containing calculated asymmetry data
* from forward/backward detector pairs. Objects are owned by this vector.
*
* \see PRunAsymmetry for asymmetry fit implementation
*/
std::vector<PRunAsymmetry*> fRunAsymmetryList;
/**
* \brief Collection of asymmetry RRF run objects.
*
* Each element is a PRunAsymmetryRRF object combining asymmetry calculation
* with RRF transformation for high-frequency analysis. Objects are owned by this vector.
*
* \see PRunAsymmetryRRF for RRF asymmetry implementation
*/
std::vector<PRunAsymmetryRRF*> fRunAsymmetryRRFList;
/**
* \brief Collection of β-NMR asymmetry run objects.
*
* Each element is a PRunAsymmetryBNMR object for beta-detected NMR measurements
* with helicity-dependent analysis. Objects are owned by this vector.
*
* \see PRunAsymmetryBNMR for β-NMR asymmetry implementation
*/
std::vector<PRunAsymmetryBNMR*> fRunAsymmetryBNMRList;
/**
* \brief Collection of μ⁻ (negative muon) run objects.
*
* Each element is a PRunMuMinus object for negative muon measurements with
* different decay characteristics than μ⁺. Objects are owned by this vector.
*
* \see PRunMuMinus for negative muon fit implementation
*/
std::vector<PRunMuMinus*> fRunMuMinusList;
/**
* \brief Collection of non-μSR run objects.
*
* Each element is a PRunNonMusr object for general time-series (x-y) data fits
* using the musrfit framework without μSR-specific assumptions. Objects are owned.
*
* \see PRunNonMusr for generic time-series fit implementation
*/
std::vector<PRunNonMusr*> fRunNonMusrList;
};
#endif // _PRUNLISTCOLLECTION_H_