Example of sulcal graph in slamΒΆ

# Authors:
# Lucile Hashimoto lucile-hashimoto
# Guillaume Auzias <guillaume.auzias@univ-amu.fr>

# License: MIT
# sphinx_gallery_thumbnail_number = 2
NOTE: there is no visualization tool in slam, but we provide at the

end of this script exemplare code to do the visualization with an external solution


importation of slam modules

import slam.io as sio
import slam.sulcal_graph as ssg
import numpy as np

loading an examplar mesh and corresponding texture

path_to_mesh = "../examples/data/example_mesh.gii"
path_to_texture = "../examples/data/example_texture.gii"
path_to_mask = ""
mesh = sio.load_mesh(path_to_mesh)
side = "left"
texture = sio.load_texture(path_to_texture)
dpf = np.array(texture.darray[0])

extract the sulcal graph from a mesh

g = ssg.extract_sulcal_graph(side, path_to_mesh, path_to_features=None, path_to_output=None, path_to_mask=None)
        Computing the curvature

Calculating vertex normals .... Please wait
Finished calculating vertex normals
Calculating curvature tensors ... Please wait
Finished Calculating curvature tensors
Calculating Principal Components ... Please wait
Finished Calculating principal components

        Computing the DPF

  Computing Laplacian
    Computing mesh weights of type conformal
    -edge length threshold needed for  0  values =  0.0  %
    -number of Nan in weights:  0  =  0.0  %
    -number of Negative values in weights:  936  =  6.706792777300086  %
    -nb Nan in Laplacian :  0
    -nb Inf in Laplacian :  0

        Computing Voronoi's vertex

    -percent polygon with obtuse angle  29.4067067927773

        Computing the Fiedler geodesic length and surface area

  Computing Laplacian
    Computing mesh weights of type fem
    -edge length threshold needed for  0  values =  0.0  %
    -number of Nan in weights:  0  =  0.0  %
    -number of Negative values in weights:  936  =  6.706792777300086  %
    -nb Nan in Laplacian :  0
    -nb Inf in Laplacian :  0
Fielder length [76.42611449]
Distance threshold : [6.47816186]
Computing watershed by flooding...
Distance between 2 pits: [6.47816186] mm - Ridge height: 1.5 mm
Number of basins found: 3
nb of basins to remove: 0
{'ridge_index': np.int64(1456), 'ridge_depth': np.float64(-0.0014745279408387838), 'ridge_length': 105}
{'ridge_index': np.int64(1582), 'ridge_depth': np.float64(0.017893096864326573), 'ridge_length': 64}
{'ridge_index': np.int64(1425), 'ridge_depth': np.float64(-0.0014448661950041066), 'ridge_length': 105}
{'ridge_index': np.int64(1852), 'ridge_depth': np.float64(-0.031923839266200967), 'ridge_length': 39}
{'ridge_index': np.int64(1624), 'ridge_depth': np.float64(0.018081363426378092), 'ridge_length': 64}
{'ridge_index': np.int64(1910), 'ridge_depth': np.float64(-0.03193010809395638), 'ridge_length': 39}
Edge 0 attributes: dict_keys(['weight'])
Edge 1 attributes: dict_keys(['weight'])
Edge 2 attributes: dict_keys(['weight'])
Edge 0 attributes: dict_keys(['weight', 'ridge_index', 'ridge_depth', 'ridge_length'])
Edge 1 attributes: dict_keys(['weight', 'ridge_index', 'ridge_depth', 'ridge_length'])
Edge 2 attributes: dict_keys(['weight', 'ridge_index', 'ridge_depth', 'ridge_length'])
Graph saved in graph.gpickle

add an attribute to nodes

g = ssg.add_node_attribute_to_graph(g, dpf, name='pit_depth', save=False)
print("Node attributes:\n", g.nodes[0].keys())
print("First node:\n", g.nodes[0])
Node attributes:
 dict_keys(['pit_index', 'basin_vertices', 'pit_depth', 'basin_area', 'basin_label'])
First node:
 {'pit_index': 1737, 'basin_vertices': [1737, 1657, 1656, 1711, 312, 320, 1712, 1632, 1630, 319, 321, 1736, 1655, 1659, 316, 330, 329, 313, 1713, 327, 1585, 3, 1672, 1583, 10, 333, 1586, 1710, 339, 322, 745, 337, 338, 24, 1714, 317, 1635, 1556, 800, 6, 1960, 801, 1930, 1554, 799, 128, 826, 1654, 1917, 323, 771, 825, 1588, 833, 1589, 1584, 1984, 394, 1558, 1929, 854, 1959, 1738, 141, 824, 341, 115, 1562, 1557, 865, 1638, 1555, 834, 1631, 99, 802, 811, 1983, 324, 855, 1918, 888, 340, 388, 1633, 116, 1590, 398, 1563, 129, 1715, 827, 1671, 881, 1862, 900, 1560, 1565, 1982, 823, 898, 416, 718, 1559, 1675, 751, 866, 889, 314, 1658, 835, 344, 696, 117, 720, 1592, 2018, 788, 919, 864, 399, 1718, 1561, 918, 1566, 1886, 836, 101, 421, 118, 1961, 921, 170, 1641, 345, 897, 890, 1564, 2028, 1634, 705, 719, 789, 1717, 1587, 151, 395, 1594, 891, 832, 932, 110, 946, 935, 1863, 899, 404, 1755, 1673, 1567, 346, 349, 1677, 2019, 1593, 383, 934, 1962, 454, 372, 422, 945, 455, 1636, 721, 837, 2029, 1591, 709, 937, 1826, 199, 955, 954, 1721, 1637, 111, 902, 1679, 493, 892, 1597, 1596, 389, 933, 1963, 1660, 1595, 735, 1887, 2001, 352, 1643, 326, 903, 417, 447, 47, 712, 473, 981, 980, 1639, 1665, 1777, 736, 1743, 979, 1599, 985, 353, 191, 904, 1666, 1941, 106, 956, 171, 219, 1603, 1964, 348, 1889, 994, 335, 159, 1640, 1723, 1601, 1598, 2002, 1646, 1006, 423, 390, 1661, 1888, 1008, 223, 995, 1874, 1604, 957, 11, 1674, 1004, 1724, 722, 920, 494, 901, 355, 1642, 1611, 1667, 737, 1931, 315, 923, 1013, 474, 1682, 1014, 996, 2003, 1647, 124, 1020, 905, 212, 969, 429, 1608, 1778, 958, 1619, 1726, 1615, 1662, 993, 1663, 173, 1650, 192, 1965, 1716, 1686, 1606, 1577, 1621, 1744, 405, 1600, 1843, 997, 1624, 1038, 1579, 723, 749, 936, 1019, 1668, 1966, 1728, 1942, 1021, 1536, 1576, 1040, 1569, 1039, 311, 1764, 484, 1664, 2069, 869, 1745, 1676, 2004, 959, 1064, 1845, 357, 1678, 2075, 1574, 1022, 1071, 1037, 437, 318, 396, 1602, 112, 971, 424, 1012, 1079, 1065, 1098, 1932, 2076, 69, 2195, 1568, 406, 1097, 1130, 1032, 1864, 407, 1605, 786, 922, 430, 724, 713, 1080, 1644, 1023, 1096, 1784, 1150, 992, 73, 125, 1163, 1030, 2151, 1128, 359, 2150, 2005, 510, 1208, 485, 1177, 193, 1099, 233, 1209, 361, 438, 575, 906, 1243, 200, 408, 1176, 448, 1262, 431, 461, 1054, 972, 1244, 787, 1610, 1180, 1112, 1081, 1283, 2196, 1286, 1301, 174, 1967, 1325, 1752, 750, 1336, 1384, 81, 65, 443, 1224, 1425, 1245, 2152, 1719, 1943, 1426, 2194, 1323, 1302, 1410, 828, 1363, 1385, 89, 1326, 72, 882, 1002, 78, 1114, 1151, 305, 1082, 76, 74, 1044, 1386, 1720, 739, 1287, 130, 1645, 867, 2111, 557, 475, 940, 1225, 962, 725, 1113, 1324, 1364, 1387, 1365, 1175, 1164, 439, 1284, 1115, 1337, 1011, 61, 293, 213, 907, 1134, 2183, 780, 1135, 893, 829, 71, 1264, 1181, 298, 858, 1890, 1083, 1389, 1754, 1366, 1102, 268, 1016, 1327, 586, 1074, 2294, 52, 2006, 2071, 295, 1154, 1210, 68, 55, 973, 1001, 1137, 2170, 360, 793, 2296, 1368, 182, 989, 576, 1265, 1116, 358, 70, 79, 595, 2182, 2169, 1285, 925, 2181, 60, 1155, 738, 1338, 1029, 1266, 1003, 1212, 286, 613, 1035, 2305, 2207, 830, 818, 1138, 1304, 1288, 1184, 50, 1753, 805, 2020, 1681, 983, 2290, 354, 1968, 1118, 265, 2141, 978, 2275, 569, 1740, 551, 2180, 296, 2245, 9, 1183, 1328, 1213, 278, 1246, 51, 761, 614, 628, 638, 1156, 2206, 632, 883, 2289, 1306, 1036, 1028, 1005, 2237, 96, 1149, 982, 558, 2209, 1140, 1182, 1340, 1178, 584, 1063, 1085, 2291, 1227, 1303, 872, 752, 1157, 44, 2281, 1185, 1290, 602, 528, 2110, 1167, 603, 511, 2246, 1790, 1214, 1680, 1944, 1087, 272, 35, 142, 2168, 1031, 645, 2238, 1307, 1186, 1120, 1179, 287, 1188, 145, 1305, 1739, 908, 706, 1129, 2022, 2208, 1741, 2321, 2095, 984, 1248, 1229, 1007, 648, 1791, 543, 1289, 175, 1088, 2109, 152, 1216, 639, 1047, 1309, 1251, 1308, 1985, 2283, 1051, 525, 577, 512, 1230, 1169, 2282, 147, 244, 1247, 2070, 684, 1250, 604, 1269, 2021, 1217, 230, 641, 100, 183, 1722, 1988, 139, 1231, 1249, 544, 1742, 710, 2025, 1253, 220, 1168, 2078, 1191, 269, 236, 1232, 334, 2108, 2284, 570, 640, 726, 1144, 646, 1920, 587, 176, 250, 545, 258, 605, 1987, 2269, 2077, 2023, 526, 2024, 629, 615, 2042, 688, 552, 711, 2142, 803, 633, 259, 727, 1893, 622, 59, 2153, 578, 1986, 986, 1868, 1919, 728, 1990, 596, 260, 245, 621, 536, 2007, 2112, 697, 566, 2184, 2270, 2080, 2250, 1945, 2079, 131, 1792, 2266, 1892, 2242, 1870, 2197, 224, 942, 2265, 1989, 254, 547, 184, 251, 119, 2264, 1895, 938, 2185, 2113, 2247, 1009, 66, 1015, 1933, 2047, 2186, 2171, 1873, 56, 120, 1991, 952, 1897, 2114, 177, 2081, 53, 234, 553, 2214, 2115, 2097, 1900, 2251, 2048, 939, 132, 754, 2096, 1904, 2116, 1971, 1898, 2098, 201, 2227, 214, 1903, 45, 2082, 156, 1875, 1798, 2099, 13, 347, 755, 2009, 1973, 2100, 2086, 2230, 21, 2083, 2050, 1992, 2084, 949, 2231, 172, 2087, 560, 202, 2072, 2085, 31, 29, 2213, 2073, 2088, 37, 948, 2215, 2212, 2200, 2174, 947, 2211, 2173, 2199, 2172, 2198, 530, 535, 529], 'pit_depth': np.float32(0.05293567), 'basin_area': np.float64(2500.062766852061), 'basin_label': 0}

add an attribute to edges

g = ssg.add_edge_attribute_to_graph(g, dpf, name='ridge_depth_bis', save=False)
print("Edge attributes:\n", g.edges[list(g.edges)[0]].keys())
print("First edge:\n", g.edges[list(g.edges)[0]])
Edge attributes:
 dict_keys(['weight', 'ridge_index', 'ridge_depth', 'ridge_length', 'ridge_depth_bis'])
First edge:
 {'weight': 1, 'ridge_index': np.int64(1425), 'ridge_depth': np.float64(-0.0014448661950041066), 'ridge_length': 105, 'ridge_depth_bis': 0.04236981272697449}

add geodesic distances attribute to edges

g = ssg.add_geodesic_distances_to_graph(g, mesh, save=False)

add mean value to nodes attributes

g = ssg.add_mean_value_to_graph(g, dpf, name='basin_mean_depth', save=False)

get textures from graph

tex_labels, tex_pits, tex_ridges = ssg.get_textures_from_graph(g, mesh, save=False, outdir=None)

Total running time of the script: (0 minutes 3.274 seconds)

Gallery generated by Sphinx-Gallery