/*************************************************************************** PMusr.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 _PMUSR_H_ #define _PMUSR_H_ #include #include #include // the following ifdef is needed for GCC 4.6 or higher, fftw 3.3 or higher and root 5.30.03 or lower //#ifdef __CINT__ //typedef struct { char a[7]; } __float128; // needed since cint doesn't know it //#endif #include "fftw3.h" //------------------------------------------------------------- /** *

Return code constants for musrfit framework operations. * *

These constants define the return values for various operations * in the musrfit framework, where 0 indicates success and negative * values indicate different types of errors. */ /// Successful operation completion #define PMUSR_SUCCESS 0 /// Syntax help was requested via command line #define PMUSR_SYNTAX_REQUEST -1 /// Incorrect startup command syntax provided #define PMUSR_WRONG_STARTUP_SYNTAX -2 /// MSR file could not be found at specified path #define PMUSR_MSR_FILE_NOT_FOUND -3 /// Memory allocation error while processing MSR file #define PMUSR_MSR_ALLOCATION_ERROR -4 /// Syntax error detected in MSR file content #define PMUSR_MSR_SYNTAX_ERROR -5 /// Error during tokenization/parsing of input #define PMUSR_TOKENIZE_ERROR -6 /// Failed to write to MSR log file #define PMUSR_MSR_LOG_FILE_WRITE_ERROR -7 /// Failed to write MSR file #define PMUSR_MSR_FILE_WRITE_ERROR -8 /// Error reading data file (ROOT, NeXus, MUD, etc.) #define PMUSR_DATA_FILE_READ_ERROR -9 /// Error during run processing or fitting #define PMUSR_MSR_RUN_ERROR -10 /// Requested feature is not yet supported #define PMUSR_UNSUPPORTED_FEATURE -11 //------------------------------------------------------------- /** *

Run type identifiers for different μSR measurement configurations. * *

These constants specify the type of μSR experiment and determine * how raw histogram data should be processed and fitted. */ /// Single histogram fit (e.g., forward or backward detector) #define PRUN_SINGLE_HISTO 0 /// Single histogram fit in rotating reference frame (RRF) #define PRUN_SINGLE_HISTO_RRF 1 /// Asymmetry fit using forward and backward detectors #define PRUN_ASYMMETRY 2 /// Asymmetry fit in rotating reference frame (RRF) #define PRUN_ASYMMETRY_RRF 3 /// Negative muon (μ-) single histogram fit #define PRUN_MU_MINUS 4 /// Beta-detected NMR asymmetry fit #define PRUN_ASYMMETRY_BNMR 5 /// Non-μSR data fit (general x-y data) #define PRUN_NON_MUSR 8 //------------------------------------------------------------- /** *

Physical constants for muon experiments. * *

These fundamental constants are used throughout the framework * for lifetime corrections, field-frequency conversions, and other * physics calculations. */ /** *

Muon lifetime in microseconds (μs). * *

The mean lifetime of the positive muon (μ+) is 2.1969811 μs. * This value is used for lifetime corrections in single histogram fits. * *

Reference: * P. A. Zyla et al. (Particle Data Group), Prog. Theor. Exp. Phys. 2020, 083C01 (2020). * https://doi.org/10.1093/ptep/ptaa104 * https://pdg.lbl.gov/2021/ */ #define PMUON_LIFETIME 2.1969811 /** *

Muon gyromagnetic ratio γ_μ/(2π) in MHz/G. * *

The muon gyromagnetic ratio relates the muon spin precession frequency * to the applied magnetic field: ν = γ_μ/(2π) × B * *

Value: 0.013553880 94(30) MHz/G = 135.53880 94(30) MHz/T * *

Calculated from: γ_μ = 2.0 × μ_μ / ℏ where * - μ_μ = -4.490 448 30(10) × 10^-26 J/T (muon magnetic moment) * - ℏ = 1.054 571 817... × 10^-34 J·s (reduced Planck constant) * *

Reference: * E. Tiesinga et al., Rev. Mod. Phys. 93, 025010 (2021). * https://doi.org/10.1103/RevModPhys.93.025010 * https://physics.nist.gov/cuu/Constants/index.html */ #define GAMMA_BAR_MUON 1.355388094e-2 //------------------------------------------------------------- /** *

Accelerator cycle periods in microseconds (μs). * *

These constants define the beam structure period for different * μSR facilities, which is needed for proper background determination * in pulsed beam experiments. */ /// PSI (Paul Scherrer Institute) accelerator cycle: 19.75 ns #define ACCEL_PERIOD_PSI 0.01975 /// TRIUMF accelerator cycle: 43.37 ns #define ACCEL_PERIOD_TRIUMF 0.04337 /// RAL (Rutherford Appleton Lab) - pulsed beam #define ACCEL_PERIOD_RAL 0.0 //------------------------------------------------------------- /** *

Histogram offset for pileup-corrected data in ROOT files. * *

Post-pileup-corrected histograms are stored with an offset * of 20 added to the original histogram number to distinguish them * from uncorrected data. */ #define POST_PILEUP_HISTO_OFFSET 20 //------------------------------------------------------------- /** *

Sentinel value indicating undefined or uninitialized parameters. * *

This large negative value (-9.9×10^99) is used throughout the * framework to indicate that a parameter has not been set or is invalid. */ #define PMUSR_UNDEFINED -9.9e99 //------------------------------------------------------------- /** *

MSR file block header tags. * *

These constants identify the different sections in a musrfit * MSR (Muon Spin Rotation) file. Each tag corresponds to a specific * block that defines different aspects of the fit configuration. */ /// TITLE block - describes the experiment #define MSR_TAG_TITLE 0 /// FITPARAMETER block - defines fit parameters with initial values and constraints #define MSR_TAG_FITPARAMETER 1 /// THEORY block - specifies the theory function(s) to fit #define MSR_TAG_THEORY 2 /// FUNCTIONS block - user-defined mathematical functions #define MSR_TAG_FUNCTIONS 3 /// GLOBAL block - global fit settings (RRF, fit type, etc.) #define MSR_TAG_GLOBAL 4 /// RUN block - run-specific settings and data file information #define MSR_TAG_RUN 5 /// COMMANDS block - post-fit commands (e.g., parameter output) #define MSR_TAG_COMMANDS 6 /// FOURIER block - Fourier transform settings #define MSR_TAG_FOURIER 7 /// PLOT block - plotting configuration for data visualization #define MSR_TAG_PLOT 8 /// STATISTIC block - fit statistics and results (generated after fit) #define MSR_TAG_STATISTIC 9 //------------------------------------------------------------- /** *

MSR file fit type tags. * *

These constants specify the fit type in the GLOBAL or RUN blocks * of an MSR file. The fit type determines how raw data is converted * into the quantity to be fitted (single histogram, asymmetry, etc.). */ /// Fit single histogram (e.g., positron counts vs. time) #define MSR_FITTYPE_SINGLE_HISTO 0 /// Fit single histogram in rotating reference frame #define MSR_FITTYPE_SINGLE_HISTO_RRF 1 /// Fit asymmetry A(t) = (F-αB)/(F+αB) #define MSR_FITTYPE_ASYM 2 /// Fit asymmetry in rotating reference frame #define MSR_FITTYPE_ASYM_RRF 3 /// Fit negative muon (μ-) single histogram #define MSR_FITTYPE_MU_MINUS 4 /// Fit beta-detected NMR asymmetry #define MSR_FITTYPE_BNMR 5 /// Fit non-μSR data (general x-y data) #define MSR_FITTYPE_NON_MUSR 8 //------------------------------------------------------------- /** *

MSR file plot type tags. * *

