Skip to content

Commit

Permalink
Merge pull request #112 from PolarizedLightFieldMicroscopy/mbl_2024
Browse files Browse the repository at this point in the history
MBL September 2024
  • Loading branch information
gschlafly authored Oct 2, 2024
2 parents faa1609 + 0a337c3 commit 4db3910
Show file tree
Hide file tree
Showing 37 changed files with 792 additions and 549 deletions.
9 changes: 8 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,11 @@
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.testing.autoTestDiscoverOnSaveEnabled": true,
}
"files.exclude": {
"**/__pycache__/": true,
"**/*.pyc": true,
"**/*.pyo": true,
".pytest_cache/": true
},
"editor.wordWrap": "on", // Wrap long lines
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![python versions](https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)
[![Run Pytest](https://github.com/PolarizedLightFieldMicroscopy/forward-model/actions/workflows/pytest-action.yml/badge.svg)](https://github.com/PolarizedLightFieldMicroscopy/forward-model/actions/workflows/pytest-action.yml)
# GeoBirT
# BirTomo: Birefringence Tomography
Polarized light field microscopy forward model and inverse model using geometrical optics and Jones Calculus.

## Installation
Expand Down
2 changes: 1 addition & 1 deletion config/iter_config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"n_epochs": 100,
"num_iterations": 100,
"regularization_weight": 0.1,
"lr": 1e-3,
"lr_birefringence": 1e-3,
Expand Down
5 changes: 3 additions & 2 deletions config/iter_config_sphere.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"n_epochs": 200,
"num_iterations": 200,
"regularization_weight": 0.5,
"lr": 1e-3,
"lr_birefringence": 1e-3,
Expand All @@ -13,11 +13,12 @@
["birefringence active negative penalty", 1000],
["birefringence mask", 0]
],
"nerf_mode": false,
"from_simulation": true,
"vox_indices_by_mla_idx_path": "",
"mla_rays_at_once": true,
"two_optic_axis_components": true,
"free_memory_by_del_large_arrays": true,
"free_memory_by_del_large_arrays": false,
"save_rays": false,
"save_freq": 20,
"output_posfix": "",
Expand Down
16 changes: 0 additions & 16 deletions config/optical_config1.json

This file was deleted.

16 changes: 0 additions & 16 deletions config/optical_config2.json

This file was deleted.

16 changes: 0 additions & 16 deletions config/optical_config3.json

This file was deleted.

16 changes: 0 additions & 16 deletions config/optical_config_sphere.json

This file was deleted.

16 changes: 0 additions & 16 deletions config/optical_config_voxel.json

This file was deleted.

Binary file removed data/xylem/mla65/azimuth.tif
Binary file not shown.
Binary file removed data/xylem/mla65/retardance.tif
Binary file not shown.
94 changes: 94 additions & 0 deletions examples/reconstruction_basic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# %% Importing necessary libraries
import os
import numpy as np
import torch
from VolumeRaytraceLFM.abstract_classes import BackEnds
from VolumeRaytraceLFM.simulations import ForwardModel
from VolumeRaytraceLFM.birefringence_implementations import BirefringentVolume
from VolumeRaytraceLFM.volumes import volume_args
from VolumeRaytraceLFM.setup_parameters import (
setup_optical_parameters,
setup_iteration_parameters,
)
from VolumeRaytraceLFM.reconstructions import ReconstructionConfig, Reconstructor
from VolumeRaytraceLFM.utils.file_utils import (
create_unique_directory,
)

# %% Configuration paramters to be changed
simulate = True

# Volume creation arguments, see src/VolumeRaytraceLFM/volumes/volume_args.py for more options
volume_gt_creation_args = volume_args.voxel_args
volume_initial_creation_args = volume_args.random_pos_args

# Paths to the optical and iteration configuration files
optical_config_file = os.path.join("..", "config", "optical_config_voxel.json")
iter_config_file = os.path.join("..", "config", "iter_config_reg.json")

# Path to the directory where the reconstruction will be saved
recon_output_dir = os.path.join("..", "reconstructions", "voxel")
recon_output_dir_postfix = "postfix"
recon_directory = create_unique_directory(recon_output_dir, postfix=recon_output_dir_postfix)

# Whether to continue a previous reconstruction
continue_recon = False
recon_file_path = r"to be alterned.h5"

# For loading forward images that were saved in a previous reconstruction folder
measurement_dir = os.path.join(recon_output_dir, "to be altered")

BACKEND = BackEnds.PYTORCH
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")

print(f"Using device: {DEVICE}")

# %% Simulate or load forward images
optical_info = setup_optical_parameters(optical_config_file)

if simulate:
optical_system = {"optical_info": optical_info}
simulator = ForwardModel(optical_system, backend=BACKEND)
volume_GT = BirefringentVolume(
backend=BACKEND,
optical_info=optical_info,
volume_creation_args=volume_gt_creation_args,
)
simulator.forward_model(volume_GT)
simulator.view_images()
ret_image_meas = simulator.ret_img.detach().numpy()
azim_image_meas = simulator.azim_img.detach().numpy()
else:
ret_image_meas = np.load(os.path.join(measurement_dir, "ret_image.npy"))
azim_image_meas = np.load(os.path.join(measurement_dir, "azim_image.npy"))
volume_GT = None

# %% Run reconstruction
recon_optical_info = optical_info.copy()
iteration_params = setup_iteration_parameters(iter_config_file)
if continue_recon:
initial_volume = BirefringentVolume.init_from_file(recon_file_path, BACKEND, recon_optical_info)
else:
initial_volume = BirefringentVolume(
backend=BACKEND,
optical_info=recon_optical_info,
volume_creation_args=volume_initial_creation_args,
)
recon_config = ReconstructionConfig(
recon_optical_info,
ret_image_meas,
azim_image_meas,
initial_volume,
iteration_params,
gt_vol=volume_GT
)
recon_config.save(recon_directory)
reconstructor = Reconstructor(
recon_config,
output_dir=recon_directory,
device=DEVICE
)
reconstructor.reconstruct(plot_live=True)
print("Reconstruction complete")

# %%
10 changes: 7 additions & 3 deletions examples/simulation_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@
from VolumeRaytraceLFM.birefringence_implementations import BirefringentVolume
from VolumeRaytraceLFM.volumes import volume_args
from VolumeRaytraceLFM.setup_parameters import setup_optical_parameters
from VolumeRaytraceLFM.visualization.plotting_volume import visualize_volume

# %% Setting up the optical system
BACKEND = BackEnds.PYTORCH
optical_info = setup_optical_parameters("../config/optical_config_sphere.json")
optical_info = setup_optical_parameters("config/optical_config_sphere.json")
optical_system = {"optical_info": optical_info}
print(optical_info)

# %% Create the simulator and volume
simulator = ForwardModel(optical_system, backend=BACKEND)
volume = BirefringentVolume(
backend=BACKEND,
optical_info=optical_info,
volume_creation_args=volume_args.sphere_args2,
volume_creation_args=volume_args.shell_small_args,
)
plotly_figure = volume.plot_lines_plotly(draw_spheres=True)
plotly_figure.show()

# %% Image the volume
simulator = ForwardModel(optical_system, backend=BACKEND)
simulator.rays.prepare_for_all_rays_at_once()
start_time = time.perf_counter()
simulator.rays.reset_timing_info()
Expand Down
7 changes: 3 additions & 4 deletions src/VolumeRaytraceLFM/abstract_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,8 @@ def rays_through_vol(pixels_per_ml, naObj, nMedium, volume_ctr_um):
pixel behind each lenslet
naObj (float): numerical aperture of the objective lens
nMedium (float): refractive index of the volume
volume_ctr_um (np.array): 3D vector containing the coordinates of the center of the
volume in volume space units (um)
volume_ctr_um (np.array): 3D vector containing the coordinates of the center
of the volume in volume space units (um)
Returns:
ray_enter (np.array): (3, X, X) array where (3, i, j) gives the coordinates
within the volume ray entrance plane for which the
Expand Down Expand Up @@ -909,8 +909,7 @@ def _filter_invalid_rays(
)

def compute_ray_collisions(self, ray_enter, ray_exit, voxel_size_um, vol_shape):
"""
Computes parameters for collisions of rays with voxels.
"""Computes parameters for collisions of rays with voxels.
For each ray defined by start (ray_enter) and end (ray_exit) points,
calculates the intersected voxels and lengths of intersections within
a volume of given shape (vol_shape) and voxel size (voxel_size_um).
Expand Down
Loading

0 comments on commit 4db3910

Please sign in to comment.