From c9ddda74ea4fd3a423193995ca5119e274a181f4 Mon Sep 17 00:00:00 2001 From: arnaudon Date: Wed, 18 Dec 2024 11:10:19 +0100 Subject: [PATCH] more --- docs/source/methodology.rst | 31 +++++++++++++++--------- region_grower/cli.py | 3 +-- region_grower/modify.py | 2 +- region_grower/synthesize_morphologies.py | 9 +++---- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/docs/source/methodology.rst b/docs/source/methodology.rst index d830ef2..29d3775 100644 --- a/docs/source/methodology.rst +++ b/docs/source/methodology.rst @@ -217,9 +217,11 @@ This block contains a list of rules, with the following entries. * ``neurite_types`` is the list of neurite_types to apply this rule. * ``processes`` is optional and is the list of type of sections in NeuroTS (``major`` or ``secondary``) to differentiate between trunk (``major``) and obliques or collaterals (``secondary``). * ``params`` is a dictionary to parametrize the rule. - * First, we specify the ``direction`` with a 3-vector, where ``[0, 1, 0]`` is the pia direction and ``[0, -1, 0]`` is opposite. For non-cortical regions, pia generalises to ``y`` coordinate of the orientation vector in ``orientation.nrrd``. - * The ``mode`` selects between ``parallel`` (default if omitted) to follow the direction, and ``perpendicular`` to follow the perpendicular directions, hence a plane. - * The optional ``power`` value is to set how strong the direction constraint is. The underlying algorithm converts the angle between the next point to grow and the direction into a probability function. If ``power=1`` (default) the relation is linear, otherwise it is a power of it (see ``get_directions`` in ``region-grower/region_grower/context.py``). + + * First, we specify the ``direction`` with a 3-vector, where ``[0, 1, 0]`` is the pia direction and ``[0, -1, 0]`` is opposite. For non-cortical regions, pia generalises to ``y`` coordinate of the orientation vector in ``orientation.nrrd``. + * The ``mode`` selects between ``parallel`` (default if omitted) to follow the direction, and ``perpendicular`` to follow the perpendicular directions, hence a plane. + * The optional ``power`` value is to set how strong the direction constraint is. The underlying algorithm converts the angle between the next point to grow and the direction into a probability function. If ``power=1`` (default) the relation is linear, otherwise it is a power of it (see ``get_directions`` in ``region-grower/region_grower/context.py``). + * Finally, this rule can be applied into only specific layers, via the list in ``layers`` entry (default to all layers). Boundary constraints @@ -252,17 +254,22 @@ Each rule contains the following: * a ``path`` entry to a mesh (readabe by https://github.com/mikedh/trimesh) in either voxel id or coordinates. If the path is relative, it will be interpreted as relative to the location of ``region_structure.yaml`` file. If the ``path`` is a folder, then it must contain mesh files which will be used for this rule. * ``mesh_type`` entry can be used with value ``voxel`` (default) for voxel ids or ``spatial`` for coordinates of the mesh. * For a folder of meshes, the way the mesh are selected to act as boundary depends on the rule parametrized by ``multimesh_mode``, which can be set to - * ``closest`` (default) for selecting the closest (in euclidiean morm) mesh to the soma as the unique mesh, - * ``closest_y`` as closst along the y direction only, - * ``inside`` to select the mesh surrounding the soma (used for barrel cortext for example), - * ``territories``, specific for olfactory bulb glomeruli (see code for details, it assumes specific form of input data) + + * ``closest`` (default) for selecting the closest (in euclidiean morm) mesh to the soma as the unique mesh, + * ``closest_y`` as closst along the y direction only, + * ``inside`` to select the mesh surrounding the soma (used for barrel cortext for example), + * ``territories``, specific for olfactory bulb glomeruli (see code for details, it assumes specific form of input data) + * There are two main modes for these rules, parametrized by ``modes``. - * ``repulsive`` (default) where the mesh will act as a repulsive wall/boundary, - * ``attractive`` where the mesh will attract the growing sections (more experimental, used for glomeruli spherical meshes for example). + + * ``repulsive`` (default) where the mesh will act as a repulsive wall/boundary, + * ``attractive`` where the mesh will attract the growing sections (more experimental, used for glomeruli spherical meshes for example). + * This rule can then be applied to either the section growing with ``params_section`` or trunk placements with ``params_trunk`` (only if the non-default trunk angle method is selected, see above), with following entries: - * ``d_min``: distance under which probability of accept is 0 - * ``d_max``: distance over which probability of accepct is 1 - * ``power``: linearity of the probability as a function of distance (same as for direction entry). + + * ``d_min``: distance under which probability of accept is 0 + * ``d_max``: distance over which probability of accepct is 1 + * ``power``: linearity of the probability as a function of distance (same as for direction entry). The algorithm uses ray tracing to compute the distance to the mesh in the direction of the growth, and convert it to a probability function. The probability will be ``0`` below a distance of ``d_min``, and ``1`` above the distance of ``d_max``. This distance is from the previous point (soma for trunk), and the direction is to the next point (first neurite point for trunk). The ``power`` argument is as above, to have a nonlinear function of distance. If ``d_min`` is close negative, there will be a probability of going though the mesh, hence making it leaky. diff --git a/region_grower/cli.py b/region_grower/cli.py index 632ec28..f988d08 100644 --- a/region_grower/cli.py +++ b/region_grower/cli.py @@ -19,11 +19,10 @@ import click import yaml -# pragma: no cover try: from mpi4py import MPI - mpi_enabled = True + mpi_enabled = True # pragma: no cover except ImportError: mpi_enabled = False diff --git a/region_grower/modify.py b/region_grower/modify.py index 4773503..f3722d9 100644 --- a/region_grower/modify.py +++ b/region_grower/modify.py @@ -145,7 +145,7 @@ def input_scaling( "with_debug_info": debug_info is not None, }, } - elif neurite_type != 'axon': + elif neurite_type != 'axon': # pragma: no cover if debug_info is not None: debug_info.update( { diff --git a/region_grower/synthesize_morphologies.py b/region_grower/synthesize_morphologies.py index 2fa2905..6338c20 100644 --- a/region_grower/synthesize_morphologies.py +++ b/region_grower/synthesize_morphologies.py @@ -336,8 +336,7 @@ def __init__( with open(tmd_distributions, "r", encoding="utf-8") as f: self.tmd_distributions = convert_from_legacy_neurite_type(json.load(f)) - # pragma: no cover - for params in self.tmd_parameters.values(): + for params in self.tmd_parameters.values(): # pragma: no cover for param in params.values(): if synthesize_axons: if "axon" not in param["grow_types"]: @@ -583,13 +582,11 @@ def assign_atlas_data(self, min_depth=25, max_depth=5000): # pylint: disable=to if "boundaries" in self.atlas.region_structure.get(_region, []): boundaries = self.atlas.region_structure[_region]["boundaries"] for boundary in boundaries: - # pragma: no cover - if not Path(boundary["path"]).is_absolute(): + if not Path(boundary["path"]).is_absolute(): # pragma: no cover boundary["path"] = str( (self.atlas.region_structure_base_path / boundary["path"]).absolute() ) - # pragma: no cover - if boundary.get("multimesh_mode", "closest") == "territories": + if boundary.get("multimesh_mode", "closest") == "territories": # pragma: no cover territories = self.atlas.atlas.load_data("glomerular_territories") pos = self.cells_data.loc[region_mask, ["x", "y", "z"]].to_numpy() self.cells_data.loc[region_mask, "glomerulus_id"] = territories.lookup(