diff --git a/bluepyopt/__init__.py b/bluepyopt/__init__.py index 845ff93..c460bc6 100644 --- a/bluepyopt/__init__.py +++ b/bluepyopt/__init__.py @@ -25,6 +25,8 @@ __version__ = get_versions()['version'] del get_versions +from . import tools # NOQA + from .api import * # NOQA import bluepyopt.optimisations import bluepyopt.deapext.optimisations diff --git a/bluepyopt/ephys/evaluators.py b/bluepyopt/ephys/evaluators.py index cf16c0f..5cb1eed 100644 --- a/bluepyopt/ephys/evaluators.py +++ b/bluepyopt/ephys/evaluators.py @@ -26,6 +26,7 @@ logger = logging.getLogger(__name__) import bluepyopt as bpopt +import bluepyopt.tools class CellEvaluator(bpopt.evaluators.Evaluator): @@ -39,7 +40,8 @@ def __init__( fitness_protocols=None, fitness_calculator=None, isolate_protocols=None, - sim=None): + sim=None, + use_params_for_seed=False): """Constructor Args: @@ -57,6 +59,8 @@ def __init__( hinder the reproducability of the simulations) sim (ephys.simulators.NrnSimulator): simulator to use for the cell evaluation + use_params_for_seed (bool): use a hashed version of the parameter + dictionary as a seed for the simulator """ super(CellEvaluator, self).__init__( @@ -77,6 +81,7 @@ def __init__( self.fitness_calculator = fitness_calculator self.isolate_protocols = isolate_protocols + self.use_params_for_seed = use_params_for_seed def param_dict(self, param_array): """Convert param_array in param_dict""" @@ -114,13 +119,34 @@ def objective_list(self, objective_dict): return objective_list - def run_protocol(self, protocol, param_values, isolate=None): + @staticmethod + def seed_from_param_dict(param_dict): + """Return a seed value based on a param_dict""" + + sorted_keys = sorted(param_dict.keys()) + + string = '' + for key in sorted_keys: + string += '%s%s' % (key, str(param_dict[key])) + + return bluepyopt.tools.uint32_seed(string) + + def run_protocol( + self, + protocol, + param_values, + isolate=None, + cell_model=None, + sim=None): """Run protocol""" + if self.use_params_for_seed: + sim.random123_globalindex = self.seed_from_param_dict(param_values) + return protocol.run( - self.cell_model, + self.cell_model if cell_model is None else cell_model, param_values, - sim=self.sim, + sim=self.sim if sim is None else sim, isolate=isolate) def run_protocols(self, protocols, param_values): diff --git a/bluepyopt/tests/test_tools.py b/bluepyopt/tests/test_tools.py new file mode 100644 index 0000000..0f8d64e --- /dev/null +++ b/bluepyopt/tests/test_tools.py @@ -0,0 +1,39 @@ +"""Test bluepyopt.tools""" + +from nose.plugins.attrib import attr +import nose.tools as nt + + +@attr('unit') +def test_load(): + """Tools: test import""" + + import bluepyopt.tools # NOQA + + +@attr('unit') +def test_uint32_seed(): + """Tools: test uint32_seed""" + + import bluepyopt.tools as bpoptools + + nt.assert_equal(bpoptools.uint32_seed("test"), 640136438) + + import random + random.seed(1) + + hashes = [] + strings = [] + for _ in range(1000): + string = ''.join( + (chr(random.randint(0, 127)) for x in + xrange(random.randint(10, 255)))) + strings.append(string) + hashes.append(bpoptools.uint32_seed(string)) + + nt.assert_equal(len(strings), len(set(strings))) + nt.assert_equal(len(hashes), len(set(hashes))) + + import numpy + for hash_value in hashes: + nt.assert_equal(hash_value, numpy.uint32(hash_value)) diff --git a/bluepyopt/tools.py b/bluepyopt/tools.py new file mode 100644 index 0000000..f46275d --- /dev/null +++ b/bluepyopt/tools.py @@ -0,0 +1,11 @@ +"""BluePyOpt tools""" + +import hashlib + + +def uint32_seed(string): + """Get unsigned int seed of a string""" + + hex_value = hashlib.md5(string).hexdigest() + + return int(hex_value, 16) & 0xFFFFFFFF diff --git a/examples/stochkv/stochkvcell.py b/examples/stochkv/stochkvcell.py index b997e55..74c6159 100644 --- a/examples/stochkv/stochkvcell.py +++ b/examples/stochkv/stochkvcell.py @@ -55,11 +55,12 @@ def run_stochkv_model(deterministic=False): param_name='celsius', value=34.0, frozen=True) + params = [epas_param, celsius_param, gkbar_param] stochkv_cell = ephys.models.CellModel( name='stochkv_cell', morph=morph, mechs=[pas_mech, stochkv_mech], - params=[epas_param, celsius_param, gkbar_param]) + params=params) soma_loc = ephys.locations.NrnSeclistCompLocation( name='soma', @@ -88,8 +89,18 @@ def run_stochkv_model(deterministic=False): nrn = ephys.simulators.NrnSimulator(cvode_active=False) + evaluator = ephys.evaluators.CellEvaluator( + cell_model=stochkv_cell, + param_names=[param.name for param in params], + fitness_calculator=ephys.objectivescalculators.ObjectivesCalculator(), + sim=nrn) + best_param_values = {'gkbar_StochKv': 0.5} - responses = protocol.run(stochkv_cell, best_param_values, sim=nrn) + responses = evaluator.run_protocol( + protocol, + cell_model=stochkv_cell, + param_values=best_param_values, + sim=nrn) hoc_string = stochkv_cell.create_hoc( param_values=best_param_values, @@ -104,10 +115,11 @@ def run_stochkv_model(deterministic=False): hoc_responses = protocol.run(stochkv_hoc_cell, best_param_values, sim=nrn) - nrn.random123_globalindex = 1.0 - different_seed_responses = protocol.run( - stochkv_cell, - best_param_values, + evaluator.use_params_for_seed = True + different_seed_responses = evaluator.run_protocol( + protocol, + cell_model=stochkv_cell, + param_values=best_param_values, sim=nrn) return responses, hoc_responses, different_seed_responses, hoc_string