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 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