Skip to content

Commit e9d46b6

Browse files
updated after review. Removed SUPER-IVIM-DC lsq fits
1 parent d8c0f66 commit e9d46b6

2 files changed

Lines changed: 52 additions & 2 deletions

File tree

tests/IVIMmodels/unit_tests/algorithms.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
{
22
"algorithms": [
3-
"TCML_TechnionIIT_lsqlm",
4-
"TCML_TechnionIIT_lsqtrf",
53
"ASD_MemorialSloanKettering_QAMPER_IVIM",
64
"ETP_SRI_LinearFitting",
75
"IAR_LU_biexp",

utilities/data_simulation/GenerateData.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,44 @@ def multilinear_signal(self, D, F, S0, bvalues, offset=0):
147147
return signal
148148

149149
def simulate_training_data(self, bvalues, SNR = (5,100), n = 1000000, Drange = (0.0005,0.0034), frange = (0,1), Dprange = (0.005,0.1), rician_noise = False):
150+
"""
151+
Simulates IVIM (Intravoxel Incoherent Motion) training data with optional Rician noise.
152+
153+
Parameters:
154+
----------
155+
bvalues : array-like
156+
A list or array of b-values used in the diffusion signal simulation.
157+
SNR : float, or tuple of two floats, optional
158+
Signal-to-noise ratio. If a tuple (min, max) is provided, SNRs are sampled
159+
logarithmically between those bounds. If set to 0, no noise is added. Default is (5, 100).
160+
n : int, optional
161+
Number of simulated voxels/signals to generate. Default is 1,000,000.
162+
Drange : tuple of two floats, optional
163+
Range (min, max) for the diffusion coefficient D (in mm²/s). Default is (0.0005, 0.0034).
164+
frange : tuple of two floats, optional
165+
Range (min, max) for the perfusion fraction f. Default is (0, 1).
166+
Dprange : tuple of two floats, optional
167+
Range (min, max) for the pseudo-diffusion coefficient Dp (in mm²/s). Default is (0.005, 0.1).
168+
rician_noise : bool, optional
169+
If True, Rician noise is added to the simulated signal. Default is False.
170+
171+
Returns:
172+
-------
173+
data_sim : ndarray of shape (n, len(bvalues))
174+
Simulated IVIM signal data normalized by S0.
175+
D : ndarray of shape (n, 1)
176+
Ground truth diffusion coefficient values used in simulation.
177+
f : ndarray of shape (n, 1)
178+
Ground truth perfusion fraction values used in simulation.
179+
Dp : ndarray of shape (n, 1)
180+
Ground truth pseudo-diffusion coefficient values used in simulation.
181+
182+
Notes:
183+
-----
184+
- The function uses self.ivim_signal() to generate signals.
185+
- Noise is applied after generating noise-free IVIM signals, using either Gaussian or Rician noise.
186+
- Simulated signals are normalized by the mean S0 (b = 0) signal.
187+
"""
150188
test = self._rng.uniform(0, 1, (n, 1))
151189
D = Drange[0] + (test * (Drange[1] - Drange[0]))
152190
test = self._rng.uniform(0, 1, (n, 1))
@@ -168,6 +206,20 @@ def simulate_training_data(self, bvalues, SNR = (5,100), n = 1000000, Drange = (
168206
for aa in range(len(D)):
169207
data_sim[aa, :] = self.ivim_signal(D[aa][0], Dp[aa][0], f[aa][0], 1, bvalues, snr=SNR[aa], rician_noise=rician_noise)
170208
# if SNR is set to zero, don't add noise
209+
if addnoise:
210+
# initialise noise arrays
211+
noise_imag = np.zeros([n, len(bvalues)])
212+
noise_real = np.zeros([n, len(bvalues)])
213+
# fill arrays
214+
for i in range(0, n - 1):
215+
noise_real[i,] = self._rng.normal(0, 1 / SNR[i],(1,len(bvalues)))
216+
noise_imag[i,] = self._rng.normal(0, 1 / SNR[i], (1, len(bvalues)))
217+
if rician_noise:
218+
# add Rician noise as the square root of squared gaussian distributed real signal + noise and imaginary noise
219+
data_sim = np.sqrt(np.power(data_sim + noise_real, 2) + np.power(noise_imag, 2))
220+
else:
221+
# or add Gaussian noise
222+
data_sim = data_sim + noise_real
171223
S0_noisy = np.mean(data_sim[:, bvalues == 0], axis=1)
172224
data_sim = data_sim / S0_noisy[:, None]
173225
return data_sim, D, f, Dp

0 commit comments

Comments
 (0)