improve doxygen documentation of PMsr2Data.*
This commit is contained in:
@@ -49,11 +49,26 @@ using namespace boost::algorithm;
|
|||||||
|
|
||||||
#include "PMsr2Data.h"
|
#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)
|
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;
|
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()
|
PMsr2Data::~PMsr2Data()
|
||||||
{
|
{
|
||||||
@@ -76,21 +97,36 @@ PMsr2Data::~PMsr2Data()
|
|||||||
fIndVar.clear();
|
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
|
* \brief Determines the number of digits used for run number formatting.
|
||||||
* 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
|
|
||||||
*
|
*
|
||||||
* <p><b>return:</b>
|
* Analyzes the first processable msr-file to determine how many digits are
|
||||||
* - 0 if the number has been determined and set successfully
|
* used for run number formatting in data file names. This ensures consistent
|
||||||
* - -1 in case the msr-file cannot be read
|
* zero-padding when generating new msr-files from templates.
|
||||||
* - -2 if the msr-file-number does not match the data-file-number
|
|
||||||
* - -3 if the msr-file does not contain a RUN block
|
|
||||||
*
|
*
|
||||||
* \param runNo run number of an msr-file
|
* The algorithm:
|
||||||
* \param normalMode false for global mode
|
* 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
|
int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo, bool normalMode) const
|
||||||
{
|
{
|
||||||
@@ -177,13 +213,27 @@ int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo, bool normalMode) con
|
|||||||
return -3;
|
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>
|
* Checks if all run numbers in the run vector can be represented with the
|
||||||
* - 0 if everything is fine
|
* number of digits determined from the data file naming convention. This
|
||||||
* - -1 if a given run number is too big
|
* 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
|
int PMsr2Data::CheckRunNumbersInRange() const
|
||||||
{
|
{
|
||||||
@@ -201,13 +251,18 @@ int PMsr2Data::CheckRunNumbersInRange() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
// GetPresentRun
|
||||||
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p> Determines the current run number
|
* \brief Returns the current run number being processed.
|
||||||
*
|
*
|
||||||
* <p><b>return:</b>
|
* Retrieves the run number pointed to by the internal iterator.
|
||||||
* - current run number
|
* Used to track progress through the run list during processing.
|
||||||
* - 0 if all runs have been processed already
|
*
|
||||||
|
* \return
|
||||||
|
* - Current run number if processing is ongoing
|
||||||
|
* - 0 if all runs have been processed (iterator at end)
|
||||||
*/
|
*/
|
||||||
unsigned int PMsr2Data::GetPresentRun() const
|
unsigned int PMsr2Data::GetPresentRun() const
|
||||||
{
|
{
|
||||||
@@ -217,15 +272,20 @@ unsigned int PMsr2Data::GetPresentRun() const
|
|||||||
return 0;
|
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
|
* - 0 if the run number is valid
|
||||||
* - 1 otherwise
|
* - 1 if the run number is invalid (< 1)
|
||||||
*
|
|
||||||
* \param runNo run number
|
|
||||||
*/
|
*/
|
||||||
int PMsr2Data::SetRunNumbers(unsigned int runNo)
|
int PMsr2Data::SetRunNumbers(unsigned int runNo)
|
||||||
{
|
{
|
||||||
@@ -239,16 +299,24 @@ int PMsr2Data::SetRunNumbers(unsigned int runNo)
|
|||||||
return 0;
|
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>
|
* Clears any existing run list and populates it with all run numbers
|
||||||
* - 0 if the run numbers are valid
|
* from runNoStart to runNoEnd (inclusive). Handles both ascending
|
||||||
* - 1 otherwise
|
* and descending ranges automatically.
|
||||||
*
|
*
|
||||||
* \param runNoStart first run number
|
* \param runNoStart First run number in the range (must be >= 1)
|
||||||
* \param runNoEnd last run number
|
* \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)
|
int PMsr2Data::SetRunNumbers(unsigned int runNoStart, unsigned int runNoEnd)
|
||||||
{
|
{
|
||||||
@@ -268,16 +336,21 @@ int PMsr2Data::SetRunNumbers(unsigned int runNoStart, unsigned int runNoEnd)
|
|||||||
return 0;
|
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
|
* - -1 if the vector is empty
|
||||||
* - 0 if all run numbers are valid
|
* - 0 if all run numbers are valid
|
||||||
* - 1 otherwise
|
* - 1 if any run number is invalid (< 1)
|
||||||
*
|
|
||||||
* \param runListVector vector containing the run numbers to be processed
|
|
||||||
*/
|
*/
|
||||||
int PMsr2Data::SetRunNumbers(const std::vector<unsigned int> &runListVector)
|
int PMsr2Data::SetRunNumbers(const std::vector<unsigned int> &runListVector)
|
||||||
{
|
{
|
||||||
@@ -295,16 +368,34 @@ int PMsr2Data::SetRunNumbers(const std::vector<unsigned int> &runListVector)
|
|||||||
return 0;
|
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
|
* - -1 if the run list file cannot be opened
|
||||||
* - 0 if all run numbers are valid
|
* - 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)
|
int PMsr2Data::SetRunNumbers(const std::string &runListFile)
|
||||||
{
|
{
|
||||||
@@ -366,13 +457,27 @@ int PMsr2Data::SetRunNumbers(const std::string &runListFile)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
// ParseXmlStartupFile
|
||||||
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p> Parse the musrfit startup xml file
|
* \brief Parses the musrfit XML startup file for configuration.
|
||||||
*
|
*
|
||||||
* <p><b>return:</b>
|
* Creates a SAX parser and startup handler to read the musrfit_startup.xml
|
||||||
* - 0 if everything went fine
|
* configuration file. This file contains paths, templates, and other settings
|
||||||
* - return value of the parseXmlFile function otherwise
|
* 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()
|
int PMsr2Data::ParseXmlStartupFile()
|
||||||
{
|
{
|
||||||
@@ -392,15 +497,22 @@ int PMsr2Data::ParseXmlStartupFile()
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
// ReadMsrFile
|
||||||
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p> Read in a msr-file into the default structure
|
* \brief Reads and parses an msr-file.
|
||||||
*
|
*
|
||||||
* <p><b>return:</b>
|
* Creates a new PMsrHandler and uses it to read and parse the specified
|
||||||
* - PMUSR_SUCCESS if everything is OK
|
* msr-file into the internal data structure.
|
||||||
* - return value of the ReadMsrFile-method otherwise
|
|
||||||
*
|
*
|
||||||
* \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
|
int PMsr2Data::ReadMsrFile(const std::string &infile) const
|
||||||
{
|
{
|
||||||
@@ -423,14 +535,23 @@ int PMsr2Data::ReadMsrFile(const std::string &infile) const
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
// GetSingleRunMsrFile
|
||||||
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p> Read in the single run msr-file corresponding to the position in the run-vector
|
* \brief Retrieves msr-file handler for a single-run fit file.
|
||||||
* into a secondary msr-handler different from the class member
|
|
||||||
*
|
*
|
||||||
* <p><b>return:</b>
|
* Reads the "-OneRunFit" variant of the msr-file for the current run.
|
||||||
* - pointer to the secondary msr-handler or 0 in case of an error
|
* 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
|
PMsrHandler* PMsr2Data::GetSingleRunMsrFile() const
|
||||||
{
|
{
|
||||||
@@ -457,13 +578,23 @@ PMsrHandler* PMsr2Data::GetSingleRunMsrFile() const
|
|||||||
return singleRunMsrFile;
|
return singleRunMsrFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
// ReadRunDataFile
|
||||||
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p> Read in a run data-file
|
* \brief Reads the run data file for the current run.
|
||||||
*
|
*
|
||||||
* <p><b>return:</b>
|
* Creates a PRunDataHandler and reads the experimental data file
|
||||||
* - 0 if everything is OK
|
* associated with the current msr-file. Uses data paths from the
|
||||||
* - 1 otherwise
|
* 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()
|
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
|
* Formats the value for column-aligned ASCII output with automatic
|
||||||
* \param value number to be written to the ASCII file
|
* selection of scientific notation for very large or very small numbers.
|
||||||
* \param width column width of the ASCII file
|
*
|
||||||
|
* 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
|
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;
|
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.
|
* \brief Writes a value with error-based precision formatting.
|
||||||
* E.g. 17.0023 +- 0.0018, or 73212.081 +- 0.033, etc.
|
|
||||||
*
|
*
|
||||||
* \param outFile output stream object
|
* Formats output with precision determined by the error value, ensuring
|
||||||
* \param value to be written to stream outFile
|
* significant digits are preserved appropriately. The precision is calculated
|
||||||
* \param errValue error of the value. needed to determine the needed accuracy
|
* based on the first significant digit of the error.
|
||||||
* \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
|
* 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
|
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.
|
* \brief Determines the position of the first significant digit.
|
||||||
* E.g. for value=2.03 it will return 1, for value=0.00023 it will return 4, etc.
|
|
||||||
*
|
*
|
||||||
* \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
|
int PMsr2Data::GetFirstSignificantDigit(const double &value) const
|
||||||
{
|
{
|
||||||
@@ -2538,15 +2709,26 @@ int PMsr2Data::GetFirstSignificantDigit(const double &value) const
|
|||||||
return prec+1;
|
return prec+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------
|
||||||
|
// InParameterList
|
||||||
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* <p>Checks paramValue is found in the paramList. If paramList
|
* \brief Checks if a parameter index should be included in output.
|
||||||
* is empty, ALL paramValues will be accepted, i.e. return true.
|
|
||||||
*
|
*
|
||||||
* \param paramValue paramValue to be checked
|
* Determines whether a given parameter should be written to the output
|
||||||
* \param paramList parameter list
|
* 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
|
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:
|
* \brief Utility class for msr2data: template-based msr-file generation and parameter extraction.
|
||||||
* generate new msr-files from a template, collect fit parameters from msr-files and write them to DB or plain ASCII files
|
*
|
||||||
|
* 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
|
class PMsr2Data
|
||||||
{
|
{
|
||||||
public:
|
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();
|
~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
|
* \brief Sets a single run number for processing.
|
||||||
int SetRunNumbers(const std::vector<unsigned int>&); // explicit run list specified using [ ]
|
*
|
||||||
|
* \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;
|
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;
|
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 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();
|
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:
|
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;
|
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 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;
|
* \brief Writes a value with its error to output stream.
|
||||||
bool fRunListFile;
|
*
|
||||||
std::vector<std::string> fIndVar;
|
* Formats output based on DB or ASCII mode.
|
||||||
std::unique_ptr<std::ifstream> fRunListFileStream;
|
*
|
||||||
std::unique_ptr<TSAXParser> fSaxParser;
|
* \param outFile Output file stream
|
||||||
std::unique_ptr<PStartupHandler> fStartupHandler;
|
* \param value Value to write
|
||||||
mutable std::unique_ptr<PRunDataHandler> fDataHandler;
|
* \param errValue Error/uncertainty value
|
||||||
mutable std::unique_ptr<PMsrHandler> fMsrHandler;
|
* \param width Field width for formatting
|
||||||
mutable unsigned int fNumGlobalParam;
|
* \param db Whether to use DB format (true) or ASCII (false)
|
||||||
mutable unsigned int fNumSpecParam;
|
*/
|
||||||
mutable unsigned int fNumTempRunBlocks;
|
void WriteValue(std::fstream &outFile, const double &value, const double &errValue, const unsigned int &width, const bool &db) const;
|
||||||
mutable unsigned int fRunNumberDigits;
|
|
||||||
mutable bool fHeaderWritten;
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* \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