Skip to content

Conversation

@singer-yang
Copy link
Owner

  1. Add a tutorial demo to visualize multi-order diffraction
  2. Refactor diffractive surface functions

@cursor
Copy link

cursor bot commented Dec 31, 2025

You have run out of free Bugbot PR reviews for this billing cycle. This will reset on January 7.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a multi-order diffraction visualization demo and refactors diffractive surface functions for improved code organization and extensibility. The changes introduce a new Grating DOE class for simulating linear grating diffraction patterns and standardize the API across all diffractive optical elements.

Key changes:

  • Adds a new Grating diffractive optical element for linear grating patterns with configurable angle and phase gradient strength
  • Refactors diffractive surface methods by renaming _phase_map0() to phase_func() and introducing quantization support via a new diff_quantize autograd function
  • Adds fab_step parameter across all DOE classes for better fabrication control

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
deeplens/optics/utils.py Adds diff_quantize autograd function for differentiable quantization using Straight-Through Estimator; removes unused torch.nn import
deeplens/optics/diffractive_surface/diffractive.py Refactors phase calculation methods (_phase_map0()phase_func()), adds fab_step parameter, integrates quantization, simplifies visualization methods, and marks computed fields with parentheses in surf_dict()
deeplens/optics/diffractive_surface/grating.py New Grating DOE class implementing linear phase gradient for multi-order diffraction with configurable angle (theta) and gradient strength (alpha)
deeplens/optics/diffractive_surface/zernike.py Updates to use new phase_func() method, adds fab_step parameter, and refactors init_from_dict() for cleaner parameter handling
deeplens/optics/diffractive_surface/thinlens.py Updates to use new phase_func() method, adds fab_step parameter, and refactors init_from_dict()
deeplens/optics/diffractive_surface/pixel2d.py Updates to use new phase_func() method, adds fab_step parameter, and refactors init_from_dict()
deeplens/optics/diffractive_surface/fresnel.py Updates to use new phase_func() method, adds fab_step parameter, and refactors init_from_dict()
deeplens/optics/diffractive_surface/binary2.py Updates to use new phase_func() method, adds fab_step parameter, and refactors init_from_dict()
deeplens/optics/diffractive_surface/init.py Adds Grating to module exports
deeplens/hybridlens.py Adds support for loading Grating DOE from JSON configuration using "type" field instead of "param_model"
datasets/lenses/hybridlens/a489_grating.json Configuration file for A489 lens with linear grating DOE for multi-order diffraction demonstrations
8_multi_order_diffraction.py Demo script visualizing multi-order diffraction PSF patterns from a hybrid lens with grating, showing both linear and log-scale plots for multiple wavelengths

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

doe = Grating.init_from_dict(doe_dict)
else:
raise ValueError(
f"Unsupported DOE parameter model: {doe_dict['param_model']}"
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message references 'doe_dict["param_model"]' but the code now uses 'doe_dict["type"]' (line 77). The error message should be updated to reference the correct dictionary key for consistency.

Suggested change
f"Unsupported DOE parameter model: {doe_dict['param_model']}"
f"Unsupported DOE parameter model: {doe_param_model}"

Copilot uses AI. Check for mistakes.
fab_step=doe_dict.get("fab_step", 16),
)

def get_phase_map(self, wvln=0.55):
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ThinLens.get_phase_map method has a default parameter value 'wvln=0.55', but the parent class DiffractiveSurface.get_phase_map now requires 'wvln' without a default. This creates an inconsistency in the API. Either remove the default from ThinLens to match the parent class signature, or add it back to the parent class if a default is desired.

Suggested change
def get_phase_map(self, wvln=0.55):
def get_phase_map(self, wvln):

Copilot uses AI. Check for mistakes.
@staticmethod
def forward(ctx, x, levels, interval=2 * torch.pi):
step = interval / levels
ctx.step = step
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable 'ctx.step' is saved in the forward pass but never used in the backward pass. Since the Straight-Through Estimator simply passes gradients through unchanged, this variable can be removed to avoid unnecessary state storage.

Suggested change
ctx.step = step

Copilot uses AI. Check for mistakes.
Comment on lines +60 to +61
self.theta = torch.tensor(theta) # angle from y-axis to grating vector
self.alpha = torch.tensor(alpha) # slope of the grating
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tensors for theta and alpha are created without specifying the device parameter, then the object is moved to device later with self.to(device). For consistency and to avoid potential device mismatch issues, these tensors should be created with the device parameter directly: torch.tensor(theta, device=device).

Suggested change
self.theta = torch.tensor(theta) # angle from y-axis to grating vector
self.alpha = torch.tensor(alpha) # slope of the grating
self.theta = torch.tensor(theta, device=device) # angle from y-axis to grating vector
self.alpha = torch.tensor(alpha, device=device) # slope of the grating

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +58
axes[0].axvline(
x=len(psf_center) // 2,
color="red",
linestyle="--",
alpha=0.5,
label="Center",
)
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The axvline is created with a label="Center" parameter after the legend has already been created (line 50). This means the "Center" label will not appear in the legend. Either remove the label parameter from axvline (since it's self-explanatory as a visual guide), or move the legend() call to after the axvline if the label should be included in the legend.

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +79
axes[1].axvline(
x=len(psf_center) // 2,
color="red",
linestyle="--",
alpha=0.5,
label="Center",
)
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The axvline is created with a label="Center" parameter after the legend has already been created (line 71). This means the "Center" label will not appear in the legend. Either remove the label parameter from axvline (since it's self-explanatory as a visual guide), or move the legend() call to after the axvline if the label should be included in the legend.

Copilot uses AI. Check for mistakes.
from .zernike import Zernike

__all__ = ["DOE", "Fresnel", "Pixel2D", "ThinLens", "Zernike", "Binary2"]
__all__ = ["DOE", "Fresnel", "Grating", "Pixel2D", "ThinLens", "Zernike", "Binary2"]
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name 'DOE' is exported by all but is not defined.

Suggested change
__all__ = ["DOE", "Fresnel", "Grating", "Pixel2D", "ThinLens", "Zernike", "Binary2"]
__all__ = ["DiffractiveSurface", "Fresnel", "Grating", "Pixel2D", "ThinLens", "Zernike", "Binary2"]

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants