Skip to content

Commit

Permalink
Still fixing the SWC issue.
Browse files Browse the repository at this point in the history
  • Loading branch information
marwan-abdellah committed Oct 7, 2018
1 parent a14164b commit d826012
Showing 1 changed file with 39 additions and 258 deletions.
297 changes: 39 additions & 258 deletions neuromorphovis/file/readers/morphology/swc_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ def __init__(self,
# sections later in an accelerated way
self.sections_terminal_samples_indices = list()

# A list of the indices of each 'disconnected' section in the morphology
self.sections_samples_indices_list = list()

# A list of continuous paths extracted from the morphology file
self.paths = list()

Expand Down Expand Up @@ -139,18 +142,15 @@ def build_connected_paths_from_samples(self):
# Filter the repeated entries in the sections_terminal_samples_indices list
self.sections_terminal_samples_indices = list(set(self.sections_terminal_samples_indices))

def build_sections_from_pathsX(self):
################################################################################################
# @build_sections_from_paths
################################################################################################
def build_sections_from_paths(self):

for path in self.paths:

print(path)

# Get an index to the first sample
first_sample_index = path[0]

# Get an index to the last sample
last_sample_index = path[-1]

# A list of all the samples located along the path
samples_located_along_path = list()

Expand Down Expand Up @@ -189,16 +189,13 @@ def build_sections_from_pathsX(self):

print(section_indices)

print('')



self.sections_samples_indices_list.append(section_indices)

print('')




#print(path)



Expand Down Expand Up @@ -300,7 +297,7 @@ def read_samples(self):
# Construct the connected paths from the samples list
self.build_connected_paths_from_samples()

self.build_sections_from_pathsX()
self.build_sections_from_paths()

################################################################################################
# @get_nmv_sample_from_samples_list
Expand Down Expand Up @@ -463,262 +460,53 @@ def build_soma(self,
return soma_object

################################################################################################
# @get_sections_from_path
# @get_sections_of_specific_type
################################################################################################
def get_sections_from_path(self,
path,
sections_terminals):
"""Gets a list of sections from a given path.
:param path:
A given path that contains at least a single section.
:param sections_terminals:
A list of all the terminals of the sections.
def get_sections_of_specific_type(self,
arbor_type):
"""
:param arbor_type:
:return:
A list of sections contained within the given path.
"""

# A list of all the sections reconstructed from the path
sections_lists = list()

# Use each section terminal indices to identify the section and reconstruct it
for section_terminals in sections_terminals:

# The index of the first sample along the section
first_sample_index = section_terminals[0]

# The index of the last sample along the section
last_sample_index = section_terminals[1]

# A flag to indicate whether this sample should be added to the list or not
collect = False

# A list to contain all the samples along the section
samples_list = list()

# Iterate over the samples in the path
for index in path:
sections_list = list()

# Is this the first sample along the section
if index == first_sample_index:
# A list that only contains the arbors of the requested type
arbor_sections_samples_indices_list = list()

# Get the a nmv sample based on its index
nmv_sample = self.get_nmv_sample_from_samples_list(index)
# For each section
for section_samples_indices in self.sections_samples_indices_list:

# Append the sample to the list
samples_list.append(nmv_sample)
# Get the last sample along this
last_sample = self.samples_list[section_samples_indices[-1]]

# Turn on the collection flag to start getting the in-between samples
collect = True
# If the type is matching
if last_sample[2] == arbor_type:

# Next sample
continue
# Append to the list
arbor_sections_samples_indices_list.append(section_samples_indices)

# If the collection flag is set
if collect:
# For each section
for arbor_section in arbor_sections_samples_indices_list:

# Get the a nmv sample based on its index
nmv_sample = self.get_nmv_sample_from_samples_list(index)
# Construct the samples list
samples_list = list()

# Append the sample to the list
samples_list.append(nmv_sample)
# For each sample in the section
for arbor_sample_index in arbor_section:

# If this was the last sample
if index == last_sample_index:
# Get the a nmv sample based on its index
nmv_sample = self.get_nmv_sample_from_samples_list(arbor_sample_index)

# Break and proceed to the next section
break
samples_list.append(nmv_sample)

# Construct an nmv section that ONLY contains the samples list, and UPDATE its other
# members later when all the other sections are reconstructed
nmv_section = neuromorphovis.skeleton.Section(samples=samples_list)

# Append this section to the sections list
sections_lists.append(nmv_section)

# Return a reference to the reference list
return sections_lists

################################################################################################
# @build_connected_paths
################################################################################################
@staticmethod
def build_connected_paths(samples_list):
"""Constructs connected paths from a given list of samples. Each path is simply represented
by a list of indices that can be used later to query the actual data of each sample.
:param samples_list:
A list of samples that are supposedly belonging to a single branch type.
:return:
A list of all the connected paths that are formed from the given list of samples.
"""

# A list of paths
paths_list = list()

# Number of samples in the input list
number_samples = len(samples_list)

# The index of the current sample
current_sample_index = 0

# Proceed if we have more samples
while current_sample_index < number_samples - 1:

# If this is the soma sample, then ignore it
# NOTE: Soma samples are indicated by -1 as a parent index
if samples_list[current_sample_index][6] == -1:

# Increment the sample index
current_sample_index = current_sample_index + 1

# Next sample
continue

# If this is a root sample with no parent, then ignore
# NOTE: Root samples are indicated by 1 as a parent index
if samples_list[current_sample_index][6] == 1:

# Increment the sample index
current_sample_index = current_sample_index + 1

# Next sample
continue

# Construct a path here
path = list()

# Get the first sample along the section
current_sample = samples_list[current_sample_index]

# Add the parent sample, or the starting sample along the branch
path.append(current_sample[6])

# Add the current sample as well
path.append(current_sample[0])

# Increment the section of the current sample
current_sample_index = current_sample_index + 1

# Process the samples again
for i in range(current_sample_index, number_samples):

# If the parent index matches the current sample index
if samples_list[i][6] == samples_list[i - 1][0]:

# Add this sample to the list
path.append(samples_list[i][0])

# Increment the sample index
current_sample_index = current_sample_index + 1

else:

# No more samples to add to the path, so append the path to the list
paths_list.append(path)

# break the 'for' loop
break

# Return a list of all the paths constructed from the list
return paths_list

################################################################################################
# @build_disconnected_sections_from_paths
################################################################################################
def build_sections_from_paths(self,
paths_list,
section_type):
"""Builds a list of disconnected sections from a list of paths list, where each path can be
composed of more than a single section.
:param paths_list:
A list of paths, where each path is composed of a list of indices that map to those
of the samples given by the samples_list.
:param section_type:
The type of the section.
:return:
A list of sections, however, they are not connected and must be processed to build
the tree of each arbor.
"""

# Get a list of the starting samples of each path of the given paths
starting_samples = list()

# Also get a list of the ending samples of each path of the given paths
ending_samples = list()

# For each path in the list
for path in paths_list:

# Append the first sample to the list
starting_samples.append(path[0])

# Append the last samples to the list
ending_samples.append(path[-1])

# Remove the duplicated samples from the lists
starting_samples = set(starting_samples)
ending_samples = set(ending_samples)

# Sort the starting samples
starting_samples = sorted(starting_samples)

# A list of all the sections
sections_list = list()

# For each path
for path in paths_list:

# A list that contains the indices of all the terminals of the sections on the path
sections_terminal_indices = list()

# Construct a list that accounts for the fork points of the path
fork_samples = list()

# Construct another list that contains the indices of the bifurcation samples
bifurcation_samples = list()

# For each starting sample
for starting_sample_index in starting_samples:

# If this sample is along the path
if starting_sample_index in path:

# And also if this sample is not the first sample along the path
if not starting_sample_index == path[0]:

# Then this sample is a bifurcation sample, add it to the list
bifurcation_samples.append(starting_sample_index)

# Construct the section samples terminals, add the first sample
fork_samples.append(path[0])

# Add the bifurcation samples
for bifurcation_sample_index in bifurcation_samples:
fork_samples.append(bifurcation_sample_index)

# Add the terminal sample
fork_samples.append(path[-1])

# Construct the rest of the section
for i_sample in range(0, len(fork_samples) - 1):

# The index of the starting sample of the section
starting_index = fork_samples[i_sample]

# The index of the ending sample of the section
ending_index = fork_samples[i_sample + 1]

# Add the indices of the section terminals to the list
sections_terminal_indices.append([starting_index, ending_index])

# Get a list of all the sections on the current path
path_sections_list = self.get_sections_from_path(path, sections_terminal_indices)

# Append the reconstructed sections to the sections list
sections_list.extend(path_sections_list)
sections_list.append(nmv_section)

# Label the sections and set different indices to them
for i, section in enumerate(sections_list):
Expand All @@ -740,6 +528,7 @@ def build_sections_from_paths(self,

# Ignore processing the same section twice
if i_section.id == j_section.id:

continue

# Root sections
Expand All @@ -763,7 +552,6 @@ def build_sections_from_paths(self,
# If the index of the last sample of the section is that of the first sample of
# another section
if i_section.samples[-1].id == j_section.samples[0].id:

# Append the child section id to the children section IDs
i_section.children_ids.append(j_section.id)

Expand All @@ -788,15 +576,8 @@ def build_arbors_from_samples(self,
A list of trees, each representing an arbor of the morphology skeleton.
"""

# Get a list of samples that ONLY correspond to the given type
samples_list = self.get_samples_list_by_type(sample_type=arbor_type)

# Build connected paths (can include more than a single morphological section) from a list
# of disconnected samples
paths = self.build_connected_paths(samples_list)

# Build sections from the constructed paths
sections = self.build_sections_from_paths(paths, arbor_type)
# Get the sections that are specific to the arbor
sections = self.get_sections_of_specific_type(arbor_type)

# Build a list of arbors from a list of sections
arbors = nmv.skeleton.ops.build_arbors_from_sections(sections)
Expand Down

0 comments on commit d826012

Please sign in to comment.