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

Merge branch 'bf/dyn_mh_reslist' into 'master'

BF/ENH: Minor fixes post 2.0

See merge request fsl/fsl_mrs!57
parents d4ee2e20 5c6d4893
Pipeline #15004 failed with stage
This document contains the FSL-MRS release history in reverse chronological order.
2.0.1 (Thursday 28th July 2022)
-------------------------------
- Fix results list generation from metropolis hastings dynamic optimisation
- Fix bug in fsl_mrs_summarise that would stop data with a disabled baseline (order = -1) working.
- Added conversion of jMRUI basis sets to basis_tools convert.
- --mask argument no longer mandatory for fsl_mrsi.
- Fixed bugs in mrsi_segment, auto run fsl_anat now work and qform copied to sform for MRSI in cases with small differences.
2.0.0 (Wednesday 6th July 2022)
-------------------------------
**Major rework of basis and fitting script interaction. First release of dynamic MRS fitting.**
......
......@@ -572,7 +572,7 @@ class dynRes_mcmc(dynRes):
:return: List of FitRes objects.
:rtype: list
"""
return self._dyn.form_FitRes(self.dataframe.to_numpy(), 'MH')
return self._dyn.form_FitRes(self.dataframe_free.to_numpy(), 'MH')
@property
def cov_free(self):
......
......@@ -248,12 +248,18 @@ def convert(args):
if args.input.is_file():
basis_tools.convert_lcm_basis(args.input, args.output)
elif args.input.is_dir():
elif args.input.is_dir()\
and (len(list(args.input.glob('*.raw'))) > 0 or len(list(args.input.glob('*.RAW'))) > 0):
basis_tools.convert_lcm_raw_basis(
args.input,
args.bandwidth,
args.fieldstrength * GYRO_MAG_RATIO['1H'],
args.output)
elif args.input.is_dir()\
and len(list(args.input.glob('*.txt'))) > 0:
basis_tools.convert_jmrui_basis(
args.input,
args.output)
if args.remove_reference:
# TODO sort this conjugation mess out.
......
......@@ -80,8 +80,9 @@ def main():
avg_group = avgparser.add_argument_group('average arguments')
avg_group.add_argument('--file', type=str, required=True,
help='MRS file(s)')
avg_group.add_argument('--dim', type=str,
help='Select dimension to average across')
avg_group.add_argument('--dim', type=str, default='DIM_DYN',
help='Select dimension to average across. '
'Should be a NIfTI-MRS dimension tag, e.g. DIM_DYN (default)')
avgparser.set_defaults(func=average)
add_common_args(avgparser)
......
......@@ -112,6 +112,8 @@ def main():
# Generate metabolite groups
metab_groups = misc.parse_metab_groups(mrs, orig_args['metab_groups'])
baseline_order = orig_args['baseline_order']
if baseline_order < 0:
baseline_order = 0 # Required to make prepare_baseline_regressor run.
ppmlim = orig_args['ppmlim']
# Generate baseline polynomials (B)
B = prepare_baseline_regressor(mrs, baseline_order, ppmlim)
......
......@@ -36,14 +36,14 @@ def main():
required.add_argument('--basis',
required=True, type=str, metavar='<str>',
help='Basis file or folder')
required.add_argument('--mask',
required=True, type=str, metavar='<str>',
help='mask volume')
required.add_argument('--output',
required=True, type=str, metavar='<str>',
help='output folder')
# FITTING ARGUMENTS
fitting_args.add_argument('--mask',
type=str, metavar='<str>',
help='Optional NIfTI binary mask of voxels to fit.')
fitting_args.add_argument('--algo', default='Newton', type=str,
help='algorithm [Newton (fast, default)'
' or MH (slow)]')
......
......@@ -46,7 +46,7 @@ def main():
return str(pathlib_path.resolve())
# If not prevented run fsl_anat for fast segmentation
if (args.anat is None) and (not args.mask_only):
if args.anat is None:
anat = args.output / 'fsl_anat'
fsl_anat(
str_resolve_path(args.t1),
......@@ -61,6 +61,10 @@ def main():
tmp_img = np.zeros(mrsi_in.shape[0:3])
tmp_img = Image(tmp_img, xform=mrsi_in.voxToWorldMat)
# HACK because applywarp is shite - Paul McCarthy 2022 ;-)
tmp_img.header.set_sform(tmp_img.header.get_qform())
# Can remove in FSL 6.1.0 when applywarp is fixed
# Register the pvseg to the MRSI data using flirt
def applywarp_func(i, o):
applywarp(str_resolve_path(i),
......
......@@ -155,6 +155,9 @@ def test_dynRes_mcmc(fixed_ratio_mrs):
assert isinstance(res_obj.dataframe_mapped, pd.DataFrame)
assert res_obj.dataframe_mapped.shape == (2, 8)
assert isinstance(res_obj.reslist, list)
assert len(res_obj.reslist) == 2
def test_load_save(fixed_ratio_mrs, tmp_path):
mrs_list = fixed_ratio_mrs
......
......@@ -20,6 +20,7 @@ mac = testsPath / 'testdata/basis_tools/macSeed.json'
diff1 = testsPath / 'testdata/basis_tools/low_res_off'
diff2 = testsPath / 'testdata/basis_tools/low_res_on'
raw = testsPath / 'testdata/basis_tools/RawBasis_for_PRESSGE_TE_35_BW_4000_NPts_2048'
jmrui_basis_path = testsPath / 'testdata' / 'mrs_io' / 'basisset_JMRUI'
def test_info():
......@@ -55,6 +56,17 @@ def test_convert_raw(tmp_path):
assert (tmp_path / 'new_raw' / 'NAA.json').is_file()
def test_convert_jmrui(tmp_path):
subprocess.check_call(['basis_tools', 'convert',
str(jmrui_basis_path),
'--bandwidth', '4000',
'--fieldstrength', '3.0',
str(tmp_path / 'new_jmrui')])
assert (tmp_path / 'new_jmrui').is_dir()
assert (tmp_path / 'new_jmrui' / 'NAA.json').is_file()
def test_convert_with_remove(tmp_path):
subprocess.check_call(['basis_tools', 'convert',
'--remove_reference',
......
......@@ -19,6 +19,7 @@ testsPath = Path(__file__).parent
fsl_basis_path = testsPath / 'testdata' / 'fsl_mrs' / 'steam_basis'
lcm_basis_path = testsPath / 'testdata' / 'basis_tools' / '3T_slaser_32vespa_1250.BASIS'
raw_basis_path = testsPath / 'testdata' / 'basis_tools' / 'RawBasis_for_PRESSGE_TE_35_BW_4000_NPts_2048'
jmrui_basis_path = testsPath / 'testdata' / 'mrs_io' / 'basisset_JMRUI'
extra_basis = testsPath / 'testdata' / 'basis_tools' / 'macSeed.json'
......@@ -51,6 +52,17 @@ def test_convert_raw(tmp_path):
assert new_basis.original_basis_array.shape == (2048, 3)
def test_convert_jmrui(tmp_path):
out_loc = tmp_path / 'test_basis_jmrui'
basis_tools.convert_jmrui_basis(
jmrui_basis_path,
out_loc)
new_basis = mrs_io.read_basis(out_loc)
assert new_basis.original_basis_array.shape == (2048, 21)
def test_add_basis():
basis = mrs_io.read_basis(fsl_basis_path)
......
......@@ -86,6 +86,19 @@ def convert_lcm_raw_basis(path_to_basis, bandwidth, central_frequency, output_lo
basis.save(output_location, info_str=sim_info)
def convert_jmrui_basis(indir, outdir):
"""Convert a directory of jMRUI formatted basis files (.txt) to FSL-MRS format.
:param indir: input directory
:type indir: pathlib.Path
:param outdir: output location
:type outdir: pathlib.Path
"""
from fsl_mrs.utils import mrs_io
in_basis = mrs_io.read_basis(indir)
in_basis.save(outdir)
def add_basis(fid, name, cf, bw, target, scale=False, width=None, conj=False, pad=False):
"""Add an additional basis spectrum to an existing FSL formatted basis set.
......
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