OSCR

AmygdalaGo-BOLT for boundary-aware segmentation of the human amygdala.

Code ↔ Paper

2 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 2 matches
  1. [1] § STAR★Methods › Method details › Model architecture › Multi-granularity adaptive collaboration ↔ H3/AmygdalaGo-BOLT/model/dim2/swin_unet.py, lines 935–1047 · score 0.62 · transformation layer, layer normalization, expanded, query, depth, bias
  2. [2] § STAR★Methods › Method details › Model architecture › Multi-granularity adaptive collaboration ↔ H3/AmygdalaGo-BOLT/model/dim3/utnetv2_utils.py, lines 12–77 · score 0.54 · semantic map, feature map, SoftMax, fusion, module, amygdala

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 1,688 lines · 36 KB · GPL-2.0 · 1 match

  1. # code is borrowed from the original repo and fit into our training framework
  2. # https://github.com/HuCaoFighting/Swin-Unet/tree/4375a8d6fa7d9c38184c5d3194db990a00a3e912
  3. from __future__ import absolute_import
  4. from __future__ import division
  5. from __future__ import print_function
  6. import torch
  7. import torch.nn as nn
  8. import torch.utils.checkpoint as checkpoint
  9. from einops import rearrange
  10. from timm.models.layers import DropPath, to_2tuple, trunc_normal_
  11. import copy
  12. import logging
  13. import math
  14. from os.path import join as pjoin
  15. import numpy as np
  16. from torch.nn import CrossEntropyLoss, Dropout, Softmax, Linear, Conv2d, LayerNorm
  17. from torch.nn.modules.utils import _pair
  18. from scipy import ndimage
  19. class Mlp(nn.Module):
  20. def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):
  21. super().__init__()
  22. out_features = out_features or in_features
  23. hidden_features = hidden_features or in_features
  24. self.fc1 = nn.Linear(in_features, hidden_features)
  25. self.act = act_layer()
  26. self.fc2 = nn.Linear(hidden_features, out_features)
  27. self.drop = nn.Dropout(drop)
  28. def forward(self, x):
  29. x = self.fc1(x)
  30. x = self.act(x)
  31. x = self.drop(x)
  32. x = self.fc2(x)
  33. x = self.drop(x)
  34. return x
  35. def window_partition(x, window_size):
  36. """
  37. Args:
  38. x: (B, H, W, C)
  39. window_size (int): window size
  40. Returns:
  41. windows: (num_windows*B, window_size, window_size, C)
  42. """
  43. B, H, W, C = x.shape
  44. x = x.view(B, H // window_size, window_size, W // window_size, window_size, C)
  45. windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C)
  46. return windows
  47. def window_reverse(windows, window_size, H, W):
  48. """
  49. Args:
  50. windows: (num_windows*B, window_size, window_size, C)
  51. window_size (int): Window size
  52. H (int): Height of image
  53. W (int): Width of image
  54. Returns:
  55. x: (B, H, W, C)
  56. """
  57. B = int(windows.shape[0] / (H * W / window_size / window_size))
  58. x = windows.view(B, H // window_size, W // window_size, window_size, window_size, -1)
  59. x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)
  60. return x
  61. class WindowAttention(nn.Module):
  62. r""" Window based multi-head self attention (W-MSA) module with relative position bias.
  63. It supports both of shifted and non-shifted window.
  64. Args:
  65. dim (int): Number of input channels.
  66. window_size (tuple[int]): The height and width of the window.
  67. num_heads (int): Number of attention heads.
  68. qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
  69. qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set
  70. attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0
  71. proj_drop (float, optional): Dropout ratio of output. Default: 0.0
  72. """
  73. def __init__(self, dim, window_size, num_heads, qkv_bias=True, qk_scale=None, attn_drop=0., proj_drop=0.):
  74. super().__init__()
  75. self.dim = dim
  76. self.window_size = window_size # Wh, Ww
  77. self.num_heads = num_heads
  78. head_dim = dim // num_heads
  79. self.scale = qk_scale or head_dim ** -0.5
  80. # define a parameter table of relative position bias
  81. self.relative_position_bias_table = nn.Parameter(
  82. torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads)) # 2*Wh-1 * 2*Ww-1, nH
  83. # get pair-wise relative position index for each token inside the window
  84. coords_h = torch.arange(self.window_size[0])
  85. coords_w = torch.arange(self.window_size[1])
  86. coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww
  87. coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww
  88. relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww
  89. relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2
  90. relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0
  91. relative_coords[:, :, 1] += self.window_size[1] - 1
  92. relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1
  93. relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww
  94. self.register_buffer("relative_position_index", relative_position_index)
  95. self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
  96. self.attn_drop = nn.Dropout(attn_drop)
  97. self.proj = nn.Linear(dim, dim)
  98. self.proj_drop = nn.Dropout(proj_drop)
  99. trunc_normal_(self.relative_position_bias_table, std=.02)
  100. self.softmax = nn.Softmax(dim=-1)
  101. def forward(self, x, mask=None):
  102. """
  103. Args:
  104. x: input features with shape of (num_windows*B, N, C)
  105. mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None
  106. """
  107. B_, N, C = x.shape
  108. qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
  109. q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)
  110. q = q * self.scale
  111. attn = (q @ k.transpose(-2, -1))
  112. relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view(
  113. self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH
  114. relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww
  115. attn = attn + relative_position_bias.unsqueeze(0)
  116. if mask is not None:
  117. nW = mask.shape[0]
  118. attn = attn.view(B_ // nW, nW, self.num_heads, N, N) + mask.unsqueeze(1).unsqueeze(0)
  119. attn = attn.view(-1, self.num_heads, N, N)
  120. attn = self.softmax(attn)
  121. else:
  122. attn = self.softmax(attn)
  123. attn = self.attn_drop(attn)
  124. x = (attn @ v).transpose(1, 2).reshape(B_, N, C)
  125. x = self.proj(x)
  126. x = self.proj_drop(x)
  127. return x
  128. def extra_repr(self) -> str:
  129. return f'dim={self.dim}, window_size={self.window_size}, num_heads={self.num_heads}'
  130. def flops(self, N):
  131. # calculate flops for 1 window with token length of N
  132. flops = 0
  133. # qkv = self.qkv(x)
  134. flops += N * self.dim * 3 * self.dim
  135. # attn = (q @ k.transpose(-2, -1))
  136. flops += self.num_heads * N * (self.dim // self.num_heads) * N
  137. # x = (attn @ v)
  138. flops += self.num_heads * N * N * (self.dim // self.num_heads)
  139. # x = self.proj(x)
  140. flops += N * self.dim * self.dim
  141. return flops
  142. class SwinTransformerBlock(nn.Module):
  143. r""" Swin Transformer Block.
  144. Args:
  145. dim (int): Number of input channels.
  146. input_resolution (tuple[int]): Input resulotion.
  147. num_heads (int): Number of attention heads.
  148. window_size (int): Window size.
  149. shift_size (int): Shift size for SW-MSA.
  150. mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
  151. qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
  152. qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
  153. drop (float, optional): Dropout rate. Default: 0.0
  154. attn_drop (float, optional): Attention dropout rate. Default: 0.0
  155. drop_path (float, optional): Stochastic depth rate. Default: 0.0
  156. act_layer (nn.Module, optional): Activation layer. Default: nn.GELU
  157. norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
  158. """
  159. def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0,
  160. mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., drop_path=0.,
  161. act_layer=nn.GELU, norm_layer=nn.LayerNorm):
  162. super().__init__()
  163. self.dim = dim
  164. self.input_resolution = input_resolution
  165. self.num_heads = num_heads
  166. self.window_size = window_size
  167. self.shift_size = shift_size
  168. self.mlp_ratio = mlp_ratio
  169. if min(self.input_resolution) <= self.window_size:
  170. # if window size is larger than input resolution, we don't partition windows
  171. self.shift_size = 0
  172. self.window_size = min(self.input_resolution)
  173. assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size"
  174. self.norm1 = norm_layer(dim)
  175. self.attn = WindowAttention(
  176. dim, window_size=to_2tuple(self.window_size), num_heads=num_heads,
  177. qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
  178. self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
  179. self.norm2 = norm_layer(dim)
  180. mlp_hidden_dim = int(dim * mlp_ratio)
  181. self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
  182. if self.shift_size > 0:
  183. # calculate attention mask for SW-MSA
  184. H, W = self.input_resolution
  185. img_mask = torch.zeros((1, H, W, 1)) # 1 H W 1
  186. h_slices = (slice(0, -self.window_size),
  187. slice(-self.window_size, -self.shift_size),
  188. slice(-self.shift_size, None))
  189. w_slices = (slice(0, -self.window_size),
  190. slice(-self.window_size, -self.shift_size),
  191. slice(-self.shift_size, None))
  192. cnt = 0
  193. for h in h_slices:
  194. for w in w_slices:
  195. img_mask[:, h, w, :] = cnt
  196. cnt += 1
  197. mask_windows = window_partition(img_mask, self.window_size) # nW, window_size, window_size, 1
  198. mask_windows = mask_windows.view(-1, self.window_size * self.window_size)
  199. attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)
  200. attn_mask = attn_mask.masked_fill(attn_mask != 0, float(-100.0)).masked_fill(attn_mask == 0, float(0.0))
  201. else:
  202. attn_mask = None
  203. self.register_buffer("attn_mask", attn_mask)
  204. def forward(self, x):
  205. H, W = self.input_resolution
  206. B, L, C = x.shape
  207. assert L == H * W, "input feature has wrong size"
  208. shortcut = x
  209. x = self.norm1(x)
  210. x = x.view(B, H, W, C)
  211. # cyclic shift
  212. if self.shift_size > 0:
  213. shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2))
  214. else:
  215. shifted_x = x
  216. # partition windows
  217. x_windows = window_partition(shifted_x, self.window_size) # nW*B, window_size, window_size, C
  218. x_windows = x_windows.view(-1, self.window_size * self.window_size, C) # nW*B, window_size*window_size, C
  219. # W-MSA/SW-MSA
  220. attn_windows = self.attn(x_windows, mask=self.attn_mask) # nW*B, window_size*window_size, C
  221. # merge windows
  222. attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C)
  223. shifted_x = window_reverse(attn_windows, self.window_size, H, W) # B H' W' C
  224. # reverse cyclic shift
  225. if self.shift_size > 0:
  226. x = torch.roll(shifted_x, shifts=(self.shift_size, self.shift_size), dims=(1, 2))
  227. else:
  228. x = shifted_x
  229. x = x.view(B, H * W, C)
  230. # FFN
  231. x = shortcut + self.drop_path(x)
  232. x = x + self.drop_path(self.mlp(self.norm2(x)))
  233. return x
  234. def extra_repr(self) -> str:
  235. return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \
  236. f"window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}"
  237. def flops(self):
  238. flops = 0
  239. H, W = self.input_resolution
  240. # norm1
  241. flops += self.dim * H * W
  242. # W-MSA/SW-MSA
  243. nW = H * W / self.window_size / self.window_size
  244. flops += nW * self.attn.flops(self.window_size * self.window_size)
  245. # mlp
  246. flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio
  247. # norm2
  248. flops += self.dim * H * W
  249. return flops
  250. class PatchMerging(nn.Module):
  251. r""" Patch Merging Layer.
  252. Args:
  253. input_resolution (tuple[int]): Resolution of input feature.
  254. dim (int): Number of input channels.
  255. norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
  256. """
  257. def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm):
  258. super().__init__()
  259. self.input_resolution = input_resolution
  260. self.dim = dim
  261. self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)
  262. self.norm = norm_layer(4 * dim)
  263. def forward(self, x):
  264. """
  265. x: B, H*W, C
  266. """
  267. H, W = self.input_resolution
  268. B, L, C = x.shape
  269. assert L == H * W, "input feature has wrong size"
  270. assert H % 2 == 0 and W % 2 == 0, f"x size ({H}*{W}) are not even."
  271. x = x.view(B, H, W, C)
  272. x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C
  273. x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C
  274. x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C
  275. x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C
  276. x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C
  277. x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C
  278. x = self.norm(x)
  279. x = self.reduction(x)
  280. return x
  281. def extra_repr(self) -> str:
  282. return f"input_resolution={self.input_resolution}, dim={self.dim}"
  283. def flops(self):
  284. H, W = self.input_resolution
  285. flops = H * W * self.dim
  286. flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim
  287. return flops
  288. class PatchExpand(nn.Module):
  289. def __init__(self, input_resolution, dim, dim_scale=2, norm_layer=nn.LayerNorm):
  290. super().__init__()
  291. self.input_resolution = input_resolution
  292. self.dim = dim
  293. self.expand = nn.Linear(dim, 2*dim, bias=False) if dim_scale==2 else nn.Identity()
  294. self.norm = norm_layer(dim // dim_scale)
  295. def forward(self, x):
  296. """
  297. x: B, H*W, C
  298. """
  299. H, W = self.input_resolution
  300. x = self.expand(x)
  301. B, L, C = x.shape
  302. assert L == H * W, "input feature has wrong size"
  303. x = x.view(B, H, W, C)
  304. x = rearrange(x, 'b h w (p1 p2 c)-> b (h p1) (w p2) c', p1=2, p2=2, c=C//4)
  305. x = x.view(B,-1,C//4)
  306. x= self.norm(x)
  307. return x
  308. class FinalPatchExpand_X4(nn.Module):
  309. def __init__(self, input_resolution, dim, dim_scale=4, norm_layer=nn.LayerNorm):
  310. super().__init__()
  311. self.input_resolution = input_resolution
  312. self.dim = dim
  313. self.dim_scale = dim_scale
  314. self.expand = nn.Linear(dim, 16*dim, bias=False)
  315. self.output_dim = dim
  316. self.norm = norm_layer(self.output_dim)
  317. def forward(self, x):
  318. """
  319. x: B, H*W, C
  320. """
  321. H, W = self.input_resolution
  322. x = self.expand(x)
  323. B, L, C = x.shape
  324. assert L == H * W, "input feature has wrong size"
  325. x = x.view(B, H, W, C)
  326. x = rearrange(x, 'b h w (p1 p2 c)-> b (h p1) (w p2) c', p1=self.dim_scale, p2=self.dim_scale, c=C//(self.dim_scale**2))
  327. x = x.view(B,-1,self.output_dim)
  328. x= self.norm(x)
  329. return x
  330. class BasicLayer(nn.Module):
  331. """ A basic Swin Transformer layer for one stage.
  332. Args:
  333. dim (int): Number of input channels.
  334. input_resolution (tuple[int]): Input resolution.
  335. depth (int): Number of blocks.
  336. num_heads (int): Number of attention heads.
  337. window_size (int): Local window size.
  338. mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
  339. qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
  340. qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
  341. drop (float, optional): Dropout rate. Default: 0.0
  342. attn_drop (float, optional): Attention dropout rate. Default: 0.0
  343. drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0
  344. norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
  345. downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None
  346. use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False.
  347. """
  348. def __init__(self, dim, input_resolution, depth, num_heads, window_size,
  349. mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0.,
  350. drop_path=0., norm_layer=nn.LayerNorm, downsample=None, use_checkpoint=False):
  351. super().__init__()
  352. self.dim = dim
  353. self.input_resolution = input_resolution
  354. self.depth = depth
  355. self.use_checkpoint = use_checkpoint
  356. # build blocks
  357. self.blocks = nn.ModuleList([
  358. SwinTransformerBlock(dim=dim, input_resolution=input_resolution,
  359. num_heads=num_heads, window_size=window_size,
  360. shift_size=0 if (i % 2 == 0) else window_size // 2,
  361. mlp_ratio=mlp_ratio,
  362. qkv_bias=qkv_bias, qk_scale=qk_scale,
  363. drop=drop, attn_drop=attn_drop,
  364. drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path,
  365. norm_layer=norm_layer)
  366. for i in range(depth)])
  367. # patch merging layer
  368. if downsample is not None:
  369. self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer)
  370. else:
  371. self.downsample = None
  372. def forward(self, x):
  373. for blk in self.blocks:
  374. if self.use_checkpoint:
  375. x = checkpoint.checkpoint(blk, x)
  376. else:
  377. x = blk(x)
  378. if self.downsample is not None:
  379. x = self.downsample(x)
  380. return x
  381. def extra_repr(self) -> str:
  382. return f"dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}"
  383. def flops(self):
  384. flops = 0
  385. for blk in self.blocks:
  386. flops += blk.flops()
  387. if self.downsample is not None:
  388. flops += self.downsample.flops()
  389. return flops
  390. class BasicLayer_up(nn.Module):
  391. """ A basic Swin Transformer layer for one stage.
  392. Args:
  393. dim (int): Number of input channels.
  394. input_resolution (tuple[int]): Input resolution.
  395. depth (int): Number of blocks.
  396. num_heads (int): Number of attention heads.
  397. window_size (int): Local window size.
  398. mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.
  399. qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True
  400. qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set.
  401. drop (float, optional): Dropout rate. Default: 0.0
  402. attn_drop (float, optional): Attention dropout rate. Default: 0.0
  403. drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0
  404. norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm
  405. downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None
  406. use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False.
  407. """
  408. def __init__(self, dim, input_resolution, depth, num_heads, window_size,
  409. mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0.,
  410. drop_path=0., norm_layer=nn.LayerNorm, upsample=None, use_checkpoint=False):
  411. super().__init__()
  412. self.dim = dim
  413. self.input_resolution = input_resolution
  414. self.depth = depth
  415. self.use_checkpoint = use_checkpoint
  416. # build blocks
  417. self.blocks = nn.ModuleList([
  418. SwinTransformerBlock(dim=dim, input_resolution=input_resolution,
  419. num_heads=num_heads, window_size=window_size,
  420. shift_size=0 if (i % 2 == 0) else window_size // 2,
  421. mlp_ratio=mlp_ratio,
  422. qkv_bias=qkv_bias, qk_scale=qk_scale,
  423. drop=drop, attn_drop=attn_drop,
  424. drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path,
  425. norm_layer=norm_layer)
  426. for i in range(depth)])
  427. # patch merging layer
  428. if upsample is not None:
  429. self.upsample = PatchExpand(input_resolution, dim=dim, dim_scale=2, norm_layer=norm_layer)
  430. else:
  431. self.upsample = None
  432. def forward(self, x):
  433. for blk in self.blocks:
  434. if self.use_checkpoint:
  435. x = checkpoint.checkpoint(blk, x)
  436. else:
  437. x = blk(x)
  438. if self.upsample is not None:
  439. x = self.upsample(x)
  440. return x
  441. class PatchEmbed(nn.Module):
  442. r""" Image to Patch Embedding
  443. Args:
  444. img_size (int): Image size. Default: 224.
  445. patch_size (int): Patch token size. Default: 4.
  446. in_chans (int): Number of input image channels. Default: 3.
  447. embed_dim (int): Number of linear projection output channels. Default: 96.
  448. norm_layer (nn.Module, optional): Normalization layer. Default: None
  449. """
  450. def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None):
  451. super().__init__()
  452. img_size = to_2tuple(img_size)
  453. patch_size = to_2tuple(patch_size)
  454. patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]]
  455. self.img_size = img_size
  456. self.patch_size = patch_size
  457. self.patches_resolution = patches_resolution
  458. self.num_patches = patches_resolution[0] * patches_resolution[1]
  459. self.in_chans = in_chans
  460. self.embed_dim = embed_dim
  461. self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)
  462. if norm_layer is not None:
  463. self.norm = norm_layer(embed_dim)
  464. else:
  465. self.norm = None
  466. def forward(self, x):
  467. B, C, H, W = x.shape
  468. # FIXME look at relaxing size constraints
  469. assert H == self.img_size[0] and W == self.img_size[1], \
  470. f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})."
  471. x = self.proj(x).flatten(2).transpose(1, 2) # B Ph*Pw C
  472. if self.norm is not None:
  473. x = self.norm(x)
  474. return x
  475. def flops(self):
  476. Ho, Wo = self.patches_resolution
  477. flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1])
  478. if self.norm is not None:
  479. flops += Ho * Wo * self.embed_dim
  480. return flops
  481. class SwinTransformerSys(nn.Module):
  482. r""" Swin Transformer
  483. A PyTorch impl of : `Swin Transformer: Hierarchical Vision Transformer using Shifted Windows` -
  484. https://arxiv.org/pdf/2103.14030
  485. Args:
  486. img_size (int | tuple(int)): Input image size. Default 224
  487. patch_size (int | tuple(int)): Patch size. Default: 4
  488. in_chans (int): Number of input image channels. Default: 3
  489. num_classes (int): Number of classes for classification head. Default: 1000
  490. embed_dim (int): Patch embedding dimension. Default: 96
  491. depths (tuple(int)): Depth of each Swin Transformer layer.
  492. num_heads (tuple(int)): Number of attention heads in different layers.
  493. window_size (int): Window size. Default: 7
  494. mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4
  495. qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True
  496. qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. Default: None
  497. drop_rate (float): Dropout rate. Default: 0
  498. attn_drop_rate (float): Attention dropout rate. Default: 0
  499. drop_path_rate (float): Stochastic depth rate. Default: 0.1
  500. norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm.
  501. ape (bool): If True, add absolute position embedding to the patch embedding. Default: False
  502. patch_norm (bool): If True, add normalization after patch embedding. Default: True
  503. use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False
  504. """
  505. def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000,
  506. embed_dim=96, depths=[2, 2, 2, 2], depths_decoder=[1, 2, 2, 2], num_heads=[3, 6, 12, 24],
  507. window_size=7, mlp_ratio=4., qkv_bias=True, qk_scale=None,
  508. drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1,
  509. norm_layer=nn.LayerNorm, ape=False, patch_norm=True,
  510. use_checkpoint=False, final_upsample="expand_first", **kwargs):
  511. super().__init__()
  512. print("SwinTransformerSys expand initial----depths:{};depths_decoder:{};drop_path_rate:{};num_classes:{}".format(depths,
  513. depths_decoder,drop_path_rate,num_classes))
  514. self.num_classes = num_classes
  515. self.num_layers = len(depths)
  516. self.embed_dim = embed_dim
  517. self.ape = ape
  518. self.patch_norm = patch_norm
  519. self.num_features = int(embed_dim * 2 ** (self.num_layers - 1))
  520. self.num_features_up = int(embed_dim * 2)
  521. self.mlp_ratio = mlp_ratio
  522. self.final_upsample = final_upsample
  523. # split image into non-overlapping patches
  524. self.patch_embed = PatchEmbed(
  525. img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim,
  526. norm_layer=norm_layer if self.patch_norm else None)
  527. num_patches = self.patch_embed.num_patches
  528. patches_resolution = self.patch_embed.patches_resolution
  529. self.patches_resolution = patches_resolution
  530. # absolute position embedding
  531. if self.ape:
  532. self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim))
  533. trunc_normal_(self.absolute_pos_embed, std=.02)
  534. self.pos_drop = nn.Dropout(p=drop_rate)
  535. # stochastic depth
  536. dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule
  537. # build encoder and bottleneck layers
  538. self.layers = nn.ModuleList()
  539. for i_layer in range(self.num_layers):
  540. layer = BasicLayer(dim=int(embed_dim * 2 ** i_layer),
  541. input_resolution=(patches_resolution[0] // (2 ** i_layer),
  542. patches_resolution[1] // (2 ** i_layer)),
  543. depth=depths[i_layer],
  544. num_heads=num_heads[i_layer],
  545. window_size=window_size,
  546. mlp_ratio=self.mlp_ratio,
  547. qkv_bias=qkv_bias, qk_scale=qk_scale,
  548. drop=drop_rate, attn_drop=attn_drop_rate,
  549. drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])],
  550. norm_layer=norm_layer,
  551. downsample=PatchMerging if (i_layer < self.num_layers - 1) else None,
  552. use_checkpoint=use_checkpoint)
  553. self.layers.append(layer)
  554. # build decoder layers
  555. self.layers_up = nn.ModuleList()
  556. self.concat_back_dim = nn.ModuleList()
  557. for i_layer in range(self.num_layers):
  558. concat_linear = nn.Linear(2*int(embed_dim*2**(self.num_layers-1-i_layer)),
  559. int(embed_dim*2**(self.num_layers-1-i_layer))) if i_layer > 0 else nn.Identity()
  560. if i_layer ==0 :
  561. layer_up = PatchExpand(input_resolution=(patches_resolution[0] // (2 ** (self.num_layers-1-i_layer)),
  562. patches_resolution[1] // (2 ** (self.num_layers-1-i_layer))), dim=int(embed_dim * 2 ** (self.num_layers-1-i_layer)), dim_scale=2, norm_layer=norm_layer)
  563. else:
  564. layer_up = BasicLayer_up(dim=int(embed_dim * 2 ** (self.num_layers-1-i_layer)),
  565. input_resolution=(patches_resolution[0] // (2 ** (self.num_layers-1-i_layer)),
  566. patches_resolution[1] // (2 ** (self.num_layers-1-i_layer))),
  567. depth=depths[(self.num_layers-1-i_layer)],
  568. num_heads=num_heads[(self.num_layers-1-i_layer)],
  569. window_size=window_size,
  570. mlp_ratio=self.mlp_ratio,
  571. qkv_bias=qkv_bias, qk_scale=qk_scale,
  572. drop=drop_rate, attn_drop=attn_drop_rate,
  573. drop_path=dpr[sum(depths[:(self.num_layers-1-i_layer)]):sum(depths[:(self.num_layers-1-i_layer) + 1])],
  574. norm_layer=norm_layer,
  575. upsample=PatchExpand if (i_layer < self.num_layers - 1) else None,
  576. use_checkpoint=use_checkpoint)
  577. self.layers_up.append(layer_up)
  578. self.concat_back_dim.append(concat_linear)
  579. self.norm = norm_layer(self.num_features)
  580. self.norm_up= norm_layer(self.embed_dim)
  581. if self.final_upsample == "expand_first":
  582. print("---final upsample expand_first---")
  583. self.up = FinalPatchExpand_X4(input_resolution=(img_size//patch_size,img_size//patch_size),dim_scale=4,dim=embed_dim)
  584. self.output = nn.Conv2d(in_channels=embed_dim,out_channels=self.num_classes,kernel_size=1,bias=False)
  585. self.apply(self._init_weights)
  586. def _init_weights(self, m):
  587. if isinstance(m, nn.Linear):
  588. trunc_normal_(m.weight, std=.02)
  589. if isinstance(m, nn.Linear) and m.bias is not None:
  590. nn.init.constant_(m.bias, 0)
  591. elif isinstance(m, nn.LayerNorm):
  592. nn.init.constant_(m.bias, 0)
  593. nn.init.constant_(m.weight, 1.0)
  594. @torch.jit.ignore
  595. def no_weight_decay(self):
  596. return {'absolute_pos_embed'}
  597. @torch.jit.ignore
  598. def no_weight_decay_keywords(self):
  599. return {'relative_position_bias_table'}
  600. #Encoder and Bottleneck
  601. def forward_features(self, x):
  602. x = self.patch_embed(x)
  603. if self.ape:
  604. x = x + self.absolute_pos_embed
  605. x = self.pos_drop(x)
  606. x_downsample = []
  607. for layer in self.layers:
  608. x_downsample.append(x)
  609. x = layer(x)
  610. x = self.norm(x) # B L C
  611. return x, x_downsample
  612. #Dencoder and Skip connection
  613. def forward_up_features(self, x, x_downsample):
  614. for inx, layer_up in enumerate(self.layers_up):
  615. if inx == 0:
  616. x = layer_up(x)
  617. else:
  618. x = torch.cat([x,x_downsample[3-inx]],-1)
  619. x = self.concat_back_dim[inx](x)
  620. x = layer_up(x)
  621. x = self.norm_up(x) # B L C
  622. return x
  623. def up_x4(self, x):
  624. H, W = self.patches_resolution
  625. B, L, C = x.shape
  626. assert L == H*W, "input features has wrong size"
  627. if self.final_upsample=="expand_first":
  628. x = self.up(x)
  629. x = x.view(B,4*H,4*W,-1)
  630. x = x.permute(0,3,1,2) #B,C,H,W
  631. x = self.output(x)
  632. return x
  633. def forward(self, x):
  634. x, x_downsample = self.forward_features(x)
  635. x = self.forward_up_features(x,x_downsample)
  636. x = self.up_x4(x)
  637. return x
  638. def flops(self):
  639. flops = 0
  640. flops += self.patch_embed.flops()
  641. for i, layer in enumerate(self.layers):
  642. flops += layer.flops()
  643. flops += self.num_features * self.patches_resolution[0] * self.patches_resolution[1] // (2 ** self.num_layers)
  644. flops += self.num_features * self.num_classes
  645. return flops
  646. logger = logging.getLogger(__name__)
  647. class SwinUnet_config():
  648. def __init__(self):
  649. self.patch_size = 4
  650. self.in_chans = 3
  651. self.num_classes = 4
  652. self.embed_dim = 96
  653. self.depths = [2, 2, 6, 2]
  654. self.num_heads = [3, 6, 12, 24]
  655. self.window_size = 7
  656. self.mlp_ratio = 4.
  657. self.qkv_bias = True
  658. self.qk_scale = None
  659. self.drop_rate = 0.
  660. self.drop_path_rate = 0.1
  661. self.ape = False
  662. self.patch_norm = True
  663. self.use_checkpoint = False
  664. class SwinUnet(nn.Module):
  665. def __init__(self, config, img_size=224, num_classes=21843, zero_head=False, vis=False):
  666. super(SwinUnet, self).__init__()
  667. self.num_classes = num_classes
  668. self.zero_head = zero_head
  669. self.config = config
  670. self.swin_unet = SwinTransformerSys(img_size=img_size,
  671. patch_size=config.patch_size,
  672. in_chans=config.in_chans,
  673. num_classes=self.num_classes,
  674. embed_dim=config.embed_dim,
  675. depths=config.depths,
  676. num_heads=config.num_heads,
  677. window_size=config.window_size,
  678. mlp_ratio=config.mlp_ratio,
  679. qkv_bias=config.qkv_bias,
  680. qk_scale=config.qk_scale,
  681. drop_rate=config.drop_rate,
  682. drop_path_rate=config.drop_path_rate,
  683. ape=config.ape,
  684. patch_norm=config.patch_norm,
  685. use_checkpoint=config.use_checkpoint)
  686. def forward(self, x):
  687. if x.size()[1] == 1:
  688. x = x.repeat(1,3,1,1)
  689. logits = self.swin_unet(x)
  690. return logits
  691. def load_from(self, pretrained_path):
  692. if pretrained_path is not None:
  693. print("pretrained_path:{}".format(pretrained_path))
  694. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  695. pretrained_dict = torch.load(pretrained_path, map_location=device)
  696. if "model" not in pretrained_dict:
  697. print("---start load pretrained modle by splitting---")
  698. pretrained_dict = {k[17:]:v for k,v in pretrained_dict.items()}
  699. for k in list(pretrained_dict.keys()):
  700. if "output" in k:
  701. print("delete key:{}".format(k))
  702. del pretrained_dict[k]
  703. msg = self.swin_unet.load_state_dict(pretrained_dict,strict=False)
  704. # print(msg)
  705. return
  706. pretrained_dict = pretrained_dict['model']
  707. print("---start load pretrained modle of swin encoder---")
  708. model_dict = self.swin_unet.state_dict()
  709. full_dict = copy.deepcopy(pretrained_dict)
  710. for k, v in pretrained_dict.items():
  711. if "layers." in k:
  712. current_layer_num = 3-int(k[7:8])
  713. current_k = "layers_up." + str(current_layer_num) + k[8:]
  714. full_dict.update({current_k:v})
  715. for k in list(full_dict.keys()):
  716. if k in model_dict:
  717. if full_dict[k].shape != model_dict[k].shape:
  718. print("delete:{};shape pretrain:{};shape model:{}".format(k,v.shape,model_dict[k].shape))
  719. del full_dict[k]
  720. msg = self.swin_unet.load_state_dict(full_dict, strict=False)
  721. # print(msg)
  722. else:
  723. print("none pretrain")

swin_unet.py at commit 9a1fc10, under GPL-2.0 · at the source

Overview

Authors: Quan Zhou1,2,3, Bo Dong4, Peng Gao2,3, Jintao Wei4, Jiale Xiao3, Wei Wang3, Peipeng Liang5, Danhua Lin3, Jie Lu1, Xi-Nian Zuo2,3,6,7, Hongjian He8,9
ORCID iDs: Peng Gao, Xi-Nian Zuo
  1. Department of Radiology and Nuclear Medicine, Xuanwu Hospital, Capital Medical University, Beijing 100053, China
  2. State Key Laboratory of Cognitive Neuroscience and Learning, Beijing Normal University, Beijing 100875, China
  3. Faculty of Psychology, Beijing Normal University, Beijing 100875, China
  4. College of Biomedical Engineering and Instrument Science, Zhejiang University, Hangzhou 310027, China
  5. School of Psychology, Capital Normal University, Beijing 100048, China
  6. Developmental Population Neuroscience Research Center, McGovern Institute for Brain Research, Beijing Normal University, Beijing 100875, China
  7. National Basic Science Data Center, Beijing 100190, China
  8. School of Physics, Zhejiang University, Hangzhou 310058, China
  9. State Key Laboratory of Brain-Machine Intelligence, Zhejiang University, Hangzhou 310027, China
Journal: Cell reports methods, volume 6, issue 7, article 101473
Dates: received 4 June 2025; accepted 4 May 2026; published online 2 June 2026; in print July 2026
Type: Research article · Language: English
License: CC BY-NC
Identifiers: DOI 10.1016/j.crmeth.2026.101473 · PMID 42229420 · PMCID PMC13390094 · OpenAlex W7163197754
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: structural MRI / diffusion (modality), human (organism), methods / tools (subfield)
Methods: Machine learning, Statistics
Keywords: Cp: Neuroscience, Cp: Imaging
MeSH: Amygdala*, Deep Learning*, Image Processing, Computer-Assisted*, Magnetic Resonance Imaging*, Neuroimaging*, Adolescent, Child, Child, Preschool, Female, Humans, Male (* major topic)
Topic: EEG and Brain-Computer Interfaces (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: Huizhi Ascent Project of Xuanwu Hospital (HZ2021ZCLJ005); Brain Science and Brain-like Intelligence Technology; National Science and Technology Major Project; Chinese Child Brain Development (2021ZD0200500); Beijing Normal University; National Natural Science Foundation of China (82102134, 82322035, 62273076); Key-Area Research and Development Program of Guangdong Province (2019B030335001); Beijing Municipal Science and Technology Commission (Z161100002616023, Z181100001518003); Major Project of National Social Science Foundation of China (20&ZD296); CAS-NWO Programme (153111KYSB20160020); National Basic Research (973) Program (2015CB351702); Chinese Academy of Sciences Key Research Program (KSZD-EW-TZ-002); International Collaboration of National Natural Science Foundation of China (81220108014); China Postdoctoral Science Foundation (2023M740301)
Citations: not cited yet (Europe PMC); 45 references in the paper

Abstract

Tracing the boundaries of the amygdala from brain images remains a major challenge in human neuroscience. Although large-scale neuroimaging studies increasingly collect thousands of scans to investigate structural development in children and adolescents, reliable segmentation of the amygdala is difficult due to its small size and complex morphology—particularly in pediatric populations. To address this, we developed AmygdalaGo-BOLT, a boundary-aware deep learning model specifically designed for amygdala segmentation. The model was trained and validated on 1,086 manually labeled pediatric MRI scans, with independent datasets used to assess generalizability. It integrates multiscale feature extraction, spatial priors, and self-attention mechanisms within a compact encoder-decoder architecture to enhance boundary detection. Across imaging centers and age groups, AmygdalaGo-BOLT demonstrates strong agreement with expert manual annotations, while substantially improving efficiency and accuracy relative to existing tools. This enables robust and scalable analysis of amygdala morphology in population neuroscience studies where manual tracing is impractical.

Reproduced under the paper's license (CC BY-NC), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 2 matches between paragraphs and lines of code.

zuoxinian/ccs

License: GPL-2.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 9a1fc10bb560f5a2aa802c7f6fcc80c5a44366ee, 12 September 2024
Languages: MATLAB (563), Python (90), Shell (74), Jupyter (2), R (1)
Size: 1,947 files, 730 scripts
Software Heritage: not archived
Found in: “Data and code availability”
Holds: README, license file, environment (H3/AmygdalaGo-BOLT/requirements_autodl.txt), 1 notebook
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: FreeSurfer (88 files), EEGLAB (75 files), PyTorch (55 files), FSL (42 files), NumPy (40 files), AFNI (21 files), Statistics and Machine Learning Toolbox (19 files), NiBabel (12 files), OpenCV (10 files), SimpleITK (10 files), GIfTI library for MATLAB (9 files), FieldTrip (8 files), ANTs (6 files), Image Processing Toolbox (5 files), Matplotlib (5 files), SciPy (5 files), SPM (4 files), Pillow (3 files), Brain Connectivity Toolbox (2 files), Signal Processing Toolbox (2 files), MONAI (2 files), Connectome Workbench (2 files), scikit-image (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
732 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 730 scripts, each with its path and the digest of its content;
  • 2 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Data and code availability

• The manually segmented amygdala datasets from the Chongqing cohort of the Chinese Color Nest Cohort (CKG-CCNC), used for model training and internal validation, are publicly available via the National Science DataBank (https://doi.org/10.11922/sciencedb.01299). The original MRI scans and corresponding demographic information (age and sex) are accessible from the Chinese Color Nest Data Community (https://ccndc.scidb.cn/en). External validation was conducted using the Zhejiang University Multi-center Traveler Cohort (ZJU-MTC), which is available on Figshare (https://figshare.com/articles/dataset/Multicenter_dataset_of_multishell_diffusion_magnetic_resonance_imaging_in_healthy_traveling_adults_with_identical_setting/8851955/6). Due to data-sharing agreements and institutional review board restrictions, the BNU-CAC dataset is not publicly available. • All source code used for training, evaluation, and visualization is publicly available via the Science DataBank (https://doi.org/10.57760/sciencedb.o00133.00090) and the Connectome Computation System release at GitHub (https://github.com/zuoxinian/CCS/tree/master/H3/AmygdalaGo-BOLT). • The AmygdalaGo-BOLT online interface is accessible at http://118.196.12.168/. • Any additional information required to re-analyze the data reported by this paper is available from the lead contact upon request.

Reproduced under the paper's license (CC BY-NC), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 11 authors, 2 keywords, 11 MeSH terms, 14 funders, 45 references.

Cite

This paper

Zhou, Q., Dong, B., Gao, P., Wei, J., Xiao, J., Wang, W., Liang, P., Lin, D., Lu, J., Zuo, X.-N., & He, H. (2026). AmygdalaGo-BOLT for boundary-aware segmentation of the human amygdala. Cell reports methods, 6(7), 101473. https://doi.org/10.1016/j.crmeth.2026.101473

BibTeX

@article{zhou2026amygdalago,
author = {Zhou, Quan and Dong, Bo and Gao, Peng and Wei, Jintao and Xiao, Jiale and Wang, Wei and Liang, Peipeng and Lin, Danhua and Lu, Jie and Zuo, Xi-Nian and He, Hongjian},
title = {{AmygdalaGo-BOLT for boundary-aware segmentation of the human amygdala}},
journal = {Cell reports methods},
year = {2026},
month = jun,
volume = {6},
number = {7},
pages = {101473},
publisher = {Elsevier},
issn = {2667-2375},
doi = {10.1016/j.crmeth.2026.101473},
url = {https://doi.org/10.1016/j.crmeth.2026.101473},
pmid = {42229420},
pmcid = {PMC13390094}
}

RIS

TY - JOUR
AU - Zhou, Quan
AU - Dong, Bo
AU - Gao, Peng
AU - Wei, Jintao
AU - Xiao, Jiale
AU - Wang, Wei
AU - Liang, Peipeng
AU - Lin, Danhua
AU - Lu, Jie
AU - Zuo, Xi-Nian
AU - He, Hongjian
TI - AmygdalaGo-BOLT for boundary-aware segmentation of the human amygdala
T2 - Cell reports methods
J2 - Cell Rep Methods
PY - 2026
DA - 2026/06/02
VL - 6
IS - 7
SP - 101473
SN - 2667-2375
PB - Elsevier
DO - 10.1016/j.crmeth.2026.101473
UR - https://doi.org/10.1016/j.crmeth.2026.101473
LA - en
ER -

CSL-JSON

{
"id": "10.1016/j.crmeth.2026.101473",
"type": "article-journal",
"title": "AmygdalaGo-BOLT for boundary-aware segmentation of the human amygdala",
"container-title": "Cell reports methods",
"author": [
{
"family": "Zhou",
"given": "Quan"
},
{
"family": "Dong",
"given": "Bo"
},
{
"family": "Gao",
"given": "Peng"
},
{
"family": "Wei",
"given": "Jintao"
},
{
"family": "Xiao",
"given": "Jiale"
},
{
"family": "Wang",
"given": "Wei"
},
{
"family": "Liang",
"given": "Peipeng"
},
{
"family": "Lin",
"given": "Danhua"
},
{
"family": "Lu",
"given": "Jie"
},
{
"family": "Zuo",
"given": "Xi-Nian"
},
{
"family": "He",
"given": "Hongjian"
}
],
"container-title-short": "Cell Rep Methods",
"volume": "6",
"issue": "7",
"page": "101473",
"DOI": "10.1016/j.crmeth.2026.101473",
"PMID": "42229420",
"PMCID": "PMC13390094",
"ISSN": "2667-2375",
"publisher": "Elsevier",
"URL": "https://doi.org/10.1016/j.crmeth.2026.101473",
"language": "en",
"issued": {
"date-parts": [
[
2026,
6,
2
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s41467-026-76011-7 [code]
Human cortex organizes dynamic co-fluctuations along the sensorimotor-association axis.
Journal: Nature communications
In common: MONAI, Brain Connectivity Toolbox, Connectome Workbench, 20 other tools, 1 reference, author Xi-Nian Zuo
[2] doi:10.1038/s41467-026-73668-y [code]
Convergent and divergent brain-cognition development in early adolescence.
Journal: Nature communications
In common: Connectome Workbench, AFNI, GIfTI library for MATLAB, 13 other tools, 1 reference, author Xi-Nian Zuo
[3] doi:10.1038/s41467-026-71151-2 [code]
Common and distinct neural correlates of social interaction processing and theory of mind in narratives.
Journal: Nature communications
In common: Brain Connectivity Toolbox, Connectome Workbench, AFNI, 14 other tools
[4] doi:10.1038/s41398-026-04025-2 [code]
Brain energetic landscapes shape state dysregulation in major depressive disorder: a morphological network controllability perspective.
Journal: Translational psychiatry
In common: Brain Connectivity Toolbox, Connectome Workbench, AFNI, 13 other tools
[5] doi:10.1002/hbm.70483 [code]
Untamed: Unconstrained Tensor Decomposition and Graph Node Embedding for Cortical Parcellation.
Journal: Human brain mapping
In common: Connectome Workbench, AFNI, GIfTI library for MATLAB, 13 other tools, methods / tools
[6] doi:10.1371/journal.pbio.3003856 [code]
Aging and metabolism contribute separately to brain-body health.
Journal: PLoS biology
In common: Connectome Workbench, AFNI, GIfTI library for MATLAB, 12 other tools, structural MRI / diffusion, 1 reference
[7] doi:10.1016/j.neuroimage.2026.122171 [code]
A conserved node degree-based backbone and flexible hub organization of brain connectome during naturalistic movie watching.
Journal: NeuroImage
In common: Connectome Workbench, AFNI, GIfTI library for MATLAB, 12 other tools, methods / tools
[8] doi:10.1093/braincomms/fcag134 [code]
Neurophysiological, imaging and neurobiological markers of central fatigue in multiple sclerosis.
Journal: Brain communications
In common: Connectome Workbench, AFNI, GIfTI library for MATLAB, 12 other tools, structural MRI / diffusion
[9] doi:10.1038/s41467-026-76452-0 [code]
Music evokes shared neural representations of imagined narratives across sensory modalities.
Journal: Nature communications
In common: Connectome Workbench, AFNI, GIfTI library for MATLAB, 12 other tools
[10] doi:10.1016/j.xcrm.2026.102943 [code]
Parent-of-origin effects in Alzheimer's liability dissociate neurocognitive and cardiovascular traits in at-risk individuals.
Journal: Cell reports. Medicine
In common: Connectome Workbench, AFNI, GIfTI library for MATLAB, 12 other tools

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.