import numpy as np
import McNeuron
import matplotlib.pyplot as plt
%matplotlib inline

"""
Explanation: In this script features of different calss of the neuron are shown. The features are in the form of histogram, density or scalar values.
End of explanation
"""


#loc1 = "/Volumes/Arch/Projects/Computational Anatomy/neuron_nmo/poorthuis/CNG version/060110-LII-III.CNG.swc"
loc1 = "../Generative-Models-of-Neuron-Morphology/Data/Pyramidal/poorthuis/CNG version/060110-LV.CNG.swc"
loc2 = "../Generative-Models-of-Neuron-Morphology/Data/Interneuron/allen cell types/CNG version/Pvalb-IRES-Cre-Ai14-475465561.CNG.swc"
pyramidal = McNeuron.Neuron(file_format = 'swc', input_file=loc1)
inter = McNeuron.Neuron(file_format = 'swc', input_file=loc2)
a = pyramidal.subsample(20.)
McNeuron.visualize.plot_2D(a,show_radius=True)
print len(a.nodes_list)
a.show_features(15,17,30)

btmorph3.visualize.plot_2D(inter,show_radius=False)

len(inter.nodes_list)

"""
Explanation: Class1: Interneuron
An indivisual neuron
End of explanation
"""


ax1 = McNeuron.visualize.plot_2D(pyramidal, show_radius=False)
ax2 = McNeuron.visualize.plot_2D(inter, show_radius=False)

"""
Explanation: Morphology of the neurons
The first one is pyramidal neuron and second is interneuron
End of explanation
"""


inter.show_features(15,17,30)

"""
Explanation: Feature of interneuron
End of explanation
"""


pyramidal.show_features(15,17,50)

"""
Explanation: Feature of Pyramidal
End of explanation
"""


f,(ax1, ax2) = plt.subplots(1, 2)
ax1.plot(pyramidal.sholl_r,pyramidal.sholl_n,'g')
ax2.plot(inter.sholl_r,inter.sholl_n,'m')

inter.features

"""
Explanation: Sholl Diagram
For given real number of $r$, we can calculate how many times a sphere with the radius $r$ with the center of the soma intersects with the neuron. Sholl diagram shows this number for differnt values of $r$.
For the pyramidal neuron it usually has two bumps, which represents the basal and apical dendrites, versus interneuron which usually has one.
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
a = pyramidal.diameter1
b = pyramidal.distance_from_root
c = ax1.hist(a[b>20],bins = 30,color = 'g')
ax1.set_xlabel('diameter (um3)')
ax1.set_ylabel('density')
#ax1.set_title('Histogram of the size of compartments of neuron')

a = inter.diameter
b = inter.distance_from_root
c = ax2.hist(a[b>20],bins = 15,color = 'm')
ax2.set_xlabel('diameter (um3)')
#ax2.set_ylabel('density')
#ax2.set_title('Histogram of the size of compartments of neuron')

a = inter.diameter
b = inter.distance_from_root
c = plt.hist(a[b>20],bins = 15,color = 'm')
plt.xlabel('diameter (um3)')

"""
Explanation: histogram of diameters
The histogram of the diameters of all compartments in the neuron
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
e = pyramidal.slope
x = ax1.hist(e[e!=0],bins=40,color = 'g')
ax1.set_xlabel('Value of Slope')
ax1.set_ylabel('density')

e = inter.slope
x = ax2.hist(e[e!=0],bins=40,color = 'm')
ax2.set_xlabel('Value of Slope')
#ax2.set_ylabel('density')

