Ejemplo n.º 1
0
def import_oas(filename, cellname = None, flatten = False):
    if filename.lower().endswith('.gds'):
        # you are looking for import_gds
        retval = pg.import_gds(filename, cellname = cellname, flatten = flatten)
        return retval
    try:
        import klayout.db as pya
    except ImportError as err:
        err.args = ('[PHIDL] klayout package needed to import OASIS. pip install klayout\n' + err.args[0], ) + err.args[1:]
        raise
    if not filename.lower().endswith('.oas'): filename += '.oas'
    fileroot = os.path.splitext(filename)[0]
    tempfilename = fileroot + '-tmp.gds'

    layout = pya.Layout()
    layout.read(filename)
    # We want to end up with one Device. If the imported layout has multiple top cells,
    # a new toplevel is created, and they go into the second level
    if len(layout.top_cells()) > 1:
        topcell = layout.create_cell('toplevel')
        rot_DTrans = pya.DTrans.R0
        origin = pya.DPoint(0, 0)
        for childcell in layout.top_cells():
            if childcell == topcell: continue
            topcell.insert(pya.DCellInstArray(childcell.cell_index(), pya.DTrans(rot_DTrans, origin)))
    else:
        topcell = layout.top_cell()
    topcell.write(tempfilename)

    retval = pg.import_gds(tempfilename, cellname = cellname, flatten = flatten)
    os.remove(tempfilename)
    return retval
Ejemplo n.º 2
0
def cell_insert_cell(cell: Cell, other_cell: Cell, origin: DPoint,
                     angle: float):
    mag = 1
    rot = angle
    mirrx = False
    u = DPoint(origin)
    trans = kdb.DCplxTrans(mag, rot, mirrx, u)

    cell.insert(kdb.DCellInstArray(other_cell.cell_index(), trans))
    return cell
Ejemplo n.º 3
0
def cell_insert_cell(cell: Type[Cell], other_cell: Type[Cell],
                     origin: Type[DPoint], angle_deg: float) -> Type[Cell]:
    mag = 1
    rot = angle_deg
    mirrx = False
    u = DPoint(origin)
    trans = kdb.DCplxTrans(mag, rot, mirrx, u)

    cell.insert(kdb.DCellInstArray(other_cell.cell_index(), trans))
    return cell
Ejemplo n.º 4
0
        def wrapper_draw(self, cell):
            layout = cell.layout()
            try:
                layer_map_dict[layout]
            except KeyError:
                layer_map_dict[layout] = pya.LayerMap()

            # Adding the dbu of the layout in the hash (bit us in the butt last time)
            short_hash_pcell = produce_hash(self,
                                            extra=(layout.dbu, extra_hash))

            # cache paths
            cache_fname = f"cache_{self.__class__.__qualname__}_{short_hash_pcell}"
            cache_fname_gds = cache_fname + ".gds"
            cache_fname_pkl = cache_fname + ".klayout.pkl"

            os.makedirs(cache_dir, mode=0o775, exist_ok=True)

            cache_fpath_gds = os.path.join(cache_dir, cache_fname_gds)
            cache_fpath_pkl = os.path.join(cache_dir, cache_fname_pkl)

            if os.path.isfile(cache_fpath_gds) and os.path.isfile(
                    cache_fpath_pkl):
                with open(cache_fpath_pkl, "rb") as file:
                    ports, read_short_hash_pcell, cellname = pickle.load(file)  # pylint: disable=unused-variable

                logger.debug(
                    f"Reading from cache: {cache_fname}: {cellname}, {ports}")
                print("r", end="", flush=True)
                if not layout.has_cell(cache_fname):
                    read_layout(layout,
                                cache_fpath_gds,
                                disambiguation_name=cellname)
                retrieved_cell = layout.cell(cache_fname)
                cell.insert(
                    pya.DCellInstArray(
                        retrieved_cell.cell_index(),
                        pya.DTrans(pya.DTrans.R0, pya.DPoint(0, 0)),
                    ))
                # cell.move_tree(retrieved_cell)
            else:
                if layout.has_cell(cache_fname):
                    logger.warning(
                        f"WARNING: {cache_fname_gds} does not exist but {cache_fname} is in layout."
                    )

                # populating .gds and .pkl
                empty_layout = pya.Layout()
                empty_layout.dbu = layout.dbu
                empty_cell = empty_layout.create_cell(cell.name)
                filled_cell, ports = draw(self, empty_cell)

                logger.debug(
                    f"Writing to cache: {cache_fname}: {filled_cell.name}, {ports}"
                )
                print("w", end="", flush=True)

                cellname, filled_cell.name = filled_cell.name, cache_fname
                # There can be duplicate cell names in subcells here.
                # We are saving a list of them inside a property named CACHE_PROP_ID
                # So we need to allow the properties to be saved inside the gds file (incompatible with the GDS2 standard)
                save_options = pya.SaveLayoutOptions()
                save_options.gds2_write_file_properties = True
                empty_layout.write(cache_fpath_gds, save_options)
                with open(cache_fpath_pkl, "wb") as file:
                    pickle.dump((ports, short_hash_pcell, cellname), file)

                # Make sure we delete the empty_layout to not grow
                # helps debug
                layer_map_dict.pop(empty_layout, None)
                del empty_layout
                assert not layout.has_cell(cache_fname)

                read_layout(layout,
                            cache_fpath_gds,
                            disambiguation_name=cellname)
                retrieved_cell = layout.cell(cache_fname)
                cell.insert(
                    pya.DCellInstArray(
                        retrieved_cell.cell_index(),
                        pya.DTrans(pya.DTrans.R0, pya.DPoint(0, 0)),
                    ))

            return cell, ports
