OSCR

Graph-based modeling of optical system enables adaptive optics on dynamic samples with self-calibration.

Code ↔ Paper

13 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 13 matches · 5 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § STAR★Methods › Method details › Synthetic data generation ↔ MATLAB code/sub-functions/createPhaseDiversityImages.m, the whole file · a weak match · score 0.87 · Gaussian noise, create phase, phase diversity images, ground truth, Zernike coefficient, Poisson
  2. [2] § STAR★Methods › Method details › Performance metrics ↔ MATLAB code/sub-functions/calculateImageQualityMetrics.m, the whole file · a weak match · score 0.72 · discrete cosine transform, image quality metrics, DCTS, zero, pixel
  3. [3] § STAR★Methods › Method details › Performance metrics ↔ MATLAB code/processPhaseDiversityImages.m, lines 1–72 · score 0.71 · square error, image quality metrics, sharpness, root, DCTS, cropping
  4. [4] § STAR★Methods › Method details › Synthetic data generation ↔ graphycs/forward_model_wf.py, the whole file · a weak match · score 0.69 · pupil plane, forward model, Zernike modes, diversity images, tetrafoil, shifting
  5. [5] § STAR★Methods › Method details › Wide-field adaptive optics system description ↔ GRAPHYCS_demo.ipynb, lines 43–91 · score 0.68 · deformable mirror, pupil plane, diameter, diversity images, camera, beam
  6. [6] § STAR★Methods › Method details › Training details and parameters ↔ graphycs/GRAPHYCS_spatially_variant_lsm.py, lines 8–43 · score 0.67 · Loss weights, affine transformation, spatially variant, motion, Fourier
  7. [7] § STAR★Methods › Method details › Aberration correction in light-sheet microscopy of larval zebrafish brain ↔ MATLAB code/processPhaseDiversityImages.m, lines 1–72 · score 0.67 · phase diversity, diversity images, Zernike coefficients, sharpness, DCTS, frame
  8. [8] § STAR★Methods › Method details › Sample-induced aberration correction in wide-field microscopy ↔ MATLAB code/sub-functions/createPhaseDiversityImages.m, the whole file · a weak match · score 0.64 · phase diversity images, Zernike coefficient, aberrated image, noise, ratio, signal
  9. [9] § Results › Spatially varying aberration sensing across the large field of view ↔ MATLAB code/sub-functions/calculateImageQualityMetrics.m, the whole file · a weak match · score 0.63 · discrete cosine transform, image quality metrics, DCTS
  10. [10] § STAR★Methods › Method details › Sample-induced aberration correction in wide-field microscopy ↔ GRAPHYCS_demo.ipynb, lines 182–283 · score 0.62 · Fourier domain, image domain, piston, aberrated image, tip, tilt
  11. [11] § STAR★Methods › Method details › Training details and parameters ↔ GRAPHYCS_demo.ipynb, lines 43–91 · score 0.59 · Loss weights, L1, Fourier, Training
  12. [12] § Results › Spatially varying aberration sensing across the large field of view ↔ graphycs/GRAPHYCS_spatially_invariant_lsm.py, lines 372–434 · score 0.56 · map visualized, phase maps, spatially invariant, component, wavefront, model
  13. [13] § Results › Spatially varying aberration sensing across the large field of view ↔ graphycs/GRAPHYCS_spatially_variant_lsm.py, lines 370–433 · score 0.51 · map visualized, phase maps, spatially variant, component, patch, model

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

Jupyter notebook · 408 lines · 14 KB · GPL-3.0 · 3 matches

  1. # %%
  2. !pip install fft-conv-pytorch
  3. !pip install scikit-image
  4. # %%
  5. import sys
  6. from pathlib import Path
  7. # Find GRAPHYCS root (folder that contains graphycs/forward_model_wf.py)
  8. start = Path.cwd()
  9. root = None
  10. for p in [start, *start.parents]:
  11. if (p / "graphycs" / "forward_model_wf.py").exists():
  12. root = p
  13. break
  14. pkg = root / "graphycs"
  15. sys.path.insert(0, str(root))
  16. sys.path.insert(0, str(pkg))
  17. # %%
  18. from datetime import datetime
  19. import os
  20. import torch
  21. import numpy as np
  22. import matplotlib.pyplot as plt
  23. from tqdm import tqdm
  24. import skimage.io as skio
  25. import torch.nn.functional as F
  26. from torch.fft import fftshift, ifftshift, ifft2, fft2
  27. # your helper modules (now in working dir)
  28. from graphycs.forward_model_wf import forward_model_wf
  29. from graphycs.utils import *
  30. from graphycs.self_calibration import *
  31. # device
  32. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  33. print("Using device:", device)
  34. # %%
  35. self_calib_param_lr = 5e-4
  36. learning_rate = 5e-3
  37. object_learning_rate = 2e-3
  38. seed = 0
  39. data_path = 'Data/Diversity_Images_Lymph.tif'
  40. zernike_coeff_path = 'Data/appliedCoeff.txt'
  41. # ─── Calibration options ────────────────────────────────────────────────────────
  42. use_self_calibration = 1 # 1 or 0
  43. use_learnable_scales = 1 # 1 or 0
  44. use_scheduler = 0 # 1 or 0
  45. # ─── Optimization hyperparameters ───────────────────────────────────────────────
  46. epochs = 500
  47. batch_size = 22
  48. use_batch_shuffling = 0 # 1 or 0
  49. use_L1_loss = 1 # 1 or 0
  50. fourier_loss_weight = 1e-5
  51. # ─── Visualization controls for training loop ───────────────────────────────────
  52. vis_frequency = 200
  53. vis_intermediates = 1 # keep in-memory stacks only
  54. # ─── Zernike orders ─────────────────────────────────────────────────────────────
  55. n_max = 14
  56. n_max_estimated = 14
  57. # ─── Optical parameters ────────────────────────────────────────────────────────
  58. NA = 0.3
  59. camera_pixel_size = 0.5343e-6
  60. wavelength = 0.513e-6
  61. n_imm = 1.33
  62. gaussian_sigma = 10.0e-3
  63. avg_background = 0.0
  64. psf_size = 101
  65. img_num_factor = 1
  66. ### Dxp: diameter of the deformable mirror in m
  67. Dxp = 10e-3
  68. pad_w, pad_h = psf_size - 1, psf_size - 1
  69. # ─── Zernike basis and defining the beam and Deformable mirror in the pupil plane────────────────────────────────────────────────────────────
  70. M = 255
  71. _, zernikes = zernike_pd_generation_higher_order(6, n_max, M, camera_pixel_size, wavelength, NA)
  72. zernikes = zernikes.to(device)
  73. # %%
  74. # ─── Setup seeds ────────────────────────────────────────────────────
  75. torch.manual_seed(seed)
  76. np.random.seed(seed)
  77. torch.cuda.manual_seed(seed)
  78. torch.backends.cudnn.deterministic = True
  79. torch.backends.cudnn.benchmark = False
  80. # %%
  81. # ─── Load applied coefficients ────────────────────────────────────────────────
  82. coeffs = np.loadtxt(zernike_coeff_path)
  83. coeffs = coeffs[::img_num_factor]
  84. coeffs = torch.tensor(coeffs, dtype=torch.float32).to(device)
  85. # coeffs[pair_idx]: known DM-applied Zernike coefficients for each diversity image.
  86. # ─── Load data ────────────────────────────────────────────────────────────────
  87. phase_added = skio.imread(data_path).astype(np.float32)
  88. bg = np.min(phase_added[phase_added > 0])
  89. phase_added = np.clip(phase_added - bg, 0, None)
  90. phase_added /= phase_added.max()
  91. phase_added = np.squeeze(phase_added)[::img_num_factor]
  92. phase_added = torch.from_numpy(phase_added).to(device)
  93. # phase_added: normalized observed diversity stack with shape [num_images, H, W].
  94. # ─── Build learnable forward model ────────────────────────────────────────────
  95. forward_model = forward_model_wf(
  96. init_object=phase_added[0].clone(),
  97. n_max=n_max,
  98. psf_size=psf_size,
  99. M=M,
  100. lmbda=wavelength,
  101. pixel_size=camera_pixel_size,
  102. n=n_imm,
  103. NA=NA,
  104. diversity_imgs_num=len(coeffs),
  105. device=device,
  106. use_affine_transform=bool(use_self_calibration),
  107. use_scales=bool(use_learnable_scales),
  108. ).to(device)
  109. # Aliases used by downstream analysis cells.
  110. found_zernike_coef = forward_model.zernike_coef
  111. found_object = forward_model.estimated_obj
  112. if use_self_calibration:
  113. print("Using affine transformation self calibration parameters in forward_model_wf")
  114. self_calib_params = [
  115. forward_model.amp_x,
  116. forward_model.amp_y,
  117. forward_model.off_x,
  118. forward_model.off_y,
  119. forward_model.rot,
  120. forward_model.grid,
  121. ]
  122. else:
  123. print("Running without affine transformation self calibration")
  124. self_calib_params = []
  125. if use_learnable_scales:
  126. print("Using learnable Zernike scaling factors in forward_model_wf")
  127. scale_factors_list = list(forward_model.scales)
  128. else:
  129. print("Running without learnable Zernike scaling factors")
  130. scale_factors_list = []
  131. optimizer_param_groups = [
  132. {'params': [found_zernike_coef], 'lr': learning_rate},
  133. {'params': [found_object], 'lr': object_learning_rate},
  134. ]
  135. if use_self_calibration:
  136. for param in self_calib_params:
  137. optimizer_param_groups.append({'params': [param], 'lr': self_calib_param_lr})
  138. if use_learnable_scales:
  139. for scale_factor in scale_factors_list:
  140. optimizer_param_groups.append({'params': [scale_factor], 'lr': self_calib_param_lr})
  141. optimizer = torch.optim.Adam(optimizer_param_groups, lr=learning_rate)
  142. if use_scheduler:
  143. scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=epochs, eta_min=0)
  144. L1_loss = torch.nn.L1Loss()
  145. # %%
  146. ## Freeze piston/tip/tilt and optional high-order modes during optimization.
  147. mask = torch.ones_like(found_zernike_coef, device=device)
  148. mask[:3] = 0
  149. if n_max_estimated < len(mask):
  150. mask[n_max_estimated + 1:] = 0
  151. train_loss_curve = []
  152. image_loss_curve = []
  153. fourier_loss_curve = []
  154. found_object_stack = []
  155. iPSF_stack = []
  156. amplitudes_stack = []
  157. generated_imgs = []
  158. mse_loss = torch.nn.MSELoss()
  159. do_vis = vis_frequency > 0
  160. t = tqdm(range(epochs))
  161. for epoch_idx in t:
  162. if use_batch_shuffling == 1:
  163. idxs = torch.randperm(len(coeffs)).long().to(device)
  164. else:
  165. idxs = torch.arange(len(coeffs)).long().to(device)
  166. forward_model.estimated_obj.requires_grad_()
  167. forward_model.zernike_coef.requires_grad_()
  168. epoch_train_loss = 0.0
  169. epoch_image_loss = 0.0
  170. epoch_fourier_loss = 0.0
  171. for it in range(0, len(coeffs), batch_size):
  172. idx = idxs[it:min(it + batch_size, len(coeffs))]
  173. coeff_batch, y_batch = coeffs[idx], phase_added[idx]
  174. optimizer.zero_grad()
  175. aberrated_imgs, psfs, amplitude_transformed = forward_model(coeff_batch, idx)
  176. recon_observed_imgs_FT = torch.real(torch.fft.fft2(aberrated_imgs, dim=(-2, -1)))
  177. observed_imgs_FT = torch.real(torch.fft.fft2(y_batch, dim=(-2, -1)))
  178. if use_L1_loss == 1:
  179. Fourier_loss = L1_loss(recon_observed_imgs_FT.squeeze(), observed_imgs_FT.squeeze())
  180. recon_loss = L1_loss(aberrated_imgs.squeeze(), y_batch.squeeze())
  181. else:
  182. Fourier_loss = mse_loss(recon_observed_imgs_FT.squeeze(), observed_imgs_FT.squeeze())
  183. recon_loss = mse_loss(aberrated_imgs.squeeze(), y_batch.squeeze())
  184. epoch_image_loss += recon_loss.item()
  185. epoch_fourier_loss += Fourier_loss.item()
  186. loss = recon_loss + fourier_loss_weight * Fourier_loss
  187. epoch_train_loss += loss.item()
  188. if do_vis and (epoch_idx % vis_frequency) == 0 and it == 0:
  189. psfs_squeezed = psfs.squeeze().detach().cpu().numpy()
  190. if vis_intermediates == 1:
  191. model_outputs_squeezed = aberrated_imgs.squeeze().detach().cpu().numpy()
  192. if model_outputs_squeezed.ndim == 3:
  193. generated_imgs.append(model_outputs_squeezed[-1, :, :])
  194. elif model_outputs_squeezed.ndim == 2:
  195. generated_imgs.append(model_outputs_squeezed)
  196. found_object_stack.append(forward_model.estimated_obj.detach().cpu().numpy())
  197. if psfs_squeezed.ndim == 3:
  198. iPSF_stack.append(psfs_squeezed[-1, :, :])
  199. elif psfs_squeezed.ndim == 2:
  200. iPSF_stack.append(psfs_squeezed)
  201. amplitudes_stack.append(amplitude_transformed.detach().cpu().numpy())
  202. loss.backward()
  203. if forward_model.zernike_coef.grad is not None:
  204. forward_model.zernike_coef.grad.mul_(mask)
  205. optimizer.step()
  206. if use_scheduler:
  207. scheduler.step()
  208. with torch.no_grad():
  209. forward_model.estimated_obj.data.clamp_(min=0.0)
  210. if use_learnable_scales:
  211. for p in forward_model.scales:
  212. p.data.clamp_(min=-1.0)
  213. train_loss_curve.append(epoch_train_loss)
  214. image_loss_curve.append(epoch_image_loss)
  215. fourier_loss_curve.append(epoch_fourier_loss)
  216. t.set_description(
  217. f"Epoch {epoch_idx + 1}/{epochs}, Total loss: {epoch_train_loss:.4f}, Image domain loss: {epoch_image_loss:.4f}, Fourier domain loss: {epoch_fourier_loss:.4f}"
  218. )
  219. # Keep explicit final handles to the trained model parameters for downstream cells.
  220. trained_model = forward_model
  221. final_found_object = trained_model.estimated_obj.detach()
  222. final_found_zernike_coef = trained_model.zernike_coef.detach()
  223. # %%
  224. # Base results path
  225. base_results = "Results"
  226. # Create a timestamp string, e.g. "20250429_163045"
  227. ts = datetime.now().strftime("%Y%m%d_%H")
  228. # Full path for this run
  229. results_dir = os.path.join(base_results, ts)
  230. os.makedirs(results_dir, exist_ok=True)
  231. # Read final trained parameters directly from the trained model.
  232. if 'trained_model' not in globals():
  233. trained_model = forward_model
  234. final_found_zernike_coef = trained_model.zernike_coef.detach()
  235. final_found_object = trained_model.estimated_obj.detach()
  236. zernike_coeffs_np = final_found_zernike_coef.cpu().numpy()
  237. found_obj_np = final_found_object.cpu().numpy()
  238. # Save Zernike coefficients
  239. np.savetxt(os.path.join(results_dir, "found_zernike_coefficients.txt"),
  240. zernike_coeffs_np, fmt="%.6e")
  241. # Save reconstructed object
  242. skio.imsave(os.path.join(results_dir, "estimated_object.tif"), found_obj_np)
  243. # Save loss curves collected in training loop
  244. np.save(os.path.join(results_dir, "train_loss_curve.npy"), np.array(train_loss_curve))
  245. np.save(os.path.join(results_dir, "image_loss_curve.npy"), np.array(image_loss_curve))
  246. np.save(os.path.join(results_dir, "fourier_loss_curve.npy"), np.array(fourier_loss_curve))
  247. # %%
  248. # — Plot training loss curves —
  249. plt.figure(figsize=(10, 4))
  250. plt.subplot(1, 3, 1)
  251. plt.plot(train_loss_curve, lw=2)
  252. plt.xlabel('Epoch')
  253. plt.ylabel('Loss')
  254. plt.title('Total Loss')
  255. plt.grid(True)
  256. plt.subplot(1, 3, 2)
  257. plt.plot(image_loss_curve, lw=2)
  258. plt.xlabel('Epoch')
  259. plt.ylabel('Loss')
  260. plt.title('Image Loss')
  261. plt.grid(True)
  262. plt.subplot(1, 3, 3)
  263. plt.plot(fourier_loss_curve, lw=2)
  264. plt.xlabel('Epoch')
  265. plt.ylabel('Loss')
  266. plt.title('Fourier Loss')
  267. plt.grid(True)
  268. plt.tight_layout()
  269. plt.show()
  270. # %%
  271. # — Compute & show estimated phase map from the trained model —
  272. if 'trained_model' not in globals():
  273. trained_model = forward_model
  274. final_found_zernike_coef = trained_model.zernike_coef.detach()
  275. estimated_phase = torch.einsum('i,ijk->jk', 1e-6 * final_found_zernike_coef, zernikes)
  276. est_phase_np = estimated_phase.detach().cpu().numpy()
  277. est_phase_np = (2 * n_imm * np.pi / wavelength) * est_phase_np # Convert from meters to radians
  278. plt.figure(figsize=(5,4))
  279. plt.imshow(est_phase_np, cmap='jet', vmin=-np.pi, vmax=np.pi)
  280. plt.colorbar(shrink=0.6)
  281. plt.title('Estimated Phase [radians]')
  282. plt.axis('off')
  283. plt.show()
  284. # %%
  285. # — Bar chart of learned Zernike coefficients from the trained model —
  286. if 'trained_model' not in globals():
  287. trained_model = forward_model
  288. coeffs_np = trained_model.zernike_coef.detach().cpu().numpy()
  289. modes = np.arange(len(coeffs_np))
  290. plt.figure(figsize=(5,3))
  291. plt.bar(modes, coeffs_np, color='C1')
  292. plt.xlabel('Zernike Mode Index')
  293. plt.ylabel('Coefficient [µm]')
  294. plt.title('Estimated Zernike Coefficients')
  295. plt.show()
  296. # %%
  297. ## Estimated zernike coefficients:
  298. print(coeffs_np)
  299. # %%
  300. # Display original vs. trained-model estimated object side-by-side
  301. if 'trained_model' not in globals():
  302. trained_model = forward_model
  303. orig_np = phase_added[0].detach().cpu().numpy()
  304. orig_np = (orig_np - orig_np.min()) / (orig_np.max() - orig_np.min()) # Normalize to [0, 1]
  305. est_obj_np = trained_model.estimated_obj.detach().cpu().numpy()
  306. est_min = est_obj_np.min()
  307. est_p999 = np.percentile(est_obj_np, 99.9)
  308. est_obj_np = np.clip((est_obj_np - est_min) / max(est_p999 - est_min, 1e-12), 0, 1) # Min->0, 99.9th percentile->1
  309. fig, axs = plt.subplots(1, 2, figsize=(10,5))
  310. axs[0].imshow(orig_np, cmap='gray', vmin=0, vmax=1)
  311. axs[0].set_title('Original Image')
  312. axs[0].axis('off')
  313. axs[1].imshow(est_obj_np, cmap='gray', vmin=0, vmax=0.8)
  314. axs[1].set_title('Estimated Object')
  315. axs[1].axis('off')
  316. plt.tight_layout()
  317. plt.show()

