Commit 871deed1 authored by William Clarke's avatar William Clarke
Browse files

Merge branch 'enh/multi_thread_ctrl' into 'master'

ENH: Enable control of multi-threads in fsl_mrs_sim

See merge request fsl/fsl_mrs!43
parents 31e06c80 37451200
Pipeline #13842 waiting for manual action with stages
in 29 minutes and 27 seconds
This document contains the FSL-MRS release history in reverse chronological order.
1.1.11 (WIP)
- Now able to choose the number of workers in fsl_mrs_sim.
- HSLVD routines now use dense (non-sparse) routine for better numerical stability
1.1.10 (Thursday 12 January 2022)
- Updates to fsl_mrs_preproc_edit
......@@ -74,6 +74,10 @@ def main():
required=False, metavar='ECHOTIME',
help='Echo time value in ms for output files (no effect on simulation).')
optional.add_argument('--num_processes', type=int,
required=False, default=None,
help='Number of worker processes to use in simulation, defaults to os.cpu_count().')
# optional.add_argument('--verbose',action="store_true",
# help='spit out verbose info')
optional.add_argument('--overwrite', action="store_true",
......@@ -216,7 +220,8 @@ def main():
# Loop over the spin systems (list) in a parallel way
poolFunc = partial(runSimForMetab, seqParams=seqParams, args=args)
poolArgs = [(i, s, n) for i, (s, n) in enumerate(zip(spinsys, spinsToSim))]
pool = mp.Pool()
# handle number of processes
pool = mp.Pool(args.num_processes)
pool.starmap(poolFunc, poolArgs)
# Additional write steps for MM and LCM basis generation
......@@ -69,3 +69,27 @@ def test_sim(spinsys, seqparams, tmp_path):
assert np.allclose(basis_j[:, names_j.index('sys1')], directSim1)
assert np.allclose(basis_j[:, names_j.index('sys2')], directSim2)
def test_sim_workers(spinsys, seqparams, tmp_path):
# Test simulation number of workers
# Run the sequence on a couple of metabolites, ask for all types of files, add the reference peak
ssFile = op.join(tmp_path, 'custom_ss.json')
outfile1 = op.join(tmp_path, 'simulated_single')
outfile2 = op.join(tmp_path, 'simulated_multi')
assert not subprocess.check_call(
'-s', ssFile,
'-o', outfile1,
'-a', seqfile,
'--num_processes', '1'])
assert not subprocess.check_call(
'-s', ssFile,
'-o', outfile2,
'-a', seqfile,
'--num_processes', '2'])
......@@ -399,14 +399,15 @@ class dynRes:
fig.legend(handles, labels, loc='right')
return fig
def plot_spectra(self, init=False, fit_to_init=False):
def plot_spectra(self, init=False, fit_to_init=False, indices=None):
"""Plot individual spectra as fitted using the dynamic model
:param init: Plot the spectra as per initilisation, defaults to False
:type init: bool, optional
:param fit_to_init: Plot the spectra as per fitting the dynamic model to init, defaults to False
:type fit_to_init: bool, optional
:param init:
:param indices: List of indicies to plot, defaults to None which plots all.
:type indices: list, optional
:return: plotly figure
from plotly.subplots import make_subplots
......@@ -427,6 +428,7 @@ class dynRes:
dyn_fit = np.asarray(dyn_fit)
dyn_fit_mean = np.mean(dyn_fit, axis=0)
dyn_fit_sd = np.std(dyn_fit.real, axis=0) + 1j * np.std(dyn_fit.imag, axis=0)
x_axis = self._dyn.mrs_list[0].getAxes(ppmlim=self._dyn._fit_args['ppmlim'])
colors = dict(data='rgb(67,67,67)',
......@@ -444,6 +446,13 @@ class dynRes:
sp_titles = [f'#{idx}: {t}' for idx, t in enumerate(self._dyn.time_var)]
if indices is not None:
init_fit = init_fit[indices, :]
init_fitted_fit = init_fitted_fit[indices, :]
dyn_fit_mean = dyn_fit_mean[indices, :]
dyn_fit_sd = dyn_fit_sd[indices, :]
sp_titles = np.asarray(sp_titles)[indices]
row, col = subplot_shape(len(sp_titles))
fig = make_subplots(rows=row, cols=col,
......@@ -92,7 +92,7 @@ def _hlsvd(FID, dwelltime, centralFrequency, limits,
:return: HLSVD modeled FID
m = FID.size // 2
r = hlsvdpropy.hlsvdpro(FID, numSingularValues, m=m, sparse=True)
r = hlsvdpropy.hlsvdpro(FID, numSingularValues, m=m, sparse=False)
r = hlsvdpropy.convert_hlsvd_result(r, dwelltime)
nsv_found, singular_values, frequencies, damping_factors, amplitudes, \
phases = r[0:6]
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