Skip to content

Commit

Permalink
split sim_across_values
Browse files Browse the repository at this point in the history
  • Loading branch information
TomDonoghue committed Sep 7, 2024
1 parent 40186b7 commit be22be1
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 12 deletions.
1 change: 1 addition & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ Multiple Signals

sim_multiple
sim_across_values
sim_multi_across_values
sim_from_sampler

Simulation Parameters
Expand Down
60 changes: 57 additions & 3 deletions neurodsp/sim/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from neurodsp.sim.signals import Simulations, VariableSimulations, MultiSimulations
from neurodsp.sim.generators import sig_yielder, sig_sampler
from neurodsp.sim.params import get_base_params
from neurodsp.utils.data import compute_nsamples

###################################################################################################
Expand Down Expand Up @@ -50,7 +51,60 @@ def sim_multiple(sim_func, sim_params, n_sims, return_type='object'):
return sims


def sim_across_values(sim_func, sim_params, n_sims, return_type='object'):
def sim_across_values(sim_func, sim_params, return_type='object'):
"""Simulate signals across different parameter values.
Parameters
----------
sim_func : callable
Function to create the simulated time series.
sim_params : ParamIter or iterable or list of dict
Simulation parameters for `sim_func`.
return_type : {'object', 'array'}
Specifies the return type of the simulations.
If 'object', returns simulations and metadata in a 'VariableSimulations' object.
If 'array', returns the simulations (no metadata) in an array.
Returns
-------
sims : VariableSimulations or array
Simulations, return type depends on `return_type` argument.
If array, signals are collected together as [n_sims, sig_length].
Examples
--------
Simulate multiple powerlaw signals using a ParamIter object:
>>> from neurodsp.sim.aperiodic import sim_powerlaw
>>> from neurodsp.sim.update import ParamIter
>>> base_params = {'n_seconds' : 2, 'fs' : 250, 'exponent' : None}
>>> param_iter = ParamIter(base_params, 'exponent', [-2, 1, 0])
>>> sims = sim_multi_across_values(sim_powerlaw, param_iter)
Simulate multiple powerlaw signals from manually defined set of simulation parameters:
>>> params = [{'n_seconds' : 2, 'fs' : 250, 'exponent' : -2},
... {'n_seconds' : 2, 'fs' : 250, 'exponent' : -1}]
>>> sims = sim_multi_across_values(sim_powerlaw, params)
"""

base = get_base_params(sim_params)

all_params = [None] * len(sim_params)
sims = np.zeros([len(sim_params), compute_nsamples(base['n_seconds'], base['fs'])])
for ind, cur_sim_params in enumerate(sim_params):
sims[ind, :] = sim_func(**cur_sim_params)
all_params[ind] = cur_sim_params

if return_type == 'object':
sims = VariableSimulations(sims, all_params, sim_func,
update=getattr(sim_params, 'update', None),
component=getattr(sim_params, 'component', None))

return sims


def sim_multi_across_values(sim_func, sim_params, n_sims, return_type='object'):
"""Simulate multiple signals across different parameter values.
Parameters
Expand Down Expand Up @@ -80,13 +134,13 @@ def sim_across_values(sim_func, sim_params, n_sims, return_type='object'):
>>> from neurodsp.sim.update import ParamIter
>>> base_params = {'n_seconds' : 2, 'fs' : 250, 'exponent' : None}
>>> param_iter = ParamIter(base_params, 'exponent', [-2, 1, 0])
>>> sigs = sim_across_values(sim_powerlaw, param_iter, n_sims=2)
>>> sims = sim_multi_across_values(sim_powerlaw, param_iter, n_sims=2)
Simulate multiple powerlaw signals from manually defined set of simulation parameters:
>>> params = [{'n_seconds' : 2, 'fs' : 250, 'exponent' : -2},
... {'n_seconds' : 2, 'fs' : 250, 'exponent' : -1}]
>>> sigs = sim_across_values(sim_powerlaw, params, n_sims=2)
>>> sims = sim_multi_across_values(sim_powerlaw, params, n_sims=2)
"""

sims = MultiSimulations(update=getattr(sim_params, 'update', None),
Expand Down
41 changes: 32 additions & 9 deletions neurodsp/tests/sim/test_multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,47 @@ def test_sim_multiple():

def test_sim_across_values(tsim_iters):

params = [{'n_seconds' : 2, 'fs' : 250, 'exponent' : -2},
{'n_seconds' : 2, 'fs' : 250, 'exponent' : -1}]

sims_obj = sim_across_values(sim_powerlaw, params, 'object')
assert isinstance(sims_obj, VariableSimulations)
assert len(sims_obj) == len(params)
for csim, cparams, oparams in zip(sims_obj, sims_obj.params, params):
assert isinstance(csim, np.ndarray)
assert cparams == oparams

sims_arr = sim_across_values(sim_powerlaw, params, 'array')
assert isinstance(sims_arr, np.ndarray)
assert sims_arr.shape[0] == len(params)

# Test with ParamIter input
siter = tsim_iters['pl_exp']
sims_iter = sim_across_values(sim_powerlaw, siter)
assert isinstance(sims_iter, VariableSimulations)
assert sims_iter.update == siter.update
assert sims_iter.values == siter.values

def test_sim_multi_across_values(tsim_iters):

n_sims = 3
params = [{'n_seconds' : 2, 'fs' : 250, 'exponent' : -2},
{'n_seconds' : 2, 'fs' : 250, 'exponent' : -1}]

sims_obj = sim_across_values(sim_powerlaw, params, n_sims, 'object')
sims_obj = sim_multi_across_values(sim_powerlaw, params, n_sims, 'object')
assert isinstance(sims_obj, MultiSimulations)
for sigs, cparams in zip(sims_obj, params):
assert isinstance(sigs, Simulations)
assert len(sigs) == n_sims
assert sigs.params == cparams
for sims, cparams in zip(sims_obj, params):
assert isinstance(sims, Simulations)
assert len(sims) == n_sims
assert sims.params == cparams

sigs_arr = sim_across_values(sim_powerlaw, params, n_sims, 'array')
assert isinstance(sigs_arr, np.ndarray)
assert sigs_arr.shape[0:2] == (len(params), n_sims)
sims_arr = sim_multi_across_values(sim_powerlaw, params, n_sims, 'array')
assert isinstance(sims_arr, np.ndarray)
assert sims_arr.shape[0:2] == (len(params), n_sims)

# Test with ParamIter input
siter = tsim_iters['pl_exp']
sims_iter = sim_across_values(sim_powerlaw, siter, n_sims)
sims_iter = sim_multi_across_values(sim_powerlaw, siter, n_sims)
assert isinstance(sims_iter, MultiSimulations)
assert sims_iter.update == siter.update
assert sims_iter.values == siter.values
Expand Down

0 comments on commit be22be1

Please sign in to comment.