Exemple #1
0
def select_instances(cell=None):
    lv = pya.Application.instance().main_window().current_view()
    if lv == None:
        raise Exception("No view selected")
    if cell is None:
        ly = lv.active_cellview().layout()
        if ly == None:
            raise Exception("No active layout")
        cell = lv.active_cellview().cell
        if cell == None:
            raise Exception("No active cell")
    else:
        ly = cell.layout()

    selection = lv.object_selection
    if selection == []:
        for instance in cell.each_inst():
            selection.append(pya.ObjectInstPath())
            selection[-1].top = cell.cell_index()
            selection[-1].append_path(pya.InstElement.new(instance))
        lv.object_selection = selection
    else:
        lv.object_selection = [o for o in selection if o.is_cell_inst()]

    return lv.object_selection
def select_paths_m(layers, cell=None, verbose=None):

    lv = pya.Application.instance().main_window().current_view()
    if lv == None:
        raise Exception("No view selected")

    if cell is None:
        ly = lv.active_cellview().layout()
        if ly == None:
            raise Exception("No active layout")
        cell = lv.active_cellview().cell
        if cell == None:
            raise Exception("No active cell")
    else:
        ly = cell.layout()

    selection = lv.object_selection
    if verbose:
        print("SiEPIC.utils.select_paths: selection, before: %s" %
              lv.object_selection)
    if selection == []:
        for layer, layer_str_name in layers:  # run through all the layers inputted into the function (allows for multiple path layer selections)
            itr = cell.begin_shapes_rec(ly.layer(layer))
            while not (itr.at_end()):
                if verbose:
                    print("SiEPIC.utils.select_paths: itr: %s" % itr)
                if itr.shape().is_path() and not itr.cell().pcell_parameters(
                ):  # must be a path and not a pcell
                    print('Name: ' + str(itr.cell().pcell_parameters()))
                    if verbose:
                        print("SiEPIC.utils.select_paths: path: %s" %
                              itr.shape())
                    selection.append(pya.ObjectInstPath())
                    selection[-1].layer = ly.layer(layer)
                    selection[-1].shape = itr.shape()
                    selection[-1].top = cell.cell_index()
                    selection[-1].cv_index = 0
                itr.next()
            #for o in selection: # set the LayerName property if the object (path) does not already have a LayerName
            #    if not o.shape.property('LayerName'): # check for LayerName property
            #        o.shape.set_property('LayerName', layer_str_name) # add LayerName propery if not present
        lv.object_selection = selection  # set the return item equal to selection after all loops are finished
    else:
        lv.object_selection = [
            o for o in selection
            if (not o.is_cell_inst() and not o.shape.cell.pcell_parameters())
            and o.shape.is_path()
        ]  # must be a path and not a pcell
    if verbose:
        print("SiEPIC.utils.select_paths: selection, after: %s" %
              lv.object_selection)
    return lv.object_selection
Exemple #3
0
def select_paths(layer, cell=None, verbose=None):
    if verbose:
        print("SiEPIC.utils.select_paths: layer: %s" % layer)

    lv = pya.Application.instance().main_window().current_view()
    if lv == None:
        raise Exception("No view selected")

    if cell is None:
        ly = lv.active_cellview().layout()
        if ly == None:
            raise Exception("No active layout")
        cell = lv.active_cellview().cell
        if cell == None:
            raise Exception("No active cell")
    else:
        ly = cell.layout()

    selection = lv.object_selection
    if verbose:
        print("SiEPIC.utils.select_paths: selection, before: %s" %
              lv.object_selection)
    if selection == []:
        itr = cell.begin_shapes_rec(ly.layer(layer))
        itr_count = 0
        while not (itr.at_end()):
            #            if verbose:
            #                print("SiEPIC.utils.select_paths: itr: %s" % itr)
            itr_count += 1
            if itr.shape().is_path():
                if verbose:
                    print("SiEPIC.utils.select_paths: path: %s" % itr.shape())
                selection.append(pya.ObjectInstPath())
                selection[-1].layer = ly.layer(layer)
                selection[-1].shape = itr.shape()
                selection[-1].top = cell.cell_index()
                selection[-1].cv_index = 0
            itr.next()
        if verbose:
            print("SiEPIC.utils.select_paths: # shapes founded: %s" %
                  itr_count)
        lv.object_selection = selection
    else:
        lv.object_selection = [
            o for o in selection
            if (not o.is_cell_inst()) and o.shape.is_path()
        ]
    if verbose:
        print("SiEPIC.utils.select_paths: selection, after: %s" %
              lv.object_selection)
    return lv.object_selection