"""
Explanation: Histogram of Slope of each segments
By looking at the conneceted compartments, we can calculate the slope of the segment by dividing the diffrernce of radius and difference of the location. For many of them the slope is zero and we ignor them.
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
a = pyramidal.distance_from_root
b = ax1.hist(a[~np.isnan(a)],bins = 50,color = 'g')
ax1.set_xlabel('distance (um)')
ax1.set_ylabel('density')
#plt.title('Histogram of distance from soma for different compartments of neuron')

a = inter.distance_from_root
b = ax2.hist(a[~np.isnan(a)],bins = 50,color = 'm')
ax2.set_xlabel('distance (um)')
#ax2.set_ylabel('density')
#plt.title('Histogram of distance from soma for different compartments of neuron')

a = inter.distance_from_root
b = plt.hist(a[~np.isnan(a)],bins = 50,color = 'm')
plt.xlabel('distance (um)')

"""
Explanation: Histogram of distance from soma
For each compartments on the neuron, the distance from the soma are calculated and histogram of them are shown
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
a = pyramidal.local_angle
b = ax1.hist(a[~np.isnan(a)],bins = 50,color = 'g')
ax1.set_xlabel('angle (radian)')
ax1.set_ylabel('density')
#plt.title('Histogram of local angles')
a = inter.local_angle
b = ax2.hist(a[~np.isnan(a)],bins = 50,color = 'm')
ax2.set_xlabel('angle (radian)')
#ax2.set_ylabel('density')

a = inter.local_angle
b = plt.hist(a[~np.isnan(a)],bins = 50,color = 'm')
plt.xlabel('angle (radian)')

"""
Explanation: Local Angle
Local angles are the angles between the vector with the starting point of one compartment and end point of its child, and the vector that connect it to $its$ $parent$.
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
a = pyramidal.angle_global
b = ax1.hist(a[~np.isnan(a)],bins = 50,color = 'g')
ax1.set_xlabel('angle (radian)')
ax1.set_ylabel('density')
#plt.title('Histogram of global angles')

a = inter.angle_global
b = ax2.hist(a[~np.isnan(a)],bins = 50,color = 'm')
ax2.set_xlabel('angle (radian)')

a = inter.angle_global
b = plt.hist(a[~np.isnan(a)],bins = 50,color = 'm')
plt.xlabel('angle (radian)')

"""
Explanation: Global Angle
Global angles are the angles between the vector with the starting point of one compartment and end point of its child, and the vector that connect it to $soma$.
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
a = pyramidal.angle_branch[0,:]
b = ax1.hist(a[~np.isnan(a)],bins = 20,color = 'g')
a = inter.angle_branch[0,:]
b = ax2.hist(a[~np.isnan(a)],bins = 20,color = 'm')

a = inter.angle_branch[0,:]
b = plt.hist(a[~np.isnan(a)],bins = 10,color = 'm')

"""
Explanation: Angle at the branching point
At each branching points in the neuron, we can cauculate the angles between two outward segments. Here we plot the histogram of them for different branching points.
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
a = pyramidal.rall_ratio
b = ax1.hist(a[~np.isnan(a)],bins = 20,color = 'g')

a = inter.rall_ratio
b = ax2.hist(a[~np.isnan(a)],bins = 20,color = 'm')

"""
Explanation: Rall Ratio
The Rall ratio is defined by taking the ratio of the diameter^2/3 parent in branching point divided by sum of diameter^2/3 of its children.
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
a = pyramidal.slope
b = ax1.hist(a[~np.isnan(a)],bins = 40,color = 'g')

a = inter.slope
b = ax2.hist(a[~np.isnan(a)],bins = 40,color = 'm')

a = inter.slope
b = plt.hist(a[~np.isnan(a)],bins = 40,color = 'm')

"""
Explanation: Slope
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
a = pyramidal.length_to_parent
b = ax1.hist(a[~np.isnan(a)],bins = 40,color = 'g')

a = inter.length_to_parent
b = ax2.hist(a[~np.isnan(a)],bins = 40,color = 'm')

a = inter.length_to_parent
b = a[~np.isnan(a)]
c = plt.hist(b[np.absolute(b)<4],bins = 70,color = 'm')

np.absolute(b)<3

"""
Explanation: distance from parent
End of explanation
"""


f, (ax1, ax2) = plt.subplots(1, 2)
ax1.hist(inter.overall_connectivity_matrix.sum(axis = 1)/inter.distance_from_root,bins = 40,color = 'g')
ax2.hist(pyramidal.overall_connectivity_matrix.sum(axis = 1)/pyramidal.distance_from_root,bins = 40,color = 'g')

plt.hist(inter.features['ratio_euclidian_neuronal'],bins = 40,color = 'g')

"""
Explanation: Ratio of neuronal distance over Euclidian distance from root
End of explanation
"""


import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(inter.connection)
plt.show()

"""
Explanation: Connectivity matrix
End of explanation
"""


