improve doxygen documentation of PMsr2Data.*
This commit is contained in:
@@ -49,11 +49,26 @@ using namespace boost::algorithm;
|
||||
|
||||
#include "PMsr2Data.h"
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Constructor
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Constructor
|
||||
* \brief Constructor that initializes the msr2data handler.
|
||||
*
|
||||
* \param ext extension/suffix of the msr-files to be processed
|
||||
* Initializes all member variables and prepares the object for processing.
|
||||
* Sets default values:
|
||||
* - Run number digits: 4 (typical for standard run numbering)
|
||||
* - Global/specific parameter counts: 0
|
||||
* - Header written flag: false
|
||||
* - Run list file flag: false
|
||||
*
|
||||
* All handler pointers (SAX parser, startup handler, data handler, msr handler)
|
||||
* are initialized to nullptr and will be created as needed during processing.
|
||||
*
|
||||
* \param ext File extension for data files (e.g., ".bin", ".root", ".mdu")
|
||||
* This extension is used to locate corresponding data files for each run
|
||||
*
|
||||
* \note The extension should include the leading dot if required
|
||||
*/
|
||||
PMsr2Data::PMsr2Data(const std::string &ext) : fFileExtension(ext), fRunListFile(false), fNumGlobalParam(0), fNumSpecParam(0), fNumTempRunBlocks(0), fRunNumberDigits(4), fHeaderWritten(false)
|
||||
{
|
||||
@@ -65,9 +80,15 @@ PMsr2Data::PMsr2Data(const std::string &ext) : fFileExtension(ext), fRunListFile
|
||||
fMsrHandler = nullptr;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Destructor
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Destructor
|
||||
* \brief Destructor that cleans up resources.
|
||||
*
|
||||
* Clears all vectors and resets iterators. The unique_ptr members
|
||||
* (fRunListFileStream, fSaxParser, fStartupHandler, fDataHandler, fMsrHandler)
|
||||
* are automatically cleaned up through their destructors.
|
||||
*/
|
||||
PMsr2Data::~PMsr2Data()
|
||||
{
|
||||
@@ -76,21 +97,36 @@ PMsr2Data::~PMsr2Data()
|
||||
fIndVar.clear();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// DetermineRunNumberDigits
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Determines the number of digits used for the run number in the data file name from the first msr-file that is processed
|
||||
* If the specified run number is the first one of the list of runs and it cannot be opened, then the rest of the given runs is checked
|
||||
* until an existing msr-file is found
|
||||
* \brief Determines the number of digits used for run number formatting.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* - 0 if the number has been determined and set successfully
|
||||
* - -1 in case the msr-file cannot be read
|
||||
* - -2 if the msr-file-number does not match the data-file-number
|
||||
* - -3 if the msr-file does not contain a RUN block
|
||||
* Analyzes the first processable msr-file to determine how many digits are
|
||||
* used for run number formatting in data file names. This ensures consistent
|
||||
* zero-padding when generating new msr-files from templates.
|
||||
*
|
||||
* \param runNo run number of an msr-file
|
||||
* \param normalMode false for global mode
|
||||
* The algorithm:
|
||||
* 1. Attempts to open the msr-file for the specified run number
|
||||
* 2. If in global mode and file not found, tries the "+global" variant
|
||||
* 3. If first run fails, iterates through the run list to find an existing file
|
||||
* 4. Searches the RUN block for the run number in the data file path
|
||||
* 5. Counts leading zeros to determine the digit width
|
||||
*
|
||||
* Example: If the data file is "run_0042.bin", this determines 4 digits.
|
||||
*
|
||||
* \param runNo Run number to analyze
|
||||
* \param normalMode true for normal mode, false for global fitting mode
|
||||
*
|
||||
* \return
|
||||
* - 0 if the number of digits was successfully determined
|
||||
* - -1 if no msr-file could be opened
|
||||
* - -2 if msr-file run number doesn't match data file run number
|
||||
* - -3 if the msr-file contains no RUN block
|
||||
*
|
||||
* \note The determined digit count is stored in fRunNumberDigits
|
||||
* \note In global mode, also checks for files with "+global" suffix
|
||||
*/
|
||||
int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo, bool normalMode) const
|
||||
{
|
||||
@@ -177,13 +213,27 @@ int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo, bool normalMode) con
|
||||
return -3;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// CheckRunNumbersInRange
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Checks if all given run numbers are in the range covered by the number of digits used in the data file name
|
||||
* \brief Validates that all run numbers fit within the determined digit width.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* - 0 if everything is fine
|
||||
* - -1 if a given run number is too big
|
||||
* Checks if all run numbers in the run vector can be represented with the
|
||||
* number of digits determined from the data file naming convention. This
|
||||
* prevents formatting errors when generating file names.
|
||||
*
|
||||
* The check has been loosened since 2023 to accommodate LEM run numbers
|
||||
* exceeding 9999 by allowing one extra digit beyond the determined width.
|
||||
*
|
||||
* Maximum allowed run number = 10^(fRunNumberDigits+1) - 1
|
||||
*
|
||||
* \return
|
||||
* - 0 if all run numbers are within the acceptable range
|
||||
* - -1 if any run number exceeds the maximum
|
||||
*
|
||||
* \note Since 2023, uses fRunNumberDigits+1 instead of fRunNumberDigits
|
||||
* to handle larger run numbers at facilities like LEM
|
||||
*/
|
||||
int PMsr2Data::CheckRunNumbersInRange() const
|
||||
{
|
||||
@@ -201,13 +251,18 @@ int PMsr2Data::CheckRunNumbersInRange() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// GetPresentRun
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Determines the current run number
|
||||
* \brief Returns the current run number being processed.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* - current run number
|
||||
* - 0 if all runs have been processed already
|
||||
* Retrieves the run number pointed to by the internal iterator.
|
||||
* Used to track progress through the run list during processing.
|
||||
*
|
||||
* \return
|
||||
* - Current run number if processing is ongoing
|
||||
* - 0 if all runs have been processed (iterator at end)
|
||||
*/
|
||||
unsigned int PMsr2Data::GetPresentRun() const
|
||||
{
|
||||
@@ -217,15 +272,20 @@ unsigned int PMsr2Data::GetPresentRun() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// SetRunNumbers (single run)
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Initialization of the internal list of runs using a single run number
|
||||
* \brief Sets a single run number for processing.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* Clears any existing run list and initializes with a single run number.
|
||||
* The internal iterator is reset to point to the beginning.
|
||||
*
|
||||
* \param runNo Run number to process (must be >= 1)
|
||||
*
|
||||
* \return
|
||||
* - 0 if the run number is valid
|
||||
* - 1 otherwise
|
||||
*
|
||||
* \param runNo run number
|
||||
* - 1 if the run number is invalid (< 1)
|
||||
*/
|
||||
int PMsr2Data::SetRunNumbers(unsigned int runNo)
|
||||
{
|
||||
@@ -239,16 +299,24 @@ int PMsr2Data::SetRunNumbers(unsigned int runNo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// SetRunNumbers (range)
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Initialization of the internal list of runs using first and last run numbers
|
||||
* \brief Sets a range of run numbers for processing.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* - 0 if the run numbers are valid
|
||||
* - 1 otherwise
|
||||
* Clears any existing run list and populates it with all run numbers
|
||||
* from runNoStart to runNoEnd (inclusive). Handles both ascending
|
||||
* and descending ranges automatically.
|
||||
*
|
||||
* \param runNoStart first run number
|
||||
* \param runNoEnd last run number
|
||||
* \param runNoStart First run number in the range (must be >= 1)
|
||||
* \param runNoEnd Last run number in the range (must be >= 1)
|
||||
*
|
||||
* \return
|
||||
* - 0 if both run numbers are valid
|
||||
* - 1 if either run number is invalid (< 1)
|
||||
*
|
||||
* \note If runNoStart > runNoEnd, the range is generated in descending order
|
||||
*/
|
||||
int PMsr2Data::SetRunNumbers(unsigned int runNoStart, unsigned int runNoEnd)
|
||||
{
|
||||
@@ -268,16 +336,21 @@ int PMsr2Data::SetRunNumbers(unsigned int runNoStart, unsigned int runNoEnd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// SetRunNumbers (explicit vector)
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Initialization of the internal list of runs using explicitly specified run numbers
|
||||
* \brief Sets run numbers from an explicit vector.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* Clears any existing run list and copies the provided vector of run numbers.
|
||||
* All run numbers in the vector must be valid (>= 1).
|
||||
*
|
||||
* \param runListVector Vector containing run numbers to process
|
||||
*
|
||||
* \return
|
||||
* - -1 if the vector is empty
|
||||
* - 0 if all run numbers are valid
|
||||
* - 1 otherwise
|
||||
*
|
||||
* \param runListVector vector containing the run numbers to be processed
|
||||
* - 1 if any run number is invalid (< 1)
|
||||
*/
|
||||
int PMsr2Data::SetRunNumbers(const std::vector<unsigned int> &runListVector)
|
||||
{
|
||||
@@ -295,16 +368,34 @@ int PMsr2Data::SetRunNumbers(const std::vector<unsigned int> &runListVector)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// SetRunNumbers (from file)
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Initialization of the internal list of runs using a run list file
|
||||
* \brief Sets run numbers from a run list file.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* Reads run numbers from a text file with the following format:
|
||||
* - First line: "RUN" followed by optional independent variable names
|
||||
* - Subsequent lines: run number followed by corresponding variable values
|
||||
* - Comments start with '#' and are ignored
|
||||
* - Empty lines are skipped
|
||||
*
|
||||
* Example run list file:
|
||||
* \verbatim
|
||||
* RUN FIELD TEMP
|
||||
* 1234 0.5 295.0
|
||||
* 1235 1.0 295.0 # This is a comment
|
||||
* 1236 1.5 295.0
|
||||
* \endverbatim
|
||||
*
|
||||
* \param runListFile Path to run list file
|
||||
*
|
||||
* \return
|
||||
* - -1 if the run list file cannot be opened
|
||||
* - 0 if all run numbers are valid
|
||||
* - 1 otherwise
|
||||
* - 1 if any run number is invalid (< 1) or file format is incorrect
|
||||
*
|
||||
* \param runListFile name of run list file
|
||||
* \note Sets fRunListFile flag to true and opens stream for reading variables
|
||||
*/
|
||||
int PMsr2Data::SetRunNumbers(const std::string &runListFile)
|
||||
{
|
||||
@@ -366,13 +457,27 @@ int PMsr2Data::SetRunNumbers(const std::string &runListFile)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// ParseXmlStartupFile
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Parse the musrfit startup xml file
|
||||
* \brief Parses the musrfit XML startup file for configuration.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* - 0 if everything went fine
|
||||
* - return value of the parseXmlFile function otherwise
|
||||
* Creates a SAX parser and startup handler to read the musrfit_startup.xml
|
||||
* configuration file. This file contains paths, templates, and other settings
|
||||
* needed for msr2data operation.
|
||||
*
|
||||
* The parseXmlFile function is used instead of ParseFile to avoid
|
||||
* environment-specific issues encountered with direct parsing.
|
||||
*
|
||||
* \return
|
||||
* - 0 if parsing succeeded
|
||||
* - Non-zero error code from parseXmlFile if parsing failed
|
||||
*
|
||||
* \note Outputs a warning to stderr if parsing fails
|
||||
*
|
||||
* \see PStartupHandler for XML configuration details
|
||||
* \see parseXmlFile for the parsing implementation
|
||||
*/
|
||||
int PMsr2Data::ParseXmlStartupFile()
|
||||
{
|
||||
@@ -392,15 +497,22 @@ int PMsr2Data::ParseXmlStartupFile()
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// ReadMsrFile
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Read in a msr-file into the default structure
|
||||
* \brief Reads and parses an msr-file.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* - PMUSR_SUCCESS if everything is OK
|
||||
* - return value of the ReadMsrFile-method otherwise
|
||||
* Creates a new PMsrHandler and uses it to read and parse the specified
|
||||
* msr-file into the internal data structure.
|
||||
*
|
||||
* \param infile name of the msr-file to be read
|
||||
* \param infile Path to the msr-file to read
|
||||
*
|
||||
* \return
|
||||
* - PMUSR_SUCCESS if reading and parsing succeeded
|
||||
* - Error code from PMsrHandler::ReadMsrFile otherwise
|
||||
*
|
||||
* \see PMsrHandler::ReadMsrFile for parsing details
|
||||
*/
|
||||
int PMsr2Data::ReadMsrFile(const std::string &infile) const
|
||||
{
|
||||
@@ -423,14 +535,23 @@ int PMsr2Data::ReadMsrFile(const std::string &infile) const
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// GetSingleRunMsrFile
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Read in the single run msr-file corresponding to the position in the run-vector
|
||||
* into a secondary msr-handler different from the class member
|
||||
* \brief Retrieves msr-file handler for a single-run fit file.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* - pointer to the secondary msr-handler or 0 in case of an error
|
||||
* Reads the "-OneRunFit" variant of the msr-file for the current run.
|
||||
* This is used when extracting individual run results from global fits.
|
||||
*
|
||||
* The file name format: "<runNumber>-OneRunFit<extension>.msr"
|
||||
*
|
||||
* \return
|
||||
* - Pointer to newly created PMsrHandler on success
|
||||
* - nullptr if file cannot be read or parsed
|
||||
*
|
||||
* \note Caller is responsible for deleting the returned handler
|
||||
* \note Different from the class member fMsrHandler
|
||||
*/
|
||||
PMsrHandler* PMsr2Data::GetSingleRunMsrFile() const
|
||||
{
|
||||
@@ -457,13 +578,23 @@ PMsrHandler* PMsr2Data::GetSingleRunMsrFile() const
|
||||
return singleRunMsrFile;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// ReadRunDataFile
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Read in a run data-file
|
||||
* \brief Reads the run data file for the current run.
|
||||
*
|
||||
* <p><b>return:</b>
|
||||
* - 0 if everything is OK
|
||||
* - 1 otherwise
|
||||
* Creates a PRunDataHandler and reads the experimental data file
|
||||
* associated with the current msr-file. Uses data paths from the
|
||||
* startup handler if available, otherwise uses defaults.
|
||||
*
|
||||
* \return
|
||||
* - 0 if all data was successfully read
|
||||
* - 1 if some data files could not be read (with warning)
|
||||
*
|
||||
* \note Outputs a warning to stderr if data is unavailable but continues processing
|
||||
*
|
||||
* \see PRunDataHandler for data file reading details
|
||||
*/
|
||||
int PMsr2Data::ReadRunDataFile()
|
||||
{
|
||||
@@ -2457,13 +2588,23 @@ int PMsr2Data::WriteOutput(const std::string &outfile, const std::vector<unsigne
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// WriteValue (single value)
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p>Write formatted output to column-formatted ASCII output file
|
||||
* \brief Writes a formatted numeric value to output stream.
|
||||
*
|
||||
* \param outFile output file stream to the ASCII file
|
||||
* \param value number to be written to the ASCII file
|
||||
* \param width column width of the ASCII file
|
||||
* Formats the value for column-aligned ASCII output with automatic
|
||||
* selection of scientific notation for very large or very small numbers.
|
||||
*
|
||||
* Formatting rules:
|
||||
* - Scientific notation if |value| >= 1e6 or (|value| < 1e-4 and value != 0)
|
||||
* - Fixed-point notation otherwise
|
||||
* - Left-aligned in field of specified width
|
||||
*
|
||||
* \param outFile Output file stream
|
||||
* \param value Numeric value to write
|
||||
* \param width Column width for formatting
|
||||
*/
|
||||
void PMsr2Data::WriteValue(std::fstream &outFile, const double &value, const unsigned int &width) const
|
||||
{
|
||||
@@ -2474,16 +2615,32 @@ void PMsr2Data::WriteValue(std::fstream &outFile, const double &value, const uns
|
||||
outFile << std::setw(width) << std::left << value;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// WriteValue (value with error)
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p>Write a value to the outFile stream. The string length is determined on its error.
|
||||
* E.g. 17.0023 +- 0.0018, or 73212.081 +- 0.033, etc.
|
||||
* \brief Writes a value with error-based precision formatting.
|
||||
*
|
||||
* \param outFile output stream object
|
||||
* \param value to be written to stream outFile
|
||||
* \param errValue error of the value. needed to determine the needed accuracy
|
||||
* \param width field width for outFile for formatted output
|
||||
* \param db true for db-file output, false for dat-file output. Needed to have at least on space between numbers for dat-file output
|
||||
* Formats output with precision determined by the error value, ensuring
|
||||
* significant digits are preserved appropriately. The precision is calculated
|
||||
* based on the first significant digit of the error.
|
||||
*
|
||||
* Examples:
|
||||
* - value=17.0023 ± errValue=0.0018 → formatted with 4 decimal places
|
||||
* - value=73212.081 ± errValue=0.033 → formatted with 2 decimal places
|
||||
*
|
||||
* Formatting rules:
|
||||
* - Precision based on error's first significant digit
|
||||
* - Scientific notation if |value| >= 1e6 or (|value| < 1e-4 and value != 0)
|
||||
* - Extra space added after value in ASCII mode for readability
|
||||
*
|
||||
* \param outFile Output file stream
|
||||
* \param value Numeric value to write
|
||||
* \param errValue Error/uncertainty value (determines precision)
|
||||
* \param width Field width for formatted output
|
||||
* \param db true for DB format, false for ASCII format (adds extra space)
|
||||
*
|
||||
* \see GetFirstSignificantDigit for precision calculation
|
||||
*/
|
||||
void PMsr2Data::WriteValue(std::fstream &outFile, const double &value, const double &errValue, const unsigned int &width, const bool &db) const
|
||||
{
|
||||
@@ -2509,14 +2666,28 @@ void PMsr2Data::WriteValue(std::fstream &outFile, const double &value, const dou
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// GetFirstSignificantDigit
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p>Determines the first significant digit of the provided number value.
|
||||
* E.g. for value=2.03 it will return 1, for value=0.00023 it will return 4, etc.
|
||||
* \brief Determines the position of the first significant digit.
|
||||
*
|
||||
* \param value for which the first significant digit needs to be determined.
|
||||
* Calculates how many decimal places are needed to reach the first
|
||||
* significant digit by repeatedly multiplying by 10 until the value
|
||||
* is >= 1.0. This is used for precision control in output formatting.
|
||||
*
|
||||
* \return first significant digit of the provided number value
|
||||
* Examples:
|
||||
* - value = 2.03 → returns 1 (first significant digit in tenths place)
|
||||
* - value = 0.00023 → returns 4 (first significant digit in ten-thousandths)
|
||||
* - value = 0.5 → returns 1
|
||||
*
|
||||
* \param value Value to analyze (typically an error/uncertainty)
|
||||
*
|
||||
* \return
|
||||
* - Position of first significant digit (1-19)
|
||||
* - 6 if no significant digit found after 20 iterations (default precision)
|
||||
*
|
||||
* \note Maximum 20 iterations to prevent infinite loops
|
||||
*/
|
||||
int PMsr2Data::GetFirstSignificantDigit(const double &value) const
|
||||
{
|
||||
@@ -2538,15 +2709,26 @@ int PMsr2Data::GetFirstSignificantDigit(const double &value) const
|
||||
return prec+1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// InParameterList
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p>Checks paramValue is found in the paramList. If paramList
|
||||
* is empty, ALL paramValues will be accepted, i.e. return true.
|
||||
* \brief Checks if a parameter index should be included in output.
|
||||
*
|
||||
* \param paramValue paramValue to be checked
|
||||
* \param paramList parameter list
|
||||
* Determines whether a given parameter should be written to the output
|
||||
* file based on the user-specified parameter list. If the parameter list
|
||||
* is empty, all parameters are included by default.
|
||||
*
|
||||
* \return true if the paramValue if found in paramList, or true if paramList is empty.
|
||||
* \param paramValue Zero-based parameter index to check
|
||||
* \param paramList Vector of one-based parameter numbers to output
|
||||
* (empty vector means output all parameters)
|
||||
*
|
||||
* \return
|
||||
* - true if paramValue should be included in output
|
||||
* - true if paramList is empty (output all parameters)
|
||||
* - false if paramValue is not in the list
|
||||
*
|
||||
* \note paramValue is zero-based while paramList contains one-based indices
|
||||
*/
|
||||
bool PMsr2Data::InParameterList(const unsigned int ¶mValue, const std::vector<unsigned int> ¶mList) const
|
||||
{
|
||||
|
||||
@@ -45,57 +45,273 @@
|
||||
|
||||
//-------------------------------------------------------------
|
||||
/**
|
||||
* <p> Class providing the necessary utilities for msr2data:
|
||||
* generate new msr-files from a template, collect fit parameters from msr-files and write them to DB or plain ASCII files
|
||||
* \brief Utility class for msr2data: template-based msr-file generation and parameter extraction.
|
||||
*
|
||||
* PMsr2Data provides comprehensive functionality for the msr2data tool, which is used to:
|
||||
* - Generate new msr-files from templates by substituting run numbers
|
||||
* - Extract fit parameters from analyzed msr-files
|
||||
* - Write collected parameters to database (DB) or plain ASCII files
|
||||
* - Support both single-run and global (multi-run) fitting workflows
|
||||
*
|
||||
* Key Features:
|
||||
* - Template-based msr-file generation with automatic run number substitution
|
||||
* - Flexible run number specification (single, range, list file, explicit list)
|
||||
* - Parameter extraction from fitted msr-files
|
||||
* - Multiple output formats (DB format, ASCII tables)
|
||||
* - Global fitting support for combined multi-run analysis
|
||||
* - XML-based configuration via startup files
|
||||
*
|
||||
* Implementation Note:
|
||||
* This class uses std::string and standard C++ string handling exclusively
|
||||
* (rather than ROOT's TString) to demonstrate modern C++ practices, though
|
||||
* this occasionally requires conversions when interfacing with PMusr classes.
|
||||
*
|
||||
* Typical Workflow:
|
||||
* 1. Create PMsr2Data object with file extension
|
||||
* 2. Parse XML startup file for configuration
|
||||
* 3. Set run numbers (single, range, or list)
|
||||
* 4. Generate msr-files from template or extract parameters from fitted files
|
||||
* 5. Write output to DB or ASCII format
|
||||
*
|
||||
* \see PStartupHandler for XML configuration parsing
|
||||
* \see PRunDataHandler for run data management
|
||||
* \see PMsrHandler for msr-file parsing and manipulation
|
||||
*/
|
||||
class PMsr2Data
|
||||
{
|
||||
public:
|
||||
PMsr2Data(const std::string&); // File extension
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Constructor that initializes the msr2data handler.
|
||||
*
|
||||
* \param fileExtension File extension for data files (e.g., "bin", "root", "mdu")
|
||||
*/
|
||||
PMsr2Data(const std::string& fileExtension);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Destructor that cleans up resources.
|
||||
*/
|
||||
~PMsr2Data();
|
||||
|
||||
int SetRunNumbers(unsigned int); // single run given
|
||||
int SetRunNumbers(unsigned int, unsigned int); // run list specified through first and last run number
|
||||
int SetRunNumbers(const std::string&); // run list file given
|
||||
int SetRunNumbers(const std::vector<unsigned int>&); // explicit run list specified using [ ]
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Sets a single run number for processing.
|
||||
*
|
||||
* \param runNumber Single run number to process
|
||||
* \return 0 on success, non-zero on error
|
||||
*/
|
||||
int SetRunNumbers(unsigned int runNumber);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Sets a range of run numbers (from first to last, inclusive).
|
||||
*
|
||||
* \param firstRun First run number in the range
|
||||
* \param lastRun Last run number in the range
|
||||
* \return 0 on success, non-zero on error
|
||||
*/
|
||||
int SetRunNumbers(unsigned int firstRun, unsigned int lastRun);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Sets run numbers from a run list file.
|
||||
*
|
||||
* Reads run numbers from a text file, one run number per line.
|
||||
*
|
||||
* \param runListFileName Path to file containing run numbers
|
||||
* \return 0 on success, non-zero on error
|
||||
*/
|
||||
int SetRunNumbers(const std::string& runListFileName);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Sets run numbers from an explicit vector.
|
||||
*
|
||||
* \param runVector Vector of run numbers to process
|
||||
* \return 0 on success, non-zero on error
|
||||
*/
|
||||
int SetRunNumbers(const std::vector<unsigned int>& runVector);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Gets the current run number being processed.
|
||||
*
|
||||
* \return Current run number from the internal iterator
|
||||
*/
|
||||
unsigned int GetPresentRun() const;
|
||||
|
||||
int DetermineRunNumberDigits(unsigned int, bool) const;
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Determines the number of digits needed for run number formatting.
|
||||
*
|
||||
* Analyzes run numbers to determine zero-padding requirements for
|
||||
* consistent file naming.
|
||||
*
|
||||
* \param maxRunNumber Maximum run number to consider
|
||||
* \param templateFile Whether processing a template file
|
||||
* \return Number of digits needed for run number formatting
|
||||
*/
|
||||
int DetermineRunNumberDigits(unsigned int maxRunNumber, bool templateFile) const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Validates that all run numbers are within acceptable ranges.
|
||||
*
|
||||
* \return 0 if all run numbers are valid, non-zero otherwise
|
||||
*/
|
||||
int CheckRunNumbersInRange() const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Parses the XML startup file for configuration.
|
||||
*
|
||||
* Reads and processes the msr2data XML startup file containing
|
||||
* paths, templates, and other configuration settings.
|
||||
*
|
||||
* \return 0 on success, non-zero on parsing errors
|
||||
*/
|
||||
int ParseXmlStartupFile();
|
||||
int ReadMsrFile(const std::string&) const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Reads and parses an msr-file.
|
||||
*
|
||||
* \param msrFileName Path to the msr-file to read
|
||||
* \return 0 on success, non-zero on read/parse errors
|
||||
*/
|
||||
int ReadMsrFile(const std::string& msrFileName) const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Reads the run data file for the current run.
|
||||
*
|
||||
* \return 0 on success, non-zero on read errors
|
||||
*/
|
||||
int ReadRunDataFile();
|
||||
|
||||
bool PrepareNewInputFile(unsigned int, bool) const; // template
|
||||
bool PrepareGlobalInputFile(unsigned int, const std::string&, unsigned int) const; // generate msr-input file for a global fit
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Generates a new msr-file from a template.
|
||||
*
|
||||
* Creates an msr-file by substituting run number placeholders in the
|
||||
* template with actual run numbers.
|
||||
*
|
||||
* \param templateNumber Template identifier number
|
||||
* \param sorted Whether to generate sorted output
|
||||
* \return true on success, false on failure
|
||||
*/
|
||||
bool PrepareNewInputFile(unsigned int templateNumber, bool sorted) const;
|
||||
|
||||
int WriteOutput(const std::string&, const std::vector<unsigned int>&, bool, unsigned int, bool global = false, unsigned int counter = 0) const;
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Generates an msr-file for global (multi-run) fitting.
|
||||
*
|
||||
* Creates a combined msr-file for global fits across multiple runs.
|
||||
*
|
||||
* \param templateNumber Template identifier number
|
||||
* \param globalOutputFile Path to output global msr-file
|
||||
* \param runListSize Number of runs in the global fit
|
||||
* \return true on success, false on failure
|
||||
*/
|
||||
bool PrepareGlobalInputFile(unsigned int templateNumber, const std::string& globalOutputFile, unsigned int runListSize) const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Writes extracted parameters to output file.
|
||||
*
|
||||
* Outputs fit parameters in either DB format or ASCII table format.
|
||||
*
|
||||
* \param outputFileName Output file path
|
||||
* \param parameters Vector of parameter indices to output
|
||||
* \param dbFormat Whether to use DB format (true) or ASCII (false)
|
||||
* \param precision Number of significant digits for output
|
||||
* \param global Whether this is global fit output
|
||||
* \param counter Counter for global fit indexing
|
||||
* \return 0 on success, non-zero on write errors
|
||||
*/
|
||||
int WriteOutput(const std::string& outputFileName, const std::vector<unsigned int>& parameters, bool dbFormat, unsigned int precision, bool global = false, unsigned int counter = 0) const;
|
||||
|
||||
private:
|
||||
bool PrepareNewSortedInputFile(unsigned int) const; // template
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Generates a sorted msr-file from a template.
|
||||
*
|
||||
* Internal helper for creating sorted msr-files with proper histogram ordering.
|
||||
*
|
||||
* \param templateNumber Template identifier number
|
||||
* \return true on success, false on failure
|
||||
*/
|
||||
bool PrepareNewSortedInputFile(unsigned int templateNumber) const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Retrieves msr-file handler for a single run.
|
||||
*
|
||||
* \return Pointer to PMsrHandler for the current run
|
||||
*/
|
||||
PMsrHandler* GetSingleRunMsrFile() const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Writes a single numeric value to output stream.
|
||||
*
|
||||
* \param outFile Output file stream
|
||||
* \param value Value to write
|
||||
* \param width Field width for formatting
|
||||
*/
|
||||
void WriteValue(std::fstream &outFile, const double &value, const unsigned int &width) const;
|
||||
void WriteValue(std::fstream &outFile, const double &value, const double &errValue, const unsigned int &width, const bool &db) const;
|
||||
int GetFirstSignificantDigit(const double &value) const;
|
||||
bool InParameterList(const unsigned int ¶mValue, const std::vector<unsigned int>&) const;
|
||||
|
||||
std::string fFileExtension;
|
||||
std::vector<unsigned int> fRunVector;
|
||||
mutable std::vector<unsigned int>::const_iterator fRunVectorIter;
|
||||
bool fRunListFile;
|
||||
std::vector<std::string> fIndVar;
|
||||
std::unique_ptr<std::ifstream> fRunListFileStream;
|
||||
std::unique_ptr<TSAXParser> fSaxParser;
|
||||
std::unique_ptr<PStartupHandler> fStartupHandler;
|
||||
mutable std::unique_ptr<PRunDataHandler> fDataHandler;
|
||||
mutable std::unique_ptr<PMsrHandler> fMsrHandler;
|
||||
mutable unsigned int fNumGlobalParam;
|
||||
mutable unsigned int fNumSpecParam;
|
||||
mutable unsigned int fNumTempRunBlocks;
|
||||
mutable unsigned int fRunNumberDigits;
|
||||
mutable bool fHeaderWritten;
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Writes a value with its error to output stream.
|
||||
*
|
||||
* Formats output based on DB or ASCII mode.
|
||||
*
|
||||
* \param outFile Output file stream
|
||||
* \param value Value to write
|
||||
* \param errValue Error/uncertainty value
|
||||
* \param width Field width for formatting
|
||||
* \param db Whether to use DB format (true) or ASCII (false)
|
||||
*/
|
||||
void WriteValue(std::fstream &outFile, const double &value, const double &errValue, const unsigned int &width, const bool &db) const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Determines the first significant digit position of a value.
|
||||
*
|
||||
* Used for intelligent formatting and precision control.
|
||||
*
|
||||
* \param value Value to analyze
|
||||
* \return Position of first significant digit
|
||||
*/
|
||||
int GetFirstSignificantDigit(const double &value) const;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* \brief Checks if a parameter is in the output parameter list.
|
||||
*
|
||||
* \param paramValue Parameter index to check
|
||||
* \param paramList List of parameters to output
|
||||
* \return true if parameter should be output, false otherwise
|
||||
*/
|
||||
bool InParameterList(const unsigned int ¶mValue, const std::vector<unsigned int>& paramList) const;
|
||||
|
||||
std::string fFileExtension; ///< File extension for data files (e.g., "bin", "root")
|
||||
std::vector<unsigned int> fRunVector; ///< Vector of run numbers to process
|
||||
mutable std::vector<unsigned int>::const_iterator fRunVectorIter; ///< Iterator for current position in run vector
|
||||
bool fRunListFile; ///< Flag indicating if run list is from a file
|
||||
std::vector<std::string> fIndVar; ///< Independent variables for output
|
||||
std::unique_ptr<std::ifstream> fRunListFileStream; ///< Stream for reading run list file
|
||||
std::unique_ptr<TSAXParser> fSaxParser; ///< XML SAX parser for startup file
|
||||
std::unique_ptr<PStartupHandler> fStartupHandler; ///< Handler for XML startup file configuration
|
||||
mutable std::unique_ptr<PRunDataHandler> fDataHandler; ///< Handler for run data files
|
||||
mutable std::unique_ptr<PMsrHandler> fMsrHandler; ///< Handler for msr-file parsing and generation
|
||||
mutable unsigned int fNumGlobalParam; ///< Number of global parameters in fit
|
||||
mutable unsigned int fNumSpecParam; ///< Number of spectrum-specific parameters
|
||||
mutable unsigned int fNumTempRunBlocks; ///< Number of temporary run blocks
|
||||
mutable unsigned int fRunNumberDigits; ///< Number of digits for run number formatting
|
||||
mutable bool fHeaderWritten; ///< Flag tracking if output header has been written
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user