from src.wrappers.OsipiBase import OsipiBase
from src.original.fitting.DT_IIITN.wls_ivim_fitting import wls_ivim_fit
import numpy as np
[docs]
class DT_IIITN_WLS(OsipiBase):
"""
Segmented IVIM fitting with selectable regression method.
Two methods are available:
- WLS: Weighted Least Squares with Veraart S² weights (default)
- RLM: Robust Linear Model with Huber's T norm (statsmodels)
Segmented approach:
1. Estimate D from high b-values using linear regression on log-signal
2. Estimate D* from residuals at low b-values using linear regression
Author: Devguru Tiwari, IIIT Nagpur
Reference:
Veraart, J. et al. (2013). "Weighted linear least squares estimation of
diffusion MRI parameters: strengths, limitations, and pitfalls."
NeuroImage, 81, 335-346.
DOI: 10.1016/j.neuroimage.2013.05.028
"""
# Algorithm identification
id_author = "Devguru Tiwari, IIIT Nagpur"
id_algorithm_type = "Weighted least squares / robust linear model segmented fit"
id_return_parameters = "f, D*, D"
id_units = "seconds per milli metre squared or milliseconds per micro metre squared"
id_ref = "https://doi.org/10.1016/j.neuroimage.2013.05.028"
# Algorithm requirements
required_bvalues = 4
required_thresholds = [0, 0]
required_bounds = False
required_bounds_optional = False
required_initial_guess = False
required_initial_guess_optional = False
# Supported inputs
supported_bounds = False
supported_initial_guess = False
supported_thresholds = True
supported_dimensions = 1
supported_priors = False
def __init__(self, bvalues=None, thresholds=None,
bounds=None, initial_guess=None, method="WLS"):
"""
Initialize the IVIM fitting algorithm.
Args:
bvalues (array-like, optional): b-values for the fitted signals.
thresholds (array-like, optional): Threshold b-value for segmented
fitting. The first value is used as the cutoff between high
and low b-values. Default: 200 s/mm².
bounds (dict, optional): Not used by this algorithm.
initial_guess (dict, optional): Not used by this algorithm.
method (str): Regression method — "WLS" (default) or "RLM".
"""
super(DT_IIITN_WLS, self).__init__(
bvalues=bvalues, bounds=bounds,
initial_guess=initial_guess, thresholds=thresholds
)
self.method = method.upper()
[docs]
def ivim_fit(self, signals, **kwargs):
"""Perform the IVIM fit using the selected method (WLS or RLM).
Args:
signals (array-like): Signal intensities at each b-value.
Returns:
dict: Dictionary with keys "D", "f", "Dp".
"""
# Use threshold as cutoff if available
cutoff = 200
if self.thresholds is not None and len(self.thresholds) > 0:
cutoff = self.thresholds[0]
D, f, Dp = wls_ivim_fit(self.bvalues, signals, cutoff=cutoff,
method=self.method)
results = {}
results["D"] = D
results["f"] = f
results["Dp"] = Dp
return results