Note
Go to the end to download the full example code.
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)