diff --git a/docs/api/simulator.rst b/docs/api/simulator.rst index 9feedae..2a41fcc 100644 --- a/docs/api/simulator.rst +++ b/docs/api/simulator.rst @@ -6,10 +6,8 @@ Simulator .. autosummary:: :toctree: _toctree - distribute_synapse_locations - generate_distance_connections - generate_input_features - generate_input_spike_trains - generate_soma_coordinates - make_h5types + distribute_synapses + generate_connections + generate_network_architecture + generate_synapse_forest measure_distances diff --git a/src/miv_simulator/config.py b/src/miv_simulator/config.py index ea48363..35c993d 100644 --- a/src/miv_simulator/config.py +++ b/src/miv_simulator/config.py @@ -13,6 +13,8 @@ # Definitions +SWCFilePath = str + class SWCTypesDef(IntEnum): soma = 1 diff --git a/src/miv_simulator/simulator/generate_input_features.py b/src/miv_simulator/input_features.py similarity index 100% rename from src/miv_simulator/simulator/generate_input_features.py rename to src/miv_simulator/input_features.py diff --git a/src/miv_simulator/simulator/generate_input_spike_trains.py b/src/miv_simulator/input_spike_trains.py similarity index 100% rename from src/miv_simulator/simulator/generate_input_spike_trains.py rename to src/miv_simulator/input_spike_trains.py diff --git a/src/miv_simulator/interface/distance_connections.py b/src/miv_simulator/interface/connections.py similarity index 94% rename from src/miv_simulator/interface/distance_connections.py rename to src/miv_simulator/interface/connections.py index cf58c23..cc8ba98 100644 --- a/src/miv_simulator/interface/distance_connections.py +++ b/src/miv_simulator/interface/connections.py @@ -4,14 +4,13 @@ from machinable import Component from pydantic import BaseModel, Field -from miv_simulator import config +from miv_simulator import config, simulator from typing import Optional, Dict -from miv_simulator.simulator import distance_connections from miv_simulator.utils import from_yaml from mpi4py import MPI -class DistanceConnections(Component): +class Connections(Component): class Config(BaseModel): filepath: str = Field("???") forest_filepath: str = Field("???") @@ -44,7 +43,7 @@ def output_filepath(self): def __call__(self): logging.basicConfig(level=logging.INFO) - distance_connections( + simulator.generate_connections( filepath=self.config.filepath, forest_filepath=self.config.forest_filepath, include_forest_populations=self.config.include_forest_populations, diff --git a/src/miv_simulator/interface/measure_distances.py b/src/miv_simulator/interface/distances.py similarity index 94% rename from src/miv_simulator/interface/measure_distances.py rename to src/miv_simulator/interface/distances.py index 260f381..7fda203 100644 --- a/src/miv_simulator/interface/measure_distances.py +++ b/src/miv_simulator/interface/distances.py @@ -5,8 +5,7 @@ from machinable import Component from machinable.config import Field -from miv_simulator.simulator import measure_distances -from miv_simulator import config +from miv_simulator import config, simulator from mpi4py import MPI @@ -32,7 +31,7 @@ class Config(BaseModel): def __call__(self): logging.basicConfig(level=logging.INFO) - measure_distances( + simulator.measure_distances( filepath=self.config.filepath, geometry_filepath=self.config.geometry_filepath, coordinate_namespace=self.config.coordinate_namespace, diff --git a/src/miv_simulator/interface/create_h5.py b/src/miv_simulator/interface/h5_types.py similarity index 88% rename from src/miv_simulator/interface/create_h5.py rename to src/miv_simulator/interface/h5_types.py index ec59f66..345f894 100644 --- a/src/miv_simulator/interface/create_h5.py +++ b/src/miv_simulator/interface/h5_types.py @@ -1,6 +1,4 @@ from machinable import Component -from machinable.element import normversion -from machinable.types import VersionType from pydantic import BaseModel, Field from miv_simulator import config from mpi4py import MPI @@ -8,7 +6,7 @@ from typing import Dict -class CreateH5(Component): +class H5Types(Component): class Config(BaseModel): cell_distributions: config.CellDistributions = Field("???") synapses: config.Synapses = Field("???") diff --git a/src/miv_simulator/interface/legacy/derive_spike_trains.py b/src/miv_simulator/interface/legacy/derive_spike_trains.py index 4e3b6ee..c9937b7 100644 --- a/src/miv_simulator/interface/legacy/derive_spike_trains.py +++ b/src/miv_simulator/interface/legacy/derive_spike_trains.py @@ -4,7 +4,7 @@ import numpy as np from machinable import Component from pydantic import Field, BaseModel -from miv_simulator.simulator import ( +from miv_simulator.input_spike_trains import ( generate_input_spike_trains, import_input_spike_train, ) diff --git a/src/miv_simulator/interface/legacy/input_features.py b/src/miv_simulator/interface/legacy/input_features.py index 2821574..1c821d2 100644 --- a/src/miv_simulator/interface/legacy/input_features.py +++ b/src/miv_simulator/interface/legacy/input_features.py @@ -4,7 +4,7 @@ from pydantic import Field, BaseModel from machinable.element import normversion from machinable.types import VersionType -from miv_simulator.simulator import generate_input_features +from miv_simulator.input_features import generate_input_features class InputFeatures(Component): diff --git a/src/miv_simulator/interface/network_clamp/go.py b/src/miv_simulator/interface/legacy/network_clamp/go.py similarity index 100% rename from src/miv_simulator/interface/network_clamp/go.py rename to src/miv_simulator/interface/legacy/network_clamp/go.py diff --git a/src/miv_simulator/interface/network_clamp/optimize.py b/src/miv_simulator/interface/legacy/network_clamp/optimize.py similarity index 100% rename from src/miv_simulator/interface/network_clamp/optimize.py rename to src/miv_simulator/interface/legacy/network_clamp/optimize.py diff --git a/src/miv_simulator/interface/network_clamp/show.py b/src/miv_simulator/interface/legacy/network_clamp/show.py similarity index 100% rename from src/miv_simulator/interface/network_clamp/show.py rename to src/miv_simulator/interface/legacy/network_clamp/show.py diff --git a/src/miv_simulator/interface/legacy/prepare_data.py b/src/miv_simulator/interface/legacy/prepare_data.py index df34ee5..66dba60 100644 --- a/src/miv_simulator/interface/legacy/prepare_data.py +++ b/src/miv_simulator/interface/legacy/prepare_data.py @@ -42,17 +42,17 @@ def __call__(self): self.distance_connections = {} self.synapse_forest = {} for dependency in self.uses: - if dependency.module == "miv_simulator.interface.create_network": + if ( + dependency.module + == "miv_simulator.interface.network_architecture" + ): self.network = dependency elif ( dependency.module == "miv_simulator.interface.legacy.derive_spike_trains" ): self.spike_trains = dependency - elif ( - dependency.module - == "miv_simulator.interface.distance_connections" - ): + elif dependency.module == "miv_simulator.interface.connections": populations = read_population_names( dependency.config.forest_filepath ) @@ -74,10 +74,7 @@ def __call__(self): f"defined in {self.synapse_forest[dependency.config.population]}" ) self.synapse_forest[dependency.config.population] = dependency - elif ( - dependency.module - == "miv_simulator.interface.distribute_synapses" - ): + elif dependency.module == "miv_simulator.interface.synapses": if dependency.config.population in self.synapses: # check for duplicates raise ValueError( diff --git a/src/miv_simulator/interface/create_network.py b/src/miv_simulator/interface/network_architecture.py similarity index 86% rename from src/miv_simulator/interface/create_network.py rename to src/miv_simulator/interface/network_architecture.py index 9be1c36..64980b5 100644 --- a/src/miv_simulator/interface/create_network.py +++ b/src/miv_simulator/interface/network_architecture.py @@ -5,17 +5,14 @@ from machinable import Component from machinable.element import normversion from machinable.types import VersionType -from miv_simulator import config -from miv_simulator.simulator.soma_coordinates import ( - generate as generate_soma_coordinates, -) +from miv_simulator import config, simulator from miv_simulator.utils import io as io_utils, from_yaml from mpi4py import MPI from pydantic import BaseModel, Field -class CreateNetwork(Component): - """Creates neural H5 type definitions and soma coordinates within specified layer geometry.""" +class NetworkArchitecture(Component): + """Creates the network architecture by generating the soma coordinates within specified layer geometry.""" class Config(BaseModel): filepath: str = Field("???") @@ -45,7 +42,7 @@ def on_write_meta_data(self): def __call__(self) -> None: logging.basicConfig(level=logging.INFO) - generate_soma_coordinates( + simulator.generate_network_architecture( output_filepath=self.config.filepath, cell_distributions=self.config.cell_distributions, layer_extents=self.config.layer_extents, @@ -67,7 +64,7 @@ def __call__(self) -> None: def measure_distances(self, version: VersionType = None): return self.derive( - "miv_simulator.interface.measure_distances", + "miv_simulator.interface.distances", [ { "filepath": self.config.filepath, @@ -87,7 +84,9 @@ def measure_distances(self, version: VersionType = None): uses=self, ) - def synapse_forest(self, version: VersionType = None) -> "Component": + def generate_synapse_forest( + self, version: VersionType = None + ) -> "Component": return self.derive( "miv_simulator.interface.synapse_forest", [ @@ -101,14 +100,14 @@ def synapse_forest(self, version: VersionType = None) -> "Component": def distribute_synapses(self, version: VersionType = None): return self.derive( - "miv_simulator.interface.distribute_synapses", + "miv_simulator.interface.synapses", [] + normversion(version), uses=self, ) - def distance_connections(self, version: VersionType = None): + def generate_connections(self, version: VersionType = None): return self.derive( - "miv_simulator.interface.distance_connections", + "miv_simulator.interface.connections", [ { "filepath": self.config.filepath, diff --git a/src/miv_simulator/interface/synapse_forest.py b/src/miv_simulator/interface/synapse_forest.py index f57cf07..a540d49 100644 --- a/src/miv_simulator/interface/synapse_forest.py +++ b/src/miv_simulator/interface/synapse_forest.py @@ -1,26 +1,13 @@ -import os -import shutil -import subprocess - -import h5py from machinable import Component -from miv_simulator import config +from miv_simulator import config, simulator from pydantic import BaseModel, Field -def _bin_check(bin: str) -> None: - if not shutil.which(bin): - raise FileNotFoundError(f"{bin} not found. Did you add it to the PATH?") - - -SWCFilePath = str - - class GenerateSynapseForest(Component): class Config(BaseModel): filepath: str = Field("???") population: config.PopulationName = Field("???") - morphology: SWCFilePath = Field("???") + morphology: config.SWCFilePath = Field("???") @property def tree_output_filepath(self) -> str: @@ -31,60 +18,10 @@ def output_filepath(self) -> str: return self.local_directory("forest.h5") def __call__(self) -> None: - # create tree - if not os.path.isfile(self.tree_output_filepath): - _bin_check("neurotrees_import") - assert ( - subprocess.run( - [ - "neurotrees_import", - self.config.population, - self.tree_output_filepath, - self.config.morphology, - ] - ).returncode - == 0 - ) - assert ( - subprocess.run( - [ - "h5copy", - "-p", - "-s", - "/H5Types", - "-d", - "/H5Types", - "-i", - self.config.filepath, - "-o", - self.tree_output_filepath, - ] - ).returncode - == 0 - ) - - if not os.path.isfile(self.output_filepath): - # determine population ranges - with h5py.File(self.config.filepath, "r") as f: - idx = list( - reversed( - f["H5Types"]["Population labels"].dtype.metadata["enum"] - ) - ).index(self.config.population) - offset = f["H5Types"]["Populations"][idx][0] - - _bin_check("neurotrees_copy") - assert ( - subprocess.run( - [ - "neurotrees_copy", - "--fill", - "--output", - self.output_filepath, - self.tree_output_filepath, - self.config.population, - str(offset), - ] - ).returncode - == 0 - ) + simulator.generate_synapse_forest( + filepath=self.config.filepath, + tree_output_filepath=self.tree_output_filepath, + output_filepath=self.output_filepath, + population=self.config.population, + morphology=self.config.morphology, + ) diff --git a/src/miv_simulator/interface/distribute_synapses.py b/src/miv_simulator/interface/synapses.py similarity index 83% rename from src/miv_simulator/interface/distribute_synapses.py rename to src/miv_simulator/interface/synapses.py index 30863a6..cb11f1d 100644 --- a/src/miv_simulator/interface/distribute_synapses.py +++ b/src/miv_simulator/interface/synapses.py @@ -9,7 +9,7 @@ from mpi4py import MPI -class DistributeSynapses(Component): +class Synapses(Component): class Config(BaseModel): forest_filepath: str = Field("???") cell_types: config.CellTypes = Field("???") @@ -17,14 +17,10 @@ class Config(BaseModel): distribution: str = "uniform" mechanisms_path: str = "./mechanisms" template_path: str = "./templates" - dt: float = 0.025 - tstop: float = 0.0 - celsius: Optional[float] = 35.0 io_size: int = -1 write_size: int = 1 chunk_size: int = 1000 value_chunk_size: int = 1000 - use_coreneuron: bool = False ranks_: int = 8 nodes_: int = 1 @@ -44,15 +40,11 @@ def __call__(self): distribution=self.config.distribution, mechanisms_path=self.config.mechanisms_path, template_path=self.config.template_path, - dt=self.config.dt, - tstop=self.config.tstop, - celsius=self.config.celsius, output_filepath=self.output_filepath, io_size=self.config.io_size, write_size=self.config.write_size, chunk_size=self.config.chunk_size, value_chunk_size=self.config.value_chunk_size, - use_coreneuron=self.config.use_coreneuron, seed=self.seed, dry_run=False, ) diff --git a/src/miv_simulator/simulator/__init__.py b/src/miv_simulator/simulator/__init__.py index 29c58b7..d4bdfcd 100644 --- a/src/miv_simulator/simulator/__init__.py +++ b/src/miv_simulator/simulator/__init__.py @@ -1,20 +1,12 @@ -from miv_simulator.simulator.distribute_synapse_locations import ( - distribute_synapse_locations, - distribute_synapses, -) -from miv_simulator.simulator.generate_distance_connections import ( - generate_distance_connections, - distance_connections, -) -from miv_simulator.simulator.generate_input_features import ( - generate_input_features, -) -from miv_simulator.simulator.generate_input_spike_trains import ( - generate_input_spike_trains, - import_input_spike_train, +__doc__ = """Contains the end-user public API of the MiV-Simulator""" + +from miv_simulator.utils.io import create_neural_h5 +from miv_simulator.simulator.generate_network_architecture import ( + generate_network_architecture, ) -from miv_simulator.simulator.soma_coordinates import generate_soma_coordinates from miv_simulator.simulator.measure_distances import measure_distances - -# !deprecated, use io_utils directly -from miv_simulator.simulator.make_h5types import make_h5types +from miv_simulator.simulator.generate_synapse_forest import ( + generate_synapse_forest, +) +from miv_simulator.simulator.distribute_synapses import distribute_synapses +from miv_simulator.simulator.generate_connections import generate_connections diff --git a/src/miv_simulator/simulator/distribute_synapse_locations.py b/src/miv_simulator/simulator/distribute_synapses.py similarity index 97% rename from src/miv_simulator/simulator/distribute_synapse_locations.py rename to src/miv_simulator/simulator/distribute_synapses.py index be1e855..fb0558e 100644 --- a/src/miv_simulator/simulator/distribute_synapse_locations.py +++ b/src/miv_simulator/simulator/distribute_synapses.py @@ -8,7 +8,7 @@ import numpy as np from miv_simulator import cells, synapses, utils from miv_simulator.mechanisms import compile_and_load -from miv_simulator.env import Env +from neuron import h from miv_simulator import config from miv_simulator.utils.neuron import configure_hoc, load_template from mpi4py import MPI @@ -203,6 +203,7 @@ def distribute_synapse_locations( mechanisms_path = "./mechanisms" utils.config_logging(verbose) + from miv_simulator.env import Env env = Env( comm=MPI.COMM_WORLD, @@ -211,6 +212,14 @@ def distribute_synapse_locations( config_prefix=config_prefix, ) + configure_hoc( + template_directory=template_path, + use_coreneuron=env.use_coreneuron, + dt=env.dt, + tstop=env.tstop, + celsius=env.globals.get("celsius", None), + ) + return distribute_synapses( forest_filepath=forest_path, cell_types=env.celltypes, @@ -218,10 +227,6 @@ def distribute_synapse_locations( distribution=distribution, mechanisms_path=mechanisms_path, template_path=template_path, - use_coreneuron=env.use_coreneuron, - dt=env.dt, - tstop=env.tstop, - celsius=env.globals.get("celsius", None), io_size=io_size, output_filepath=output_path, write_size=write_size, @@ -239,15 +244,11 @@ def distribute_synapses( distribution: Literal["uniform", "poisson"], mechanisms_path: str, template_path: str, - dt: float, - tstop: float, - celsius: Optional[float], output_filepath: Optional[str], io_size: int, write_size: int, chunk_size: int, value_chunk_size: int, - use_coreneuron: bool, seed: Optional[int], dry_run: bool, ): @@ -261,13 +262,17 @@ def distribute_synapses( compile_and_load(mechanisms_path) - configure_hoc( - template_directory=template_path, - use_coreneuron=use_coreneuron, - dt=dt, - tstop=tstop, - celsius=celsius, - ) + # check if neuron is loaded + if not hasattr(h, "pc"): + h.load_file("stdrun.hoc") + h.load_file("loadbal.hoc") + h("objref pc, nc, nil") + h.pc = h.ParallelContext() + h.pc.gid_clear() + if hasattr(h, "nrn_netrec_state_adjust"): + h.nrn_netrec_state_adjust = 1 + if hasattr(h, "nrn_sparse_partrans"): + h.nrn_sparse_partrans = 1 if io_size == -1: io_size = comm.size diff --git a/src/miv_simulator/simulator/generate_distance_connections.py b/src/miv_simulator/simulator/generate_connections.py similarity index 99% rename from src/miv_simulator/simulator/generate_distance_connections.py rename to src/miv_simulator/simulator/generate_connections.py index 4c6552b..c5d7541 100644 --- a/src/miv_simulator/simulator/generate_distance_connections.py +++ b/src/miv_simulator/simulator/generate_connections.py @@ -72,7 +72,7 @@ def generate_distance_connections( env.model_config["Random Seeds"]["Connectivity Clustering"] ) - return distance_connections( + return generate_connections( filepath=coords_path, forest_filepath=forest_path, include_forest_populations=include, @@ -98,7 +98,7 @@ def generate_distance_connections( ) -def distance_connections( +def generate_connections( filepath: str, forest_filepath: str, include_forest_populations: Optional[list], diff --git a/src/miv_simulator/simulator/soma_coordinates.py b/src/miv_simulator/simulator/generate_network_architecture.py similarity index 99% rename from src/miv_simulator/simulator/soma_coordinates.py rename to src/miv_simulator/simulator/generate_network_architecture.py index 0fa6d00..c707144 100755 --- a/src/miv_simulator/simulator/soma_coordinates.py +++ b/src/miv_simulator/simulator/generate_network_architecture.py @@ -124,7 +124,7 @@ def rho(x): return in_nodes -# !deprecated, use generate() instead +# !deprecated, use generate_network_architecture() instead def generate_soma_coordinates( config: str, types_path: str, @@ -152,7 +152,7 @@ def generate_soma_coordinates( random_seed = int(env.model_config["Random Seeds"]["Soma Locations"]) random.seed(random_seed) - return generate( + return generate_network_architecture( output_filepath=output_path, h5_types_filepath=types_path, layer_extents=env.geometry["Parametric Surface"]["Layer Extents"], @@ -173,7 +173,7 @@ def generate_soma_coordinates( ) -def generate( +def generate_network_architecture( output_filepath: str, cell_distributions: config.CellDistributions, layer_extents: config.LayerExtents, diff --git a/src/miv_simulator/simulator/generate_synapse_forest.py b/src/miv_simulator/simulator/generate_synapse_forest.py new file mode 100644 index 0000000..e7418f5 --- /dev/null +++ b/src/miv_simulator/simulator/generate_synapse_forest.py @@ -0,0 +1,77 @@ +import os +import shutil +import subprocess + +import h5py +from miv_simulator import config + + +def _bin_check(bin: str) -> None: + if not shutil.which(bin): + raise FileNotFoundError(f"{bin} not found. Did you add it to the PATH?") + + +def generate_synapse_forest( + filepath: str, + tree_output_filepath: str, + output_filepath: str, + population: config.PopulationName, + morphology: config.SWCFilePath, +) -> None: + # create tree + if not os.path.isfile(tree_output_filepath): + _bin_check("neurotrees_import") + assert ( + subprocess.run( + [ + "neurotrees_import", + population, + tree_output_filepath, + morphology, + ] + ).returncode + == 0 + ) + assert ( + subprocess.run( + [ + "h5copy", + "-p", + "-s", + "/H5Types", + "-d", + "/H5Types", + "-i", + filepath, + "-o", + tree_output_filepath, + ] + ).returncode + == 0 + ) + + if not os.path.isfile(output_filepath): + # determine population ranges + with h5py.File(filepath, "r") as f: + idx = list( + reversed( + f["H5Types"]["Population labels"].dtype.metadata["enum"] + ) + ).index(population) + offset = f["H5Types"]["Populations"][idx][0] + + _bin_check("neurotrees_copy") + assert ( + subprocess.run( + [ + "neurotrees_copy", + "--fill", + "--output", + output_filepath, + tree_output_filepath, + population, + str(offset), + ] + ).returncode + == 0 + ) diff --git a/src/miv_simulator/simulator/make_h5types.py b/src/miv_simulator/simulator/make_h5types.py deleted file mode 100644 index 6d05e95..0000000 --- a/src/miv_simulator/simulator/make_h5types.py +++ /dev/null @@ -1,16 +0,0 @@ -from miv_simulator.env import Env -from miv_simulator.utils import io as io_utils - - -# !deprecated, call io_utils.create_neural_h5 directly instead -def make_h5types( - config: str, output_file: str, gap_junctions: bool = False, config_prefix="" -): - env = Env(config=config, config_prefix=config_prefix) - return io_utils.create_neural_h5( - output_file, - env.geometry["Cell Distribution"], - env.connection_config, - env.gapjunctions if gap_junctions else None, - env.Populations, - ) diff --git a/src/miv_simulator/simulator/reposition_tree.py b/src/miv_simulator/simulator/reposition_tree.py deleted file mode 100644 index 8d66ec1..0000000 --- a/src/miv_simulator/simulator/reposition_tree.py +++ /dev/null @@ -1,64 +0,0 @@ -import gc -import os -import copy -import sys -import h5py -import numpy as np -from miv_simulator import utils -from scipy.spatial.distance import cdist -from miv_simulator.utils import config_logging, get_module_logger - -logger = get_module_logger("reposition_tree") - - -def reposition_tree(neurotree_dict, cell_coords, swc_type_defs): - """ - Given a neurotree dictionary, relocates all point coordinates to - the positions indicated by cell_coords. The delta distance - necessary to reposition the cells is calculated as the smallest - distances between soma points and cell_coords. - - Note: This procedure does not recalculate layer information. - - :param neurotree_dict: - :param cell_coords: - :param swc_type_defs: - :return: neurotree dict - - """ - - cell_coords = np.asarray(cell_coords).reshape((1, -1)) - - pt_xs = copy.deepcopy(neurotree_dict["x"]) - pt_ys = copy.deepcopy(neurotree_dict["y"]) - pt_zs = copy.deepcopy(neurotree_dict["z"]) - pt_radius = copy.deepcopy(neurotree_dict["radius"]) - pt_layers = copy.deepcopy(neurotree_dict["layer"]) - pt_parents = copy.deepcopy(neurotree_dict["parent"]) - pt_swc_types = copy.deepcopy(neurotree_dict["swc_type"]) - pt_sections = copy.deepcopy(neurotree_dict["sections"]) - sec_src = copy.deepcopy(neurotree_dict["src"]) - sec_dst = copy.deepcopy(neurotree_dict["dst"]) - soma_pts = np.where(pt_swc_types == swc_type_defs["soma"])[0] - - soma_coords = np.column_stack( - (pt_xs[soma_pts], pt_ys[soma_pts], pt_zs[soma_pts]) - ) - pos_delta = ( - soma_coords[np.argmin(cdist(soma_coords, cell_coords))] - cell_coords - ).reshape((-1,)) - - new_tree_dict = { - "x": pt_xs - pos_delta[0], - "y": pt_ys - pos_delta[1], - "z": pt_zs - pos_delta[2], - "radius": pt_radius, - "layer": pt_layers, - "parent": pt_parents, - "swc_type": pt_swc_types, - "sections": pt_sections, - "src": sec_src, - "dst": sec_dst, - } - - return new_tree_dict diff --git a/src/scripts/distribute_synapse_locs.py b/src/scripts/distribute_synapse_locs.py index e178f66..28657d0 100644 --- a/src/scripts/distribute_synapse_locs.py +++ b/src/scripts/distribute_synapse_locs.py @@ -5,7 +5,9 @@ import click from miv_simulator import utils -from miv_simulator.simulator import distribute_synapse_locations +from miv_simulator.simulator.distribute_synapses import ( + distribute_synapse_locations, +) @click.command() diff --git a/src/scripts/generate_distance_connections.py b/src/scripts/generate_distance_connections.py index 5534c3a..a4690c6 100644 --- a/src/scripts/generate_distance_connections.py +++ b/src/scripts/generate_distance_connections.py @@ -9,7 +9,9 @@ import click from miv_simulator import utils -from miv_simulator.simulator import generate_distance_connections +from miv_simulator.simulator.generate_connections import ( + generate_distance_connections, +) @click.command() diff --git a/src/scripts/generate_input_features.py b/src/scripts/generate_input_features.py index 3fba052..1107c1b 100644 --- a/src/scripts/generate_input_features.py +++ b/src/scripts/generate_input_features.py @@ -3,7 +3,7 @@ import sys import click -from miv_simulator.simulator import generate_input_features +from miv_simulator.input_features import generate_input_features from miv_simulator.utils import list_find diff --git a/src/scripts/generate_input_spike_trains.py b/src/scripts/generate_input_spike_trains.py index e4bc4b7..ec803db 100644 --- a/src/scripts/generate_input_spike_trains.py +++ b/src/scripts/generate_input_spike_trains.py @@ -3,7 +3,7 @@ import sys import click -from miv_simulator.simulator import generate_input_spike_trains +from miv_simulator.input_spike_trains import generate_input_spike_trains from miv_simulator.utils import list_find diff --git a/src/scripts/generate_soma_coordinates.py b/src/scripts/generate_soma_coordinates.py index 12350bd..497c982 100644 --- a/src/scripts/generate_soma_coordinates.py +++ b/src/scripts/generate_soma_coordinates.py @@ -7,7 +7,9 @@ import sys import click -from miv_simulator.simulator import generate_soma_coordinates +from miv_simulator.simulator.generate_network_architecture import ( + generate_soma_coordinates, +) from miv_simulator.utils import list_find diff --git a/src/scripts/make_h5types.py b/src/scripts/make_h5types.py index 3952fa2..d775d6c 100644 --- a/src/scripts/make_h5types.py +++ b/src/scripts/make_h5types.py @@ -4,7 +4,21 @@ import click from miv_simulator import utils -from miv_simulator.simulator import make_h5types +from miv_simulator.env import Env +from miv_simulator.utils import io as io_utils + + +def make_h5types( + config: str, output_file: str, gap_junctions: bool = False, config_prefix="" +): + env = Env(config=config, config_prefix=config_prefix) + return io_utils.create_neural_h5( + output_file, + env.geometry["Cell Distribution"], + env.connection_config, + env.gapjunctions if gap_junctions else None, + env.Populations, + ) @click.command() diff --git a/src/scripts/measure_distances.py b/src/scripts/measure_distances.py index cb23b79..db5b113 100644 --- a/src/scripts/measure_distances.py +++ b/src/scripts/measure_distances.py @@ -5,7 +5,9 @@ import click from miv_simulator import utils -from miv_simulator.simulator import measure_distances_ as measure_distances +from miv_simulator.simulator.measure_distances import ( + measure_distances_ as measure_distances, +) @click.command() diff --git a/src/scripts/tools/reposition_trees.py b/src/scripts/tools/reposition_trees.py index 06f0c79..fbd5019 100644 --- a/src/scripts/tools/reposition_trees.py +++ b/src/scripts/tools/reposition_trees.py @@ -2,7 +2,6 @@ import click import numpy as np from mpi4py import MPI -from miv_simulator.simulator.reposition_tree import reposition_tree from miv_simulator.utils import config_logging, get_script_logger, list_find from miv_simulator.env import Env from neuroh5.io import ( @@ -13,6 +12,61 @@ read_population_ranges, ) import h5py +import copy +from scipy.spatial.distance import cdist + + +def reposition_tree(neurotree_dict, cell_coords, swc_type_defs): + """ + Given a neurotree dictionary, relocates all point coordinates to + the positions indicated by cell_coords. The delta distance + necessary to reposition the cells is calculated as the smallest + distances between soma points and cell_coords. + + Note: This procedure does not recalculate layer information. + + :param neurotree_dict: + :param cell_coords: + :param swc_type_defs: + :return: neurotree dict + + """ + cell_coords = np.asarray(cell_coords).reshape((1, -1)) + + pt_xs = copy.deepcopy(neurotree_dict["x"]) + pt_ys = copy.deepcopy(neurotree_dict["y"]) + pt_zs = copy.deepcopy(neurotree_dict["z"]) + pt_radius = copy.deepcopy(neurotree_dict["radius"]) + pt_layers = copy.deepcopy(neurotree_dict["layer"]) + pt_parents = copy.deepcopy(neurotree_dict["parent"]) + pt_swc_types = copy.deepcopy(neurotree_dict["swc_type"]) + pt_sections = copy.deepcopy(neurotree_dict["sections"]) + sec_src = copy.deepcopy(neurotree_dict["src"]) + sec_dst = copy.deepcopy(neurotree_dict["dst"]) + soma_pts = np.where(pt_swc_types == swc_type_defs["soma"])[0] + + soma_coords = np.column_stack( + (pt_xs[soma_pts], pt_ys[soma_pts], pt_zs[soma_pts]) + ) + pos_delta = ( + soma_coords[np.argmin(cdist(soma_coords, cell_coords))] - cell_coords + ).reshape((-1,)) + + new_tree_dict = { + "x": pt_xs - pos_delta[0], + "y": pt_ys - pos_delta[1], + "z": pt_zs - pos_delta[2], + "radius": pt_radius, + "layer": pt_layers, + "parent": pt_parents, + "swc_type": pt_swc_types, + "sections": pt_sections, + "src": sec_src, + "dst": sec_dst, + } + + return new_tree_dict + sys_excepthook = sys.excepthook