Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
019f485
Outlined tutorials
cedriclim1 Jan 31, 2026
c4a5019
Added a README file for tomography/hpc
cedriclim1 Jan 31, 2026
617c687
Renamed notebooks to tutorials
cedriclim1 Jan 31, 2026
6d3c798
Finished tomography lite tutorial v1
cedriclim1 Feb 2, 2026
97a6699
Example tilt series and tilt angles .npy files (what's the best way t…
cedriclim1 Feb 2, 2026
eab93ee
Tomography scripts and notebook tutorials implemented
cedriclim1 Feb 2, 2026
a4616c0
Added HPC tutorials
cedriclim1 Feb 2, 2026
9133716
.gitignore update
cedriclim1 Feb 2, 2026
2227eb6
Added bash script for queuing a job
cedriclim1 Feb 3, 2026
8edbf70
Oops, added the actual run_job here
cedriclim1 Feb 3, 2026
cb9b851
Script check
cedriclim1 Feb 3, 2026
d294124
Added phantom back in
cedriclim1 Feb 19, 2026
f1ebced
Update directories, and updated tomography_02_full.ipynb to due to ch…
cedriclim1 Mar 3, 2026
770444f
Moved some stuff around - updated tomography_01_lite.ipynb. Hyperpara…
cedriclim1 Mar 3, 2026
bf13263
Added tensorboard logging into tomography_01_lite.ipynb; A little jan…
cedriclim1 Mar 3, 2026
1842620
Also added tensorboard cell in tomography_02
cedriclim1 Mar 3, 2026
bbc6712
Tomography_02_full.ipynb complete with loading and saving; need to ad…
cedriclim1 Mar 3, 2026
0fcad81
Saving and loading added to TomographyLite tutorial
cedriclim1 Mar 3, 2026
afc3593
Tomography_02_full.ipynb everything runs
cedriclim1 Mar 3, 2026
a329ccc
HPC scripts updated module loads due to cudatoolkit 13.0 upgrade errors
cedriclim1 Mar 3, 2026
0a23e3e
Updates to tomography_02_full using new ObjectConstraints, and update…
cedriclim1 Mar 5, 2026
2724178
DatasetConstraints implemented in tomgraphy_02_full.ipynb
cedriclim1 Mar 5, 2026
db4dc42
DatasetConstraints implemented in tomgraphy_02_full.ipynb
cedriclim1 Mar 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.ipynb_checkpoints
*.zip
*.npy
# *.npy
.DS_Store
dvlp_notebooks
notebooks/runs/vols/
outputs/
Binary file added data/phantom.npy
Binary file not shown.
Binary file added data/tilt_angles_1_deg_tilt_axis.npy
Binary file not shown.
Binary file added data/tilt_series_1_deg_tilt_axis.npy
Binary file not shown.
Binary file removed notebooks/tomography/runs/logs/auxiliary_params.pt
Binary file not shown.
Binary file not shown.
829 changes: 0 additions & 829 deletions notebooks/tomography/tomo_01.ipynb

This file was deleted.

File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions tutorials/tomography/hpc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# HPC (NERSC) Tomography Reconstructions

Included in this folder are two files:

- `run.sh`: Initializes all necessary parameters for `torch` to see all gpus across nodes using `torchrun`.
- `tomography_recon.py`: Contains the full reconstruction script; similar to `Scripts/tomography_02_full.py`
12 changes: 12 additions & 0 deletions tutorials/tomography/hpc/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1)
export MASTER_PORT=29500
export OMP_NUM_THREADS=8
ml nccl/2.24.3
ml conda
ml nccl
conda activate /global/common/software/mxxxx/'INSERT USER HERE'/conda/quantem


srun -l torchrun --nnodes=$SLURM_JOB_NUM_NODES --nproc-per-node=$SLURM_GPUS_PER_NODE --rdzv-backend=c10d --rdzv-endpoint=$MASTER_ADDR:$MASTER_PORT tomography_recon.py
21 changes: 21 additions & 0 deletions tutorials/tomography/hpc/run_job.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
#SBATCH -A mxxxx
#SBATCH -C gpu
#SBATCH -q regular
#SBATCH -t 4:00:00
#SBATCH -N 4
#SBATCH --ntasks-per-node=1
#SBATCH -c 128
#SBATCH --gpus-per-node=4
#SBATCH --gpu-bind=none
#SBATCH --mail-type=begin,end,fail
#SBATCH --mail-user=xxx@xxx.xxx

export MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1)
export MASTER_PORT=29500
export OMP_NUM_THREADS=8
ml nccl/2.24.3
ml conda
ml nccl
conda activate /global/common/software/mxxxx/'INSERT USER HERE'/conda/quantem
srun -l torchrun --nnodes=$SLURM_JOB_NUM_NODES --nproc-per-node=$SLURM_GPUS_PER_NODE --rdzv-backend=c10d --rdzv-endpoint=$MASTER_ADDR:$MASTER_PORT tomography_recon.py
131 changes: 131 additions & 0 deletions tutorials/tomography/hpc/tomography_recon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
from quantem.tomography.tomography import TomographyConventional, Tomography
from quantem.tomography.dataset_models import TomographyPixDataset, TomographyINRDataset, TomographyINRPretrainDataset
from quantem.tomography.object_models import ObjectINR, ObjectPixelated
from quantem.tomography.logger_tomography import LoggerTomography
from quantem.core.ml.inr import HSiren
import numpy as np

from quantem.tomography.utils import fourier_cropping
from quantem.core.visualization import show_2d
import torch

"""
Example script to run the tomography reconstruction on HPC (NERSC).

- Major difference is not needing to specify the device, as it will be automatically set by the DDP framework.

*Cedric Lim, 2/2/26*
"""


# Load Phantom Dataset
tilt_series = np.load('../../../data/tilt_series.npy')
tilt_angles = np.load('../../../data/tilt_angles.npy')

tilt_series = np.array([fourier_cropping(img, (100, 100)) for img in tilt_series]) # Cropped down to 100x100 for speed

dset = TomographyINRDataset(
tilt_stack = tilt_series,
tilt_angles = tilt_angles,
)

# Initialize INR Model
model = HSiren(alpha = 1, winner_initialization = True)

# Initialize INR Object
obj_inr = ObjectINR(
shape = (100, 100, 100),
model = model,
)

# Define a logger
logger = LoggerTomography(
log_dir = "../../../outputs/tomography/tutorial_02_scripts/",
run_prefix = "inr_tomography_warmup_cosineanneal_hpc",
run_suffix = "",
log_images_every = 2,
)

# Initialize INR-Based Tomography Object
tomo_inr = Tomography(
dset = dset,
obj_model = obj_inr,
logger = logger,
)

# Define optimizer and scheduler parameters - only optimizing the object.

optimizer_params = {
"object": {
"type": "adam",
"lr": 5e-4,
},
}

scheduler_params = {
"object": {
"type": "linear",
},
}

# Define constraints

constraints = {
"tv_vol": 5e-7,
"positivity": True,
}

# Warmup Schedule for 10 epochs

num_samples_per_ray = [
(0, 20),
(1, 20),
(2, 40),
(3, 40),
(4, 60),
(4, 60),
(6, 80),
(7, 80),
(8, 100),
(9, 100),
]

tomo_inr.reconstruct(
num_iter = 10,
optimizer_params = optimizer_params,
scheduler_params = scheduler_params,
constraints = constraints,
num_samples_per_ray = num_samples_per_ray,
num_workers = 32,
)


# Initialzie pose optimizer

optimizer_params = {
"pose": {
"type": "adam",
"lr": 1e-2,
}
}

# Define new schedulers for both optimizers using CosineAnnealing
scheduler_params = {
"object": {
"type": "cosine_annealing",
},
"pose": {
"type": "cosine_annealing",
}
}

# Reconstruct

tomo_inr.reconstruct(
num_iter = 100,
optimizer_params = optimizer_params,
scheduler_params = scheduler_params,
num_samples_per_ray = 100,
)


685 changes: 685 additions & 0 deletions tutorials/tomography/notebooks/tomography_01_lite.ipynb

Large diffs are not rendered by default.

1,307 changes: 1,307 additions & 0 deletions tutorials/tomography/notebooks/tomography_02_full.ipynb

Large diffs are not rendered by default.

Empty file.
52 changes: 52 additions & 0 deletions tutorials/tomography/scripts/tomography_01_lite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from quantem.tomography.dataset_models import TomographyPixDataset, TomographyINRDataset
from quantem.tomography.tomography_lite import TomographyLiteConv, TomographyLiteINR
import numpy as np
from quantem.core.visualization import show_2d

