improve the doxygen docu of PRunBase.*

This commit is contained in:
2025-11-15 08:02:11 +01:00
parent a05b4fe867
commit 38decd8b58
2 changed files with 354 additions and 103 deletions

View File

@@ -42,7 +42,14 @@
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor. Needed otherwise vector's cannot be generated ;-)
* \brief Default constructor that initializes all member variables to default values.
*
* Creates an empty, invalid run object with all pointers set to nullptr and
* values set to undefined/invalid states. This constructor is needed to allow
* creation of vectors of PRunBase-derived objects.
*
* A run created with this constructor requires initialization via the main
* constructor before it can be used for fitting.
*/
PRunBase::PRunBase()
{
@@ -64,12 +71,25 @@ PRunBase::PRunBase()
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor.
* \brief Main constructor that initializes a run from MSR file and raw data.
*
* \param msrInfo pointer to the msr-file handler
* \param rawData pointer to the raw-data handler
* \param runNo msr-file run number
* \param tag tag telling if fit, view, or rrf representation is whished.
* Performs comprehensive initialization:
* 1. Stores operation mode (fit vs. view) and pointers to MSR and data handlers
* 2. Extracts run-specific settings from the appropriate MSR RUN block
* 3. Validates function parameter mappings to ensure FUNCTIONS block is valid
* 4. Initializes metadata structures (field, energy, temperature)
* 5. Initializes function value cache for FUNCTIONS block evaluation
* 6. Creates PTheory object for evaluating the theory function
* 7. Validates that theory initialization succeeded
*
* If any initialization step fails (e.g., invalid theory, out-of-range parameters),
* the program exits with an error message. The run object is marked as valid upon
* successful completion.
*
* \param msrInfo Pointer to MSR file handler (must remain valid for object lifetime)
* \param rawData Pointer to raw data handler (must remain valid for object lifetime)
* \param runNo Run number (0-based index into MSR file RUN blocks)
* \param tag Operation mode: kFit (fitting), kView (display/plotting)
*/
PRunBase::PRunBase(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo, EPMusrHandleTag tag) :
fHandleTag(tag), fMsrInfo(msrInfo), fRawData(rawData)
@@ -118,7 +138,16 @@ PRunBase::PRunBase(PMsrHandler *msrInfo, PRunDataHandler *rawData, UInt_t runNo,
// Destructor
//--------------------------------------------------------------------------
/**
* <p>Destructor.
* \brief Virtual destructor that cleans up allocated resources.
*
* Frees memory allocated for:
* - t0 value vectors (fT0s)
* - Additional run t0 vectors (fAddT0s)
* - Function value cache (fFuncValues)
*
* The PTheory object is automatically deleted via unique_ptr.
* Pointers to MSR handler and raw data handler are NOT deleted as they
* are owned by the calling code.
*/
PRunBase::~PRunBase()
{
@@ -135,9 +164,25 @@ PRunBase::~PRunBase()
// SetFitRange (public)
//--------------------------------------------------------------------------
/**
* <p> Sets the current fit range, and recalculated the number of fitted bins
* \brief Sets the fit time range and recalculates the number of fitted bins.
*
* \param fitRange vector with fit ranges
* Updates the fitting window for this run. This method handles two scenarios:
* 1. Single fit range: If fitRange contains one pair, it applies to all runs
* 2. Multiple fit ranges: If fitRange contains multiple pairs, it selects the
* appropriate range based on fRunNo
*
* The method validates that:
* - The fit range vector is not empty (asserts)
* - The run number is within the fit range vector bounds
* - Start time is before end time (swaps if not)
*
* This is typically called by the FIT_RANGE command to dynamically adjust the
* fitting window during optimization or range scanning.
*
* \param fitRange Vector of (start, end) time pairs in microseconds (μs)
*
* Example: fitRange = {(0.1, 10.0), (0.2, 8.0)} applies first range to run 0,
* second range to run 1
*/
void PRunBase::SetFitRange(PDoublePairVector fitRange)
{
@@ -177,7 +222,13 @@ void PRunBase::SetFitRange(PDoublePairVector fitRange)
// CleanUp (public)
//--------------------------------------------------------------------------
/**
* <p> Clean up all locally allocate memory
* \brief Cleans up allocated resources.
*
* Releases memory used by the PTheory object via unique_ptr reset.
* This is called when the run processing is complete or when preparing
* for a new fit with different settings.
*
* Other data structures (vectors) are managed automatically by their destructors.
*/
void PRunBase::CleanUp()
{
@@ -188,14 +239,37 @@ void PRunBase::CleanUp()
// CalculateKaiserFilterCoeff (protected)
//--------------------------------------------------------------------------
/**
* <p>Calculates the Kaiser filter coefficients for a low pass filter with
* a cut off frequency wc.
* For details see "Zeitdiskrete Signalverarbeitung", A.V. Oppenheim, R.W. Schafer, J.R. Buck. Pearson 2004.
* \brief Calculates Kaiser window FIR filter coefficients for RRF smoothing.
*
* \param wc cut off frequency
* \param A defined as \f$ A = -\log_{10}(\delta) \f$, where \f$\delta\f$ is the tolerance band.
* \param dw defined as \f$ \Delta\omega = \omega_{\rm S} - \omega_{\rm P} \f$, where \f$ \omega_{\rm S} \f$ is the
* stop band frequency, and \f$ \omega_{\rm P} \f$ is the pass band frequency.
* Designs a low-pass FIR filter using the Kaiser window method, which provides
* excellent control over the frequency response characteristics. The filter is
* used to smooth theory curves in rotating reference frame (RRF) fits, ensuring
* consistent comparison between filtered data and filtered theory.
*
* Algorithm (based on Oppenheim, Schafer, Buck, "Discrete-Time Signal Processing"):
* 1. Determine β parameter from attenuation requirement A
* 2. Calculate filter order m from transition width dw
* 3. Generate Kaiser window: \f$ w[n] = \frac{I_0(\beta\sqrt{1-(n/\alpha)^2})}{I_0(\beta)} \f$
* 4. Apply window to ideal sinc filter: \f$ h[n] = \frac{\sin(\omega_c n)}{\pi n} \cdot w[n] \f$
* 5. Normalize coefficients to unity gain at DC
*
* The β parameter is chosen based on attenuation A (in dB):
* - A > 50: β = 0.1102(A - 8.7)
* - 21 ≤ A ≤ 50: β = 0.5842(A - 21)^0.4 + 0.07886(A - 21)
* - A < 21: β = 0
*
* Filter order: m = (A - 8) / (2.285 × Δω × π), rounded to nearest odd integer
*
* Reference: A.V. Oppenheim, R.W. Schafer, J.R. Buck,
* "Discrete-Time Signal Processing", Pearson 2004, pp. 574ff
*
* \param wc Cutoff frequency (normalized, 0 to π rad/sample)
* \param A Attenuation in dB: A = -20 log₁₀(δ) where δ is the tolerance band
* \param dw Transition width: Δω = ω_S - ω_P (stop band - pass band frequencies)
*
* The computed coefficients are stored in fKaiserFilter and normalized for unity DC gain.
*
* \see FilterTheo() for application of these coefficients
*/
void PRunBase::CalculateKaiserFilterCoeff(Double_t wc, Double_t A, Double_t dw)
{
@@ -235,7 +309,33 @@ void PRunBase::CalculateKaiserFilterCoeff(Double_t wc, Double_t A, Double_t dw)
// FilterTheo (protected)
//--------------------------------------------------------------------------
/**
* <p>Filters the theory with a Kaiser FIR filter.
* \brief Applies Kaiser FIR filter to theory values for RRF fits.
*
* Performs time-domain convolution of the theory function with the Kaiser filter
* coefficients computed by CalculateKaiserFilterCoeff(). This smooths the theory
* curve to match the filtering applied to RRF-transformed data, ensuring fair
* comparison during χ² calculation.
*
* The filtering operation is:
* \f[ y_{\rm filtered}[i] = \sum_{j=0}^{M-1} h[j] \cdot y_{\rm theory}[i-j] \f]
*
* where:
* - h[j] are the Kaiser filter coefficients from fKaiserFilter
* - M is the filter length
* - For i < j, the missing samples are treated as zero (causal filter)
*
* Additional processing:
* - The filtered theory replaces the original theory in fData
* - Time start is shifted backward by half the filter length to compensate
* for the group delay introduced by the symmetric FIR filter
*
* This method is only called by RRF-derived classes (PRunAsymmetryRRF, PRunSingleHistoRRF)
* after theory calculation and RRF transformation.
*
* \pre CalculateKaiserFilterCoeff() must have been called to initialize fKaiserFilter
* \pre fData must contain theory values (CalcTheory() must have been called)
*
* \see CalculateKaiserFilterCoeff() for filter coefficient calculation
*/
void PRunBase::FilterTheo()
{