def wireguide_to_path(cell=None):
    from . import _globals
    from .utils import get_layout_variables

    if cell is None:
        TECHNOLOGY, lv, ly, cell = get_layout_variables()
    else:
        TECHNOLOGY, lv, _, _ = get_layout_variables()
        ly = cell.layout()

    lv.transaction("wireguide to path")

    # record objects to delete:
    to_delete = []

    wireguides = select_wireguides(cell)
    selection = []
    for obj in wireguides:
        # path from wireguide guiding shape
        wireguide = obj.inst()
        layer_list = wireguide.cell.pcell_parameter(
            'layers'
        )  # get the list of layers in the wireguide pcell (should only be one)
        original_layer = ly.layer(
            TECHNOLOGY[layer_list[0]]
        )  # convert layer to understandable type for future functions

        from ._globals import KLAYOUT_VERSION

        if KLAYOUT_VERSION > 24:
            path = wireguide.cell.pcell_parameters_by_name()['path']
        else:
            # wireguide path and width from Wireguide PCell
            path1 = wireguide.cell.pcell_parameters_by_name()['path']
            path = pya.Path()
            path.width = wireguide.cell.pcell_parameters_by_name(
            )['width'] / TECHNOLOGY['dbu']
            pts = []
            for pt in [pt1 for pt1 in (path1).each_point()]:
                if type(pt) == pya.Point:
                    # for instantiated PCell
                    pts.append(pya.Point())
                else:
                    # for wireguide from path
                    pts.append(pya.Point().from_dpoint(
                        pt * (1 / TECHNOLOGY['dbu'])))
            path.points = pts

        selection.append(pya.ObjectInstPath())
        selection[-1].layer = original_layer
        # DPath.transformed requires DTrans. wireguide.trans is a Trans object
        if KLAYOUT_VERSION > 24:
            selection[-1].shape = cell.shapes(original_layer).insert(
                path.transformed(wireguide.trans.to_dtype(TECHNOLOGY['dbu'])))
        else:
            selection[-1].shape = cell.shapes(original_layer).insert(
                path.transformed(
                    pya.Trans(wireguide.trans.disp.x, wireguide.trans.disp.y)))

        selection[-1].top = obj.top
        selection[-1].cv_index = obj.cv_index

        # deleting the instance was ok, but would leave the cell which ends up as
        # an uninstantiated top cell
        to_delete.append(obj.inst())

    # deleting instance or cell should be done outside of the for loop,
    # otherwise each deletion changes the instance pointers in KLayout's
    # internal structure
    [t.delete() for t in to_delete]

    # Clear the layout view selection, since we deleted some objects (but
    # others may still be selected):
    lv.clear_object_selection()
    # Select the newly added objects
    lv.object_selection = selection
    # Record a transaction, to enable "undo"
    lv.commit()
def path_to_wireguide(cell=None,
                      lv_commit=True,
                      verbose=False,
                      select_wireguides=False):
    from . import _globals
    TECHNOLOGY, lv, ly, top_cell = get_layout_variables_m()

    if not cell:
        cell = top_cell

    if verbose:
        print("SiEPIC.scripts path_to_wireguide()")

    if lv_commit:
        lv.transaction("Path to Wireguide")

    layers_to_select = list()
    for key in TECHNOLOGY.keys():
        if 'Wireguide' in key:
            layers_to_select.append((TECHNOLOGY[key], key))
            print(key)

    selected_paths = select_paths_m(
        layers_to_select, cell,
        verbose=verbose)  # find all paths on the selected layers

    if verbose:
        print("SiEPIC.scripts path_to_wireguide(): selected_paths = %s" %
              selected_paths)
    selection = []

    warning = pya.QMessageBox()
    warning.setStandardButtons(pya.QMessageBox.Yes | pya.QMessageBox.Cancel)
    warning.setDefaultButton(pya.QMessageBox.Yes)

    params = {
        'radius': 0,
        'width': 2,
        'adiabatic': False,
        'bezier': '0',
        'offset': 0
    }  # set parameters

    if verbose:
        print("SiEPIC.scripts path_to_wireguide(): params = %s" % params)

    for obj in selected_paths:
        path = obj.shape.path

        dbu = obj.layout().dbu  # get the database units
        params[
            'width'] = path.width * dbu  # adjust the width and save for wireguide creation
        if obj.shape.property(
                'LayerName'
        ):  # check if obj has LayerName (for no mouse selections)
            input_layer_name = obj.shape.property(
                'LayerName')  # save layer name for wireguide creation
        else:  # find the name of the layer if not specified (for mouse selections)
            lv = pya.Application.instance().main_window().current_view()
            ly = lv.active_cellview().layout()
            dbu = ly.dbu
            lp_found = None
            iter = lv.begin_layers()  # loop through all layers
            while not iter.at_end():
                lp = iter.current()
                if lp.cellview() == obj.cv_index and lp.layer_index(
                ) == obj.layer:  # find specified layer within the layer loop
                    lp_found = lp  # save layer properties
                iter.next()
            input_layer_name = lp_found.name  # save layer name for wireguide creation

        path.unique_points()
        if not path.is_manhattan_endsegments():
            warning.setText(
                "Warning: Wireguide segments (first, last) are not Manhattan (vertical, horizontal)."
            )
            warning.setInformativeText("Do you want to Proceed?")
            if (pya.QMessageBox_StandardButton(
                    warning.exec_()) == pya.QMessageBox.Cancel):
                return
        if not path.is_manhattan():
            warning.setText(
                "Error: Wireguide segments are not Manhattan (vertical, horizontal). This is not supported in SiEPIC-Tools."
            )
            warning.setInformativeText("Do you want to Proceed?")
            if (pya.QMessageBox_StandardButton(
                    warning.exec_()) == pya.QMessageBox.Cancel):
                return
        if not path.radius_check(params['radius'] / TECHNOLOGY['dbu']):
            warning.setText(
                "Warning: One of the wireguide segments has insufficient length to accommodate the desired bend radius."
            )
            warning.setInformativeText("Do you want to Proceed?")
            if (pya.QMessageBox_StandardButton(
                    warning.exec_()) == pya.QMessageBox.Cancel):
                return

        path.snap_m(cell.find_pins())
        Dpath = path.to_dtype(TECHNOLOGY['dbu'])
        width_devrec = params[
            'width'] + _globals.WG_DEVREC_SPACE * 2  # get DevRec width based on the wireguide width found earlier
        try:
            pcell = ly.create_cell(
                "Wireguide",
                TECHNOLOGY['technology_name'],
                {
                    "path": Dpath,  # input parameters
                    "radius": params['radius'],
                    "width": params['width'],
                    "adiab": params['adiabatic'],
                    "bezier": params['bezier'],
                    "layers": [input_layer_name] + [
                        'DevRec'
                    ],  # set the layer as the same as the path that the wireguide came from (along with DevRec)
                    "widths": [params['width']] + [width_devrec],
                    "offsets": [params['offset']] + [0]
                })
            print(
                "SiEPIC.metal_menu_helper.path_to_wireguide(): Wireguide from %s, %s"
                % (TECHNOLOGY['technology_name'], pcell))
        except:
            pass
        if not pcell:
            try:
                pcell = ly.create_cell(
                    "Wireguide",
                    "SiEPIC General",
                    {
                        "path": Dpath,  # input parameters
                        "radius": params['radius'],
                        "width": params['width'],
                        "adiab": params['adiabatic'],
                        "bezier": params['bezier'],
                        "layers": [input_layer_name] + [
                            'DevRec'
                        ],  # set the layer as the same as the path that the wireguide came from (along with DevRec)
                        "widths": [params['width']] + [width_devrec],
                        "offsets": [params['offset']] + [0]
                    })
                print(
                    "SiEPIC.metal_menu_helper.path_to_wireguide(): Wireguide from SiEPIC General, %s"
                    % pcell)
            except:
                pass
        if not pcell:
            raise Exception(
                "'Wireguide' in 'SiEPIC General' library is not available. Check that the library was loaded successfully."
            )
        selection.append(pya.ObjectInstPath())
        selection[-1].top = obj.top
        selection[-1].append_path(
            pya.InstElement.new(
                cell.insert(
                    pya.CellInstArray(pcell.cell_index(),
                                      pya.Trans(pya.Trans.R0, 0, 0)))))

        obj.shape.delete()

    lv.clear_object_selection()
    if select_wireguides:
        lv.object_selection = selection
    if lv_commit:
        lv.commit()