from quantem.tomography.utils import fourier_cropping

"""
Example script to run the lite version of the INR-based tomography pipeline.

*Cedric Lim, 2/1/26*
"""

# Load Phantom Dataset
tilt_series = np.load('../../../data/tilt_series.npy')
tilt_angles = np.load('../../../data/tilt_angles.npy')

# Fourier crop
tilt_series = np.array([fourier_cropping(img, (100, 100)) for img in tilt_series]) # Cropped down to 100x100 for speed

# Initialize dataset
dset = TomographyINRDataset(
tilt_stack = tilt_series,
tilt_angles = tilt_angles,
)

# Initialize tomography object
tomography_inr = TomographyLiteINR.from_dataset(
dset,
device = 'cuda:0',
log_dir = '../../../outputs/tomography/tutorial_01_scripts/tomo_inr_lite',
log_images_every = 2,
)


constraints = {
"positivity": True,
"tv_vol": 1e-6,
}

tomography_inr.reconstruct(
num_iter = 50,
# reset = True,
obj_lr = 1e-4,
pose_lr = 1e-2,
batch_size = 1024,
num_workers = 32,
learn_pose = True,
scheduler_type = "cosine_annealing",
constraints = constraints,
)

132 changes: 132 additions & 0 deletions tutorials/tomography/scripts/tomography_02_full.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
from quantem.tomography.tomography import TomographyConventional, Tomography
from quantem.tomography.dataset_models import TomographyPixDataset, TomographyINRDataset, TomographyINRPretrainDataset
from quantem.tomography.object_models import ObjectINR, ObjectPixelated
from quantem.tomography.logger_tomography import LoggerTomography
from quantem.core.ml.inr import HSiren
import numpy as np

from quantem.tomography.utils import fourier_cropping
from quantem.core.visualization import show_2d
import torch

"""
Example script to run the full version of the INR-based tomography pipeline. In this case, doing the full warmup procedure to cosine annealing.

*Cedric Lim, 2/1/26*
"""

device = "cuda:2"

# Load Phantom Dataset
tilt_series = np.load('../../../data/tilt_series.npy')
tilt_angles = np.load('../../../data/tilt_angles.npy')

tilt_series = np.array([fourier_cropping(img, (100, 100)) for img in tilt_series]) # Cropped down to 100x100 for speed

dset = TomographyINRDataset(
tilt_stack = tilt_series,
tilt_angles = tilt_angles,
)

# Initialize INR Model
model = HSiren(alpha = 1, winner_initialization = True)

# Initialize INR Object
obj_inr = ObjectINR(
shape = (100, 100, 100),
device = device,
model = model,
)

# Define a logger
logger = LoggerTomography(
log_dir = "../../../outputs/tomography/tutorial_02_scripts/",
run_prefix = "inr_tomography_warmup_cosineanneal",
run_suffix = "",
log_images_every = 2,
)

# Initialize INR-Based Tomography Object
tomo_inr = Tomography(
dset = dset,
obj_model = obj_inr,
device = device,
logger = logger,
)

# Define optimizer and scheduler parameters - only optimizing the object.

optimizer_params = {
"object": {
"type": "adam",
"lr": 1e-4,
},
}

scheduler_params = {
"object": {
"type": "linear",
},
}

# Define constraints

constraints = {
"tv_vol": 5e-7,
"positivity": True,
}

# Warmup Schedule for 10 epochs

num_samples_per_ray = [
(0, 20),
(1, 20),
(2, 40),
(3, 40),
(4, 60),
(4, 60),
(6, 80),
(7, 80),
(8, 100),
(9, 100),
]

tomo_inr.reconstruct(
num_iter = 10,
optimizer_params = optimizer_params,
scheduler_params = scheduler_params,
constraints = constraints,
num_samples_per_ray = num_samples_per_ray,
num_workers = 32,
)


# Initialzie pose optimizer

optimizer_params = {
"pose": {
"type": "adam",
"lr": 1e-2,
}
}

# Define new schedulers for both optimizers using CosineAnnealing
scheduler_params = {
"object": {
"type": "cosine_annealing",
},
"pose": {
"type": "cosine_annealing",
}
}

# Reconstruct

tomo_inr.reconstruct(
num_iter = 20,
optimizer_params = optimizer_params,
scheduler_params = scheduler_params,
num_samples_per_ray = 100,
)


Loading