GRAPHYCS_demo.ipynb at commit 84c2c58, under GPL-3.0 · at the source

Overview

Authors: Eun-Seo Cho1, Joon Park1, Hyungwon Jin2, Yoonjae Chung1, Minho Eom1, Hyejin Shin3, Jae-Byum Chang3, Jung-Hoon Park2, Young-Gyu Yoon1,4,5
ORCID iDs: Young-Gyu Yoon
  1. School of Electrical Engineering, KAIST, Daejeon, Republic of Korea
  2. Department of Biomedical Engineering, Ulsan National Institute of Science and Technology (UNIST), Ulsan, Republic of Korea
  3. Department of Materials Science and Engineering, KAIST, Daejeon, Republic of Korea
  4. Department of Semiconductor System Engineering, KAIST, Daejeon, Republic of Korea
  5. KAIST Institute for Human Augmentation Convergence, Daejeon, Republic of Korea
Journal: iScience, volume 29, issue 8, article 116769
Dates: received 18 November 2025; accepted 26 June 2026; published online 14 July 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1016/j.isci.2026.116769 · PMID 42519053 · PMCID PMC13382438 · OpenAlex W7168241314
Open access: gold, a free copy (OpenAlex)
Status: code verified
Methods: Connectivity, fMRI & imaging, Single-unit activity, calcium imaging, Physiology & signal measures
Keywords: adaptive optics, graph-based modeling, phase diversity, wavefront sensing
Topic: Neural Networks and Reservoir Computing (Artificial Intelligence, Computer Science), according to OpenAlex
Funding: Korea Ministry of Science and ICT (RS-2021-NR056586, RS-2022-NR068424, RS-2026-25504129, RS-2023-00264980, RS-2023-00264409, RS-2026-25475246, RS-2023-00209473, RS-2024-00401676); Human Frontier Science Program; International Human Frontier Science Program Organization (RGP003/2024); National Research Foundation of Korea; Convergence; Korea Basic Science Institute; Ministry of Education; KAIST
Citations: not cited yet (Europe PMC); 50 references in the paper

