improve the doxygen docu of PUserFcn.* and PUserFcnBase.*
All checks were successful
Build and Deploy Documentation / build-and-deploy (push) Successful in 18s

This commit is contained in:
2025-11-23 17:58:07 +01:00
parent d8ae606a55
commit 0db498284f
4 changed files with 323 additions and 53 deletions

View File

@@ -35,7 +35,15 @@ ClassImp(PUserFcn)
//------------------------------------------------------
/**
* <p>Constructor
* \brief Default constructor for PUserFcn.
*
* Initializes a third-order polynomial user function. This implementation
* requires no special initialization as it has no internal state - all
* computation is done directly in the operator() method.
*
* \note This simple constructor serves as a template for more complex user
* functions. Functions requiring initialization (e.g., loading lookup tables,
* precomputing constants) should perform that work here or in SetGlobalPart().
*/
PUserFcn::PUserFcn()
{
@@ -43,7 +51,16 @@ PUserFcn::PUserFcn()
//------------------------------------------------------
/**
* <p>Destructor
* \brief Destructor for PUserFcn.
*
* Cleans up any resources allocated by the polynomial function. Since this
* implementation has no dynamically allocated resources, the destructor is
* empty.
*
* \note User functions with allocated resources (lookup tables, buffers,
* external library handles) must clean them up here to prevent memory leaks.
* If using the global part interface, ensure proper coordination with
* gGlobalUserFcn cleanup.
*/
PUserFcn::~PUserFcn()
{
@@ -51,16 +68,48 @@ PUserFcn::~PUserFcn()
//------------------------------------------------------
/**
* <p> user function example: polynome of 3rd order
* \brief Evaluates the third-order polynomial at the given time.
*
* \f[ = \sum_{k=0}^3 c_k t^k \f]
* Computes a cubic polynomial of the form:
*
* <b>meaning of paramValues:</b> \f$c_0\f$, \f$c_1\f$, \f$c_2\f$, \f$c_3\f$
* \f[ P(t) = c_0 + c_1 t + c_2 t^2 + c_3 t^3 = \sum_{k=0}^{3} c_k t^k \f]
*
* <b>return:</b> function value
* where the coefficients \f$c_k\f$ are provided in the parameter vector.
*
* \param t time in \f$(\mu\mathrm{s})\f$, or x-axis value for non-muSR fit
* \param param parameter vector
* \section puserfcn_op_example Example MSR Configuration
*
* \code
* FITPARAMETER
* # No Name Value Step Pos_Error Boundaries
* 1 c0 0.95 0.01 none
* 2 c1 -0.001 0.0001 none
* 3 c2 0.00001 0.000001 none
* 4 c3 0.0 0.0000001 none 0 none (fixed to zero for quadratic)
*
* THEORY
* userFcn libPUserFcn.so PUserFcn 1 2 3 4
* \endcode
*
* \section puserfcn_op_notes Implementation Notes
*
* - Uses direct polynomial evaluation (Horner's method could improve
* numerical stability for high-precision applications)
* - Asserts exactly 4 parameters to catch MSR file configuration errors
* - No special handling for negative time values
*
* \param t Independent variable (time in μs for μSR, or general x-axis
* value for non-μSR fits)
* \param param Vector containing exactly 4 polynomial coefficients:
* - param[0]: \f$c_0\f$ - constant term (dimensionless)
* - param[1]: \f$c_1\f$ - linear coefficient (μs⁻¹)
* - param[2]: \f$c_2\f$ - quadratic coefficient (μs⁻²)
* - param[3]: \f$c_3\f$ - cubic coefficient (μs⁻³)
*
* \return The polynomial value \f$P(t)\f$ at the specified time
*
* \pre param.size() == 4 (enforced by assertion)
*
* \see PUserFcnBase::operator() for the virtual interface specification
*/
Double_t PUserFcn::operator()(Double_t t, const std::vector<Double_t> &param) const
{

View File

@@ -34,21 +34,58 @@
ClassImp(PUserFcnBase)
//--------------------------------------------------------------------------
// This function is a replacement for the ParseFile method of TSAXParser.
// It is needed because in certain environments ParseFile does not work but ParseBuffer does.
//--------------------------------------------------------------------------
/**
* <p> Replacement for the ParseFile method of TSAXParser
* that can be used in user functions.
* \brief Parses an XML file using buffer-based parsing for better compatibility.
*
* <p><b>return:</b>
* - 1 if file cannot be read
* - 0 if the file has been parsed successfully
* - parse error code otherwise
* This function provides a replacement for TSAXParser::ParseFile() that works
* reliably across different environments. Some systems have issues with direct
* file parsing, but buffer-based parsing (ParseBuffer) works consistently.
*
* \param saxParser pointer to a TSAXParser object
* \param startup_path_name full path to the XML file to be read
* \section parsexml_usage Usage in User Functions
*
* User functions that need to read XML configuration files should use this
* function instead of TSAXParser::ParseFile():
*
* \code{.cpp}
* class TMyConfigurableFcn : public PUserFcnBase {
* private:
* MyConfigHandler fHandler; // Derived from TSAXParser callbacks
*
* public:
* Bool_t LoadConfig(const char* configFile) {
* TSAXParser parser;
* parser.ConnectToHandler("MyConfigHandler", &fHandler);
*
* Int_t status = parseXmlFile(&parser, configFile);
* if (status != 0) {
* std::cerr << "Failed to parse config: " << configFile << std::endl;
* return false;
* }
* return true;
* }
* };
* \endcode
*
* \section parsexml_algorithm Algorithm
*
* 1. Opens the file in binary mode, seeking to end
* 2. Determines file size from stream position
* 3. Allocates buffer and reads entire file
* 4. Passes buffer to TSAXParser::ParseBuffer()
* 5. Cleans up buffer memory
*
* \param saxParser Pointer to a configured TSAXParser object. The parser
* should have its handler connected before calling this function.
* \param startup_path_name Full filesystem path to the XML file to parse.
*
* \return Status code:
* - 0: Success - file parsed without errors
* - 1: File error - could not open or read the file
* - >1: XML parse error from TSAXParser::ParseBuffer()
*
* \see PStartupHandler for an example of XML parsing in musrfit
* \see TSAXParser for ROOT's SAX parser documentation
*/
Int_t parseXmlFile(TSAXParser *saxParser, const char *startup_path_name)
{
@@ -76,5 +113,43 @@ Int_t parseXmlFile(TSAXParser *saxParser, const char *startup_path_name)
return status;
}
// place a void pointer vector for global user function objects which might be needed
//--------------------------------------------------------------------------
/**
* \brief Global storage for user function objects requiring persistent state.
*
* This vector provides a global container for user functions that need to
* maintain state across multiple evaluations or share data between runs.
* It is primarily used by user functions implementing the "global part"
* interface (NeedGlobalPart(), SetGlobalPart(), GlobalPartIsValid()).
*
* \section gGlobalUserFcn_usage Usage Pattern
*
* User functions with expensive initialization (lookup tables, precomputed
* grids, loaded data files) store their global objects here:
*
* \code{.cpp}
* // In user function's SetGlobalPart implementation:
* void TMyFcn::SetGlobalPart(std::vector<void*> &globalPart, UInt_t idx) {
* if (idx < globalPart.size() && globalPart[idx] != nullptr) {
* fGlobal = static_cast<MyGlobalData*>(globalPart[idx]);
* } else {
* fGlobal = new MyGlobalData();
* fGlobal->Initialize(); // Expensive one-time computation
* if (idx < globalPart.size())
* globalPart[idx] = fGlobal;
* else
* globalPart.push_back(fGlobal);
* }
* }
* \endcode
*
* \note The vector stores void pointers, so user functions must cast
* appropriately and manage memory for their specific data types.
*
* \warning User functions are responsible for proper cleanup of their
* global objects to avoid memory leaks.
*
* \see PUserFcnBase::SetGlobalPart() for the interface to populate this vector
* \see PTheory for how global parts are initialized during theory setup
*/
std::vector<void *> gGlobalUserFcn;