Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 2e524b41 authored by DEBREUVE Eric's avatar DEBREUVE Eric
Browse files

recfactoring

parent ec1286f4
No related branches found
No related tags found
No related merge requests found
...@@ -31,13 +31,13 @@ ...@@ -31,13 +31,13 @@
import brick.processing.dijkstra_1_to_n as dk_ import brick.processing.dijkstra_1_to_n as dk_
from brick.component.extension import extension_t from brick.component.extension import extension_t
from brick.component.glial_cmp import glial_cmp_t
from brick.component.soma import soma_t from brick.component.soma import soma_t
from brick.general.type import array_t, site_h, site_path_h from brick.general.type import array_t, site_h, site_path_h
import itertools as it_ import itertools as it_
from typing import Callable, Sequence, Tuple from typing import Callable, Sequence, Tuple
import cython as cy_
import numpy as np_ import numpy as np_
...@@ -46,7 +46,7 @@ def CandidateConnections( ...@@ -46,7 +46,7 @@ def CandidateConnections(
influence_map: array_t, influence_map: array_t,
dist_to_closest: array_t, dist_to_closest: array_t,
extensions: Sequence[extension_t], extensions: Sequence[extension_t],
max_straight_sq_dist: cy_.double = np_.inf, max_straight_sq_dist: float = np_.inf,
) -> list: ) -> list:
# #
candidate_conn_nfo = [] # conn=connection candidate_conn_nfo = [] # conn=connection
...@@ -84,3 +84,22 @@ def ShortestPathFromToN( ...@@ -84,3 +84,22 @@ def ShortestPathFromToN(
costs[candidate_indexing] = np_.inf costs[candidate_indexing] = np_.inf
return path, length return path, length
def ValidateConnection(
glial_cmp: glial_cmp_t, extension: glial_cmp_t, dijkstra_path: site_path_h, costs: array_t
) -> None:
#
connection_path = tuple(zip(*dijkstra_path[1:-1]))
if connection_path.__len__() == 0:
connection_path = None
glial_cmp.connection_path[extension.uid] = connection_path
glial_cmp.extensions.append(extension)
extension.BackReferenceSoma(glial_cmp)
# TODO: Ideally, these paths should be dilated + put this outside
# but in ext-ext connections, there must not be dilation around the current ext
# (current ext plays the role of a soma in soma-ext step)
if connection_path is not None:
costs[connection_path] = np_.inf
...@@ -70,8 +70,7 @@ class extension_t(glial_cmp_t): ...@@ -70,8 +70,7 @@ class extension_t(glial_cmp_t):
bmp = lmp == uid bmp = lmp == uid
instance.InitializeFromMap(bmp, uid) instance.InitializeFromMap(bmp, uid)
end_point_map = cls.EndPointMap(bmp) end_point_map = cls.EndPointMap(bmp)
end_point_lmp = end_point_map * lmp instance.end_points = end_point_map.nonzero()
instance.end_points = (end_point_lmp == uid).nonzero()
instance.scales = scales[instance.sites] instance.scales = scales[instance.sites]
instance.__cache__ = {} instance.__cache__ = {}
...@@ -85,7 +84,7 @@ class extension_t(glial_cmp_t): ...@@ -85,7 +84,7 @@ class extension_t(glial_cmp_t):
@property @property
def end_points_as_array(self) -> array_t: def end_points_as_array(self) -> array_t:
# #
pty_name = "end_points_as_array" pty_name = extension_t.end_points_as_array.__name__
if pty_name not in self.__cache__: if pty_name not in self.__cache__:
self.__cache__[pty_name] = np_.array(self.end_points) self.__cache__[pty_name] = np_.array(self.end_points)
......
...@@ -33,6 +33,7 @@ from __future__ import annotations ...@@ -33,6 +33,7 @@ from __future__ import annotations
from brick.general.type import array_t, np_array_picker_h, py_array_picker_h, site_path_h from brick.general.type import array_t, np_array_picker_h, py_array_picker_h, site_path_h
from abc import abstractmethod
from typing import Dict, List, Optional, Tuple from typing import Dict, List, Optional, Tuple
import numpy as np_ import numpy as np_
...@@ -66,28 +67,7 @@ class glial_cmp_t: ...@@ -66,28 +67,7 @@ class glial_cmp_t:
# #
return self.extensions.__len__() > 0 return self.extensions.__len__() > 0
def ExtendWith( @abstractmethod
self, extension: glial_cmp_t, through: site_path_h, costs: array_t
) -> None:
#
connection_path = tuple(zip(*through[1:-1]))
if connection_path.__len__() == 0:
connection_path = None
extension_path = extension.sites
self.connection_path[extension.uid] = connection_path
self.extensions.append(extension)
# TODO: put this outside
extension.BackReferenceSoma(self)
# TODO: Ideally, these paths should be dilated + put this outside
# but in ext-ext connections, there must not be dilation around the current ext
# (current ext plays the role of a soma in soma-ext step)
if connection_path is not None:
costs[connection_path] = np_.inf
costs[extension_path] = np_.inf
def BackReferenceSoma(self, glial_cmp: glial_cmp_t) -> None: def BackReferenceSoma(self, glial_cmp: glial_cmp_t) -> None:
# #
raise NotImplementedError pass
...@@ -66,8 +66,7 @@ class soma_t(glial_cmp_t): ...@@ -66,8 +66,7 @@ class soma_t(glial_cmp_t):
bmp = lmp == uid bmp = lmp == uid
instance.InitializeFromMap(bmp, uid) instance.InitializeFromMap(bmp, uid)
contour_map = cls.ContourMap(bmp) contour_map = cls.ContourMap(bmp)
contour_lmp = contour_map * lmp instance.contour_points = tuple(zip(*contour_map.nonzero()))
instance.contour_points = tuple(zip(*(contour_lmp == uid).nonzero()))
return instance return instance
...@@ -164,9 +163,9 @@ class soma_t(glial_cmp_t): ...@@ -164,9 +163,9 @@ class soma_t(glial_cmp_t):
def FilteredMap(map_: array_t, min_area: int) -> array_t: def FilteredMap(map_: array_t, min_area: int) -> array_t:
result = map_.copy() result = map_.copy()
lmp = ms_.label(map_) lmp = ms_.label(map_) # label the image region by measuring the connectivity
for region in ms_.regionprops(lmp): for region in ms_.regionprops(lmp): # Measure properties of labeled image regions
if region.area <= min_area: if region.area <= min_area:
region_sites = (lmp == region.label).nonzero() region_sites = (lmp == region.label).nonzero()
result[region_sites] = 0 result[region_sites] = 0
......
...@@ -35,7 +35,9 @@ from brick.component.soma import soma_t ...@@ -35,7 +35,9 @@ from brick.component.soma import soma_t
from typing import Sequence, Tuple from typing import Sequence, Tuple
import matplotlib as mpl_
import matplotlib.pyplot as pl_ import matplotlib.pyplot as pl_
mpl_.use('TkAgg')
def PrintConnectedExtensions(extensions: Sequence[extension_t]) -> None: def PrintConnectedExtensions(extensions: Sequence[extension_t]) -> None:
...@@ -56,7 +58,9 @@ def PlotSomas(somas: Sequence[soma_t], som_nfo: dict, axes: dict) -> None: ...@@ -56,7 +58,9 @@ def PlotSomas(somas: Sequence[soma_t], som_nfo: dict, axes: dict) -> None:
axes[soma.uid] = ot_.PlotLMap(som_nfo["lmp"], labels=soma.uid) axes[soma.uid] = ot_.PlotLMap(som_nfo["lmp"], labels=soma.uid)
pl_.title(f"Soma.{soma.uid}") pl_.title(f"Soma.{soma.uid}")
pl_.matshow(som_nfo["influence_map"].max(axis=0)), pl_.title("Soma Influencess") pl_.matshow(som_nfo["influence_map"].max(axis=0)), pl_.title("Soma Influencess")
pl_.show(block=True)
pl_.matshow(som_nfo["dist_to_closest"].max(axis=0)), pl_.title("Soma Distances") pl_.matshow(som_nfo["dist_to_closest"].max(axis=0)), pl_.title("Soma Distances")
pl_.show(block=True)
def PlotExtensions( def PlotExtensions(
...@@ -68,6 +72,7 @@ def PlotExtensions( ...@@ -68,6 +72,7 @@ def PlotExtensions(
pl_.title(f"Extension.{extension.uid}") pl_.title(f"Extension.{extension.uid}")
pl_.matshow(ext_nfo["map"].max(axis=0)) pl_.matshow(ext_nfo["map"].max(axis=0))
pl_.title("Extensions Extremities") pl_.title("Extensions Extremities")
pl_.show(block=True)
def PlotSomasWithExtensions(somas: Sequence[soma_t], som_nfo: dict, which: str) -> None: def PlotSomasWithExtensions(somas: Sequence[soma_t], som_nfo: dict, which: str) -> None:
...@@ -80,8 +85,11 @@ def PlotSomasWithExtensions(somas: Sequence[soma_t], som_nfo: dict, which: str) ...@@ -80,8 +85,11 @@ def PlotSomasWithExtensions(somas: Sequence[soma_t], som_nfo: dict, which: str)
continue continue
_ = ot_.PlotSomaWithExtensions(soma, som_nfo["lmp"]) _ = ot_.PlotSomaWithExtensions(soma, som_nfo["lmp"])
pl_.title(f"Soma.{soma.uid} + Ext.{tuple(ext.uid for ext in soma.extensions)}") pl_.title(f"Soma.{soma.uid} + Ext.{tuple(ext.uid for ext in soma.extensions)}")
pl_.show(block=True)
any_plot = True any_plot = True
if any_plot: if any_plot:
pl_.matshow(som_nfo["soma_w_ext_lmp"].max(axis=0)) pl_.matshow(som_nfo["soma_w_ext_lmp"].max(axis=0))
pl_.title("Somas + Extensions") pl_.title("Somas + Extensions")
pl_.show(block=True)
...@@ -36,7 +36,9 @@ import numpy as np_ ...@@ -36,7 +36,9 @@ import numpy as np_
def NormalizedImage(image: array_t) -> array_t: def NormalizedImage(image: array_t) -> array_t:
# #
print("This normalization does not bring anything; left as is for now to avoid the need for changing prms") print(
"This normalization does not bring anything; left as is for now to avoid the need for changing prms"
)
nonextreme_values = image[np_.logical_and(image > 0.0, image < image.max())] nonextreme_values = image[np_.logical_and(image > 0.0, image < image.max())]
if nonextreme_values.size > 0: if nonextreme_values.size > 0:
...@@ -46,3 +48,15 @@ def NormalizedImage(image: array_t) -> array_t: ...@@ -46,3 +48,15 @@ def NormalizedImage(image: array_t) -> array_t:
result = image.astype(np_.float32) result = image.astype(np_.float32)
return result return result
def DijkstraCosts(image: array_t, som_map: array_t, ext_map: array_t) -> array_t:
#
# TODO: Ideally, the extension part should be dilated
# but in ext-ext connections, there must not be dilation around the current or the other exts
# (current ext plays the role of a soma in soma-ext step)
#
dijkstra_costs = 1.0 / (image + 1.0)
dijkstra_costs[np_.logical_or(som_map > 0, ext_map > 0)] = np_.inf
return dijkstra_costs
...@@ -42,7 +42,7 @@ shifts_of_26_neighbors_c = tuple( ...@@ -42,7 +42,7 @@ shifts_of_26_neighbors_c = tuple(
for i in (-1, 0, 1) for i in (-1, 0, 1)
for j in (-1, 0, 1) for j in (-1, 0, 1)
for k in (-1, 0, 1) for k in (-1, 0, 1)
if i != 0 or j != 0 or k != 0 if i != 0 or j != 0 or k != 0 # take every direct neighbors except itself
) )
...@@ -54,8 +54,8 @@ def PartLMap(map_: array_t) -> array_t: ...@@ -54,8 +54,8 @@ def PartLMap(map_: array_t) -> array_t:
# isolated pixels receive 0). # isolated pixels receive 0).
# #
result = np_.array(map_, dtype=np_.int8) result = np_.array(map_, dtype=np_.int8)
result[result > 0] = 1 result[result > 0] = 1 # binary map
padded_sm = np_.pad(map_ > 0, 1, "constant") padded_sm = np_.pad(map_ > 0, 1, "constant") # pad for voxels at the border --> map of booleans / binary mask
for shifts in shifts_of_26_neighbors_c: for shifts in shifts_of_26_neighbors_c:
result += np_.roll(padded_sm, shifts, axis=(0, 1, 2))[1:-1, 1:-1, 1:-1] result += np_.roll(padded_sm, shifts, axis=(0, 1, 2))[1:-1, 1:-1, 1:-1]
......
...@@ -88,7 +88,7 @@ def PlotConnection( ...@@ -88,7 +88,7 @@ def PlotConnection(
if new_axes: if new_axes:
_, axes = __FigAndAxes__(shape, depth_limit) _, axes = __FigAndAxes__(shape, depth_limit)
# This test is put here but could be move outside this function # TODO This test is put here but could be move outside this function
if connection is not None: if connection is not None:
axes.plot( axes.plot(
depth_factor * np_.array(connection[0]), depth_factor * np_.array(connection[0]),
......
No preview for this file type
_t=type
_h=
_c=constant
som=soma som=soma
ext=extension ext=extension
......
...@@ -41,7 +41,7 @@ import brick.component.connection as cn_ ...@@ -41,7 +41,7 @@ import brick.component.connection as cn_
import brick.component.extension as xt_ import brick.component.extension as xt_
import brick.component.soma as sm_ import brick.component.soma as sm_
import brick.general.feedback as fb_ import brick.general.feedback as fb_
import brick.processing.normalization as nm_ import brick.processing.input as in_
# from main_prm import * # from main_prm import *
import os as os_ import os as os_
...@@ -54,6 +54,7 @@ import numpy as np_ ...@@ -54,6 +54,7 @@ import numpy as np_
import skimage.io as io_ import skimage.io as io_
import skimage.measure as ms_ import skimage.measure as ms_
print(sy_.argv, sy_.argv.__len__())
if sy_.argv.__len__() < 2: if sy_.argv.__len__() < 2:
print("Missing parameter file argument") print("Missing parameter file argument")
...@@ -63,7 +64,7 @@ if not (os_.path.isfile(sy_.argv[1]) and os_.access(sy_.argv[1], os_.R_OK)): ...@@ -63,7 +64,7 @@ if not (os_.path.isfile(sy_.argv[1]) and os_.access(sy_.argv[1], os_.R_OK)):
sy_.exit(0) sy_.exit(0)
data_path = None data_path = None
with_plot = None with_plot = True
soma_low_c = None soma_low_c = None
soma_high_c = None soma_high_c = None
ext_low_c = None ext_low_c = None
...@@ -88,9 +89,16 @@ start_time = tm_.time() ...@@ -88,9 +89,16 @@ start_time = tm_.time()
# --- Images # --- Images
image = io_.imread(data_path) image = io_.imread(data_path)
assert image.ndim == 3 # TODO: replace assertion with proper exception handling
image = image[:, 512:, 512:]#562 image = image[:,:,:,1] # TODO For the green channel - change in case of other channel or greyscale
# pl_.imshow(image[10,:,:])
# pl_.show(block=True)
assert image.ndim == 3 # TODO: replace assertion with proper exception handling
image = image[:, 512:, 512:] # 562
img_shape = image.shape img_shape = image.shape
pl_.matshow(image[image.shape[0] // 2,:,:])
pl_.show()
# #
# max_img = image.max() # max_img = image.max()
# image.fill(image.min()) # image.fill(image.min())
...@@ -98,9 +106,8 @@ img_shape = image.shape ...@@ -98,9 +106,8 @@ img_shape = image.shape
# #
print(f"IMAGE: s.{img_shape} t.{image.dtype} m.{image.min()} M.{image.max()}") print(f"IMAGE: s.{img_shape} t.{image.dtype} m.{image.min()} M.{image.max()}")
image_for_soma = nm_.NormalizedImage(image) image_for_soma = in_.NormalizedImage(image)
image_for_ext = nm_.NormalizedImage(image) image_for_ext = in_.NormalizedImage(image)
costs = 1.0 / (image + 1.0)
print(f"NRM-IMG: t.{image_for_soma.dtype} m.{image_for_soma.min():.2f} M.{image_for_soma.max():.2f}") print(f"NRM-IMG: t.{image_for_soma.dtype} m.{image_for_soma.min():.2f} M.{image_for_soma.max():.2f}")
...@@ -120,6 +127,7 @@ print("\n--- Soma Detection") ...@@ -120,6 +127,7 @@ print("\n--- Soma Detection")
som_nfo["map"] = soma_t.Map(image_for_soma, soma_low_c, soma_high_c, soma_selem_c) som_nfo["map"] = soma_t.Map(image_for_soma, soma_low_c, soma_high_c, soma_selem_c)
som_nfo["map"] = soma_t.FilteredMap(som_nfo["map"], min_area_c) som_nfo["map"] = soma_t.FilteredMap(som_nfo["map"], min_area_c)
#TODO: change label into relabel + max
som_nfo["lmp"], n_somas = ms_.label(som_nfo["map"], return_num=True) som_nfo["lmp"], n_somas = ms_.label(som_nfo["map"], return_num=True)
som_nfo["dist_to_closest"], som_nfo["influence_map"] = soma_t.InfluenceMaps( som_nfo["dist_to_closest"], som_nfo["influence_map"] = soma_t.InfluenceMaps(
som_nfo["lmp"] som_nfo["lmp"]
...@@ -158,14 +166,13 @@ if with_plot: ...@@ -158,14 +166,13 @@ if with_plot:
fb_.PlotExtensions(extensions, ext_nfo, img_shape) fb_.PlotExtensions(extensions, ext_nfo, img_shape)
# -- Preparation for Connections
dijkstra_costs = in_.DijkstraCosts(image, som_nfo["map"], ext_nfo["map"])
# -- Soma-Extention # -- Soma-Extention
print("\n--- Soma <-> Extension") print("\n--- Soma <-> Extension")
# TODO: Ideally, the extension part should be dilated
# but in ext-ext connections, there must not be dilation around the current ext
# (current ext plays the role of a soma in soma-ext step)
costs[np_.logical_or(som_nfo["map"] > 0, ext_nfo["map"] > 0)] = np_.inf
candidate_conn_nfo = cn_.CandidateConnections( candidate_conn_nfo = cn_.CandidateConnections(
somas, somas,
som_nfo["influence_map"], som_nfo["influence_map"],
...@@ -179,18 +186,18 @@ for ep_idx, soma, extension, end_point in candidate_conn_nfo: ...@@ -179,18 +186,18 @@ for ep_idx, soma, extension, end_point in candidate_conn_nfo:
print(f" Soma.{soma.uid} <-?-> Ext.{extension.uid}({ep_idx})", end="") print(f" Soma.{soma.uid} <-?-> Ext.{extension.uid}({ep_idx})", end="")
path, length = cn_.ShortestPathFromToN( path, length = cn_.ShortestPathFromToN(
end_point, end_point,
costs, dijkstra_costs,
soma.ContourPointsCloseTo, soma.ContourPointsCloseTo,
max_straight_sq_dist=max_straight_sq_dist_c, max_straight_sq_dist=max_straight_sq_dist_c,
) )
if length <= max_weighted_length_c: if length <= max_weighted_length_c:
soma.ExtendWith(extension, path, costs) cn_.ValidateConnection(soma, extension, path, dijkstra_costs)
print(": Made") print(": Made")
else: else:
print("") print("")
# for soma in somas: # for soma in somas:
# soma.Extend(extensions, som_nfo["dist_to_closest"], costs) # soma.Extend(extensions, som_nfo["dist_to_closest"], dijkstra_costs)
fb_.PrintConnectedExtensions(extensions) fb_.PrintConnectedExtensions(extensions)
elapsed_time = tm_.gmtime(tm_.time() - start_time) elapsed_time = tm_.gmtime(tm_.time() - start_time)
...@@ -223,13 +230,13 @@ while should_look_for_connections: ...@@ -223,13 +230,13 @@ while should_look_for_connections:
print(f" Soma.{soma.uid} <-?-> Ext.{extension.uid}({ep_idx})", end="") print(f" Soma.{soma.uid} <-?-> Ext.{extension.uid}({ep_idx})", end="")
path, length = cn_.ShortestPathFromToN( path, length = cn_.ShortestPathFromToN(
end_point, end_point,
costs, dijkstra_costs,
soma.ExtensionPointsCloseTo, soma.ExtensionPointsCloseTo,
max_straight_sq_dist=max_straight_sq_dist_c, max_straight_sq_dist=max_straight_sq_dist_c,
) )
if length <= max_weighted_length_c: if length <= max_weighted_length_c:
tgt_extenstion = extension_t.ExtensionWithSite(extensions, path[-1]) tgt_extenstion = extension_t.ExtensionWithSite(extensions, path[-1])
tgt_extenstion.ExtendWith(extension, path, costs) cn_.ValidateConnection(tgt_extenstion, extension, path, dijkstra_costs)
should_look_for_connections = True should_look_for_connections = True
print(": Made") print(": Made")
else: else:
......
...@@ -33,7 +33,7 @@ import skimage.morphology as mp_ ...@@ -33,7 +33,7 @@ import skimage.morphology as mp_
data_path = "./data/DIO_6H_6_1.70bis_2.2_3.tif" data_path = "./data/DIO_6H_6_1.70bis_2.2_3.tif"
with_plot = False with_plot = True
soma_low_c = 0.15 soma_low_c = 0.15
soma_high_c = 0.7126 soma_high_c = 0.7126
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment