Skip to content

Conversation

joamatab
Copy link
Contributor

@joamatab joamatab commented May 25, 2025

Fixes meep plugin

fixes #575

image

@Arthaj-Octopus
@vvahidd
@threaddy
@joelslaby
@jan-david-fischbach

Summary by Sourcery

Improve the Meep plugin by adding layer exclusion and dynamic algorithm selection, streamlining geometry processing and simulation setup, and updating example notebooks.

New Features:

  • Add exclude_layers parameter to filter out unwanted layers in get_meep_geometry_from_component
  • Allow specifying the optimization algorithm by name in run_meep_adjoint_optimizer instead of using a hardcoded constant

Enhancements:

  • Refactor geometry extraction to merge and map polygons per layer, handling LogicalLayer and DerivedLayer uniformly
  • Flatten a copied component in get_simulation rather than displaying it

Documentation:

  • Update Meep S-parameter example notebooks to include y-axis margins and bump Python kernel to 3.11

Copy link
Contributor

sourcery-ai bot commented May 25, 2025

Reviewer's Guide

This PR refactors Meep geometry extraction to support layer exclusion and robust layer handling, optimizes simulation setup by flattening on a component copy, updates the example notebook with margin parameters and kernel metadata, and modernizes the adjoint optimizer’s algorithm parameter to use string identifiers.

Sequence Diagram: Updated Meep Geometry Extraction with Layer Exclusion

sequenceDiagram
    participant Caller
    participant GMFC as "get_meep_geometry_from_component()"
    participant Component
    participant LayerStack

    Caller->>+GMFC: Call(component, layer_stack, exclude_layers, ...)
    GMFC->>Component: component.get_polygons_points(merge=True)
    Component-->>GMFC: polygons_per_layer
    GMFC->>LayerStack: Access layer_stack.layers.values()
    LayerStack-->>GMFC: levels (iterator/list)

    loop For each 'level' in levels
        GMFC->>GMFC: current_layer_tuple = Determine from level.layer / level.derived_layer.layer
        GMFC->>GMFC: current_layer_index = get_layer(current_layer_tuple)

        alt layer_index in exclude_layers OR layer_index not in polygons_per_layer
            GMFC->>GMFC: Skip layer processing (continue loop)
        else Process this layer
            GMFC->>GMFC: zmin = level.zmin
            GMFC->>GMFC: height = level.thickness
            GMFC->>GMFC: polygons = polygons_per_layer[current_layer_index]
            GMFC->>LayerStack: Get material_name for level.layer
            LayerStack-->>GMFC: material_name
            loop For each polygon in polygons
                GMFC->>GMFC: Create Meep vertices (using zmin)
                GMFC->>GMFC: Create mp.GeometricObject
                GMFC->>GMFC: Add to results list
            end
        end
    end
    GMFC-->>-Caller: List of mp.GeometricObject
Loading

Class Diagram: Modified Function Signatures in gplugins.gmeep Modules

classDiagram
    class GetMeepGeometryModule {
        <<gplugins.gmeep.get_meep_geometry>>
        +get_meep_geometry_from_component(component: any, wavelength: float, is_3d: bool, dispersive: bool, exclude_layers: LayerSpecs | None, **kwargs) list~mp.GeometricObject~
    }
    class MeepAdjointOptimizationModule {
        <<gplugins.gmeep.meep_adjoint_optimization>>
        +run_meep_adjoint_optimizer(..., algorithm: str, ...) any
    }
Loading

File-Level Changes

Change Details Files
Refactor get_meep_geometry to support exclude_layers and robust layer handling
  • Add exclude_layers parameter and default to empty list
  • Pre-calculate polygons_per_layer from component
  • Replace manual layer loop with traversal of layer_stack.layers handling LogicalLayer and DerivedLayer
  • Filter out layers in exclude_layers and those without polygons
  • Remove debug prints and commented code
  • Use shapely.geometry.Polygon for consistent vertex extraction
gplugins/gmeep/get_meep_geometry.py
Adjust simulation setup to flatten on a copied component
  • Copy component_extended before flattening
  • Call flatten() on the copied component
  • Remove component_extended.show() and obsolete commented lines
gplugins/gmeep/get_simulation.py
Update notebook parameters and metadata for s-parameter examples
  • Add ymargin_top=3 and ymargin_bot=3 in write_sparameters_meep calls
  • Update kernel display_name to "mp311"
  • Bump Python version in metadata to 3.11.9
