Skip to content

Commit

Permalink
Export circuitconfig
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaudon committed Aug 19, 2022
1 parent 1d09844 commit 44db085
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 7 deletions.
4 changes: 2 additions & 2 deletions examples/rat_vaccum/luigi.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ mtypes = ["L5_TPC:A", "L1_DAC"]

[GetSynthesisInputs]
# this fetches input data from a repository (one can also use local files)
url = git@bbpgitlab.epfl.ch:circuits/thncx.git
git_synthesis_input_path = entities/synthesis_workflow/rat/vacuum/synthesis_input
url = git@bbpgitlab.epfl.ch:neuromath/synthdb.git
git_synthesis_input_path = insitu_synthesis_inputs/rat_sscx
local_synthesis_input_path = synthesis_input

[BuildMorphsDF]
Expand Down
1 change: 1 addition & 0 deletions requirements/base.pip
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ tmd
neurots>=3.1,<4
tqdm
voxcell>=3,<4
bluepy-configfile
18 changes: 16 additions & 2 deletions src/synthesis_workflow/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import numpy as np
import pandas as pd
import yaml
from atlas_analysis.planes.planes import _smoothing
from atlas_analysis.planes.planes import create_centerline
from atlas_analysis.planes.planes import create_planes as _create_planes
from brainbuilder.app.cells import _place as place
from region_grower.atlas_helper import AtlasHelper
Expand Down Expand Up @@ -224,7 +226,12 @@ def get_centerline_bounds(layer):
"""Find centerline bounds using PCA of the voxell position of a given layer in the region."""
_ls = np.unique(layer.raw[layer.raw > 0])
central_layer = _ls[int(len(_ls) / 2)]
ids = np.column_stack(np.where(layer.raw == central_layer))

# we select voxels which are on the boundary of the region, to prevent picking them in y dir
layer_raw = np.array(layer.raw, dtype=float)
layer_raw[layer_raw == 0] = -10000 # large number to be safe
boundary_mask = sum(abs(g) for g in np.gradient(layer_raw)) > 1000
ids = np.column_stack(np.where((layer.raw == central_layer) & boundary_mask))
points = layer.indices_to_positions(ids)
_align = points.dot(_get_principal_direction(points))
return ids[_align.argmin()], ids[_align.argmax()]
Expand Down Expand Up @@ -269,7 +276,7 @@ def create_planes(
for centerline (in voxcell index)
centerline_axis (str): (for plane_type = aligned) axis along which to create planes
"""
if plane_type == "centerline":
if plane_type == "centerline_straight":
if centerline_first_bound is None and centerline_last_bound is None:
centerline_first_bound, centerline_last_bound = get_centerline_bounds(layer_annotation)
centerline = np.array(
Expand All @@ -278,6 +285,13 @@ def create_planes(
layer_annotation.indices_to_positions(centerline_last_bound),
]
)
elif plane_type == "centerline_curved":
if centerline_first_bound is None and centerline_last_bound is None:
centerline_first_bound, centerline_last_bound = get_centerline_bounds(layer_annotation)
centerline = create_centerline(
layer_annotation, [centerline_first_bound, centerline_last_bound]
)
centerline = _smoothing(centerline)

elif plane_type == "aligned":
centerline = np.zeros([2, 3])
Expand Down
4 changes: 2 additions & 2 deletions src/synthesis_workflow/tasks/circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ class CreateAtlasPlanes(WorkflowTask):
"""Create plane cuts of an atlas."""

plane_type = luigi.ChoiceParameter(
default="centerline",
choices=["aligned", "centerline"],
default="aligned",
choices=["aligned", "centerline_straight", "centerline_curved"],
description=(
":str: Type of planes creation algorithm. It can take the value 'centerline', "
"so the center line is computed between first_bound and last_bound with internal "
Expand Down
54 changes: 54 additions & 0 deletions src/synthesis_workflow/tasks/workflows.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
"""Luigi tasks for validation workflows."""
import os

import luigi
import numpy as np
import pandas as pd
from atlas_analysis.planes.planes import load_planes_centerline
from bluepy_configfile.configfile import BlueConfig
from luigi.parameter import PathParameter
from luigi_tools.parameter import BoolParameter
from luigi_tools.target import OutputLocalTarget
from luigi_tools.task import WorkflowTask
from luigi_tools.task import WorkflowWrapperTask

from synthesis_workflow.tasks.circuit import CreateAtlasPlanes
from synthesis_workflow.tasks.config import CircuitConfig
from synthesis_workflow.tasks.config import GetSynthesisInputs
from synthesis_workflow.tasks.config import ValidationLocalTarget
from synthesis_workflow.tasks.synthesis import ApplySubstitutionRules
from synthesis_workflow.tasks.synthesis import Synthesize
from synthesis_workflow.tasks.vacuum_synthesis import PlotVacuumMorphologies
from synthesis_workflow.tasks.validation import MorphologyValidationReports
from synthesis_workflow.tasks.validation import PlotCollage
Expand All @@ -20,6 +30,49 @@
from synthesis_workflow.validation import plot_morphometrics


class CreateBlueConfig(WorkflowTask):
"""Create a CircuitConfig file to be read with other BBP tools (bluepy, etc.)."""

circuitconfig_path = PathParameter("CircuitConfig")

def requires(self):
""" """
return {"synthesis": Synthesize(), "planes": CreateAtlasPlanes()}

def run(self):
""" """
bc = BlueConfig()
morph_path = self.input()["synthesis"]["out_morphologies"].pathlib_path.parent / "ascii"
if morph_path.exists():
os.remove(morph_path)

contents = {
"MorphologyPath": str(morph_path.parent.resolve()),
"CircuitPath": str(self.input()["synthesis"]["out_mvd3"].pathlib_path.resolve()),
"Atlas": CircuitConfig().atlas_path,
"nrnPath": "N/A",
"METypePath": "N/A",
}
morph_path.symlink_to(self.input()["synthesis"]["out_morphologies"].pathlib_path.resolve())
bc.add_section("Run", "default", contents)
with open(self.output().path, "w") as out_file:
out_file.write(str(bc))

# convert plane data for collage
planes = load_planes_centerline(self.input()["planes"].path)
np.savetxt(
self.input()["planes"].pathlib_path.parent / "centerline.dat", planes["centerline"]
)
_planes = []
for plane in planes["planes"]:
_planes.append(np.hstack([plane.point, plane.normal]))
np.savetxt(self.input()["planes"].pathlib_path.parent / "planes.dat", _planes)

def output(self):
""" """
return OutputLocalTarget(self.circuitconfig_path)


class ValidateSynthesis(WorkflowWrapperTask):
"""Workflow to validate synthesis.
Expand Down Expand Up @@ -68,6 +121,7 @@ def requires(self):
tasks.append(PlotScoreMatrix(in_atlas=True))
if self.with_trunk_validation:
tasks.append(TrunkValidation(in_atlas=True))
tasks.append(CreateBlueConfig())
return tasks


Expand Down
2 changes: 1 addition & 1 deletion src/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
"""Package version."""
VERSION = "0.1.1"
VERSION = "0.1.2.dev1"

0 comments on commit 44db085

Please sign in to comment.