Skip to content

Commit

Permalink
Tried some testing with the standardized version of an algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanARashid committed Aug 29, 2023
1 parent f8b1690 commit ac3125f
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ __pycache__/
.cache
nosetests.xml
coverage.xml
*.pyc
Binary file modified src/original/ETP_SRI/__pycache__/LinearFitting.cpython-39.pyc
Binary file not shown.
16 changes: 10 additions & 6 deletions src/standardized/ETP_SRI_LinearFitting.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ETP_SRI_LinearFitting(OsipiBase):

# Algorithm requirements
required_bvalues = 3
required_thresholds = [1,1] # Interval from 1 to 1, in case submissions allow a custom number of thresholds
required_thresholds = [0,1] # Interval from 1 to 1, in case submissions allow a custom number of thresholds
required_bounds = False
required_bounds_optional = True # Bounds may not be required but are optional
required_initial_guess = False
Expand All @@ -45,7 +45,7 @@ def __init__(self, bvalues=None, thresholds=None, bounds=None, initial_guess=Non
# Check the inputs


def ivim_fit(self, signals, bvalues):
def ivim_fit(self, signals, bvalues=None):
"""
We may want this function to be as simple as
data and b-values in -> parameter estimates out.
Expand All @@ -55,8 +55,13 @@ def ivim_fit(self, signals, bvalues):
This makes the execution of submissions easy and predictable.
All execution stepts requires should be performed here.
"""
if bvalues is None:
bvalues = self.bvalues

ETP_object = LinearFit(self.thresholds[0])
if self.thresholds is None:
ETP_object = LinearFit()
else:
ETP_object = LinearFit(self.thresholds[0])
f, D, Dstar = ETP_object.ivim_fit(bvalues, signals)


Expand All @@ -73,7 +78,6 @@ def ivim_model(b, S0=1, f=0.1, Dstar=0.03, D=0.001):

signals = ivim_model(bvalues)

model = ETP_SRI_LinearFitting(thresholds=[200])
model = ETP_SRI_LinearFitting()
results = model.ivim_fit(signals, bvalues)
test = model.osipi_simple_bias_and_RMSE_test(SNR=20, bvalues=bvalues, f=0.1, Dstar=0.03, D=0.001, noise_realizations=10)
#model.print_requirements_osipi()
test = model.osipi_simple_bias_and_RMSE_test(SNR=20, bvalues=bvalues, f=0.1, Dstar=0.03, D=0.001, noise_realizations=10)
16 changes: 12 additions & 4 deletions src/wrappers/OsipiBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,23 @@ class OsipiBase:
"""The base class for OSIPI IVIM fitting"""

def __init__(self, bvalues=None, thresholds=None, bounds=None, initial_guess=None):
self.bvalues = np.asarray(bvalues)
self.thresholds = np.asarray(thresholds)
self.bounds = np.asarray(bounds)
self.initial_guess = np.asarray(initial_guess)
# Define the attributes as numpy arrays only if they are not None
self.bvalues = np.asarray(bvalues) if bvalues is not None else None
self.thresholds = np.asarray(thresholds) if thresholds is not None else None
self.bounds = np.asarray(bounds) if bounds is not None else None
self.initial_guess = np.asarray(initial_guess) if initial_guess is not None else None

def osipi_fit(self, data=None, bvalues=None, initial_guess=None, bounds=None, thresholds=None, **kwargs):
"""Fits the data with the bvalues
Returns [S0, f, D*, D]
"""
if bvalues is None:
bvalues = self.bvalues

args = [data, bvalues, initial_guess, bounds, thresholds]
args = [arg for arg in args if arg is not None]
f, Dstar, D = self.ivim_fit(*args)

#self.parameter_estimates = self.ivim_fit(data, bvalues)
pass

Expand Down
Binary file modified src/wrappers/__pycache__/OsipiBase.cpython-39.pyc
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/IVIMmodels/data/test_GenerateData.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import numpy as np
import numpy.testing as npt
import pytest
import torch
#import torch

from utilities.data_simulation.GenerateData import GenerateData

Expand Down
13 changes: 11 additions & 2 deletions tests/IVIMmodels/unit_tests/test_ivim_fit_linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from utilities.data_simulation.GenerateData import GenerateData
from src.original.ETP_SRI.LinearFitting import LinearFit

# Import the standardized version of the algorithm
from src.standardized.ETP_SRI_LinearFitting import ETP_SRI_LinearFitting

#run using python -m pytest from the root folder

Expand Down Expand Up @@ -39,10 +41,17 @@ def test_linear_fit(D, bvals):
]
@pytest.mark.parametrize("f, D, Dp, bvals", test_ivim_data)
def test_ivim_fit(f, D, Dp, bvals):
# We should make a wrapper that runs this for a range of different settings, such as b thresholds, bounds, etc.
# An additional inputs to these functions could perhaps be a "settings" class with attributes that are the settings to the
# algorithms. I.e. bvalues, thresholds, bounds, initial guesses.
# That way, we can write something that defines a range of settings, and then just run them through here.
gd = GenerateData()
gd_signal = gd.ivim_signal(D, Dp, f, 1, bvals)
fit = LinearFit()
[f_fit, D_fit, Dp_fit] = fit.ivim_fit(bvals, gd_signal)
#fit = LinearFit() # This is the old code by ETP

fit = ETP_SRI_LinearFitting() # This is the standardized format by IAR, which every algorithm will be implemented with

[f_fit, Dp_fit, D_fit] = fit.ivim_fit(gd_signal, bvals) # Note that I have transposed Dp and D. We should decide on a standard order for these. I usually go with f, Dp, and D ordered after size.
npt.assert_allclose([f, D], [f_fit, D_fit], atol=1e-5)
if not np.allclose(f, 0):
npt.assert_allclose(Dp, Dp_fit, rtol=1e-2, atol=1e-3)
Expand Down

0 comments on commit ac3125f

Please sign in to comment.