Show code cell content
import matplotlib.pyplot as plt
import numpy as np
import SimpleITK as sitk
from armscan_env.config import get_config
from armscan_env.envs.rewards import anatomy_based_rwd
from armscan_env.util.visualizations import show_slices
config = get_config()
Simple Clustering and Linear Sweep Search#
Loading the dataset:
volume = sitk.ReadImage(config.get_single_labelmap_path(1))
volume_img = sitk.GetArrayFromImage(volume)
print(f"{volume_img.shape=}")
size = np.array(volume.GetSize()) * np.array(volume.GetSpacing())
print(f"{size=} mm")
transversal_extent = (0, size[0], 0, size[2])
longitudinal_extent = (0, size[1], 0, size[2])
frontal_extent = (0, size[0], size[1], 0)
volume_img.shape=(61, 864, 606)
size=array([150.0486095 , 213.93069077, 61. ]) mm
)In this notebook, we are going to explain the process of searching the carpal tunnel along one axis using a simple clustering algorithm. The first step is to visualize the data to understand the anatomy of the hand at the level of the carpal tunnel. We will then use a simple clustering algorithm to identify the number of features present in each image. Based on the number of features and their relative positions, we will be able to identify the carpal tunnel, basing on its anatomical description.
Since we are not changing the orientation of the slices along the hand, we are bound to a sub-optimal visualization along the axis on which the images have been stacked. This is not exactly transversal to the carpal tunnel, so our anatomical description will be relative to this suboptimal orientation. However, we can still demonstrate that the anatomical description of the region of interest is enough to optimize the navigation.
The following images are slices in proximity of the carpal tunnel area.
show_slices(data=volume_img, start=690, end=20, lap=1, extent=transversal_extent)
plt.show()
The values of the labels are going to be used to identify the clusters of tissues and reason about the anatomy seen in the image.
tissues = {
"bones": 1,
"tendons": 2,
"ulnar": 3,
}
The function cluster_iter
is going to be used to identify the clusters of tissues in the image. It iterates over the tissues in the dictionary and identifies the clusters of each tissue. The clustering algorithm uses a center-symmetric filter to identify clusters of neighboring pixels with the same value. The algorithm is based on the label
function from the scipy.ndimage
package. The function returns a dictionary with the clusters of tissues and the center of each of them.
from armscan_env.clustering import cluster_iter
from armscan_env.util.visualizations import show_clusters
clusters_679 = cluster_iter(tissues, volume_img[:, 679, :].T)
fig = show_clusters(clusters_679, volume_img[:, 679, :].T, extent=transversal_extent)
fig.set_xlabel("X [mm]")
fig.set_ylabel("Z [mm]")
plt.show()
Visualizing slices of the hand at different levels, is going to make clear why it is enough to reason about the anatomy of one slice to identify the region of interest.
The function anatomy_based_rwd
calculates the score of each image. This offers an observable reward, which can be used to optimize the navigation problem with classical search methods as well as with RL algorithms. The score is based on the number of clusters recognized for each tissue, which should be equal to the n_landmarks
parameter. If some of the tissues are not present at all, this is more hardly penalized, because it means that the navigation is far off. Moreover, the score takes into account the position of the landmarks: in particular it checks whether the ulnar artery lies underneath the tendons clusters or not. The score is then normalized to sum up to one.
We tuned the score function to our sub-optimal region of interest: it returns a zero loss for the slice showing the described anatomical conformation.
Show code cell source
# Create a figure and a gridspec with two rows and two columns
fig = plt.figure(constrained_layout=True, figsize=(12, 6))
gs = fig.add_gridspec(2, 3)
# Add subplots
ax1 = fig.add_subplot(gs[:, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[0, 2])
ax4 = fig.add_subplot(gs[1, 1])
ax5 = fig.add_subplot(gs[1, 2])
ax1.axhline(y=418, color="red", linestyle="--", label=f"Horizontal Line at Z-index = {418}")
ax1.axhline(y=601, color="red", linestyle="--", label=f"Horizontal Line at Z-index = {601}")
ax1.axhline(y=679, color="red", linestyle="--", label=f"Horizontal Line at Z-index = {679}")
ax1.axhline(y=739, color="red", linestyle="--", label=f"Horizontal Line at Z-index = {739}")
ax1.imshow(volume_img[35, :, :], label="Hand")
ax1.set_xlabel("x: pixels")
ax1.set_ylabel("z: pixels")
ax1.legend()
clusters_418 = cluster_iter(tissues, volume_img[:, 418, :].T)
show_clusters(clusters_418, volume_img[:, 418, :].T, ax2, extent=transversal_extent)
reward_418 = anatomy_based_rwd(clusters_418, n_landmarks=(7, 5, 1))
ax2.text(
0.95,
0.1,
f"Reward: {reward_418:.2f}",
horizontalalignment="right",
verticalalignment="bottom",
transform=ax2.transAxes,
bbox=dict(facecolor="white", alpha=0.5, edgecolor="black", boxstyle="round,pad=1"),
)
ax2.set_title("Slice 418")
ax2.axis("off")
clusters_601 = cluster_iter(tissues, volume_img[:, 601, :].T)
show_clusters(clusters_601, volume_img[:, 601, :].T, ax3, extent=transversal_extent)
reward_601 = anatomy_based_rwd(clusters_601, n_landmarks=(7, 5, 1))
ax3.text(
0.95,
0.1,
f"Reward: {reward_601:.2f}",
horizontalalignment="right",
verticalalignment="bottom",
transform=ax3.transAxes,
bbox=dict(facecolor="white", alpha=0.5, edgecolor="black", boxstyle="round,pad=1"),
)
ax3.set_title("Slice 601")
ax3.axis("off")
show_clusters(clusters_679, volume_img[:, 679, :].T, ax4, extent=transversal_extent)
reward_679 = anatomy_based_rwd(clusters_679, n_landmarks=(7, 5, 1))
ax4.text(
0.95,
0.1,
f"Reward: {reward_679:.2f}",
horizontalalignment="right",
verticalalignment="bottom",
transform=ax4.transAxes,
bbox=dict(facecolor="white", alpha=0.5, edgecolor="black", boxstyle="round,pad=1"),
)
ax4.set_title("Slice 679")
ax4.axis("off")
clusters_739 = cluster_iter(tissues, volume_img[:, 739, :].T)
show_clusters(clusters_739, volume_img[:, 739, :].T, ax5, extent=transversal_extent)
reward_739 = anatomy_based_rwd(clusters_739, n_landmarks=(7, 5, 1))
ax5.text(
0.95,
0.1,
f"Reward: {reward_739:.2f}",
horizontalalignment="right",
verticalalignment="bottom",
transform=ax5.transAxes,
bbox=dict(facecolor="white", alpha=0.5, edgecolor="black", boxstyle="round,pad=1"),
)
ax5.set_title("Slice 739")
ax5.axis("off")
plt.show()
The clustering algorithm does not just give us information about the number of tissues clusters, but also about their position. Hence, it is possible to reason about the orientation of the image and the relation of the tissues to one another.
clusters_679 = cluster_iter(tissues, volume_img[:, 679, :].T)
bones_centers = [cluster.center for _, cluster in enumerate(clusters_679.bones)]
ligament_centers = [cluster.center for _, cluster in enumerate(clusters_679.tendons)]
bones_center = np.mean(bones_centers, axis=0)
print("bones_center: ", bones_center)
ligament_center = np.mean(ligament_centers, axis=0)
print("ligament_center: ", ligament_center)
ulnar_center = clusters_679.ulnar[0].center
print("ulnar_center: ", ulnar_center)
bones_center: [289.53353614 36.76763969]
ligament_center: [312.05577456 30.23236792]
ulnar_center: (268.2307692307692, 22.26923076923077)
anatomy_based_rwd(clusters_679, n_landmarks=(7, 5, 1))
-0.0
Performing a linear sweep search along the axis of the hand, we can identify the optimal region that returns a zero loss. We can also see that the loss converges to zero as we approach the optimal region.
sweep_loss = []
zero_loss_clusters = []
for i in range(volume_img.shape[1]):
clusters = cluster_iter(tissues, volume_img[:, i, :].T)
loss = anatomy_based_rwd(clusters, n_landmarks=(7, 5, 1))
sweep_loss.append(loss)
if loss == 0:
zero_loss_clusters.append(clusters)
print(f"Loss for slice {i}: {sweep_loss[i]}")
Show code cell output
Loss for slice 0: -1.0
Loss for slice 1: -1.0
Loss for slice 2: -1.0
Loss for slice 3: -1.0
Loss for slice 4: -1.0
Loss for slice 5: -1.0
Loss for slice 6: -1.0
Loss for slice 7: -1.0
Loss for slice 8: -1.0
Loss for slice 9: -1.0
Loss for slice 10: -1.0
Loss for slice 11: -1.0
Loss for slice 12: -1.0
Loss for slice 13: -1.0
Loss for slice 14: -1.0
Loss for slice 15: -1.0
Loss for slice 16: -1.0
Loss for slice 17: -1.0
Loss for slice 18: -1.0
Loss for slice 19: -1.0
Loss for slice 20: -1.0
Loss for slice 21: -1.0
Loss for slice 22: -1.0
Loss for slice 23: -1.0
Loss for slice 24: -1.0
Loss for slice 25: -1.0
Loss for slice 26: -1.0
Loss for slice 27: -1.0
Loss for slice 28: -1.0
Loss for slice 29: -1.0
Loss for slice 30: -1.0
Loss for slice 31: -1.0
Loss for slice 32: -1.0
Loss for slice 33: -1.0
Loss for slice 34: -1.0
Loss for slice 35: -1.0
Loss for slice 36: -1.0
Loss for slice 37: -1.0
Loss for slice 38: -1.0
Loss for slice 39: -1.0
Loss for slice 40: -1.0
Loss for slice 41: -1.0
Loss for slice 42: -1.0
Loss for slice 43: -1.0
Loss for slice 44: -1.0
Loss for slice 45: -1.0
Loss for slice 46: -1.0
Loss for slice 47: -1.0
Loss for slice 48: -1.0
Loss for slice 49: -1.0
Loss for slice 50: -1.0
Loss for slice 51: -1.0
Loss for slice 52: -1.0
Loss for slice 53: -1.0
Loss for slice 54: -1.0
Loss for slice 55: -1.0
Loss for slice 56: -1.0
Loss for slice 57: -1.0
Loss for slice 58: -1.0
Loss for slice 59: -1.0
Loss for slice 60: -1.0
Loss for slice 61: -1.0
Loss for slice 62: -1.0
Loss for slice 63: -1.0
Loss for slice 64: -1.0
Loss for slice 65: -1.0
Loss for slice 66: -1.0
Loss for slice 67: -1.0
Loss for slice 68: -1.0
Loss for slice 69: -1.0
Loss for slice 70: -1.0
Loss for slice 71: -1.0
Loss for slice 72: -1.0
Loss for slice 73: -1.0
Loss for slice 74: -1.0
Loss for slice 75: -1.0
Loss for slice 76: -1.0
Loss for slice 77: -1.0
Loss for slice 78: -1.0
Loss for slice 79: -1.0
Loss for slice 80: -1.0
Loss for slice 81: -1.0
Loss for slice 82: -1.0
Loss for slice 83: -1.0
Loss for slice 84: -1.0
Loss for slice 85: -1.0
Loss for slice 86: -1.0
Loss for slice 87: -0.8632478632478633
Loss for slice 88: -0.8632478632478633
Loss for slice 89: -0.8632478632478633
Loss for slice 90: -0.8632478632478633
Loss for slice 91: -0.8632478632478633
Loss for slice 92: -0.8632478632478633
Loss for slice 93: -0.8632478632478633
Loss for slice 94: -0.8632478632478633
Loss for slice 95: -0.8632478632478633
Loss for slice 96: -0.8632478632478633
Loss for slice 97: -0.8632478632478633
Loss for slice 98: -0.8632478632478633
Loss for slice 99: -0.8632478632478633
Loss for slice 100: -0.8632478632478633
Loss for slice 101: -0.8632478632478633
Loss for slice 102: -0.8632478632478633
Loss for slice 103: -0.8632478632478633
Loss for slice 104: -0.8632478632478633
Loss for slice 105: -0.8632478632478633
Loss for slice 106: -0.8632478632478633
Loss for slice 107: -0.8632478632478633
Loss for slice 108: -0.8632478632478633
Loss for slice 109: -0.8632478632478633
Loss for slice 110: -0.8632478632478633
Loss for slice 111: -0.8632478632478633
Loss for slice 112: -0.8632478632478633
Loss for slice 113: -0.8632478632478633
Loss for slice 114: -0.8632478632478633
Loss for slice 115: -0.8632478632478633
Loss for slice 116: -0.8632478632478633
Loss for slice 117: -0.8632478632478633
Loss for slice 118: -0.8632478632478633
Loss for slice 119: -0.8632478632478633
Loss for slice 120: -0.8632478632478633
Loss for slice 121: -0.8632478632478633
Loss for slice 122: -0.8632478632478633
Loss for slice 123: -0.8632478632478633
Loss for slice 124: -0.8632478632478633
Loss for slice 125: -0.8632478632478633
Loss for slice 126: -0.8632478632478633
Loss for slice 127: -0.8632478632478633
Loss for slice 128: -0.8632478632478633
Loss for slice 129: -0.8632478632478633
Loss for slice 130: -0.8632478632478633
Loss for slice 131: -0.8376068376068375
Loss for slice 132: -0.8376068376068375
Loss for slice 133: -0.8376068376068375
Loss for slice 134: -0.8376068376068375
Loss for slice 135: -0.8376068376068375
Loss for slice 136: -0.8376068376068375
Loss for slice 137: -0.8376068376068375
Loss for slice 138: -0.8376068376068375
Loss for slice 139: -0.8376068376068375
Loss for slice 140: -0.8376068376068375
Loss for slice 141: -0.8376068376068375
Loss for slice 142: -0.8376068376068375
Loss for slice 143: -0.8376068376068375
Loss for slice 144: -0.8376068376068375
Loss for slice 145: -0.811965811965812
Loss for slice 146: -0.7863247863247863
Loss for slice 147: -0.7606837606837606
Loss for slice 148: -0.7094017094017093
Loss for slice 149: -0.811965811965812
Loss for slice 150: -0.7863247863247863
Loss for slice 151: -0.811965811965812
Loss for slice 152: -0.811965811965812
Loss for slice 153: -0.811965811965812
Loss for slice 154: -0.811965811965812
Loss for slice 155: -0.811965811965812
Loss for slice 156: -0.811965811965812
Loss for slice 157: -0.811965811965812
Loss for slice 158: -0.811965811965812
Loss for slice 159: -0.811965811965812
Loss for slice 160: -0.811965811965812
Loss for slice 161: -0.811965811965812
Loss for slice 162: -0.811965811965812
Loss for slice 163: -0.811965811965812
Loss for slice 164: -0.811965811965812
Loss for slice 165: -0.811965811965812
Loss for slice 166: -0.811965811965812
Loss for slice 167: -0.811965811965812
Loss for slice 168: -0.811965811965812
Loss for slice 169: -0.811965811965812
Loss for slice 170: -0.811965811965812
Loss for slice 171: -0.811965811965812
Loss for slice 172: -0.7863247863247863
Loss for slice 173: -0.7863247863247863
Loss for slice 174: -0.811965811965812
Loss for slice 175: -0.811965811965812
Loss for slice 176: -0.811965811965812
Loss for slice 177: -0.811965811965812
Loss for slice 178: -0.811965811965812
Loss for slice 179: -0.811965811965812
Loss for slice 180: -0.811965811965812
Loss for slice 181: -0.811965811965812
Loss for slice 182: -0.811965811965812
Loss for slice 183: -0.811965811965812
Loss for slice 184: -0.811965811965812
Loss for slice 185: -0.811965811965812
Loss for slice 186: -0.811965811965812
Loss for slice 187: -0.811965811965812
Loss for slice 188: -0.811965811965812
Loss for slice 189: -0.811965811965812
Loss for slice 190: -0.811965811965812
Loss for slice 191: -0.811965811965812
Loss for slice 192: -0.811965811965812
Loss for slice 193: -0.811965811965812
Loss for slice 194: -0.811965811965812
Loss for slice 195: -0.811965811965812
Loss for slice 196: -0.811965811965812
Loss for slice 197: -0.811965811965812
Loss for slice 198: -0.811965811965812
Loss for slice 199: -0.811965811965812
Loss for slice 200: -0.811965811965812
Loss for slice 201: -0.7606837606837606
Loss for slice 202: -0.7863247863247863
Loss for slice 203: -0.7863247863247863
Loss for slice 204: -0.811965811965812
Loss for slice 205: -0.811965811965812
Loss for slice 206: -0.811965811965812
Loss for slice 207: -0.811965811965812
Loss for slice 208: -0.811965811965812
Loss for slice 209: -0.811965811965812
Loss for slice 210: -0.811965811965812
Loss for slice 211: -0.811965811965812
Loss for slice 212: -0.811965811965812
Loss for slice 213: -0.811965811965812
Loss for slice 214: -0.811965811965812
Loss for slice 215: -0.811965811965812
Loss for slice 216: -0.811965811965812
Loss for slice 217: -0.811965811965812
Loss for slice 218: -0.811965811965812
Loss for slice 219: -0.811965811965812
Loss for slice 220: -0.811965811965812
Loss for slice 221: -0.811965811965812
Loss for slice 222: -0.811965811965812
Loss for slice 223: -0.811965811965812
Loss for slice 224: -0.811965811965812
Loss for slice 225: -0.7863247863247863
Loss for slice 226: -0.7863247863247863
Loss for slice 227: -0.7863247863247863
Loss for slice 228: -0.7863247863247863
Loss for slice 229: -0.7863247863247863
Loss for slice 230: -0.7863247863247863
Loss for slice 231: -0.7863247863247863
Loss for slice 232: -0.7863247863247863
Loss for slice 233: -0.7863247863247863
Loss for slice 234: -0.7863247863247863
Loss for slice 235: -0.7863247863247863
Loss for slice 236: -0.7863247863247863
Loss for slice 237: -0.7863247863247863
Loss for slice 238: -0.7863247863247863
Loss for slice 239: -0.7863247863247863
Loss for slice 240: -0.7863247863247863
Loss for slice 241: -0.7863247863247863
Loss for slice 242: -0.7863247863247863
Loss for slice 243: -0.7094017094017093
Loss for slice 244: -0.7094017094017093
Loss for slice 245: -0.7094017094017093
Loss for slice 246: -0.7094017094017093
Loss for slice 247: -0.7606837606837606
Loss for slice 248: -0.7350427350427351
Loss for slice 249: -0.7350427350427351
Loss for slice 250: -0.7606837606837606
Loss for slice 251: -0.7606837606837606
Loss for slice 252: -0.7606837606837606
Loss for slice 253: -0.7606837606837606
Loss for slice 254: -0.7606837606837606
Loss for slice 255: -0.7606837606837606
Loss for slice 256: -0.7606837606837606
Loss for slice 257: -0.7606837606837606
Loss for slice 258: -0.7606837606837606
Loss for slice 259: -0.7606837606837606
Loss for slice 260: -0.7606837606837606
Loss for slice 261: -0.7350427350427351
Loss for slice 262: -0.7350427350427351
Loss for slice 263: -0.7350427350427351
Loss for slice 264: -0.7350427350427351
Loss for slice 265: -0.7094017094017093
Loss for slice 266: -0.7863247863247863
Loss for slice 267: -0.7606837606837606
Loss for slice 268: -0.7606837606837606
Loss for slice 269: -0.7606837606837606
Loss for slice 270: -0.7863247863247863
Loss for slice 271: -0.7606837606837606
Loss for slice 272: -0.7606837606837606
Loss for slice 273: -0.7606837606837606
Loss for slice 274: -0.7863247863247863
Loss for slice 275: -0.7863247863247863
Loss for slice 276: -0.7863247863247863
Loss for slice 277: -0.7606837606837606
Loss for slice 278: -0.7606837606837606
Loss for slice 279: -0.7606837606837606
Loss for slice 280: -0.7606837606837606
Loss for slice 281: -0.7606837606837606
Loss for slice 282: -0.7606837606837606
Loss for slice 283: -0.7350427350427351
Loss for slice 284: -0.7350427350427351
Loss for slice 285: -0.7606837606837606
Loss for slice 286: -0.7606837606837606
Loss for slice 287: -0.7606837606837606
Loss for slice 288: -0.7606837606837606
Loss for slice 289: -0.7606837606837606
Loss for slice 290: -0.7606837606837606
Loss for slice 291: -0.7606837606837606
Loss for slice 292: -0.7606837606837606
Loss for slice 293: -0.7606837606837606
Loss for slice 294: -0.7606837606837606
Loss for slice 295: -0.7606837606837606
Loss for slice 296: -0.7863247863247863
Loss for slice 297: -0.7863247863247863
Loss for slice 298: -0.7863247863247863
Loss for slice 299: -0.7863247863247863
Loss for slice 300: -0.7863247863247863
Loss for slice 301: -0.7863247863247863
Loss for slice 302: -0.7863247863247863
Loss for slice 303: -0.7863247863247863
Loss for slice 304: -0.7863247863247863
Loss for slice 305: -0.7863247863247863
Loss for slice 306: -0.7863247863247863
Loss for slice 307: -0.7863247863247863
Loss for slice 308: -0.7863247863247863
Loss for slice 309: -0.7863247863247863
Loss for slice 310: -0.7863247863247863
Loss for slice 311: -0.7863247863247863
Loss for slice 312: -0.7863247863247863
Loss for slice 313: -0.7863247863247863
Loss for slice 314: -0.7863247863247863
Loss for slice 315: -0.7863247863247863
Loss for slice 316: -0.7863247863247863
Loss for slice 317: -0.7863247863247863
Loss for slice 318: -0.7863247863247863
Loss for slice 319: -0.7863247863247863
Loss for slice 320: -0.7863247863247863
Loss for slice 321: -0.7863247863247863
Loss for slice 322: -0.7863247863247863
Loss for slice 323: -0.7350427350427351
Loss for slice 324: -0.7606837606837606
Loss for slice 325: -0.7863247863247863
Loss for slice 326: -0.7863247863247863
Loss for slice 327: -0.7863247863247863
Loss for slice 328: -0.7863247863247863
Loss for slice 329: -0.7863247863247863
Loss for slice 330: -0.7606837606837606
Loss for slice 331: -0.7606837606837606
Loss for slice 332: -0.7863247863247863
Loss for slice 333: -0.7863247863247863
Loss for slice 334: -0.7863247863247863
Loss for slice 335: -0.7863247863247863
Loss for slice 336: -0.7863247863247863
Loss for slice 337: -0.7863247863247863
Loss for slice 338: -0.7863247863247863
Loss for slice 339: -0.7863247863247863
Loss for slice 340: -0.7863247863247863
Loss for slice 341: -0.7863247863247863
Loss for slice 342: -0.7863247863247863
Loss for slice 343: -0.7863247863247863
Loss for slice 344: -0.7863247863247863
Loss for slice 345: -0.7863247863247863
Loss for slice 346: -0.7863247863247863
Loss for slice 347: -0.7863247863247863
Loss for slice 348: -0.7863247863247863
Loss for slice 349: -0.7863247863247863
Loss for slice 350: -0.7863247863247863
Loss for slice 351: -0.7863247863247863
Loss for slice 352: -0.7863247863247863
Loss for slice 353: -0.7863247863247863
Loss for slice 354: -0.7863247863247863
Loss for slice 355: -0.7863247863247863
Loss for slice 356: -0.7863247863247863
Loss for slice 357: -0.7863247863247863
Loss for slice 358: -0.7863247863247863
Loss for slice 359: -0.7863247863247863
Loss for slice 360: -0.7863247863247863
Loss for slice 361: -0.7863247863247863
Loss for slice 362: -0.7863247863247863
Loss for slice 363: -0.7863247863247863
Loss for slice 364: -0.7863247863247863
Loss for slice 365: -0.7863247863247863
Loss for slice 366: -0.7863247863247863
Loss for slice 367: -0.7863247863247863
Loss for slice 368: -0.7863247863247863
Loss for slice 369: -0.7863247863247863
Loss for slice 370: -0.7863247863247863
Loss for slice 371: -0.7863247863247863
Loss for slice 372: -0.7863247863247863
Loss for slice 373: -0.7863247863247863
Loss for slice 374: -0.7863247863247863
Loss for slice 375: -0.7863247863247863
Loss for slice 376: -0.7863247863247863
Loss for slice 377: -0.7863247863247863
Loss for slice 378: -0.7606837606837606
Loss for slice 379: -0.7606837606837606
Loss for slice 380: -0.7606837606837606
Loss for slice 381: -0.7606837606837606
Loss for slice 382: -0.7606837606837606
Loss for slice 383: -0.7606837606837606
Loss for slice 384: -0.7863247863247863
Loss for slice 385: -0.7863247863247863
Loss for slice 386: -0.7863247863247863
Loss for slice 387: -0.7863247863247863
Loss for slice 388: -0.7863247863247863
Loss for slice 389: -0.7863247863247863
Loss for slice 390: -0.7863247863247863
Loss for slice 391: -0.7863247863247863
Loss for slice 392: -0.7863247863247863
Loss for slice 393: -0.7863247863247863
Loss for slice 394: -0.7863247863247863
Loss for slice 395: -0.7863247863247863
Loss for slice 396: -0.7863247863247863
Loss for slice 397: -0.7863247863247863
Loss for slice 398: -0.7863247863247863
Loss for slice 399: -0.7863247863247863
Loss for slice 400: -0.7863247863247863
Loss for slice 401: -0.7863247863247863
Loss for slice 402: -0.7863247863247863
Loss for slice 403: -0.7863247863247863
Loss for slice 404: -0.7863247863247863
Loss for slice 405: -0.7606837606837606
Loss for slice 406: -0.7606837606837606
Loss for slice 407: -0.7606837606837606
Loss for slice 408: -0.7606837606837606
Loss for slice 409: -0.7606837606837606
Loss for slice 410: -0.7606837606837606
Loss for slice 411: -0.7094017094017093
Loss for slice 412: -0.7350427350427351
Loss for slice 413: -0.7350427350427351
Loss for slice 414: -0.7350427350427351
Loss for slice 415: -0.7606837606837606
Loss for slice 416: -0.7606837606837606
Loss for slice 417: -0.7606837606837606
Loss for slice 418: -0.7350427350427351
Loss for slice 419: -0.7606837606837606
Loss for slice 420: -0.7606837606837606
Loss for slice 421: -0.7606837606837606
Loss for slice 422: -0.7350427350427351
Loss for slice 423: -0.7350427350427351
Loss for slice 424: -0.7350427350427351
Loss for slice 425: -0.7350427350427351
Loss for slice 426: -0.7350427350427351
Loss for slice 427: -0.7094017094017093
Loss for slice 428: -0.7350427350427351
Loss for slice 429: -0.7094017094017093
Loss for slice 430: -0.7350427350427351
Loss for slice 431: -0.7094017094017093
Loss for slice 432: -0.7350427350427351
Loss for slice 433: -0.7350427350427351
Loss for slice 434: -0.7606837606837606
Loss for slice 435: -0.7606837606837606
Loss for slice 436: -0.7606837606837606
Loss for slice 437: -0.7606837606837606
Loss for slice 438: -0.7606837606837606
Loss for slice 439: -0.7606837606837606
Loss for slice 440: -0.7606837606837606
Loss for slice 441: -0.7606837606837606
Loss for slice 442: -0.7350427350427351
Loss for slice 443: -0.7350427350427351
Loss for slice 444: -0.7606837606837606
Loss for slice 445: -0.7094017094017093
Loss for slice 446: -0.7094017094017093
Loss for slice 447: -0.7094017094017093
Loss for slice 448: -0.7350427350427351
Loss for slice 449: -0.7350427350427351
Loss for slice 450: -0.7350427350427351
Loss for slice 451: -0.7350427350427351
Loss for slice 452: -0.7350427350427351
Loss for slice 453: -0.7606837606837606
Loss for slice 454: -0.7350427350427351
Loss for slice 455: -0.7350427350427351
Loss for slice 456: -0.7350427350427351
Loss for slice 457: -0.7094017094017093
Loss for slice 458: -0.7350427350427351
Loss for slice 459: -0.7350427350427351
Loss for slice 460: -0.7350427350427351
Loss for slice 461: -0.7350427350427351
Loss for slice 462: -0.7350427350427351
Loss for slice 463: -0.7350427350427351
Loss for slice 464: -0.7350427350427351
Loss for slice 465: -0.7606837606837606
Loss for slice 466: -0.7606837606837606
Loss for slice 467: -0.7606837606837606
Loss for slice 468: -0.7606837606837606
Loss for slice 469: -0.6239316239316239
Loss for slice 470: -0.6239316239316239
Loss for slice 471: -0.6239316239316239
Loss for slice 472: -0.5982905982905983
Loss for slice 473: -0.5982905982905983
Loss for slice 474: -0.5982905982905983
Loss for slice 475: -0.5982905982905983
Loss for slice 476: -0.5982905982905983
Loss for slice 477: -0.5982905982905983
Loss for slice 478: -0.5982905982905983
Loss for slice 479: -0.5982905982905983
Loss for slice 480: -0.5982905982905983
Loss for slice 481: -0.5982905982905983
Loss for slice 482: -0.5726495726495726
Loss for slice 483: -0.5726495726495726
Loss for slice 484: -0.5726495726495726
Loss for slice 485: -0.5726495726495726
Loss for slice 486: -0.5726495726495726
Loss for slice 487: -0.5726495726495726
Loss for slice 488: -0.547008547008547
Loss for slice 489: -0.5726495726495726
Loss for slice 490: -0.5726495726495726
Loss for slice 491: -0.5726495726495726
Loss for slice 492: -0.5726495726495726
Loss for slice 493: -0.5726495726495726
Loss for slice 494: -0.5726495726495726
Loss for slice 495: -0.5726495726495726
Loss for slice 496: -0.5726495726495726
Loss for slice 497: -0.5726495726495726
Loss for slice 498: -0.547008547008547
Loss for slice 499: -0.547008547008547
Loss for slice 500: -0.547008547008547
Loss for slice 501: -0.547008547008547
Loss for slice 502: -0.547008547008547
Loss for slice 503: -0.547008547008547
Loss for slice 504: -0.547008547008547
Loss for slice 505: -0.547008547008547
Loss for slice 506: -0.547008547008547
Loss for slice 507: -0.5213675213675213
Loss for slice 508: -0.547008547008547
Loss for slice 509: -0.547008547008547
Loss for slice 510: -0.547008547008547
Loss for slice 511: -0.547008547008547
Loss for slice 512: -0.547008547008547
Loss for slice 513: -0.547008547008547
Loss for slice 514: -0.547008547008547
Loss for slice 515: -0.547008547008547
Loss for slice 516: -0.547008547008547
Loss for slice 517: -0.547008547008547
Loss for slice 518: -0.5213675213675213
Loss for slice 519: -0.49572649572649574
Loss for slice 520: -0.49572649572649574
Loss for slice 521: -0.49572649572649574
Loss for slice 522: -0.49572649572649574
Loss for slice 523: -0.49572649572649574
Loss for slice 524: -0.49572649572649574
Loss for slice 525: -0.5213675213675213
Loss for slice 526: -0.5213675213675213
Loss for slice 527: -0.5213675213675213
Loss for slice 528: -0.5213675213675213
Loss for slice 529: -0.5213675213675213
Loss for slice 530: -0.547008547008547
Loss for slice 531: -0.547008547008547
Loss for slice 532: -0.547008547008547
Loss for slice 533: -0.547008547008547
Loss for slice 534: -0.547008547008547
Loss for slice 535: -0.547008547008547
Loss for slice 536: -0.547008547008547
Loss for slice 537: -0.547008547008547
Loss for slice 538: -0.547008547008547
Loss for slice 539: -0.5726495726495726
Loss for slice 540: -0.5726495726495726
Loss for slice 541: -0.5726495726495726
Loss for slice 542: -0.5726495726495726
Loss for slice 543: -0.547008547008547
Loss for slice 544: -0.547008547008547
Loss for slice 545: -0.547008547008547
Loss for slice 546: -0.547008547008547
Loss for slice 547: -0.547008547008547
Loss for slice 548: -0.547008547008547
Loss for slice 549: -0.5213675213675213
Loss for slice 550: -0.5213675213675213
Loss for slice 551: -0.5213675213675213
Loss for slice 552: -0.5213675213675213
Loss for slice 553: -0.5213675213675213
Loss for slice 554: -0.5213675213675213
Loss for slice 555: -0.05128205128205128
Loss for slice 556: -0.05128205128205128
Loss for slice 557: -0.02564102564102564
Loss for slice 558: -0.05128205128205128
Loss for slice 559: -0.05128205128205128
Loss for slice 560: -0.10256410256410256
Loss for slice 561: -0.05128205128205128
Loss for slice 562: -0.02564102564102564
Loss for slice 563: -0.02564102564102564
Loss for slice 564: -0.05128205128205128
Loss for slice 565: -0.05128205128205128
Loss for slice 566: -0.07692307692307693
Loss for slice 567: -0.07692307692307693
Loss for slice 568: -0.07692307692307693
Loss for slice 569: -0.07692307692307693
Loss for slice 570: -0.07692307692307693
Loss for slice 571: -0.07692307692307693
Loss for slice 572: -0.07692307692307693
Loss for slice 573: -0.07692307692307693
Loss for slice 574: -0.07692307692307693
Loss for slice 575: -0.05128205128205128
Loss for slice 576: -0.05128205128205128
Loss for slice 577: -0.07692307692307693
Loss for slice 578: -0.07692307692307693
Loss for slice 579: -0.07692307692307693
Loss for slice 580: -0.07692307692307693
Loss for slice 581: -0.07692307692307693
Loss for slice 582: -0.05128205128205128
Loss for slice 583: -0.05128205128205128
Loss for slice 584: -0.05128205128205128
Loss for slice 585: -0.07692307692307693
Loss for slice 586: -0.07692307692307693
Loss for slice 587: -0.07692307692307693
Loss for slice 588: -0.05128205128205128
Loss for slice 589: -0.07692307692307693
Loss for slice 590: -0.4358974358974359
Loss for slice 591: -0.4358974358974359
Loss for slice 592: -0.07692307692307693
Loss for slice 593: -0.07692307692307693
Loss for slice 594: -0.07692307692307693
Loss for slice 595: -0.07692307692307693
Loss for slice 596: -0.07692307692307693
Loss for slice 597: -0.07692307692307693
Loss for slice 598: -0.07692307692307693
Loss for slice 599: -0.07692307692307693
Loss for slice 600: -0.07692307692307693
Loss for slice 601: -0.10256410256410256
Loss for slice 602: -0.10256410256410256
Loss for slice 603: -0.10256410256410256
Loss for slice 604: -0.10256410256410256
Loss for slice 605: -0.1282051282051282
Loss for slice 606: -0.1282051282051282
Loss for slice 607: -0.1282051282051282
Loss for slice 608: -0.1282051282051282
Loss for slice 609: -0.1282051282051282
Loss for slice 610: -0.1282051282051282
Loss for slice 611: -0.1282051282051282
Loss for slice 612: -0.15384615384615385
Loss for slice 613: -0.1282051282051282
Loss for slice 614: -0.1282051282051282
Loss for slice 615: -0.1282051282051282
Loss for slice 616: -0.1282051282051282
Loss for slice 617: -0.15384615384615385
Loss for slice 618: -0.10256410256410256
Loss for slice 619: -0.1282051282051282
Loss for slice 620: -0.07692307692307693
Loss for slice 621: -0.07692307692307693
Loss for slice 622: -0.10256410256410256
Loss for slice 623: -0.07692307692307693
Loss for slice 624: -0.1282051282051282
Loss for slice 625: -0.1282051282051282
Loss for slice 626: -0.1282051282051282
Loss for slice 627: -0.1282051282051282
Loss for slice 628: -0.1282051282051282
Loss for slice 629: -0.10256410256410256
Loss for slice 630: -0.1282051282051282
Loss for slice 631: -0.10256410256410256
Loss for slice 632: -0.15384615384615385
Loss for slice 633: -0.1282051282051282
Loss for slice 634: -0.1282051282051282
Loss for slice 635: -0.1282051282051282
Loss for slice 636: -0.15384615384615385
Loss for slice 637: -0.1282051282051282
Loss for slice 638: -0.1282051282051282
Loss for slice 639: -0.1282051282051282
Loss for slice 640: -0.1282051282051282
Loss for slice 641: -0.10256410256410256
Loss for slice 642: -0.10256410256410256
Loss for slice 643: -0.1282051282051282
Loss for slice 644: -0.10256410256410256
Loss for slice 645: -0.07692307692307693
Loss for slice 646: -0.10256410256410256
Loss for slice 647: -0.10256410256410256
Loss for slice 648: -0.10256410256410256
Loss for slice 649: -0.10256410256410256
Loss for slice 650: -0.1282051282051282
Loss for slice 651: -0.10256410256410256
Loss for slice 652: -0.10256410256410256
Loss for slice 653: -0.07692307692307693
Loss for slice 654: -0.10256410256410256
Loss for slice 655: -0.10256410256410256
Loss for slice 656: -0.15384615384615385
Loss for slice 657: -0.10256410256410256
Loss for slice 658: -0.15384615384615385
Loss for slice 659: -0.17948717948717952
Loss for slice 660: -0.1282051282051282
Loss for slice 661: -0.07692307692307693
Loss for slice 662: -0.05128205128205128
Loss for slice 663: -0.07692307692307693
Loss for slice 664: -0.05128205128205128
Loss for slice 665: -0.02564102564102564
Loss for slice 666: -0.05128205128205128
Loss for slice 667: -0.0
Loss for slice 668: -0.02564102564102564
Loss for slice 669: -0.02564102564102564
Loss for slice 670: -0.02564102564102564
Loss for slice 671: -0.02564102564102564
Loss for slice 672: -0.02564102564102564
Loss for slice 673: -0.02564102564102564
Loss for slice 674: -0.0
Loss for slice 675: -0.02564102564102564
Loss for slice 676: -0.02564102564102564
Loss for slice 677: -0.02564102564102564
Loss for slice 678: -0.02564102564102564
Loss for slice 679: -0.0
Loss for slice 680: -0.3846153846153846
Loss for slice 681: -0.3589743589743589
Loss for slice 682: -0.0
Loss for slice 683: -0.02564102564102564
Loss for slice 684: -0.02564102564102564
Loss for slice 685: -0.02564102564102564
Loss for slice 686: -0.05128205128205128
Loss for slice 687: -0.02564102564102564
Loss for slice 688: -0.10256410256410256
Loss for slice 689: -0.07692307692307693
Loss for slice 690: -0.02564102564102564
Loss for slice 691: -0.07692307692307693
Loss for slice 692: -0.10256410256410256
Loss for slice 693: -0.07692307692307693
Loss for slice 694: -0.07692307692307693
Loss for slice 695: -0.07692307692307693
Loss for slice 696: -0.10256410256410256
Loss for slice 697: -0.07692307692307693
Loss for slice 698: -0.10256410256410256
Loss for slice 699: -0.10256410256410256
Loss for slice 700: -0.10256410256410256
Loss for slice 701: -0.07692307692307693
Loss for slice 702: -0.05128205128205128
Loss for slice 703: -0.02564102564102564
Loss for slice 704: -0.07692307692307693
Loss for slice 705: -0.10256410256410256
Loss for slice 706: -0.07692307692307693
Loss for slice 707: -0.41025641025641024
Loss for slice 708: -0.15384615384615385
Loss for slice 709: -0.10256410256410256
Loss for slice 710: -0.1282051282051282
Loss for slice 711: -0.4615384615384615
Loss for slice 712: -0.05128205128205128
Loss for slice 713: -0.05128205128205128
Loss for slice 714: -0.4358974358974359
Loss for slice 715: -0.5128205128205128
Loss for slice 716: -0.6153846153846154
Loss for slice 717: -0.10256410256410256
Loss for slice 718: -0.07692307692307693
Loss for slice 719: -0.07692307692307693
Loss for slice 720: -0.10256410256410256
Loss for slice 721: -0.4871794871794872
Loss for slice 722: -0.4871794871794872
Loss for slice 723: -0.10256410256410256
Loss for slice 724: -0.5641025641025641
Loss for slice 725: -0.5384615384615384
Loss for slice 726: -0.5897435897435896
Loss for slice 727: -0.5384615384615384
Loss for slice 728: -0.17948717948717952
Loss for slice 729: -0.15384615384615385
Loss for slice 730: -0.17948717948717952
Loss for slice 731: -0.5384615384615384
Loss for slice 732: -0.5384615384615384
Loss for slice 733: -0.5641025641025641
Loss for slice 734: -0.5897435897435896
Loss for slice 735: -0.10256410256410256
Loss for slice 736: -0.1282051282051282
Loss for slice 737: -0.17948717948717952
Loss for slice 738: -0.1282051282051282
Loss for slice 739: -0.1282051282051282
Loss for slice 740: -0.1282051282051282
Loss for slice 741: -0.1282051282051282
Loss for slice 742: -0.15384615384615385
Loss for slice 743: -0.1282051282051282
Loss for slice 744: -0.5128205128205128
Loss for slice 745: -0.4615384615384615
Loss for slice 746: -0.4871794871794872
Loss for slice 747: -0.1282051282051282
Loss for slice 748: -0.5128205128205128
Loss for slice 749: -0.1282051282051282
Loss for slice 750: -0.10256410256410256
Loss for slice 751: -0.1282051282051282
Loss for slice 752: -0.07692307692307693
Loss for slice 753: -0.15384615384615385
Loss for slice 754: -0.15384615384615385
Loss for slice 755: -0.07692307692307693
Loss for slice 756: -0.1282051282051282
Loss for slice 757: -0.10256410256410256
Loss for slice 758: -0.15384615384615385
Loss for slice 759: -0.15384615384615385
Loss for slice 760: -0.17948717948717952
Loss for slice 761: -0.15384615384615385
Loss for slice 762: -0.17948717948717952
Loss for slice 763: -0.15384615384615385
Loss for slice 764: -0.17948717948717952
Loss for slice 765: -0.17948717948717952
Loss for slice 766: -0.1282051282051282
Loss for slice 767: -0.1282051282051282
Loss for slice 768: -0.1282051282051282
Loss for slice 769: -0.15384615384615385
Loss for slice 770: -0.15384615384615385
Loss for slice 771: -0.17948717948717952
Loss for slice 772: -0.15384615384615385
Loss for slice 773: -0.20512820512820512
Loss for slice 774: -0.15384615384615385
Loss for slice 775: -0.1282051282051282
Loss for slice 776: -0.1282051282051282
Loss for slice 777: -0.15384615384615385
Loss for slice 778: -0.1282051282051282
Loss for slice 779: -0.15384615384615385
Loss for slice 780: -0.17948717948717952
Loss for slice 781: -0.17948717948717952
Loss for slice 782: -0.15384615384615385
Loss for slice 783: -0.15384615384615385
Loss for slice 784: -0.1282051282051282
Loss for slice 785: -0.1282051282051282
Loss for slice 786: -0.5384615384615384
Loss for slice 787: -0.4871794871794872
Loss for slice 788: -0.1282051282051282
Loss for slice 789: -0.4871794871794872
Loss for slice 790: -0.15384615384615385
Loss for slice 791: -0.5128205128205128
Loss for slice 792: -0.5641025641025641
Loss for slice 793: -0.17948717948717952
Loss for slice 794: -0.15384615384615385
Loss for slice 795: -0.15384615384615385
Loss for slice 796: -0.15384615384615385
Loss for slice 797: -0.15384615384615385
Loss for slice 798: -0.1282051282051282
Loss for slice 799: -0.1282051282051282
Loss for slice 800: -0.15384615384615385
Loss for slice 801: -0.17948717948717952
Loss for slice 802: -0.15384615384615385
Loss for slice 803: -0.1282051282051282
Loss for slice 804: -0.1282051282051282
Loss for slice 805: -0.17948717948717952
Loss for slice 806: -0.15384615384615385
Loss for slice 807: -0.15384615384615385
Loss for slice 808: -0.15384615384615385
Loss for slice 809: -0.17948717948717952
Loss for slice 810: -0.15384615384615385
Loss for slice 811: -0.17948717948717952
Loss for slice 812: -0.17948717948717952
Loss for slice 813: -0.17948717948717952
Loss for slice 814: -0.20512820512820512
Loss for slice 815: -0.17948717948717952
Loss for slice 816: -0.17948717948717952
Loss for slice 817: -0.1282051282051282
Loss for slice 818: -0.15384615384615385
Loss for slice 819: -0.1282051282051282
Loss for slice 820: -0.1282051282051282
Loss for slice 821: -0.1282051282051282
Loss for slice 822: -0.1282051282051282
Loss for slice 823: -0.15384615384615385
Loss for slice 824: -0.15384615384615385
Loss for slice 825: -0.15384615384615385
Loss for slice 826: -0.15384615384615385
Loss for slice 827: -0.15384615384615385
Loss for slice 828: -0.15384615384615385
Loss for slice 829: -0.1282051282051282
Loss for slice 830: -0.10256410256410256
Loss for slice 831: -0.1282051282051282
Loss for slice 832: -0.1282051282051282
Loss for slice 833: -0.1282051282051282
Loss for slice 834: -0.15384615384615385
Loss for slice 835: -0.15384615384615385
Loss for slice 836: -0.1282051282051282
Loss for slice 837: -0.15384615384615385
Loss for slice 838: -0.15384615384615385
Loss for slice 839: -0.1282051282051282
Loss for slice 840: -0.1282051282051282
Loss for slice 841: -0.1282051282051282
Loss for slice 842: -0.1282051282051282
Loss for slice 843: -0.15384615384615385
Loss for slice 844: -0.17948717948717952
Loss for slice 845: -0.20512820512820512
Loss for slice 846: -0.17948717948717952
Loss for slice 847: -0.17948717948717952
Loss for slice 848: -0.17948717948717952
Loss for slice 849: -0.15384615384615385
Loss for slice 850: -0.15384615384615385
Loss for slice 851: -0.15384615384615385
Loss for slice 852: -0.15384615384615385
Loss for slice 853: -0.5128205128205128
Loss for slice 854: -0.5128205128205128
Loss for slice 855: -0.15384615384615385
Loss for slice 856: -0.15384615384615385
Loss for slice 857: -0.15384615384615385
Loss for slice 858: -0.15384615384615385
Loss for slice 859: -0.20512820512820512
Loss for slice 860: -0.15384615384615385
Loss for slice 861: -0.15384615384615385
Loss for slice 862: -0.15384615384615385
Loss for slice 863: -0.15384615384615385
Show code cell source
plt.plot(range(len(sweep_loss)), sweep_loss, marker="o")
plt.xlabel("Slice index")
plt.ylabel("Score")
plt.title("Score along axial slices")
plt.show()
We can visualize the slices that return a zero loss to check whether this approach is valid.
zero_loss_indices = np.where(np.array(sweep_loss) == 0)[0]
print(f"{len(zero_loss_indices)} indices return a zero loss: ", zero_loss_indices)
nrows = 1
ncols = len(zero_loss_indices) // nrows
indices_to_display = nrows * ncols
if indices_to_display > 0:
fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(20, 10))
axes = axes.flatten()
for i, idx in enumerate(zero_loss_indices[:indices_to_display]):
axes[i] = show_clusters(
tissue_clusters=zero_loss_clusters[i],
slice=volume_img[:, idx, :].T,
extent=transversal_extent,
aspect=2,
ax=axes[i],
)
axes[i].set_title(f"Index: {idx}, Loss: {sweep_loss[idx]:.2f}")
axes[i].axis("off")
plt.show()
4 indices return a zero loss: [667 674 679 682]
As we can see, the results are quite promising, but the clustering algorithm is not really identifying the clusters robustly. There are some clusters that are not separated because they have connected pixels. Moreover, it is not possible to tune the clustering algorithm for an expected size, preventing outliers to be detected.
clusters_668 = cluster_iter(tissues, volume_img[:, 668, :].T)
show_clusters(clusters_668, volume_img[:, 668, :].T, extent=transversal_extent, aspect=2)
plt.axis("off")
plt.show()
In the next notebook, we will show the performance using a different clustering algorithm.