From 8c2d866caad1abde3d8b01e136416e3b93bccd22 Mon Sep 17 00:00:00 2001 From: ElinaPetersson-stat Date: Fri, 23 Jan 2026 10:06:18 +0100 Subject: [PATCH 01/21] Preprocessig script for outlier removal --- src/original/EP_GU/info.json | 4 + src/original/EP_GU/outlier_removal.py | 165 ++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 src/original/EP_GU/info.json create mode 100644 src/original/EP_GU/outlier_removal.py diff --git a/src/original/EP_GU/info.json b/src/original/EP_GU/info.json new file mode 100644 index 00000000..3e937823 --- /dev/null +++ b/src/original/EP_GU/info.json @@ -0,0 +1,4 @@ +{ + "developers": "Oscar Jalnefjord", + "institutions": ["University of Gothenburg, Gothenburg, Sweden", "Sahlgrenska University Hospital, Gothenburg, Sweden"] +} \ No newline at end of file diff --git a/src/original/EP_GU/outlier_removal.py b/src/original/EP_GU/outlier_removal.py new file mode 100644 index 00000000..6ee7c108 --- /dev/null +++ b/src/original/EP_GU/outlier_removal.py @@ -0,0 +1,165 @@ +""" Methods for outlier removal. +Reproduced with permission from Oscar Jalngefjord: https://github.com/oscarjalnefjord/ivim/tree/outlier by Elina Petersson +""" + +import numpy as np +import nibabel as nib +import numpy.typing as npt +import matplotlib.pyplot as plt +from scipy.optimize import minimize +from scipy.stats import norm + +NO_REGIME = 'no' +DIFFUSIVE_REGIME = 'diffusive' +BALLISTIC_REGIME = 'ballistic' +Db = 1.75e-3 # mm2/s, see Ahlgren et al 2016 NMR in Biomedicine + +def roi_based(im_file: str, bval_file: str, roi_file: str, outbase: str, regime:str , fig: bool = False, cval_file: str | None = None): + """ + Identify outliers by fit to ROI average. + + Arguments: + im_file: path to nifti image file + bval_file: path to .bval file + roi_file: path to nifti file defining a region-of-interest (ROI) in which the correction is calculated and applied + outbase: basis for output filenames, i.e. filename without file extension to which .nii.gz, .bval, etc. is added + regime: IVIM regime to model: no (= sIVIM), diffusive (long encoding time) or ballistic (short encoding time) + fig: (optional) if True, a diagnostic figure is output + cval_file: (optional) path to .cval file + """ + + check_regime(regime) + Y = nib.load(im_file).get_fdata() + if roi_file is not None: + roi = nib.load(roi_file).get_fdata().astype(bool) + else: + roi = np.full(Y.shape[:-1], True) + Y = Y[roi,:] + b = np.atleast_1d(np.loadtxt(bval_file)) + if regime == BALLISTIC_REGIME: + c = np.atleast_1d(np.loadtxt(cval_file)) + + y_avg = np.median(Y, axis=0) + + if regime == NO_REGIME: + def model(x, idx): + return sIVIM(b[idx], x[0], x[1], x[2]) + x0 = [1e-3, 0.1, np.max(y_avg)] + bounds = ((0, 3e-3), (0, 1), (0, 2*np.max(y_avg))) + elif regime == BALLISTIC_REGIME: + def model(x, idx): + return ballistic(b[idx], c[idx], x[0], x[1], x[2], x[3]) + x0 = [1e-3, 0.1, 2, np.max(y_avg)] + bounds = ((0, 3e-3), (0, 1), (0, 5), (0, 2*np.max(y_avg))) + else: # diffusive + def model(x, idx): + return diffusive(b[idx], x[0], x[1], x[2], x[3]) + x0 = [1e-3, 0.1, 10e-3, np.max(y_avg)] + bounds = ((0, 3e-3), (0, 1), (0, 1), (0, 2*np.max(y_avg))) + + + has_outliers = True + idx = np.full_like(b, True, dtype=bool) + while has_outliers: + def fun(x): + return np.sum(np.abs(model(x, idx)-y_avg[idx])) + + x = minimize(fun, x0, bounds=bounds).x + res = np.squeeze(model(x, idx)) - y_avg[idx] + iqr = (np.quantile(res, 0.75) - np.quantile(res, 0.25)) + tmp = np.full_like(b, False, dtype=bool) + tmp[idx] = np.abs(res) < 3*iqr + if np.all(tmp == idx): + has_outliers = False + else: + idx = tmp + + if fig: + fig, ax = plt.subplots(1, 1) + b_plot = np.linspace(np.min(b), np.max(b)) + if regime == NO_REGIME: + y = np.squeeze(sIVIM(b_plot, x[0], x[1], x[2])) + + elif regime == BALLISTIC_REGIME: + c_plot = b_plot * (c/b)[c>0][np.argmax(b[c>0])] + y = np.squeeze(ballistic(b_plot, c_plot, x[0], x[1], x[2], x[3])) + if np.any((b>0)&(c==0)): + ax.plot(b_plot, np.squeeze(ballistic(b_plot, np.zeros_like(b_plot), x[0], x[1], x[2], x[3]))) + else: + y = np.squeeze(diffusive(b_plot, x[0], x[1], x[2], x[3])) + ax.plot(b_plot, y) + ax.plot(b, y_avg, 'ko') + ax.plot(b[~idx], y_avg[~idx], 'rx') + ax.set_xlabel(r'b [s/mm$^2$]') + ax.set_ylabel('Signal [a.u]') + fig.savefig(outbase+'.png') + plt.close(fig) + + sz = roi.shape + + if Y[:,idx].ndim > 1: + im_new = np.full(list(sz) + [Y[:,idx].shape[1]], np.nan) + im_new[roi, :] = Y[:,idx] + else: + im_new = np.full(sz, np.nan) + im_new[roi] = Y[:,idx] + nib.save(nib.Nifti1Image(im_new, nib.load(im_file).affine, nib.load(im_file).header), outbase+'.nii.gz') + np.savetxt(outbase+'.bval', b[idx], fmt='%.1f', newline=' ') + if regime == BALLISTIC_REGIME: + np.savetxt(outbase+'.cval', c[idx], fmt='%.1f', newline=' ') + + + +def at_least_1d(pars: list) -> list: + """ Check that each parameter is atleast one dimension in shape. """ + for i, par in enumerate(pars): + pars[i] = np.atleast_1d(par) + return pars + +def check_regime(regime: str) -> None: + """ Check that the regime is valid. """ + if regime not in [NO_REGIME, DIFFUSIVE_REGIME, BALLISTIC_REGIME]: + raise ValueError(f'Invalid regime "{regime}". Valid regimes are "{NO_REGIME}", "{DIFFUSIVE_REGIME}" and "{BALLISTIC_REGIME}".') + +def monoexp(b: npt.NDArray[np.float64], D: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: + """ + Return the monoexponential e^(-b*D). + """ + + [b, D] = at_least_1d([b, D]) + S = np.exp(-np.outer(D, b)) + return np.reshape(S, list(D.shape) + [b.size]) # reshape as np.outer flattens D is ndim > 1 + +def kurtosis(b: npt.NDArray[np.float64], D: npt.NDArray[np.float64], K: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]: + """ + Return the kurtosis signal representation. + """ + + [b, D, K] = at_least_1d([b, D, K]) + Slin = monoexp(b, D) + Squad = np.exp(np.reshape(np.outer(D, b)**2, list(D.shape) + [b.size]) * K[..., np.newaxis]/6) + return Slin * Squad + +def sIVIM(b: npt.NDArray[np.float64], D: npt.NDArray[np.float64], f: npt.NDArray[np.float64], S0: npt.NDArray[np.float64] = 1, K: npt.NDArray[np.float64] = 0) -> npt.NDArray[np.float64]: + """ + Return MR signal based on the simplified IVIM (sIVIM) model. + """ + + [b, D, f, S0] = at_least_1d([b, D, f, S0]) + return S0[..., np.newaxis] * ((1-f[..., np.newaxis]) * kurtosis(b, D, K) + np.reshape(np.outer(f, b==0), list(f.shape) + [b.size])) + +def ballistic(b: npt.NDArray[np.float64], c: npt.NDArray[np.float64], D: npt.NDArray[np.float64], f: npt.NDArray[np.float64], vd: npt.NDArray[np.float64], S0: npt.NDArray[np.float64] = 1, K: npt.NDArray[np.float64] = 0) -> npt.NDArray[np.float64]: + """ + Return MR signal based on the ballistic IVIM model. + """ + + [b, c, D, f, vd, S0] = at_least_1d([b, c, D, f, vd, S0]) + return S0[..., np.newaxis] * ((1-f[..., np.newaxis])*kurtosis(b, D, K) + f[..., np.newaxis]*monoexp(b, Db)*monoexp(c**2, vd**2)) + +def diffusive(b: npt.NDArray[np.float64], D: npt.NDArray[np.float64], f: npt.NDArray[np.float64], Dstar: npt.NDArray[np.float64], S0: npt.NDArray[np.float64] = 1, K: npt.NDArray[np.float64] = 0) -> npt.NDArray[np.float64]: + """ + Return MR signal based on the diffusive IVIM model. + """ + + [b, D, f, Dstar, S0] = at_least_1d([b, D, f, Dstar, S0]) + return S0[..., np.newaxis] * ((1-f[..., np.newaxis])*kurtosis(b, D, K) + f[..., np.newaxis]*monoexp(b, Dstar)) \ No newline at end of file From c5850edcfb8ef8356f3a038d3a5df5a3bc6a5bce Mon Sep 17 00:00:00 2001 From: ElinaPetersson Date: Fri, 27 Feb 2026 08:02:28 +0100 Subject: [PATCH 02/21] preproc pipeline for brain --- src/original/EP_GU/brain_pipeline.py | 184 +++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 src/original/EP_GU/brain_pipeline.py diff --git a/src/original/EP_GU/brain_pipeline.py b/src/original/EP_GU/brain_pipeline.py new file mode 100644 index 00000000..3fd68987 --- /dev/null +++ b/src/original/EP_GU/brain_pipeline.py @@ -0,0 +1,184 @@ +''' +Preprocessing of brain IVIM data +Requirements: +- ivim +- fsl +- freesurfer +- itk +- itk-elastix +''' +#%% +import numpy as np +import nibabel as nib +import subprocess, os +from nipype.interfaces import fsl +import itk +from ivim.io.base import read_bval, write_bval +from ivim.preproc.base import extract, combine, average +from ivim.preproc import signal_drift + + +def denoise_wrap(im_file): + ''' Denoising ''' + im_file_denoised = im_file.replace('.nii.gz','-pca.nii.gz') + noise_level = im_file.replace('.nii.gz','-noise_level.nii.gz') + print('Denoising...') + subprocess.run(['dwidenoise', '-noise', noise_level, im_file, im_file_denoised]) + subprocess.run(['cp',im_file.replace('.nii.gz','.bval'),im_file_denoised.replace('.nii.gz','.bval')]) + subprocess.run(['cp',im_file.replace('.nii.gz','.bvec'),im_file_denoised.replace('.nii.gz','.bvec')]) + return im_file_denoised + +def degibbs_wrap(im_file): + ''' Gibbs ringing artifact removal ''' + im_file_degibbs = im_file.replace('.nii.gz','-gib.nii.gz') + print('Degibbsing...') + subprocess.run(['mrdegibbs', im_file, im_file_degibbs]) + subprocess.run(['cp',im_file.replace('.nii.gz','.bval'),im_file_degibbs.replace('.nii.gz','.bval')]) + subprocess.run(['cp',im_file.replace('.nii.gz','.bvec'),im_file_degibbs.replace('.nii.gz','.bvec')]) + return im_file_degibbs + +def extract_volume(in_file, t_index): + ''' + Extracts a 3D volume at time index t_index from a 4D image. + Returns the path to the temporary file. + ''' + out_file = in_file.replace('.nii.gz',f'-tmp{t_index}.nii.gz') + subprocess.run(['fslroi',in_file,out_file,str(t_index),'1']) + return out_file + +def register_3D_to_ref(in_file, ref_idx, out_file,method='rigid'): + ''' + Registers a 3D image to a reference image using ITK Elastix. + ''' + PixelType = itk.F + Dimension3D = 3 + Image3DType = itk.Image[PixelType, Dimension3D] + + # Built-in default parameter map seems to work well for brain + parameter_object = itk.ParameterObject.New() + parameter_object.AddParameterMap(parameter_object.GetDefaultParameterMap(method)) + + # Load reference image + tmp_ref = extract_volume(in_file, ref_idx) + ref_itk = itk.imread(tmp_ref, pixel_type=PixelType) + + # Loop through all volumes and register to reference + n_vols = nib.load(in_file).shape[3] + registered_vols = [] + for t in range(n_vols): + if t == ref_idx: + registered_vols.append(tmp_ref) # No need to register reference to itself + continue + + # Load moving image + tmp_moving = extract_volume(in_file, t) + moving_itk = itk.imread(tmp_moving, pixel_type=PixelType) + + print(f'Registering volume {t} to reference volume {ref_idx}...') + elastix = itk.ElastixRegistrationMethod.New(ref_itk, moving_itk) + # elastix.SetFixedImage(ref_itk) + # elastix.SetMovingImage(moving_itk) + elastix.SetParameterObject(parameter_object) + elastix.Update() + result = elastix.GetOutput() + tmp_out = out_file.replace('.nii.gz',f'-tmp{t}.nii.gz') + itk.imwrite(result, tmp_out) + os.remove(tmp_moving) # Clean up temp moving image + registered_vols.append(tmp_out) + + out_file = in_file.replace('.nii.gz','-rigid.nii.gz') + # Stack back to 4D + subprocess.run(['fslmerge','-t',out_file]+registered_vols) + + # Clean up + os.remove(tmp_ref) # Clean up temp reference image + for t in range(1,n_vols): + os.remove(out_file.replace('-rigid.nii.gz',f'-reg-tmp{t}.nii.gz')) # Clean up temp registered images + return out_file + +def topup_wrap(im_file,bval_file, b0rev_file, b0rev_bval_file): + ''' Susceptibility distortion correction ''' + print('Running topup...') + im_file_unwarp = im_file.replace('.nii.gz','-unwarp.nii.gz') + + # Prepare b0:s for topup + extract(im_file=im_file, bval_file=bval_file, outbase=im_file.replace('.nii.gz','-b0'),b_ex=0) # we dont perform averaging since it seems preferable to not do it + combine(dwi_files=[im_file.replace('.nii.gz','-b0.nii.gz'),b0rev_file], + bval_files=[im_file.replace('.nii.gz','-b0.bval'),b0rev_bval_file], + outbase=im_file.replace('.nii.gz','-b0-b0rev')) + b = read_bval(im_file.replace('.nii.gz','-b0.bval')) + brev = read_bval(b0rev_bval_file) + interbase = im_file.replace('.nii.gz','-b0-b0rev') + acqp_file = interbase + '_acqparams.txt' + with open(acqp_file,'w') as f: + for _ in range(np.sum(b==0)): + f.write('0 1 0 0.050\n') + for _ in range(np.sum(brev==0)): + f.write('0 -1 0 0.050\n') + + topup_cmd = f'topup --imain={im_file.replace(".nii.gz","-b0-b0rev.nii.gz")} --datain={acqp_file} --config=b02b0.cnf --subsamp=1 --out={interbase} --verbose' + os.system(topup_cmd) + + applytopup_cmd = f'applytopup --imain={im_file} --datain={acqp_file} --inindex=1 --topup={interbase} --out={im_file_unwarp} --method=jac --verbose' + os.system(applytopup_cmd) + subprocess.run(['cp',im_file.replace('.nii.gz','.bval'),im_file_unwarp.replace('.nii.gz','.bval')]) + + return im_file_unwarp + +def brain_preproc(im_file: str, bval_file: str, b0rev_file: str, b0rev_bval_file: str, temp_folder: str): + + # Denoising + im_file_denoised = denoise_wrap(im_file) + + # Degibbsing + im_file_degibbs = degibbs_wrap(im_file_denoised) + + # Registration to b0 + im_file_reg = register_3D_to_ref(im_file_degibbs, ref_idx=0, out_file=im_file_degibbs.replace('.nii.gz','-reg.nii.gz')) + + # Suseptibility distortion correction + im_file_unwarp = topup_wrap(im_file_reg, bval_file, b0rev_file, b0rev_bval_file) + + # Brain extraction + brain_mask = im_file_unwarp.replace('.nii.gz','-brain-mask.nii.gz') + extract(im_file_unwarp, im_file_unwarp.replace('.nii.gz','.bval'), outbase=im_file_unwarp.replace('.nii.gz','-b0'), b_ex=0) + average(im_file_unwarp.replace('.nii.gz','-b0.nii.gz'), im_file_unwarp.replace('.nii.gz','-b0.bval'), im_file_unwarp.replace('.nii.gz','-b0-avr')) + subprocess.run(['mri_synthstrip', '-i', im_file_unwarp.replace('.nii.gz','-b0-avr.nii.gz'), '-o', im_file_unwarp.replace('.nii.gz', '-brain.nii.gz'), '-m', im_file_unwarp.replace('.nii.gz', '-brain-mask.nii.gz')]) + os.remove(im_file_unwarp.replace('.nii.gz','-b0.nii.gz')) + os.remove(im_file_unwarp.replace('.nii.gz','-b0.bval')) + os.remove(im_file_unwarp.replace('.nii.gz','-b0-avr.nii.gz')) + + # Signal drift correction + signal_drift.spatiotemporal(im_file = im_file_unwarp, + bval_file = im_file_unwarp.replace('.nii.gz','.bval'), + outbase = im_file_unwarp.replace('.nii.gz','-sigdri'), + roi_file = brain_mask) + subprocess.run(['cp',im_file_unwarp.replace('.nii.gz','.bval'),im_file_unwarp.replace('.nii.gz','-sigdri_corr.bval')]) +#%% +# im_file = os.getcwd()+'/temp/diffusive_snr200.nii.gz' +# bval_file = os.getcwd()+'/temp/diffusive_snr200.bval' +# b0rev_file = os.getcwd()+'/temp/diffusive_snr200_b0.nii.gz' +# b0rev_bval_file = os.getcwd()+'/temp/diffusive_snr200_b0.bval' + +# im_file_denoised = denoise_wrap(im_file) +# im_file_degibbs = degibbs_wrap(im_file_denoised) +# im_file_reg = register_3D_to_ref(im_file_degibbs, ref_idx=0, out_file=im_file_degibbs.replace('.nii.gz','-reg.nii.gz')) +# im_file_unwarp = topup_wrap(im_file_reg, bval_file, b0rev_file, b0rev_bval_file) + +# Brain extraction +# brain_mask = im_file_unwarp.replace('.nii.gz','-brain-mask.nii.gz') +# extract(im_file_unwarp, bval_file, outbase=im_file_unwarp.replace('.nii.gz','-b0'), b_ex=0) +# average(im_file_unwarp.replace('.nii.gz','-b0.nii.gz'), im_file_unwarp.replace('.nii.gz','-b0.bval'), im_file_unwarp.replace('.nii.gz','-b0-avr')) +# subprocess.run(['mri_synthstrip', '-i', im_file_unwarp.replace('.nii.gz','-b0-avr.nii.gz'), '-o', im_file_unwarp.replace('.nii.gz', '-brain.nii.gz'), '-m', im_file_unwarp.replace('.nii.gz', '-brain-mask.nii.gz')]) +# os.remove(im_file_unwarp.replace('.nii.gz','-b0.nii.gz')) +# os.remove(im_file_unwarp.replace('.nii.gz','-b0.bval')) +# os.remove(im_file_unwarp.replace('.nii.gz','-b0-avr.nii.gz')) + +# # Signal drift correction +# signal_drift.spatiotemporal(im_file = im_file_unwarp, +# bval_file = bval_file, +# outbase = im_file_unwarp.replace('.nii.gz','-sigdri'), +# roi_file = brain_mask) +# subprocess.run(['cp',im_file_unwarp.replace('.nii.gz','.bval'),im_file_unwarp.replace('.nii.gz','-sigdri_corr.bval')]) + +# %% From bbb5531b204c10cf30f096ffe8da08e99250ca74 Mon Sep 17 00:00:00 2001 From: ElinaPetersson Date: Wed, 25 Mar 2026 09:45:52 +0100 Subject: [PATCH 03/21] Tests and simulation for brain denoise --- .gitignore | 5 ++ phantoms/__init__.py | 0 .../diffusive_relax_groundtruth.json | 8 ++ phantoms/brain/sim_brain_phantom_preproc.py | 82 +++++++++++++++++++ tests/IVIMpreproc/unit_tests/__init__.py | 0 tests/IVIMpreproc/unit_tests/test_denoise.py | 63 ++++++++++++++ 6 files changed, 158 insertions(+) create mode 100644 phantoms/__init__.py create mode 100644 phantoms/brain/ground_truth/diffusive_relax_groundtruth.json create mode 100644 phantoms/brain/sim_brain_phantom_preproc.py create mode 100644 tests/IVIMpreproc/unit_tests/__init__.py create mode 100644 tests/IVIMpreproc/unit_tests/test_denoise.py diff --git a/.gitignore b/.gitignore index a21b99bf..ba0c6610 100644 --- a/.gitignore +++ b/.gitignore @@ -40,5 +40,10 @@ coverage.xml *.pyc phantoms/MR_XCAT_qMRI/*.json phantoms/MR_XCAT_qMRI/*.txt +phantoms/brain/data/*.nii.gz +phantoms/brain/ground_truth/*.nii.gz tests/IVIMmodels/unit_tests/models models +temp +.vscode +.env diff --git a/phantoms/__init__.py b/phantoms/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/phantoms/brain/ground_truth/diffusive_relax_groundtruth.json b/phantoms/brain/ground_truth/diffusive_relax_groundtruth.json new file mode 100644 index 00000000..d6bcda7a --- /dev/null +++ b/phantoms/brain/ground_truth/diffusive_relax_groundtruth.json @@ -0,0 +1,8 @@ +{ + "tissues": ["WM","GM","CSF"], + "D":[0.81e-3,0.86e-3,3e-3], + "f":[0.044,0.033,0], + "Dstar":[84e-3,76e-3,0], + "T1":[1.0, 1.5, 3.4], + "T2":[0.046,0.068,0.45] +} diff --git a/phantoms/brain/sim_brain_phantom_preproc.py b/phantoms/brain/sim_brain_phantom_preproc.py new file mode 100644 index 00000000..1543a607 --- /dev/null +++ b/phantoms/brain/sim_brain_phantom_preproc.py @@ -0,0 +1,82 @@ +import os +import shutil +import json +import numpy as np +import nibabel as nib +from scipy.ndimage import zoom +from utilities.data_simulation.Download_data import download_data + + +def simulate_brain_phantom(snr=100, TE=60e-3, TR=5, resolution=[3,3,3]): + ''' + Simulation parameters can be set by changing the default values of the function arguments. The default values are chosen to be suitable for a diffusive regime phantom, but can be changed to simulate a ballistic regime phantom as well. The simulated image is saved in phantoms/brain/data with the name 'diffusive_sn{snr}_relax.nii.gz' or 'ballistic_sn{snr}_relax.nii.gz' depending on the regime. The corresponding bvals and cvals (if applicable) are also saved in the same folder. + snr: signal-to-noise ratio of the simulated image + TE: echo time in seconds + TR: repetition time in seconds + resolution: voxel size in mm + ''' + download_data() + + DIFFUSIVE_REGIME = 'diffusive' + BALLISTIC_REGIME = 'ballistic' + + regime = DIFFUSIVE_REGIME # only adapted for diffusive regime for now, but can be easily changed to simulate ballistic regime as well by changing this variable and providing the corresponding ground truth parameters in the json file + + folder = os.path.dirname(__file__) + + # Ground truth + nii = nib.load(os.path.join(os.path.split(os.path.split(folder)[0])[0],'download','Phantoms','brain','ground_truth','hrgt_icbm_2009a_nls_3t.nii.gz')) + segmentation = np.squeeze(nii.get_fdata()[...,-1]) + + with open(os.path.join(folder,'ground_truth',regime+'_relax_groundtruth.json'), 'r') as f: + ivim_pars = json.load(f) + S0 = 1 + + # Sequence parameters + bval_file = os.path.join(folder,'ground_truth',regime+'.bval') + b = np.loadtxt(bval_file) + if regime == BALLISTIC_REGIME: + cval_file = bval_file.replace('bval','cval') + c = np.loadtxt(cval_file) + + # Calculate signal + S = np.zeros(list(np.shape(segmentation))+[b.size]) + print(ivim_pars) + if regime == BALLISTIC_REGIME: + Db = ivim_pars["Db"] + for i,(D,f,vd,T1,T2) in enumerate(zip(ivim_pars["D"],ivim_pars["f"],ivim_pars["vd"],ivim_pars["T1"],ivim_pars["T2"])): + S[segmentation==i+1,:] = S0*((1-f)*np.exp(-b*D)+f*np.exp(-b*Db-c**2*vd**2))*np.exp(-TE/T2)*(1-np.exp(-TR/T1)) + else: + for i,(D,f,Dstar,T1,T2) in enumerate(zip(ivim_pars["D"],ivim_pars["f"],ivim_pars["Dstar"],ivim_pars["T1"],ivim_pars["T2"])): + S[segmentation==i+1,:] = S0*((1-f)*np.exp(-b*D)+f*np.exp(-b*Dstar))*np.exp(-TE/T2)*(1-np.exp(-TR/T1)) + + # Resample to suitable resolution + im = zoom(S,np.append(np.diag(nii.affine)[:3]/np.array(resolution),1),order=1) + sz = im.shape + + # Save image without noise for reference + nii_out = nib.Nifti1Image(im,np.eye(4)) + base_name = os.path.join(folder,'data','{}_reference_relax'.format(regime,snr)) + nib.save(nii_out,base_name+'.nii.gz') + shutil.copyfile(bval_file,base_name+'.bval') + + # Add Rician noise + im_noise = np.abs(im + S0/snr*(np.random.randn(sz[0],sz[1],sz[2],sz[3])+1j*np.random.randn(sz[0],sz[1],sz[2],sz[3]))) + + # Save as image and sequence parameters + nii_out = nib.Nifti1Image(im_noise,np.eye(4)) + base_name = os.path.join(folder,'data','{}_snr{}_relax'.format(regime,snr)) + nib.save(nii_out,base_name+'.nii.gz') + shutil.copyfile(bval_file,base_name+'.bval') + if regime == BALLISTIC_REGIME: + shutil.copyfile(cval_file,base_name+'.cval') + + # Resample and save segmentation + segmentation = zoom(segmentation,np.diag(nii.affine)[:3]/np.array(resolution),order=0) + nii_out = nib.Nifti1Image(segmentation,np.eye(4)) + base_name = os.path.join(folder,'data','{}_snr{}_relax_mask'.format(regime,snr)) + nib.save(nii_out,base_name+'.nii.gz') + + +if __name__ == "__main__": + simulate_brain_phantom() diff --git a/tests/IVIMpreproc/unit_tests/__init__.py b/tests/IVIMpreproc/unit_tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/IVIMpreproc/unit_tests/test_denoise.py b/tests/IVIMpreproc/unit_tests/test_denoise.py new file mode 100644 index 00000000..bbf26197 --- /dev/null +++ b/tests/IVIMpreproc/unit_tests/test_denoise.py @@ -0,0 +1,63 @@ +''' +1. Load brain phantom +2. Add Rician noise +3. Denoise using denoise algorithm +4. Check that sum of squared residuals decreased after denoising +''' +import os + +import numpy as np +from phantoms.brain.sim_brain_phantom_preproc import simulate_brain_phantom +import nibabel as nib +import matplotlib.pyplot as plt +from src.original.EP_GU.brain_pipeline import denoise_wrap + + +def test_denoise_wrap(): + # Simulate phantom with noise + snr = 50 + simulate_brain_phantom(snr = snr) + + # Denoising + im_file = 'phantoms/brain/data/diffusive_snr{}_relax.nii.gz'.format(snr) + im_file_denoised = denoise_wrap(im_file) + S_denoised = nib.load(im_file_denoised).get_fdata() + + # Compute sum of squared residuals before denoising + mask = nib.load(os.path.join('phantoms','brain','data','diffusive_snr{}_relax_mask.nii.gz'.format(snr))).get_fdata() + ref_file = 'phantoms/brain/data/diffusive_reference_relax.nii.gz' + S = nib.load(im_file).get_fdata() + S_ref = nib.load(ref_file).get_fdata() + ssr_before = np.sum((S[mask!=0,:]-S_ref[mask!=0,:])**2) + ssr_after = np.sum((S_denoised[mask!=0,:]-S_ref[mask!=0,:])**2) + + + + # print('SSR before denoising: {}'.format(ssr_before)) + # print('SSR after denoising: {}'.format(ssr_after)) + + # plt.subplot(1,3,1) + # plt.imshow(np.rot90(S_ref[:,:,30,10]),cmap='gray') + # plt.title('Reference') + # plt.xticks([]) + # plt.yticks([]) + # plt.subplot(1,3,2) + # plt.imshow(np.rot90(S[:,:,30,10]),cmap='gray') + # plt.title('Noisy') + # plt.xticks([]) + # plt.yticks([]) + # plt.subplot(1,3,3) + # plt.imshow(np.rot90(S_denoised[:,:,30,10]),cmap='gray') + # plt.title('Denoised') + # plt.xticks([]) + # plt.yticks([]) + # plt.show() + + # Check that sum of squared residuals decreased after denoising + if ssr_after < ssr_before: + assert True + else: + assert False + + + From ee1ca0ccde7f7e20de949e4692fe7a43f7744143 Mon Sep 17 00:00:00 2001 From: ElinaPetersson Date: Wed, 25 Mar 2026 09:56:15 +0100 Subject: [PATCH 04/21] first attempt at degibbs script --- tests/IVIMpreproc/unit_tests/test_degibbs.py | 81 ++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 tests/IVIMpreproc/unit_tests/test_degibbs.py diff --git a/tests/IVIMpreproc/unit_tests/test_degibbs.py b/tests/IVIMpreproc/unit_tests/test_degibbs.py new file mode 100644 index 00000000..656d36b6 --- /dev/null +++ b/tests/IVIMpreproc/unit_tests/test_degibbs.py @@ -0,0 +1,81 @@ +''' +Not done! Need a better metric than just noise correlation + +''' +# %% +from phantoms.brain.sim_brain_phantom_preproc import simulate_brain_phantom + +simulate_brain_phantom(snr = 50) +#%% +import nibabel as nib +import numpy as np +from src.original.EP_GU.brain_pipeline import degibbs_wrap +import matplotlib.pyplot as plt +import os + +# load brain phantom +S_ref = nib.load('phantoms/brain/data/diffusive_reference_relax.nii.gz').get_fdata() + +# Convert to k-space +S_k = np.fft.fftn(S_ref,axes=(0,1)) +S_k = np.fft.fftshift(S_k,axes=(0,1)) + +plt.subplot(1,2,1) +plt.imshow(np.log(np.abs(S_k[:,:,30,0])+1),cmap='gray') +plt.xticks([]) +plt.yticks([]) + +# Crop k-space +S_k[:10,:,:,:] = 0 +S_k[-10:,:,:,:] = 0 +# S_k[:,:10,:,:] = 0 +# S_k[:,-10:,:,:] = 0 + +# Test plot +plt.subplot(1,2,2) +plt.imshow(np.log(np.abs(S_k[:,:,30,0])+1),cmap='gray') +plt.xticks([]) +plt.yticks([]) +plt.show() + +# Inverse Fourier transform +S_crop = np.fft.ifftshift(S_k,axes=(0,1)) +S_crop = np.fft.ifftn(S_crop,axes=(0,1)).real + +# Save image +S_crop_nii = nib.Nifti1Image(S_crop.astype(np.float32),np.eye(4)) +S_crop_file = 'phantoms/brain/data/diffusive_reference_relax_cropped.nii.gz' +nib.save(S_crop_nii,S_crop_file) + +# Apply degibbs +S_degibbs_file = degibbs_wrap(S_crop_file) + +# Plot results +S_degibbs = nib.load(S_degibbs_file).get_fdata() +plt.subplot(1,3,1) +plt.imshow(np.rot90(S_ref[:,:,30,0]),cmap='gray') +plt.xticks([]) +plt.yticks([]) +plt.subplot(1,3,2) +plt.imshow(np.rot90(S_crop[:,:,30,0]),cmap='gray') +plt.xticks([]) +plt.yticks([]) +plt.subplot(1,3,3) +plt.imshow(np.rot90(S_degibbs[:,:,30,0]),cmap='gray') +plt.xticks([]) +plt.yticks([]) +plt.show() + +mask = nib.load(os.path.join('phantoms','brain','data','diffusive_snr50_relax_mask.nii.gz')).get_fdata() + +def noise_correlation(img): + img = img - np.mean(img) + return np.sum(img[:, :-1] * img[:, 1:]) / np.sum(img**2) + +S_crop = nib.load(S_crop_file).get_fdata() +S_degibbs = nib.load(S_degibbs_file).get_fdata() +S_crop[mask==0,:]=0 +S_degibbs[mask==0,:]=0 + +print('Noise correlation before degibbs: {}'.format(noise_correlation(S_crop))) +print('Noise correlation after degibbs: {}'.format(noise_correlation(S_degibbs))) \ No newline at end of file From bc77b44c6231dc01410e7ee9c9dad7c7243b5b88 Mon Sep 17 00:00:00 2001 From: ElinaPetersson Date: Fri, 27 Mar 2026 11:26:27 +0100 Subject: [PATCH 05/21] Added brain pipeline contribution to csv --- doc/code_contributions_record.csv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/code_contributions_record.csv b/doc/code_contributions_record.csv index a3471709..dd7753c4 100644 --- a/doc/code_contributions_record.csv +++ b/doc/code_contributions_record.csv @@ -29,4 +29,5 @@ IVIM,Fitting,LSQ fitting,Part of the SUPER-IVIM-DC python package - trust region IVIM,Fitting,LSQ fitting,Part of the SUPER-IVIM-DC python package - segmented algorithm,TCML_TechnionIIT,TF2.4_IVIM-MRI_CodeCollection/src/original/TCML_TechnionIIT/SUPER-IVIM-DC,Noam Korngut/Elad Rotman/Onur Afacan Sila Kurugol/Yael Zaffrani-Reznikov/Shira Nemirovsky-Rotman/Simon Warfield/Moti Freiman,TCML Technion IIT,super_ivim_dc.source.Classsic_ivim_fit.IVIM_fit_sls,https://doi.org/10.1007/978-3-031-16434-7_71,TCML_TechnionIIT_lsqSLS IVIM,Fitting,LSQ fitting,Part of the SUPER-IVIM-DC python package - Levenberg Marquart lsq algorithm initialized with segmented fitting,TCML_TechnionIIT,TF2.4_IVIM-MRI_CodeCollection/src/original/TCML_TechnionIIT/SUPER-IVIM-DC,Noam Korngut/Elad Rotman/Onur Afacan Sila Kurugol/Yael Zaffrani-Reznikov/Shira Nemirovsky-Rotman/Simon Warfield/Moti Freiman,TCML Technion IIT,super_ivim_dc.source.Classsic_ivim_fit.IVIM_fit_sls_lm,https://doi.org/10.1007/978-3-031-16434-7_71,TCML_TechnionIIT_lsq_sls_lm IVIM,Fitting,LSQ fitting,Part of the SUPER-IVIM-DC python package - trust region lsq algorithm initialized with segmented fitting,TCML_TechnionIIT,TF2.4_IVIM-MRI_CodeCollection/src/original/TCML_TechnionIIT/SUPER-IVIM-DC,Noam Korngut/Elad Rotman/Onur Afacan Sila Kurugol/Yael Zaffrani-Reznikov/Shira Nemirovsky-Rotman/Simon Warfield/Moti Freiman,TCML Technion IIT,super_ivim_dc.source.Classsic_ivim_fit.IVIM_fit_sls_trf,https://doi.org/10.1007/978-3-031-16434-7_71,TCML_TechnionIIT_lsq_sls_trf -IVIM,Fitting,Segmented linear fitting,Consensus algorithm,TF_reference,TF2.4_IVIM-MRI_CodeCollection/src/original/TF_reference/,Ben Neijndorff/OSIPI taskforce 2.4,OSIPI,segmented_IVIMfit,tba,TF_reference_IVIMfit \ No newline at end of file +IVIM,Fitting,Segmented linear fitting,Consensus algorithm,TF_reference,TF2.4_IVIM-MRI_CodeCollection/src/original/TF_reference/,Ben Neijndorff/OSIPI taskforce 2.4,OSIPI,segmented_IVIMfit,tba,TF_reference_IVIMfit +IVIM,Preprocessing,Full pipeline,Brain pipeline,EP_GU,TF2.4_IVIM-MRI_CodeCollection/src/original/EP_GU,Elina Petersson,University of Gothenburg,brain_preproc,tba, \ No newline at end of file From 1d85015c0f0f3a0b2c1c5c86b0fbf852e5463244 Mon Sep 17 00:00:00 2001 From: ElinaPetersson Date: Fri, 27 Mar 2026 11:31:20 +0100 Subject: [PATCH 06/21] hide the degibs test --- tests/IVIMpreproc/unit_tests/test_degibbs.py | 82 +------------------- 1 file changed, 1 insertion(+), 81 deletions(-) diff --git a/tests/IVIMpreproc/unit_tests/test_degibbs.py b/tests/IVIMpreproc/unit_tests/test_degibbs.py index 656d36b6..4287ca86 100644 --- a/tests/IVIMpreproc/unit_tests/test_degibbs.py +++ b/tests/IVIMpreproc/unit_tests/test_degibbs.py @@ -1,81 +1 @@ -''' -Not done! Need a better metric than just noise correlation - -''' -# %% -from phantoms.brain.sim_brain_phantom_preproc import simulate_brain_phantom - -simulate_brain_phantom(snr = 50) -#%% -import nibabel as nib -import numpy as np -from src.original.EP_GU.brain_pipeline import degibbs_wrap -import matplotlib.pyplot as plt -import os - -# load brain phantom -S_ref = nib.load('phantoms/brain/data/diffusive_reference_relax.nii.gz').get_fdata() - -# Convert to k-space -S_k = np.fft.fftn(S_ref,axes=(0,1)) -S_k = np.fft.fftshift(S_k,axes=(0,1)) - -plt.subplot(1,2,1) -plt.imshow(np.log(np.abs(S_k[:,:,30,0])+1),cmap='gray') -plt.xticks([]) -plt.yticks([]) - -# Crop k-space -S_k[:10,:,:,:] = 0 -S_k[-10:,:,:,:] = 0 -# S_k[:,:10,:,:] = 0 -# S_k[:,-10:,:,:] = 0 - -# Test plot -plt.subplot(1,2,2) -plt.imshow(np.log(np.abs(S_k[:,:,30,0])+1),cmap='gray') -plt.xticks([]) -plt.yticks([]) -plt.show() - -# Inverse Fourier transform -S_crop = np.fft.ifftshift(S_k,axes=(0,1)) -S_crop = np.fft.ifftn(S_crop,axes=(0,1)).real - -# Save image -S_crop_nii = nib.Nifti1Image(S_crop.astype(np.float32),np.eye(4)) -S_crop_file = 'phantoms/brain/data/diffusive_reference_relax_cropped.nii.gz' -nib.save(S_crop_nii,S_crop_file) - -# Apply degibbs -S_degibbs_file = degibbs_wrap(S_crop_file) - -# Plot results -S_degibbs = nib.load(S_degibbs_file).get_fdata() -plt.subplot(1,3,1) -plt.imshow(np.rot90(S_ref[:,:,30,0]),cmap='gray') -plt.xticks([]) -plt.yticks([]) -plt.subplot(1,3,2) -plt.imshow(np.rot90(S_crop[:,:,30,0]),cmap='gray') -plt.xticks([]) -plt.yticks([]) -plt.subplot(1,3,3) -plt.imshow(np.rot90(S_degibbs[:,:,30,0]),cmap='gray') -plt.xticks([]) -plt.yticks([]) -plt.show() - -mask = nib.load(os.path.join('phantoms','brain','data','diffusive_snr50_relax_mask.nii.gz')).get_fdata() - -def noise_correlation(img): - img = img - np.mean(img) - return np.sum(img[:, :-1] * img[:, 1:]) / np.sum(img**2) - -S_crop = nib.load(S_crop_file).get_fdata() -S_degibbs = nib.load(S_degibbs_file).get_fdata() -S_crop[mask==0,:]=0 -S_degibbs[mask==0,:]=0 - -print('Noise correlation before degibbs: {}'.format(noise_correlation(S_crop))) -print('Noise correlation after degibbs: {}'.format(noise_correlation(S_degibbs))) \ No newline at end of file +# \ No newline at end of file From 44aa7be63e05c5bc84a53a04c0b7d6ff2ff4e496 Mon Sep 17 00:00:00 2001 From: oonim Date: Wed, 1 Apr 2026 17:08:39 +0200 Subject: [PATCH 07/21] topup and eddy preproc added --- src/original/MG_LU/TOPED_fsl_commands.py | 313 +++++++++++++++++++ src/original/MG_LU/TOPED_fsl_runner.py | 372 +++++++++++++++++++++++ 2 files changed, 685 insertions(+) create mode 100644 src/original/MG_LU/TOPED_fsl_commands.py create mode 100644 src/original/MG_LU/TOPED_fsl_runner.py diff --git a/src/original/MG_LU/TOPED_fsl_commands.py b/src/original/MG_LU/TOPED_fsl_commands.py new file mode 100644 index 00000000..236a55cf --- /dev/null +++ b/src/original/MG_LU/TOPED_fsl_commands.py @@ -0,0 +1,313 @@ +import os +import re +import shutil +import subprocess +from typing import Optional, Tuple + + +class TOPED: + def __init__(self, distribution: str, user: str, linux_workdir: str): + """ Specify WSL distribution, user, and working directory for FSL. + Parameters: + distribution : str The WSL distribution where FSL is installed (e.g., "Ubuntu"). + user : str The Linux username to run commands as. + linux_workdir : str The directory in the Linux filesystem to use for temporary files. + """ + + if not os.path.exists(linux_workdir): + #raise ValueError(f"Linux working directory not found: {linux_workdir}") + print(f"Linux working directory not found, creating: {linux_workdir}") + os.makedirs(linux_workdir) + + self.distribution = distribution + self.user = user + self.linux_workdir = linux_workdir + + # CORE COMMAND FUNCTION + def run_command(self, command: str, workdir: str): + """ Run a generic FSL command through WSL. + Parameters: + command : str The FSL command to execute. + Returns: + subprocess.CompletedProcess The completed process. + """ + # print the full command in the IDE output when running the fsl_runner. + print(f" command: {command}") + + full_cmd = f"source ~/.profile; source ~/.bashrc; {command}" + return subprocess.run( + ['wsl', '-d', self.distribution, '-u', self.user, '-e', 'bash', '-c', full_cmd], + cwd=workdir, + check=True, + capture_output=True, + text=True + ) + + # TOPUP + def run_topup( + self, + b0_path: str, + acq_parameter_path: str, + config_file_path: Optional[str] = None, + nthr: Optional[int] = None, + logout: Optional[str] = None, # new + dfout: Optional[str] = None, # new + jacout: Optional[str] = None, # new + patient_id: Optional[str] = None, + output_dir: Optional[str] = None # iout mandatory bruh! + ) -> str: + """ Run FSL TOPUP on a stack of b0 images. + Parameters: + b0_path : str The path to the b0 image to process with TOPUP. + acq_parameter_path : str Path to the acquisition parameters file. + config_file_path : str, optional Path to the TOPUP configuration file, by default None, which uses the default FSL config b02b0.cnf. + nthr : int, optional Number of threads to use, by default None (uses default_threads) + Returns: + whatever specified in the TOPUP command output (dfout, iout, jacout) + Corrected image, fieldmap, and Jacobian determinant paths are generated in the Linux working directory. + """ + workdir = self.get_patient_workdir(patient_id) + + if not os.path.exists(b0_path): + raise ValueError("b0_path invalid") + if not os.path.exists(acq_parameter_path): + raise ValueError("acq_parameter_path invalid") + + output_dir = output_dir or os.path.dirname(b0_path) + + # Copy inputs + b0_name = self.copy_to_wsl(b0_path, workdir) + b0_basename, _ = self.split_nifti_gz(b0_name) + + acqparam = self.copy_to_wsl(acq_parameter_path, workdir) + if config_file_path: + config_filename = self.copy_to_wsl(config_file_path, workdir) + config_arg = f"--config={config_filename} " + else: + # Force FSL default config + config_arg = "--config=b02b0.cnf " + + # Build command + cmd = ( + f"topup " + f"--imain={b0_name} " + f"--datain={acqparam} " + f"--out={b0_basename} " + #f"--dfout={self.get_fieldmap_name(b0_basename)} " + f"--iout={self.get_corrected_name(b0_basename)} " + #f"--jacout={self.get_jacobian_name(b0_basename)} " + ) + + if logout is not None: cmd += f"--logout={self.get_log_name(b0_basename)} " + if dfout is not None: cmd += f"--dfout={self.get_warpfig_name(b0_basename)} " + if jacout is not None: cmd += f"--jacout={self.get_jacobian_name(b0_basename)} " + if nthr is not None: + cmd += f"--nthr={nthr} " + cmd += config_arg + + # Run + self.run_command(cmd, workdir) + + # Copy corrected image back + self.ensure_dir(output_dir) + corrected_filename = self.get_corrected_name(b0_basename, ext=True) + self.copy_from_wsl(corrected_filename, output_dir, workdir) + + # Return topup base for Eddy + return b0_basename + + # Eddy + def run_eddy( + self, + dwi_path: str, + mask_path: str, + acq_parameter_path: str, + index_path: str, + bvecs_path: str, + bvals_path: str, + topup_base: str, + slspec_path: Optional[str] = None, + b_range: Optional[int] = None, + flm: Optional[str] = None, + slm: Optional[str] = None, + niter: Optional[int] = None, + fwhm: Optional[str] = None, + resamp: Optional[str] = None, + fep: Optional[bool] = None, + repol: Optional[bool] = None, + estimate_move_by_susceptibility: Optional[bool] = None, + mporder: Optional[int] = None, + patient_id: Optional[str] = None, + output_dir: Optional[str] = None, + json_path: Optional[str] = None, # new from here. + interp: Optional[str] = None, + nvoxhp: Optional[int] = None, + ff: Optional[float] = None, + dont_sep_offs_move: Optional[bool] = None, + dont_peas: Optional[bool] = None, + ol_nstd: Optional[float] = None, + ol_nvox: Optional[int] = None, + ol_type: Optional[str] = None, + ol_ss: Optional[int] = None, + ol_pos: Optional[bool] = None, + ol_sqr: Optional[bool] = None, + s2v_niter: Optional[int] = None, + s2v_lambda: Optional[float] = None, + s2v_interp: Optional[str] = None, + mbs_niter: Optional[int] = None, + mbs_lambda: Optional[float] = None, + mbs_ksp: Optional[float] = None, + cnr_maps: Optional[bool] = None, + residuals: Optional[bool] = None, + data_is_shelled: Optional[bool] = None, + nthr: Optional[int] = None + ) -> str: + + """ Run FSL Eddy. + Parameters: + dwi_path : str Path to the input DWI image. This is the stack to be corrected by Eddy & TOPUP. + mask_path : str Path to the mask image. + acqparams_path : str Path to acquisition parameters file + index_path : str Path to index file + bvecs_path : str Path to bvecs file + bvals_path : str Path to bvals file + topup_base : str Base name used for topup output. is is automatically set by TOUP in the linux working directory and is used as input for Eddy. + output_dir : str Output directory + bunch of optional Eddy flags (set to None to use FSL defaults). + Returns: + (Eddy + TOPUP) Corrected DWI image (path to output image) + """ + + workdir = self.get_patient_workdir(patient_id) + + for p in [dwi_path, mask_path, acq_parameter_path, index_path, bvecs_path, bvals_path]: + if not os.path.exists(p): + raise ValueError(f"Missing compulsory file: {p}") + + output_dir = output_dir or os.path.dirname(dwi_path) + + # Copy inputs + dwi_name = self.copy_to_wsl(dwi_path, workdir) + dwi_basename, _ = self.split_nifti_gz(dwi_name) + + mask = self.copy_to_wsl(mask_path, workdir) + acqp = self.copy_to_wsl(acq_parameter_path, workdir) + index = self.copy_to_wsl(index_path, workdir) + bvecs = self.copy_to_wsl(bvecs_path, workdir) + bvals = self.copy_to_wsl(bvals_path, workdir) + + slspec = self.copy_to_wsl(slspec_path, workdir) if slspec_path else None + json_file = self.copy_to_wsl(json_path, workdir) if json_path else None + + # Build command dynamically + cmd = ( + f"eddy " + f"--imain={dwi_name} " + f"--mask={mask} " + f"--acqp={acqp} " + f"--index={index} " + f"--bvecs={bvecs} " + f"--bvals={bvals} " + f"--topup={topup_base} " + f"--out={self.get_corrected_name_eddy(dwi_basename)} " + ) + + # Optional params + if slspec: cmd += f"--slspec={slspec} " + if json_file: cmd += f"--json={json_file} " + if b_range is not None: cmd += f"--b_range={b_range} " + + if flm is not None: cmd += f"--flm={flm} " + if slm is not None: cmd += f"--slm={slm} " + if fwhm is not None: cmd += f"--fwhm={fwhm} " + if niter is not None: cmd += f"--niter={niter} " + if interp is not None: cmd += f"--interp={interp} " + if resamp is not None: cmd += f"--resamp={resamp} " + if fep is not None: cmd += f"--fep " + if nvoxhp is not None: cmd += f"--nvoxhp={nvoxhp} " + if ff is not None: cmd += f"--ff={ff} " + if dont_sep_offs_move is not None: cmd += f"--dont_sep_offs_move " + if dont_peas is not None: cmd += f"--dont_peas " + + if repol is not None: cmd += f"--repol " + if ol_nstd is not None: cmd += f"--ol_nstd={ol_nstd} " + if ol_nvox is not None: cmd += f"--ol_nvox={ol_nvox} " + if ol_type is not None: cmd += f"--ol_type={ol_type} " + if ol_ss is not None: cmd += f"--ol_ss={ol_ss} " + if ol_pos is not None: cmd += f"--ol_pos " + if ol_sqr is not None: cmd += f"--ol_sqr " + + if mporder is not None: cmd += f"--mporder={mporder} " + if s2v_niter is not None: cmd += f"--s2v_niter={s2v_niter} " + if s2v_lambda is not None: cmd += f"--s2v_lambda={s2v_lambda} " + if s2v_interp is not None: cmd += f"--s2v_interp={s2v_interp} " + + if estimate_move_by_susceptibility is not None: + cmd += f"--estimate_move_by_susceptibility={int(estimate_move_by_susceptibility)} " + if mbs_niter is not None: cmd += f"--mbs_niter={mbs_niter} " + if mbs_lambda is not None: cmd += f"--mbs_lambda={mbs_lambda} " + if mbs_ksp is not None: cmd += f"--mbs_ksp={mbs_ksp} " + + if cnr_maps is not None: cmd += f"--cnr_maps " + if residuals is not None: cmd += f"--residuals " + if data_is_shelled is not None: cmd += f"--data_is_shelled " + if nthr is not None: cmd += f"--nthr={nthr} " + + + # Run + self.run_command(cmd, workdir) + + # Copy output back + self.ensure_dir(output_dir) + output_filename = self.get_corrected_name_eddy(dwi_basename, ext=True) + self.copy_from_wsl(output_filename, output_dir, workdir) + + return os.path.join(output_dir, output_filename) + + + # FILE HANDLING between windows and wsl + def copy_to_wsl(self, path: str, workdir: str) -> str: + filename = os.path.basename(path) + dst = os.path.join(workdir, filename) + shutil.copy(path, dst) + return filename + + def copy_from_wsl(self, filename: str, output_dir: str, workdir: str): + src = os.path.join(workdir, filename) + dst = os.path.join(output_dir, filename) + if not os.path.exists(src): + raise FileNotFoundError(f"Expected output not found: {src}") + shutil.copy(src, dst) + + + # HELPERS - filenames and folders etc. + def split_nifti_gz(self, filename: str) -> Tuple[str, str]: + match = re.match(r"^(.*)(\.nii\.gz)$", filename) + return match.group(1), match.group(2) if match else os.path.splitext(filename) + + def get_warpfig_name(self, base: str): + return f"{base}_warpfig" + + def get_jacobian_name(self, base: str): + return f"{base}_jacobian" + + def get_log_name(self, base: str): + return f"{base}_log" + + def get_corrected_name(self, base: str, ext=False): + return f"{base}_corrected.nii.gz" if ext else f"{base}_corrected" + + def get_corrected_name_eddy(self, base: str, ext=False): + return f"{base}_EddyCorrected.nii.gz" if ext else f"{base}_EddyCorrected" + + def ensure_dir(self, path: str): + if not os.path.exists(path): + os.makedirs(path) + + def get_patient_workdir(self, patient_id: Optional[str]) -> str: + if not patient_id: + return self.linux_workdir + path = os.path.join(self.linux_workdir, patient_id) + if not os.path.exists(path): + os.makedirs(path) + return path \ No newline at end of file diff --git a/src/original/MG_LU/TOPED_fsl_runner.py b/src/original/MG_LU/TOPED_fsl_runner.py new file mode 100644 index 00000000..d16c8670 --- /dev/null +++ b/src/original/MG_LU/TOPED_fsl_runner.py @@ -0,0 +1,372 @@ +import os +from typing import Optional +from TOPED_fsl_commands import TOPED # script containing subprocess commands + +""" +About this script: +The script is run in Windows but runs FSL commands through a WSL subprocess. The corrected files are copied back into windows from linux. +On the user-end, everything should be done in windows. + +This script runs all linux commands as a subprocess using the TOPED class in TOPED_fsl_commands.py. + The input data is read from your specified windows directory 'main_dir' and the final output is saved in the same directory. + However, all processing is done in the specified linux_workdir. All files for each loop (/patient) are saved there and then copied back to the respective folders in windows main_dir. +To run the script you will need to specify the parameters in the configuration section below. +Input files for topup and and eddy are identified through keywords specified in the IDENTIFIERS dict. + for each input type (e.g. b0, dwi stack, mask, acqp, bvecs, bvals, index), specify a keyword that is contained in the respective file names in your dataset. + This should be unique, i.e. if the keyword for the topup imain input is "b0", the script looks for files containing "b0" in the name and takes that as input. If there are multiple files containing "b0", an error is raised. + The assumed directory strucure is seen below. The script looks for the input files in the 'patient' folders first, then in the common folder if not found in the patient folder. + If you keep all data in the 'patient' folders and do not have a common folder, set COMMON_FOLDER_NAME to None and the script will only look in the patient folders. + The structure of the main directory will be copied into the Linux working directory (i.e. the same folders and files will be generated). + +Requirements: +- Python packages os, re, typing, subprocess, shutil) +- FSL installed with an WSL distro. user needs to be configured. Make sure FSL can be run from the command line in WSL. + + +- Files needed for topup and eddy: + Topup: + - b0 image (4D file containing multiple b0 volumes). nii.gz + - acqparams.txt (PE directions) + - configuration file (optional, if not specified the default FSL config b02b0.cnf is used) .cnf + Eddy: + - dwi image (4D stack contaning whatever should be topup+eddy corrected). nii.gz + - mask (typically brain mask, but i dont do brain so its whatever i guess). nii.gz + - acqparams (assumed to be the same as for topup). + - index (to match the dwi stack volumes to the acqparams lines). + - bvecs (as generated by e.g. dcm2niix). make sure they match the full stack. + - bvals (as generated by e.g. dcm2niix). make sure they match the full stack. + - slspec (optional). + - JSON (optional) +""" + +# main_directory +# ├── patient_1 +# │ ├── pt1_b0.nii.gz +# │ ├── pt1_dwi_stack.nii.gz +# │ ├── pt1_mask.nii.gz +# │ └── ... (other patient-specific files, e.g. pt1_jsonfile.json) +# ├── patient_2 +# │ ├── pt2_b0.nii.gz +# │ ├── pt2_dwi_stack.nii.gz +# │ ├── pt2_mask.nii.gz +# │ └── ... (other patient-specific files) +# └── common_files (optional) +# ├── acqparams.txt +# ├── bvecs +# ├── bvals +# ├── index.txt +# ├── slspec.txt +# └── config.cnf + +# Note: 'patient_1' etc. are examples and can be any suitable name. +# The names of these folders are copied into the linux working directory and are used to identify the respective entries. +# a 'common_files' folder is optional. The purpose is is you e.g. have the same config file or acqparams/bvecs/bvals/index/slspec files for all patients. + +# ======================================================================================================================================================= +"""CONFIGURATION - Adjust these parameters according to your data""" # change things in this section! + +#main directory in WINDOWS containing patient folders and common folder. +MAIN_DIR = r"C:\path\to\your\main_dir" # replace with path to your main_dir. + +# folder inside main_dir that contains files which are common for all patients (e.g. acqparams, bvecs, bvals, index, slspec). +COMMON_FOLDER_NAME = "common_files" # replace with your path, or set to None if there is no common folder. +# The script looks in the patient folders first. if it does not find the required files there, it looks in the common folder. + + +# Filename identifiers - Change the RHS here according to your own file naming conventions!!! +# The script will look for files containing these keywords in the patient folders first (then in the common folder). +IDENTIFIERS = { + "b0": "b0.nii.gz", # e.g. topup --imain. assumed to contain str 'b0' in the filename. + # the name of the b0 file determines the names of generated output files. + # a b0 file named 'patient1_ddmmyyyy_b0.nii.gz' will generate output files which all have the prefix 'patient1_ddmmyyyy'. + "dwi": "stack.nii.gz", # e.g. eddy --imain. DWI stack assumed to contain 'stack' in the filename. Should have the same prefix as the b0 file, e.g. 'patient1_ddmmyyyy_stack.nii.gz' to match with 'patient1_ddmmyyyy_b0.nii.gz'. + "mask": "mask", # eddy --mask. contains 'mask' in the filename. + "bvec": "bvec", + "bval": "bval", + "index": "index", # index for eddy + "acqp": "acq", # acqparams for topup and eddy. + "slspec": "slspec", # optional slice spec for eddy. + "json": "json", # optional json file for eddy. + "config": ".cnf" # optional config file for topup. If not found, the FSL default config b02b0.cnf will be used. +} + +# FSL PARAMETERS - adjust as needed. +TOPUP_PARAMS = { + "nthr": 14, # --nthr to run topup. + "jacout": None, # Default False. + "logout": None, # Default False. + "dfout": None, # Default False. + "output_dir": None # all files are saved in the linux working directory by default (None). The corrected files are copied back into main_dir in windows. + # remaining Topup parameters are set with the config file. You can specify a config file for each patient or a common one in the common folder by placing the .cnf file in the directory. +} + + +EDDY_PARAMS = { + "b_range": None, # None defaults to 50. + "flm": None, # ('linear', 'quadratic', 'cubic'). None defaults to 'quadratic' + "slm": None, # ('none', 'linear', 'quadratic'). None defaults to 'none'. + "fwhm": 10, # Default: 0 mm. Set to 10 for testing. + "niter": 1, # Default: 5. Set to 1 for testing. + "interp": None, # ('spline', 'trilinear'). None defaults to 'spline'. + "resamp": None, # ('jac', 'lsr'). None defaults to 'jac'. + "fep": None, # True/False. None defaults to False. + "nvoxhp": None, # None defaults to 1000. + "ff": None, # [0,10]. None defaults to 10. + "dont_sep_offs_move": None, # True/False. None defaults to False. + "dont_peas": None, # True/False. None defaults to False. + + "repol": None, # True/False. None defaults to False. set to True to enable outlier replacement. + "ol_nstd": None, # When repol=True; None defaults to 4. + "ol_nvox": None, # When repol=True; None defaults to 250. + "ol_type": None, # When repol=True; ('sw', 'gw', 'both'). None defaults to 'sw'. + "ol_ss": None, # When repol=True; ('sw', 'pooled'). None defaults to 'sw'. + "ol_pos": None, # When repol=True; True/False. None defaults to False. + "ol_sqr": None, # When repol=True; True/False. None defaults to False. + + "mporder": None, # Default 0. + "s2v_niter": None, # When mporder>0; None defaults to 5. + "s2v_lambda": None, # When mporder>0; None defaults to 1. + "s2v_interp": None, # When mporder>0; ('trilinear', 'spline'). None defaults to 'trilinear'. + + "estimate_move_by_susceptibility": None, # True/Flase. None defaults to False. + "mbs_niter": None, # When estimate_move_by_susceptibility=True; None defaults to 10. + "mbs_lambda": None, # When estimate_move_by_susceptibility=True; None defaults to 10. + "mbs_ksp": None, # When estimate_move_by_susceptibility=True; None defaults to 10. + + "cnr_maps": None, # True/False. None defaults to False. + "residuals": None, # True/False. None defaults to False. + "data_is_shelled": None,# True/False. None defaults to False. + "nthr": None, # --nthr to run eddy. only relevant for CPU! + + "output_dir": None # all files are saved in the linux working directory by default (None). The corrected files are copied back into original dir in windows. +} + +# WSL commands are run through your distro and in whatever directory you specify as your linux_workdir. +fsl = TOPED( + + distribution="Ubuntu-22.04", # your WSL distribution name you can find it by running 'wsl -l -v' in powershell. + user="username", # replace with your WSL user. + linux_workdir=r"\\wsl.localhost\Ubuntu-22.04\home\user\yourfolder" # replace with the name of a folder located in home/user in your WSL distribution. + # yourfolder is the wd for FSL commands. It will be created if it does not exist. + # All output files will be saved here. Corrected files from TOPUP and Eddy will be copied back to the patient folders in windows. + # The data will be organised into folders matching your main_dir structure, i.e. for each patient folder in main_dir, a corresponding folder is created in linux_workdir and all processing for that patient is done in that folder. + # Make sure to change this path between different runs so that you dont overwrite your data. :) +) + + + + + +# ======================================================================================================================================================= +"""RUNNING LOOP THOUGH FOLDERS IN MAIN_DIR, WITH PARAMTERS SPECIFIED ABOVE""" +# ALL lops are run with the parameters as specified in the configuration section above. parameters are global for the run. +# be careful if/when changing this section below (needs to match with TOPED_fsl_commands.py). + + +# HELPER functions to find input files based in IDENTIFIERS dict. +def find_file(folder, keyword) -> Optional[str]: + matches = [f for f in os.listdir(folder) if keyword.lower() in f.lower()] + if len(matches) == 0: + return None + if len(matches) > 1: + raise RuntimeError(f"Multiple files found for '{keyword}' in {folder}") + return os.path.join(folder, matches[0]) + +# function for finding cnf files. +def find_cnf_file(folder): + matches = [f for f in os.listdir(folder) if f.lower().endswith(".cnf")] + if len(matches) == 0: + return None + if len(matches) > 1: + raise RuntimeError(f"Multiple .cnf files found in {folder}! clean this shit up") + return os.path.join(folder, matches[0]) +# function for finding json files. +def find_json_file(folder): + matches = [f for f in os.listdir(folder) if f.lower().endswith(".json")] + if len(matches) == 0: + return None + if len(matches) > 1: + raise RuntimeError(f"Multiple .json files found in {folder}!") + return os.path.join(folder, matches[0]) + + +# searches for the file in the patient folder first, then in the common folder if not found in the patient folder. +def resolve_file(patient_dir, common_dir, key): + local = find_file(patient_dir, IDENTIFIERS[key]) + if local: + return local + if common_dir: + return find_file(common_dir, IDENTIFIERS[key]) + return None + + +# main loops start HERE - runs TOPUP and Eddy for each patient folder in main_dir +common_dir = (os.path.join(MAIN_DIR, COMMON_FOLDER_NAME) if COMMON_FOLDER_NAME else None) + +# Input file check - check all of main_dir, do the files exist for all patients? +# this is so that you wont leeave this overnight and come back to some shit error that could have been prevented. + +print("\n File check: Checking if all required files are found...") +file_check = True + +for patient in os.listdir(MAIN_DIR): + patient_dir = os.path.join(MAIN_DIR, patient) + if not os.path.isdir(patient_dir) or patient == COMMON_FOLDER_NAME: + continue + + issues = [] + + # Locate files using same logic as the main loop + b0_path = find_file(patient_dir, IDENTIFIERS["b0"]) + dwi_path = find_file(patient_dir, IDENTIFIERS["dwi"]) + mask_path = find_file(patient_dir, IDENTIFIERS["mask"]) + acqp_path = resolve_file(patient_dir, common_dir, "acqp") + bvecs_path = resolve_file(patient_dir, common_dir, "bvec") + bvals_path = resolve_file(patient_dir, common_dir, "bval") + index_path = resolve_file(patient_dir, common_dir, "index") + + # TOPUP compulsory inputs + if not b0_path: issues.append("TOPUP: cannot find b0 file") + if not acqp_path: issues.append("TOPUP: cannot find acqisition parameters file") + + # EDDY compulsory (only warn if b0 exists, i.e. TOPUP would run) + if b0_path: + if not dwi_path: issues.append("EDDY: cannot find 4D dwi file") + if not mask_path: issues.append("EDDY: cannot find mask file") + if not bvecs_path: issues.append("EDDY: cannot find bvecs file") + if not bvals_path: issues.append("EDDY: cannot find bvals file") + if not index_path: issues.append("EDDY: cannot find index file") + + if issues: + print(f" FAIL {patient}:") + for issue in issues: + print(f" - {issue}") + file_check = False + else: + print(f" OK {patient}") + +if not file_check: + print("\n WARNING!!!!!!!!! File check failed. Some files cannot be found. You may want to abort and fix the issues. " \ + "\n Consider renaming your files to contain the specified keyword or adjust the IDENTIFIERS dict accordingly. " \ + "\n TOPUP/Eddy will run only for the 'OK' cases.") +else: + print("\n File check passed — all patients have all compulosry inputs.") + + +for patient in os.listdir(MAIN_DIR): + # searches ALL folders in main_dir (except for specified common_folder). -> Attempts to run topup+eddy on all folders in main_dir. + patient_dir = os.path.join(MAIN_DIR, patient) + if not os.path.isdir(patient_dir) or patient == COMMON_FOLDER_NAME: + continue + print(f"\n \nProcessing folder: {patient}--------------------------------------------------------------") + patient_id = patient # this is the name of the folder both in windows and in linux workdir. + + try: + # Locate compulsory files - these files should be in the 'patient' directory, not in common. + b0_path = find_file(patient_dir, IDENTIFIERS["b0"]) + dwi_path = find_file(patient_dir, IDENTIFIERS["dwi"]) + mask_path = find_file(patient_dir, IDENTIFIERS["mask"]) + # these can be in both common and patient dir. + acqp_path = resolve_file(patient_dir, common_dir, "acqp") + bvecs_path = resolve_file(patient_dir, common_dir, "bvec") + bvals_path = resolve_file(patient_dir, common_dir, "bval") + index_path = resolve_file(patient_dir, common_dir, "index") + slspec_path = resolve_file(patient_dir, common_dir, "slspec") + config_path = find_cnf_file(patient_dir) + if not config_path and common_dir: + config_path = find_cnf_file(common_dir) + json_path = find_json_file(patient_dir) + if not json_path and common_dir: + json_path = find_json_file(common_dir) + + # Check TOPUP inputs + if not b0_path: + print(f" o_O No b0 found in {patient} → Cannot run TOPUP. skipping dataset. Rename your b0 file to contain the specified keyword or adjust the IDENTIFIERS dict accordingly.") + continue + if not acqp_path: + raise RuntimeError(" Missing acquisition parameters (acqp). Please add file or update IDENTIFIERS dict.") + + print(f" → Running TOPUP :)") + # RUN TOPUP + topup_base = fsl.run_topup( + b0_path=b0_path, + acq_parameter_path=acqp_path, + config_file_path=config_path, + nthr=TOPUP_PARAMS["nthr"], + logout=TOPUP_PARAMS["logout"], + jacout=TOPUP_PARAMS["jacout"], + dfout=TOPUP_PARAMS["dfout"], + patient_id=patient, + output_dir=TOPUP_PARAMS["output_dir"] or patient_dir + ) + + # Check EDDY inputs + missing_eddy = [] + if not dwi_path: missing_eddy.append("dwi") + if not mask_path: missing_eddy.append("mask") + if not bvecs_path: missing_eddy.append("bvecs") + if not bvals_path: missing_eddy.append("bvals") + if not index_path: missing_eddy.append("index") + + if missing_eddy: + print(f" o_O Eddy missing compulsory parameters: {missing_eddy} → Cannot run EDDY. Rename your files to contain the respective keywords or adjust the IDENTIFIERS dict accordingly.") + continue +# + print(f" → Running Eddy :)") + + # RUN EDDY + fsl.run_eddy( + dwi_path=dwi_path, + mask_path=mask_path, + acq_parameter_path=acqp_path, + index_path=index_path, + bvecs_path=bvecs_path, + bvals_path=bvals_path, + patient_id=patient, + topup_base=topup_base, + + slspec_path=slspec_path, + json_path=json_path, + b_range=EDDY_PARAMS["b_range"], + + flm=EDDY_PARAMS["flm"], + slm=EDDY_PARAMS["slm"], + fwhm=EDDY_PARAMS["fwhm"], + niter=EDDY_PARAMS["niter"], + interp=EDDY_PARAMS["interp"], + resamp=EDDY_PARAMS["resamp"], + fep=EDDY_PARAMS["fep"], + nvoxhp=EDDY_PARAMS["nvoxhp"], + ff=EDDY_PARAMS["ff"], + dont_sep_offs_move=EDDY_PARAMS["dont_sep_offs_move"], + dont_peas=EDDY_PARAMS["dont_peas"], + + repol=EDDY_PARAMS["repol"], + ol_nstd=EDDY_PARAMS["ol_nstd"], + ol_nvox=EDDY_PARAMS["ol_nvox"], + ol_type=EDDY_PARAMS["ol_type"], + ol_ss=EDDY_PARAMS["ol_ss"], + ol_pos=EDDY_PARAMS["ol_pos"], + ol_sqr=EDDY_PARAMS["ol_sqr"], + mporder=EDDY_PARAMS["mporder"], + s2v_niter=EDDY_PARAMS["s2v_niter"], + s2v_lambda=EDDY_PARAMS["s2v_lambda"], + s2v_interp=EDDY_PARAMS["s2v_interp"], + + estimate_move_by_susceptibility=EDDY_PARAMS["estimate_move_by_susceptibility"], + mbs_niter=EDDY_PARAMS["mbs_niter"], + mbs_lambda=EDDY_PARAMS["mbs_lambda"], + mbs_ksp=EDDY_PARAMS["mbs_ksp"], + + cnr_maps=EDDY_PARAMS["cnr_maps"], + residuals=EDDY_PARAMS["residuals"], + data_is_shelled=EDDY_PARAMS["data_is_shelled"], + + + output_dir=EDDY_PARAMS["output_dir"] or patient_dir + ) + + print(f"\n Done. Check your output for {patient} :)") + + except Exception as e: + print(f"ERROR in {patient}: {str(e)}") \ No newline at end of file From e5a7d7b403b0c74e3fe2f5c1d5b180e80b004e58 Mon Sep 17 00:00:00 2001 From: oonim Date: Wed, 1 Apr 2026 17:36:06 +0200 Subject: [PATCH 08/21] typos etc --- src/original/MG_LU/TOPED_fsl_commands.py | 19 +++++------ src/original/MG_LU/TOPED_fsl_runner.py | 43 +++++++++++------------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/original/MG_LU/TOPED_fsl_commands.py b/src/original/MG_LU/TOPED_fsl_commands.py index 236a55cf..94533698 100644 --- a/src/original/MG_LU/TOPED_fsl_commands.py +++ b/src/original/MG_LU/TOPED_fsl_commands.py @@ -28,8 +28,7 @@ def run_command(self, command: str, workdir: str): """ Run a generic FSL command through WSL. Parameters: command : str The FSL command to execute. - Returns: - subprocess.CompletedProcess The completed process. + workdir : str The working directory in the Linux filesystem where the command should be executed. """ # print the full command in the IDE output when running the fsl_runner. print(f" command: {command}") @@ -50,11 +49,11 @@ def run_topup( acq_parameter_path: str, config_file_path: Optional[str] = None, nthr: Optional[int] = None, - logout: Optional[str] = None, # new - dfout: Optional[str] = None, # new - jacout: Optional[str] = None, # new + logout: Optional[str] = None, + dfout: Optional[str] = None, + jacout: Optional[str] = None, patient_id: Optional[str] = None, - output_dir: Optional[str] = None # iout mandatory bruh! + output_dir: Optional[str] = None ) -> str: """ Run FSL TOPUP on a stack of b0 images. Parameters: @@ -84,7 +83,7 @@ def run_topup( config_filename = self.copy_to_wsl(config_file_path, workdir) config_arg = f"--config={config_filename} " else: - # Force FSL default config + # FSL default config config_arg = "--config=b02b0.cnf " # Build command @@ -93,9 +92,7 @@ def run_topup( f"--imain={b0_name} " f"--datain={acqparam} " f"--out={b0_basename} " - #f"--dfout={self.get_fieldmap_name(b0_basename)} " f"--iout={self.get_corrected_name(b0_basename)} " - #f"--jacout={self.get_jacobian_name(b0_basename)} " ) if logout is not None: cmd += f"--logout={self.get_log_name(b0_basename)} " @@ -139,7 +136,7 @@ def run_eddy( mporder: Optional[int] = None, patient_id: Optional[str] = None, output_dir: Optional[str] = None, - json_path: Optional[str] = None, # new from here. + json_path: Optional[str] = None, interp: Optional[str] = None, nvoxhp: Optional[int] = None, ff: Optional[float] = None, @@ -199,7 +196,7 @@ def run_eddy( slspec = self.copy_to_wsl(slspec_path, workdir) if slspec_path else None json_file = self.copy_to_wsl(json_path, workdir) if json_path else None - # Build command dynamically + # Build command cmd = ( f"eddy " f"--imain={dwi_name} " diff --git a/src/original/MG_LU/TOPED_fsl_runner.py b/src/original/MG_LU/TOPED_fsl_runner.py index d16c8670..0e488ea8 100644 --- a/src/original/MG_LU/TOPED_fsl_runner.py +++ b/src/original/MG_LU/TOPED_fsl_runner.py @@ -4,37 +4,35 @@ """ About this script: -The script is run in Windows but runs FSL commands through a WSL subprocess. The corrected files are copied back into windows from linux. -On the user-end, everything should be done in windows. - +The script is run in Windows and expects files located in windows directories. + This script runs all linux commands as a subprocess using the TOPED class in TOPED_fsl_commands.py. The input data is read from your specified windows directory 'main_dir' and the final output is saved in the same directory. - However, all processing is done in the specified linux_workdir. All files for each loop (/patient) are saved there and then copied back to the respective folders in windows main_dir. + All processing is done in a specified linux working directory. All files for each patient are saved there and then copied back to the respective folders in the windows directory. To run the script you will need to specify the parameters in the configuration section below. -Input files for topup and and eddy are identified through keywords specified in the IDENTIFIERS dict. +Input files for topup and and eddy are identified through keywords specified in the IDENTIFIERS dictionary. for each input type (e.g. b0, dwi stack, mask, acqp, bvecs, bvals, index), specify a keyword that is contained in the respective file names in your dataset. This should be unique, i.e. if the keyword for the topup imain input is "b0", the script looks for files containing "b0" in the name and takes that as input. If there are multiple files containing "b0", an error is raised. The assumed directory strucure is seen below. The script looks for the input files in the 'patient' folders first, then in the common folder if not found in the patient folder. - If you keep all data in the 'patient' folders and do not have a common folder, set COMMON_FOLDER_NAME to None and the script will only look in the patient folders. The structure of the main directory will be copied into the Linux working directory (i.e. the same folders and files will be generated). Requirements: -- Python packages os, re, typing, subprocess, shutil) +- Python packages (os, re, typing, subprocess, shutil) - FSL installed with an WSL distro. user needs to be configured. Make sure FSL can be run from the command line in WSL. -- Files needed for topup and eddy: +Supported file inputs: Topup: - - b0 image (4D file containing multiple b0 volumes). nii.gz - - acqparams.txt (PE directions) - - configuration file (optional, if not specified the default FSL config b02b0.cnf is used) .cnf + - b0 image (4D file containing multiple b0 volumes). nii.gz (compulsory) + - acqparams.txt (PE directions) (compulsory) + - configuration file (if not specified the default FSL config b02b0.cnf is used) .cnf (optional) Eddy: - - dwi image (4D stack contaning whatever should be topup+eddy corrected). nii.gz - - mask (typically brain mask, but i dont do brain so its whatever i guess). nii.gz - - acqparams (assumed to be the same as for topup). - - index (to match the dwi stack volumes to the acqparams lines). - - bvecs (as generated by e.g. dcm2niix). make sure they match the full stack. - - bvals (as generated by e.g. dcm2niix). make sure they match the full stack. + - dwi image (4D stack contaning whatever should be topup+eddy corrected). nii.gz (compulsory) + - mask (typically brain mask, but i dont do brain so its whatever i guess). nii.gz (compulsory) + - acqparams (assumed to be the same as for topup). (compulsory) + - index (to match the dwi stack volumes to the acqparams lines). (compulsory) + - bvecs (as generated by e.g. dcm2niix). make sure they match the full stack. (compulsory) + - bvals (as generated by e.g. dcm2niix). make sure they match the full stack. (compulsory) - slspec (optional). - JSON (optional) """ @@ -80,7 +78,7 @@ # the name of the b0 file determines the names of generated output files. # a b0 file named 'patient1_ddmmyyyy_b0.nii.gz' will generate output files which all have the prefix 'patient1_ddmmyyyy'. "dwi": "stack.nii.gz", # e.g. eddy --imain. DWI stack assumed to contain 'stack' in the filename. Should have the same prefix as the b0 file, e.g. 'patient1_ddmmyyyy_stack.nii.gz' to match with 'patient1_ddmmyyyy_b0.nii.gz'. - "mask": "mask", # eddy --mask. contains 'mask' in the filename. + "mask": "mask", # eddy --mask. contains 'mask' in the filename. "bvec": "bvec", "bval": "bval", "index": "index", # index for eddy @@ -144,13 +142,12 @@ # WSL commands are run through your distro and in whatever directory you specify as your linux_workdir. fsl = TOPED( - distribution="Ubuntu-22.04", # your WSL distribution name you can find it by running 'wsl -l -v' in powershell. + distribution="Ubuntu-22.04", # your WSL distribution name. you can find it by running 'wsl -l -v' in powershell. user="username", # replace with your WSL user. - linux_workdir=r"\\wsl.localhost\Ubuntu-22.04\home\user\yourfolder" # replace with the name of a folder located in home/user in your WSL distribution. - # yourfolder is the wd for FSL commands. It will be created if it does not exist. + linux_workdir=r"\\wsl.localhost\Ubuntu-22.04\home\user\yourfolder" # replace with a path to a folder in your WSL distribution. + # yourfolder will be created if it does not exist. # All output files will be saved here. Corrected files from TOPUP and Eddy will be copied back to the patient folders in windows. - # The data will be organised into folders matching your main_dir structure, i.e. for each patient folder in main_dir, a corresponding folder is created in linux_workdir and all processing for that patient is done in that folder. - # Make sure to change this path between different runs so that you dont overwrite your data. :) + # linux_workdir will be organised into folders matching your main_dir structure, i.e. for each patient folder in main_dir, a corresponding folder is created in linux_workdir and all processing for that patient is done in that folder. ) From 75efef19269da807d780f72b6683eaef09d01c8a Mon Sep 17 00:00:00 2001 From: oonim Date: Wed, 1 Apr 2026 19:23:59 +0200 Subject: [PATCH 09/21] minor changes --- src/original/MG_LU/TOPED_fsl_commands.py | 26 +++++++++++------------- src/original/MG_LU/TOPED_fsl_runner.py | 18 ++++++++++------ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/original/MG_LU/TOPED_fsl_commands.py b/src/original/MG_LU/TOPED_fsl_commands.py index 94533698..28a330fe 100644 --- a/src/original/MG_LU/TOPED_fsl_commands.py +++ b/src/original/MG_LU/TOPED_fsl_commands.py @@ -98,8 +98,7 @@ def run_topup( if logout is not None: cmd += f"--logout={self.get_log_name(b0_basename)} " if dfout is not None: cmd += f"--dfout={self.get_warpfig_name(b0_basename)} " if jacout is not None: cmd += f"--jacout={self.get_jacobian_name(b0_basename)} " - if nthr is not None: - cmd += f"--nthr={nthr} " + if nthr is not None: cmd += f"--nthr={nthr} " cmd += config_arg # Run @@ -145,7 +144,7 @@ def run_eddy( ol_nstd: Optional[float] = None, ol_nvox: Optional[int] = None, ol_type: Optional[str] = None, - ol_ss: Optional[int] = None, + ol_ss: Optional[str] = None, ol_pos: Optional[bool] = None, ol_sqr: Optional[bool] = None, s2v_niter: Optional[int] = None, @@ -220,34 +219,33 @@ def run_eddy( if niter is not None: cmd += f"--niter={niter} " if interp is not None: cmd += f"--interp={interp} " if resamp is not None: cmd += f"--resamp={resamp} " - if fep is not None: cmd += f"--fep " + if fep: cmd += f"--fep " if nvoxhp is not None: cmd += f"--nvoxhp={nvoxhp} " if ff is not None: cmd += f"--ff={ff} " - if dont_sep_offs_move is not None: cmd += f"--dont_sep_offs_move " - if dont_peas is not None: cmd += f"--dont_peas " + if dont_sep_offs_move: cmd += f"--dont_sep_offs_move " + if dont_peas: cmd += f"--dont_peas " - if repol is not None: cmd += f"--repol " + if repol: cmd += f"--repol " if ol_nstd is not None: cmd += f"--ol_nstd={ol_nstd} " if ol_nvox is not None: cmd += f"--ol_nvox={ol_nvox} " if ol_type is not None: cmd += f"--ol_type={ol_type} " if ol_ss is not None: cmd += f"--ol_ss={ol_ss} " - if ol_pos is not None: cmd += f"--ol_pos " - if ol_sqr is not None: cmd += f"--ol_sqr " + if ol_pos: cmd += f"--ol_pos " + if ol_sqr: cmd += f"--ol_sqr " if mporder is not None: cmd += f"--mporder={mporder} " if s2v_niter is not None: cmd += f"--s2v_niter={s2v_niter} " if s2v_lambda is not None: cmd += f"--s2v_lambda={s2v_lambda} " if s2v_interp is not None: cmd += f"--s2v_interp={s2v_interp} " - if estimate_move_by_susceptibility is not None: - cmd += f"--estimate_move_by_susceptibility={int(estimate_move_by_susceptibility)} " + if estimate_move_by_susceptibility: cmd += f"--estimate_move_by_susceptibility " if mbs_niter is not None: cmd += f"--mbs_niter={mbs_niter} " if mbs_lambda is not None: cmd += f"--mbs_lambda={mbs_lambda} " if mbs_ksp is not None: cmd += f"--mbs_ksp={mbs_ksp} " - if cnr_maps is not None: cmd += f"--cnr_maps " - if residuals is not None: cmd += f"--residuals " - if data_is_shelled is not None: cmd += f"--data_is_shelled " + if cnr_maps: cmd += f"--cnr_maps " + if residuals: cmd += f"--residuals " + if data_is_shelled: cmd += f"--data_is_shelled " if nthr is not None: cmd += f"--nthr={nthr} " diff --git a/src/original/MG_LU/TOPED_fsl_runner.py b/src/original/MG_LU/TOPED_fsl_runner.py index 0e488ea8..80100f86 100644 --- a/src/original/MG_LU/TOPED_fsl_runner.py +++ b/src/original/MG_LU/TOPED_fsl_runner.py @@ -50,13 +50,13 @@ # │ └── ... (other patient-specific files) # └── common_files (optional) # ├── acqparams.txt -# ├── bvecs -# ├── bvals +# ├── bvecs.txt +# ├── bvals.txt # ├── index.txt # ├── slspec.txt # └── config.cnf -# Note: 'patient_1' etc. are examples and can be any suitable name. +# names of folders are arbitrary. # The names of these folders are copied into the linux working directory and are used to identify the respective entries. # a 'common_files' folder is optional. The purpose is is you e.g. have the same config file or acqparams/bvecs/bvals/index/slspec files for all patients. @@ -198,7 +198,13 @@ def resolve_file(patient_dir, common_dir, key): # main loops start HERE - runs TOPUP and Eddy for each patient folder in main_dir -common_dir = (os.path.join(MAIN_DIR, COMMON_FOLDER_NAME) if COMMON_FOLDER_NAME else None) +common_dir = None +if COMMON_FOLDER_NAME: + _common_path = os.path.join(MAIN_DIR, COMMON_FOLDER_NAME) + if os.path.isdir(_common_path): + common_dir = _common_path + else: + print("note: no common folder found -> checking compulsory files in remaining folders...") # Input file check - check all of main_dir, do the files exist for all patients? # this is so that you wont leeave this overnight and come back to some shit error that could have been prevented. @@ -224,7 +230,7 @@ def resolve_file(patient_dir, common_dir, key): # TOPUP compulsory inputs if not b0_path: issues.append("TOPUP: cannot find b0 file") - if not acqp_path: issues.append("TOPUP: cannot find acqisition parameters file") + if not acqp_path: issues.append("TOPUP: cannot find acquisition parameters file") # EDDY compulsory (only warn if b0 exists, i.e. TOPUP would run) if b0_path: @@ -247,7 +253,7 @@ def resolve_file(patient_dir, common_dir, key): "\n Consider renaming your files to contain the specified keyword or adjust the IDENTIFIERS dict accordingly. " \ "\n TOPUP/Eddy will run only for the 'OK' cases.") else: - print("\n File check passed — all patients have all compulosry inputs.") + print("\n File check passed — all patients have all compulsory inputs.") for patient in os.listdir(MAIN_DIR): From 3a6c9f9f6e430b31a7d38778903b72204ebe6782 Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 11:31:29 +0200 Subject: [PATCH 10/21] Added fitting and preprocessing folders in /src/original, and adjusted the imports in /standardized --- .../MRI-QAMPER_IVIM/.gitignore | 0 .../MRI-QAMPER_IVIM/IVIM_standard_bcin.m | 0 .../MRI-QAMPER_IVIM/README.md | 0 .../MRI-QAMPER_IVIM/avgRepeatBvalVols.m | 0 .../MRI-QAMPER_IVIM/bvalOrderFix.m | 0 .../MRI-QAMPER_IVIM/dataPrepDWI.m | 0 .../MRI-QAMPER_IVIM/demo_QAMPER_IVIM.m | 0 .../MRI-QAMPER_IVIM/getTestData.m | 0 .../MRI-QAMPER_IVIM/inpaint_nans.m | 0 .../MRI-QAMPER_IVIM/ivim_modeling_noise.m | 0 .../MRI-QAMPER_IVIM/qa_fitting/outputHNMPAResults.m | 0 .../MRI-QAMPER_IVIM/qa_fitting/qualityFit.m | 0 .../MRI-QAMPER_IVIM/qa_fitting/returnFeatures.log | 0 .../MRI-QAMPER_IVIM/qa_fitting/returnFeatures.m | 0 .../MRI-QAMPER_IVIM/qa_fitting/write_param_txt.m | 0 .../MRI-QAMPER_IVIM/runQAMPERBatch.m | 0 .../MRI-QAMPER_IVIM/run_QAMPER_IVIM.m | 0 .../MRI-QAMPER_IVIM/utils/Dir2Arr.m | 0 .../MRI-QAMPER_IVIM/utils/arr2map2.m | 0 .../MRI-QAMPER_IVIM/utils/deb.m | 0 .../MRI-QAMPER_IVIM/utils/flipCheck.m | 0 .../MRI-QAMPER_IVIM/utils/map2arr.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/FAQ.pdf | Bin .../utils/nifti_toolbox/NIfTI_tools.pdf | Bin .../utils/nifti_toolbox/UseANALYZE.pdf | Bin .../MRI-QAMPER_IVIM/utils/nifti_toolbox/affine.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/bipolar.m | 0 .../utils/nifti_toolbox/bresenham_line3d.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/clip_nii.m | 0 .../utils/nifti_toolbox/collapse_nii_scan.m | 0 .../utils/nifti_toolbox/collapse_nii_scan2.m | 0 .../utils/nifti_toolbox/examples.txt | 0 .../utils/nifti_toolbox/expand_nii_scan.m | 0 .../utils/nifti_toolbox/extra_nii_hdr.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/flip_lr.m | 0 .../utils/nifti_toolbox/get_nii_frame.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/license.txt | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii.m | 0 .../utils/nifti_toolbox/load_nii_ext.m | 0 .../utils/nifti_toolbox/load_nii_hdr.m | 0 .../utils/nifti_toolbox/load_nii_img.m | 0 .../utils/nifti_toolbox/load_untouch0_nii_hdr.m | 0 .../utils/nifti_toolbox/load_untouch_header_only.m | 0 .../utils/nifti_toolbox/load_untouch_nii.m | 0 .../utils/nifti_toolbox/load_untouch_nii_hdr.m | 0 .../utils/nifti_toolbox/load_untouch_nii_img.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/make_ana.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/make_nii.m | 0 .../utils/nifti_toolbox/mat_into_hdr.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/pad_nii.m | 0 .../utils/nifti_toolbox/reslice_nii.m | 0 .../utils/nifti_toolbox/rri_file_menu.m | 0 .../utils/nifti_toolbox/rri_orient.m | 0 .../utils/nifti_toolbox/rri_orient_ui.m | 0 .../utils/nifti_toolbox/rri_select_file.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_xhair.m | 0 .../utils/nifti_toolbox/rri_zoom_menu.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii.m | 0 .../utils/nifti_toolbox/save_nii_ext.m | 0 .../utils/nifti_toolbox/save_nii_hdr.m | 0 .../utils/nifti_toolbox/save_untouch0_nii_hdr.m | 0 .../utils/nifti_toolbox/save_untouch_header_only.m | 0 .../utils/nifti_toolbox/save_untouch_nii.m | 0 .../utils/nifti_toolbox/save_untouch_nii_hdr.m | 0 .../utils/nifti_toolbox/save_untouch_slice.m | 0 .../utils/nifti_toolbox/unxform_nii.m | 0 .../utils/nifti_toolbox/verify_nii_ext.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii.m | 0 .../utils/nifti_toolbox/view_nii_menu.m | 0 .../MRI-QAMPER_IVIM/utils/nifti_toolbox/xform_nii.m | 0 .../MRI-QAMPER_IVIM/utils/nii_load.m | 0 .../MRI-QAMPER_IVIM/utils/nii_save.m | 0 .../ASD_MemorialSloanKettering}/__init__.py | 0 .../DK_OGC_AmsterdamUMC}/__init__.py | 0 .../DK_OGC_AmsterdamUMC/utils}/__init__.py | 0 .../utils/data_loading}/__init__.py | 0 .../utils/data_loading/load_ivim_subject.py | 0 .../utils/data_processing}/__init__.py | 0 .../processors/AverageSignalsOfEqualXvals.py | 0 .../data_processing/processors/FlattenImageData.py | 0 .../processors/NormalizeMaxSignal.py | 0 .../data_processing/processors/NormalizeSignals.py | 0 .../data_processing/processors/NormalizeXvals.py | 0 .../data_processing/processors/SignalCuration.py | 0 .../utils/data_processing/processors/SignalMask.py | 0 .../data_processing/processors/SortSignalOnXval.py | 0 .../utils/data_processing/processors}/__init__.py | 0 src/original/{ => fitting}/ETP_SRI/LinearFitting.py | 0 src/original/fitting/ETP_SRI/__init__.py | 0 src/original/fitting/IAR_LundUniversity/__init__.py | 0 .../IAR_LundUniversity/ivim_fit_method_biexp.py | 0 .../IAR_LundUniversity/ivim_fit_method_linear.py | 0 .../ivim_fit_method_modified_mix.py | 0 .../ivim_fit_method_modified_topopro.py | 0 .../ivim_fit_method_segmented_2step.py | 0 .../ivim_fit_method_segmented_3step.py | 0 .../IAR_LundUniversity/ivim_fit_method_sivim.py | 0 .../ivim_fit_method_subtracted.py | 0 .../OGC_AUMC_IVIMNET/Example_1_simple_map.py | 0 .../OGC_AUMC_IVIMNET/Example_2_simulations.py | 0 .../OGC_AUMC_IVIMNET/Example_3_volunteer.py | 0 src/original/fitting/OGC_AUMC_IVIMNET/__init__.py | 0 .../{ => fitting}/OGC_AUMC_IVIMNET/hyperparams.py | 0 .../{ => fitting}/OGC_AmsterdamUMC/LSQ_fitting.py | 0 src/original/fitting/OGC_AmsterdamUMC/__init__.py | 0 src/original/{ => fitting}/OJ_GU/IVIM_bayes.m | 0 src/original/{ => fitting}/OJ_GU/IVIM_seg.m | 0 src/original/fitting/OJ_GU/__init__.py | 0 src/original/{ => fitting}/OJ_GU/info.json | 0 src/original/{ => fitting}/OJ_GU/ivim_seg.py | 0 src/original/fitting/PV_MUMC/__init__.py | 0 .../PV_MUMC/triexp_fitting_algorithms.py | 0 .../{ => fitting}/PV_MUMC/two_step_IVIM_fit.py | 0 .../{ => fitting}/PvH_KB_NKI/DWI_Examples.py | 0 .../PvH_KB_NKI/DWI_functions_standalone.py | 0 src/original/fitting/PvH_KB_NKI/__init__.py | 0 .../TCML_TechnionIIT/SUPER-IVIM-DC/README.md | 0 .../TCML_TechnionIIT/SUPER-IVIM-DC/sample.ipynb | 0 src/original/fitting/TCML_TechnionIIT/__init__.py | 0 src/original/fitting/TF_reference/__init__.py | 0 .../{ => fitting}/TF_reference/segmented_IVIMfit.py | 0 src/original/fitting/__init__.py | 0 src/original/preprocessing/EP_GU/__init__.py | 0 .../{ => preprocessing}/EP_GU/brain_pipeline.py | 0 src/original/{ => preprocessing}/EP_GU/info.json | 0 .../{ => preprocessing}/EP_GU/outlier_removal.py | 0 .../{ => preprocessing}/MG_LU/TOPED_fsl_commands.py | 0 .../{ => preprocessing}/MG_LU/TOPED_fsl_runner.py | 0 src/original/preprocessing/MG_LU/__init__.py | 0 src/original/preprocessing/__init__.py | 0 src/standardized wip/IAR_LU_linear.py | 2 +- src/standardized/ETP_SRI_LinearFitting.py | 2 +- src/standardized/IAR_LU_biexp.py | 2 +- src/standardized/IAR_LU_modified_mix.py | 2 +- src/standardized/IAR_LU_modified_topopro.py | 2 +- src/standardized/IAR_LU_segmented_2step.py | 2 +- src/standardized/IAR_LU_segmented_3step.py | 2 +- src/standardized/IAR_LU_subtracted.py | 2 +- src/standardized/OGC_AmsterdamUMC_Bayesian_biexp.py | 2 +- src/standardized/OGC_AmsterdamUMC_biexp.py | 2 +- .../OGC_AmsterdamUMC_biexp_segmented.py | 2 +- src/standardized/OJ_GU_seg.py | 2 +- src/standardized/PV_MUMC_biexp.py | 2 +- src/standardized/PvH_KB_NKI_IVIMfit.py | 2 +- src/standardized/TF_reference_IVIMfit.py | 2 +- src/wrappers/ivim_fit.py | 2 +- tests/IVIMpreproc/unit_tests/test_denoise.py | 2 +- 147 files changed, 17 insertions(+), 17 deletions(-) rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/.gitignore (100%) rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/IVIM_standard_bcin.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/README.md (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/avgRepeatBvalVols.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/bvalOrderFix.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/dataPrepDWI.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/demo_QAMPER_IVIM.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/getTestData.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/inpaint_nans.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/ivim_modeling_noise.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/outputHNMPAResults.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/qualityFit.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.log (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/write_param_txt.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/runQAMPERBatch.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/run_QAMPER_IVIM.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/Dir2Arr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/arr2map2.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/deb.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/flipCheck.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/map2arr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/FAQ.pdf (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/NIfTI_tools.pdf (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/UseANALYZE.pdf (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/affine.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bipolar.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bresenham_line3d.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/clip_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan2.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/examples.txt (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/expand_nii_scan.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/extra_nii_hdr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/flip_lr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/get_nii_frame.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/license.txt (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_ext.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_hdr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_img.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch0_nii_hdr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_header_only.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_hdr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_img.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_ana.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/mat_into_hdr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/pad_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/reslice_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_file_menu.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient_ui.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_select_file.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_xhair.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_zoom_menu.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_ext.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_hdr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch0_nii_hdr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_header_only.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii_hdr.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_slice.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/unxform_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/verify_nii_ext.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii_menu.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/xform_nii.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_load.m (100%) mode change 100755 => 100644 rename src/original/{ => fitting}/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_save.m (100%) mode change 100755 => 100644 rename src/original/{DK_OGC_AmsterdamUMC => fitting/ASD_MemorialSloanKettering}/__init__.py (100%) rename src/original/{DK_OGC_AmsterdamUMC/utils => fitting/DK_OGC_AmsterdamUMC}/__init__.py (100%) rename src/original/{DK_OGC_AmsterdamUMC/utils/data_loading => fitting/DK_OGC_AmsterdamUMC/utils}/__init__.py (100%) rename src/original/{DK_OGC_AmsterdamUMC/utils/data_processing => fitting/DK_OGC_AmsterdamUMC/utils/data_loading}/__init__.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_loading/load_ivim_subject.py (100%) rename src/original/{DK_OGC_AmsterdamUMC/utils/data_processing/processors => fitting/DK_OGC_AmsterdamUMC/utils/data_processing}/__init__.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_processing/processors/AverageSignalsOfEqualXvals.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_processing/processors/FlattenImageData.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeMaxSignal.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeSignals.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeXvals.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalCuration.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalMask.py (100%) rename src/original/{ => fitting}/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SortSignalOnXval.py (100%) rename src/original/{ETP_SRI => fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors}/__init__.py (100%) rename src/original/{ => fitting}/ETP_SRI/LinearFitting.py (100%) create mode 100644 src/original/fitting/ETP_SRI/__init__.py create mode 100644 src/original/fitting/IAR_LundUniversity/__init__.py rename src/original/{ => fitting}/IAR_LundUniversity/ivim_fit_method_biexp.py (100%) rename src/original/{ => fitting}/IAR_LundUniversity/ivim_fit_method_linear.py (100%) rename src/original/{ => fitting}/IAR_LundUniversity/ivim_fit_method_modified_mix.py (100%) rename src/original/{ => fitting}/IAR_LundUniversity/ivim_fit_method_modified_topopro.py (100%) rename src/original/{ => fitting}/IAR_LundUniversity/ivim_fit_method_segmented_2step.py (100%) rename src/original/{ => fitting}/IAR_LundUniversity/ivim_fit_method_segmented_3step.py (100%) rename src/original/{ => fitting}/IAR_LundUniversity/ivim_fit_method_sivim.py (100%) rename src/original/{ => fitting}/IAR_LundUniversity/ivim_fit_method_subtracted.py (100%) rename src/original/{ => fitting}/OGC_AUMC_IVIMNET/Example_1_simple_map.py (100%) rename src/original/{ => fitting}/OGC_AUMC_IVIMNET/Example_2_simulations.py (100%) rename src/original/{ => fitting}/OGC_AUMC_IVIMNET/Example_3_volunteer.py (100%) create mode 100644 src/original/fitting/OGC_AUMC_IVIMNET/__init__.py rename src/original/{ => fitting}/OGC_AUMC_IVIMNET/hyperparams.py (100%) rename src/original/{ => fitting}/OGC_AmsterdamUMC/LSQ_fitting.py (100%) create mode 100644 src/original/fitting/OGC_AmsterdamUMC/__init__.py rename src/original/{ => fitting}/OJ_GU/IVIM_bayes.m (100%) rename src/original/{ => fitting}/OJ_GU/IVIM_seg.m (100%) create mode 100644 src/original/fitting/OJ_GU/__init__.py rename src/original/{ => fitting}/OJ_GU/info.json (100%) rename src/original/{ => fitting}/OJ_GU/ivim_seg.py (100%) create mode 100644 src/original/fitting/PV_MUMC/__init__.py rename src/original/{ => fitting}/PV_MUMC/triexp_fitting_algorithms.py (100%) rename src/original/{ => fitting}/PV_MUMC/two_step_IVIM_fit.py (100%) rename src/original/{ => fitting}/PvH_KB_NKI/DWI_Examples.py (100%) rename src/original/{ => fitting}/PvH_KB_NKI/DWI_functions_standalone.py (100%) create mode 100644 src/original/fitting/PvH_KB_NKI/__init__.py rename src/original/{ => fitting}/TCML_TechnionIIT/SUPER-IVIM-DC/README.md (100%) rename src/original/{ => fitting}/TCML_TechnionIIT/SUPER-IVIM-DC/sample.ipynb (100%) create mode 100644 src/original/fitting/TCML_TechnionIIT/__init__.py create mode 100644 src/original/fitting/TF_reference/__init__.py rename src/original/{ => fitting}/TF_reference/segmented_IVIMfit.py (100%) create mode 100644 src/original/fitting/__init__.py create mode 100644 src/original/preprocessing/EP_GU/__init__.py rename src/original/{ => preprocessing}/EP_GU/brain_pipeline.py (100%) rename src/original/{ => preprocessing}/EP_GU/info.json (100%) rename src/original/{ => preprocessing}/EP_GU/outlier_removal.py (100%) rename src/original/{ => preprocessing}/MG_LU/TOPED_fsl_commands.py (100%) rename src/original/{ => preprocessing}/MG_LU/TOPED_fsl_runner.py (100%) create mode 100644 src/original/preprocessing/MG_LU/__init__.py create mode 100644 src/original/preprocessing/__init__.py diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/.gitignore b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/.gitignore similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/.gitignore rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/.gitignore diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/IVIM_standard_bcin.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/IVIM_standard_bcin.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/IVIM_standard_bcin.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/IVIM_standard_bcin.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/README.md b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/README.md old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/README.md rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/README.md diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/avgRepeatBvalVols.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/avgRepeatBvalVols.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/avgRepeatBvalVols.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/avgRepeatBvalVols.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/bvalOrderFix.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/bvalOrderFix.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/bvalOrderFix.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/bvalOrderFix.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/dataPrepDWI.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/dataPrepDWI.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/dataPrepDWI.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/dataPrepDWI.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/demo_QAMPER_IVIM.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/demo_QAMPER_IVIM.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/demo_QAMPER_IVIM.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/demo_QAMPER_IVIM.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/getTestData.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/getTestData.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/getTestData.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/getTestData.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/inpaint_nans.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/inpaint_nans.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/inpaint_nans.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/inpaint_nans.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/ivim_modeling_noise.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/ivim_modeling_noise.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/ivim_modeling_noise.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/ivim_modeling_noise.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/outputHNMPAResults.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/outputHNMPAResults.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/outputHNMPAResults.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/outputHNMPAResults.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/qualityFit.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/qualityFit.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/qualityFit.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/qualityFit.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.log b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.log old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.log rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.log diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/returnFeatures.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/write_param_txt.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/write_param_txt.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/write_param_txt.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/qa_fitting/write_param_txt.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/runQAMPERBatch.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/runQAMPERBatch.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/runQAMPERBatch.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/runQAMPERBatch.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/run_QAMPER_IVIM.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/run_QAMPER_IVIM.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/run_QAMPER_IVIM.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/run_QAMPER_IVIM.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/Dir2Arr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/Dir2Arr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/Dir2Arr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/Dir2Arr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/arr2map2.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/arr2map2.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/arr2map2.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/arr2map2.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/deb.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/deb.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/deb.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/deb.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/flipCheck.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/flipCheck.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/flipCheck.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/flipCheck.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/map2arr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/map2arr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/map2arr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/map2arr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/FAQ.pdf b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/FAQ.pdf old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/FAQ.pdf rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/FAQ.pdf diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/NIfTI_tools.pdf b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/NIfTI_tools.pdf old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/NIfTI_tools.pdf rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/NIfTI_tools.pdf diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/UseANALYZE.pdf b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/UseANALYZE.pdf old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/UseANALYZE.pdf rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/UseANALYZE.pdf diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/affine.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/affine.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/affine.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/affine.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bipolar.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bipolar.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bipolar.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bipolar.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bresenham_line3d.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bresenham_line3d.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bresenham_line3d.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/bresenham_line3d.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/clip_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/clip_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/clip_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/clip_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan2.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan2.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan2.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/collapse_nii_scan2.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/examples.txt b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/examples.txt old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/examples.txt rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/examples.txt diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/expand_nii_scan.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/expand_nii_scan.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/expand_nii_scan.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/expand_nii_scan.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/extra_nii_hdr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/extra_nii_hdr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/extra_nii_hdr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/extra_nii_hdr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/flip_lr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/flip_lr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/flip_lr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/flip_lr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/get_nii_frame.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/get_nii_frame.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/get_nii_frame.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/get_nii_frame.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/license.txt b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/license.txt old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/license.txt rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/license.txt diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_ext.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_ext.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_ext.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_ext.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_hdr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_hdr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_hdr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_hdr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_img.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_img.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_img.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_nii_img.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch0_nii_hdr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch0_nii_hdr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch0_nii_hdr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch0_nii_hdr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_header_only.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_header_only.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_header_only.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_header_only.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_hdr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_hdr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_hdr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_hdr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_img.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_img.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_img.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/load_untouch_nii_img.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_ana.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_ana.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_ana.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_ana.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/make_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/mat_into_hdr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/mat_into_hdr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/mat_into_hdr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/mat_into_hdr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/pad_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/pad_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/pad_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/pad_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/reslice_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/reslice_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/reslice_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/reslice_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_file_menu.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_file_menu.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_file_menu.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_file_menu.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient_ui.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient_ui.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient_ui.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_orient_ui.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_select_file.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_select_file.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_select_file.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_select_file.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_xhair.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_xhair.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_xhair.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_xhair.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_zoom_menu.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_zoom_menu.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_zoom_menu.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/rri_zoom_menu.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_ext.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_ext.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_ext.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_ext.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_hdr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_hdr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_hdr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_nii_hdr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch0_nii_hdr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch0_nii_hdr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch0_nii_hdr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch0_nii_hdr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_header_only.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_header_only.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_header_only.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_header_only.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii_hdr.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii_hdr.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii_hdr.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_nii_hdr.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_slice.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_slice.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_slice.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/save_untouch_slice.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/unxform_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/unxform_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/unxform_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/unxform_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/verify_nii_ext.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/verify_nii_ext.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/verify_nii_ext.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/verify_nii_ext.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii_menu.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii_menu.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii_menu.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/view_nii_menu.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/xform_nii.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/xform_nii.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/xform_nii.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nifti_toolbox/xform_nii.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_load.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_load.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_load.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_load.m diff --git a/src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_save.m b/src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_save.m old mode 100755 new mode 100644 similarity index 100% rename from src/original/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_save.m rename to src/original/fitting/ASD_MemorialSloanKettering/MRI-QAMPER_IVIM/utils/nii_save.m diff --git a/src/original/DK_OGC_AmsterdamUMC/__init__.py b/src/original/fitting/ASD_MemorialSloanKettering/__init__.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/__init__.py rename to src/original/fitting/ASD_MemorialSloanKettering/__init__.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/__init__.py b/src/original/fitting/DK_OGC_AmsterdamUMC/__init__.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/__init__.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/__init__.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_loading/__init__.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/__init__.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_loading/__init__.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/__init__.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/__init__.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_loading/__init__.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/__init__.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_loading/__init__.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_loading/load_ivim_subject.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_loading/load_ivim_subject.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_loading/load_ivim_subject.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_loading/load_ivim_subject.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/__init__.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/__init__.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/__init__.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/__init__.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/AverageSignalsOfEqualXvals.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/AverageSignalsOfEqualXvals.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/AverageSignalsOfEqualXvals.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/AverageSignalsOfEqualXvals.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/FlattenImageData.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/FlattenImageData.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/FlattenImageData.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/FlattenImageData.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeMaxSignal.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeMaxSignal.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeMaxSignal.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeMaxSignal.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeSignals.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeSignals.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeSignals.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeSignals.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeXvals.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeXvals.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeXvals.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/NormalizeXvals.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalCuration.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalCuration.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalCuration.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalCuration.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalMask.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalMask.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalMask.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SignalMask.py diff --git a/src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SortSignalOnXval.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SortSignalOnXval.py similarity index 100% rename from src/original/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SortSignalOnXval.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/SortSignalOnXval.py diff --git a/src/original/ETP_SRI/__init__.py b/src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/__init__.py similarity index 100% rename from src/original/ETP_SRI/__init__.py rename to src/original/fitting/DK_OGC_AmsterdamUMC/utils/data_processing/processors/__init__.py diff --git a/src/original/ETP_SRI/LinearFitting.py b/src/original/fitting/ETP_SRI/LinearFitting.py similarity index 100% rename from src/original/ETP_SRI/LinearFitting.py rename to src/original/fitting/ETP_SRI/LinearFitting.py diff --git a/src/original/fitting/ETP_SRI/__init__.py b/src/original/fitting/ETP_SRI/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/fitting/IAR_LundUniversity/__init__.py b/src/original/fitting/IAR_LundUniversity/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/IAR_LundUniversity/ivim_fit_method_biexp.py b/src/original/fitting/IAR_LundUniversity/ivim_fit_method_biexp.py similarity index 100% rename from src/original/IAR_LundUniversity/ivim_fit_method_biexp.py rename to src/original/fitting/IAR_LundUniversity/ivim_fit_method_biexp.py diff --git a/src/original/IAR_LundUniversity/ivim_fit_method_linear.py b/src/original/fitting/IAR_LundUniversity/ivim_fit_method_linear.py similarity index 100% rename from src/original/IAR_LundUniversity/ivim_fit_method_linear.py rename to src/original/fitting/IAR_LundUniversity/ivim_fit_method_linear.py diff --git a/src/original/IAR_LundUniversity/ivim_fit_method_modified_mix.py b/src/original/fitting/IAR_LundUniversity/ivim_fit_method_modified_mix.py similarity index 100% rename from src/original/IAR_LundUniversity/ivim_fit_method_modified_mix.py rename to src/original/fitting/IAR_LundUniversity/ivim_fit_method_modified_mix.py diff --git a/src/original/IAR_LundUniversity/ivim_fit_method_modified_topopro.py b/src/original/fitting/IAR_LundUniversity/ivim_fit_method_modified_topopro.py similarity index 100% rename from src/original/IAR_LundUniversity/ivim_fit_method_modified_topopro.py rename to src/original/fitting/IAR_LundUniversity/ivim_fit_method_modified_topopro.py diff --git a/src/original/IAR_LundUniversity/ivim_fit_method_segmented_2step.py b/src/original/fitting/IAR_LundUniversity/ivim_fit_method_segmented_2step.py similarity index 100% rename from src/original/IAR_LundUniversity/ivim_fit_method_segmented_2step.py rename to src/original/fitting/IAR_LundUniversity/ivim_fit_method_segmented_2step.py diff --git a/src/original/IAR_LundUniversity/ivim_fit_method_segmented_3step.py b/src/original/fitting/IAR_LundUniversity/ivim_fit_method_segmented_3step.py similarity index 100% rename from src/original/IAR_LundUniversity/ivim_fit_method_segmented_3step.py rename to src/original/fitting/IAR_LundUniversity/ivim_fit_method_segmented_3step.py diff --git a/src/original/IAR_LundUniversity/ivim_fit_method_sivim.py b/src/original/fitting/IAR_LundUniversity/ivim_fit_method_sivim.py similarity index 100% rename from src/original/IAR_LundUniversity/ivim_fit_method_sivim.py rename to src/original/fitting/IAR_LundUniversity/ivim_fit_method_sivim.py diff --git a/src/original/IAR_LundUniversity/ivim_fit_method_subtracted.py b/src/original/fitting/IAR_LundUniversity/ivim_fit_method_subtracted.py similarity index 100% rename from src/original/IAR_LundUniversity/ivim_fit_method_subtracted.py rename to src/original/fitting/IAR_LundUniversity/ivim_fit_method_subtracted.py diff --git a/src/original/OGC_AUMC_IVIMNET/Example_1_simple_map.py b/src/original/fitting/OGC_AUMC_IVIMNET/Example_1_simple_map.py similarity index 100% rename from src/original/OGC_AUMC_IVIMNET/Example_1_simple_map.py rename to src/original/fitting/OGC_AUMC_IVIMNET/Example_1_simple_map.py diff --git a/src/original/OGC_AUMC_IVIMNET/Example_2_simulations.py b/src/original/fitting/OGC_AUMC_IVIMNET/Example_2_simulations.py similarity index 100% rename from src/original/OGC_AUMC_IVIMNET/Example_2_simulations.py rename to src/original/fitting/OGC_AUMC_IVIMNET/Example_2_simulations.py diff --git a/src/original/OGC_AUMC_IVIMNET/Example_3_volunteer.py b/src/original/fitting/OGC_AUMC_IVIMNET/Example_3_volunteer.py similarity index 100% rename from src/original/OGC_AUMC_IVIMNET/Example_3_volunteer.py rename to src/original/fitting/OGC_AUMC_IVIMNET/Example_3_volunteer.py diff --git a/src/original/fitting/OGC_AUMC_IVIMNET/__init__.py b/src/original/fitting/OGC_AUMC_IVIMNET/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/OGC_AUMC_IVIMNET/hyperparams.py b/src/original/fitting/OGC_AUMC_IVIMNET/hyperparams.py similarity index 100% rename from src/original/OGC_AUMC_IVIMNET/hyperparams.py rename to src/original/fitting/OGC_AUMC_IVIMNET/hyperparams.py diff --git a/src/original/OGC_AmsterdamUMC/LSQ_fitting.py b/src/original/fitting/OGC_AmsterdamUMC/LSQ_fitting.py similarity index 100% rename from src/original/OGC_AmsterdamUMC/LSQ_fitting.py rename to src/original/fitting/OGC_AmsterdamUMC/LSQ_fitting.py diff --git a/src/original/fitting/OGC_AmsterdamUMC/__init__.py b/src/original/fitting/OGC_AmsterdamUMC/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/OJ_GU/IVIM_bayes.m b/src/original/fitting/OJ_GU/IVIM_bayes.m similarity index 100% rename from src/original/OJ_GU/IVIM_bayes.m rename to src/original/fitting/OJ_GU/IVIM_bayes.m diff --git a/src/original/OJ_GU/IVIM_seg.m b/src/original/fitting/OJ_GU/IVIM_seg.m similarity index 100% rename from src/original/OJ_GU/IVIM_seg.m rename to src/original/fitting/OJ_GU/IVIM_seg.m diff --git a/src/original/fitting/OJ_GU/__init__.py b/src/original/fitting/OJ_GU/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/OJ_GU/info.json b/src/original/fitting/OJ_GU/info.json similarity index 100% rename from src/original/OJ_GU/info.json rename to src/original/fitting/OJ_GU/info.json diff --git a/src/original/OJ_GU/ivim_seg.py b/src/original/fitting/OJ_GU/ivim_seg.py similarity index 100% rename from src/original/OJ_GU/ivim_seg.py rename to src/original/fitting/OJ_GU/ivim_seg.py diff --git a/src/original/fitting/PV_MUMC/__init__.py b/src/original/fitting/PV_MUMC/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/PV_MUMC/triexp_fitting_algorithms.py b/src/original/fitting/PV_MUMC/triexp_fitting_algorithms.py similarity index 100% rename from src/original/PV_MUMC/triexp_fitting_algorithms.py rename to src/original/fitting/PV_MUMC/triexp_fitting_algorithms.py diff --git a/src/original/PV_MUMC/two_step_IVIM_fit.py b/src/original/fitting/PV_MUMC/two_step_IVIM_fit.py similarity index 100% rename from src/original/PV_MUMC/two_step_IVIM_fit.py rename to src/original/fitting/PV_MUMC/two_step_IVIM_fit.py diff --git a/src/original/PvH_KB_NKI/DWI_Examples.py b/src/original/fitting/PvH_KB_NKI/DWI_Examples.py similarity index 100% rename from src/original/PvH_KB_NKI/DWI_Examples.py rename to src/original/fitting/PvH_KB_NKI/DWI_Examples.py diff --git a/src/original/PvH_KB_NKI/DWI_functions_standalone.py b/src/original/fitting/PvH_KB_NKI/DWI_functions_standalone.py similarity index 100% rename from src/original/PvH_KB_NKI/DWI_functions_standalone.py rename to src/original/fitting/PvH_KB_NKI/DWI_functions_standalone.py diff --git a/src/original/fitting/PvH_KB_NKI/__init__.py b/src/original/fitting/PvH_KB_NKI/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/TCML_TechnionIIT/SUPER-IVIM-DC/README.md b/src/original/fitting/TCML_TechnionIIT/SUPER-IVIM-DC/README.md similarity index 100% rename from src/original/TCML_TechnionIIT/SUPER-IVIM-DC/README.md rename to src/original/fitting/TCML_TechnionIIT/SUPER-IVIM-DC/README.md diff --git a/src/original/TCML_TechnionIIT/SUPER-IVIM-DC/sample.ipynb b/src/original/fitting/TCML_TechnionIIT/SUPER-IVIM-DC/sample.ipynb similarity index 100% rename from src/original/TCML_TechnionIIT/SUPER-IVIM-DC/sample.ipynb rename to src/original/fitting/TCML_TechnionIIT/SUPER-IVIM-DC/sample.ipynb diff --git a/src/original/fitting/TCML_TechnionIIT/__init__.py b/src/original/fitting/TCML_TechnionIIT/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/fitting/TF_reference/__init__.py b/src/original/fitting/TF_reference/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/TF_reference/segmented_IVIMfit.py b/src/original/fitting/TF_reference/segmented_IVIMfit.py similarity index 100% rename from src/original/TF_reference/segmented_IVIMfit.py rename to src/original/fitting/TF_reference/segmented_IVIMfit.py diff --git a/src/original/fitting/__init__.py b/src/original/fitting/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/preprocessing/EP_GU/__init__.py b/src/original/preprocessing/EP_GU/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/EP_GU/brain_pipeline.py b/src/original/preprocessing/EP_GU/brain_pipeline.py similarity index 100% rename from src/original/EP_GU/brain_pipeline.py rename to src/original/preprocessing/EP_GU/brain_pipeline.py diff --git a/src/original/EP_GU/info.json b/src/original/preprocessing/EP_GU/info.json similarity index 100% rename from src/original/EP_GU/info.json rename to src/original/preprocessing/EP_GU/info.json diff --git a/src/original/EP_GU/outlier_removal.py b/src/original/preprocessing/EP_GU/outlier_removal.py similarity index 100% rename from src/original/EP_GU/outlier_removal.py rename to src/original/preprocessing/EP_GU/outlier_removal.py diff --git a/src/original/MG_LU/TOPED_fsl_commands.py b/src/original/preprocessing/MG_LU/TOPED_fsl_commands.py similarity index 100% rename from src/original/MG_LU/TOPED_fsl_commands.py rename to src/original/preprocessing/MG_LU/TOPED_fsl_commands.py diff --git a/src/original/MG_LU/TOPED_fsl_runner.py b/src/original/preprocessing/MG_LU/TOPED_fsl_runner.py similarity index 100% rename from src/original/MG_LU/TOPED_fsl_runner.py rename to src/original/preprocessing/MG_LU/TOPED_fsl_runner.py diff --git a/src/original/preprocessing/MG_LU/__init__.py b/src/original/preprocessing/MG_LU/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/original/preprocessing/__init__.py b/src/original/preprocessing/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/standardized wip/IAR_LU_linear.py b/src/standardized wip/IAR_LU_linear.py index 7ff310d0..928024b8 100644 --- a/src/standardized wip/IAR_LU_linear.py +++ b/src/standardized wip/IAR_LU_linear.py @@ -1,7 +1,7 @@ import numpy as np from dipy.core.gradients import gradient_table from src.wrappers.OsipiBase import OsipiBase -from src.original.IAR_LundUniversity.ivim_fit_method_linear import IvimModelLinear +from src.original.fitting.IAR_LundUniversity.ivim_fit_method_linear import IvimModelLinear class IAR_LU_linear(OsipiBase): diff --git a/src/standardized/ETP_SRI_LinearFitting.py b/src/standardized/ETP_SRI_LinearFitting.py index f219ff16..981ec2b8 100644 --- a/src/standardized/ETP_SRI_LinearFitting.py +++ b/src/standardized/ETP_SRI_LinearFitting.py @@ -1,6 +1,6 @@ import numpy as np from src.wrappers.OsipiBase import OsipiBase -from src.original.ETP_SRI.LinearFitting import LinearFit +from src.original.fitting.ETP_SRI.LinearFitting import LinearFit import warnings warnings.simplefilter('once', UserWarning) diff --git a/src/standardized/IAR_LU_biexp.py b/src/standardized/IAR_LU_biexp.py index ff54311c..36c29702 100644 --- a/src/standardized/IAR_LU_biexp.py +++ b/src/standardized/IAR_LU_biexp.py @@ -1,7 +1,7 @@ import numpy as np from dipy.core.gradients import gradient_table from src.wrappers.OsipiBase import OsipiBase -from src.original.IAR_LundUniversity.ivim_fit_method_biexp import IvimModelBiExp +from src.original.fitting.IAR_LundUniversity.ivim_fit_method_biexp import IvimModelBiExp class IAR_LU_biexp(OsipiBase): diff --git a/src/standardized/IAR_LU_modified_mix.py b/src/standardized/IAR_LU_modified_mix.py index 5ff5c9aa..bf644995 100644 --- a/src/standardized/IAR_LU_modified_mix.py +++ b/src/standardized/IAR_LU_modified_mix.py @@ -1,7 +1,7 @@ import numpy as np from dipy.core.gradients import gradient_table from src.wrappers.OsipiBase import OsipiBase -from src.original.IAR_LundUniversity.ivim_fit_method_modified_mix import IvimModelVP +from src.original.fitting.IAR_LundUniversity.ivim_fit_method_modified_mix import IvimModelVP class IAR_LU_modified_mix(OsipiBase): diff --git a/src/standardized/IAR_LU_modified_topopro.py b/src/standardized/IAR_LU_modified_topopro.py index bf8b582f..05cfb8f2 100644 --- a/src/standardized/IAR_LU_modified_topopro.py +++ b/src/standardized/IAR_LU_modified_topopro.py @@ -1,7 +1,7 @@ import numpy as np from dipy.core.gradients import gradient_table from src.wrappers.OsipiBase import OsipiBase -from src.original.IAR_LundUniversity.ivim_fit_method_modified_topopro import IvimModelTopoPro +from src.original.fitting.IAR_LundUniversity.ivim_fit_method_modified_topopro import IvimModelTopoPro class IAR_LU_modified_topopro(OsipiBase): diff --git a/src/standardized/IAR_LU_segmented_2step.py b/src/standardized/IAR_LU_segmented_2step.py index c5be9b45..3b281cbd 100644 --- a/src/standardized/IAR_LU_segmented_2step.py +++ b/src/standardized/IAR_LU_segmented_2step.py @@ -1,7 +1,7 @@ import numpy as np from dipy.core.gradients import gradient_table from src.wrappers.OsipiBase import OsipiBase -from src.original.IAR_LundUniversity.ivim_fit_method_segmented_2step import IvimModelSegmented2Step +from src.original.fitting.IAR_LundUniversity.ivim_fit_method_segmented_2step import IvimModelSegmented2Step class IAR_LU_segmented_2step(OsipiBase): diff --git a/src/standardized/IAR_LU_segmented_3step.py b/src/standardized/IAR_LU_segmented_3step.py index 73aeb42b..f5b5c6a7 100644 --- a/src/standardized/IAR_LU_segmented_3step.py +++ b/src/standardized/IAR_LU_segmented_3step.py @@ -1,7 +1,7 @@ import numpy as np from dipy.core.gradients import gradient_table from src.wrappers.OsipiBase import OsipiBase -from src.original.IAR_LundUniversity.ivim_fit_method_segmented_3step import IvimModelSegmented3Step +from src.original.fitting.IAR_LundUniversity.ivim_fit_method_segmented_3step import IvimModelSegmented3Step class IAR_LU_segmented_3step(OsipiBase): diff --git a/src/standardized/IAR_LU_subtracted.py b/src/standardized/IAR_LU_subtracted.py index abd38d63..88729506 100644 --- a/src/standardized/IAR_LU_subtracted.py +++ b/src/standardized/IAR_LU_subtracted.py @@ -1,7 +1,7 @@ import numpy as np from dipy.core.gradients import gradient_table from src.wrappers.OsipiBase import OsipiBase -from src.original.IAR_LundUniversity.ivim_fit_method_subtracted import IvimModelSubtracted +from src.original.fitting.IAR_LundUniversity.ivim_fit_method_subtracted import IvimModelSubtracted class IAR_LU_subtracted(OsipiBase): diff --git a/src/standardized/OGC_AmsterdamUMC_Bayesian_biexp.py b/src/standardized/OGC_AmsterdamUMC_Bayesian_biexp.py index 11a9a944..2af4b9a8 100644 --- a/src/standardized/OGC_AmsterdamUMC_Bayesian_biexp.py +++ b/src/standardized/OGC_AmsterdamUMC_Bayesian_biexp.py @@ -1,5 +1,5 @@ from src.wrappers.OsipiBase import OsipiBase -from src.original.OGC_AmsterdamUMC.LSQ_fitting import flat_neg_log_prior, fit_bayesian, empirical_neg_log_prior, fit_segmented, fit_bayesian_array, fit_segmented_array +from src.original.fitting.OGC_AmsterdamUMC.LSQ_fitting import flat_neg_log_prior, fit_bayesian, empirical_neg_log_prior, fit_segmented, fit_bayesian_array, fit_segmented_array import numpy as np class OGC_AmsterdamUMC_Bayesian_biexp(OsipiBase): diff --git a/src/standardized/OGC_AmsterdamUMC_biexp.py b/src/standardized/OGC_AmsterdamUMC_biexp.py index 0fce2d2f..1f3704f3 100644 --- a/src/standardized/OGC_AmsterdamUMC_biexp.py +++ b/src/standardized/OGC_AmsterdamUMC_biexp.py @@ -1,5 +1,5 @@ from src.wrappers.OsipiBase import OsipiBase -from src.original.OGC_AmsterdamUMC.LSQ_fitting import fit_least_squares, fit_least_squares_array +from src.original.fitting.OGC_AmsterdamUMC.LSQ_fitting import fit_least_squares, fit_least_squares_array import numpy as np class OGC_AmsterdamUMC_biexp(OsipiBase): diff --git a/src/standardized/OGC_AmsterdamUMC_biexp_segmented.py b/src/standardized/OGC_AmsterdamUMC_biexp_segmented.py index aebf8224..765cfebb 100644 --- a/src/standardized/OGC_AmsterdamUMC_biexp_segmented.py +++ b/src/standardized/OGC_AmsterdamUMC_biexp_segmented.py @@ -1,5 +1,5 @@ from src.wrappers.OsipiBase import OsipiBase -from src.original.OGC_AmsterdamUMC.LSQ_fitting import fit_segmented, fit_segmented_array +from src.original.fitting.OGC_AmsterdamUMC.LSQ_fitting import fit_segmented, fit_segmented_array import numpy as np class OGC_AmsterdamUMC_biexp_segmented(OsipiBase): diff --git a/src/standardized/OJ_GU_seg.py b/src/standardized/OJ_GU_seg.py index b5b33c11..3a20480d 100644 --- a/src/standardized/OJ_GU_seg.py +++ b/src/standardized/OJ_GU_seg.py @@ -1,6 +1,6 @@ import numpy as np from src.wrappers.OsipiBase import OsipiBase -from src.original.OJ_GU.ivim_seg import seg +from src.original.fitting.OJ_GU.ivim_seg import seg class OJ_GU_seg(OsipiBase): """ diff --git a/src/standardized/PV_MUMC_biexp.py b/src/standardized/PV_MUMC_biexp.py index 21e2d4a7..92dc7e64 100644 --- a/src/standardized/PV_MUMC_biexp.py +++ b/src/standardized/PV_MUMC_biexp.py @@ -1,6 +1,6 @@ import numpy as np from src.wrappers.OsipiBase import OsipiBase -from src.original.PV_MUMC.two_step_IVIM_fit import fit_least_squares +from src.original.fitting.PV_MUMC.two_step_IVIM_fit import fit_least_squares class PV_MUMC_biexp(OsipiBase): diff --git a/src/standardized/PvH_KB_NKI_IVIMfit.py b/src/standardized/PvH_KB_NKI_IVIMfit.py index c36c512a..a05eb669 100644 --- a/src/standardized/PvH_KB_NKI_IVIMfit.py +++ b/src/standardized/PvH_KB_NKI_IVIMfit.py @@ -1,5 +1,5 @@ from src.wrappers.OsipiBase import OsipiBase -from src.original.PvH_KB_NKI.DWI_functions_standalone import generate_IVIMmaps_standalone, generate_ADC_standalone +from src.original.fitting.PvH_KB_NKI.DWI_functions_standalone import generate_IVIMmaps_standalone, generate_ADC_standalone import numpy as np import warnings warnings.simplefilter('once', UserWarning) diff --git a/src/standardized/TF_reference_IVIMfit.py b/src/standardized/TF_reference_IVIMfit.py index 146c5b75..c3349a32 100644 --- a/src/standardized/TF_reference_IVIMfit.py +++ b/src/standardized/TF_reference_IVIMfit.py @@ -1,5 +1,5 @@ from src.wrappers.OsipiBase import OsipiBase -from src.original.TF_reference.segmented_IVIMfit import segmented_IVIM_fit +from src.original.fitting.TF_reference.segmented_IVIMfit import segmented_IVIM_fit import numpy as np class TF_reference_IVIMfit(OsipiBase): diff --git a/src/wrappers/ivim_fit.py b/src/wrappers/ivim_fit.py index fe1f9dc6..268afe66 100644 --- a/src/wrappers/ivim_fit.py +++ b/src/wrappers/ivim_fit.py @@ -7,7 +7,7 @@ import numpy as np # from utils.data_simulation.GenerateData import GenerateData -from src.original.ETP_SRI.LinearFitting import LinearFit +from src.original.fitting.ETP_SRI.LinearFitting import LinearFit author_lookup = { 'ETP_SRI': LinearFit diff --git a/tests/IVIMpreproc/unit_tests/test_denoise.py b/tests/IVIMpreproc/unit_tests/test_denoise.py index bbf26197..d8495b2a 100644 --- a/tests/IVIMpreproc/unit_tests/test_denoise.py +++ b/tests/IVIMpreproc/unit_tests/test_denoise.py @@ -10,7 +10,7 @@ from phantoms.brain.sim_brain_phantom_preproc import simulate_brain_phantom import nibabel as nib import matplotlib.pyplot as plt -from src.original.EP_GU.brain_pipeline import denoise_wrap +from src.original.preprocessing.EP_GU.brain_pipeline import denoise_wrap def test_denoise_wrap(): From 2435de7f090e5d794355d5057f9ab9081a51baf2 Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 12:26:53 +0200 Subject: [PATCH 11/21] added nipype --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3250d946..165694a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,4 +18,5 @@ sphinx_rtd_theme pytest-json-report statsmodels ivimnet -nlopt \ No newline at end of file +nlopt +nipype \ No newline at end of file From 58d664ecd423b576856c7a04f7e3090a0e2b6c1d Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 12:32:15 +0200 Subject: [PATCH 12/21] added itk --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 165694a3..454ca659 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,4 +19,5 @@ pytest-json-report statsmodels ivimnet nlopt -nipype \ No newline at end of file +nipype +itk \ No newline at end of file From a6ba403474d3af4ecf4a9480ccde04880b6475aa Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 12:36:32 +0200 Subject: [PATCH 13/21] Update requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 454ca659..11a73f0e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,4 +20,5 @@ statsmodels ivimnet nlopt nipype -itk \ No newline at end of file +itk +ivim-mri \ No newline at end of file From 22e18045a879fb480cd1686bff9d15a520c1a6c7 Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 12:48:32 +0200 Subject: [PATCH 14/21] Holding the implementation of some stuff, a package doesn't seem to work with newer versions of python --- requirements.txt | 2 +- .../unit_tests/{test_degibbs.py => wip_test_degibbs.py} | 0 .../unit_tests/{test_denoise.py => wip_test_denoise.py} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename tests/IVIMpreproc/unit_tests/{test_degibbs.py => wip_test_degibbs.py} (100%) rename tests/IVIMpreproc/unit_tests/{test_denoise.py => wip_test_denoise.py} (100%) diff --git a/requirements.txt b/requirements.txt index 11a73f0e..d445ba1c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,4 +21,4 @@ ivimnet nlopt nipype itk -ivim-mri \ No newline at end of file +#ivim-mri \ No newline at end of file diff --git a/tests/IVIMpreproc/unit_tests/test_degibbs.py b/tests/IVIMpreproc/unit_tests/wip_test_degibbs.py similarity index 100% rename from tests/IVIMpreproc/unit_tests/test_degibbs.py rename to tests/IVIMpreproc/unit_tests/wip_test_degibbs.py diff --git a/tests/IVIMpreproc/unit_tests/test_denoise.py b/tests/IVIMpreproc/unit_tests/wip_test_denoise.py similarity index 100% rename from tests/IVIMpreproc/unit_tests/test_denoise.py rename to tests/IVIMpreproc/unit_tests/wip_test_denoise.py From 4a87c643811b0661a645b4c458d131885a8c7b60 Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 12:56:28 +0200 Subject: [PATCH 15/21] moved to fitting folder --- src/original/{ => fitting}/DT_IIITN/__init__.py | 0 src/original/{ => fitting}/DT_IIITN/wls_ivim_fitting.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/original/{ => fitting}/DT_IIITN/__init__.py (100%) rename src/original/{ => fitting}/DT_IIITN/wls_ivim_fitting.py (100%) diff --git a/src/original/DT_IIITN/__init__.py b/src/original/fitting/DT_IIITN/__init__.py similarity index 100% rename from src/original/DT_IIITN/__init__.py rename to src/original/fitting/DT_IIITN/__init__.py diff --git a/src/original/DT_IIITN/wls_ivim_fitting.py b/src/original/fitting/DT_IIITN/wls_ivim_fitting.py similarity index 100% rename from src/original/DT_IIITN/wls_ivim_fitting.py rename to src/original/fitting/DT_IIITN/wls_ivim_fitting.py From 3bd5287d085316a8aaf1fa257fde2f9cfef60e52 Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 12:56:44 +0200 Subject: [PATCH 16/21] renamed so that theyre not being run --- tests/IVIMpreproc/unit_tests/wip_degibbs.py | 1 + tests/IVIMpreproc/unit_tests/wip_denoise.py | 63 +++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 tests/IVIMpreproc/unit_tests/wip_degibbs.py create mode 100644 tests/IVIMpreproc/unit_tests/wip_denoise.py diff --git a/tests/IVIMpreproc/unit_tests/wip_degibbs.py b/tests/IVIMpreproc/unit_tests/wip_degibbs.py new file mode 100644 index 00000000..4287ca86 --- /dev/null +++ b/tests/IVIMpreproc/unit_tests/wip_degibbs.py @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/tests/IVIMpreproc/unit_tests/wip_denoise.py b/tests/IVIMpreproc/unit_tests/wip_denoise.py new file mode 100644 index 00000000..d8495b2a --- /dev/null +++ b/tests/IVIMpreproc/unit_tests/wip_denoise.py @@ -0,0 +1,63 @@ +''' +1. Load brain phantom +2. Add Rician noise +3. Denoise using denoise algorithm +4. Check that sum of squared residuals decreased after denoising +''' +import os + +import numpy as np +from phantoms.brain.sim_brain_phantom_preproc import simulate_brain_phantom +import nibabel as nib +import matplotlib.pyplot as plt +from src.original.preprocessing.EP_GU.brain_pipeline import denoise_wrap + + +def test_denoise_wrap(): + # Simulate phantom with noise + snr = 50 + simulate_brain_phantom(snr = snr) + + # Denoising + im_file = 'phantoms/brain/data/diffusive_snr{}_relax.nii.gz'.format(snr) + im_file_denoised = denoise_wrap(im_file) + S_denoised = nib.load(im_file_denoised).get_fdata() + + # Compute sum of squared residuals before denoising + mask = nib.load(os.path.join('phantoms','brain','data','diffusive_snr{}_relax_mask.nii.gz'.format(snr))).get_fdata() + ref_file = 'phantoms/brain/data/diffusive_reference_relax.nii.gz' + S = nib.load(im_file).get_fdata() + S_ref = nib.load(ref_file).get_fdata() + ssr_before = np.sum((S[mask!=0,:]-S_ref[mask!=0,:])**2) + ssr_after = np.sum((S_denoised[mask!=0,:]-S_ref[mask!=0,:])**2) + + + + # print('SSR before denoising: {}'.format(ssr_before)) + # print('SSR after denoising: {}'.format(ssr_after)) + + # plt.subplot(1,3,1) + # plt.imshow(np.rot90(S_ref[:,:,30,10]),cmap='gray') + # plt.title('Reference') + # plt.xticks([]) + # plt.yticks([]) + # plt.subplot(1,3,2) + # plt.imshow(np.rot90(S[:,:,30,10]),cmap='gray') + # plt.title('Noisy') + # plt.xticks([]) + # plt.yticks([]) + # plt.subplot(1,3,3) + # plt.imshow(np.rot90(S_denoised[:,:,30,10]),cmap='gray') + # plt.title('Denoised') + # plt.xticks([]) + # plt.yticks([]) + # plt.show() + + # Check that sum of squared residuals decreased after denoising + if ssr_after < ssr_before: + assert True + else: + assert False + + + From e6f5df4359b3e5a597e7e6cd00f7d27eee2708b2 Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 12:57:09 +0200 Subject: [PATCH 17/21] renamed --- .../unit_tests/wip_test_degibbs.py | 1 - .../unit_tests/wip_test_denoise.py | 63 ------------------- 2 files changed, 64 deletions(-) delete mode 100644 tests/IVIMpreproc/unit_tests/wip_test_degibbs.py delete mode 100644 tests/IVIMpreproc/unit_tests/wip_test_denoise.py diff --git a/tests/IVIMpreproc/unit_tests/wip_test_degibbs.py b/tests/IVIMpreproc/unit_tests/wip_test_degibbs.py deleted file mode 100644 index 4287ca86..00000000 --- a/tests/IVIMpreproc/unit_tests/wip_test_degibbs.py +++ /dev/null @@ -1 +0,0 @@ -# \ No newline at end of file diff --git a/tests/IVIMpreproc/unit_tests/wip_test_denoise.py b/tests/IVIMpreproc/unit_tests/wip_test_denoise.py deleted file mode 100644 index d8495b2a..00000000 --- a/tests/IVIMpreproc/unit_tests/wip_test_denoise.py +++ /dev/null @@ -1,63 +0,0 @@ -''' -1. Load brain phantom -2. Add Rician noise -3. Denoise using denoise algorithm -4. Check that sum of squared residuals decreased after denoising -''' -import os - -import numpy as np -from phantoms.brain.sim_brain_phantom_preproc import simulate_brain_phantom -import nibabel as nib -import matplotlib.pyplot as plt -from src.original.preprocessing.EP_GU.brain_pipeline import denoise_wrap - - -def test_denoise_wrap(): - # Simulate phantom with noise - snr = 50 - simulate_brain_phantom(snr = snr) - - # Denoising - im_file = 'phantoms/brain/data/diffusive_snr{}_relax.nii.gz'.format(snr) - im_file_denoised = denoise_wrap(im_file) - S_denoised = nib.load(im_file_denoised).get_fdata() - - # Compute sum of squared residuals before denoising - mask = nib.load(os.path.join('phantoms','brain','data','diffusive_snr{}_relax_mask.nii.gz'.format(snr))).get_fdata() - ref_file = 'phantoms/brain/data/diffusive_reference_relax.nii.gz' - S = nib.load(im_file).get_fdata() - S_ref = nib.load(ref_file).get_fdata() - ssr_before = np.sum((S[mask!=0,:]-S_ref[mask!=0,:])**2) - ssr_after = np.sum((S_denoised[mask!=0,:]-S_ref[mask!=0,:])**2) - - - - # print('SSR before denoising: {}'.format(ssr_before)) - # print('SSR after denoising: {}'.format(ssr_after)) - - # plt.subplot(1,3,1) - # plt.imshow(np.rot90(S_ref[:,:,30,10]),cmap='gray') - # plt.title('Reference') - # plt.xticks([]) - # plt.yticks([]) - # plt.subplot(1,3,2) - # plt.imshow(np.rot90(S[:,:,30,10]),cmap='gray') - # plt.title('Noisy') - # plt.xticks([]) - # plt.yticks([]) - # plt.subplot(1,3,3) - # plt.imshow(np.rot90(S_denoised[:,:,30,10]),cmap='gray') - # plt.title('Denoised') - # plt.xticks([]) - # plt.yticks([]) - # plt.show() - - # Check that sum of squared residuals decreased after denoising - if ssr_after < ssr_before: - assert True - else: - assert False - - - From 1b341bf9091b616100f98e5d43e386c7b8ebed13 Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 13:12:09 +0200 Subject: [PATCH 18/21] Ignore tests that are wip --- pytest.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest.ini b/pytest.ini index 1d85aaef..b3286ddb 100644 --- a/pytest.ini +++ b/pytest.ini @@ -3,6 +3,7 @@ markers = slow: marks tests as slow (deselect with '-m "not slow"') addopts = -m 'not slow' + --ignore-glob=**/wip_*.py testpaths = tests filterwarnings = ignore::Warning From d958c204f0696a657d9a086e3c090c7acb6d9c3d Mon Sep 17 00:00:00 2001 From: IvanARashid Date: Mon, 4 May 2026 13:49:47 +0200 Subject: [PATCH 19/21] Update DT_IIITN_WLS.py --- src/standardized/DT_IIITN_WLS.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/standardized/DT_IIITN_WLS.py b/src/standardized/DT_IIITN_WLS.py index 4925dbed..97f1fb9a 100644 --- a/src/standardized/DT_IIITN_WLS.py +++ b/src/standardized/DT_IIITN_WLS.py @@ -1,5 +1,5 @@ from src.wrappers.OsipiBase import OsipiBase -from src.original.DT_IIITN.wls_ivim_fitting import wls_ivim_fit +from src.original.fitting.DT_IIITN.wls_ivim_fitting import wls_ivim_fit import numpy as np From 68d01f2a05ff9415b81b3d071b16a271215a9a24 Mon Sep 17 00:00:00 2001 From: ElinaPetersson-stat Date: Tue, 5 May 2026 15:07:01 +0200 Subject: [PATCH 20/21] merge to just one sim_brain_phantom script --- .../ground_truth/ballistic_groundtruth.json | 5 +- .../ground_truth/diffusive_groundtruth.json | 7 +- .../diffusive_relax_groundtruth.json | 8 -- phantoms/brain/sim_brain_phantom.py | 59 +++++++++---- phantoms/brain/sim_brain_phantom_preproc.py | 82 ------------------- tests/IVIMpreproc/unit_tests/wip_denoise.py | 8 +- 6 files changed, 55 insertions(+), 114 deletions(-) delete mode 100644 phantoms/brain/ground_truth/diffusive_relax_groundtruth.json delete mode 100644 phantoms/brain/sim_brain_phantom_preproc.py diff --git a/phantoms/brain/ground_truth/ballistic_groundtruth.json b/phantoms/brain/ground_truth/ballistic_groundtruth.json index 6a5a7995..d4709f81 100644 --- a/phantoms/brain/ground_truth/ballistic_groundtruth.json +++ b/phantoms/brain/ground_truth/ballistic_groundtruth.json @@ -1,6 +1,9 @@ { + "tissues": ["WM","GM","CSF"], "D":[1.2e-3,0.98e-3,3e-3], "f":[0.0243,0.0164,0], "vd":[1.71,1.73,0], - "Db":1.75e-3 + "Db":1.75e-3, + "T1":[1.0, 1.5, 3.4], + "T2":[0.046,0.068,0.45] } \ No newline at end of file diff --git a/phantoms/brain/ground_truth/diffusive_groundtruth.json b/phantoms/brain/ground_truth/diffusive_groundtruth.json index 27ac53d6..d6bcda7a 100644 --- a/phantoms/brain/ground_truth/diffusive_groundtruth.json +++ b/phantoms/brain/ground_truth/diffusive_groundtruth.json @@ -1,5 +1,8 @@ { + "tissues": ["WM","GM","CSF"], "D":[0.81e-3,0.86e-3,3e-3], "f":[0.044,0.033,0], - "Dstar":[84e-3,76e-3,0] -} \ No newline at end of file + "Dstar":[84e-3,76e-3,0], + "T1":[1.0, 1.5, 3.4], + "T2":[0.046,0.068,0.45] +} diff --git a/phantoms/brain/ground_truth/diffusive_relax_groundtruth.json b/phantoms/brain/ground_truth/diffusive_relax_groundtruth.json deleted file mode 100644 index d6bcda7a..00000000 --- a/phantoms/brain/ground_truth/diffusive_relax_groundtruth.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "tissues": ["WM","GM","CSF"], - "D":[0.81e-3,0.86e-3,3e-3], - "f":[0.044,0.033,0], - "Dstar":[84e-3,76e-3,0], - "T1":[1.0, 1.5, 3.4], - "T2":[0.046,0.068,0.45] -} diff --git a/phantoms/brain/sim_brain_phantom.py b/phantoms/brain/sim_brain_phantom.py index d5ba89a5..9a686df3 100644 --- a/phantoms/brain/sim_brain_phantom.py +++ b/phantoms/brain/sim_brain_phantom.py @@ -6,23 +6,28 @@ from scipy.ndimage import zoom from utilities.data_simulation.Download_data import download_data -if __name__ == "__main__": +DIFFUSIVE_REGIME = 'diffusive' +BALLISTIC_REGIME = 'ballistic' + +def simulate_brain_phantom(regime=DIFFUSIVE_REGIME, snr=100, sim_relaxation=True, TE=60e-3, TR=5, resolution=[3,3,3]): + ''' + Simulation parameters can be set by changing the default values of the function arguments. + The default values are chosen to be suitable for a diffusive regime phantom, but can be changed to simulate a ballistic regime phantom as well. + The simulated image is saved in phantoms/brain/data with the name 'diffusive_sn{snr}_relax.nii.gz' or 'ballistic_sn{snr}_relax.nii.gz' depending on the regime. + The corresponding bvals and cvals (if applicable) are also saved in the same folder. + + regime: 'diffusive' or 'ballistic' to choose the type of phantom to simulate + snr: signal-to-noise ratio of the simulated image + sim_relaxation: whether to simulate T1 and T2 relaxation effects in the signal + TE: echo time in seconds + TR: repetition time in seconds + resolution: voxel size in mm + ''' download_data() - DIFFUSIVE_REGIME = 'diffusive' - BALLISTIC_REGIME = 'ballistic' folder = os.path.dirname(__file__) - ########################### - # Simulation parameters # - regime = DIFFUSIVE_REGIME - snr = 200 - resolution = [3,3,3] - # # - ########################### - - # Ground truth nii = nib.load(os.path.join(os.path.split(os.path.split(folder)[0])[0],'download','Phantoms','brain','ground_truth','hrgt_icbm_2009a_nls_3t.nii.gz')) segmentation = np.squeeze(nii.get_fdata()[...,-1]) @@ -40,20 +45,30 @@ # Calculate signal S = np.zeros(list(np.shape(segmentation))+[b.size]) - + print(ivim_pars) if regime == BALLISTIC_REGIME: Db = ivim_pars["Db"] - for i,(D,f,vd) in enumerate(zip(ivim_pars["D"],ivim_pars["f"],ivim_pars["vd"])): + for i,(D,f,vd,T1,T2) in enumerate(zip(ivim_pars["D"],ivim_pars["f"],ivim_pars["vd"],ivim_pars["T1"],ivim_pars["T2"])): S[segmentation==i+1,:] = S0*((1-f)*np.exp(-b*D)+f*np.exp(-b*Db-c**2*vd**2)) + if sim_relaxation: + S[segmentation==i+1,:] *= np.exp(-TE/T2)*(1-np.exp(-TR/T1)) else: - for i,(D,f,Dstar) in enumerate(zip(ivim_pars["D"],ivim_pars["f"],ivim_pars["Dstar"])): + for i,(D,f,Dstar,T1,T2) in enumerate(zip(ivim_pars["D"],ivim_pars["f"],ivim_pars["Dstar"],ivim_pars["T1"],ivim_pars["T2"])): S[segmentation==i+1,:] = S0*((1-f)*np.exp(-b*D)+f*np.exp(-b*Dstar)) + if sim_relaxation: + S[segmentation==i+1,:] *= np.exp(-TE/T2)*(1-np.exp(-TR/T1)) # Resample to suitable resolution im = zoom(S,np.append(np.diag(nii.affine)[:3]/np.array(resolution),1),order=1) sz = im.shape - # Add noise + # Save image without noise for reference + nii_out = nib.Nifti1Image(im,np.eye(4)) + base_name = os.path.join(folder,'data','{}_reference'.format(regime,snr)) + nib.save(nii_out,base_name+'.nii.gz') + shutil.copyfile(bval_file,base_name+'.bval') + + # Add Rician noise im_noise = np.abs(im + S0/snr*(np.random.randn(sz[0],sz[1],sz[2],sz[3])+1j*np.random.randn(sz[0],sz[1],sz[2],sz[3]))) # Save as image and sequence parameters @@ -62,4 +77,14 @@ nib.save(nii_out,base_name+'.nii.gz') shutil.copyfile(bval_file,base_name+'.bval') if regime == BALLISTIC_REGIME: - shutil.copyfile(cval_file,base_name+'.cval') \ No newline at end of file + shutil.copyfile(cval_file,base_name+'.cval') + + # Resample and save segmentation + segmentation = zoom(segmentation,np.diag(nii.affine)[:3]/np.array(resolution),order=0) + nii_out = nib.Nifti1Image(segmentation,np.eye(4)) + base_name = os.path.join(folder,'data','{}_snr{}_mask'.format(regime,snr)) + nib.save(nii_out,base_name+'.nii.gz') + + +if __name__ == "__main__": + simulate_brain_phantom() diff --git a/phantoms/brain/sim_brain_phantom_preproc.py b/phantoms/brain/sim_brain_phantom_preproc.py deleted file mode 100644 index 1543a607..00000000 --- a/phantoms/brain/sim_brain_phantom_preproc.py +++ /dev/null @@ -1,82 +0,0 @@ -import os -import shutil -import json -import numpy as np -import nibabel as nib -from scipy.ndimage import zoom -from utilities.data_simulation.Download_data import download_data - - -def simulate_brain_phantom(snr=100, TE=60e-3, TR=5, resolution=[3,3,3]): - ''' - Simulation parameters can be set by changing the default values of the function arguments. The default values are chosen to be suitable for a diffusive regime phantom, but can be changed to simulate a ballistic regime phantom as well. The simulated image is saved in phantoms/brain/data with the name 'diffusive_sn{snr}_relax.nii.gz' or 'ballistic_sn{snr}_relax.nii.gz' depending on the regime. The corresponding bvals and cvals (if applicable) are also saved in the same folder. - snr: signal-to-noise ratio of the simulated image - TE: echo time in seconds - TR: repetition time in seconds - resolution: voxel size in mm - ''' - download_data() - - DIFFUSIVE_REGIME = 'diffusive' - BALLISTIC_REGIME = 'ballistic' - - regime = DIFFUSIVE_REGIME # only adapted for diffusive regime for now, but can be easily changed to simulate ballistic regime as well by changing this variable and providing the corresponding ground truth parameters in the json file - - folder = os.path.dirname(__file__) - - # Ground truth - nii = nib.load(os.path.join(os.path.split(os.path.split(folder)[0])[0],'download','Phantoms','brain','ground_truth','hrgt_icbm_2009a_nls_3t.nii.gz')) - segmentation = np.squeeze(nii.get_fdata()[...,-1]) - - with open(os.path.join(folder,'ground_truth',regime+'_relax_groundtruth.json'), 'r') as f: - ivim_pars = json.load(f) - S0 = 1 - - # Sequence parameters - bval_file = os.path.join(folder,'ground_truth',regime+'.bval') - b = np.loadtxt(bval_file) - if regime == BALLISTIC_REGIME: - cval_file = bval_file.replace('bval','cval') - c = np.loadtxt(cval_file) - - # Calculate signal - S = np.zeros(list(np.shape(segmentation))+[b.size]) - print(ivim_pars) - if regime == BALLISTIC_REGIME: - Db = ivim_pars["Db"] - for i,(D,f,vd,T1,T2) in enumerate(zip(ivim_pars["D"],ivim_pars["f"],ivim_pars["vd"],ivim_pars["T1"],ivim_pars["T2"])): - S[segmentation==i+1,:] = S0*((1-f)*np.exp(-b*D)+f*np.exp(-b*Db-c**2*vd**2))*np.exp(-TE/T2)*(1-np.exp(-TR/T1)) - else: - for i,(D,f,Dstar,T1,T2) in enumerate(zip(ivim_pars["D"],ivim_pars["f"],ivim_pars["Dstar"],ivim_pars["T1"],ivim_pars["T2"])): - S[segmentation==i+1,:] = S0*((1-f)*np.exp(-b*D)+f*np.exp(-b*Dstar))*np.exp(-TE/T2)*(1-np.exp(-TR/T1)) - - # Resample to suitable resolution - im = zoom(S,np.append(np.diag(nii.affine)[:3]/np.array(resolution),1),order=1) - sz = im.shape - - # Save image without noise for reference - nii_out = nib.Nifti1Image(im,np.eye(4)) - base_name = os.path.join(folder,'data','{}_reference_relax'.format(regime,snr)) - nib.save(nii_out,base_name+'.nii.gz') - shutil.copyfile(bval_file,base_name+'.bval') - - # Add Rician noise - im_noise = np.abs(im + S0/snr*(np.random.randn(sz[0],sz[1],sz[2],sz[3])+1j*np.random.randn(sz[0],sz[1],sz[2],sz[3]))) - - # Save as image and sequence parameters - nii_out = nib.Nifti1Image(im_noise,np.eye(4)) - base_name = os.path.join(folder,'data','{}_snr{}_relax'.format(regime,snr)) - nib.save(nii_out,base_name+'.nii.gz') - shutil.copyfile(bval_file,base_name+'.bval') - if regime == BALLISTIC_REGIME: - shutil.copyfile(cval_file,base_name+'.cval') - - # Resample and save segmentation - segmentation = zoom(segmentation,np.diag(nii.affine)[:3]/np.array(resolution),order=0) - nii_out = nib.Nifti1Image(segmentation,np.eye(4)) - base_name = os.path.join(folder,'data','{}_snr{}_relax_mask'.format(regime,snr)) - nib.save(nii_out,base_name+'.nii.gz') - - -if __name__ == "__main__": - simulate_brain_phantom() diff --git a/tests/IVIMpreproc/unit_tests/wip_denoise.py b/tests/IVIMpreproc/unit_tests/wip_denoise.py index d8495b2a..f198a263 100644 --- a/tests/IVIMpreproc/unit_tests/wip_denoise.py +++ b/tests/IVIMpreproc/unit_tests/wip_denoise.py @@ -7,7 +7,7 @@ import os import numpy as np -from phantoms.brain.sim_brain_phantom_preproc import simulate_brain_phantom +from phantoms.brain.sim_brain_phantom import simulate_brain_phantom import nibabel as nib import matplotlib.pyplot as plt from src.original.preprocessing.EP_GU.brain_pipeline import denoise_wrap @@ -19,13 +19,13 @@ def test_denoise_wrap(): simulate_brain_phantom(snr = snr) # Denoising - im_file = 'phantoms/brain/data/diffusive_snr{}_relax.nii.gz'.format(snr) + im_file = 'phantoms/brain/data/diffusive_snr{}.nii.gz'.format(snr) im_file_denoised = denoise_wrap(im_file) S_denoised = nib.load(im_file_denoised).get_fdata() # Compute sum of squared residuals before denoising - mask = nib.load(os.path.join('phantoms','brain','data','diffusive_snr{}_relax_mask.nii.gz'.format(snr))).get_fdata() - ref_file = 'phantoms/brain/data/diffusive_reference_relax.nii.gz' + mask = nib.load(os.path.join('phantoms','brain','data','diffusive_snr{}_mask.nii.gz'.format(snr))).get_fdata() + ref_file = 'phantoms/brain/data/diffusive_reference.nii.gz' S = nib.load(im_file).get_fdata() S_ref = nib.load(ref_file).get_fdata() ssr_before = np.sum((S[mask!=0,:]-S_ref[mask!=0,:])**2) From 8b132271e85c6491e5ea91089afbe077c2dec688 Mon Sep 17 00:00:00 2001 From: ElinaPetersson-stat Date: Tue, 5 May 2026 15:11:10 +0200 Subject: [PATCH 21/21] small edit of description --- phantoms/brain/sim_brain_phantom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phantoms/brain/sim_brain_phantom.py b/phantoms/brain/sim_brain_phantom.py index 9a686df3..295f0f6c 100644 --- a/phantoms/brain/sim_brain_phantom.py +++ b/phantoms/brain/sim_brain_phantom.py @@ -13,7 +13,7 @@ def simulate_brain_phantom(regime=DIFFUSIVE_REGIME, snr=100, sim_relaxation=True ''' Simulation parameters can be set by changing the default values of the function arguments. The default values are chosen to be suitable for a diffusive regime phantom, but can be changed to simulate a ballistic regime phantom as well. - The simulated image is saved in phantoms/brain/data with the name 'diffusive_sn{snr}_relax.nii.gz' or 'ballistic_sn{snr}_relax.nii.gz' depending on the regime. + The simulated image is saved in phantoms/brain/data with the name 'diffusive_sn{snr}.nii.gz' or 'ballistic_sn{snr}.nii.gz' depending on the regime. The corresponding bvals and cvals (if applicable) are also saved in the same folder. regime: 'diffusive' or 'ballistic' to choose the type of phantom to simulate