These constants specify the plot type in the PLOT block * of an MSR file, determining how data should be displayed * in musrview or other visualization tools. */ /// Plot single histogram #define MSR_PLOT_SINGLE_HISTO 0 /// Plot single histogram in rotating reference frame #define MSR_PLOT_SINGLE_HISTO_RRF 1 /// Plot asymmetry #define MSR_PLOT_ASYM 2 /// Plot asymmetry in rotating reference frame #define MSR_PLOT_ASYM_RRF 3 /// Plot negative muon (μ-) data #define MSR_PLOT_MU_MINUS 4 /// Plot beta-detected NMR data #define MSR_PLOT_BNMR 5 /// Plot non-μSR data #define MSR_PLOT_NON_MUSR 8 //------------------------------------------------------------- /** *

Offsets for parameter parsing in MSR files. * *

When parameters are referenced via map functions or user-defined * functions, these offsets are added to distinguish them from direct * parameter references (which use indices 1, 2, 3, ...). */ /// Offset added to map indices for parameter parsing #define MSR_PARAM_MAP_OFFSET 10000 /// Offset added to function indices for parameter parsing #define MSR_PARAM_FUN_OFFSET 20000 //------------------------------------------------------------- /** *

Fourier transform unit tags. * *

These constants specify the units for Fourier transform * output in the FOURIER block of MSR files. */ /// Units not specified #define FOURIER_UNIT_NOT_GIVEN 0 /// Magnetic field in Gauss (G) #define FOURIER_UNIT_GAUSS 1 /// Magnetic field in Tesla (T) #define FOURIER_UNIT_TESLA 2 /// Frequency in MHz #define FOURIER_UNIT_FREQ 3 /// Angular frequency in Mc/s (Mega-cycles per second) #define FOURIER_UNIT_CYCLES 4 //------------------------------------------------------------- /** *

Fourier transform apodization tags. * *

Apodization (windowing) reduces spectral leakage in Fourier * transforms by applying a window function to the time-domain data. * Stronger apodization improves frequency resolution but reduces * signal amplitude accuracy. */ /// Apodization not specified #define FOURIER_APOD_NOT_GIVEN 0 /// No apodization (rectangular window) #define FOURIER_APOD_NONE 1 /// Weak apodization (gentle windowing) #define FOURIER_APOD_WEAK 2 /// Medium apodization (moderate windowing) #define FOURIER_APOD_MEDIUM 3 /// Strong apodization (heavy windowing for best frequency resolution) #define FOURIER_APOD_STRONG 4 //------------------------------------------------------------- /** *

Fourier transform plot type tags. * *

These constants specify which component(s) of the complex * Fourier transform should be displayed. */ /// Plot type not specified #define FOURIER_PLOT_NOT_GIVEN 0 /// Plot real component only #define FOURIER_PLOT_REAL 1 /// Plot imaginary component only #define FOURIER_PLOT_IMAG 2 /// Plot both real and imaginary components (default) #define FOURIER_PLOT_REAL_AND_IMAG 3 /// Plot power spectrum |F(ω)|² #define FOURIER_PLOT_POWER 4 /// Plot phase spectrum arg(F(ω)) #define FOURIER_PLOT_PHASE 5 /// Plot phase-optimized real component #define FOURIER_PLOT_PHASE_OPT_REAL 6 //------------------------------------------------------------- /** *

Rotating Reference Frame (RRF) unit tags. * *

In RRF analysis, data is transformed into a frame rotating at * a specified frequency/field. These tags specify the units for the * RRF frequency, which can be given as frequency or equivalent field. */ /// RRF unit undefined #define RRF_UNIT_UNDEF -1 /// Frequency in kHz (kilohertz) #define RRF_UNIT_kHz 0 /// Frequency in MHz (megahertz) #define RRF_UNIT_MHz 1 /// Angular frequency in Mc/s (Mega-cycles per second) #define RRF_UNIT_Mcs 2 /// Equivalent magnetic field in Gauss (G) #define RRF_UNIT_G 3 /// Equivalent magnetic field in Tesla (T) #define RRF_UNIT_T 4 /** *

Sentinel value indicating undefined RRF frequency. * *

This large value (10^10) marks an RRF frequency as uninitialized * or invalid. */ #define RRF_FREQ_UNDEF 1.0e10 //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of a bool vector. */ typedef std::vector PBoolVector; //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of an unsigned int vector */ typedef std::vector PUIntVector; //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of an int vector */ typedef std::vector PIntVector; //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of an int pair */ typedef std::pair PIntPair; //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of an int pair vector */ typedef std::vector PIntPairVector; //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of a double vector */ typedef std::vector PDoubleVector; //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of a double pair */ typedef std::pair PDoublePair; //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of a double pair vector */ typedef std::vector PDoublePairVector; //------------------------------------------------------------- /** *

typedef to make to code more readable. Definition of a string vector */ typedef std::vector PStringVector; //------------------------------------------------------------- /** *

Data handling mode tag for musrfit operations. * *

