%%capture
!pip install tmd wget neurom[plotly]

import os
import wget
import tmd

import neurom as nm
import ipywidgets as widgets

from neurom.view import plotly_impl

astrocyte_base_url = "https://bbp.epfl.ch/ngv-portal/data/anatomy/reconstruction-data/synthesized-astrocyte-morphologies"
astrocyte_filenames = ["GLIA_0000000000100.h5", "GLIA_0000000000400.h5", "GLIA_0000000001200.h5", "GLIA_0000000001500.h5", "GLIA_0000000002350.h5", "GLIA_0000000003100.h5", "GLIA_0000000003400.h5", "GLIA_0000000004200.h5", "GLIA_0000000004500.h5", "GLIA_0000000000200.h5", "GLIA_0000000000500.h5", "GLIA_0000000001350.h5", "GLIA_0000000002100.h5", "GLIA_0000000002400.h5", "GLIA_0000000003250.h5", "GLIA_0000000003500.h5", "GLIA_0000000004300.h5", "GLIA_0000000000300.h5", "GLIA_0000000001100.h5", "GLIA_0000000001400.h5", "GLIA_0000000002250.h5", "GLIA_0000000002500.h5", "GLIA_0000000003350.h5", "GLIA_0000000004100.h5", "GLIA_0000000004400.h5"]

astrocyte_select = widgets.Select(
    options=astrocyte_filenames,
    value=astrocyte_filenames[0],
    rows=10,
    description='Astrocyte:',
    disabled=False
)
display(astrocyte_select)

astrocyte_path = astrocyte_select.value
astrocyte_url = f'{astrocyte_base_url}/{astrocyte_path}'
wget.download(astrocyte_url, os.getcwd())

astrocyte = nm.load_morphology(astrocyte_path)

"""
Explanation: Astrocyte analysis
End of explanation
"""


fig, ax = plotly_impl.plot_morph3d(astrocyte, inline=True)

"""
Explanation: Show the astrocyte
<div class="alert alert-block alert-warning">
    <b>Hint:</b>
    The plot in the following cell might appear with a delay, even if the cell execution is marked as 'done'. This is because a significant amount of data has to be transferred after the actual cell execution has finished.
</div>
End of explanation
"""


# Extract the total number of neurites (basal and apical dendrites, and axons)
number_of_neurites = nm.get('number_of_neurites', astrocyte)

# Extract the total number of sections
number_of_sections = nm.get('number_of_sections', astrocyte)

# Extract the soma radius
soma_radius = astrocyte.soma.radius

# Extract the number of sections per neurite
number_of_sections_per_neurite = nm.get('number_of_sections_per_neurite', astrocyte)

# Print result
print("Astrocyte id       : {0} \n\
Number of neurites : {1} \n\
Soma radius        : {2:.2f} \n\
Number of sections : {3}".format(astrocyte.name, number_of_neurites, soma_radius, number_of_sections))
print()
print("Neurite type \t\t\t| Number of sections")
for i, neurite in enumerate(astrocyte.neurites):    
    print("{0:31} | {1}".format(str(neurite.type), number_of_sections_per_neurite[i]))

# Extract the lengths of the sections
section_lengths = nm.get('section_lengths', astrocyte)

# Extract the lengths of the segments
segment_lengths = nm.get('segment_lengths', astrocyte)

# Extract the local bifurcation angles
local_bif_angles = nm.get('local_bifurcation_angles', astrocyte)

# Extract the remote bifurcation angles
remote_bif_angles = nm.get('remote_bifurcation_angles', astrocyte)

# Extract the radial distances of the sections
section_radial_distances = nm.get('section_radial_distances', astrocyte)

# Extract the path distances of the sections
section_path_distances = nm.get('section_path_distances', astrocyte)

# Print result
features = (segment_lengths, section_lengths, local_bif_angles, 
            remote_bif_angles, section_path_distances, section_radial_distances)

def check(feature_list, n): 
    return '{0:.2f}'.format(feature_list[n]) if n < len(feature_list) else ''

print('|sg_len|sc_len|lc_bif_angles|rm_bif_angles|sc_path_dists|sc_rad_dists|')
for n in range(0, 50):
    args = (check(f, n) for f in features)
    print('|{0:^6}|{1:^6}|{2:^13}|{3:^13}|{4:^13}|{5:^12}|'.format(*args))



"""
Explanation: Morphology Analysis
End of explanation
"""


import matplotlib.pyplot as plt

# Select the feature of choice
feature = nm.get('section_lengths', astrocyte)

# Create empty figure
fig = plt.figure(figsize=(21, 5))

# Create histogram
ax = fig.add_subplot(131)
ax.hist(feature, bins=25, edgecolor='black')

# Create cumulative histogram
ax = fig.add_subplot(132)
ax.hist(feature, bins=25, cumulative=True, edgecolor='black')

# Create boxplot; flier points are indicated with green dots
ax = fig.add_subplot(133)
_ = ax.boxplot(feature, sym='g.')

# Select the feature of choice
feature = nm.get('section_path_distances', astrocyte)

# Create empty figure
fig = plt.figure(figsize=(21, 5))

# Create histogram
ax = fig.add_subplot(131)
ax.hist(feature, bins=25, edgecolor='black')

# Create cumulative histogram
ax = fig.add_subplot(132)
ax.hist(feature, bins=25, cumulative=True, edgecolor='black')

# Create boxplot; flier points are indicated with green dots
ax = fig.add_subplot(133)
_ = ax.boxplot(feature, sym='g.')

"""
Explanation: Morphometrics plots
End of explanation
"""


# Step 2: Load your morphology
neu = tmd.io.load_neuron(astrocyte_path)

# Step 5: Extract the ph diagram of a neuron's trees,
# depending on the neurite_type
ph_axon = tmd.methods.get_ph_neuron(neu, neurite_type='axon')
ph_basal = tmd.methods.get_ph_neuron(neu, neurite_type='basal')

# Step 6: Plot the extracted topological data with three different ways
from tmd.view import view, plot

# Visualize the persistence diagram
fig, ax = plot.diagram(ph_axon)

# Visualize the persistence barcode
fig, ax = plot.barcode(ph_axon)

# Visualize the persistence image
fig, ax = plot.persistence_image(ph_axon)

"""
Explanation: Extract and plot branching topology
End of explanation
"""


