Commit b1a83e76 authored by William Clarke's avatar William Clarke
Browse files

Merge branch 'enh/improved_preproc_edit' into 'master'

Enh: Improved preproc edit

See merge request !40
parents c6589c0f 3420ce93
Pipeline #12262 passed with stages
in 16 minutes and 51 seconds
This document contains the FSL-MRS release history in reverse chronological order. This document contains the FSL-MRS release history in reverse chronological order.
1.1.10 (WIP)
----------------------------------
- Updates to fsl_mrs_preproc_edit
- Updated install documentation.
1.1.9 (Tuesday 30th November 2021) 1.1.9 (Tuesday 30th November 2021)
---------------------------------- ----------------------------------
- Fixed typos in fsl_mrs_proc help. - Fixed typos in fsl_mrs_proc help.
......
...@@ -27,6 +27,14 @@ The primary installation method is via *conda*. After installing conda and creat ...@@ -27,6 +27,14 @@ The primary installation method is via *conda*. After installing conda and creat
-c https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ \ -c https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ \
fsl_mrs fsl_mrs
To check the version installed run :code:`fsl_mrs --version`. FSL-MRS can be updated by running :code:`conda update`:
::
conda update -c conda-forge -c defaults \
-c https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ \
fsl_mrs
Example data with conda Example data with conda
----------------------- -----------------------
Installation with conda is easy, but you won't get the packaged example data and notebooks. This can be downloaded separately here: |fslmrs_pkg_data|_. Installation with conda is easy, but you won't get the packaged example data and notebooks. This can be downloaded separately here: |fslmrs_pkg_data|_.
......
...@@ -55,15 +55,17 @@ def main(): ...@@ -55,15 +55,17 @@ def main():
help='Apply HLSVD for residual water removal.') help='Apply HLSVD for residual water removal.')
optional.add_argument('--dynamic_align', action="store_true", optional.add_argument('--dynamic_align', action="store_true",
help='Align spectra based on dynamic fitting. Must specify dynamic basis sets.') help='Align spectra based on dynamic fitting. Must specify dynamic basis sets.')
optional.add_argument('--dynamic_align_edit', action="store_true",
help='Align conditions based on dynamic fitting. Must specify dynamic basis sets.')
optional.add_argument('--dynamic_basis', type=str, nargs=2, optional.add_argument('--dynamic_basis', type=str, nargs=2,
help='Paths to the two editing condition basis sets. ' help='Paths to the two editing condition basis sets. '
'Only needed if --dynamic_align is specified.') 'Only needed if --dynamic_align is specified.')
optional.add_argument('--leftshift', type=int, metavar='POINTS', optional.add_argument('--leftshift', type=int, metavar='POINTS',
help='Remove points at the start of the fid.') help='Remove points at the start of the fid.')
optional.add_argument('--dynamic_align_ppm', type=float, nargs=2, default=(1.9, 4.2), optional.add_argument('--align_ppm_dynamic', type=float, nargs=2, default=(1.9, 4.2),
help='PPM limit for dynamics dimension alignment. Default=(0.0, 4.2).') help='PPM limit for dynamics dimension alignment. Default=(0.0, 4.2).')
optional.add_argument('--edit_align_ppm', type=float, nargs=2, default=(2.5, 4.2), optional.add_argument('--align_ppm_edit', type=float, nargs=2, default=None,
help='PPM limit for edit dimension alignment. Default=(2.5, 4.2).') help='PPM limit for edit dimension alignment. Default=full spectrum.')
optional.add_argument('--t1', type=str, default=None, metavar='IMAGE', optional.add_argument('--t1', type=str, default=None, metavar='IMAGE',
help='structural image (for report)') help='structural image (for report)')
optional.add_argument('--verbose', action="store_true", optional.add_argument('--verbose', action="store_true",
...@@ -212,7 +214,7 @@ def main(): ...@@ -212,7 +214,7 @@ def main():
supp_data = nifti_mrs_proc.align( supp_data = nifti_mrs_proc.align(
supp_data, supp_data,
'DIM_DYN', 'DIM_DYN',
ppmlim=args.dynamic_align_ppm, ppmlim=args.align_ppm_dynamic,
niter=4, niter=4,
apodize=0.0, apodize=0.0,
report=report_dir, report=report_dir,
...@@ -319,12 +321,12 @@ def main(): ...@@ -319,12 +321,12 @@ def main():
final_wref = nifti_mrs_proc.phase_correct(ref_data, (4.55, 4.7), hlsvd=False, report=report_dir) final_wref = nifti_mrs_proc.phase_correct(ref_data, (4.55, 4.7), hlsvd=False, report=report_dir)
# Align between edit dimension # Align between edit dimension
if args.dynamic_align and args.average: if args.dynamic_align_edit and args.average:
metab_edit_align, eps, phi = dproc.align_by_dynamic_fit(supp_data, [basis_0, basis_1], fitargs_1) metab_edit_align, eps, phi = dproc.align_by_dynamic_fit(supp_data, [basis_0, basis_1], fitargs_1)
if report_dir is not None: if report_dir is not None:
dproc.align_by_dynamic_fit_report(supp_data, metab_edit_align, eps, phi, html=report_dir) dproc.align_by_dynamic_fit_report(supp_data, metab_edit_align, eps, phi, html=report_dir)
elif args.dynamic_align: elif args.dynamic_align_edit:
# Do not average and dynamic alignment # Do not average and dynamic alignment
# Work out alignement on averaged data # Work out alignement on averaged data
supp_data_avg = nifti_mrs_proc.average(supp_data, 'DIM_DYN') supp_data_avg = nifti_mrs_proc.average(supp_data, 'DIM_DYN')
...@@ -345,9 +347,9 @@ def main(): ...@@ -345,9 +347,9 @@ def main():
metab_edit_align = nifti_mrs_proc.align( metab_edit_align = nifti_mrs_proc.align(
supp_data, supp_data,
'DIM_EDIT', 'DIM_EDIT',
ppmlim=args.edit_align_ppm, ppmlim=args.align_ppm_edit,
niter=4, niter=4,
apodize=0.0, apodize=10.0,
report=report_dir) report=report_dir)
# Differencing # Differencing
......
...@@ -14,6 +14,37 @@ data = testsPath / 'testdata/fsl_mrs_preproc_edit' ...@@ -14,6 +14,37 @@ data = testsPath / 'testdata/fsl_mrs_preproc_edit'
t1 = str(testsPath / 'testdata/svs_segment/T1.anat/T1_biascorr.nii.gz') t1 = str(testsPath / 'testdata/svs_segment/T1.anat/T1_biascorr.nii.gz')
def test_preproc_defaults(tmp_path):
metab = str(data / 'metab_raw.nii.gz')
wrefc = str(data / 'wref_internal.nii.gz')
wrefq = str(data / 'wref_quant.nii.gz')
ecc = str(data / 'wref_internal.nii.gz')
retcode = subprocess.check_call(
['fsl_mrs_preproc_edit',
'--output', str(tmp_path),
'--data', metab,
'--reference', wrefc,
'--quant', wrefq,
'--ecc', ecc,
'--t1', t1,
'--hlsvd',
'--leftshift', '2',
'--overwrite',
'--report',
'--verbose'])
assert retcode == 0
assert (tmp_path / 'diff.nii.gz').exists()
assert (tmp_path / 'edit_0.nii.gz').exists()
assert (tmp_path / 'edit_1.nii.gz').exists()
assert (tmp_path / 'wref.nii.gz').exists()
assert (tmp_path / 'options.txt').exists()
assert (tmp_path / 'mergedReports.html').exists()
assert (tmp_path / 'voxel_location.png').exists()
def test_preproc(tmp_path): def test_preproc(tmp_path):
metab = str(data / 'metab_raw.nii.gz') metab = str(data / 'metab_raw.nii.gz')
...@@ -29,8 +60,8 @@ def test_preproc(tmp_path): ...@@ -29,8 +60,8 @@ def test_preproc(tmp_path):
'--quant', wrefq, '--quant', wrefq,
'--ecc', ecc, '--ecc', ecc,
'--t1', t1, '--t1', t1,
'--dynamic_align_ppm', '1.8', '4.2', '--align_ppm_dynamic', '1.8', '4.2',
'--edit_align_ppm', '2.5', '4.2', '--align_ppm_edit', '2.5', '4.2',
'--hlsvd', '--hlsvd',
'--leftshift', '2', '--leftshift', '2',
'--overwrite', '--overwrite',
...@@ -62,8 +93,8 @@ def test_preproc_noavg(tmp_path): ...@@ -62,8 +93,8 @@ def test_preproc_noavg(tmp_path):
'--quant', wrefq, '--quant', wrefq,
'--ecc', ecc, '--ecc', ecc,
'--t1', t1, '--t1', t1,
'--dynamic_align_ppm', '1.8', '4.2', '--align_ppm_dynamic', '1.8', '4.2',
'--edit_align_ppm', '2.5', '4.2', '--align_ppm_edit', '2.5', '4.2',
'--leftshift', '2', '--leftshift', '2',
'--overwrite', '--overwrite',
'--report', '--report',
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment