diff --git a/neurodamus/connection.py b/neurodamus/connection.py index e60634c0..8d89ee3d 100644 --- a/neurodamus/connection.py +++ b/neurodamus/connection.py @@ -714,36 +714,12 @@ def create_on(self, conn, sec, position, syn_obj, syn_params, base_seed, _rate_v self._store(ips, netcon) src_pop_id, dst_pop_id = conn.population_id - rng_mode = self._rng_info.getRNGMode() rng_seed = self._rng_info.getMinisSeed() tgid_seed = conn.tgid + 250 - if rng_mode == self._rng_info.RANDOM123: - seed2 = (src_pop_id * 65536 + dst_pop_id + rng_seed) - ips.setRNGs(syn_obj.synapseID + 200, tgid_seed, seed2 + 300, - syn_obj.synapseID + 200, tgid_seed, seed2 + 350) - else: - seed2 = src_pop_id * 16777216 - exprng = Nd.Random() - if rng_mode == self._rng_info.COMPATIBILITY: - exprng.MCellRan4(syn_obj.synapseID * 100000 + 200, - tgid_seed + base_seed + rng_seed) - else: # if ( rngIndo.getRNGMode()== rng_info.UPMCELLRAN4 ): - exprng.MCellRan4(syn_obj.synapseID * 1000 + 200, - seed2 + tgid_seed + base_seed + rng_seed) - - exprng.negexp(1) - uniformrng = Nd.Random() - if rng_mode == self._rng_info.COMPATIBILITY: - uniformrng.MCellRan4(syn_obj.synapseID * 100000 + 300, - tgid_seed + base_seed + rng_seed) - else: # if ( rngIndo.getRNGMode()== rng_info.UPMCELLRAN4 ): - uniformrng.MCellRan4(syn_obj.synapseID * 1000 + 300, - seed2 + tgid_seed + base_seed + rng_seed) - - uniformrng.uniform(0.0, 1.0) - ips.setRNGs(exprng, uniformrng) - self._keep_alive += (exprng, uniformrng) + seed2 = (src_pop_id * 65536 + dst_pop_id + rng_seed) + ips.setRNGs(syn_obj.synapseID + 200, tgid_seed, seed2 + 300, + syn_obj.synapseID + 200, tgid_seed, seed2 + 350) def __bool__(self): """object is considered False in case rate is not positive""" diff --git a/neurodamus/core/configuration.py b/neurodamus/core/configuration.py index 53adfc44..c67d8240 100644 --- a/neurodamus/core/configuration.py +++ b/neurodamus/core/configuration.py @@ -108,8 +108,6 @@ class CircuitConfig(ConfigT): class RNGConfig(ConfigT): - Modes = Enum("Mode", "COMPATIBILITY RANDOM123 UPMCELLRAN4") - mode = Modes.COMPATIBILITY global_seed = None IonChannelSeed = None StimulusSeed = None diff --git a/neurodamus/core/random.py b/neurodamus/core/random.py index 82af0db0..b3e161d9 100644 --- a/neurodamus/core/random.py +++ b/neurodamus/core/random.py @@ -3,57 +3,36 @@ """ from __future__ import absolute_import from . import Neuron -from neurodamus.core.configuration import RNGConfig -# NOTE: These are pure wrappers, in the sense they dont create Python objects. Instead +# NOTE: These are pure wrappers, in the sense they don't create Python objects. Instead # Neuron objects are returned (using __new__) class RNG(object): - def __new__(cls, *ids, **kw): - """Creates a default RNG, currently based on ACG""" - seed = kw.get("seed") - return Neuron.h.Random() if seed is None else Neuron.h.Random(seed) + def __new__(cls, **kw): + """Creates a default RNG (Random123 with ids of 0,1,2)""" + seed = kw.get("seed", 0) + return Random123(0, 1, 2, seed) @classmethod - def create(cls, rng_mode, ids, seed=None): - # type: (RNGConfig, tuple, object) -> RNG - if rng_mode == RNGConfig.Modes.RANDOM123: - assert len(ids) == 3, "Random123 requires three ids (as a tuple)" - obj = Random123(ids[0], ids[1], ids[2], seed) - elif rng_mode == RNGConfig.Modes.UPMCELLRAN4: - assert len(ids) == 1 - obj = MCellRan4(ids[0], seed) - else: - obj = RNG(seed) + def create(cls, ids, seed=None): + # type: (tuple, object) -> RNG + assert len(ids) == 3, "Random123 requires three ids (as a tuple)" + obj = Random123(ids[0], ids[1], ids[2], seed) return obj -class ACG(RNG): - def __new__(cls, size=None, seed=None): - rng = RNG(seed=seed) - rng.ACG(seed, size) - return rng - - class Random123(RNG): def __new__(cls, id1, id2, id3, seed=None): - rng = RNG() + rng = Neuron.h.Random() if seed is None else Neuron.h.Random(seed) if seed is not None: rng.Random123_globalindex(seed) rng.Random123(id1, id2, id3) return rng -class MCellRan4(RNG): - def __new__(cls, high_i, seed=None, low_i=0): - rng = RNG(seed=seed) - rng.MCellRan4(high_i, low_i) - return rng - - # Gamma-distributed sample generator (not available in NEURON) def gamma(rng, a, b, N=1): """ diff --git a/neurodamus/data/hoc/RNGSettings.hoc b/neurodamus/data/hoc/RNGSettings.hoc index 51819462..86801e9b 100644 --- a/neurodamus/data/hoc/RNGSettings.hoc +++ b/neurodamus/data/hoc/RNGSettings.hoc @@ -7,7 +7,7 @@ */ {load_file("fileUtils.hoc")} -rngMode = 0 // corresponds to COMPATIBILITY defined below +rngMode = 1 // corresponds to RANDOM123 defined below ionchannelSeed = 0 synapseSeed = 0 stimulusSeed = 0 @@ -17,15 +17,13 @@ globalSeed = 0 begintemplate RNGSettings public init, interpret, getRNGMode, getIonChannelSeed, getSynapseSeed, getStimulusSeed, getMinisSeed, getGlobalSeed -public COMPATIBILITY, RANDOM123, UPMCELLRAN4 +public RANDOM123 external rngMode, ionchannelSeed, synapseSeed, stimulusSeed, minisSeed, globalSeed, terminate proc init() { // consts for random number handling - COMPATIBILITY = 0 RANDOM123 = 1 - UPMCELLRAN4 = 2 } /** @@ -50,40 +48,21 @@ proc interpret() { local coreNeuronUsed localobj runInfo, pc, rng if( runInfo.exists( "RNGMode" ) ) { rngModeField = runInfo.get( "RNGMode" ).s - if( strcmp( rngModeField, "Compatibility" ) == 0 ) { - rngMode = COMPATIBILITY - } else if( strcmp( rngModeField, "UpdatedMCell" ) == 0 ) { - rngMode = UPMCELLRAN4 - } else if( strcmp( rngModeField, "Random123" ) == 0 ) { + if( strcmp( rngModeField, "Random123" ) == 0 ) { rngMode = RANDOM123 } else { - terminate( "Invalid RNGMode ", rngModeField ) + terminate( "Invalid RNGMode (only Random123 is currently supported) ", rngModeField ) } - if( pc.id() == 0 ) { - print "RNGMode set to ", rngMode, " [COMPATIBILITY=0, RANDOM123=1, UPMCELLRAN4=2]" - } - } - - if( coreNeuronUsed && rngMode != RANDOM123) { - // Given R123 is now the default there's no sense to allow an explicit invalid option - terminate( "Config Error: CoreNEURON requires Random123 RNG" ) } if( runInfo.exists("BaseSeed") ) { globalSeed = runInfo.valueOf( "BaseSeed" ) // random123 can set the global index now - if( rngMode == RANDOM123 ) { - rng = new Random() - rng.Random123_globalindex( globalSeed ) - } + rng = new Random() + rng.Random123_globalindex( globalSeed ) } - // don't search for indicidual seeds if we are in compatibility mode - if( rngMode == COMPATIBILITY ) { - return - } - if( runInfo.exists("IonChannelSeed") ) { ionchannelSeed = runInfo.valueOf( "IonChannelSeed" ) } @@ -123,120 +102,3 @@ func getGlobalSeed() { } endtemplate RNGSettings - - -/////////////////////////////////////////////////////////////////////// -/// -/// These are legacy functions to keep compaltibility -/// -/////////////////////////////////////////////////////////////////////// - -/*! - * In place of using a CCell's re_init_rng function, we will check for cells that define the re_init_rng function, - * but then setRNG using global seed as well - * - * @param $o1 CCell which is to be checked for setRNG - */ -obfunc rngForStochKvInit() { local channelID, hasStochKv localobj CCell, rng, rngInfo, rngList, pc - CCell = $o1 - //print "Replace rng for stochKv in gid ", CCell.CellRef.gid - - // quick check to verify this object contains StochKv - hasStochKv = 0 - CCell.CellRef.soma { - if( ismembrane( "StochKv" ) ) { - hasStochKv = 1 - } - } - - if( !hasStochKv ) { - return - } - - rngList = new List() - - channelID = 0 - forsec CCell.CellRef.somatic { - for (x, 0) { - setdata_StochKv(x) - rng = new Random() - rng.MCellRan4( channelID*10000+100, globalSeed + ionchannelSeed + CCell.CellRef.gid*10000+250+1 ) - channelID = channelID + 1 - rng.uniform(0,1) - setRNG_StochKv(rng) - rngList.append(rng) - } - } - forsec CCell.CellRef.basal { - for (x, 0) { - setdata_StochKv(x) - rng = new Random() - rng.MCellRan4( channelID*10000+100, globalSeed + ionchannelSeed + CCell.CellRef.gid*10000+250+1 ) - channelID = channelID + 1 - rng.uniform(0,1) - setRNG_StochKv(rng) - rngList.append(rng) - } - } - forsec CCell.CellRef.apical { - for (x, 0) { - setdata_StochKv(x) - rng = new Random() - rng.MCellRan4( channelID*10000+100, globalSeed + ionchannelSeed + CCell.CellRef.gid*10000+250+1 ) - channelID = channelID + 1 - rng.uniform(0,1) - setRNG_StochKv(rng) - rngList.append(rng) - } - } - - return rngList -} - -//----------------------------------------------------------------------------------------------- - -/*! - * In place of using a CCell's re_init_rng function, we will check for cells that define the re_init_rng function, - * but then setRNG using random123 - * - * @param $o1 CCell which is to be checked for setRNG - */ -proc rng123ForStochKvInit() { local channelID, hasStochKv localobj CCell - CCell = $o1 - //print "Replace rng for stochKv in gid ", CCell.CellRef.gid - - // quick check to verify this object contains StochKv - hasStochKv = 0 - CCell.CellRef.soma { - if( ismembrane( "StochKv" ) ) { - hasStochKv = 1 - } - } - - if( !hasStochKv ) { - return - } - - channelID = 0 - forsec CCell.CellRef.somatic { - for (x, 0) { - setdata_StochKv(x) - setRNG_StochKv(ionchannelSeed, channelID, CCell.CellRef.gid + 1) - channelID = channelID + 1 - } - } - forsec CCell.CellRef.basal { - for (x, 0) { - setdata_StochKv(x) - setRNG_StochKv(ionchannelSeed, channelID, CCell.CellRef.gid + 1) - channelID = channelID + 1 - } - } - forsec CCell.CellRef.apical { - for (x, 0) { - setdata_StochKv(x) - setRNG_StochKv(ionchannelSeed, channelID, CCell.CellRef.gid + 1) - channelID = channelID + 1 - } - } -} diff --git a/neurodamus/stimulus_manager.py b/neurodamus/stimulus_manager.py index 2b40b8a3..78fc38b4 100644 --- a/neurodamus/stimulus_manager.py +++ b/neurodamus/stimulus_manager.py @@ -561,15 +561,11 @@ def __init__(self, target, stim_info: dict, cell_manager): self.parse_check_all_parameters(stim_info) sim_dt = float(SimConfig.run_conf["Dt"]) # simulation time-step [ms] - rng_mode = SimConfig.rng_info.getRNGMode() # simulation RNGMode # setup RNG - if rng_mode == SimConfig.rng_info.RANDOM123: - rand = lambda gid: random.Random123(Noise.stimCount + 100, - SimConfig.rng_info.getStimulusSeed() + 500, - gid + 300) - else: - raise Exception("rng_mod is not RANDOM123") + rand = lambda gid: random.Random123(Noise.stimCount + 100, + SimConfig.rng_info.getStimulusSeed() + 500, + gid + 300) # apply stim to each point in target tpoints = target.getPointList(cell_manager) diff --git a/tests/integration/test_neuron.py b/tests/integration/test_neuron.py index 1d062094..b7554477 100644 --- a/tests/integration/test_neuron.py +++ b/tests/integration/test_neuron.py @@ -15,4 +15,4 @@ def test_base_h(): def neurodamus(): from neurodamus.core import NeurodamusCore as Nd rng_conf = Nd.RNGSettings() - assert rng_conf.RANDOM123 == 1 + assert rng_conf.getGlobalSeed() == 0