Files
musrfit/src/include/PMusr.h

1444 lines
68 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.
/***************************************************************************
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 <vector>
#include <map>
#include <TString.h>
// 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"
//-------------------------------------------------------------
/**
* <p>Return code constants for musrfit framework operations.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Run type identifiers for different μSR measurement configurations.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Physical constants for muon experiments.
*
* <p>These fundamental constants are used throughout the framework
* for lifetime corrections, field-frequency conversions, and other
* physics calculations.
*/
/**
* <p>Muon lifetime in microseconds (μs).
*
* <p>The mean lifetime of the positive muon (μ+) is 2.1969811 μs.
* This value is used for lifetime corrections in single histogram fits.
*
* <p><b>Reference:</b>
* 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
/**
* <p>Muon gyromagnetic ratio γ_μ/(2π) in MHz/G.
*
* <p>The muon gyromagnetic ratio relates the muon spin precession frequency
* to the applied magnetic field: ν = γ_μ/(2π) × B
*
* <p>Value: 0.013553880 94(30) MHz/G = 135.53880 94(30) MHz/T
*
* <p>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)
*
* <p><b>Reference:</b>
* 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
//-------------------------------------------------------------
/**
* <p>Accelerator cycle periods in microseconds (μs).
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Histogram offset for pileup-corrected data in ROOT files.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Sentinel value indicating undefined or uninitialized parameters.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>MSR file block header tags.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>MSR file fit type tags.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>MSR file plot type tags.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Offsets for parameter parsing in MSR files.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Fourier transform unit tags.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Fourier transform apodization tags.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Fourier transform plot type tags.
*
* <p>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
//-------------------------------------------------------------
/**
* <p>Rotating Reference Frame (RRF) unit tags.
*
* <p>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
/**
* <p>Sentinel value indicating undefined RRF frequency.
*
* <p>This large value (10^10) marks an RRF frequency as uninitialized
* or invalid.
*/
#define RRF_FREQ_UNDEF 1.0e10
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of a bool vector.
*/
typedef std::vector<Bool_t> PBoolVector;
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of an unsigned int vector
*/
typedef std::vector<UInt_t> PUIntVector;
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of an int vector
*/
typedef std::vector<Int_t> PIntVector;
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of an int pair
*/
typedef std::pair<Int_t, Int_t> PIntPair;
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of an int pair vector
*/
typedef std::vector<PIntPair> PIntPairVector;
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of a double vector
*/
typedef std::vector<Double_t> PDoubleVector;
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of a double pair
*/
typedef std::pair<Double_t, Double_t> PDoublePair;
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of a double pair vector
*/
typedef std::vector<PDoublePair> PDoublePairVector;
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. Definition of a string vector
*/
typedef std::vector<TString> PStringVector;
//-------------------------------------------------------------
/**
* <p>Data handling mode tag for musrfit operations.
*
* <p>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
};
//-------------------------------------------------------------
/**
* <p>Metadata structure for user-defined FUNCTIONS block.
*
* <p>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.
*
* <p><b>Example use case:</b> 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)
};
//-------------------------------------------------------------
/**
* <p>Container for pre-processed data and theory vectors used in fitting.
*
* <p>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 <b>not</b> raw histogram
* data - it represents the final data points and theory that enter the χ²
* calculation.
*
* <p>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); }
/**
* <p>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);
/**
* <p>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
};
//-------------------------------------------------------------
/**
* <p>Container for non-μSR raw data (general x-y data sets).
*
* <p>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.
*
* <p><b>Use cases:</b> 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<PDoubleVector>* GetData() { return &fData; }
/// Returns pointer to vector of error data columns
virtual const std::vector<PDoubleVector>* 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; }
/**
* <p>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); }
/**
* <p>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); }
/**
* <p>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);
/**
* <p>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<PDoubleVector> fData; ///< vector of all data
std::vector<PDoubleVector> fErrData; ///< vector of all data errors
};
//-------------------------------------------------------------
/**
* <p>Container for a single raw μSR histogram with associated metadata.
*
* <p>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.
*
* <p>Does <b>not</b> 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
};
//-------------------------------------------------------------
/**
* <p>Vector container for multiple PRawRunDataSet objects with flexible indexing.
*
* <p>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.
*
* <p><b>Example:</b> 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(); }
/**
* <p>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);
/**
* <p>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);
/**
* <p>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);
/**
* <p>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);
/**
* <p>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);
/**
* <p>Gets time-zero bin for specified histogram.
*
* @param histoNo Histogram number
* @return Time-zero bin value
*/
virtual Double_t GetT0Bin(UInt_t histoNo);
/**
* <p>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);
/**
* <p>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);
/**
* <p>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);
/**
* <p>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<PRawRunDataSet> fDataVec;
};
//-------------------------------------------------------------
/**
* <p>Complete raw data container for a single run.
*
* <p>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.
*
* <p>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.
};
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable. A vector of a raw musr run.
*/
typedef std::vector<PRawRunData> PRawRunDataList;
//-------------------------------------------------------------
/**
* <p>Helper structure for MSR file parsing.
*
* <p>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
};
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable: list of msr-file lines.
*/
typedef std::vector<PMsrLineStructure> PMsrLines;
//-------------------------------------------------------------
/**
* <p>Structure defining a fit parameter in the FITPARAMETER block.
*
* <p>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.
*
* <p><b>Example MSR line:</b> "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)
};
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable: vector of fit parameters.
*/
typedef std::vector<PMsrParamStructure> PMsrParamList;
//-------------------------------------------------------------
/**
* <p>Container for GLOBAL block information in MSR files.
*
* <p>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.
*
* <p><b>Example use:</b> 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<PDoubleVector> 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
};
//-------------------------------------------------------------
/**
* <p>Container for a single RUN block in MSR files.
*
* <p>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.
*
* <p><b>Key features:</b>
* - 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
*
* <p><b>Example:</b> Fitting a field-dependent measurement where each run
* has a different field value but shares common relaxation parameters.
*/
class PMsrRunBlock {
public:
PMsrRunBlock();
virtual ~PMsrRunBlock();
/**
* <p>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<TString, Int_t> *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<PDoubleVector> 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<TString, Int_t> 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
};
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable: list of runs with its parameters.
*/
typedef std::vector<PMsrRunBlock> PMsrRunList;
//-------------------------------------------------------------
/**
* <p>Structure containing all FOURIER block settings.
*
* <p>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.
*
* <p><b>Common use case:</b> 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
};
//-------------------------------------------------------------
/**
* <p>Structure containing settings for a single PLOT block.
*
* <p>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.
*
* <p><b>Example uses:</b>
* - 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
};
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable: list of plots.
*/
typedef std::vector<PMsrPlotStructure> PMsrPlotList;
//-------------------------------------------------------------
/**
* <p>Structure containing fit statistics and results.
*
* <p>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.
*
* <p><b>Note:</b> 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
};
//-------------------------------------------------------------
/**
* <p>Configuration structure for the any2many data format converter.
*
* <p>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.
*
* <p><b>Supported conversions:</b> 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.
};
//-------------------------------------------------------------
/**
* <p>Structure holding command-line startup options for musrfit.
*
* <p>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
};
//-------------------------------------------------------------
/**
* <p>Parser for flexible number list specifications.
*
* <p>This utility class parses string representations of number lists
* that combine three different notations:
* - <b>(i)</b> Space-separated integers: "1 3 7 14"
* - <b>(ii)</b> Range notation: "13-27" generates 13, 14, 15, ..., 26, 27
* - <b>(iii)</b> Sequence notation: "10:20:2" generates 10, 12, 14, 16, 18, 20
*
* <p>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].
*
* <p><b>Use cases:</b> 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(); }
/**
* <p>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();
};
//-------------------------------------------------------------
/**
* <p>Run name template for automatic file path construction.
*
* <p>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.
*
* <p><b>Example:</b> 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)
};
//-------------------------------------------------------------
/**
* <p>typedef to make to code more readable: list of run name templates.
*/
typedef std::vector<PRunNameTemplate> PRunNameTemplateList;
#endif // _PMUSR_H_