Abstract

Sensor less adaptive optics offers significant advantages over hardware-based wavefront sensing but faces persistent challenges: Its performance degrades when idealized models fail to capture system imperfections, it is largely restricted to spatially invariant aberrations, and it cannot accommodate dynamic biological samples due to static-object assumptions. Here we present graph-modeling and phase-diversity-based computational adaptive optics with self-calibration (GRAPHYCS), a differentiable graph-based modeling framework that addresses all three limitations. GRAPHYCS automatically self-calibrates to correct system-specific non-idealities, enables spatially variant wavefront sensing across extended fields of view by modeling local aberrations, and supports dynamic live-sample imaging where conventional computational methods fail. In simulations, GRAPHYCS achieves up to a 9-fold improvement in wavefront sensing accuracy compared to analytic phase diversity under system non-idealities. In real microscopy experiments, it consistently outperforms phase-diversity-based methods compared in this study. Furthermore, in live zebrafish brain imaging, GRAPHYCS enables simultaneous wavefront sensing and neuronal activity detection—an application beyond the reach of existing approaches without additional hardware complexity.

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

Repositories

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

NICALab/GRAPHYCS

License: GPL-3.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 84c2c588030f909abf4c6da899f65f40afb49a9f, 23 July 2026
Languages: Python (11), Jupyter (1)
Size: 17 files, 12 scripts
Software Heritage: not archived
Found in: “Data and code availability”
Holds: README, license file, environment (requirements.txt), 1 notebook
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: NumPy (12 files), PyTorch (12 files), scikit-image (7 files), Matplotlib (6 files), SciPy (5 files)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
14 files