Ejemplo n.º 5
0
        def wrapper_draw(self, cell):
            global layer_map_dict
            layout = cell.layout()
            try:
                layer_map_dict[layout]
            except KeyError:
                layer_map_dict[layout] = pya.LayerMap()

            # Adding the dbu of the layout in the hash (bit us in the butt last time)
            short_hash_pcell = produce_hash(self, extra=(layout.dbu, extra_hash))

            # cache paths
            cache_fname = f"cache_{self.__class__.__qualname__}_{short_hash_pcell}"
            cache_fname_gds = cache_fname + ".gds"
            cache_fname_pkl = cache_fname + ".klayout.pkl"

            os.makedirs(cache_dir, mode=0o775, exist_ok=True)

            cache_fpath_gds = os.path.join(cache_dir, cache_fname_gds)
            cache_fpath_pkl = os.path.join(cache_dir, cache_fname_pkl)

            if os.path.isfile(cache_fpath_gds) and os.path.isfile(cache_fpath_pkl):
                with open(cache_fpath_pkl, "rb") as file:
                    ports, read_short_hash_pcell, cellname = pickle.load(file)
                if debug:
                    print(f"Reading from cache: {cache_fname}: {cellname}, {ports}")
                else:
                    print("r", end="", flush=True)
                if not layout.has_cell(cache_fname):
                    read_layout(layout, cache_fpath_gds)
                retrieved_cell = layout.cell(cache_fname)
                cell.insert(
                    pya.DCellInstArray(
                        retrieved_cell.cell_index(),
                        pya.DTrans(pya.DTrans.R0, pya.DPoint(0, 0)),
                    )
                )
                # cell.move_tree(retrieved_cell)
            else:
                if layout.has_cell(cache_fname):
                    print(
                        f"WARNING: {cache_fname_gds} does not exist but {cache_fname} is in layout."
                    )

                # populating .gds and .pkl
                empty_layout = pya.Layout()
                empty_layout.dbu = layout.dbu
                empty_cell = empty_layout.create_cell(cell.name)
                filled_cell, ports = draw(self, empty_cell)

                if debug:
                    print(
                        f"Writing to cache: {cache_fname}: {filled_cell.name}, {ports}"
                    )
                else:
                    print("w", end="", flush=True)

                cellname, filled_cell.name = filled_cell.name, cache_fname
                filled_cell.write(cache_fpath_gds)
                with open(cache_fpath_pkl, "wb") as file:
                    pickle.dump((ports, short_hash_pcell, cellname), file)

                # Make sure we delete the empty_layout to not grow
                # helps debug
                layer_map_dict.pop(empty_layout, None)
                del empty_layout
                assert not layout.has_cell(cache_fname)

                read_layout(layout, cache_fpath_gds)
                retrieved_cell = layout.cell(cache_fname)
                cell.insert(
                    pya.DCellInstArray(
                        retrieved_cell.cell_index(),
                        pya.DTrans(pya.DTrans.R0, pya.DPoint(0, 0)),
                    )
                )

            return cell, ports