In [1]:
from maybrain import constants as ct
from maybrain import resources as rr
from maybrain import brain as mbt
a = mbt.Brain()
a.import_adj_file(rr.DUMMY_ADJ_FILE_500)
a.import_spatial_info(rr.MNI_SPACE_COORDINATES_500)
a.apply_threshold()
In [2]:
a.subject = 2316 # For example, an ID
a.scan = '20170501U-ID15160' # For example, the day of the scan and the correspondent ID
# Python also has functionalities if you want to uniquely identify a Brain instance:
print(id(a))
In [3]:
print("Old value at edge (2,3) in adjMat: ", a.adjMat[2][3])
print("Old value at edge (2,3) in a.G", a.G.edges[2,3][ct.WEIGHT])
# Changing edge (2,3) at a.G:
a.G.edges[2,3][ct.WEIGHT] = 3
a.update_adj_mat((2,3))
print("New value at edge (2,3) in a.G: ", a.G.edges[2,3][ct.WEIGHT])
print("New value at edge (2,3) in adjMat: ", a.adjMat[2][3])
You can also update the whole adjacency matrix at once. Note that in our G
object there is no edge between a node to itself thus, when reconstructing the adjacency matrix, that value will be nan
:
In [4]:
print("Weight of edge (0,0) in adjMat: ", a.adjMat[0][0])
a.reconstruct_adj_mat()
print("Weight of edge (0,0) in adjMat after reconstructing: ", a.adjMat[0][0])
In [5]:
# Import adjacency file again because adjMat was altered before
a.import_adj_file(rr.DUMMY_ADJ_FILE_500)
a.apply_threshold(threshold_type="totalEdges", value = 1)
print("Number of nodes: ", a.G.number_of_nodes())
a.remove_unconnected_nodes()
print("Number of nodes after removing: ", a.G.number_of_nodes())
Looking to the edges of your G
object you can see which nodes are connected, but you might prefer to have that information in the nodes themselves.
With find_linked_nodes()
you can add a property to each node saying to which other nodes it is connected. You can access that property through constants.LINKED_NODES
.
In [6]:
# Import adjacency file again because adjMat was altered before
a.import_adj_file(rr.DUMMY_ADJ_FILE_500)
a.apply_threshold(threshold_type="totalEdges", value="5")
print("Our edges are: ", a.G.edges())
a.find_linked_nodes()
#As the graph is undirected, this property works on both directions:
print("Node 341 is linked to: ", a.G.nodes[341][ct.LINKED_NODES])
print("Node 238 is linked to: ", a.G.nodes[238][ct.LINKED_NODES])
print("Node 92 is linked to: ", a.G.nodes[92][ct.LINKED_NODES])
print("Node 1 is linked to: ", a.G.nodes[1][ct.LINKED_NODES], " (nothing)")
With a weight, the higher the value the stronger the connection. With a distance, the higher the value the "weaker" the connection.
If you want to convert the weights of our edges in a way that they can be seen as distances, you just have to use weight_to_distance()
. Note that there is no measurement unit for the distance, as it just a conversion from the weights.
Essentially, the value of the maximum weight will be approximately the value of the highest possible distance (if your weights are all positive in the first place).
In [7]:
print("Our edges before conversion: ")
for e in a.G.edges(data=True):
print(e)
a.weight_to_distance()
print("Our edges after conversion: ")
for e in a.G.edges(data=True):
print(e)
You can access weights and distances of specific edges through constants.WEIGHT
and constants.DISTANCE
, respectively:
In [8]:
print("Weight of edge (92,302): ", a.G.edges[92, 302][ct.WEIGHT])
print("Distance of edge (92,302): ", a.G.edges[92, 302][ct.DISTANCE])
All the examples so far consider that a brain is represented as an unidirected graph. It is possible to use Brain as a brain that is represented as a directed graph.
In practice, that means that when you call import_adj_file()
, the lower half of the matrix is also considered, as now the adjacency matrix is not considered symmetric.
In [9]:
# Not directed adjacency matrix
a.import_adj_file(rr.DUMMY_ADJ_FILE_500)
a.apply_threshold()
print("Is the brain 'a' directed?: ", a.directed)
print("Number of edges of a: ", a.G.number_of_edges())
# Direct adjacency matrix
d = mbt.Brain(directed=True)
d.import_adj_file(rr.DUMMY_ADJ_FILE_500)
d.apply_threshold()
print("Is the brain 'd' directed?: ", d.directed)
print("Number of edges of d: ", d.G.number_of_edges())
Because of being directed, some methods cannot be executed, but an exception is thrown in those cases:
In [10]:
try:
d.local_thresholding()
except TypeError as error:
print("Error message:", error)
In [11]:
%matplotlib inline
from maybrain.plotting import connectome as cc
# Spatial information for plotting
a.import_spatial_info(rr.MNI_SPACE_COORDINATES_500)
# Removing nodes from left hemisphere (nodes with X coordinate below 0)
nodes_remove = []
for n in a.G.nodes():
if a.G.nodes[n][ct.XYZ][0] < 0:
nodes_remove.append(n)
a.G.remove_nodes_from(nodes_remove)
# Plotting how the brain is now
cc.plot_connectome(a, only_nodes=True, node_size=10)
Out[11]:
Now, we can call maybrain's method copy_hemisphere
, specifying that we want to copy the right hemisphere. It is noteworthy to say that at this point, if there were any nodes in the left hemisphere, they would be deleted beforehand. However, for an easier visualisation, we removed those already.
In [12]:
a.copy_hemisphere("R")
cc.plot_connectome(a, only_nodes=True, node_size=10)
Out[12]:
We could do the same thing the other way around: copying the left hemisphere to the right hemisphere (the current nodes on the right hemisphere are deleted):
In [13]:
a.copy_hemisphere("L")
cc.plot_connectome(a, only_nodes=True, node_size=10)
Out[13]: