diff --git a/doc/source/conf.py b/doc/source/conf.py index 077f22cdde..8ce0d1a629 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -360,7 +360,8 @@ def setup(app): # Sphinx gallery customization nbsphinx_thumbnails = { - "examples/use_configuration/set_up_edb_for_signal_integrity_analysis": "_static/thumbnails/101_getting_started.png", + "examples/use_configuration/pdn_analysis": "_static/thumbnails/101_getting_started.png", + "examples/use_configuration/serdes": "_static/thumbnails/101_getting_started.png", "examples/use_configuration/import_stackup": "_static/thumbnails/101_getting_started.png", "examples/use_configuration/import_material": "_static/thumbnails/101_getting_started.png", "examples/use_configuration/import_ports": "_static/thumbnails/101_getting_started.png", diff --git a/examples/use_configuration/index.rst b/examples/use_configuration/index.rst index 8012729af7..f8378e2376 100644 --- a/examples/use_configuration/index.rst +++ b/examples/use_configuration/index.rst @@ -7,7 +7,8 @@ End-to-end workflow .. nbgallery:: - set_up_edb_for_signal_integrity_analysis.py + pdn_analysis.py + serdes.py Step explanation ------------------------- diff --git a/examples/use_configuration/set_up_edb_for_signal_integrity_analysis.py b/examples/use_configuration/pdn_analysis.py similarity index 98% rename from examples/use_configuration/set_up_edb_for_signal_integrity_analysis.py rename to examples/use_configuration/pdn_analysis.py index fa6b1009f9..ef6a44014d 100644 --- a/examples/use_configuration/set_up_edb_for_signal_integrity_analysis.py +++ b/examples/use_configuration/pdn_analysis.py @@ -1,4 +1,4 @@ -# # Set up EDB for Power Integrity Analysis +# # Set up EDB for Power Distribution Network Analysis # This example shows how to set up the electronics database (EDB) for power integrity analysis from a single # configuration file. diff --git a/examples/use_configuration/serdes.py b/examples/use_configuration/serdes.py new file mode 100644 index 0000000000..cf7b7c34bd --- /dev/null +++ b/examples/use_configuration/serdes.py @@ -0,0 +1,277 @@ +# # Set up EDB for Serdes channel S-parameter extraction + +# ## Import the required packages + +import json + +# + +import os +import tempfile + +from ansys.aedt.core import Hfss3dLayout +from ansys.aedt.core.downloads import download_file + +from pyedb import Edb + +AEDT_VERSION = "2024.2" +NG_MODE = False + +# - + +# Download the example PCB data. + +temp_folder = tempfile.TemporaryDirectory(suffix=".ansys") +file_edb = download_file(source="edb/ANSYS-HSD_V1.aedb", destination=temp_folder.name) +download_file(source="touchstone", name="GRM32_DC0V_25degC_series.s2p", destination=os.path.split(file_edb)[0]) + +# ## Load example layout + +edbapp = Edb(file_edb, edbversion=AEDT_VERSION) + +# ## Create config file + +cfg_general = {"anti_pads_always_on": True, "suppress_pads": True} + +# Define dielectric materials, stackup and surface roughness model. + +cfg_stackup = { + "materials": [ + {"name": "copper", "permittivity": 1, "conductivity": 58000000.0}, + {"name": "megtron4", "permittivity": 3.77, "dielectric_loss_tangent": 0.005}, + {"name": "solder_resist", "permittivity": 3.0, "dielectric_loss_tangent": 0.035}, + ], + "layers": [ + { + "name": "Top", + "type": "signal", + "material": "copper", + "fill_material": "solder_resist", + "thickness": "0.035mm", + "roughness": { + "top": {"model": "huray", "nodule_radius": "0.5um", "surface_ratio": "5"}, + "bottom": {"model": "huray", "nodule_radius": "0.5um", "surface_ratio": "5"}, + "side": {"model": "huray", "nodule_radius": "0.5um", "surface_ratio": "5"}, + "enabled": True, + }, + }, + {"name": "DE1", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.1mm"}, + {"name": "Inner1", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"}, + {"name": "DE2", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.088mm"}, + {"name": "Inner2", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"}, + {"name": "DE3", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.1mm"}, + {"name": "Inner3", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"}, + {"name": "Megtron4-1mm", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": 0.001}, + {"name": "Inner4", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"}, + {"name": "DE5", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.1mm"}, + {"name": "Inner5", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"}, + {"name": "DE6", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.088mm"}, + {"name": "Inner6", "type": "signal", "material": "copper", "fill_material": "megtron4", "thickness": "0.017mm"}, + {"name": "DE7", "type": "dielectric", "material": "megtron4", "fill_material": "", "thickness": "0.1mm"}, + { + "name": "Bottom", + "type": "signal", + "material": "copper", + "fill_material": "solder_resist", + "thickness": "0.035mm", + }, + ], +} + +# Define Component with solderballs. + +cfg_components = [ + { + "reference_designator": "U1", + "part_type": "io", + "solder_ball_properties": {"shape": "cylinder", "diameter": "300um", "height": "300um"}, + "port_properties": { + "reference_offset": "0", + "reference_size_auto": True, + "reference_size_x": 0, + "reference_size_y": 0, + }, + } +] + +# Edit via padstack definition. Add backdrilling. + +cfg_padstacks = { + "definitions": [ + { + "name": "v40h15-2", + "material": "copper", + "hole_range": "upper_pad_to_lower_pad", + "hole_parameters": {"shape": "circle", "diameter": "0.2mm"}, + }, + { + "name": "v35h15-1", + "material": "copper", + "hole_range": "upper_pad_to_lower_pad", + "hole_parameters": {"shape": "circle", "diameter": "0.25mm"}, + }, + ], + "instances": [ + { + "name": "Via313", + "backdrill_parameters": { + "from_bottom": {"drill_to_layer": "Inner3", "diameter": "1mm", "stub_length": "0.2mm"} + }, + }, + { + "name": "Via314", + "backdrill_parameters": { + "from_bottom": {"drill_to_layer": "Inner3", "diameter": "1mm", "stub_length": "0.2mm"} + }, + }, + ], +} + +# Define ports. + +cfg_ports = [ + { + "name": "port_1", + "reference_designator": "U1", + "type": "coax", + "positive_terminal": {"net": "PCIe_Gen4_TX2_CAP_P"}, + }, + { + "name": "port_2", + "reference_designator": "U1", + "type": "coax", + "positive_terminal": {"net": "PCIe_Gen4_TX2_CAP_N"}, + }, + { + "name": "port_3", + "reference_designator": "X1", + "type": "circuit", + "positive_terminal": {"pin": "B8"}, + "negative_terminal": {"pin": "B7"}, + }, + { + "name": "port_4", + "reference_designator": "X1", + "type": "circuit", + "positive_terminal": {"pin": "B9"}, + "negative_terminal": {"pin": "B10"}, + }, +] + +# Define S-parameter assignment + +cfg_s_parameters = [ + { + "name": "cap_10nf", + "file_path": "$PROJECTDIR\\touchstone\\GRM32_DC0V_25degC_series.s2p", + "component_definition": "CAPC1005X55X25LL05T10", + "components": ["C375", "C376"], + "reference_net": "GND", + } +] + +# Define SIwave setup. + +cfg_setups = [ + { + "name": "siwave_setup", + "type": "siwave_ac", + "si_slider_position": 1, + "freq_sweep": [ + { + "name": "Sweep1", + "type": "interpolation", + "frequencies": [ + {"distribution": "linear_scale", "start": "50MHz", "stop": "20GHz", "increment": "50MHz"} + ], + } + ], + } +] + +# Define cutout. + +cfg_operations = { + "cutout": { + "signal_list": ["PCIe_Gen4_TX2_CAP_P", "PCIe_Gen4_TX2_CAP_N", "PCIe_Gen4_TX2_P", "PCIe_Gen4_TX2_N"], + "reference_list": ["GND"], + "custom_extent": [ + [0.014, 0.055], + [0.03674271504652968, 0.05493094625752912], + [0.07, 0.039], + [0.07, 0.034], + [0.05609890516829415, 0.03395233061637539], + [0.014, 0.044], + ], + } +} + +# Create final configuration. + +cfg = { + "general": cfg_general, + "stackup": cfg_stackup, + "components": cfg_components, + "padstacks": cfg_padstacks, + "ports": cfg_ports, + "s_parameters": cfg_s_parameters, + "setups": cfg_setups, + "operations": cfg_operations, +} + +# Create the config file. + +file_json = os.path.join(temp_folder.name, "edb_configuration.json") +with open(file_json, "w") as f: + json.dump(cfg, f, indent=4, ensure_ascii=False) + +# ## Apply Config file + +# Apply configuration to the example layout + +edbapp.configuration.load(config_file=file_json) +edbapp.configuration.run() + +edbapp.nets.plot(nets=[]) + +# Save and close EDB. + +edbapp.save() +edbapp.close() + +# The configured EDB file is saved in a temp folder. + +print(temp_folder.name) + +# ## Load edb into HFSS 3D Layout. + +h3d = Hfss3dLayout(edbapp.edbpath, version=AEDT_VERSION, non_graphical=NG_MODE, new_desktop=True) + +# Create differential pair definition. + +h3d.set_differential_pair( + differential_mode="DIFF_BGA", + assignment="port_1", + reference="port_2", +) + +h3d.set_differential_pair( + differential_mode="DIFF_CONN", + assignment="port_3", + reference="port_4", +) + +# Solve. + +h3d.analyze(setup="siwave_setup") + +# Plot insertion loss. + +solutions = h3d.post.get_solution_data(expressions="mag(S(DIFF_CONN,DIFF_BGA))", context="Differential Pairs") +solutions.plot(formula="db20") + +# Shut Down Electronics Desktop + +h3d.close_desktop() + +# All project files are saved in the folder ``temp_file.dir``. If you've run this example as a Jupyter notebook you +# can retrieve those project files. diff --git a/pyproject.toml b/pyproject.toml index 1914b4d151..b81cf55b6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ "pywin32 >= 303;platform_system=='Windows'", "ansys-pythonnet >= 3.1.0rc3", "dotnetcore2 ==3.1.23;platform_system=='Linux'", - "numpy>=1.20.0,<2", + "numpy>=1.20.0,<3", "pandas>=1.1.0,<2.3", "pydantic>=2.6.4,<2.10", "Rtree >= 1.2.0", @@ -50,7 +50,7 @@ doc = [ "ansys-sphinx-theme>=0.10.0,<1.1", "imageio>=2.30.0,<2.37", "ipython>=8.13.0,<8.30", - "jupyterlab>=4.0.0,<4.3", + "jupyterlab>=4.0.0,<4.4", "jupytext>=1.16.0,<1.17", "matplotlib>=3.5.0,<3.10", "nbsphinx>=0.9.0,<0.10", diff --git a/src/pyedb/configuration/cfg_padstacks.py b/src/pyedb/configuration/cfg_padstacks.py index 96cbda4684..acff073046 100644 --- a/src/pyedb/configuration/cfg_padstacks.py +++ b/src/pyedb/configuration/cfg_padstacks.py @@ -62,7 +62,9 @@ def apply(self): def retrieve_parameters_from_edb(self): self.clean() - for _, obj in self._pedb.padstacks.definitions.items(): + for name, obj in self._pedb.padstacks.definitions.items(): + if name.lower() == "symbol": + continue pdef = CfgPadstackDefinition(self._pedb, obj) pdef.retrieve_parameters_from_edb() self.definitions.append(pdef) diff --git a/src/pyedb/configuration/configuration.py b/src/pyedb/configuration/configuration.py index f13d7570ab..dd75d4186a 100644 --- a/src/pyedb/configuration/configuration.py +++ b/src/pyedb/configuration/configuration.py @@ -327,7 +327,7 @@ def export( self, file_path, stackup=True, - package_definitions=True, + package_definitions=False, setups=True, sources=True, ports=True, diff --git a/src/pyedb/dotnet/edb.py b/src/pyedb/dotnet/edb.py index 9879f4fdbc..7e70c14402 100644 --- a/src/pyedb/dotnet/edb.py +++ b/src/pyedb/dotnet/edb.py @@ -95,7 +95,7 @@ SiwaveDCSimulationSetup, SiwaveSimulationSetup, ) -from pyedb.generic.constants import AEDT_UNITS, SolverType +from pyedb.generic.constants import AEDT_UNITS, SolverType, unit_converter from pyedb.generic.general_methods import ( generate_unique_name, get_string_version, @@ -4598,3 +4598,45 @@ def definitions(self): def workflow(self): """Workflow class.""" return Workflow(self) + + def export_gds_comp_xml(self, comps_to_export, gds_comps_unit="mm", control_path=None): + """Exports an XML file with selected components information for use in a GDS import. + + Parameters + ---------- + comps_to_export : list + List of components whose information will be exported to xml file. + gds_comps_unit : str, optional + GDS_COMPONENTS section units. Default is ``"mm"``. + control_path : str, optional + Path for outputting the XML file. + + Returns + ------- + bool + ``True`` when successful, ``False`` when failed. + """ + from pyedb.generic.general_methods import ET + + components = ET.Element("GDS_COMPONENTS") + components.set("LengthUnit", gds_comps_unit) + if not comps_to_export: + comps_to_export = self.components.components + for comp in comps_to_export: + ocomp = self.components.components[comp] + gds_component = ET.SubElement(components, "GDS_COMPONENT") + for pin_name, pin in ocomp.pins.items(): + pins_position_unit = unit_converter(pin.position, output_units=gds_comps_unit) + gds_pin = ET.SubElement(gds_component, "GDS_PIN") + gds_pin.set("Name", pin_name) + gds_pin.set("x", str(pins_position_unit[0])) + gds_pin.set("y", str(pins_position_unit[1])) + gds_pin.set("Layer", pin.placement_layer) + component = ET.SubElement(gds_component, "Component") + component.set("RefDes", ocomp.refdes) + component.set("PartName", ocomp.partname) + component.set("PartType", ocomp.type) + tree = ET.ElementTree(components) + ET.indent(tree, space="\t", level=0) + tree.write(control_path) + return True if os.path.exists(control_path) else False diff --git a/src/pyedb/dotnet/edb_core/cell/primitive/primitive.py b/src/pyedb/dotnet/edb_core/cell/primitive/primitive.py index aa99dbc3b8..023930210e 100644 --- a/src/pyedb/dotnet/edb_core/cell/primitive/primitive.py +++ b/src/pyedb/dotnet/edb_core/cell/primitive/primitive.py @@ -580,17 +580,17 @@ def aedt_name(self): _, name = self._edb_object.GetProductProperty(self._pedb._edb.ProductId.Designer, 1, val) name = str(name).strip("'") if name == "": - if str(self.primitive_type) == "Path": + if str(self.primitive_type).lower() == "path": ptype = "line" - elif str(self.primitive_type) == "Rectangle": + elif str(self.primitive_type).lower() == "rectangle": ptype = "rect" - elif str(self.primitive_type) == "Polygon": + elif str(self.primitive_type).lower() == "polygon": ptype = "poly" - elif str(self.primitive_type) == "Bondwire": + elif str(self.primitive_type).lower() == "bondwire": ptype = "bwr" else: ptype = str(self.primitive_type).lower() - name = "{}_{}".format(ptype, self.id) + name = "{}__{}".format(ptype, self.id) self._edb_object.SetProductProperty(self._pedb._edb.ProductId.Designer, 1, name) return name @@ -603,10 +603,6 @@ def polygon_data(self): """:class:`pyedb.dotnet.edb_core.dotnet.database.PolygonDataDotNet`: Outer contour of the Polygon object.""" return PolygonData(self._pedb, self._edb_object.GetPolygonData()) - @polygon_data.setter - def polygon_data(self, poly): - self._edb_object.SetPolygonData(poly._edb_object) - def add_void(self, point_list): """Add a void to current primitive. @@ -757,24 +753,6 @@ def points_raw(self): points.append(point) return points - def expand(self, offset=0.001, tolerance=1e-12, round_corners=True, maximum_corner_extension=0.001): - """Expand the polygon shape by an absolute value in all direction. - Offset can be negative for negative expansion. - - Parameters - ---------- - offset : float, optional - Offset value in meters. - tolerance : float, optional - Tolerance in meters. - round_corners : bool, optional - Whether to round corners or not. - If True, use rounded corners in the expansion otherwise use straight edges (can be degenerate). - maximum_corner_extension : float, optional - The maximum corner extension (when round corners are not used) at which point the corner is clipped. - """ - return self.polygon_data.expand(offset, tolerance, round_corners, maximum_corner_extension) - def scale(self, factor, center=None): """Scales the polygon relative to a center point by a factor. diff --git a/src/pyedb/dotnet/edb_core/edb_data/control_file.py b/src/pyedb/dotnet/edb_core/edb_data/control_file.py index 1193b1148e..076b85f575 100644 --- a/src/pyedb/dotnet/edb_core/edb_data/control_file.py +++ b/src/pyedb/dotnet/edb_core/edb_data/control_file.py @@ -193,6 +193,19 @@ def _write_xml(self, root): content.set("Thickness", self.properties.get("Thickness", "0.001")) if self.properties.get("Type"): content.set("Type", self.properties.get("Type", "conductor")) + if self.properties.get("ConvertPolygonToCircle"): + content.set("ConvertPolygonToCircle", self.properties["ConvertPolygonToCircle"]) + if self.properties.get("ConvertPolygonToCircleRatio"): + content.set("ConvertPolygonToCircleRatio", self.properties["ConvertPolygonToCircleRatio"]) + if self.properties.get("ReconstructArcs"): + content.set("ReconstructArcs", self.properties["ReconstructArcs"]) + if self.properties.get("ArcTolerance"): + content.set("ArcTolerance", self.properties["ArcTolerance"]) + if self.properties.get("UnionPrimitives"): + content.set("UnionPrimitives", self.properties["UnionPrimitives"]) + # To confirm syntax with development + if self.properties.get("DefeatureMinTraceWidth"): + content.set("DefeatureMinTraceWidth", self.properties["DefeatureMinTraceWidth"]) class ControlFileVia(ControlFileLayer): @@ -226,6 +239,14 @@ def _write_xml(self, root): content.set("Thickness", self.properties.get("Thickness", "0.001")) if self.properties.get("Type"): content.set("Type", self.properties.get("Type", "conductor")) + if self.properties.get("ConvertPolygonToCircle"): + content.set("ConvertPolygonToCircle", self.properties["ConvertPolygonToCircle"]) + if self.properties.get("ConvertPolygonToCircleRatio"): + content.set("ConvertPolygonToCircleRatio", self.properties["ConvertPolygonToCircleRatio"]) + if self.properties.get("ReconstructArcs"): + content.set("ReconstructArcs", self.properties["ReconstructArcs"]) + if self.properties.get("ArcTolerance"): + content.set("ArcTolerance", self.properties["ArcTolerance"]) if self.create_via_group: viagroup = ET.SubElement(content, "CreateViaGroups") viagroup.set("CheckContainment", "true" if self.check_containment else "false") diff --git a/src/pyedb/dotnet/edb_core/edb_data/primitives_data.py b/src/pyedb/dotnet/edb_core/edb_data/primitives_data.py index bbd9524b2c..687017f0e5 100644 --- a/src/pyedb/dotnet/edb_core/edb_data/primitives_data.py +++ b/src/pyedb/dotnet/edb_core/edb_data/primitives_data.py @@ -29,6 +29,7 @@ RectangleDotNet, TextDotNet, ) +from pyedb.dotnet.edb_core.geometry.polygon_data import PolygonData from pyedb.modeler.geometry_operators import GeometryOperators @@ -305,6 +306,36 @@ def in_polygon( # prim = point_list # return self.add_void(prim) + @property + def polygon_data(self): + """:class:`pyedb.dotnet.edb_core.dotnet.database.PolygonDataDotNet`: Outer contour of the Polygon object.""" + return PolygonData(self._pedb, self._edb_object.GetPolygonData()) + + @polygon_data.setter + def polygon_data(self, poly): + self._edb_object.SetPolygonData(poly._edb_object) + + def expand(self, offset=0.001, tolerance=1e-12, round_corners=True, maximum_corner_extension=0.001): + """Expand the polygon shape by an absolute value in all direction. + Offset can be negative for negative expansion. + + Parameters + ---------- + offset : float, optional + Offset value in meters. + tolerance : float, optional + Tolerance in meters. + round_corners : bool, optional + Whether to round corners or not. + If True, use rounded corners in the expansion otherwise use straight edges (can be degenerate). + maximum_corner_extension : float, optional + The maximum corner extension (when round corners are not used) at which point the corner is clipped. + """ + pd = self.polygon_data + pd.expand(offset, tolerance, round_corners, maximum_corner_extension) + self.polygon_data = pd + return pd + class EdbText(Primitive, TextDotNet): def __init__(self, raw_primitive, core_app): diff --git a/tests/legacy/system/test_edb.py b/tests/legacy/system/test_edb.py index be7d5f2466..bb11bad5ce 100644 --- a/tests/legacy/system/test_edb.py +++ b/tests/legacy/system/test_edb.py @@ -1395,6 +1395,41 @@ def test_backdrill_via_with_offset(self): assert padstack_instance2.backdrill_bottom[2] == "100um" edb.close() + def test_add_via_with_options_control_file(self): + """Add new via layer with option in control file.""" + from pyedb.dotnet.edb_core.edb_data.control_file import ControlFile + + ctrl = ControlFile() + ctrl.stackup.add_layer( + "m2", + properties={ + "Elevation": "0.0", + "Material": "copper", + "Type": "conductor", + "Thickness": "1.0", + "UnionPrimitives": "true", + }, + ) + assert [layer for layer in ctrl.stackup.layers if layer.name == "m2"] + + ctrl.stackup.add_layer( + "m1", + properties={ + "Elevation": "1.0", + "Material": "copper", + "Type": "conductor", + "Thickness": "1.5", + "UnionPrimitives": "false", + "ConvertPolygonToCircle": "true", + }, + ) + assert [layer for layer in ctrl.stackup.layers if layer.properties["Elevation"] == "1.0"] + + ctrl.stackup.add_via( + "via12", properties={"StartLayer": "m2", "StopLayer": "m1", "ConvertPolygonToCircle": "true"} + ) + assert [via for via in ctrl.stackup.vias if via.properties["ConvertPolygonToCircle"] == "true"] + def test_add_layer_api_with_control_file(self): """Add new layers with control file.""" from pyedb.dotnet.edb_core.edb_data.control_file import ControlFile diff --git a/tests/legacy/system/test_edb_components.py b/tests/legacy/system/test_edb_components.py index d06868bdc5..a5e8655ae9 100644 --- a/tests/legacy/system/test_edb_components.py +++ b/tests/legacy/system/test_edb_components.py @@ -625,3 +625,10 @@ def test_properties(self, edb_examples): } edbapp.components["C378"].model_properties = pp assert edbapp.components["C378"].model_properties == pp + + def test_export_gds_comp_xml(self, edb_examples): + edbapp = edb_examples.get_si_verse() + xml_output = os.path.join(self.local_scratch.path, "test.xml") + assert edbapp.export_gds_comp_xml(["U1", "U2", "C2", "R1"], control_path=xml_output) + assert os.path.isfile(xml_output) + edbapp.close() diff --git a/tests/legacy/system/test_edb_modeler.py b/tests/legacy/system/test_edb_modeler.py index 98cc549be2..7e2921e684 100644 --- a/tests/legacy/system/test_edb_modeler.py +++ b/tests/legacy/system/test_edb_modeler.py @@ -85,9 +85,6 @@ def test_modeler_polygons(self): assert k.expand(0.0005) # edb.modeler.parametrize_polygon(k, poly_5953, offset_name=f"offset_{i}", origin=centroid) - poly_167 = [i for i in self.edbapp.modeler.paths if i.id == 167][0] - assert poly_167.expand(0.0005) - def test_modeler_paths(self, edb_examples): """Evaluate modeler paths""" edbapp = edb_examples.get_si_verse()