Skip to content

Commit

Permalink
Add testing of example scripts (#1041) (#1096)
Browse files Browse the repository at this point in the history
  • Loading branch information
eleftherioszisis authored Jan 26, 2024
1 parent 8c30ecc commit cb18a10
Show file tree
Hide file tree
Showing 16 changed files with 245 additions and 547 deletions.
26 changes: 23 additions & 3 deletions examples/boxplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,17 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Box Plot function for multiple morphs."""
from pathlib import Path

from neurom import load_morphologies
from neurom.view import matplotlib_utils
from neurom.features import get


def boxplot(neurons, feature, new_fig=True, subplot=False):
PACKAGE_DIR = Path(__file__).resolve().parent.parent


def boxplot(neurons, feature, new_fig=True, subplot=111):
"""Plot a histogram of the selected feature for the population of morphologies.
Plots x-axis versus y-axis on a scatter|histogram|binned values plot.
Expand All @@ -52,12 +58,26 @@ def boxplot(neurons, feature, new_fig=True, subplot=False):
Default is False, which returns a matplotlib figure object. If True,
returns a matplotlib axis object, for use as a subplot.
"""
feature_values = [getattr(neu, 'get_' + feature)() for neu in neurons]
feature_values = [get(feature, neuron) for neuron in neurons]

_, ax = matplotlib_utils.get_figure(new_fig=new_fig, subplot=subplot)

ax.boxplot(feature_values)

x_labels = ['neuron_id' for _ in neurons]
x_labels = [neuron.name for neuron in neurons]

ax.set_xticklabels(x_labels)

# uncomment below to show image
# pylab.show()


def main():

morphology_directory = Path(PACKAGE_DIR, "tests/data/valid_set")
neurons = load_morphologies(morphology_directory)
boxplot(neurons, "section_lengths")


if __name__ == "__main__":
main()
31 changes: 27 additions & 4 deletions examples/density_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,28 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Example for generating density plots."""
from pathlib import Path

import pylab as plt
import matplotlib as mpl
import numpy as np

from neurom import get as get_feat
from neurom.view import matplotlib_utils, matplotlib_impl
from neurom.core.types import NeuriteType

from neurom import load_morphologies

PACKAGE_DIR = Path(__file__).resolve().parent.parent


def extract_density(population, plane='xy', bins=100, neurite_type=NeuriteType.basal_dendrite):
"""Extracts the 2d histogram of the center
coordinates of segments in the selected plane.
"""
segment_midpoints = get_feat('segment_midpoints', population, neurite_type=neurite_type)
segment_midpoints = np.array(
get_feat('segment_midpoints', population, neurite_type=neurite_type)
)
horiz = segment_midpoints[:, 'xyz'.index(plane[0])]
vert = segment_midpoints[:, 'xyz'.index(plane[1])]
return np.histogram2d(np.array(horiz), np.array(vert), bins=(bins, bins))
Expand All @@ -62,12 +70,13 @@ def plot_density(population, # pylint: disable=too-many-arguments, too-many-loc
mask = H1 < threshold # mask = H1==0
H2 = np.ma.masked_array(H1, mask)

getattr(plt.cm, color_map).set_bad(color='white', alpha=None)
colormap = mpl.cm.get_cmap(color_map).copy()
colormap.set_bad(color='white', alpha=None)

plots = ax.contourf((xedges1[:-1] + xedges1[1:]) / 2,
(yedges1[:-1] + yedges1[1:]) / 2,
np.transpose(H2), # / np.max(H2),
cmap=getattr(plt.cm, color_map), levels=levels)
cmap=colormap, levels=levels)

if not no_colorbar:
cbar = plt.colorbar(plots)
Expand All @@ -91,9 +100,23 @@ def plot_neuron_on_density(population, # pylint: disable=too-many-arguments
"""
_, ax = matplotlib_utils.get_figure(new_fig=new_fig)

matplotlib_impl.plot_tree(population.neurites[0], ax)
ref_neuron = population[0]
matplotlib_impl.plot_tree(ref_neuron.neurites[0], ax)

return plot_density(population, plane=plane, bins=bins, new_fig=False, subplot=subplot,
colorlabel=colorlabel, labelfontsize=labelfontsize, levels=levels,
color_map=color_map, no_colorbar=no_colorbar, threshold=threshold,
neurite_type=neurite_type, **kwargs)


def main():

morphology_directory = Path(PACKAGE_DIR, "tests/data/valid_set")
neurons = load_morphologies(morphology_directory)

plot_density(neurons)
plot_neuron_on_density(neurons)


if __name__ == "__main__":
main()
15 changes: 12 additions & 3 deletions examples/end_to_end_distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Calculate and plot end-to-end distance of neurites."""
from pathlib import Path

import neurom as nm
from neurom import morphmath
import numpy as np
import matplotlib.pyplot as plt


PACKAGE_DIR = Path(__file__).resolve().parent.parent


def path_end_to_end_distance(neurite):
"""Calculate and return end-to-end-distance of a given neurite."""
trunk = neurite.root_node.points[0]
Expand All @@ -54,7 +58,8 @@ def make_end_to_end_distance_plot(nb_segments, end_to_end_distance, neurite_type
plt.title(neurite_type)
plt.xlabel('Number of segments')
plt.ylabel('End-to-end distance')
plt.show()
# uncomment to show
#plt.show()


def calculate_and_plot_end_to_end_distance(neurite):
Expand All @@ -71,9 +76,9 @@ def _dist(seg):
end_to_end_distance, neurite.type)


if __name__ == '__main__':
def main():
# load a neuron from an SWC file
filename = 'tests/data/swc/Neuron_3_random_walker_branches.swc'
filename = Path(PACKAGE_DIR, 'tests/data/swc/Neuron_3_random_walker_branches.swc')
m = nm.load_morphology(filename)

# print mean end-to-end distance per neurite type
Expand All @@ -92,3 +97,7 @@ def _dist(seg):
# print (number of segments, end-to-end distance, neurite type)
print(sum(len(s.points) - 1 for s in nrte.root_node.ipreorder()),
path_end_to_end_distance(nrte), nrte.type)


if __name__ == '__main__':
main()
38 changes: 16 additions & 22 deletions examples/extract_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,52 +31,46 @@
"""Extract a distribution for the selected feature of the population of morphologies among
the exponential, normal and uniform distribution, according to the minimum ks distance.
"""
from pathlib import Path

from itertools import chain
import argparse
import json

import neurom as nm
from neurom import stats
from neurom.utils import NeuromJSON


def parse_args():
"""Parse command line arguments."""
parser = argparse.ArgumentParser(
description='Morphology fit distribution extractor',
epilog='Note: Outputs json of the optimal distribution \
and corresponding parameters.')
PACKAGE_DIR = Path(__file__).resolve().parent.parent

parser.add_argument('datapath',
help='Path to morphology data directory')

parser.add_argument('feature',
help='Feature to be extracted with neurom.get')

return parser.parse_args()


def extract_data(data_path, feature):
def find_optimal_distribution(population_directory, feature):
"""Loads a list of morphologies, extracts feature
and transforms the fitted distribution in the correct format.
Returns the optimal distribution, corresponding parameters,
minimun and maximum values.
"""
population = nm.load_morphologies(data_path)
population = nm.load_morphologies(population_directory)

feature_data = [nm.get(feature, n) for n in population]
feature_data = list(chain(*feature_data))

return stats.optimal_distribution(feature_data)


if __name__ == '__main__':
args = parse_args()
def main():

population_directory = Path(PACKAGE_DIR, "tests/data/valid_set")

d_path = args.datapath
result = stats.fit_results_to_dict(
find_optimal_distribution(population_directory, "section_lengths")
)

feat = args.feature
print(json.dumps(
result, indent=2, separators=(',', ': '), cls=NeuromJSON
))

_result = stats.fit_results_to_dict(extract_data(d_path, feat))

print(json.dumps(_result, indent=2, separators=(',', ': ')))
if __name__ == '__main__':
main()
48 changes: 20 additions & 28 deletions examples/features_graph_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,33 +28,14 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Example for comparison of the same feature of multiple cells."""
import argparse
from pathlib import Path

import pylab as pl
import neurom as nm
from neurom.io.utils import get_morph_files


def parse_args():
"""Parse command line arguments."""
parser = argparse.ArgumentParser(description='Feature Comparison Between Different Cells')

parser.add_argument('-d',
'--datapath',
help='Data directory')

parser.add_argument('-o',
'--odir',
default='.',
help='Output path')

parser.add_argument('-f',
'--features',
nargs='+',
help='List features separated by spaces')

return parser.parse_args()
PACKAGE_DIR = Path(__file__).resolve().parent.parent


def stylize(ax, name, feature):
Expand Down Expand Up @@ -88,7 +69,7 @@ def histogram(neuron, feature, ax, bins=15, normed=True, cumulative=False):

feature_values = nm.get(feature, neuron)
# generate histogram
ax.hist(feature_values, bins=bins, cumulative=cumulative, normed=normed)
ax.hist(feature_values, bins=bins, cumulative=cumulative, density=normed)


def plot_feature(feature, cell):
Expand All @@ -106,14 +87,25 @@ def plot_feature(feature, cell):
return fig


if __name__ == '__main__':
args = parse_args()
def create_feature_plots(morphologies_dir, feature_list, output_dir):

for morph_file in get_morph_files(args.datapath):
for morph_file in get_morph_files(morphologies_dir):
m = nm.load_morphology(morph_file)

for _feature in args.features:
f = plot_feature(_feature, m)
figname = "{0}_{1}.eps".format(_feature, m.name)
f.savefig(Path(args.odir, figname))
for feature_name in feature_list:
f = plot_feature(feature_name, m)
figname = f"{feature_name}_{m.name}.eps"
f.savefig(Path(output_dir, figname))
pl.close(f)


def main():
create_feature_plots(
morphologies_dir=Path(PACKAGE_DIR, "tests/data/valid_set"),
feature_list=["section_lengths"],
output_dir=".",
)


if __name__ == '__main__':
main()
13 changes: 10 additions & 3 deletions examples/get_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@
morphometrics functionality.
"""
from pathlib import Path

from __future__ import print_function
from pprint import pprint
import numpy as np
import neurom as nm


PACKAGE_DIR = Path(__file__).resolve().parent.parent


def stats(data):
"""Dictionary with summary stats for data
Expand All @@ -60,9 +63,9 @@ def pprint_stats(data):
pprint(stats(data))


if __name__ == '__main__':
def main():

filename = 'tests/data/swc/Neuron.swc'
filename = Path(PACKAGE_DIR, 'tests/data/swc/Neuron.swc')

# load a neuron from an SWC file
m = nm.load_morphology(filename)
Expand Down Expand Up @@ -152,3 +155,7 @@ def pprint_stats(data):
rem_bifangles = nm.get('remote_bifurcation_angles', m, neurite_type=ttype)
print('Local bifurcation angles (', ttype, '):', sep='')
pprint_stats(rem_bifangles)


if __name__ == '__main__':
main()
Loading

0 comments on commit cb18a10

Please sign in to comment.