notebooks/meep_01_sparameters.ipynb
Modernize meep_adjoint_optimization algorithm parameter handling
  • Change algorithm parameter type from int to string
  • Import nlopt inside the function
  • Convert algorithm string to nlopt constant via getattr
gplugins/gmeep/meep_adjoint_optimization.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @joamatab - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟡 General issues: 5 issues found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

wavelength: float = 1.55,
is_3d: bool = False,
dispersive: bool = False,
exclude_layers: LayerSpecs | None = None,
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Clarify exclude_layers type and usage

Consider renaming the parameter to exclude_layer_indices: Sequence[int] or converting it to set[int] for clearer intent and improved performance.

Suggested implementation:

    exclude_layer_indices: Sequence[int] | None = None,
) -> list[mp.GeometricObject]:
    """Returns Meep geometry from a gdsfactory component.

    Args:
        exclude_layer_indices: Sequence of layer indices to exclude from geometry generation.
        kwargs: settings.

    """
    component = gf.get_component(component=component, **kwargs)
    polygons_per_layer = component.get_polygons_points(merge=True)
    layer_stack = layer_stack or get_layer_stack()

    layer_to_thickness = layer_stack.get_layer_to_thickness()

    # Convert exclude_layer_indices to set for fast lookup, if provided
    exclude_layer_indices_set = set(exclude_layer_indices) if exclude_layer_indices is not None else set()
  • You will need to update all logic in the function that previously checked for excluded layers using exclude_layers to now use exclude_layer_indices_set. For example, if you have code like if layer in exclude_layers:, change it to if layer in exclude_layer_indices_set:.
  • Make sure to update any function calls or references to the old parameter name in the rest of the file and in any calling code.
  • If the function is part of a public API, update any relevant documentation or type hints elsewhere in the codebase.


geometry = []
exclude_layers = exclude_layers or []
layer_to_polygons = component_with_booleans.get_polygons_points()
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Remove unused layer_to_polygons assignment

Since layer_to_polygons is not used after introducing polygons_per_layer, removing it will make the code cleaner.

Comment on lines 84 to 87
for polygon in polygons:
p = shapely.geometry.Polygon(polygon)
vertices = [mp.Vector3(p[0], p[1], zmin_um) for p in polygon]
material_name = layer_to_material[layer]
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Unnecessary shapely Polygon construction

Since p is not used, consider removing its instantiation to avoid unnecessary computation.

Suggested change
for polygon in polygons:
p = shapely.geometry.Polygon(polygon)
vertices = [mp.Vector3(p[0], p[1], zmin_um) for p in polygon]
material_name = layer_to_material[layer]
for polygon in polygons:
vertices = [mp.Vector3(p[0], p[1], zmin_um) for p in polygon]
material_name = layer_to_material[layer]


layer_index = int(get_layer(layer_tuple))

if layer_index in exclude_layers:
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (performance): Optimize exclude_layers membership checks

Consider converting exclude_layers to a set before the loop to improve membership test performance for large collections.

Suggested implementation:

        layer_index = int(get_layer(layer_tuple))

        # Convert exclude_layers to a set for faster membership checks
        if not isinstance(exclude_layers, set):
            exclude_layers_set = set(exclude_layers) if exclude_layers is not None else set()
        else:
            exclude_layers_set = exclude_layers

        if layer_index in exclude_layers_set:
            continue

You should ensure that the initialization of exclude_layers_set happens outside the loop that contains this code, so the conversion to a set is not repeated on every iteration. If this code is inside a loop, move the conversion to just before the loop starts, and use exclude_layers_set in the loop body.

update_variable: np.ndarray,
maximize_cost_function: bool = True,
algorithm: int = nlopt.LD_MMA,
algorithm: str = "LD_MMA",
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion: Rename algorithm parameter to reflect new string usage

Consider renaming the parameter to algorithm_name to clarify that it now expects a string, not an algorithm object.

Suggested implementation:

    algorithm_name: str = "LD_MMA",
    algorithm = getattr(nlopt, algorithm_name)
    solver = nlopt.opt(algorithm, number_of_params)

@joamatab joamatab merged commit 2ac8520 into main May 25, 2025
12 of 14 checks passed
@joamatab joamatab deleted the fix_meep branch May 25, 2025 14:59
@sourcery-ai sourcery-ai bot mentioned this pull request May 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

gmeep.write_sparameters_meep not implementing geometry.
1 participant