PolarizedLightFieldMicroscopy / GeoBirT

Geometrical Birefringence Tomography
BSD 3-Clause "New" or "Revised" License
4 stars 2 forks source link

Artifacts with 3 microlenses #90

Open gschlafly opened 4 months ago

gschlafly commented 4 months ago

Description

When simulating the images of a birefringent voxel centered within the volume, the retardance should only be nonzero behind the central microlens. Moreover, since the optic axis of the birefringent voxel is oriented in line with the microscope axis, the retardance image should have circular symmetry.

Symmetry

There is not circular symmetry when using 3x3 microlenses. There are a few hot spots in the bottom left quadrant. Interestingly, there is circular symmetry for 1x1 and 5x5 microlenses.

Containment within central microlens

Through trial and error, I observed that any n_medium < 1.62 causes there to be nonzero retardance outside of the central microlens. The angles for which each ray is calculated for each pixel behind the detector is calculated here: https://github.com/PolarizedLightFieldMicroscopy/GeoBirT/blob/0d153919a07b5a28a94039c23686a8bffd0ae513/VolumeRaytraceLFM/abstract_classes.py#L369-L421

Screenshots

image

Files

To Reproduce

With either numpy or pytorch backend, run the following simulation code:

optical_info = setup_optical_parameters(
    "config_settings/optical_config_voxel.json")
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_args.voxel_args
)
simulator.forward_model(volume_GT)
simulator.view_images()

with the optical_config_voxel.json containing the following parameters:

{
    "volume_shape"      : [3, 7, 7],
    "axial_voxel_size_um"     : 1.0,
    "cube_voxels"       : true,
    "pixels_per_ml"     : 17,
    "n_micro_lenses"    : 3,
    "n_voxels_per_ml"   : 1,
    "M_obj"             : 60,
    "na_obj"            : 1.2,
    "n_medium"          : 1.35,
    "wavelength"        : 0.550,
    "camera_pix_pitch"  : 6.5,
    "polarizer"         : [[1, 0], [0, 1]],
    "analyzer"          : [[1, 0], [0, 1]],
    "polarizer_swing"   : 0.03
}

Tasks

gschlafly commented 4 months ago

Strangely, the 3x3 microlens case also does not have all rays passing through a single voxel. It fails the following test while the other microlens options pass: https://github.com/PolarizedLightFieldMicroscopy/GeoBirT/blob/5b45f5a1711c4827932a9573b1c5e749ddcb2f12/tests/test_raytrace_voxels.py#L19-L30

gschlafly commented 2 months ago

Locally the test test_identify_voxels_repeated_zero_ret_empty_list() with the 3x3 MLA passes, but it fails with the github action. The number of voxels calculated is 70 instead of the intended 71 voxels.

gschlafly commented 2 months ago

Locally the test test_identify_voxels_repeated_zero_ret_empty_list() with the 3x3 MLA passes, but it fails with the github action. The number of voxels calculated is 70 instead of the intended 71 voxels.

In the github pytest, the voxel index 105 is only counted once instead of twice: https://github.com/PolarizedLightFieldMicroscopy/GeoBirT/blob/9a039d52e5620ca5107a025304c3def5b92c85ee/tests/test_indexing.py#L81

print("DEBUG: ", sorted([(key, count) for key, count in counts.items()])) gives the following output:

[(20, 15), (21, 46), (22, 59), (23, 43), (24, 13), (29, 45), (30, 148), (31, 166), (32, 144), (33, 39), (38, 57), (39, 166), (40, 111), (41, 161), (42, 47), (47, 43), (48, 143), (49, 161), (50, 139), (51, 33), (56, 14), (57, 40), (58, 48), (59, 33), (60, 8), (101, 1), (102, 17), (103, 16), (104, 17), (105, 1), (110, 16), (111, 205), (112, 194), (113, 209), (114, 19), (119, 13), (120, 194), (121, 1), (122, 197), (123, 16), (128, 16), (129, 206), (130, 194), (131, 209), (132, 19), (137, 1), (138, 17), (139, 16), (140, 17), (141, 1), (182, 12), (183, 41), (184, 44), (185, 41), (186, 12), (191, 41), (192, 146), (193, 161), (194, 137), (195, 31), (200, 44), (201, 164), (202, 152), (203, 160), (204, 34), (209, 41), (210, 140), (211, 157), (212, 131), (213, 26), (218, 12), (219, 34), (220, 34), (221, 29), (222, 6)] Perhaps the counts for other voxels differ too!