improve the doxygen docu of PUserFcn.* and PUserFcnBase.*
All checks were successful
Build and Deploy Documentation / build-and-deploy (push) Successful in 18s
All checks were successful
Build and Deploy Documentation / build-and-deploy (push) Successful in 18s
This commit is contained in:
@@ -37,52 +37,134 @@
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* <p>Abstract base class for user-defined theory functions.
|
||||
* \brief Abstract base class for user-defined theory functions in musrfit.
|
||||
*
|
||||
* <p>PUserFcnBase enables extending musrfit with custom theory functions
|
||||
* beyond the 33 built-in functions. Users create derived classes implementing
|
||||
* PUserFcnBase enables extending musrfit with custom theory functions
|
||||
* beyond the 34 built-in functions. Users create derived classes implementing
|
||||
* specific physics models, compile them into shared libraries, and load them
|
||||
* dynamically at runtime.
|
||||
* dynamically at runtime via ROOT's plugin mechanism.
|
||||
*
|
||||
* <p><b>Use cases:</b>
|
||||
* \section userfcn_use_cases Use Cases
|
||||
*
|
||||
* User functions are valuable for:
|
||||
* - Novel relaxation mechanisms not in standard library
|
||||
* - Material-specific models (e.g., Skyrmion lattices)
|
||||
* - Complex multi-component functions
|
||||
* - Proprietary or experimental theory functions
|
||||
* - Functions requiring external libraries (GSL, CUDA, etc.)
|
||||
* - Material-specific models (e.g., Skyrmion lattices, spin ice)
|
||||
* - Complex multi-component functions requiring custom logic
|
||||
* - Proprietary or experimental theory functions under development
|
||||
* - Functions requiring external libraries (GSL, CUDA, MKL, etc.)
|
||||
* - Performance-critical implementations with custom optimization
|
||||
*
|
||||
* <p><b>Implementation steps:</b>
|
||||
* 1. Create a class deriving from PUserFcnBase
|
||||
* 2. Implement operator()(t, param) with your theory
|
||||
* 3. Optionally implement global part for heavy initialization
|
||||
* 4. Compile to shared library (.so/.dylib/.dll)
|
||||
* 5. Reference in MSR file THEORY block: "userFcn libMyFunc TMyFuncClass"
|
||||
* \section userfcn_implementation Implementation Guide
|
||||
*
|
||||
* <b>Step 1: Create header file (MyUserFcn.h)</b>
|
||||
* \code{.cpp}
|
||||
* #ifndef MY_USER_FCN_H
|
||||
* #define MY_USER_FCN_H
|
||||
*
|
||||
* #include "PUserFcnBase.h"
|
||||
*
|
||||
* <p><b>Example minimal implementation:</b>
|
||||
* @code
|
||||
* class TMyRelaxation : public PUserFcnBase {
|
||||
* public:
|
||||
* Double_t operator()(Double_t t, const std::vector<Double_t> &par) const {
|
||||
* // par[0] = rate, par[1] = exponent, par[2] = time shift
|
||||
* Double_t tt = t - par[2];
|
||||
* if (tt < 0) return 0.0;
|
||||
* return exp(-pow(par[0]*tt, par[1]));
|
||||
* }
|
||||
* TMyRelaxation() {}
|
||||
* virtual ~TMyRelaxation() {}
|
||||
*
|
||||
* virtual Double_t operator()(Double_t t, const std::vector<Double_t> &par) const;
|
||||
*
|
||||
* ClassDef(TMyRelaxation, 1)
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
* <p><b>Global part:</b> For expensive one-time computations (lookup tables,
|
||||
* matrix inversions), override NeedGlobalPart(), SetGlobalPart(), and
|
||||
* GlobalPartIsValid(). The global part is initialized once and shared across
|
||||
* all fit iterations.
|
||||
* #endif
|
||||
* \endcode
|
||||
*
|
||||
* <p><b>MSR file usage:</b>
|
||||
* @code
|
||||
* <b>Step 2: Implement source file (MyUserFcn.cpp)</b>
|
||||
* \code{.cpp}
|
||||
* #include "MyUserFcn.h"
|
||||
* #include <cmath>
|
||||
*
|
||||
* ClassImp(TMyRelaxation)
|
||||
*
|
||||
* Double_t TMyRelaxation::operator()(Double_t t, const std::vector<Double_t> &par) const {
|
||||
* // par[0] = rate (lambda), par[1] = exponent (beta)
|
||||
* if (t < 0) return 1.0;
|
||||
* return exp(-pow(par[0] * t, par[1]));
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* <b>Step 3: Create LinkDef file (MyUserFcnLinkDef.h)</b>
|
||||
* \code{.cpp}
|
||||
* #ifdef __CINT__
|
||||
* #pragma link off all globals;
|
||||
* #pragma link off all classes;
|
||||
* #pragma link off all functions;
|
||||
*
|
||||
* #pragma link C++ class TMyRelaxation+;
|
||||
* #endif
|
||||
* \endcode
|
||||
*
|
||||
* <b>Step 4: Build shared library</b>
|
||||
* \code{.sh}
|
||||
* rootcint -f MyUserFcnDict.cxx -c MyUserFcn.h MyUserFcnLinkDef.h
|
||||
* g++ -shared -fPIC -o libMyUserFcn.so MyUserFcn.cpp MyUserFcnDict.cxx \
|
||||
* $(root-config --cflags --libs) -I$MUSRFIT/include
|
||||
* \endcode
|
||||
*
|
||||
* <b>Step 5: Use in MSR file</b>
|
||||
* \code
|
||||
* THEORY
|
||||
* asymmetry 1
|
||||
* userFcn libMyRelax.so TMyRelaxation map1 2 0.5 (rate, expo, tshift)
|
||||
* @endcode
|
||||
* userFcn libMyUserFcn.so TMyRelaxation 2 3 (rate, exponent)
|
||||
* \endcode
|
||||
*
|
||||
* \section userfcn_global Global Part for Expensive Computations
|
||||
*
|
||||
* For functions requiring expensive one-time setup (lookup tables, matrix
|
||||
* decompositions, file loading), implement the global part interface:
|
||||
*
|
||||
* \code{.cpp}
|
||||
* class TMyComplexFcn : public PUserFcnBase {
|
||||
* private:
|
||||
* mutable void *fGlobal; // Pointer to global data
|
||||
*
|
||||
* public:
|
||||
* virtual Bool_t NeedGlobalPart() const { return true; }
|
||||
*
|
||||
* virtual void SetGlobalPart(std::vector<void*> &globalPart, UInt_t idx) {
|
||||
* if (idx < globalPart.size() && globalPart[idx] != nullptr) {
|
||||
* fGlobal = globalPart[idx]; // Reuse existing
|
||||
* } else {
|
||||
* fGlobal = new MyGlobalData(); // Create new
|
||||
* static_cast<MyGlobalData*>(fGlobal)->Initialize();
|
||||
* if (idx < globalPart.size())
|
||||
* globalPart[idx] = fGlobal;
|
||||
* else
|
||||
* globalPart.push_back(fGlobal);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* virtual Bool_t GlobalPartIsValid() const {
|
||||
* return fGlobal != nullptr;
|
||||
* }
|
||||
*
|
||||
* // ... operator() uses fGlobal for fast lookup
|
||||
* };
|
||||
* \endcode
|
||||
*
|
||||
* \section userfcn_parameters Parameter Conventions
|
||||
*
|
||||
* <b>In the MSR file THEORY block:</b>
|
||||
* \code
|
||||
* userFcn libName.so ClassName param1 param2 ... paramN
|
||||
* \endcode
|
||||
*
|
||||
* Parameters can be:
|
||||
* - Direct numbers: \c 1, \c 2 → parameter indices from FITPARAMETER block
|
||||
* - Map references: \c map1, \c map2 → via RUN block map
|
||||
* - Function references: \c fun1, \c fun2 → evaluated FUNCTIONS
|
||||
*
|
||||
* <b>Convention:</b> The last parameter is typically a time shift.
|
||||
*
|
||||
* \see PTheory for how user functions are loaded and called
|
||||
* \see PUserFcn for a simple example implementation
|
||||
*/
|
||||
class PUserFcnBase : public TObject
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user