All checks were successful
Build and Deploy Documentation / build-and-deploy (push) Successful in 18s
243 lines
8.7 KiB
C++
243 lines
8.7 KiB
C++
/***************************************************************************
|
|
|
|
PUserFcnBase.h
|
|
|
|
Author: Andreas Suter
|
|
e-mail: andreas.suter@psi.ch
|
|
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* Copyright (C) 2007-2025 by Andreas Suter *
|
|
* andreas.suter@psi.ch *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
#ifndef _PUSERFCNBASE_H_
|
|
#define _PUSERFCNBASE_H_
|
|
|
|
#include <vector>
|
|
|
|
#include "TObject.h"
|
|
#include "TSAXParser.h"
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
/**
|
|
* \brief Abstract base class for user-defined theory functions in musrfit.
|
|
*
|
|
* 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 via ROOT's plugin mechanism.
|
|
*
|
|
* \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, 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
|
|
*
|
|
* \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"
|
|
*
|
|
* class TMyRelaxation : public PUserFcnBase {
|
|
* public:
|
|
* TMyRelaxation() {}
|
|
* virtual ~TMyRelaxation() {}
|
|
*
|
|
* virtual Double_t operator()(Double_t t, const std::vector<Double_t> &par) const;
|
|
*
|
|
* ClassDef(TMyRelaxation, 1)
|
|
* };
|
|
*
|
|
* #endif
|
|
* \endcode
|
|
*
|
|
* <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 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
|
|
{
|
|
public:
|
|
/// Default constructor
|
|
PUserFcnBase() {}
|
|
|
|
/// Virtual destructor
|
|
virtual ~PUserFcnBase() {}
|
|
|
|
/**
|
|
* <p>Indicates if this function requires global initialization.
|
|
*
|
|
* <p>Override to return true if your function needs expensive one-time
|
|
* setup (e.g., calculating lookup tables, loading external data).
|
|
* The global part is computed once and reused across fit iterations.
|
|
*
|
|
* @return true if global part needed, false otherwise (default: false)
|
|
*/
|
|
virtual Bool_t NeedGlobalPart() const { return false; }
|
|
|
|
/**
|
|
* <p>Sets up the global part of the user function.
|
|
*
|
|
* <p>Called once during initialization if NeedGlobalPart() returns true.
|
|
* Use this to allocate and initialize shared data structures.
|
|
*
|
|
* @param globalPart Vector of global objects (one per run)
|
|
* @param idx Index of this run's global object in the vector
|
|
*/
|
|
virtual void SetGlobalPart(std::vector<void *> &globalPart, UInt_t idx) {}
|
|
|
|
/**
|
|
* <p>Checks if the global part initialized correctly.
|
|
*
|
|
* <p>Override to validate your global data structure after SetGlobalPart().
|
|
*
|
|
* @return true if global part is valid and ready, false otherwise (default: false)
|
|
*/
|
|
virtual Bool_t GlobalPartIsValid() const { return false; }
|
|
|
|
/**
|
|
* <p>Evaluates the user function at time t (pure virtual).
|
|
*
|
|
* <p>This is the core evaluation method called for each data point
|
|
* during fitting. Must be implemented by derived classes.
|
|
*
|
|
* <p><b>Parameter convention:</b> The last parameter is typically the
|
|
* time shift. Earlier parameters are model-specific (rates, amplitudes,
|
|
* exponents, etc.).
|
|
*
|
|
* @param t Time in microseconds (μs)
|
|
* @param param Vector of function parameters (from MSR file + maps)
|
|
* @return Function value at time t
|
|
*/
|
|
virtual Double_t operator()(Double_t t, const std::vector<Double_t> ¶m) const = 0;
|
|
|
|
ClassDef(PUserFcnBase, 1)
|
|
};
|
|
|
|
//--------------------------------------------------------------------------
|
|
/**
|
|
* <p>XML file parser for user function configurations.
|
|
*
|
|
* <p>This function provides a replacement for TSAXParser::ParseFile with
|
|
* better error handling for XML configuration files used by some user
|
|
* functions to load parameters or settings.
|
|
*
|
|
* @param parser Pointer to TSAXParser object
|
|
* @param fileName Path to XML file to parse
|
|
* @return 0 on success, error code on failure
|
|
*/
|
|
Int_t parseXmlFile(TSAXParser*, const Char_t*);
|
|
|
|
#endif // _PUSERFCNBASE_H_
|