This enumeration specifies the operational mode of the musrfit * framework, determining whether data should be fitted, viewed, or * if no operation is active. */ enum EPMusrHandleTag { kEmpty, ///< No operation active kFit, ///< Fitting mode - perform least-squares fit to data kView ///< Viewing mode - display data and theory without fitting }; //------------------------------------------------------------- /** *

Metadata structure for user-defined FUNCTIONS block. * *

This structure stores experimental metadata (field, energy, temperature) * that can be accessed within user-defined functions in the FUNCTIONS block * of MSR files. This allows functions to depend on experimental conditions * without requiring additional fit parameters. * *

Example use case: A temperature-dependent relaxation rate can * be calculated using fTemp values rather than fitting temperature as a parameter. */ struct PMetaData { Double_t fField; ///< Applied magnetic field in Gauss (G) Double_t fEnergy; ///< Muon implantation energy in kiloelectronvolts (keV) PDoubleVector fTemp; ///< Vector of sample temperature(s) in Kelvin (K) }; //------------------------------------------------------------- /** *

Container for pre-processed data and theory vectors used in fitting. * *

This class stores the processed data (after background subtraction, * packing, asymmetry calculation, etc.) that is actually used in the fit, * along with the corresponding theory values. This is not raw histogram * data - it represents the final data points and theory that enter the χ² * calculation. * *

The class maintains separate time grids for data and theory, allowing * theory evaluation at higher resolution than the data binning. For non-μSR * fits, x-axis vectors are also stored. */ class PRunData { public: PRunData(); virtual ~PRunData(); /// Returns the start time of the data set in microseconds (μs) virtual Double_t GetDataTimeStart() { return fDataTimeStart; } /// Returns the time bin width for data in microseconds (μs) virtual Double_t GetDataTimeStep() { return fDataTimeStep; } /// Returns the start time for theory evaluation in microseconds (μs) virtual Double_t GetTheoryTimeStart() { return fTheoryTimeStart; } /// Returns the time step for theory evaluation in microseconds (μs) virtual Double_t GetTheoryTimeStep() { return fTheoryTimeStep; } /// Returns pointer to x-axis vector (used only for non-μSR data) virtual const PDoubleVector* GetX() { return &fX; } /// Returns pointer to data value vector (asymmetry, counts, or y-data) virtual const PDoubleVector* GetValue() { return &fValue; } /// Returns pointer to data error vector (statistical uncertainties) virtual const PDoubleVector* GetError() { return &fError; } /// Returns pointer to x-axis vector for theory (non-μSR only) virtual const PDoubleVector* GetXTheory() { return &fXTheory; } /// Returns pointer to theory value vector virtual const PDoubleVector* GetTheory() { return &fTheory; } /// Sets the start time of the data set in microseconds (μs) /// @param dval Start time value virtual void SetDataTimeStart(Double_t dval) { fDataTimeStart = dval; } /// Sets the time bin width for data in microseconds (μs) /// @param dval Time step value virtual void SetDataTimeStep(Double_t dval) { fDataTimeStep = dval; } /// Sets the start time for theory evaluation in microseconds (μs) /// @param dval Start time value virtual void SetTheoryTimeStart(Double_t dval) { fTheoryTimeStart = dval; } /// Sets the time step for theory evaluation in microseconds (μs) /// @param dval Time step value virtual void SetTheoryTimeStep(Double_t dval) { fTheoryTimeStep = dval; } /// Appends a value to the x-axis vector (non-μSR only) /// @param dval X-coordinate value to append virtual void AppendXValue(Double_t dval) { fX.push_back(dval); } /// Appends a value to the data vector /// @param dval Data value to append virtual void AppendValue(Double_t dval) { fValue.push_back(dval); } /// Appends an error value to the error vector /// @param dval Error/uncertainty value to append virtual void AppendErrorValue(Double_t dval) { fError.push_back(dval); } /// Appends a value to the theory x-axis vector (non-μSR only) /// @param dval X-coordinate value for theory virtual void AppendXTheoryValue(Double_t dval) { fXTheory.push_back(dval); } /// Appends a value to the theory vector /// @param dval Theory value to append virtual void AppendTheoryValue(Double_t dval) { fTheory.push_back(dval); } /** *

Sets a specific theory value at given index. * * @param i Index in theory vector * @param dval New theory value */ virtual void SetTheoryValue(UInt_t i, Double_t dval); /** *

Replaces the entire theory vector with a new one. * * @param theo New theory vector to replace current theory */ virtual void ReplaceTheory(const PDoubleVector &theo); private: // data related info Double_t fDataTimeStart; ///< start time for the data set Double_t fDataTimeStep; ///< time step for the data set, i.e. the time length of a bin PDoubleVector fX; ///< x-axis vector. Only used for non-muSR PDoubleVector fValue; ///< data vector PDoubleVector fError; ///< data error vector // theory related info Double_t fTheoryTimeStart; ///< start time of the theory Double_t fTheoryTimeStep; ///< time step of the theory, i.e. the time length of a bin PDoubleVector fXTheory; ///< x-axis vector. Only used for non-muSR PDoubleVector fTheory; ///< theory vector }; //------------------------------------------------------------- /** *

Container for non-μSR raw data (general x-y data sets). * *

This class handles raw data for non-μSR experiments (fit type NON_MUSR), * supporting both ASCII file input and database (db/dat) file formats. * It stores multiple data columns with labels, allowing general x-y fitting * beyond traditional μSR time histograms. * *

Use cases: Fitting arbitrary x-y data, susceptibility vs. temperature, * field scans, or any other non-time-domain measurements. */ class PNonMusrRawRunData { public: PNonMusrRawRunData(); virtual ~PNonMusrRawRunData(); /// Returns true if data was loaded from ASCII file, false for db/dat format virtual Bool_t FromAscii() { return fFromAscii; } /// Returns pointer to vector of axis/column labels virtual const PStringVector* GetLabels() { return &fLabels; } /// Returns pointer to vector of data tags (identifiers for each data column) virtual const PStringVector* GetDataTags() { return &fDataTags; } /// Returns pointer to vector of data columns virtual const std::vector* GetData() { return &fData; } /// Returns pointer to vector of error data columns virtual const std::vector* GetErrData() { return &fErrData; } /// Sets the flag indicating if data is from ASCII format /// @param bval True for ASCII, false for db/dat format virtual void SetFromAscii(const Bool_t bval) { fFromAscii = bval; } /** *

Pre-allocates space for a given number of data columns. * * @param size Number of data columns to allocate */ virtual void SetSize(const UInt_t size); /// Appends a label to the label vector /// @param str Label string (e.g., "Temperature (K)", "Field (G)") virtual void AppendLabel(const TString str) { fLabels.push_back(str); } /** *

Sets or replaces a label at specific index. * * @param idx Index in label vector * @param str New label string */ virtual void SetLabel(const UInt_t idx, const TString str); /// Appends a data tag identifier /// @param str Data tag string virtual void AppendDataTag(const TString str) { fDataTags.push_back(str); } /// Appends a complete data column vector /// @param data Data vector to append virtual void AppendData(const PDoubleVector &data) { fData.push_back(data); } /// Appends a complete error data column vector /// @param data Error data vector to append virtual void AppendErrData(const PDoubleVector &data) { fErrData.push_back(data); } /** *

Appends a single value to a specific data column. * * @param idx Index of data column * @param dval Data value to append */ virtual void AppendSubData(const UInt_t idx, const Double_t dval); /** *

Appends a single error value to a specific error data column. * * @param idx Index of error data column * @param dval Error value to append */ virtual void AppendSubErrData(const UInt_t idx, const Double_t dval); private: Bool_t fFromAscii; ///< if true: data file was an ascii input file, otherwise it is a db/dat input file PStringVector fLabels; ///< vector of all labels (used for x-, y-axis title in view) PStringVector fDataTags; ///< vector of all data tags std::vector fData; ///< vector of all data std::vector fErrData; ///< vector of all data errors }; //------------------------------------------------------------- /** *

Container for a single raw μSR histogram with associated metadata. * *

This class stores one raw histogram from a μSR experiment along with * essential information like time-zero bin, good data range, and background * range. It represents the most basic unit of μSR data before any processing * or corrections are applied. * *

Does not contain run header information (temperature, field, etc.) - * only the histogram data and its immediate properties. */ class PRawRunDataSet { public: PRawRunDataSet(); virtual ~PRawRunDataSet() { fData.clear(); } /// Returns the histogram title string virtual TString GetTitle() { return fTitle; } /// Returns the histogram name virtual TString GetName() { return fName; } /// Returns the histogram number as stored in the data file virtual Int_t GetHistoNo() { return fHistoNo; } /// Returns the time-zero bin (t0) position virtual Double_t GetTimeZeroBin() { return fTimeZeroBin; } /// Returns the estimated time-zero bin from automatic determination virtual Double_t GetTimeZeroBinEstimated() { return fTimeZeroBinEstimated; } /// Returns the first bin of good data range (after prompt peak) virtual Int_t GetFirstGoodBin() { return fFirstGoodBin; } /// Returns the last bin of good data range virtual Int_t GetLastGoodBin() { return fLastGoodBin; } /// Returns the first bin of background range virtual Int_t GetFirstBkgBin() { return fFirstBkgBin; } /// Returns the last bin of background range virtual Int_t GetLastBkgBin() { return fLastBkgBin; } /// Returns pointer to raw histogram data vector (counts per bin) virtual PDoubleVector *GetData() { return &fData; } /// Clears all data from this histogram set virtual void Clear(); /// Sets the histogram title /// @param str Title string virtual void SetTitle(TString str) { fTitle = str; } /// Sets the histogram name /// @param str Name string virtual void SetName(TString str) { fName = str; } /// Sets the histogram number /// @param no Histogram number from data file virtual void SetHistoNo(Int_t no) { fHistoNo = no; } /// Sets the time-zero bin position /// @param tzb Time-zero bin value (can be fractional) virtual void SetTimeZeroBin(Double_t tzb) { fTimeZeroBin = tzb; } /// Sets the estimated time-zero bin from automatic determination /// @param tzb Estimated time-zero bin value virtual void SetTimeZeroBinEstimated(Double_t tzb) { fTimeZeroBinEstimated = tzb; } /// Sets the first bin of good data range /// @param fgb First good bin index virtual void SetFirstGoodBin(Int_t fgb) { fFirstGoodBin = fgb; } /// Sets the last bin of good data range /// @param lgb Last good bin index virtual void SetLastGoodBin(Int_t lgb) { fLastGoodBin = lgb; } /// Sets the first bin of background range /// @param fbb First background bin index virtual void SetFirstBkgBin(Int_t fbb) { fFirstBkgBin = fbb; } /// Sets the last bin of background range (note: bug in original code sets fLastGoodBin) /// @param lbb Last background bin index virtual void SetLastBkgBin(Int_t lbb) { fLastGoodBin = lbb; } /// Sets the entire histogram data vector /// @param data Vector of histogram counts virtual void SetData(PDoubleVector data) { fData = data; } private: TString fTitle; ///< histogram title. TString fName; ///< keeps the histogram name. Int_t fHistoNo; ///< corresponds to the histogram number in the data file Double_t fTimeZeroBin; ///< keeps the time zero bin Double_t fTimeZeroBinEstimated; ///< keeps the estimated time zero bin Int_t fFirstGoodBin; ///< keeps the first good bin of the data set Int_t fLastGoodBin; ///< keeps the last good bin of the data set Int_t fFirstBkgBin; ///< keeps the first background bin of the data set Int_t fLastBkgBin; ///< keeps the last background bin of the data set PDoubleVector fData; ///< keeps the histogram data }; //------------------------------------------------------------- /** *

Vector container for multiple PRawRunDataSet objects with flexible indexing. * *

This class manages a collection of raw histogram data sets, providing * both sequential indexing (0, 1, 2, ...) and histogram-number-based access. * The flexible indexing is necessary because histogram numbers in data files * (especially MusrRoot files with Red/Green options) may not be contiguous. * *

Example: A MusrRoot file might contain histograms numbered * [1, 2, 5, 6] (Red group) and [21, 22, 25, 26] (Green group with offset). */ class PRawRunDataVector { public: PRawRunDataVector() {} virtual ~PRawRunDataVector() { fDataVec.clear(); } /// Returns the number of histogram data sets in this vector virtual UInt_t Size() { return fDataVec.size(); } /** *

Checks if a histogram with given number exists in the vector. * * @param histoNo Histogram number to search for * @return true if histogram is present, false otherwise */ virtual Bool_t IsPresent(UInt_t histoNo); /** *

Gets histogram data set by sequential index (0, 1, 2, ...). * * @param idx Sequential index in vector * @return Pointer to histogram data set, or nullptr if index out of range */ virtual PRawRunDataSet* GetSet(UInt_t idx); /** *

Gets histogram data set by histogram number. * * @param histoNo Histogram number from data file * @return Pointer to histogram data set, or nullptr if not found */ virtual PRawRunDataSet* Get(UInt_t histoNo); /** *

Operator overload for histogram-number-based access. * * @param histoNo Histogram number from data file * @return Pointer to histogram data set */ virtual PRawRunDataSet* operator[](UInt_t histoNo); /** *

Gets histogram data vector by histogram number. * * @param histoNo Histogram number * @return Pointer to data vector, or nullptr if not found */ virtual PDoubleVector* GetData(UInt_t histoNo); /** *

Gets time-zero bin for specified histogram. * * @param histoNo Histogram number * @return Time-zero bin value */ virtual Double_t GetT0Bin(UInt_t histoNo); /** *

Gets estimated time-zero bin for specified histogram. * * @param histoNo Histogram number * @return Estimated time-zero bin value */ virtual Double_t GetT0BinEstimated(UInt_t histoNo); /** *

Gets background bin range for specified histogram. * * @param histoNo Histogram number * @return Pair (first bin, last bin) of background range */ virtual PIntPair GetBkgBin(UInt_t histoNo); /** *

Gets good data bin range for specified histogram. * * @param histoNo Histogram number * @return Pair (first bin, last bin) of good data range */ virtual PIntPair GetGoodDataBin(UInt_t histoNo); /** *

Adds or updates a histogram data set in the vector. * * @param dataSet Histogram data set to add * @param idx Optional index; if -1 (default), appends to end */ virtual void Set(PRawRunDataSet dataSet, Int_t idx=-1); private: std::vector fDataVec; }; //------------------------------------------------------------- /** *

Complete raw data container for a single run. * *

This class stores all raw data and metadata for one experimental run, * including run header information (temperature, field, setup details), * histogram data (for μSR) or column data (for non-μSR), and data file * metadata. It serves as the primary interface between data file readers * and the fitting/analysis framework. * *

Supports multiple data formats: * - MusrRoot files (.root) * - NeXus files (.nxs) * - MUD files (.msr from TRIUMF) * - PSI binary files * - ASCII data files (for non-μSR) * - Database files (.db, .dat for non-μSR) */ class PRawRunData { public: PRawRunData(); virtual ~PRawRunData(); virtual const TString* GetVersion() { return &fVersion; } virtual const TString* GetGenericValidatorUrl() { return &fGenericValidatorURL; } virtual const TString* GetSpecificValidatorUrl() { return &fSpecificValidatorURL; } virtual const TString* GetGenerator() { return &fGenerator; } virtual const TString* GetComment() { return &fComment; } virtual const TString* GetFileName() { return &fFileName; } virtual const TString* GetLaboratory() { return &fLaboratory; } virtual const TString* GetBeamline() { return &fBeamline; } virtual const TString* GetInstrument() { return &fInstrument; } virtual const TString* GetRunName() { return &fRunName; } virtual const TString* GetMuonSource() { return &fMuonSource; } virtual const TString* GetMuonSpecies() { return &fMuonSpecies; } virtual const Double_t GetMuonBeamMomentum() { return fMuonBeamMomentum; } virtual const Double_t GetMuonSpinAngle() { return fMuonSpinAngle; } virtual const Int_t GetRunNumber() { return fRunNumber; } virtual const TString* GetRunTitle() { return &fRunTitle; } virtual const TString* GetSetup() { return &fSetup; } virtual const TString* GetStartTime() { return &fStartTime; } virtual const TString* GetStartDate() { return &fStartDate; } virtual const time_t GetStartDateTime() { return fStartDateTimeSec; } virtual const time_t CalcStartDateTime(bool &ok); virtual const TString* GetStopTime() { return &fStopTime; } virtual const TString* GetStopDate() { return &fStopDate; } virtual const time_t GetStopDateTime() { return fStopDateTimeSec; } virtual const time_t CalcStopDateTime(bool &ok); virtual const TString* GetCryoName() { return &fCryo; } virtual const TString* GetSample() { return &fSample; } virtual const TString* GetOrientation() { return &fOrientation; } virtual const TString* GetMagnetName() { return &fMagnet; } virtual const Double_t GetField() { return fField; } virtual const UInt_t GetNoOfTemperatures() { return fTemp.size(); } virtual const PDoublePairVector* GetTemperature() const { return &fTemp; } virtual const Double_t GetTemperature(const UInt_t idx); virtual const Double_t GetTempError(const UInt_t idx); virtual const Double_t GetEnergy() { return fEnergy; } virtual const Double_t GetTransport() { return fTransport; } virtual const PDoubleVector GetRingAnode() { return fRingAnode; } virtual const Double_t GetRingAnode(const UInt_t idx); virtual const Double_t GetTimeResolution() { return fTimeResolution; } virtual const Bool_t IsPresent(UInt_t histoNo) { return fData.IsPresent(histoNo); } virtual const Double_t GetT0Bin(const UInt_t histoNo) { return fData.GetT0Bin(histoNo); } virtual const Double_t GetT0BinEstimated(const UInt_t histoNo) { return fData.GetT0BinEstimated(histoNo); } virtual const PIntPair GetBkgBin(const UInt_t histoNo) { return fData.GetBkgBin(histoNo); } virtual const PIntPair GetGoodDataBin(const UInt_t histoNo) { return fData.GetGoodDataBin(histoNo); } virtual const PIntVector GetRedGreenOffset() { return fRedGreenOffset; } virtual const UInt_t GetNoOfHistos() { return fData.Size(); } virtual PRawRunDataSet* GetDataSet(const UInt_t idx, Bool_t wantHistoNo = true); virtual const PDoubleVector* GetDataBin(const UInt_t histoNo) { return fData.GetData(histoNo); } virtual const PNonMusrRawRunData* GetDataNonMusr() { return &fDataNonMusr; } virtual void SetVersion(const TString &str) { fVersion = str; } virtual void SetGenericValidatorUrl(const TString &str) { fGenericValidatorURL = str; } virtual void SetSpecificValidatorUrl(const TString &str) { fSpecificValidatorURL = str; } virtual void SetGenerator(const TString &str) { fGenerator = str; } virtual void SetComment(const TString &str) { fComment = str; } virtual void SetFileName(const TString &str) { fFileName = str; } virtual void SetLaboratory(const TString &str) { fLaboratory = str; } virtual void SetBeamline(const TString &str) { fBeamline = str; } virtual void SetInstrument(const TString &str) { fInstrument = str; } virtual void SetMuonSource(const TString &str) { fMuonSource = str; } virtual void SetMuonSpecies(const TString &str) { fMuonSpecies = str; } virtual void SetMuonBeamMomentum(const Double_t dval) { fMuonBeamMomentum = dval; } virtual void SetMuonSpinAngle(const Double_t dval) { fMuonSpinAngle = dval; } virtual void SetRunName(const TString &str) { fRunName = str; } virtual void SetRunNumber(const Int_t &val) { fRunNumber = val; } virtual void SetRunTitle(const TString str) { fRunTitle = str; } virtual void SetSetup(const TString str) { fSetup = str; } virtual void SetStartTime(const TString str) { fStartTime = str; } virtual void SetStartDate(const TString str) { fStartDate = str; } virtual void SetStartDateTime(const time_t val) { fStartDateTimeSec = val; } virtual void SetStopTime(const TString str) { fStopTime = str; } virtual void SetStopDate(const TString str) { fStopDate = str; } virtual void SetStopDateTime(const time_t val) { fStopDateTimeSec = val; } virtual void SetMagnetName(const TString str) { fMagnet = str; } virtual void SetField(const Double_t dval) { fField = dval; } virtual void SetCryoName(const TString str) { fCryo = str; } virtual void SetSample(const TString str) { fSample = str; } virtual void SetOrientation(const TString str) { fOrientation = str; } virtual void ClearTemperature() { fTemp.clear(); } virtual void SetTemperature(const UInt_t idx, const Double_t temp, const Double_t errTemp); virtual void SetTempError(const UInt_t idx, const Double_t errTemp); virtual void SetEnergy(const Double_t dval) { fEnergy = dval; } virtual void SetTransport(const Double_t dval) { fTransport = dval; } virtual void SetRingAnode(const UInt_t idx, const Double_t dval); virtual void SetTimeResolution(const Double_t dval) { fTimeResolution = dval; } virtual void SetRedGreenOffset(PIntVector &ivec) { fRedGreenOffset = ivec; } virtual void SetDataSet(PRawRunDataSet &dataSet, UInt_t idx=-1) { fData.Set(dataSet, idx); } PNonMusrRawRunData fDataNonMusr; ///< keeps all ascii- or db-file info in case of nonMusr fit private: TString fVersion; ///< keeps the version information of the data file TString fGenericValidatorURL; ///< keeps the generic validator MusrRoot URL TString fSpecificValidatorURL; ///< keeps the instrument specific validator MusrRoot URL TString fGenerator; ///< keeps the data file generator name TString fComment; ///< keeps the data file comment TString fFileName; ///< keeps the name of the original data file TString fLaboratory; ///< keeps the name of the laboratory, e.g. PSI, ISIS, TRIUMF, JPARC TString fBeamline; ///< keeps the name of the be beamline, e.g. muE4, piM3.1, ... TString fInstrument; ///< keeps the name of the instrument, e.g. LEM, GPS, MUSR, EMU, ... TString fMuonSource; ///< keeps the type of muon source, e.g. continous surface beam, pulsed beam, low energy muon beam TString fMuonSpecies; ///< positive muon or negative muon Double_t fMuonBeamMomentum; ///< given in MeV/c, for LEM this is the momentum of the secondary beamline and NOT the momentum of the low energy beam Double_t fMuonSpinAngle; ///< gives the muon spin angle in degrees (reference frame depends on the instrument) TString fRunName; ///< name of the run as found in the msr-file Int_t fRunNumber; ///< run number TString fRunTitle; ///< run title TString fSetup; ///< description of the setup of this run TString fStartTime; ///< start time of the run TString fStartDate; ///< start date of the run time_t fStartDateTimeSec; ///< start run given as time_t object TString fStopTime; ///< stop time of the run TString fStopDate; ///< stop date of the run time_t fStopDateTimeSec; ///< stop run given as time_t object TString fCryo; ///< name of the cryo TString fSample; ///< description of the sample TString fOrientation; ///< description of the orientation TString fMagnet; ///< name of the sample magnet Double_t fField; ///< magnetic field value in (G) PDoublePairVector fTemp; ///< measured temperatures and standard deviations during the run Double_t fEnergy; ///< implantation energy of the muon Double_t fTransport; ///< LEM transport settings (Moderator HV) PDoubleVector fRingAnode; ///< LEM ring anode HVs (L,R[,T,B]) Double_t fTimeResolution; ///< time resolution of the run in (ns) PIntVector fRedGreenOffset; ///< keeps the Red/Green offsets PRawRunDataVector fData; ///< keeps the histos together with the histo related properties such as T0, first good bin, etc. }; //------------------------------------------------------------- /** *

typedef to make to code more readable. A vector of a raw musr run. */ typedef std::vector PRawRunDataList; //------------------------------------------------------------- /** *

Helper structure for MSR file parsing. * *

Stores a single line from an MSR file along with its line number, * facilitating error reporting and maintaining correspondence between * parsed content and original file locations. */ struct PMsrLineStructure { Int_t fLineNo; ///< Line number in original MSR file (1-based) TString fLine; ///< Content of the MSR file line }; //------------------------------------------------------------- /** *

typedef to make to code more readable: list of msr-file lines. */ typedef std::vector PMsrLines; //------------------------------------------------------------- /** *

Structure defining a fit parameter in the FITPARAMETER block. * *

This structure contains all information about a single fit parameter: * its number, name, value, uncertainty, and optional constraints (boundaries). * Parameters can be fixed (fStep=0) or free (fStep>0), and may have asymmetric * errors after fitting. * *

Example MSR line: "3 alpha 1.0 0.1 0.5 1.5" defines parameter * #3 named "alpha" with value 1.0, step 0.1, and bounds [0.5, 1.5]. */ struct PMsrParamStructure{ Int_t fNoOfParams; ///< Total number of parameters in FITPARAMETER block Int_t fNo; ///< Parameter number (1, 2, 3, ...) TString fName; ///< Parameter name (e.g., "alpha", "lambda", "field") Double_t fValue; ///< Parameter value (initial or fitted) Double_t fStep; ///< Step size / error / negative error (context-dependent) Bool_t fPosErrorPresent; ///< True if positive error explicitly defined (asymmetric errors) Double_t fPosError; ///< Positive error for asymmetric uncertainties Bool_t fLowerBoundaryPresent; ///< True if lower bound constraint is active Double_t fLowerBoundary; ///< Lower boundary value for parameter constraints Bool_t fUpperBoundaryPresent; ///< True if upper bound constraint is active Double_t fUpperBoundary; ///< Upper boundary value for parameter constraints Bool_t fIsGlobal; ///< True if parameter is global (for msr2data global mode) }; //------------------------------------------------------------- /** *

typedef to make to code more readable: vector of fit parameters. */ typedef std::vector PMsrParamList; //------------------------------------------------------------- /** *

Container for GLOBAL block information in MSR files. * *

The GLOBAL block defines settings that apply to all RUN blocks, * including fit type, data ranges, time-zero bins, rotating reference * frame (RRF) parameters, and packing. This block is optional - if absent, * all settings must be specified individually in each RUN block. * *

Example use: When fitting multiple runs with identical * experimental setup, the GLOBAL block avoids repetition by centralizing * common parameters like RRF frequency, fit range, and t0 bins. */ class PMsrGlobalBlock { public: PMsrGlobalBlock(); virtual ~PMsrGlobalBlock() {} virtual Bool_t IsPresent() { return fGlobalPresent; } virtual Double_t GetRRFFreq(const char *unit); virtual TString GetRRFUnit(); virtual Int_t GetRRFUnitTag() { return fRRFUnitTag; } virtual Double_t GetRRFPhase() { return fRRFPhase; } virtual Int_t GetRRFPacking() { return fRRFPacking; } virtual Int_t GetFitType() { return fFitType; } virtual Int_t GetDataRange(UInt_t idx); virtual UInt_t GetT0BinSize() { return fT0.size(); } virtual Double_t GetT0Bin(UInt_t idx=0); virtual UInt_t GetAddT0BinEntries() { return fAddT0.size(); } virtual Int_t GetAddT0BinSize(UInt_t addRunIdx); virtual Double_t GetAddT0Bin(UInt_t addRunIdx, UInt_t histoIdx); virtual Bool_t IsFitRangeInBin() { return fFitRangeInBins; } virtual Double_t GetFitRange(UInt_t idx); virtual Int_t GetFitRangeOffset(UInt_t idx); virtual Int_t GetPacking() { return fPacking; } virtual Double_t GetEstimatedAlpha() { return fAlpha; } virtual void SetGlobalPresent(Bool_t bval) { fGlobalPresent = bval; } virtual void SetRRFFreq(Double_t freq, const char *unit); virtual void SetRRFPhase(Double_t phase) { fRRFPhase = phase; } virtual void SetRRFPacking(Int_t pack); virtual void SetFitType(Int_t ival) { fFitType = ival; } virtual void SetDataRange(Int_t ival, Int_t idx); virtual void SetT0Bin(Double_t dval, Int_t idx=-1); virtual void SetAddT0Bin(Double_t dval, UInt_t addRunIdx, UInt_t histoNoIdx); virtual void SetFitRangeInBins(Bool_t bval) { fFitRangeInBins = bval; } virtual void SetFitRange(Double_t dval, UInt_t idx); virtual void SetFitRangeOffset(Int_t ival, UInt_t idx); virtual void SetPacking(Int_t ival) { fPacking = ival; } private: Bool_t fGlobalPresent; ///< flag showing if a GLOBAL block is present at all. Double_t fRRFFreq; ///< RRF frequency given in units of (MHz, Mc, T) Int_t fRRFUnitTag; ///< RRF unit tag Double_t fRRFPhase; ///< RRF phase in (°) Int_t fRRFPacking; ///< RRF packing Int_t fFitType; ///< fit type: 0=single histo fit, 1=single histo RRF fit, 2=asymmetry fit, 4=mu^- single histo fit, 8=non muSR fit Int_t fDataRange[4]; ///< data bin range (fit type 0, 1, 2, 4) PDoubleVector fT0; ///< t0 bins (fit type 0, 1, 2, 4). if fit type 0 -> f0, f1, f2, ...; if fit type 2, 4 -> f0, b0, f1, b1, ... std::vector fAddT0; ///< addt0 bins (fit type 0, 1, 2, 4). if fit type 0 -> f0, f1, f2, ...; if fit type 2, 4 -> f0, b0, f1, b1, ... Bool_t fFitRangeInBins; ///< flag telling if fit range is given in time or in bins Double_t fFitRange[2]; ///< fit range in (us) Int_t fFitRangeOffset[2]; ///< if fit range is given in bins it can have the form fit fgb+n0 lgb-n1. This variable holds the n0 and n1. Int_t fPacking; ///< packing/rebinning Double_t fAlpha; ///< estimated alpha value from F/B counts }; //------------------------------------------------------------- /** *

Container for a single RUN block in MSR files. * *

Each RUN block defines one run or a group of runs to be fitted together, * specifying the data file(s), fit type, histogram selections, background * handling, time-zero bins, fit ranges, and theory-to-histogram mapping. * Multiple RUN blocks enable simultaneous fitting of related data sets. * *

Key features: * - Supports multiple data files (run name vector) * - Flexible histogram selection (forward/backward for asymmetry) * - Theory parameter mapping (allows parameter variations between runs) * - Background estimation or fixing * - Run-specific or global settings * *

Example: Fitting a field-dependent measurement where each run * has a different field value but shares common relaxation parameters. */ class PMsrRunBlock { public: PMsrRunBlock(); virtual ~PMsrRunBlock(); /** *

Cleans up and resets all data in the run block. */ virtual void CleanUp(); virtual UInt_t GetRunNameSize() { return fRunName.size(); } virtual TString *GetRunName(UInt_t idx=0); virtual UInt_t GetBeamlineSize() { return fBeamline.size(); } virtual TString *GetBeamline(UInt_t idx=0); virtual UInt_t GetInstituteSize() { return fInstitute.size(); } virtual TString *GetInstitute(UInt_t idx=0); virtual UInt_t GetFileFormatSize() { return fFileFormat.size(); } virtual TString *GetFileFormat(UInt_t idx=0); virtual Int_t GetFitType() { return fFitType; } virtual Int_t GetAlphaParamNo() { return fAlphaParamNo; } virtual Int_t GetBetaParamNo() { return fBetaParamNo; } virtual Int_t GetNormParamNo() { return fNormParamNo; } virtual Int_t GetBkgFitParamNo() { return fBkgFitParamNo; } virtual Int_t GetLifetimeParamNo() { return fLifetimeParamNo; } virtual Bool_t IsLifetimeCorrected() { return fLifetimeCorrection; } virtual PIntVector* GetMap() { return &fMap; } virtual Int_t GetMap(UInt_t idx); virtual UInt_t GetForwardHistoNoSize() { return fForwardHistoNo.size(); } virtual Int_t GetForwardHistoNo(UInt_t idx=0); virtual UInt_t GetBackwardHistoNoSize() { return fBackwardHistoNo.size(); } virtual Int_t GetBackwardHistoNo(UInt_t idx=0); virtual Double_t GetBkgEstimated(UInt_t idx); virtual Double_t GetBkgFix(UInt_t idx); virtual Int_t GetBkgRange(UInt_t idx); virtual Int_t GetDataRange(UInt_t idx); virtual UInt_t GetT0BinSize() { return fT0.size(); } virtual Double_t GetT0Bin(UInt_t idx=0); virtual UInt_t GetAddT0BinEntries() { return fAddT0.size(); } virtual Int_t GetAddT0BinSize(UInt_t addRunIdx); virtual Double_t GetAddT0Bin(UInt_t addRunIdx, UInt_t histoIdx); virtual Bool_t IsFitRangeInBin() { return fFitRangeInBins; } virtual Double_t GetFitRange(UInt_t idx); virtual Int_t GetFitRangeOffset(UInt_t idx); virtual Int_t GetPacking() { return fPacking; } virtual Double_t GetEstimatedAlpha() { return fAlpha; } virtual Int_t GetXDataIndex() { return fXYDataIndex[0]; } virtual Int_t GetYDataIndex() { return fXYDataIndex[1]; } virtual TString* GetXDataLabel() { return &fXYDataLabel[0]; } virtual TString* GetYDataLabel() { return &fXYDataLabel[1]; } virtual std::map *GetParGlobal() { return &fParGlobal; } virtual PIntVector *GetMapGlobal() { return &fMapGlobal; } virtual void SetRunName(TString &str, Int_t idx=-1); virtual void SetBeamline(TString &str, Int_t idx=-1); virtual void SetInstitute(TString &str, Int_t idx=-1); virtual void SetFileFormat(TString &str, Int_t idx=-1); virtual void SetFitType(Int_t ival) { fFitType = ival; } virtual void SetAlphaParamNo(Int_t ival) { fAlphaParamNo = ival; } virtual void SetBetaParamNo(Int_t ival) { fBetaParamNo = ival; } virtual void SetNormParamNo(Int_t ival) { fNormParamNo = ival; } virtual void SetBkgFitParamNo(Int_t ival) { fBkgFitParamNo = ival; } virtual void SetLifetimeParamNo(Int_t ival) { fLifetimeParamNo = ival; } virtual void SetLifetimeCorrection(Bool_t bval) { fLifetimeCorrection = bval; } virtual void SetMap(Int_t mapVal, Int_t idx=-1); virtual void SetForwardHistoNo(Int_t histoNo, Int_t idx=-1); virtual void SetBackwardHistoNo(Int_t histoNo, Int_t idx=-1); virtual void SetBkgEstimated(Double_t dval, Int_t idx); virtual void SetEstimatedAlpha(Double_t dval); virtual void SetBkgFix(Double_t dval, Int_t idx); virtual void SetBkgRange(Int_t ival, Int_t idx); virtual void SetDataRange(Int_t ival, Int_t idx); virtual void SetT0Bin(Double_t dval, Int_t idx=-1); virtual void SetAddT0Bin(Double_t dval, UInt_t addRunIdx, UInt_t histoNoIdx); virtual void SetFitRangeInBins(Bool_t bval) { fFitRangeInBins = bval; } virtual void SetFitRange(Double_t dval, UInt_t idx); virtual void SetFitRangeOffset(Int_t ival, UInt_t idx); virtual void SetPacking(Int_t ival) { fPacking = ival; } virtual void SetXDataIndex(Int_t ival) { fXYDataIndex[0] = ival; } virtual void SetYDataIndex(Int_t ival) { fXYDataIndex[1] = ival; } virtual void SetXDataLabel(TString& str) { fXYDataLabel[0] = str; } virtual void SetYDataLabel(TString& str) { fXYDataLabel[1] = str; } virtual void SetParGlobal(const TString &str, Int_t ival); virtual void SetMapGlobal(UInt_t idx, Int_t ival); private: PStringVector fRunName; ///< name of the run file PStringVector fBeamline; ///< e.g. mue4, mue1, pim3, emu, m15, ... (former: run type) PStringVector fInstitute; ///< e.g. psi, ral, triumf (former: run format) PStringVector fFileFormat; ///< e.g. root, nexus, psi-bin, mud, ascii, db Int_t fFitType; ///< fit type: 0=single histo fit, 2=asymmetry fit, 4=mu^- single histo fit, 8=non muSR fit Int_t fAlphaParamNo; ///< alpha parameter number (fit type 2, 4) Int_t fBetaParamNo; ///< beta parameter number (fit type 2, 4) Int_t fNormParamNo; ///< N0 parameter number (fit type 0) Int_t fBkgFitParamNo; ///< background fit parameter number (fit type 0) Int_t fLifetimeParamNo; ///< muon lifetime parameter number (fit type 0) Bool_t fLifetimeCorrection; ///< lifetime correction flag for viewing (fit type 0) PIntVector fMap; ///< map vector needed to switch parameters for different runs within a single theory PIntVector fForwardHistoNo; ///< forward histogram number (fit type 0, 2, 4) PIntVector fBackwardHistoNo; ///< backward histogram number (fit type 2, 4) Double_t fBkgEstimated[2]; ///< keeps estimated background values (if present) Double_t fBkgFix[2]; ///< fixed background in (1/ns) (fit type 0, 2, 4) Int_t fBkgRange[4]; ///< background bin range (fit type 0, 2, 4) Int_t fDataRange[4]; ///< data bin range (fit type 0, 2, 4) PDoubleVector fT0; ///< t0 bins (fit type 0, 2, 4). if fit type 0 -> f0, f1, f2, ...; if fit type 2, 4 -> f0, b0, f1, b1, ... std::vector fAddT0; ///< t0 bins for addrun's Bool_t fFitRangeInBins; ///< flag telling if fit range is given in time or in bins Double_t fFitRange[2]; ///< fit range in (us) Int_t fFitRangeOffset[2]; ///< if fit range is given in bins it can have the form fit fgb+n0 lgb-n1. This variable holds the n0 and n1. Double_t fAlpha; ///< estimated alpha value from F/B counts Int_t fPacking; ///< packing/rebinning Int_t fXYDataIndex[2]; ///< used to get the data indices when using db-files (fit type 8) TString fXYDataLabel[2]; ///< used to get the indices via labels when using db-files (fit type 8) // Two members used for msr2data in the global mode: fParGlobal and fMapGlobal // These are intended to track global and run specific parameters used in the RUN blocks // Suggested keys for the std::map: (alpha, beta, norm, bkgfit, lifetime) // Suggested values for the std::map: 1 -> parameter is global // 0 -> parameter is run specific // -1 -> tag not present in the RUN block // The information about global parameters in the map line is stored in an std::vector which should have the same length as the map-vector // The values in this std::vector can be the same as for the std::map of the other parameters. std::map fParGlobal; ///< here is stored if the parameters used in the RUN block are global or not PIntVector fMapGlobal; ///< here is stored if the maps used in the RUN block are global or not }; //------------------------------------------------------------- /** *

typedef to make to code more readable: list of runs with its parameters. */ typedef std::vector PMsrRunList; //------------------------------------------------------------- /** *

Structure containing all FOURIER block settings. * *

The FOURIER block controls how Fourier transforms are performed * and displayed. It specifies units (field or frequency), DC correction, * zero-padding, apodization, phase corrections, and plot ranges. * *

Common use case: Converting time-domain μSR data to frequency * domain to identify precession frequencies and their distributions, * particularly useful for identifying field distributions in magnetic * samples or multiple muon stopping sites. */ struct PMsrFourierStructure { Bool_t fFourierBlockPresent; ///< flag indicating if a Fourier block is present in the msr-file Int_t fUnits; ///< flag used to indicate the units. 1=field units (G); 2=field units (T); 3=frequency units (MHz); 4=Mc/s Bool_t fDCCorrected; ///< if set true, the dc offset of the signal/theory will be removed before the FFT is made. Int_t fFourierPower; ///< i.e. zero padding up to 2^fFourierPower, default = 0 which means NO zero padding Int_t fApodization; ///< tag indicating the kind of apodization wished, 0=no appodization (default), 1=weak, 2=medium, 3=strong (for details see the docu) Int_t fPlotTag; ///< tag used for initial plot. 0=real, 1=imaginary, 2=real & imaginary (default), 3=power, 4=phase Int_t fPhaseRef; ///< phase reference for relative phase(s) PIntVector fPhaseParamNo; ///< parameter number(s) if used instead of a phase value PDoubleVector fPhase; ///< phase(s) Double_t fRangeForPhaseCorrection[2]; ///< field/frequency range for automatic phase correction Double_t fPlotRange[2]; ///< field/frequency plot range Double_t fPhaseIncrement; ///< phase increment for manual phase optimization }; //------------------------------------------------------------- /** *

Structure containing settings for a single PLOT block. * *

PLOT blocks define how data should be visualized in musrview, * specifying which runs to display, axis ranges, log scales, and * view-specific settings like RRF parameters. Multiple PLOT blocks * allow different visualizations of the same data set. * *

Example uses: * - Plotting multiple runs with common y-axis scale for comparison * - Creating separate plots for different time ranges (overview vs. detail) * - Applying different RRF frequencies to examine different frequency components */ struct PMsrPlotStructure{ Int_t fPlotType; ///< plot type Bool_t fLifeTimeCorrection; ///< needed for single histo. If yes, only the asymmetry is shown, otherweise the positron spectrum Bool_t fUseFitRanges; ///< yes -> use the fit ranges to plot the data, no (default) -> use range information if present Bool_t fLogX; ///< yes -> x-axis in log-scale, no (default) -> x-axis in lin-scale Bool_t fLogY; ///< yes -> y-axis in log-scale, no (default) -> y-axis in lin-scale Int_t fViewPacking; ///< -1 -> use the run packing to generate the view, otherwise is fViewPacking for the binning of ALL runs. PIntVector fRuns; ///< list of runs to be plotted PDoubleVector fTmin; ///< time minimum PDoubleVector fTmax; ///< time maximum PDoubleVector fYmin; ///< asymmetry/counts minimum PDoubleVector fYmax; ///< asymmetry/counts maximum UInt_t fRRFPacking; ///< rotating reference frame (RRF) packing Double_t fRRFFreq; ///< RRF frequency UInt_t fRRFUnit; ///< RRF frequency unit. 0=kHz, 1=MHz, 2=Mc/s, 3=Gauss, 4=Tesla Int_t fRRFPhaseParamNo; ///< parameter number if used instead of a RRF phase value Double_t fRRFPhase; ///< RRF phase }; //------------------------------------------------------------- /** *

typedef to make to code more readable: list of plots. */ typedef std::vector PMsrPlotList; //------------------------------------------------------------- /** *

Structure containing fit statistics and results. * *

The STATISTIC block is automatically generated after a successful * fit, containing χ² (or maximum likelihood), degrees of freedom, * expected values, and per-histogram statistics. This information * assesses the quality of fit and helps identify problematic data sets. * *

Note: This block is written by musrfit after fitting and * should not be manually edited in MSR files. */ struct PMsrStatisticStructure { Bool_t fValid; ///< flag showing if the statistics block is valid, i.e. a fit took place which converged PMsrLines fStatLines; ///< statistics block in msr-file clear text TString fDate; ///< string holding fitting date and time Bool_t fChisq; ///< flag telling if min = chi2 or min = max.likelihood Double_t fMin; ///< chisq or max. likelihood PDoubleVector fMinPerHisto; ///< chisq or max. likelihood per histo UInt_t fNdf; ///< number of degrees of freedom Double_t fMinExpected; ///< expected total chi2 or max. likelihood PDoubleVector fMinExpectedPerHisto; ///< expected pre histo chi2 or max. likelihood PUIntVector fNdfPerHisto; ///< number of degrees of freedom per histo }; //------------------------------------------------------------- /** *

Configuration structure for the any2many data format converter. * *

This structure contains all settings needed to convert μSR data * between different file formats (ROOT, NeXus, MUD, PSI-BIN, ASCII). * It supports batch conversion, rebinning, compression, and format-specific * options like histogram group selection for MusrRoot files. * *

Supported conversions: Any-to-any among ROOT, NeXus, MUD, * PSI-BIN, WKM, and ASCII formats. */ struct PAny2ManyInfo { Bool_t useStandardOutput{false}; ///< flag showing if the converted shall be sent to the standard output TString inFormat{""}; ///< holds the information about the input data file format TString outFormat{""}; ///< holds the information about the output data file format TString inTemplate{""}; ///< holds the input file template TString outTemplate{""}; ///< holds the output file template TString year{""}; ///< holds the information about the year to be used PUIntVector runList; ///< holds the run number list to be converted PIntVector groupHistoList; ///< holds the histo group list offset (used to define for MusrRoot files, what to be exported) PStringVector inFileName; ///< holds the file name of the input data file TString outFileName{""}; ///< holds the output file name PStringVector outPathFileName; ///< holds the out path/file name TString outPath{""}; ///< holds the output path UInt_t rebin{1}; ///< holds the number of bins to be packed UInt_t compressionTag{0}; ///< 0=no compression, 1=gzip compression, 2=bzip2 compression TString compressFileName{""}; ///< holds the name of the outputfile name in case of compression is used UInt_t idf{0}; ///< IDF version for NeXus files. }; //------------------------------------------------------------- /** *

Structure holding command-line startup options for musrfit. * *

Contains flags that control musrfit behavior based on command-line * arguments, such as whether to output expected χ² values or estimate * N0 for single histogram fits. */ struct PStartupOptions { Bool_t writeExpectedChisq; ///< if set to true, expected chisq and chisq per block will be written Bool_t estimateN0; ///< if set to true, for single histogram fits N0 will be estimated }; //------------------------------------------------------------- /** *

Parser for flexible number list specifications. * *

This utility class parses string representations of number lists * that combine three different notations: * - (i) Space-separated integers: "1 3 7 14" * - (ii) Range notation: "13-27" generates 13, 14, 15, ..., 26, 27 * - (iii) Sequence notation: "10:20:2" generates 10, 12, 14, 16, 18, 20 * *

These forms can be combined in a single string, e.g., * "1 5-8 10:20:2" produces [1, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20]. * *

Use cases: Specifying run numbers, histogram lists, or * parameter indices on command line or in configuration files. */ class PStringNumberList { public: /// Constructor from C string /// @param str String to parse PStringNumberList(char *str) { fString = str; } /// Constructor from std::string /// @param str String to parse PStringNumberList(std::string str) { fString = str; } virtual ~PStringNumberList() { fList.clear(); } /** *

Parses the input string and generates the number list. * * @param errorMsg Reference to string that will contain error message if parsing fails * @param ignoreFirstToken If true, skips the first space-separated token (useful when first token is a label) * @return true if parsing succeeded, false on error */ virtual bool Parse(std::string &errorMsg, bool ignoreFirstToken=false); /// Returns the parsed list of numbers /// @return Vector of unsigned integers extracted from input string virtual PUIntVector GetList() { return fList; } private: std::string fString; bool fIsValid; PUIntVector fList; virtual bool IsNumber(std::string &str) { return (str.find_first_not_of("0123456789") == std::string::npos); } virtual void StripSpaces(); }; //------------------------------------------------------------- /** *

Run name template for automatic file path construction. * *

This structure associates an instrument identifier with a file naming * template, enabling automatic construction of data file paths from run * numbers. Templates use placeholders that are replaced with actual run * numbers and years. * *

Example: For instrument "GPS" with template "/data/gps/%y/%r.root", * run 2425 in year 2023 becomes "/data/gps/2023/2425.root". */ struct PRunNameTemplate { TString instrument{""}; ///< Instrument identifier (e.g., "GPS", "LEM", "DOLLY") TString runNameTemplate{""}; ///< File path template with placeholders (%r=run, %y=year) }; //------------------------------------------------------------- /** *

typedef to make to code more readable: list of run name templates. */ typedef std::vector PRunNameTemplateList; #endif // _PMUSR_H_