From 7762f69c24721e7064daa45540812c35306fe9de Mon Sep 17 00:00:00 2001 From: Andreas Suter Date: Fri, 14 Nov 2025 09:22:24 +0100 Subject: [PATCH] improve doxygen documentation of PMsrHandler.* --- src/classes/PMsrHandler.cpp | 167 +++++++++++++++++++++++++++++++----- src/include/PMsrHandler.h | 149 +++++++++++++++++++++++--------- 2 files changed, 257 insertions(+), 59 deletions(-) diff --git a/src/classes/PMsrHandler.cpp b/src/classes/PMsrHandler.cpp index 9133dd4ab..963cb1cc3 100644 --- a/src/classes/PMsrHandler.cpp +++ b/src/classes/PMsrHandler.cpp @@ -45,13 +45,28 @@ // Constructor //-------------------------------------------------------------------------- /** - *

Constructor + * \brief Constructor that initializes the MSR handler. * - * \param fileName name of a msr-file. + * Initializes all internal data structures and extracts the directory path + * from the MSR file name. The directory path is used for resolving relative + * paths in the MSR file (e.g., for data files). + * + * Initialization includes: + * - Setting default values for all MSR blocks + * - Initializing statistics structure (invalid, χ² mode, min=-1, ndf=0) + * - Extracting file directory path from file name + * - Setting block counter to 0 + * + * \param fileName Path to MSR file (absolute or relative) + * \param startupOptions Optional pointer to startup configuration from musrfit_startup.xml + * \param fourierOnly If true, only parse Fourier-related blocks (used by musrFT tool) + * + * \note If fileName contains "/" characters, the directory path is extracted + * and stored in fMsrFileDirectoryPath; otherwise defaults to "./" */ PMsrHandler::PMsrHandler(const Char_t *fileName, PStartupOptions *startupOptions, const Bool_t fourierOnly) : fFourierOnly(fourierOnly), fStartupOptions(startupOptions), fFileName(fileName) -{ +{ // init variables fMsrBlockCounter = 0; @@ -83,7 +98,19 @@ PMsrHandler::PMsrHandler(const Char_t *fileName, PStartupOptions *startupOptions // Destructor //-------------------------------------------------------------------------- /** - *

Destructor + * \brief Destructor that cleans up all data structures. + * + * Clears all vectors and releases memory: + * - Parameter list + * - Theory lines + * - Functions lines + * - Run configurations + * - MINUIT commands + * - Plot settings + * - Statistics data + * - Parameter usage flags + * + * The unique_ptr member (fFuncHandler) is automatically cleaned up. */ PMsrHandler::~PMsrHandler() { @@ -103,11 +130,46 @@ PMsrHandler::~PMsrHandler() // ReadMsrFile (public) //-------------------------------------------------------------------------- /** - *

Reads and parses a msr-file. + * \brief Reads and parses the MSR file. * - *

return: - * - PMUSR_SUCCESS if everything is OK - * - line number if an error in the MSR file was encountered which cannot be handled. + * Performs comprehensive parsing of all MSR file blocks in the following order: + * 1. TITLE - File description + * 2. FITPARAMETER - Fit parameters with values, errors, and constraints + * 3. THEORY - Asymmetry/relaxation function definitions + * 4. FUNCTIONS (optional) - User-defined mathematical functions + * 5. GLOBAL (optional) - Global fit settings + * 6. RUN - Data file specifications and fit ranges + * 7. COMMANDS - MINUIT fitting commands + * 8. FOURIER (optional) - Fourier transform parameters + * 9. PLOT (optional) - Plotting parameters + * 10. STATISTIC - Fit results (χ², NDF, convergence) + * + * After parsing, performs extensive validation: + * - Checks for legacy lifetimecorrection syntax + * - Validates RUN block integrity (required fields, grouping consistency) + * - Verifies parameter name uniqueness + * - Checks map index validity + * - Validates user-defined functions + * - Verifies histogram grouping consistency + * - Checks addrun parameter references + * - Validates RRF (Rotating Reference Frame) settings + * - Checks real FFT requirements + * - Validates maximum likelihood settings + * + * Error Handling: + * - Detailed error messages are written to stderr + * - Error messages are accumulated in fLastErrorMsg for programmatic access + * - Returns line number where error occurred for syntax errors + * + * \return + * - PMUSR_SUCCESS (0) if parsing succeeded + * - PMUSR_MSR_FILE_NOT_FOUND if file cannot be opened + * - PMUSR_MSR_SYNTAX_ERROR if syntax error encountered + * - Positive line number if parsing error occurred at specific line + * + * \note In Fourier-only mode (fFourierOnly=true), only relevant blocks are parsed + * + * \see HandleFitParameterEntry, HandleTheoryEntry, HandleRunEntry for block parsing */ Int_t PMsrHandler::ReadMsrFile() { @@ -341,15 +403,42 @@ Int_t PMsrHandler::ReadMsrFile() // WriteMsrLogFile (public) //-------------------------------------------------------------------------- /** - *

Writes a mlog-file. + * \brief Writes an MSR log file (.mlog) with parsed MSR content. * - *

return: - * - PMUSR_SUCCESS everything is OK - * - PMUSR_MSR_LOG_FILE_WRITE_ERROR msr-/mlog-file couldn't be opened - * - PMUSR_MSR_SYNTAX_ERROR a syntax error has been encountered + * Creates a log file with the same base name as the MSR file but with .mlog + * extension. The log file contains the parsed and formatted MSR structure, + * which is useful for: + * - Debugging MSR file parsing + * - Verifying parameter interpretation + * - Checking fit range calculations + * - Reviewing theory and function definitions * - * \param messages if true some additional messages concerning the statistic block are written. - * When using musrt0, messages will be set to false. + * The log file format mirrors the MSR file structure but with: + * - Standardized formatting and precision + * - Expanded parameter values + * - Calculated fit ranges (in bins and microseconds) + * - Resolved function definitions + * - Complete statistics (if available) + * + * Processing includes: + * - Re-reading original MSR file to preserve comments and structure + * - Identifying missing tags (t0, background, data) in RUN blocks + * - Formatting numeric values with appropriate precision + * - Writing all MSR blocks in canonical format + * + * \param messages If true, includes additional informational messages about + * the statistics block. Set to false when called from musrt0 + * to suppress messages. + * + * \return + * - PMUSR_SUCCESS if log file written successfully + * - PMUSR_MSR_LOG_FILE_WRITE_ERROR if MSR or log file cannot be opened + * - PMUSR_MSR_SYNTAX_ERROR if syntax error encountered during processing + * + * \note The log file name is constructed by replacing the MSR file extension + * with ".mlog" (e.g., "run1234.msr" → "run1234.mlog") + * + * \see WriteMsrFile for writing updated MSR files */ Int_t PMsrHandler::WriteMsrLogFile(const Bool_t messages) { @@ -1549,13 +1638,51 @@ Int_t PMsrHandler::WriteMsrLogFile(const Bool_t messages) // WriteMsrFile (public) //-------------------------------------------------------------------------- /** - *

Writes a msr-file from the internal data structures + * \brief Writes an MSR file from internal data structures. * - *

return: - * - PMUSR_SUCCESS everything is OK - * - PMUSR_MSR_FILE_WRITE_ERROR msr output file couldn't be opened + * Creates a complete MSR file with all blocks, typically called after fitting + * to save updated parameter values, errors, and fit statistics. The file + * includes properly formatted blocks in the standard MSR file order. * - * \param filename The name of the output file. + * **MSR File Structure Written:** + * 1. TITLE block + * 2. FITPARAMETER block (with fitted values and errors) + * 3. THEORY block + * 4. FUNCTIONS block (if functions are defined) + * 5. GLOBAL block (if global settings exist) + * 6. RUN blocks (one per run) + * 7. COMMANDS block + * 8. FOURIER block (if Fourier parameters are defined) + * 9. PLOT blocks (if plot settings exist) + * 10. STATISTIC block (with fit results) + * + * **Comment Preservation:** + * The comment maps allow preserving user comments from specific MSR blocks. + * Comments are inserted before the corresponding line based on the map key + * (line number). This is useful when updating MSR files while maintaining + * documentation. + * + * **Formatting:** + * - Parameters: Right-aligned numbers, left-aligned names and values + * - Precision: 6 significant digits for floating-point values + * - Boundaries: Properly formatted lower/upper limits + * - Separators: Dashed lines between major sections + * + * \param filename Output MSR file path + * \param commentsPAR Optional map of line number → comment for FITPARAMETER block + * \param commentsTHE Optional map of line number → comment for THEORY block + * \param commentsFUN Optional map of line number → comment for FUNCTIONS block + * \param commentsRUN Optional map of line number → comment for RUN blocks + * + * \return + * - PMUSR_SUCCESS if file written successfully + * - PMUSR_MSR_FILE_WRITE_ERROR if output file cannot be opened + * + * \note Comments are removed from the maps after being written + * \note The STATISTIC block content depends on fCopyStatisticsBlock flag + * + * \see WriteMsrLogFile for writing debug/verification log files + * \see SetMsrStatisticMin, SetMsrStatisticNdf for updating statistics */ Int_t PMsrHandler::WriteMsrFile(const Char_t *filename, std::map *commentsPAR, \ std::map *commentsTHE, \ diff --git a/src/include/PMsrHandler.h b/src/include/PMsrHandler.h index 0e6593717..de7ec2d29 100644 --- a/src/include/PMsrHandler.h +++ b/src/include/PMsrHandler.h @@ -45,32 +45,73 @@ //------------------------------------------------------------- /** - *

MSR file parser and manager for musrfit framework. + * \brief MSR file parser and manager for the musrfit framework. * - *

This class handles all MSR (Muon Spin Rotation) file operations including: - * - Reading and parsing MSR files - * - Writing MSR files and log files - * - Validating MSR file content (parameter ranges, theory consistency, etc.) - * - Managing fit parameters, theory definitions, run configurations - * - Evaluating user-defined functions - * - Handling parameter mapping between runs + * PMsrHandler is the central class for managing MSR (Muon Spin Rotation/Relaxation) + * files used throughout the musrfit suite. It provides comprehensive functionality for: * - *

The PMsrHandler performs comprehensive validation during parsing, checking for: - * - Parameter name uniqueness - * - Valid theory-to-parameter mappings - * - Histogram grouping consistency - * - RRF (Rotating Reference Frame) settings - * - Function syntax and parameter usage + * **File Operations:** + * - Reading and parsing MSR files with full syntax validation + * - Writing MSR files with fitted parameters and statistics + * - Generating log files (.mlog) for debugging + * - Preserving user comments during file I/O * - *

Usage pattern: - * @code - * PMsrHandler handler("myfile.msr"); + * **Data Management:** + * - Fit parameters (values, errors, constraints, names) + * - Theory definitions (fit functions for asymmetry/relaxation) + * - User-defined functions (mathematical expressions) + * - Global settings (fit type, data format, etc.) + * - Run configurations (data files, histograms, ranges) + * - MINUIT commands (fit strategy, precision, etc.) + * - Fourier transform parameters + * - Plot settings + * - Fit statistics (χ², degrees of freedom, convergence) + * + * **Validation and Integrity Checking:** + * - Parameter name uniqueness verification + * - Theory-to-parameter mapping validation + * - Histogram grouping consistency checks + * - RRF (Rotating Reference Frame) configuration validation + * - Function syntax and parameter usage verification + * - Map index range checking + * - Legacy lifetimecorrection detection + * + * **MSR File Structure:** + * An MSR file contains the following blocks (in order): + * 1. TITLE - Brief description of the fit + * 2. FITPARAMETER - Fit parameters with initial values and constraints + * 3. THEORY - Asymmetry/relaxation function definitions + * 4. FUNCTIONS (optional) - User-defined mathematical functions + * 5. GLOBAL (optional) - Global fit settings + * 6. RUN - Data file specifications and fit ranges + * 7. COMMANDS - MINUIT fitting commands + * 8. FOURIER (optional) - Fourier transform settings + * 9. PLOT (optional) - Plotting parameters + * 10. STATISTIC - Fit results (χ², NDF, convergence) + * + * **Usage Example:** + * \code + * // Reading an MSR file + * PMsrHandler handler("run1234.msr"); * if (handler.ReadMsrFile() == PMUSR_SUCCESS) { * PMsrParamList *params = handler.GetMsrParamList(); - * // Process parameters, run fits, etc. - * handler.WriteMsrFile("output.msr"); + * + * // Access and modify parameters + * handler.SetMsrParamValue(0, 12.5); + * + * // Perform fit (in calling code) + * // ... + * + * // Update statistics and write results + * handler.SetMsrStatisticMin(chisq); + * handler.SetMsrStatisticNdf(ndf); + * handler.WriteMsrFile("run1234_fitted.msr"); * } - * @endcode + * \endcode + * + * \see PMusr.h for MSR data structure definitions + * \see PFunctionHandler for user-defined function evaluation + * \see PStartupOptions for configuration settings */ class PMsrHandler { @@ -338,69 +379,99 @@ class PMsrHandler virtual Int_t GetNoOfMaps() { return fNoOfMaps; } private: - Bool_t fFourierOnly; ///< flag indicating if Fourier transform only is wished. If yes, some part of the msr-file blocks are not needed. - PStartupOptions *fStartupOptions; ///< contains information about startup options from the musrfit_startup.xml + Bool_t fFourierOnly; ///< Flag indicating Fourier transform only mode (for musrFT) + PStartupOptions *fStartupOptions; ///< Pointer to startup options from musrfit_startup.xml - TString fFileName; ///< file name of the msr-file - TString fMsrFileDirectoryPath; ///< msr-file directory path - TString fTitle; ///< holds the title string of the msr-file - PMsrParamList fParam; ///< holds a list of the fit parameters - PMsrLines fTheory; ///< holds the theory definition - PMsrLines fFunctions; ///< holds the user defined functions - PMsrGlobalBlock fGlobal; ///< holds the information of the global section - PMsrRunList fRuns; ///< holds a list of run information - PMsrLines fCommands; ///< holds a list of the minuit commands - PMsrFourierStructure fFourier; ///< holds the parameters used for the Fourier transform - PMsrPlotList fPlots; ///< holds a list of the plot input parameters - PMsrStatisticStructure fStatistic; ///< holds the statistic info + TString fFileName; ///< MSR file name (with path) + TString fMsrFileDirectoryPath; ///< Directory path of the MSR file + TString fTitle; ///< MSR file title string + PMsrParamList fParam; ///< List of fit parameters with values, errors, constraints + PMsrLines fTheory; ///< Theory block lines defining asymmetry/relaxation functions + PMsrLines fFunctions; ///< User-defined functions block lines + PMsrGlobalBlock fGlobal; ///< Global block settings (fit type, data format, etc.) + PMsrRunList fRuns; ///< List of RUN blocks with data file specifications + PMsrLines fCommands; ///< MINUIT commands block lines + PMsrFourierStructure fFourier; ///< Fourier transform parameters and settings + PMsrPlotList fPlots; ///< List of PLOT blocks with plotting parameters + PMsrStatisticStructure fStatistic; ///< Fit statistics (χ², NDF, convergence status) - Int_t fMsrBlockCounter; ///< used to select the proper msr-block + Int_t fMsrBlockCounter; ///< Counter to track current MSR block during parsing - std::unique_ptr fFuncHandler; ///< needed to parse functions + std::unique_ptr fFuncHandler; ///< Handler for parsing and evaluating user-defined functions - PIntVector fParamInUse; ///< array holding the information if a particular parameter is used at all, i.e. if the theory is using it (perhaps via maps or functions) + PIntVector fParamInUse; ///< Flags indicating which parameters are actually used in theory/functions - Bool_t fCopyStatisticsBlock; ///< flag, if true: just copy to old statistics block (musrt0), otherwise write a new one (musrfit) + Bool_t fCopyStatisticsBlock; ///< If true, copy old statistics block (musrt0); if false, write new one (musrfit) Int_t fNoOfMaps; - std::stringstream fLastErrorMsg; + std::stringstream fLastErrorMsg; ///< Stream accumulating error messages during parsing + /// Parses FITPARAMETER block entries virtual Bool_t HandleFitParameterEntry(PMsrLines &line); + /// Parses THEORY block entries virtual Bool_t HandleTheoryEntry(PMsrLines &line); + /// Parses FUNCTIONS block entries virtual Bool_t HandleFunctionsEntry(PMsrLines &line); + /// Parses GLOBAL block entries virtual Bool_t HandleGlobalEntry(PMsrLines &line); + /// Parses RUN block entries virtual Bool_t HandleRunEntry(PMsrLines &line); + /// Parses COMMANDS block entries virtual Bool_t HandleCommandsEntry(PMsrLines &line); + /// Parses FOURIER block entries virtual Bool_t HandleFourierEntry(PMsrLines &line); + /// Parses PLOT block entries virtual Bool_t HandlePlotEntry(PMsrLines &line); + /// Parses STATISTIC block entries virtual Bool_t HandleStatisticEntry(PMsrLines &line); + /// Determines which parameters are used in theory and functions virtual void FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLines &run); + /// Initializes Fourier parameter structure with default values virtual void InitFourierParameterStructure(PMsrFourierStructure &fourier); + /// Removes comments from MSR file line virtual void RemoveComment(const TString &str, TString &truncStr); + /// Parses Fourier phase value vector virtual Bool_t ParseFourierPhaseValueVector(PMsrFourierStructure &fourier, const TString &str, Bool_t &error); + /// Parses Fourier phase parameter vector virtual Bool_t ParseFourierPhaseParVector(PMsrFourierStructure &fourier, const TString &str, Bool_t &error); + /// Parses Fourier phase parameter iteration vector virtual Bool_t ParseFourierPhaseParIterVector(PMsrFourierStructure &fourier, const TString &str, Bool_t &error); + /// Extracts number from string with specific filter pattern virtual Bool_t FilterNumber(TString str, const Char_t *filter, Int_t offset, Int_t &no); + /// Calculates precision needed for formatting a double value virtual UInt_t NeededPrecision(Double_t dval, UInt_t precLimit=13); + /// Finds position of last significant digit in a double value virtual UInt_t LastSignificant(Double_t dval, UInt_t precLimit=6); + /// Creates detector grouping string from integer vector virtual void MakeDetectorGroupingString(TString str, PIntVector &group, TString &result, Bool_t includeDetector = true); + /// Formats Fourier phase parameter string for display virtual TString BeautifyFourierPhaseParameterString(); + /// Checks for deprecated lifetimecorrection syntax and warns user virtual void CheckLegacyLifetimecorrection(); + /// Validates RUN block structure and consistency virtual Bool_t CheckRunBlockIntegrity(); + /// Checks that all parameter names are unique virtual Bool_t CheckUniquenessOfParamNames(UInt_t &parX, UInt_t &parY); + /// Validates that all map indices are within parameter range virtual Bool_t CheckMaps(); + /// Validates user-defined functions syntax and parameter usage virtual Bool_t CheckFuncs(); + /// Checks histogram grouping consistency across runs virtual Bool_t CheckHistoGrouping(); + /// Validates addrun parameter references virtual Bool_t CheckAddRunParameters(); + /// Validates RRF (Rotating Reference Frame) settings virtual Bool_t CheckRRFSettings(); + /// Checks if real FFT requirements are met virtual Bool_t CheckRealFFT(); + /// Validates maximum likelihood fit settings virtual void CheckMaxLikelihood(); virtual void HandleTheoryArguments(const TString theo, PStringVector &args);