diff --git a/examples/notebooks/neuromodulation/data/connectivity_v2.json b/examples/notebooks/neuromodulation/data/connectivity_v2.json new file mode 100644 index 000000000..9708f3f1e --- /dev/null +++ b/examples/notebooks/neuromodulation/data/connectivity_v2.json @@ -0,0 +1,28 @@ +{ + "regions": { + "Cube": { + "connectivity": { + "dspn,dspn": { + "GABA": { + "conductance": [ + 1e-9, + 1e-3 + ], + "channel_parameters": { + "mod_file": "tmGabaA" + }, + "cluster_size": 1, + "cluster_spread": null, + "pruning": { + "f1": null, + "soft_max": null, + "mu2": null, + "a3": null, + "cluster_pruning": false + } + } + } + } + } + } +} diff --git a/examples/notebooks/neuromodulation/data/input_v4.json b/examples/notebooks/neuromodulation/data/input_v4.json new file mode 100644 index 000000000..edcdde114 --- /dev/null +++ b/examples/notebooks/neuromodulation/data/input_v4.json @@ -0,0 +1,31 @@ +{ + "0": { + "cortical" : { + "generator" : "poisson", + "start" : [0], + "end" : [2], + "frequency" : [5], + "conductance" : 0.5e-9, + "input_correlation": 0.5, + "num_inputs" : 50, + "parameter_file": "data/tmglut_DA_parameters.json", + "mod_file": "tmGlut" + }, + "DA" : { + "generator" : "poisson", + "start" : [0.3], + "end" : [1.3], + "frequency" : [20], + "conductance" : 0.5e-9, + "num_inputs" : 200, + "num_soma_synapses" : 10, + "mod_file": "DASyn", + "RxD": { + "species_name": "DA", + "flux_variable": "open", + "region": "internal", + "weight_scale": 1e18 + } + } + } +} diff --git a/snudda/cli.py b/snudda/cli.py index 557a991d9..099321e10 100644 --- a/snudda/cli.py +++ b/snudda/cli.py @@ -144,12 +144,13 @@ def snudda_cli(): simulate_parser.add_argument("--disableGJ", "--disableGapJunctions", action="store_true", dest="disable_gj", default=None, help="Disable gap junctions") - simulate_parser.add_argument("-mechdir", "--mechDir", dest="mech_dir", + simulate_parser.add_argument("--mechdir", "--mechDir", dest="mech_dir", help="mechanism directory if not default", default=None) simulate_parser.add_argument("--profile", help="Run python cProfile", action="store_true") simulate_parser.add_argument("--verbose", action="store_true") simulate_parser.add_argument("--exportCoreNeuron", action="store_true") simulate_parser.add_argument("--recordALL", dest="record_all", type=str, default=None) + simulate_parser.add_argument("--disable_rxd_neuromodulation", dest="use_rxd_neuromodulation", action="store_false", default=True) export_parser = sub_parsers.add_parser("export") export_parser.add_argument("path", help="Location of network") diff --git a/snudda/core.py b/snudda/core.py index 840396b55..f0ab8d702 100755 --- a/snudda/core.py +++ b/snudda/core.py @@ -716,6 +716,7 @@ def simulate_wrapper(self, args): record_all=args.record_all, simulation_config=args.simulation_config, export_core_neuron=args.exportCoreNeuron, + use_rxd_neuromodulation=args.use_rxd_neuromodulation, verbose=args.verbose) sim.clear_neuron() @@ -735,6 +736,7 @@ def simulate(self, sample_dt=None, simulation_config=None, export_core_neuron=False, + use_rxd_neuromodulation=True, verbose=False): start = timeit.default_timer() @@ -811,6 +813,7 @@ def simulate(self, log_file=log_file, simulation_config=simulation_config, sample_dt=sample_dt, + use_rxd_neuromodulation=use_rxd_neuromodulation, verbose=verbose) sim.setup() sim.add_external_input() diff --git a/snudda/neurons/neuron_model_extended.py b/snudda/neurons/neuron_model_extended.py index df18b7318..060b6a0ae 100644 --- a/snudda/neurons/neuron_model_extended.py +++ b/snudda/neurons/neuron_model_extended.py @@ -31,7 +31,8 @@ def __init__(self, modulation_id=None, parameter_key=None, morphology_key=None, - modulation_key=None): + modulation_key=None, + use_rxd_neuromodulation=True): """ Constructor @@ -61,6 +62,7 @@ def __init__(self, self.script_dir = os.path.dirname(__file__) self.config_dir = os.path.join(self.script_dir, 'config') + self.use_rxd_neuromodulation = use_rxd_neuromodulation if os.path.isfile(morph_path): # If morph_path is a swc file, use it directly @@ -114,7 +116,7 @@ def __init__(self, super(NeuronModel, self).__init__(name=cell_name, morph=morph, mechs=mechs, params=params) - if reaction_diffusion_file: + if reaction_diffusion_file and self.use_rxd_neuromodulation: self.modulation = NeuronModulation(neuron=self) self.modulation.config_file = reaction_diffusion_file else: diff --git a/snudda/neurons/neuron_modulation.py b/snudda/neurons/neuron_modulation.py index 8cba32a45..6caadeb60 100644 --- a/snudda/neurons/neuron_modulation.py +++ b/snudda/neurons/neuron_modulation.py @@ -6,7 +6,7 @@ # TODO: Move DA species to external compartment. IMPORTANT. import numpy as np -import neuron.crxd as rxd +import neuron.rxd as rxd import json from itertools import chain diff --git a/snudda/simulate/simulate.py b/snudda/simulate/simulate.py index 2bf0dd12a..5f6e2900c 100644 --- a/snudda/simulate/simulate.py +++ b/snudda/simulate/simulate.py @@ -59,6 +59,7 @@ def __init__(self, disable_synapses=None, disable_gap_junctions=None, sample_dt=None, + use_rxd_neuromodulation=True, simulation_config=None): """ @@ -124,6 +125,7 @@ def __init__(self, self.neuron_id = None self.neuron_id_on_node = None self.synapse_parameters = None + self.use_rxd_neuromodulation = use_rxd_neuromodulation self.sim_start_time = 0 self.fih_time = None @@ -293,7 +295,7 @@ def setup_parse_sim_info(self): self.add_volt_recording_soma(cell_id=record_soma_cell_id) if "record_all_compartments" in self.sim_info: - raise DeprecationWarning("record_all_compartments depricated, please use record_voltate_all_compartments") + raise DeprecationWarning("record_all_compartments deprecated, please use record_voltate_all_compartments") record_comp_cell_id = np.array(self.sim_info["record_all_compartments"], dtype=int) self.add_volt_recording_all(cell_id=record_comp_cell_id) @@ -302,7 +304,7 @@ def setup_parse_sim_info(self): self.add_volt_recording_all(cell_id=record_comp_cell_id) if "record_all_synapses" in self.sim_info: - raise DeprecationWarning("record_all_synapses depricated, please use record_current_all_synapses") + raise DeprecationWarning("record_all_synapses deprecated, please use record_current_all_synapses") record_syn_cell_id = np.array(self.sim_info["record_all_synapses"], dtype=int) self.add_synapse_current_recording_all(record_syn_cell_id) @@ -310,7 +312,11 @@ def setup_parse_sim_info(self): record_syn_cell_id = np.array(self.sim_info["record_current_all_synapses"], dtype=int) self.add_synapse_current_recording_all(record_syn_cell_id) - if "record_rxd_species_concentration_all_compartments" in self.sim_info: + if "rxd_enable_extracellular" in self.sim_info: + import neuron.rxd as rxd + rxd.options.enable.extracellular = self.sim_info["rxd_enable_extracellular"] + + if "record_rxd_species_concentration_all_compartments" in self.sim_info and self.use_rxd_neuromodulation: rec_info = self.sim_info["record_rxd_species_concentration_all_compartments"] @@ -323,6 +329,11 @@ def setup_parse_sim_info(self): for rxd_neuron_id in record_rxd_neuron_id: self.add_rxd_internal_concentration_recording_all(record_rx_species, rxd_neuron_id) + if "record_rxd_species_all" in self.sim_info and self.use_rxd_neuromodulation: + rxd_record_neuron_id = self.sim_info["record_rxd_species_all"] + + self.add_rxd_internal_concentration_recording_all_species(neuron_id=rxd_record_neuron_id) + if "record_density_mechanism" in self.sim_info: record_info = self.sim_info["record_density_mechanism"] @@ -648,7 +659,8 @@ def setup_neurons(self): reaction_diffusion_file=reaction_diffusion_file, parameter_key=parameter_key, morphology_key=morphology_key, - modulation_key=modulation_key) + modulation_key=modulation_key, + use_rxd_neuromodulation=self.use_rxd_neuromodulation) # Register ID as belonging to this worker node try: @@ -1190,7 +1202,7 @@ def add_synapse(self, cell_id_source, cell_id_dest, dend_compartment, section_id import pdb pdb.set_trace() - if "RxD" in par_set: + if "RxD" in par_set and self.use_rxd_neuromodulation: species_name = par_set["RxD"]["species_name"] region = par_set["RxD"]["region"] @@ -1412,7 +1424,7 @@ def add_external_input(self, input_file=None): def get_rxd_external_input_parameters(self, neuron_input): - if "RxD" in neuron_input.attrs.keys(): + if "RxD" in neuron_input.attrs.keys() and self.use_rxd_neuromodulation: rxd_dict = json.loads(neuron_input.attrs["RxD"]) @@ -1849,6 +1861,10 @@ def add_synapse_current_recording(self, source_id, dest_id): def add_rxd_concentration_recording(self, species: str, neuron_id: int, region, sec_id, sec_x): + if not self.use_rxd_neuromodulation: + print(f"add_rxd_concentration_recording: not enabled, ignoring recording of {species} in neuron {neuron_id}") + return + if sec_id == -1: sec_type = "soma" elif sec_id >= 0: @@ -1881,6 +1897,10 @@ def add_rxd_internal_concentration_recording_all(self, species, neuron_id): if neuron_id not in self.neuron_id: return + if not self.use_rxd_neuromodulation: + print(f"add_rxd_internal_concentration_recording_all: not enabled, ignoring recording of {species} in neuron {neuron_id}") + return + # Add soma self.add_rxd_concentration_recording(species, neuron_id, "soma_internal", "soma", -1, 0.5) @@ -1889,11 +1909,23 @@ def add_rxd_internal_concentration_recording_all(self, species, neuron_id): f"Internal error, assumed {sid} was section id of {sec.name()}" self.add_rxd_concentration_recording(species, neuron_id, "dend_internal", "dend", sid, 0.5) - def add_rxd_internal_concentration_recording_all_species(self, neuron_id): + def add_rxd_internal_concentration_recording_all_species(self, neuron_id, quiet=False): + + if not quiet: + self.write_log(f"Recording all RxD species from neurons: {neuron_id}") + + if isinstance(neuron_id, (list, np.ndarray)): + for nid in neuron_id: + self.add_rxd_internal_concentration_recording_all_species(neuron_id=nid, quiet=True) + return if neuron_id not in self.neuron_id: return + if not self.use_rxd_neuromodulation: + print(f"add_rxd_internal_concentration_recording_all_species: not enabled, ignoring recording of neuron {neuron_id}") + return + for species in self.neurons[neuron_id].modulation.species.keys(): # Add soma