diff --git a/src/classes/PFunction.cpp b/src/classes/PFunction.cpp index f1361d08c..3d0f8b963 100644 --- a/src/classes/PFunction.cpp +++ b/src/classes/PFunction.cpp @@ -40,24 +40,34 @@ // Constructor //-------------------------------------------------------------------------- /** - *
Constructor. + * \brief Constructor that initializes the function from a parsed AST. * - * info is an abstract syntax tree (AST) generate by the spirit parse library - * (see http://spirit.sourceforge.net/distrib/spirit_1_8_5/libs/spirit/doc/trees.html). - * It contains a single parsed msr-function in an ascii representation. - * Here it takes the from + * This constructor performs the following steps: + * 1. Stores the AST generated by the Boost.Spirit parser + * 2. Extracts the function number from the function label (FUNx) + * 3. Converts the AST into an efficient evaluation tree structure + * 4. Generates a human-readable string representation of the function + * + * The input AST has the following structure: * \verbatim * assignment (root node) - * |_ 'FUNx' - * |_ '=' - * |_ expression - * |_ ... + * |_ 'FUNx' (function label) + * |_ '=' (assignment operator) + * |_ expression (mathematical expression tree) + * |_ term + * |_ factor + * |_ ... * \endverbatim * - *
Since it would be inefficient to evaluate this AST directly it is transferred to - * a more efficient tree fFuncs here in the constructor. + * Direct evaluation of the AST would be inefficient due to its verbose structure. + * Therefore, it is converted to a more compact evaluation tree (fFunc) optimized + * for repeated evaluation with different parameter values during fitting. * - * \param info AST parse tree holding a single parsed msr-function in an ascii representation + * \param info AST parse tree from Boost.Spirit containing a parsed msr-function + * + * \see SetFuncNo for function number extraction + * \see GenerateFuncEvalTree for AST to evaluation tree conversion + * \see EvalTreeForString for string representation generation */ PFunction::PFunction(tree_parse_info<> info) : fInfo(info) { @@ -80,7 +90,12 @@ PFunction::PFunction(tree_parse_info<> info) : fInfo(info) // Destructor //-------------------------------------------------------------------------- /** - *
Destructor. + * \brief Destructor that releases all resources. + * + * Cleans up: + * - Parameter vector + * - Map vector + * - Evaluation tree (recursively frees all nodes and their children) */ PFunction::~PFunction() { @@ -112,9 +127,14 @@ void PFunction::InitNode(PFuncTreeNode &node) // SetFuncNo (protected) //------------------------------------------------------------- /** - *
Extracts the function number of the AST tree. + * \brief Extracts the function number from the AST tree. * - * return: true if the function number (of FUNx, x being a number) could be extracted, otherwise false. + * Navigates to the function label node in the AST and parses the numeric + * identifier from the "FUNx" label. For example, "FUN3" yields 3. + * + * \return true if the function number was successfully extracted, false otherwise + * + * \note The function number is stored in the member variable fFuncNo */ Bool_t PFunction::SetFuncNo() { @@ -145,8 +165,15 @@ Bool_t PFunction::SetFuncNo() // GenerateFuncEvalTree (protected) //------------------------------------------------------------- /** - *
Stub to generate the function evaluation tree from the AST tree. Needed for an efficient - * evaluation. + * \brief Initiates conversion of AST to evaluation tree. + * + * This function initializes the root node and triggers the recursive + * conversion process. The evaluation tree is a more efficient representation + * than the AST for repeated function evaluations during fitting. + * + * \return true (currently always successful) + * + * \see FillFuncEvalTree for the recursive conversion algorithm */ Bool_t PFunction::GenerateFuncEvalTree() { @@ -160,10 +187,23 @@ Bool_t PFunction::GenerateFuncEvalTree() // FillFuncEvalTree (protected) //------------------------------------------------------------- /** - *
Recursive generation of the evaluation tree. + * \brief Recursively converts AST nodes to evaluation tree nodes. * - * \param i iterator of the AST tree - * \param node of the evaluation tree + * This function traverses the AST and builds a corresponding evaluation tree. + * It handles all node types defined in PFunctionGrammar: + * - Leaf nodes: real numbers, constants (PI, GAMMA_MU, B, EN, T), parameters, maps + * - Operator nodes: arithmetic operations (+, -, *, /) + * - Function nodes: mathematical functions (cos, sin, exp, etc.) + * - Power nodes: POW(base, exponent) + * - Composite nodes: factors, terms, expressions + * + * The resulting tree structure is optimized for efficient evaluation. + * + * \param i Iterator pointing to the current AST node to process + * \param node Evaluation tree node to populate with data from the AST + * + * \see PFunctionGrammar for AST node type definitions + * \see EvalNode for the evaluation algorithm that uses this tree */ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) { @@ -340,10 +380,17 @@ void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node) // CheckMapAndParamRange (public) //------------------------------------------------------------- /** - *
Stub the check map and fit parameter ranges.
+ * \brief Validates all map and parameter references in the function.
*
- * \param mapSize size of the map vector
- * \param paramSize size of the parameter vector
+ * Initiates a recursive traversal of the evaluation tree to verify that all
+ * MAP# and PAR# references fall within valid ranges. This prevents runtime
+ * errors during evaluation caused by out-of-bounds array access.
+ *
+ * \param mapSize Number of available map entries (MAP1 to MAP Recursive checking of map and fit parameter ranges.
+ * \brief Recursively validates map and parameter references in the tree.
*
- * \param node of the evaluation tree
- * \param mapSize size of the map vector
- * \param paramSize size of the fit parameter vector
+ * Traverses the evaluation tree depth-first, checking each node:
+ * - For parameter nodes (PAR#): verifies # <= paramSize
+ * - For map nodes (MAP#): verifies # <= mapSize
+ * - For other nodes: recursively checks all children
+ *
+ * The validation ensures that array indices will be valid during evaluation,
+ * preventing potential segmentation faults or undefined behavior.
+ *
+ * \param node Current evaluation tree node being checked
+ * \param mapSize Number of available map entries
+ * \param paramSize Number of available fit parameters
+ * \return true if this node and all descendants have valid references, false otherwise
*/
Bool_t PFunction::FindAndCheckMapAndParamRange(PFuncTreeNode &node, UInt_t mapSize, UInt_t paramSize)
{
@@ -416,11 +472,25 @@ Bool_t PFunction::FindAndCheckMapAndParamRange(PFuncTreeNode &node, UInt_t mapSi
// Eval (public)
//-------------------------------------------------------------
/**
- * Stub starting the evaluation of the evaluation tree.
+ * \brief Evaluates the function with given parameters and metadata.
*
- * return: the value of the function call.
+ * This is the main evaluation entry point. It:
+ * 1. Stores the current parameter values and metadata
+ * 2. Initiates recursive evaluation of the tree
+ * 3. Returns the computed result
*
- * \param param fit parameter vector
+ * The function can be evaluated multiple times with different parameter
+ * values without re-parsing or rebuilding the evaluation tree, making it
+ * efficient for iterative fitting algorithms.
+ *
+ * \param param Vector of fit parameter values (PAR1, PAR2, ...)
+ * \param metaData Experimental metadata (field, energy, temperature, etc.)
+ * \return Computed function value
+ *
+ * \see EvalNode for the recursive evaluation algorithm
+ *
+ * \warning Ensure CheckMapAndParamRange has been called before evaluation
+ * to prevent out-of-bounds access
*/
Double_t PFunction::Eval(std::vector Recursive evaluation of the evaluation tree.
+ * \brief Recursively evaluates an evaluation tree node.
*
- * \param node of the evaluation tree
+ * This is the core evaluation algorithm that computes the function value
+ * by recursively processing the tree structure. Each node type is handled
+ * appropriately:
+ *
+ * - Leaf nodes (constants, parameters, maps): Return their values directly
+ * - Operator nodes (+, -, *, /): Evaluate children and apply operation
+ * - Function nodes (cos, sin, exp, etc.): Evaluate argument and apply function
+ * - Power nodes: Evaluate base and exponent, compute power
+ *
+ * Special handling:
+ * - Division by zero: Triggers an error and assertion
+ * - Negative bases in power: Takes absolute value if exponent is non-integer
+ * - Logarithms and square roots: Use absolute value to avoid complex numbers
+ * - Maps: Returns 0 if map value is 0, otherwise returns the mapped parameter
+ *
+ * \param node Current evaluation tree node to evaluate
+ * \return Computed value for this node
+ *
+ * \see Eval for the public evaluation entry point
*/
Double_t PFunction::EvalNode(PFuncTreeNode &node)
{
@@ -570,7 +658,12 @@ Double_t PFunction::EvalNode(PFuncTreeNode &node)
// CleanupFuncEvalTree (protected)
//-------------------------------------------------------------
/**
- * Stub to clean up the evaluation tree.
+ * \brief Initiates cleanup of the evaluation tree.
+ *
+ * Starts the recursive cleanup process from the root node to free all
+ * dynamically allocated child nodes in the tree.
+ *
+ * \see CleanupNode for the recursive cleanup algorithm
*/
void PFunction::CleanupFuncEvalTree()
{
@@ -582,9 +675,13 @@ void PFunction::CleanupFuncEvalTree()
// CleanupNode (protected)
//-------------------------------------------------------------
/**
- * Recursive clean up of the evaluation tree.
+ * \brief Recursively cleans up evaluation tree nodes and their children.
*
- * \param node of the evaluation tree
+ * Performs depth-first traversal to clean up all child nodes before
+ * clearing the current node's children vector. This ensures proper
+ * resource deallocation and prevents memory leaks.
+ *
+ * \param node Current evaluation tree node to clean up
*/
void PFunction::CleanupNode(PFuncTreeNode &node)
{
@@ -600,9 +697,15 @@ void PFunction::CleanupNode(PFuncTreeNode &node)
// EvalTreeForString (private)
//-------------------------------------------------------------
/**
- * Stub to generate the function string (clean and tidy).
+ * \brief Initiates generation of human-readable function string from AST.
*
- * \param info AST tree
+ * Creates a formatted, readable string representation of the function by
+ * traversing the AST. The resulting string is stored in fFuncString and
+ * can be used for display, logging, or debugging purposes.
+ *
+ * \param info AST parse tree to convert to string
+ *
+ * \see EvalTreeForStringExpression for the recursive string generation algorithm
*/
void PFunction::EvalTreeForString(tree_parse_info<> info)
{
@@ -614,9 +717,24 @@ void PFunction::EvalTreeForString(tree_parse_info<> info)
// EvalTreeForStringExpression (private)
//-------------------------------------------------------------
/**
- * Recursive generation of the function string (clean and tidy).
+ * \brief Recursively generates formatted function string from AST.
*
- * \param i iterator of the AST tree
+ * Traverses the AST and builds a human-readable string representation.
+ * The function handles:
+ * - Proper parenthesization to maintain operator precedence
+ * - Formatting of constants (PI -> Pi, GAMMA_MU -> gamma_mu)
+ * - Proper spacing around operators
+ * - Special handling for division denominators (adds parentheses if needed)
+ * - Function call formatting with arguments
+ *
+ * The resulting string is formatted for readability while maintaining
+ * mathematical correctness.
+ *
+ * \param i Iterator pointing to current AST node
+ * \param funcFlag Flag indicating if currently processing inside a function argument
+ * (affects parenthesization rules)
+ *
+ * \note Uses a static variable termOp to track operator nesting depth
*/
void PFunction::EvalTreeForStringExpression(iter_t const& i, bool funcFlag)
{
diff --git a/src/include/PFunction.h b/src/include/PFunction.h
index af7a294e3..8f624deb6 100644
--- a/src/include/PFunction.h
+++ b/src/include/PFunction.h
@@ -48,85 +48,256 @@
#include "PFunctionGrammar.h"
//----------------------------------------------------------------------------
-#define OP_ADD 0
-#define OP_SUB 1
-#define OP_MUL 2
-#define OP_DIV 3
+// Operator tags for arithmetic operations
+//----------------------------------------------------------------------------
+#define OP_ADD 0 ///< Addition operator tag
+#define OP_SUB 1 ///< Subtraction operator tag
+#define OP_MUL 2 ///< Multiplication operator tag
+#define OP_DIV 3 ///< Division operator tag
-#define FUN_COS 0
-#define FUN_SIN 1
-#define FUN_TAN 2
-#define FUN_COSH 3
-#define FUN_SINH 4
-#define FUN_TANH 5
-#define FUN_ACOS 6
-#define FUN_ASIN 7
-#define FUN_ATAN 8
-#define FUN_ACOSH 9
-#define FUN_ASINH 10
-#define FUN_ATANH 11
-#define FUN_LOG 12
-#define FUN_LN 13
-#define FUN_EXP 14
-#define FUN_SQRT 15
-#define FUN_POW 16
+//----------------------------------------------------------------------------
+// Function tags for mathematical functions
+//----------------------------------------------------------------------------
+#define FUN_COS 0 ///< Cosine function tag
+#define FUN_SIN 1 ///< Sine function tag
+#define FUN_TAN 2 ///< Tangent function tag
+#define FUN_COSH 3 ///< Hyperbolic cosine function tag
+#define FUN_SINH 4 ///< Hyperbolic sine function tag
+#define FUN_TANH 5 ///< Hyperbolic tangent function tag
+#define FUN_ACOS 6 ///< Inverse cosine (arccos) function tag
+#define FUN_ASIN 7 ///< Inverse sine (arcsin) function tag
+#define FUN_ATAN 8 ///< Inverse tangent (arctan) function tag
+#define FUN_ACOSH 9 ///< Inverse hyperbolic cosine function tag
+#define FUN_ASINH 10 ///< Inverse hyperbolic sine function tag
+#define FUN_ATANH 11 ///< Inverse hyperbolic tangent function tag
+#define FUN_LOG 12 ///< Base-10 logarithm function tag
+#define FUN_LN 13 ///< Natural logarithm function tag
+#define FUN_EXP 14 ///< Exponential function tag
+#define FUN_SQRT 15 ///< Square root function tag
+#define FUN_POW 16 ///< Power function tag (base^exponent)
//----------------------------------------------------------------------------
/**
- * Structure needed to evaluate a function tree (see FUNCTIONS block of an msr-file).
+ * \brief Tree node structure for efficient function evaluation.
+ *
+ * This structure represents a node in the evaluation tree used to compute
+ * function values. The abstract syntax tree (AST) generated by the parser
+ * is converted into this more efficient tree structure for faster evaluation.
+ *
+ * Each node can represent:
+ * - A leaf node (constant, parameter, map reference)
+ * - An operator node (arithmetic operation)
+ * - A function node (mathematical function)
+ *
+ * The tree is evaluated recursively by traversing from the root to the leaves.
+ *
+ * \see PFunction::EvalNode for the recursive evaluation algorithm
*/
typedef struct func_tree_node {
- Int_t fID; ///< tag showing what tree element this is
- Int_t fOperatorTag; ///< tag for '+', '-', '*', '/'
- Int_t fFunctionTag; ///< tag got "cos", "sin", ...
- Int_t fIvalue; ///< for parameter numbers and maps
- Bool_t fSign; ///< for sign, true means '-', false '+'
- Double_t fDvalue; ///< for numbers
- std::vector Class handling a function from the msr-file FUNCTIONS block.
+ * \brief Class for parsing and evaluating mathematical functions from msr-file FUNCTIONS blocks.
+ *
+ * This class handles the complete lifecycle of a function definition:
+ * 1. Parses the function string using PFunctionGrammar into an AST
+ * 2. Converts the AST into an efficient evaluation tree
+ * 3. Validates parameter and map references
+ * 4. Evaluates the function with given parameters and metadata
+ *
+ * Functions can reference:
+ * - Fit parameters (PAR1, PAR2, ...)
+ * - Map values (MAP1, MAP2, ...)
+ * - Constants (PI, GAMMA_MU)
+ * - Metadata (magnetic field B, energy EN, temperature T)
+ * - Other functions (FUN1, FUN2, ...)
+ *
+ * Example function definition:
+ * \code
+ * FUN1 = PAR1 * COS(2.0 * PI * GAMMA_MU * B * PAR2)
+ * \endcode
+ *
+ * \see PFunctionGrammar for the grammar definition
+ * \see PFuncTreeNode for the evaluation tree structure
*/
class PFunction {
public:
+ //------------------------------------------------------------------------
+ /**
+ * \brief Constructor that parses and prepares a function for evaluation.
+ *
+ * \param info Abstract syntax tree (AST) from parsing a function expression
+ */
PFunction(tree_parse_info<> info);
+
+ //------------------------------------------------------------------------
+ /**
+ * \brief Destructor that cleans up the evaluation tree.
+ */
virtual ~PFunction();
+ //------------------------------------------------------------------------
+ /**
+ * \brief Checks if the function was successfully parsed and initialized.
+ *
+ * \return true if the function is valid, false otherwise
+ */
virtual Bool_t IsValid() { return fValid; }
+
+ //------------------------------------------------------------------------
+ /**
+ * \brief Returns the function number extracted from the function label.
+ *
+ * \return Function number (x from FUNx), or -1 if invalid
+ */
virtual Int_t GetFuncNo() { return fFuncNo; }
+
+ //------------------------------------------------------------------------
+ /**
+ * \brief Validates that all parameter and map references are within valid ranges.
+ *
+ * \param mapSize Number of available map entries
+ * \param paramSize Number of available fit parameters
+ * \return true if all references are valid, false otherwise
+ */
virtual Bool_t CheckMapAndParamRange(UInt_t mapSize, UInt_t paramSize);
+
+ //------------------------------------------------------------------------
+ /**
+ * \brief Evaluates the function with given parameters and metadata.
+ *
+ * \param param Vector of fit parameter values
+ * \param metaData Metadata containing field, energy, temperature, etc.
+ * \return Computed function value
+ */
virtual Double_t Eval(std::vector EBNF like grammar definition of a function entry in the msr-file FUNCTION block.
+ * \brief EBNF-like grammar definition for parsing function entries in msr-file FUNCTION blocks.
+ *
+ * This grammar defines the syntax for parsing mathematical function expressions in msr-files.
+ * It supports:
+ * - Basic arithmetic operations (+, -, *, /)
+ * - Mathematical functions (trigonometric, hyperbolic, logarithmic, exponential, etc.)
+ * - Constants (PI, GAMMA_MU, field B, energy EN, temperature T)
+ * - Parameters (PAR) and maps (MAP)
+ * - Function references (FUN)
+ *
+ * The grammar follows an EBNF-like structure with the following hierarchy:
+ * \verbatim
+ * assignment = fun_label '=' expression
+ * expression = term { ('+' | '-') term }
+ * term = factor { ('*' | '/') factor }
+ * factor = real | constant | parameter | map | function | power | '(' expression ')'
+ * \endverbatim
+ *
+ * \see PFunction for the class that uses this grammar to evaluate parsed expressions
*/
struct PFunctionGrammar : public grammar