ceej640/PhaseDiversity

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: b0839b690fd965a9d5628b1ba45a3bfadeae80f0, 25 February 2025
Languages: MATLAB (29)
Size: 31 files, 29 scripts
Software Heritage: not archived
Found in: the text, “Comparison with other algorithms”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
30 files

Intelligent-Sensing/NeuWS

License: other
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: c56b9bb8f3c722b4288af73a27e2507129a01de0, 30 June 2023
Languages: Python (4)
Size: 7 files, 4 scripts
Software Heritage: not archived
Found in: the text, “Comparison with other algorithms”
Holds: README, license file, environment (requirements.txt)
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: NumPy (4 files), PyTorch (4 files), SciPy (3 files), imageio (2 files), Matplotlib (2 files), h5py (1 file), Pillow (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
6 files

NICALab/SUPPORT

License: GPL-3.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 9fba0f415b35106d7d7b9c0144e72917329f0575, 11 August 2025
Languages: Python (13)
Size: 33 files, 13 scripts
Software Heritage: not archived
Found in: the resources table
Holds: README, license file, environment (env.yml), documentation
Not found: CITATION.cff, tests, continuous integration
Tools: NumPy (12 files), PyTorch (12 files), scikit-image (8 files), Matplotlib (2 files), Pillow (2 files), tifffile (2 files)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
15 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:

  • 4 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 58 scripts, each with its path and the digest of its content;
  • 13 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 datasets generated and/or analyzed during the current study have been deposited at Zenodo at https://zenodo.org/records/17049780 (https://zenodo.org/records/15421484) and are publicly available as of the date of publication.

All original code has been deposited at a GitHub repository and is publicly available at https://github.com/NICALab/GRAPHYCS as of the date of publication.

Any additional information required to reanalyze the data reported in this paper is available from the lead contact upon request.

Reproduced under the paper's license (CC BY), 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, 9 authors, 4 keywords, 8 funders, 50 references.

Cite

This paper

Cho, E.-S., Park, J., Jin, H., Chung, Y., Eom, M., Shin, H., Chang, J.-B., Park, J.-H., & Yoon, Y.-G. (2026). Graph-based modeling of optical system enables adaptive optics on dynamic samples with self-calibration. iScience, 29(8), 116769. https://doi.org/10.1016/j.isci.2026.116769

BibTeX

@article{cho2026graph,
author = {Cho, Eun-Seo and Park, Joon and Jin, Hyungwon and Chung, Yoonjae and Eom, Minho and Shin, Hyejin and Chang, Jae-Byum and Park, Jung-Hoon and Yoon, Young-Gyu},
title = {{Graph-based modeling of optical system enables adaptive optics on dynamic samples with self-calibration}},
journal = {iScience},
year = {2026},
month = jul,
volume = {29},
number = {8},
pages = {116769},
publisher = {Elsevier},
issn = {2589-0042},
doi = {10.1016/j.isci.2026.116769},
url = {https://doi.org/10.1016/j.isci.2026.116769},
pmid = {42519053},
pmcid = {PMC13382438}
}

RIS

TY - JOUR
AU - Cho, Eun-Seo
AU - Park, Joon
AU - Jin, Hyungwon
AU - Chung, Yoonjae
AU - Eom, Minho
AU - Shin, Hyejin
AU - Chang, Jae-Byum
AU - Park, Jung-Hoon
AU - Yoon, Young-Gyu
TI - Graph-based modeling of optical system enables adaptive optics on dynamic samples with self-calibration
T2 - iScience
J2 - iScience
PY - 2026
DA - 2026/07/14
VL - 29
IS - 8
SP - 116769
SN - 2589-0042
PB - Elsevier
DO - 10.1016/j.isci.2026.116769
UR - https://doi.org/10.1016/j.isci.2026.116769
LA - en
ER -

CSL-JSON

{
"id": "10.1016/j.isci.2026.116769",
"type": "article-journal",
"title": "Graph-based modeling of optical system enables adaptive optics on dynamic samples with self-calibration",
"container-title": "iScience",
"author": [
{
"family": "Cho",
"given": "Eun-Seo"
},
{
"family": "Park",
"given": "Joon"
},
{
"family": "Jin",
"given": "Hyungwon"
},
{
"family": "Chung",
"given": "Yoonjae"
},
{
"family": "Eom",
"given": "Minho"
},
{
"family": "Shin",
"given": "Hyejin"
},
{
"family": "Chang",
"given": "Jae-Byum"
},
{
"family": "Park",
"given": "Jung-Hoon"
},
{
"family": "Yoon",
"given": "Young-Gyu"
}
],
"container-title-short": "iScience",
"volume": "29",
"issue": "8",
"page": "116769",
"DOI": "10.1016/j.isci.2026.116769",
"PMID": "42519053",
"PMCID": "PMC13382438",
"ISSN": "2589-0042",
"publisher": "Elsevier",
"URL": "https://doi.org/10.1016/j.isci.2026.116769",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
14
]
]
}
}

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-73389-2 [code]
Physics-informed multi-encoder adaptive optics enables rapid aberration correction for intravital microscopy of deep complex tissue.
Journal: Nature communications
In common: SciPy, Matplotlib, NumPy, 18 references
[2] doi:10.1038/s41467-026-75347-4 [code]
Sleep reveals dynamics integrating and segregating movement and stimulus representations in V1.
Journal: Nature communications
In common: Curve Fitting Toolbox, imageio, Parallel Computing Toolbox, 7 other tools
[3] doi:10.1038/s41467-026-73045-9 [code]
Aberration-aware 3D localization microscopy via self-supervised neural-physics learning.
Journal: Nature communications
In common: imageio, tifffile, scikit-image, 5 other tools, 2 references
[4] doi:10.1038/s41592-026-03179-7 [code]
Voltage imaging of neurons distributed across entire brains of larval zebrafish.
Journal: Nature methods
In common: scikit-image, h5py, SciPy, 2 other tools, 5 references
[5] doi:10.1038/s41467-026-76242-8 [code]
Whole-brain, all-optical interrogation of neuronal dynamics underlying gut and vascular interoception in zebrafish.
Journal: Nature communications
In common: tifffile, Parallel Computing Toolbox, scikit-image, 5 other tools, 2 references
[6] doi:10.1038/s41592-026-03066-1 [code]
A multimodal adaptive optical microscope for in vivo imaging from molecules to organisms.
Journal: Nature methods
In common: Parallel Computing Toolbox, Image Processing Toolbox, NumPy, 5 references
[7] doi:10.1126/sciadv.aee9298 [code]
Synaptic zinc plasticity shapes adaptive and maladaptive cortical plasticity following cochlear injury.
Journal: Science advances
In common: imageio, tifffile, Parallel Computing Toolbox, 6 other tools
[8] doi:10.1080/07853890.2026.2685416 [code]
Pulmonary and cerebral damage in COVID-19 survivors: is there any association?
Journal: Annals of medicine
In common: Curve Fitting Toolbox, imageio, scikit-image, 6 other tools
[9] doi:10.1364/boe.605322 [code]
Generalized plaque digitization framework for multi-dimensional mesoscopic images.
Journal: Biomedical optics express
In common: imageio, tifffile, scikit-image, 6 other tools
[10] doi:10.1038/s41598-026-57519-w [code]
Automated segmentation of neurons and spinal cord structures in immunofluorescence images using SpineDL.
Journal: Scientific reports
In common: imageio, tifffile, scikit-image, 6 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.