gplugins 0.10.2__tar.gz → 0.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gplugins-0.10.2 → gplugins-0.12.0}/PKG-INFO +9 -7
- {gplugins-0.10.2 → gplugins-0.12.0}/README.md +1 -1
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/__init__.py +1 -1
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/add_simulation_markers.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/async_helpers.py +5 -3
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/disable_print.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/get_component_with_net_layers.py +3 -3
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/optical_constants.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/parse_layer_stack.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/devsim/get_simulation_xsection.py +2 -3
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/femwell/solve_thermal.py +6 -6
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/get_simulation.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/get_simulation_grating_farfield.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/write_sparameters_grating.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/parse_component.py +20 -19
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/parse_gds.py +2 -1
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/dataprep/regions.py +3 -6
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/samples/drc_errors.py +24 -19
- gplugins-0.12.0/gplugins/klayout/netlist_graph.py +137 -0
- gplugins-0.12.0/gplugins/klayout/netlist_spice_reader.py +117 -0
- gplugins-0.12.0/gplugins/klayout/plot_nets.py +100 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_netlist_spice_reader.py +11 -6
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_plot_nets.py +5 -6
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/lumerical/write_sparameters_lumerical.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/lumerical/write_sparameters_lumerical_components.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/find_modes.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/find_modes_cross_section.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/neff_convergence_test.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/path_length_analysis/path_length_analysis.py +2 -2
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/implant_tables.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/pysrim.py +1 -3
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/silicon.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/models.py +173 -13
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/read.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/tests/test_mzi.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/tests/test_mzi_lattice.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/component.py +8 -8
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/get_simulation_grating_coupler.py +1 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/pyproject.toml +9 -7
- gplugins-0.10.2/gplugins/klayout/netlist_spice_reader.py +0 -16
- gplugins-0.10.2/gplugins/klayout/plot_nets.py +0 -188
- {gplugins-0.10.2 → gplugins-0.12.0}/LICENSE +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/base_models/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/base_models/component.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/base_models/simulation.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/config.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/types.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/cache.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/convert_sparameters.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/get_capacitance.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/get_component_with_local_layers.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/get_effective_indices.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/get_scattering.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/get_sparameters_path.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/plot.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/plot_csv.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/port_symmetries.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/common/utils/tests/test_get_component_with_new_port_layers.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/dagster/Makefile +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/dagster/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/dagster/workflow.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/devsim/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/devsim/doping.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/devsim/get_simulation.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/devsim/get_solver.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/devsim/test_devsim.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/elmer/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/elmer/electrostatic.sif.j2 +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/elmer/get_capacitance.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/elmer/tests/test_elmer.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/fdtdz/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/fdtdz/get_epsilon_fdtdz.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/fdtdz/get_ports_fdtdz.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/fdtdz/get_sparameters_fdtdz.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/femwell/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/femwell/mode_solver.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/femwell/test_mode_solver.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/get_material.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/get_meep_geometry.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/get_port_eigenmode.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/get_simulation_grating_fiber.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/meep_adjoint_optimization.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_eigenmode.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_materials.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_sparameterNxN/test_sparameterNxN_crossing.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_sparameterNxN/test_sparameterNxN_straight.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameterNxN_crossing.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameterNxN_straight.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameterNxN_symmetries_straight.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameter_straight_mpi.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameter_straight_mpi_pool.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameters_crossing_symmetric.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameters_straight.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameters_straight_batch.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameters_straight_mpi.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameters_straight_mpi_pool.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep/test_sparameters_straight_symmetric.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/test_write_sparameters_meep.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/write_sparameters_meep.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/write_sparameters_meep_batch.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmeep/write_sparameters_meep_mpi.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/define_polysurfaces.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/get_mesh.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/tests/test_custom_names.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/tests/test_meshing_2D.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/tests/test_meshing_3D.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/uz_xsection_mesh.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/xy_xsection_mesh.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/gmsh/xyz_mesh.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/dataprep/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/check_duplicated_cells.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/check_exclusion.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/check_inclusion.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/check_space.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/check_width.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/count_drc.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/write_connectivity.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/drc/write_drc.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/get_density.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/get_netlist.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_dataprep_regions.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_density.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_drc_exclusion.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_drc_inclusion.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_drc_space.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_drc_width.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_geometry_write_connectivity.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/klayout/tests/test_global_density.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/lumerical/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/lumerical/interconnect.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/lumerical/read.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/lumerical/settings.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/lumerical/tests/test_lumerical_read_sparameters.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/materials/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/materials/inorganic.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/materials/optical/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/materials/optical/optical_mat.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/materials/optical/refractive_index_info.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/materials/semiconductor/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/materials/semiconductor/semiconductor_mat.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/meow/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/meow/meow_eme.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/meow/test_meow_simulation.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/coupler.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/find_coupling_vs_gap.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/find_mode_dispersion.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/find_neff_ng_dw_dh.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/find_neff_vs_width.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/get_mode_solver_coupler.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/get_mode_solver_cross_section.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/get_mode_solver_rib.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/modes/neff_vs_width_nitride.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/modes/neff_vs_width_rib.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/modes/neff_vs_width_strip.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/neff_vs_width.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/overlap.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_dw_dh/test_dw_dh.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_dw_dh/test_dw_dh.obtained.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_dw_dh/test_dw_dh_dispersion.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_dw_dh.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_find_modes.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_find_modes_dispersion.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_neff_vs_width/test_neff_vs_width.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_neff_vs_width/test_neff_vs_width.obtained.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/tests/test_neff_vs_width.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/types.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/modes/waveguide.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/palace/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/palace/driven.json +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/palace/electrostatic.json +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/palace/get_capacitance.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/palace/get_scattering.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/palace/tests/test_palace.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/path_length_analysis/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/path_length_analysis/test_pathlength_extraction.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/photonic_circuit_models/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/photonic_circuit_models/coupler.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/photonic_circuit_models/fsr.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/photonic_circuit_models/heater.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/photonic_circuit_models/mzi.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/photonic_circuit_models/ring.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/diffusion.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/skew/antimony_si_skew.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/skew/arsenic_si_skew.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/skew/boron_si_skew.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/process/skew/phosphorus_si_skew.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/build_model.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/integrations/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/integrations/femwell_waveguide_model.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/integrations/meep_FDTD_model.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/integrations/meow_eme_model.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/interpolators.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/mlp.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/parameter.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/plot_model.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/tests/test_mzi_lattice/test_mzi_lattice.obtained.yml +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/tests/test_mzi_lattice/test_mzi_lattice.yml +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/sax/tests/test_parameters.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/schematic_editor/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/schematic_editor/circuitviz.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/schematic_editor/schematic_editor.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/get_results.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/materials.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/modes.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/test_component_modeler.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/test_materials.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/test_modes/test_sweep_width.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/test_modes/test_sweep_width.obtained.csv +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/test_modes_coupler.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/test_modes_waveguide.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/test_plot_simulation_grating_coupler.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/test_write_sparameters.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/tests_sparameters/sim_ref.yaml +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/tests_sparameters/test_simulation.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/tests_sparameters/test_write_sparameters.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/tests/tests_sparameters/test_write_sparameters_grating_coupler.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/types.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/util.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/tidy3d/write_sparameters_grating_coupler.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/vlsir/__init__.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/vlsir/export_netlist.py +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/vlsir/tests/resources/pads_correct.cir +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/vlsir/tests/resources/pads_correct.scs +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/vlsir/tests/resources/pads_correct.sp +0 -0
- {gplugins-0.10.2 → gplugins-0.12.0}/gplugins/vlsir/tests/test_vlsir.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: gplugins
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: gdsfactory plugins
|
|
5
5
|
Keywords: python
|
|
6
6
|
Author-email: gdsfactory <contact@gdsfactory.com>
|
|
@@ -46,12 +46,14 @@ Requires-Dist: shapely ; extra == "gmsh"
|
|
|
46
46
|
Requires-Dist: meshwell>=1.0.7,<=1.1 ; extra == "gmsh"
|
|
47
47
|
Requires-Dist: klayout ; extra == "klayout"
|
|
48
48
|
Requires-Dist: pyvis<=0.3.1 ; extra == "klayout"
|
|
49
|
-
Requires-Dist: jax
|
|
50
|
-
Requires-Dist: jaxlib
|
|
51
|
-
Requires-Dist:
|
|
49
|
+
Requires-Dist: jax>=0.4.26 ; extra == "meow"
|
|
50
|
+
Requires-Dist: jaxlib>=0.4.26 ; extra == "meow"
|
|
51
|
+
Requires-Dist: flax>=0.8.2 ; extra == "meow"
|
|
52
|
+
Requires-Dist: meow-sim>=0.9.0,<0.12.0 ; extra == "meow"
|
|
52
53
|
Requires-Dist: tidy3d==2.5.2 ; extra == "meow"
|
|
53
|
-
Requires-Dist: jax
|
|
54
|
-
Requires-Dist: jaxlib
|
|
54
|
+
Requires-Dist: jax>=0.4.26 ; extra == "sax"
|
|
55
|
+
Requires-Dist: jaxlib>=0.4.26 ; extra == "sax"
|
|
56
|
+
Requires-Dist: flax>=0.8.2 ; extra == "sax"
|
|
55
57
|
Requires-Dist: sax>=0.12.1,<0.13.0 ; extra == "sax"
|
|
56
58
|
Requires-Dist: scikit-learn ; extra == "sax"
|
|
57
59
|
Requires-Dist: pyvis<=0.3.1 ; extra == "sax"
|
|
@@ -75,7 +77,7 @@ Provides-Extra: schematic
|
|
|
75
77
|
Provides-Extra: tidy3d
|
|
76
78
|
Provides-Extra: vlsir
|
|
77
79
|
|
|
78
|
-
# gplugins 0.
|
|
80
|
+
# gplugins 0.12.0
|
|
79
81
|
|
|
80
82
|
[](https://gdsfactory.github.io/gplugins/)
|
|
81
83
|
[](https://pypi.org/project/gplugins/)
|
|
@@ -18,9 +18,11 @@ async def handle_return(
|
|
|
18
18
|
append: bool = False,
|
|
19
19
|
) -> None:
|
|
20
20
|
"""Reads through a :class:`StreamReader` and tees content to ``out_stream`` and ``log_file``."""
|
|
21
|
-
with
|
|
22
|
-
log_file, "a" if append else "w", encoding="utf-8", buffering=1
|
|
23
|
-
|
|
21
|
+
with (
|
|
22
|
+
open(log_file, "a" if append else "w", encoding="utf-8", buffering=1)
|
|
23
|
+
if log_file
|
|
24
|
+
else nullcontext(None) as f
|
|
25
|
+
):
|
|
24
26
|
while True:
|
|
25
27
|
# Without this sleep, the program won't exit
|
|
26
28
|
await asyncio.sleep(0)
|
|
@@ -88,9 +88,9 @@ def get_component_with_net_layers(
|
|
|
88
88
|
new_layers_init[0] + i,
|
|
89
89
|
new_layers_init[1] + j,
|
|
90
90
|
)
|
|
91
|
-
layer_stack.layers[
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
layer_stack.layers[f"{old_layername}{delimiter}{portname}"] = (
|
|
92
|
+
new_layer
|
|
93
|
+
)
|
|
94
94
|
net_component.add_polygon(polygon, layer=new_layer_number)
|
|
95
95
|
# Otherwise put the polygon back on the same layer
|
|
96
96
|
else:
|
|
@@ -8,7 +8,6 @@ From Chrostowski, L., & Hochberg, M. (2015). Silicon Photonics Design: From Devi
|
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
from __future__ import annotations
|
|
13
12
|
|
|
14
13
|
import warnings
|
|
@@ -57,8 +56,8 @@ def dn_carriers(wavelength: float, dN: float, dP: float) -> float:
|
|
|
57
56
|
else:
|
|
58
57
|
wavelength *= 1e-6
|
|
59
58
|
return (
|
|
60
|
-
-3.64 * 1e-10 * wavelength**2 * dN
|
|
61
|
-
- 3.51 * 1e-6 * wavelength**2 * np.power(dP, 0.8)
|
|
59
|
+
-3.64 * 1e-10 * wavelength** 2 * dN
|
|
60
|
+
- 3.51 * 1e-6 * wavelength** 2 * np.power(dP, 0.8)
|
|
62
61
|
)
|
|
63
62
|
|
|
64
63
|
|
|
@@ -45,16 +45,16 @@ def get_thermal_conductivities(basis):
|
|
|
45
45
|
# adding the layer to the thermal_conductivities dict. Check for that
|
|
46
46
|
# case
|
|
47
47
|
if domain in thermal_conductivities:
|
|
48
|
-
thermal_conductivity[
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
thermal_conductivity[basis.get_dofs(elements=domain)] = (
|
|
49
|
+
thermal_conductivities[domain]
|
|
50
|
+
)
|
|
51
51
|
else:
|
|
52
52
|
for material, labels in materials_dict.items():
|
|
53
53
|
if domain in labels:
|
|
54
54
|
# Assign the right values
|
|
55
|
-
thermal_conductivity[
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
thermal_conductivity[basis.get_dofs(elements=domain)] = (
|
|
56
|
+
thermal_conductivities[material]
|
|
57
|
+
)
|
|
58
58
|
break
|
|
59
59
|
|
|
60
60
|
thermal_conductivity *= 1e-12 # 1e-12 -> conversion from 1/m^2 -> 1/um^2
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Preprocessing involving both the GDS and the LayerStack, or the resulting simulation polygons."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import numpy as np
|
|
@@ -75,15 +76,15 @@ def process_buffers(layer_polygons_dict: dict, layer_stack: LayerStack):
|
|
|
75
76
|
layer_stack.layers[layername].thickness * zs[z_ind + 1]
|
|
76
77
|
- layer_stack.layers[layername].thickness * z
|
|
77
78
|
)
|
|
78
|
-
extended_layer_stack_layers[
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
extended_layer_stack_layers[f"{layername}_{poly_ind}_{z}"] = (
|
|
80
|
+
LayerLevel(
|
|
81
|
+
layer=layer_stack.layers[layername].layer,
|
|
82
|
+
thickness=new_thickness,
|
|
83
|
+
zmin=new_zmin,
|
|
84
|
+
material=layer_stack.layers[layername].material,
|
|
85
|
+
info=layer_stack.layers[layername].info,
|
|
86
|
+
mesh_order=layer_stack.layers[layername].mesh_order,
|
|
87
|
+
)
|
|
87
88
|
)
|
|
88
89
|
extended_layer_polygons_dict[f"{layername}_{poly_ind}_{z}"] = (
|
|
89
90
|
f"{layername}",
|
|
@@ -91,16 +92,16 @@ def process_buffers(layer_polygons_dict: dict, layer_stack: LayerStack):
|
|
|
91
92
|
polygon.buffer(width_buffer),
|
|
92
93
|
polygon.buffer(width_buffers[z_ind + 1]),
|
|
93
94
|
)
|
|
94
|
-
extended_layer_stack_layers[
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
extended_layer_stack_layers[f"{layername}_{poly_ind}_{zs[-1]}"] = (
|
|
96
|
+
LayerLevel(
|
|
97
|
+
layer=layer_stack.layers[layername].layer,
|
|
98
|
+
thickness=0,
|
|
99
|
+
zmin=layer_stack.layers[layername].zmin
|
|
100
|
+
+ layer_stack.layers[layername].thickness,
|
|
101
|
+
material=layer_stack.layers[layername].material,
|
|
102
|
+
info=layer_stack.layers[layername].info,
|
|
103
|
+
mesh_order=layer_stack.layers[layername].mesh_order,
|
|
104
|
+
)
|
|
104
105
|
)
|
|
105
106
|
return extended_layer_polygons_dict, LayerStack(layers=extended_layer_stack_layers)
|
|
106
107
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Preprocessing involving mostly the GDS polygons."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import gdsfactory as gf
|
|
@@ -39,7 +40,7 @@ def fuse_polygons(
|
|
|
39
40
|
]
|
|
40
41
|
|
|
41
42
|
return shapely.ops.unary_union(shapely_polygons).simplify(
|
|
42
|
-
simplify_tol, preserve_topology=
|
|
43
|
+
simplify_tol, preserve_topology=False
|
|
43
44
|
)
|
|
44
45
|
|
|
45
46
|
|
|
@@ -95,6 +95,7 @@ class RegionCollection:
|
|
|
95
95
|
self.layout = lib.cell_by_name(cell_name) if cell_name else lib.top_cell()
|
|
96
96
|
self.lib = lib
|
|
97
97
|
self.regions = {}
|
|
98
|
+
self.cell = lib[lib.top_cell().cell_index()]
|
|
98
99
|
|
|
99
100
|
def __getitem__(self, layer: tuple[int, int]) -> Region:
|
|
100
101
|
_assert_is_layer(layer)
|
|
@@ -142,13 +143,9 @@ class RegionCollection:
|
|
|
142
143
|
else:
|
|
143
144
|
c.write(gdspath)
|
|
144
145
|
|
|
145
|
-
def plot(self
|
|
146
|
+
def plot(self) -> kf.KCell:
|
|
146
147
|
"""Plot regions."""
|
|
147
|
-
|
|
148
|
-
self.write_gds(gdspath=gdspath, **kwargs)
|
|
149
|
-
gf.clear_cache()
|
|
150
|
-
c = gf.import_gds(gdspath)
|
|
151
|
-
return c.plot()
|
|
148
|
+
return self.cell
|
|
152
149
|
|
|
153
150
|
def get_kcell(
|
|
154
151
|
self, keep_original: bool = True, cellname: str = "Unnamed"
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
"""Write GDS with sample errors."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import gdsfactory as gf
|
|
6
|
+
import numpy as np
|
|
5
7
|
from gdsfactory.component import Component
|
|
6
|
-
from gdsfactory.typings import
|
|
8
|
+
from gdsfactory.typings import Layer
|
|
7
9
|
|
|
8
10
|
layer = (1, 0)
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
@gf.cell
|
|
12
|
-
def width_min(
|
|
13
|
-
return gf.components.rectangle(size=
|
|
14
|
+
def width_min(width: float = 0.1) -> Component:
|
|
15
|
+
return gf.components.rectangle(size=(width, width), layer=layer)
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
@gf.cell
|
|
17
|
-
def area_min() -> Component:
|
|
18
|
-
size
|
|
19
|
-
return gf.components.rectangle(size=size, layer=layer)
|
|
19
|
+
def area_min(width: float = 0.2) -> Component:
|
|
20
|
+
return gf.components.rectangle(size=(width, width), layer=layer)
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
@gf.cell
|
|
@@ -46,8 +47,13 @@ def enclosing(
|
|
|
46
47
|
enclosing: float = 0.1, layer1: Layer = (40, 0), layer2: Layer = (41, 0)
|
|
47
48
|
) -> Component:
|
|
48
49
|
"""Layer1 must be enclosed by layer2 by value.
|
|
49
|
-
|
|
50
50
|
checks if layer1 encloses (is bigger than) layer2 by value
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
enclosing: value to enclose layer1 by layer2.
|
|
54
|
+
layer1: layer to enclose.
|
|
55
|
+
layer2: layer to enclose by.
|
|
56
|
+
|
|
51
57
|
"""
|
|
52
58
|
w1 = 1
|
|
53
59
|
w2 = w1 + enclosing
|
|
@@ -69,18 +75,17 @@ def snapping_error(gap: float = 1e-3) -> Component:
|
|
|
69
75
|
|
|
70
76
|
|
|
71
77
|
@gf.cell
|
|
72
|
-
def errors() -> Component:
|
|
73
|
-
"""Write a GDS with sample errors."""
|
|
74
|
-
components = [width_min(), gap_min(), separation(), enclosing()]
|
|
75
|
-
c = gf.pack(components, spacing=1.5)
|
|
76
|
-
return gf.add_padding_container(c[0], layers=((64, 0),), default=5)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@gf.cell
|
|
80
|
-
def errors2() -> Component:
|
|
78
|
+
def errors(n: int = 20) -> Component:
|
|
81
79
|
"""Write a GDS with sample errors."""
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
wmin = 0.1
|
|
81
|
+
# components = [width_min(), gap_min(), separation(), enclosing()]
|
|
82
|
+
cs = []
|
|
83
|
+
cs += [width_min(wmin * np.random.rand()) for _ in range(n)]
|
|
84
|
+
cs += [gap_min(gap=0.1 * np.random.rand()) for _ in range(n)]
|
|
85
|
+
cs += [separation(gap=0.1 * np.random.rand()) for _ in range(n)]
|
|
86
|
+
cs += [enclosing(enclosing=0.1 * np.random.rand()) for _ in range(n)]
|
|
87
|
+
|
|
88
|
+
c = gf.pack(cs, spacing=1.5)
|
|
84
89
|
return gf.add_padding_container(c[0], layers=((64, 0),), default=5)
|
|
85
90
|
|
|
86
91
|
|
|
@@ -92,6 +97,6 @@ if __name__ == "__main__":
|
|
|
92
97
|
# c = snapping_error()
|
|
93
98
|
# c.write_gds("snap.gds")
|
|
94
99
|
|
|
95
|
-
c =
|
|
100
|
+
c = errors()
|
|
96
101
|
c.write_gds("errors.gds")
|
|
97
102
|
c.show(show_ports=True)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import klayout.db as kdb
|
|
5
|
+
import networkx as nx
|
|
6
|
+
from gdsfactory.config import logger
|
|
7
|
+
from gdsfactory.typings import PathType
|
|
8
|
+
|
|
9
|
+
from gplugins.klayout.netlist_spice_reader import (
|
|
10
|
+
CalibreSpiceReader,
|
|
11
|
+
NetlistSpiceReaderDelegateWithStrings,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_device_name(device: kdb.Device) -> str:
|
|
16
|
+
"""Get a unique name for a ``Device`` instance."""
|
|
17
|
+
return f"{device.device_class().name}_{device.expanded_name()}"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def netlist_to_networkx(
|
|
21
|
+
netlist: kdb.Netlist,
|
|
22
|
+
include_labels: bool = True,
|
|
23
|
+
top_cell: str | None = None,
|
|
24
|
+
spice_reader_instance: NetlistSpiceReaderDelegateWithStrings | None = None,
|
|
25
|
+
) -> nx.Graph:
|
|
26
|
+
"""Convert a KLayout DB `Netlist` to a networkx graph.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
netlist: The KLayout DB `Netlist` to convert to a NetworkX `Graph`.
|
|
30
|
+
include_labels: Whether to include net labels in the graph connected to corresponding cells.
|
|
31
|
+
top_cell: The name of the top cell to consider for the NetworkX graph. Defaults to all top cells.
|
|
32
|
+
spice_reader_instance: The KLayout Spice reader that was used for parsing SPICE netlists.
|
|
33
|
+
Used for fetching string parameter values from a stored mapping.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
A networkx `Graph` representing the connectivity of the `Netlist`.
|
|
37
|
+
"""
|
|
38
|
+
G = nx.Graph()
|
|
39
|
+
netlist.flatten()
|
|
40
|
+
|
|
41
|
+
top_circuits = list(
|
|
42
|
+
itertools.islice(netlist.each_circuit_top_down(), netlist.top_circuit_count())
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
if top_cell:
|
|
46
|
+
try:
|
|
47
|
+
top_circuits = (
|
|
48
|
+
next(
|
|
49
|
+
c for c in top_circuits if c.name.casefold() == top_cell.casefold()
|
|
50
|
+
),
|
|
51
|
+
)
|
|
52
|
+
except StopIteration as e:
|
|
53
|
+
available_top_cells = [cell.name for cell in top_circuits]
|
|
54
|
+
raise ValueError(
|
|
55
|
+
f"{top_cell=!r} not found in the netlist. Available top cells: {available_top_cells!r}"
|
|
56
|
+
) from e
|
|
57
|
+
|
|
58
|
+
all_used_nets = set()
|
|
59
|
+
for circuit in top_circuits:
|
|
60
|
+
for device in circuit.each_device():
|
|
61
|
+
# Gather properties of Device class
|
|
62
|
+
device_class = device.device_class()
|
|
63
|
+
parameter_definitions = device_class.parameter_definitions()
|
|
64
|
+
terminal_definitions = device_class.terminal_definitions()
|
|
65
|
+
|
|
66
|
+
# Gather values for specific Device instance
|
|
67
|
+
parameters = {
|
|
68
|
+
parameter.name: (
|
|
69
|
+
spice_reader_instance.integer_to_string_map.get(
|
|
70
|
+
int(device.parameter(parameter.name)),
|
|
71
|
+
device.parameter(parameter.name),
|
|
72
|
+
)
|
|
73
|
+
if spice_reader_instance
|
|
74
|
+
else device.parameter(parameter.name)
|
|
75
|
+
)
|
|
76
|
+
for parameter in parameter_definitions
|
|
77
|
+
}
|
|
78
|
+
nets = [
|
|
79
|
+
device.net_for_terminal(terminal.name)
|
|
80
|
+
for terminal in terminal_definitions
|
|
81
|
+
]
|
|
82
|
+
device_name = _get_device_name(device)
|
|
83
|
+
|
|
84
|
+
# Create NetworkX representation
|
|
85
|
+
G.add_node(device_name, **parameters)
|
|
86
|
+
for net in nets:
|
|
87
|
+
net_name = net.expanded_name()
|
|
88
|
+
G.add_edge(device_name, net_name)
|
|
89
|
+
all_used_nets.add(net_name)
|
|
90
|
+
|
|
91
|
+
if not include_labels:
|
|
92
|
+
for node in all_used_nets:
|
|
93
|
+
connections = list(G.neighbors(node))
|
|
94
|
+
G.add_edges_from(itertools.combinations(connections, r=2))
|
|
95
|
+
G.remove_node(node)
|
|
96
|
+
|
|
97
|
+
return G
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def networkx_from_spice(
|
|
101
|
+
filepath: PathType,
|
|
102
|
+
include_labels: bool = True,
|
|
103
|
+
top_cell: str | None = None,
|
|
104
|
+
spice_reader: type[NetlistSpiceReaderDelegateWithStrings] = CalibreSpiceReader,
|
|
105
|
+
**kwargs,
|
|
106
|
+
) -> nx.Graph:
|
|
107
|
+
"""Returns a networkx Graph from a SPICE netlist file or KLayout LayoutToNetlist.
|
|
108
|
+
Args:
|
|
109
|
+
filepath: Path to the KLayout LayoutToNetlist file or a SPICE netlist.
|
|
110
|
+
File extensions should be `.l2n` and `.spice`, respectively.
|
|
111
|
+
include_labels: Whether to include labels in the graph connected to corresponding cells.
|
|
112
|
+
top_cell: The name of the top cell to consider for the NetworkX graph. Defaults to all top cells.
|
|
113
|
+
spice_reader: The KLayout Spice reader to use for parsing SPICE netlists.
|
|
114
|
+
"""
|
|
115
|
+
spice_reader_instance = None
|
|
116
|
+
match Path(filepath).suffix:
|
|
117
|
+
case ".l2n" | ".txt":
|
|
118
|
+
l2n = kdb.LayoutToNetlist()
|
|
119
|
+
l2n.read(str(filepath))
|
|
120
|
+
netlist = l2n.netlist()
|
|
121
|
+
case ".cir" | ".sp" | ".spi" | ".spice":
|
|
122
|
+
reader = kdb.NetlistSpiceReader(spice_reader_instance := spice_reader())
|
|
123
|
+
netlist = kdb.Netlist()
|
|
124
|
+
netlist.read(str(filepath), reader)
|
|
125
|
+
case _:
|
|
126
|
+
logger.warning("Assuming file is KLayout native LayoutToNetlist file")
|
|
127
|
+
l2n = kdb.LayoutToNetlist()
|
|
128
|
+
l2n.read(str(filepath))
|
|
129
|
+
netlist = l2n.netlist()
|
|
130
|
+
|
|
131
|
+
# Creating a graph for the connectivity
|
|
132
|
+
return netlist_to_networkx(
|
|
133
|
+
netlist,
|
|
134
|
+
include_labels=include_labels,
|
|
135
|
+
top_cell=top_cell,
|
|
136
|
+
spice_reader_instance=spice_reader_instance,
|
|
137
|
+
)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import re
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from collections.abc import MutableMapping, Sequence
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import klayout.db as kdb
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class NetlistSpiceReaderDelegateWithStrings(kdb.NetlistSpiceReaderDelegate, ABC):
|
|
11
|
+
"""A KLayout SPICE reader delegate that supports string variables for ``Device`` through a hash map."""
|
|
12
|
+
|
|
13
|
+
@property
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def integer_to_string_map(self) -> MutableMapping[int, str]:
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class NoCommentReader(kdb.NetlistSpiceReaderDelegate):
|
|
20
|
+
"""KLayout Spice reader without comments after $. This allows checking the netlist for HSPICE."""
|
|
21
|
+
|
|
22
|
+
n_nodes: int = 0
|
|
23
|
+
|
|
24
|
+
def parse_element(self, s: str, element: str) -> kdb.ParseElementData:
|
|
25
|
+
if "$" in s:
|
|
26
|
+
s, *_ = s.split("$") # Don't take comments into account
|
|
27
|
+
parsed = super().parse_element(s, element)
|
|
28
|
+
# ensure uniqueness
|
|
29
|
+
parsed.model_name = parsed.model_name + f"_{self.n_nodes}"
|
|
30
|
+
self.n_nodes += 1
|
|
31
|
+
return parsed
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CalibreSpiceReader(NetlistSpiceReaderDelegateWithStrings):
|
|
35
|
+
"""KLayout Spice reader for Calibre LVS extraction output.
|
|
36
|
+
|
|
37
|
+
Considers parameter values for generic `X` devices that start with `WG`.
|
|
38
|
+
Ignores comments after $ excluding location given with ``$X=number $Y=number``."""
|
|
39
|
+
|
|
40
|
+
n_nodes: int = 0
|
|
41
|
+
calibre_location_pattern: str = r"\$X=(-?\d+) \$Y=(-?\d+)"
|
|
42
|
+
integer_to_string_map: MutableMapping[int, str] = {}
|
|
43
|
+
|
|
44
|
+
def wants_subcircuit(self, name: str):
|
|
45
|
+
"""Model all SPICE models that start with `WG` as devices in order to support parameters."""
|
|
46
|
+
return "WG" in name or super().wants_subcircuit(name)
|
|
47
|
+
|
|
48
|
+
def parse_element(self, s: str, element: str) -> kdb.ParseElementData:
|
|
49
|
+
x_value, y_value = None, None
|
|
50
|
+
if "$" in s:
|
|
51
|
+
if location_matches := re.search(self.calibre_location_pattern, s):
|
|
52
|
+
x_value, y_value = (int(e) / 1000 for e in location_matches.group(1, 2))
|
|
53
|
+
|
|
54
|
+
# Use default KLayout parser for rest of the SPICE
|
|
55
|
+
s, *_ = s.split("$")
|
|
56
|
+
|
|
57
|
+
parsed = super().parse_element(s, element)
|
|
58
|
+
parsed.parameters |= {"x": x_value, "y": y_value}
|
|
59
|
+
|
|
60
|
+
# ensure uniqueness
|
|
61
|
+
parsed.model_name = parsed.model_name
|
|
62
|
+
self.n_nodes += 1
|
|
63
|
+
return parsed
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def hash_str_to_int(s: str) -> int:
|
|
67
|
+
return int(hashlib.shake_128(s.encode()).hexdigest(4), 16)
|
|
68
|
+
|
|
69
|
+
def element(
|
|
70
|
+
self,
|
|
71
|
+
circuit: kdb.Circuit,
|
|
72
|
+
element: str,
|
|
73
|
+
name: str,
|
|
74
|
+
model: str,
|
|
75
|
+
value: Any,
|
|
76
|
+
nets: Sequence[kdb.Net],
|
|
77
|
+
parameters: dict[str, int | float | str],
|
|
78
|
+
):
|
|
79
|
+
# Handle non-'X' elements with standard KLayout processing
|
|
80
|
+
if element != "X":
|
|
81
|
+
# Other devices with standard KLayout
|
|
82
|
+
return super().element(
|
|
83
|
+
circuit, element, name, model, value, nets, parameters
|
|
84
|
+
)
|
|
85
|
+
clx = circuit.netlist().device_class_by_name(model)
|
|
86
|
+
|
|
87
|
+
# Create Device class on first occurrence
|
|
88
|
+
if not clx:
|
|
89
|
+
clx = kdb.DeviceClass()
|
|
90
|
+
clx.name = model
|
|
91
|
+
for key, value in parameters.items():
|
|
92
|
+
clx.add_parameter(kdb.DeviceParameterDefinition(key))
|
|
93
|
+
# map string variables to integers
|
|
94
|
+
if (
|
|
95
|
+
isinstance(value, str)
|
|
96
|
+
and value not in self.integer_to_string_map.values()
|
|
97
|
+
):
|
|
98
|
+
hashed_value = CalibreSpiceReader.hash_str_to_int(value)
|
|
99
|
+
self.integer_to_string_map[hashed_value] = value
|
|
100
|
+
|
|
101
|
+
for i in range(len(nets)):
|
|
102
|
+
clx.add_terminal(kdb.DeviceTerminalDefinition(str(i)))
|
|
103
|
+
circuit.netlist().add(clx)
|
|
104
|
+
|
|
105
|
+
device = circuit.create_device(clx, name)
|
|
106
|
+
for i, net in enumerate(nets):
|
|
107
|
+
device.connect_terminal(i, net)
|
|
108
|
+
|
|
109
|
+
for key, value in parameters.items():
|
|
110
|
+
device.set_parameter(
|
|
111
|
+
key,
|
|
112
|
+
(
|
|
113
|
+
CalibreSpiceReader.hash_str_to_int(value)
|
|
114
|
+
if isinstance(value, str)
|
|
115
|
+
else value
|
|
116
|
+
),
|
|
117
|
+
)
|