def watch(self,dark = False):
        #Gerhards color scheme here :D, dark and smooth colours
        bkg = '#2C2A4A'

        colour = {}
        c_list = ['#DABFFF','#D5A021','#95B2B0','#7FDEFF','#D3BDB0','#89937C','#EAE2B7','#EDA4BD','#A0ACAD','#C8D6AF','#95B2B0','#BA274A','#2191FB','#FCB0B3','#CE7DA5','#CFFFB0','#907AD6','#A44200']
        for i in range(18):
            colour[(i,0)] = c_list[i]
        if dark:
            gdspy.LayoutViewer(depth=0, pattern={'default': 8}, background=bkg,color=colour)  # this opens a viewer
        else:
            gdspy.LayoutViewer(depth=0, pattern={'default': 8}, background='#FFFFFF')
Пример #2
0
def makeFile(filename, parts):
    lib = gdspy.GdsLibrary()
    cell = lib.new_cell('cell')
    cell.add(parts)
    cell.add(gdspy.Label('origin', [0, 0]))
    lib.write_gds(filename)
    gdspy.LayoutViewer()
Пример #3
0
def _example():
    file_path = './layout/Combinenation_SiO2.gds'
    origin = (100, 100)
    loadedcell = new_import.import_gds(file_path, origin, 'GC_a230_0_0')
    lib = gdspy.GdsLibrary(name='GC', precision=1e-10)
    device = lib.new_cell('loadedCell')
    device.add(loadedcell)
    gdspy.LayoutViewer(lib)
Пример #4
0
def generate_gds_file(layout_path, cellname):
    print(os.popen("mkdir -p " + layout_path + "/gds").read())
    print(
        os.popen("magic -Tscmos.tech -dnull -noconsole << EOF" +
                 get_gds_magic_script(layout_path, cellname) + "EOF").read())

    gdsii = gdspy.GdsLibrary()
    gdsii.read_gds(layout_path + "/gds/" + cellname + ".gds")
    cell = gdsii.extract(cellname)
    cell = cell.flatten()
    bb = cell.get_bounding_box()

    if '-st' in sys.argv:
        gdspy.LayoutViewer(cells=cellname)

    try:
        p11 = bb[0] - [orig_box_width, orig_box_width
                       ] - [orig_box_spacing, orig_box_spacing]
        p12 = bb[0] - [orig_box_spacing, orig_box_spacing]

        p21 = bb[1] + [orig_box_spacing, orig_box_spacing]
        p22 = bb[1] + [orig_box_spacing, orig_box_spacing
                       ] + [orig_box_width, orig_box_width]

        cell = cell.add(gdspy.Rectangle(p11, p12, 1))
        cell = cell.add(gdspy.Rectangle(p21, p22, 1))
        cell = cell.flatten()

        for layername in layer_mapping:
            ncell = cell.copy(layername, deep_copy=True)
            for idx in ncell.get_layers():
                if not idx in layer_mapping[layername]:
                    ncell = ncell.remove_polygons(
                        lambda pts, layer, datatype: layer == idx)
            ncell = ncell.add(gdspy.Rectangle(p11, p12, 1))
            ncell = ncell.add(gdspy.Rectangle(p21, p22, 1))
            ncell = ncell.flatten(single_layer=1, single_datatype=1)
            newgdsii = gdspy.GdsLibrary("mask_" + layername)
            newgdsii.add(ncell)
            newgdsii.write_gds(layout_path + "/gds/mask_" + layername + ".gds")

    except Exception as e:
        print("Can't do this:" + e)

    if '-s' in sys.argv:
        gdspy.LayoutViewer()
Пример #5
0
def generate_hall_bar_array(title, width_list, length_xx_list, dx, dy, orientation=0, leg_type='default'):
    """
    Generates a gdspy cell populated with single nanowires with the specified parameters
    :param title: str. Also filename
    :param width_list: list of floats. In um
    :param length_xx_list: list of floats. In um
    :param dx: float. Distance in um between neighboring structures
    :param dy: float. Distance in um between neighboring structures
    :param orientation: float in degrees. 0deg is horizontal.
    :param leg_type: {'fishbone', 'default'}
    :return: gdspy viewer
    """

    cell = gdspy.Cell(title)
    tools.make_title(title, cell, y=2 * dy, text_size=20)

    for i, w in enumerate(width_list):
        for j, L in enumerate(length_xx_list):
            wire_list = []  # will contain a wire and eventually labels, SmartWalls...
            x = j * dx
            y = - i * dy

            # labels
            if y == 0:
                x_label = 'L_xx=' + str(L)
                tools.make_x_label(x_label, wire_list, y=dy)
            if x == 0:
                y_label = 'w=' + str(int(w * 1000)) + 'nm\n'
                tools.make_y_label(y_label, wire_list, x=-dx)

            length_S_to_junction = 1.5
            length_total = L + 2 * length_S_to_junction
            length_leg = 1

            if j % 2 == 0:
                reservoir_enable = True
            else:
                reservoir_enable = False

            struct = tools.modified_hall_bar(w, length_total=length_total, length_leg=length_leg, length_xx=L,
                                             leg_offset=0, orientation=orientation, leg_type=leg_type,
                                             reservoir_enable=reservoir_enable)

            wire_list.append(struct)

            tools.add_label('X{}Y{}'.format(str(j), str(i)), wire_list, text_size=2, layer=20)  # adds a number label to the wire_cell
            # tools.add_label('W{}L{}X{}Y{}'.format(str(int(w*1000)), str(L), str(j), str(i)), wire_list, text_size=2)  # adds a number label to the wire_cell
            
            tools.move_list(wire_list, x, y)  # translates the entire wire_cell
            cell.add(wire_list)

    gdspy.write_gds(os.path.join(pattern_directory, title + '.gds'), cells=[cell], unit=1.0e-6, precision=1e-11)
    # 1um unit, 1e-11 precision allows total cell area up to ~20mm*20mm
    return gdspy.LayoutViewer(cells=[cell])
Пример #6
0
    def output(self, name=None, path='current'):
        """ Plot the cell or library using gdspy viewer. """

        glib = gdspy.GdsLibrary(name=self.name)

        if isinstance(self, spira.Library):
            glib = settings.get_library()
            glib += self
            glib.to_gdspy
        elif isinstance(self, spira.Cell):
            self.construct_gdspy_tree(glib)
        gdspy.LayoutViewer(library=glib)
Пример #7
0
def generate_2d_array(title, x_labels, y_labels, unit_function, arg_2d_list, dx=40, dy=40, preview=False):
    """
    Generates a 2D array of patterns with unique identifiers, a title, a column of labels on the left and a row of labels on top
    :param title: string, also filename
    :param x_labels: list of strings, each is the label for a column
    :param y_labels: list of strings, each is the label for a row
    :param unit_function: a function that takes each args tuple as parameters and returns a gdspy shape
    :param dx: float, x distance in um
    :param dy: float, y distance in um
    :return: writes a .gds file and launches the gdspy layout viewer
    """

    if len(x_labels) != len(arg_2d_list[0]) or len(y_labels) != len(arg_2d_list):
        print('Check dimensions of arg_2d_list and x/y_labels!')
        raise ValueError

    cell = gdspy.Cell(title)
    tools.make_title(title, cell, y=2 * dy, text_size=20)

    for y_count, arg_1d_list in enumerate(arg_2d_list):
        for x_count, args in enumerate(arg_1d_list):
            x = x_count * dx
            y = -y_count * dy
            wire_cell = []  # will contain a wire and eventually labels, SmartWalls...
            
            # labels
            if y == 0:
                x_label = x_labels[x_count]
                tools.make_x_label(x_label, wire_cell, y=dy, text_size=5)
            if x == 0:
                y_label = y_labels[y_count]
                tools.make_y_label(y_label, wire_cell, x=-dx/2, y=dy/2, text_size=4)

            wire_shape = unit_function(**args)
            if type(wire_shape) == tuple:
                for single_shape in wire_shape:
                    wire_cell.append(single_shape)
            else:
                wire_cell.append(wire_shape)

            if x_count != 0: # left most row can be labeled by the big X labels
                tools.add_label('X{}Y{}'.format(str(x_count), str(y_count)), wire_cell, x=-dx/2, y=dy/2, text_size=2, layer=11)  # adds a number label to the wire_cell
            
            tools.move_list(wire_cell, x, y)  # translates the entire wire_cell
            cell.add(wire_cell)
            
    gdspy.write_gds(os.path.join(pattern_directory, title + '.gds'), cells=[cell], unit=1.0e-6, precision=1e-11)
    # 1um unit, 1e-11 precision allows total cell area up to ~20mm*20mm
    if preview:
        return gdspy.LayoutViewer(cells=[cell])
Пример #8
0
    def gds(self, filename=None, view=False, extra=0, units='nms'):
        #check to make sure the geometry isn't an array
        if len(self.clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == 'nms':
            scale = 1
        elif units == 'microns':
            scale = 10**-3
        else:
            raise ValueError('Invalid units')

        #scale to proper units
        sc_radius = self.radius * scale
        sc_gap = self.gap * scale
        sc_width = self.width * scale
        sc_length = self.length * scale

        #write to GDS
        pathTop = gdspy.Path(sc_width,
                             (sc_radius + sc_length / 2,
                              sc_radius + sc_width / 2 + sc_gap / 2 + extra))
        pathTop.segment(extra, '-y')
        pathTop.arc(sc_radius, 0, -np.pi / 2)
        pathTop.segment(sc_length, '-x')
        pathTop.arc(sc_radius, -np.pi / 2, -np.pi)
        pathTop.segment(extra, '+y')

        pathBottom = gdspy.Path(sc_width,
                                (-sc_radius - sc_width / 2 - sc_length / 2 -
                                 extra, -sc_gap / 2 - sc_width / 2))
        pathBottom.segment(
            2 * (sc_radius + sc_width / 2) + sc_length + 2 * extra, '+x')

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell('C0')
        path_cell.add(pathTop)
        path_cell.add(pathBottom)

        if view:
            gdspy.LayoutViewer(cells='C0')

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
Пример #9
0
def bitmarker_2inch():
    dx = 20
    dy = 20 
    # text_size = 100
    nrows = 32
    ncols = 32
    output_dir = r'/Users/wgz/Downloads'
    title = 'BitmarkerArray'
    cell = gp.Cell(title)
    for x in range(ncols):
        for y in range(nrows):
            # x_label = string.ascii_uppercase[x]
            # y_label = str(y)
            # shape = gp.Text(x_label+y_label, text_size, position=(x*dx, -y*dy), layer=10)
            shape = tools.bitmarker(x, y)
            shape.translate(x*dx, -y*dy)
            cell.add(shape)
    gp.LayoutViewer(cells=[cell])
    gp.write_gds(os.path.join(output_dir, title + '.gds'), cells=[cell], unit=1.0e-6, 
    precision=1e-10)
Пример #10
0
    def gds(self, filename=None, extra=0, units='microns', view=False):
        """Writes the geometry to the gds file

        Args:
            filename (str): location to save file to, or if you don't want to defaults to None
            extra    (int): extra straight portion to add to ends of waveguides to make room in simulation
                                (input with units same as units input)
            units    (str): either 'microns' or 'nms'. Units to save gds file in
        """
        #check to make sure the geometry isn't an array
        if len(self.clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == 'nms':
            scale = 1
        elif units == 'microns':
            scale = 10**-3
        else:
            raise ValueError('Invalid units')

        #scale to proper units
        sc_width = self.width * scale
        sc_length = self.length * scale

        #write to GDS
        path = gdspy.Path(sc_width, (-sc_length / 2 - extra, 0))
        path.segment(2 * extra + sc_length, '+x')

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell('C0')
        path_cell.add(path)

        if view:
            gdspy.LayoutViewer(cells='C0')

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
Пример #11
0
def check(device: Device, joined=False, blocking=True, gds=False):
    ''' Shows the device layout.

        If run by terminal, blocks script until window is closed.

        Parameters
        ----------
            device : phidl.Device

            joined : boolean (optional, default False)
                if true, returns a flattened/joined version of device

            gds : boolean
                if true, view in gdspy viewer

    '''
    set_quickplot_options(blocking=blocking)

    if joined:

        cell = join(device)

    else:

        cell = device

    if gds:

        lib = gdspy.GdsLibrary()

        gcell = lib.new_cell("Output")

        gcell.add(cell)

        gdspy.LayoutViewer(lib)

    else:

        qp(cell)
Пример #12
0
    def gdsii_output(self, name=None, view_type='hierarchical', disabled_ports=None, view=True):

        _default = {'cells': True, 'polygons': True, 'arrows': True, 'labels': True}
        # _default = {'cells': True, 'polygons': False, 'arrows': False, 'labels': False}

        if disabled_ports is not None:
            _default.update(disabled_ports)

        G = OutputGdsii(cell=self, view_type=view_type, disabled_ports=_default)

        gdspy_library = gdspy.GdsLibrary(name=self.name)
        G.gdspy_gdsii_output(gdspy_library)

        if name is not None:
            writer = gdspy.GdsWriter('{}.gds'.format(name), unit=1.0e-6, precision=1.0e-12)
            for name, cell in gdspy_library.cell_dict.items():
                writer.write_cell(cell)
                del cell
            writer.close()

        if view is True:
            gdspy.LayoutViewer(library=gdspy_library)
Пример #13
0
 def start_viewer(self):
     import gdspy
     gdspy.LayoutViewer(library=self.get_gdspy_lib(), depth=10)
Пример #14
0
if __name__ == "__main__":
    from . import *

    top = gdspy.Cell("top")
    wgt_strip = WaveguideTemplate(bend_radius=50,
                                  wg_type="strip",
                                  wg_width=0.7)
    wgt_slot = WaveguideTemplate(bend_radius=50,
                                 wg_type="slot",
                                 wg_width=0.7,
                                 slot=0.2)

    wg1 = Waveguide([(0, 0), (100, 100)], wgt_strip)
    tk.add(top, wg1)

    ycoup = StripSlotYConverter(wgt_strip,
                                wgt_slot,
                                10.0,
                                0.2,
                                end_slot_width=0.1,
                                **wg1.portlist["output"])
    tk.add(top, ycoup)

    (x1, y1) = ycoup.portlist["output"]["port"]
    wg2 = Waveguide([(x1, y1), (x1 + 100, y1 + 100)], wgt_slot)
    tk.add(top, wg2)

    gdspy.LayoutViewer(cells=top)
#    gdspy.write_gds('stripslotyconverter.gds', unit=1.0e-6, precision=1.0e-9)
Пример #15
0
                                "xor",
                                precision=0.1 * tolerance,
                                max_points=0,
                            ).polygons[0]
                            break
                        elif gdspy.inside(polys[i][:1], [poly],
                                          precision=0.1 * tolerance)[0]:
                            p = polys.pop(i)
                            poly = gdspy.boolean(
                                [p],
                                [poly],
                                "xor",
                                precision=0.1 * tolerance,
                                max_points=0,
                            ).polygons[0]
                        i -= 1
                xmax = max(xmax, poly[:, 0].max())
                polys.append(poly)
    return polys


if __name__ == "__main__":
    fp = FontProperties(family="serif", style="italic")
    text = gdspy.PolygonSet(render_text("Text rendering", 10, font_prop=fp),
                            layer=1)
    lib = gdspy.GdsLibrary()
    cell = lib.new_cell("TXT")
    cell.add(text)
    lib.write_gds("fonts.gds")
    gdspy.LayoutViewer(lib)
Пример #16
0
    def gds(self,
            filename=None,
            view=False,
            extra=0,
            units='nms',
            sbend_h=0,
            sbend_v=0):
        #check to make sure the geometry isn't an array
        if len(self.clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == 'nms':
            scale = 1
        elif units == 'microns':
            scale = 10**-3
        else:
            raise ValueError('Invalid units')

        #scale to proper units
        sc_width = self.width * scale
        sc_gap = self.gap * scale
        sc_length = self.length * scale
        sc_H = self.H * scale
        sc_V = self.V * scale

        #make parametric functions
        sbendDown = lambda x: (sc_H * x, -sc_V / 2 * (1 - np.cos(np.pi * x)))
        sbendUp = lambda x: (sc_H * x, sc_V / 2 * (1 - np.cos(np.pi * x)))
        dsbendDown = lambda x: (sc_H, -np.pi * sc_V / 2 * np.sin(np.pi * x))
        dsbendUp = lambda x: (sc_H, np.pi * sc_V / 2 * np.sin(np.pi * x))

        sbend = False
        if sbend_h != 0 and sbend_v != 0:
            sbend = True
        sbendDownExtra = lambda x: (sbend_h * x, -sbend_v / 2 *
                                    (1 - np.cos(np.pi * x)))
        sbendUpExtra = lambda x: (sbend_h * x, sbend_v / 2 *
                                  (1 - np.cos(np.pi * x)))
        dsbendDownExtra = lambda x: (sbend_h, -np.pi * sbend_v / 2 * np.sin(
            np.pi * x))
        dsbendUpExtra = lambda x: (sbend_h, np.pi * sbend_v / 2 * np.sin(np.pi
                                                                         * x))

        #write to GDS
        pathTop = gdspy.Path(sc_width,
                             (-sc_length / 2 - sc_H - sbend_h - extra,
                              sc_V + sbend_v + sc_width / 2 + sc_gap / 2))
        pathTop.segment(extra, '+x')
        if sbend: pathTop.parametric(sbendDownExtra, dsbendDownExtra)
        pathTop.parametric(sbendDown, dsbendDown)
        pathTop.segment(sc_length, '+x')
        pathTop.parametric(sbendUp, dsbendUp)
        if sbend: pathTop.parametric(sbendUpExtra, dsbendUpExtra)
        pathTop.segment(extra, '+x')

        pathBottom = gdspy.Path(sc_width,
                                (-sc_length / 2 - sc_H - sbend_h - extra,
                                 -sc_V - sbend_v - sc_width / 2 - sc_gap / 2))
        pathBottom.segment(extra, '+x')
        if sbend: pathBottom.parametric(sbendUpExtra, dsbendUpExtra)
        pathBottom.parametric(sbendUp, dsbendUp)
        pathBottom.segment(sc_length, '+x')
        pathBottom.parametric(sbendDown, dsbendDown)
        if sbend: pathBottom.parametric(sbendDownExtra, dsbendDownExtra)
        pathBottom.segment(extra, '+x')

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell('C0')
        path_cell.add(pathTop)
        path_cell.add(pathBottom)

        if view:
            gdspy.LayoutViewer(cells='C0')

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
Пример #17
0
                max_points=199,
                **cur_spec
            )
            self.add(clad)

    def __build_ports(self):
        # Portlist format:
        # example: example:  {'port':(x_position, y_position), 'direction': 'NORTH'}
        self.portlist["input"] = {"port": self.input_port, "direction": "WEST"}
        self.portlist["output"] = {"port": self.output_port, "direction": "EAST"}


if __name__ == "__main__":
    from . import *

    top = gdspy.Cell("top")
    wgt = WaveguideTemplate(bend_radius=50, resist="+")

    wg1 = Waveguide([(0, 0), (100, 0)], wgt)
    tk.add(top, wg1)

    sb1 = SBend(wgt, 200.0, 100.0, **wg1.portlist["output"])
    tk.add(top, sb1)

    x, y = sb1.portlist["output"]["port"]
    wg2 = Waveguide([(x, y), (x + 100, y)], wgt)
    tk.add(top, wg2)

    gdspy.LayoutViewer(cells=top, depth=3)
#    gdspy.write_gds('sbend.gds', unit=1.0e-6, precision=1.0e-9)
Пример #18
0
        self.portlist["input"] = {"port": self.portlist_input, "direction": "WEST"}
        self.portlist["output"] = {"port": self.portlist_output, "direction": "EAST"}


if __name__ == "__main__":
    from picwriter.components.waveguide import WaveguideTemplate

    gdspy.current_library = gdspy.GdsLibrary()
    top = gdspy.Cell("top")
    wgt = WaveguideTemplate(
        bend_radius=50, wg_width=1.0, clad_width=10.0, euler_bend=True
    )

    sp1 = Spiral(
        wgt,
        width=2700.0,
        length=2900.0,
        spacing=20.0,
        parity=1,
        port=(0, 0),
        direction="EAST",
    )
    tk.add(top, sp1)

    print("length is " + str(sp1.get_spiral_length()))
    print("portlist = " + str(sp1.portlist))

    gdspy.LayoutViewer(cells="top")
    # gdspy.write_gds('spiral.gds', unit=1.0e-6, precision=1.0e-9)
Пример #19
0
    chip1.set_current_coor(['0.9mm', con1], [1,0])
    chip1.draw_capa_inline('capa_readout', PM.track, PM.gap, '100um', PM.gap_capa_readout, n_pad=2)
    
    PM.set_variable('tune_ro', '3mm')
    chip1.double_port('constrain_readout1', [PM.x_T-PM.tune_ro, PM.y_T], [1,0], PM.track, PM.gap)
    chip1.double_port('constrain_readout2', [PM.x_T-0.3574*PM.tune_ro, 0.5*(PM.y_T+con1)], [0,-1] ,PM.track, PM.gap)

    chip1.draw_cable('readout', 'trm_portOut2','constrain_readout1_front', 'constrain_readout1_back','constrain_readout2_front', 'constrain_readout2_back', 'capa_readout_outPort1', is_bond=is_bond, fillet=PM.fillet)
    chip1.draw_cable('bef_capa', 'capa_readout_outPort2', chip1.name+'in_readoutiOut', is_bond=is_bond, fillet=PM.fillet)
#

gdspy.write_gds('test.gds', unit=1.0, precision=1e-9)
t2 = time.time()
print("execution time: ", t2-t1)
#%%
gdspy.LayoutViewer(library=gdspy.current_library, pattern={'default': 8},background='#FFFFFF')
#### Test junctions
#
#if litho and 1:
#    PM.set_variable('x_D', '4.6mm')
#    PM.set_variable('y_D', '3.6mm')
#    PM.set_variable('dose_pad', '100um')
#    PM.set_variable('dose_sep', '100um')
#    PM.set_variable('dose_cor', '10um')
#    PM.key_elt('dose_test', [PM.x_D, PM.y_D], [1,0])
#    dose_mat = [2,6]
#    
#    PM.key_elt('align_dose_test', PM.dose_test.pos + 0.5*Vector([2*PM.dose_pad*dose_mat[0] + 3*PM.dose_sep*dose_mat[0] - PM.dose_cor*(2*dose_mat[0]-1), PM.dose_pad*dose_mat[1] + PM.dose_sep*(dose_mat[1]+1)]), PM.dose_test.ori)
#    PM.align_dose_test.draw_alignement_marks('20um', ['0.3mm', '0.7mm'])
#    PM.key_elt('align_chip', [0.5*PM.chip_width, 0.5*PM.chip_length], PM.dose_test.ori)
#    PM.align_chip.draw_alignement_marks('80um', ['3.5mm', '3.2mm'])
Пример #20
0
 def viewer(self, item):
     self.collect(item)
     library = gdspy.GdsLibrary(name=self.file_name)
     for c in self.collector.values():
         library.add(c)
     gdspy.LayoutViewer(library=library)
Пример #21
0
    gp.write_gds(os.path.join(output_dir, title + '.gds'), cells=[cell], unit=1.0e-6, precision=1e-10)


def bitmarker_2inch():
    dx = 20
    dy = 20 
    # text_size = 100
    nrows = 32
    ncols = 32
    output_dir = r'/Users/wgz/Downloads'
    title = 'BitmarkerArray'
    cell = gp.Cell(title)
    for x in range(ncols):
        for y in range(nrows):
            # x_label = string.ascii_uppercase[x]
            # y_label = str(y)
            # shape = gp.Text(x_label+y_label, text_size, position=(x*dx, -y*dy), layer=10)
            shape = tools.bitmarker(x, y)
            shape.translate(x*dx, -y*dy)
            cell.add(shape)
    gp.LayoutViewer(cells=[cell])
    gp.write_gds(os.path.join(output_dir, title + '.gds'), cells=[cell], unit=1.0e-6, 
    precision=1e-10)

bitmarker_array(cell)

gp.LayoutViewer(cells=[cell])

bitmarker_array()
Пример #22
0
    def gds(self, filename=None, view=False, extra=0, units="nms"):
        """Writes the geometry to the gds file.

        Parameters
        ----------
        filename : str, optional
            Location to save file to. Defaults to None.
        extra : int, optional
            Extra straight portion to add to ends of waveguides to make room in simulation
            (units same as units parameter). Defaults to 0.
        units : {'microns' or 'nms'}, optional
            Units to save gds file in. Defaults to microns.
        view : bool, optional
            Whether to visually show gds file. Defaults to False.
        """
        # check to make sure the geometry isn't an array
        if len(self._clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == "nms":
            scale = 1e-3
        elif units == "microns":
            scale = 1
        else:
            raise ValueError("Invalid units")

        # scale to proper units
        sc_radius = self.radius * scale
        sc_gap = self.gap * scale
        sc_width = self.width * scale
        sc_length = self.length * scale

        # write to GDS
        pathTop = gdspy.Path(
            sc_width,
            (-sc_length / 2, 2 * sc_radius + sc_width / 2 + sc_gap / 2))
        pathTop.segment(sc_length, "+x")
        pathTop.turn(sc_radius, "rr")
        pathTop.segment(sc_length, "-x")
        pathTop.turn(sc_radius, "rr")

        pathBottom = gdspy.Path(
            sc_width,
            (-sc_radius - sc_width / 2 - sc_length / 2,
             -sc_gap / 2 - sc_width / 2),
        )
        pathBottom.segment(2 * (sc_radius + sc_width / 2) + sc_length, "+x")

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell("C0")
        path_cell.add(pathTop)
        path_cell.add(pathBottom)

        if view:
            gdspy.LayoutViewer(cells="C0")

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
Пример #23
0
        (40, 251),  #M4 lbl
        (45, 0),  #V4
        (50, 0),  #M5
        (50, 251),  #M5 lbl
        (55, 0),  #V5
        (60, 0),  #M6
        (60, 251),  #M6 lbl
        (65, 0),  #V6
        (70, 0),  #M7
        (70, 251),  #M7 lbl
        (75, 0),  #V7
        (80, 0),  #M8
        (80, 251),  #M8 lbl
        (85, 0),  #V8
        (88, 0),  #SDT
        (90, 0),  #M9
        (90, 251),  #M9 lbl
        (95, 0),  #V9
        (96, 0),  #Pad
        (97, 0),  #SLVT
        (98, 0),  #LVT
        (99, 0),  #SRAMDRC
        (100, 0),  #BOUNDARY
        (101, 0),  #TEXT
        (110, 0),  #SRAMVT
        (235, 5)  #DIEAREA
    ]

    print('Opening layout in gdspy...')
    gdspy.LayoutViewer(gds_lib, hidden_types=hidden, depth=1)
Пример #24
0
 def watch(self):
     gdspy.LayoutViewer(depth=0,
                        pattern={'default': 8},
                        background='#FFFFFF')  # this opens a viewer
Пример #25
0
 def watch_cells(self, num):
     gdspy.LayoutViewer(cells=self.cells[num])
Пример #26
0
def create_sim_space(
    gds_fg_name: str,
    gds_bg_name: str,
    grating_len: float = 12000,
    etch_frac: float = 0.5,
    box_thickness: float = 2000,
    wg_width: float = 12000,
    wg_thickness: float = 220,
    buffer_len: float = 1500,
    dx: int = 40,
    num_pmls: int = 10,
    visualize: bool = False,
) -> optplan.SimulationSpace:
    """Creates the simulation space.

    The simulation space contains information about the boundary conditions,
    gridding, and design region of the simulation.

    Args:
        gds_fg_name: Location to save foreground GDS.
        gds_bg_name: Location to save background GDS.
        grating_len: Length of the grating coupler and design region.
        etch_frac: Etch fraction of the grating. 1.0 indicates a fully-etched
            grating.
        box_thickness: Thickness of BOX layer in nm.
        wg_thickness: Thickness of the waveguide.
        wg_width: Width of the waveguide.
        buffer_len: Buffer distance to put between grating and the end of the
            simulation region. This excludes PMLs.
        dx: Grid spacing to use.
        num_pmls: Number of PML layers to use on each side.
        visualize: If `True`, draws the polygons of the GDS file.

    Returns:
        A `SimulationSpace` description.
    """
    # Calculate the simulation size, including  PMLs
    sim_size = [
        grating_len + 2 * buffer_len + dx * num_pmls,
        wg_width + 2 * buffer_len + dx * num_pmls
    ]
    # First, we use `gdspy` to draw the waveguides and shapes that we would
    # like to use. Instead of programmatically generating a GDS file using
    # `gdspy`, we could also simply provide a GDS file (e.g. drawn using
    # KLayout).

    # Declare some constants to represent the different layers.
    LAYER_SILICON_ETCHED = 100
    LAYER_SILICON_NONETCHED = 101

    # Create rectangles corresponding to the waveguide, the BOX layer, and the
    # design region. We extend the rectangles outside the simulation region
    # by multiplying locations by a factor of 1.1.

    # We distinguish between the top part of the waveguide (which is etched)
    # and the bottom part of the waveguide (which is not etched).
    waveguide_top = gdspy.Rectangle((-1.1 * sim_size[0] / 2, -wg_width / 2),
                                    (-grating_len / 2, wg_width / 2),
                                    LAYER_SILICON_ETCHED)
    waveguide_bottom = gdspy.Rectangle((-1.1 * sim_size[0] / 2, -wg_width / 2),
                                       (grating_len / 2, wg_width / 2),
                                       LAYER_SILICON_NONETCHED)
    design_region = gdspy.Rectangle((-grating_len / 2, -wg_width / 2),
                                    (grating_len / 2, wg_width / 2),
                                    LAYER_SILICON_ETCHED)

    # Generate the foreground and background GDS files.
    gds_fg = gdspy.Cell("FOREGROUND", exclude_from_current=True)
    gds_fg.add(waveguide_top)
    gds_fg.add(waveguide_bottom)
    gds_fg.add(design_region)

    gds_bg = gdspy.Cell("BACKGROUND", exclude_from_current=True)
    gds_bg.add(waveguide_top)
    gds_bg.add(waveguide_bottom)

    gdspy.write_gds(gds_fg_name, [gds_fg], unit=1e-9, precision=1e-9)
    gdspy.write_gds(gds_bg_name, [gds_bg], unit=1e-9, precision=1e-9)

    if visualize:
        gdspy.LayoutViewer(cells=[gds_fg])
        gdspy.LayoutViewer(cells=[gds_bg])

    # The BOX layer/silicon device interface is set at `z = 0`.
    #
    # Describe materials in each layer.
    # We actually have four material layers:
    # 1) Silicon substrate
    # 2) Silicon oxide BOX layer
    # 3) Bottom part of grating that is not etched
    # 4) Top part of grating that can be etched.
    #
    # The last two layers put together properly describe a partial etch.
    #
    # Note that the layer numbering in the GDS file is arbitrary. In our case,
    # layer 100 and 101 correspond to actual structure. Layer 300 is a dummy
    # layer; it is used for layers that only have one material (i.e. the
    # background and foreground indices are identical) so the actual structure
    # used does not matter.
    stack = [
        optplan.GdsMaterialStackLayer(
            foreground=optplan.Material(mat_name="Si"),
            background=optplan.Material(mat_name="Si"),
            # Note that layer number here does not actually matter because
            # the foreground and background are the same material.
            gds_layer=[300, 0],
            extents=[-10000, -box_thickness],
        ),
        optplan.GdsMaterialStackLayer(
            foreground=optplan.Material(mat_name="SiO2"),
            background=optplan.Material(mat_name="SiO2"),
            gds_layer=[300, 0],
            extents=[-box_thickness, 0],
        ),
    ]
    # If `etch-frac` is 1, then we do not need two separate layers.
    if etch_frac != 1:
        stack.append(
            optplan.GdsMaterialStackLayer(
                foreground=optplan.Material(mat_name="Si"),
                background=optplan.Material(mat_name="SiO2"),
                gds_layer=[LAYER_SILICON_NONETCHED, 0],
                extents=[0, wg_thickness * (1 - etch_frac)],
            ))
    stack.append(
        optplan.GdsMaterialStackLayer(
            foreground=optplan.Material(mat_name="Si"),
            background=optplan.Material(mat_name="SiO2"),
            gds_layer=[LAYER_SILICON_ETCHED, 0],
            extents=[wg_thickness * (1 - etch_frac), wg_thickness],
        ))

    mat_stack = optplan.GdsMaterialStack(
        # Any region of the simulation that is not specified is filled with
        # oxide.
        background=optplan.Material(mat_name="SiO2"),
        stack=stack,
    )

    sim_z_start = -box_thickness - 1000
    sim_z_end = wg_thickness + 1500

    # Create a simulation space for both continuous and discrete optimization.
    simspace = optplan.SimulationSpace(
        name="simspace",
        mesh=optplan.UniformMesh(dx=dx),
        eps_fg=optplan.GdsEps(gds=gds_fg_name, mat_stack=mat_stack),
        eps_bg=optplan.GdsEps(gds=gds_bg_name, mat_stack=mat_stack),
        # Note that we explicitly set the simulation region. Anything
        # in the GDS file outside of the simulation extents will not be drawn.
        sim_region=optplan.Box3d(
            center=[0, 0, (sim_z_start + sim_z_end) / 2],
            extents=[sim_size[0], dx, sim_z_end - sim_z_start],
        ),
        selection_matrix_type="uniform",
        # PMLs are applied on x- and z-axes. No PMLs are applied along y-axis
        # because it is the axis of translational symmetry.
        pml_thickness=[num_pmls, num_pmls, 0, 0, num_pmls, num_pmls],
    )

    if visualize:
        # To visualize permittivity distribution, we actually have to
        # construct the simulation space object.
        import matplotlib.pyplot as plt
        from spins.invdes.problem_graph.simspace import get_fg_and_bg

        context = workspace.Workspace()
        eps_fg, eps_bg = get_fg_and_bg(context.get_object(simspace), wlen=1550)

        def plot(x):
            plt.imshow(np.abs(x)[:, 0, :].T.squeeze(), origin="lower")

        plt.figure()
        plt.subplot(3, 1, 1)
        plot(eps_fg[2])
        plt.title("eps_fg")

        plt.subplot(3, 1, 2)
        plot(eps_bg[2])
        plt.title("eps_bg")

        plt.subplot(3, 1, 3)
        plot(eps_fg[2] - eps_bg[2])
        plt.title("design region")
        plt.show()
    return simspace
Пример #27
0
import gdspy

# Create the geometry: a single rectangle.
rect = gdspy.Rectangle((0, 0), (2, 1))
cell = gdspy.Cell("FIRST")
cell.add(rect)
# Save all created cells in file 'first.gds'.
gdspy.write_gds("first.gds")
# Optionally, display all cells using the internal viewer.
gdspy.LayoutViewer(gdspy.current_library)
Пример #28
0
    def gds(self,
            filename=None,
            extra=0,
            units='microns',
            view=False,
            sbend_h=0,
            sbend_v=0):
        #check to make sure the geometry isn't an array
        if len(self.clean_args(None)[0]) != 1:
            raise ValueError(
                "You have changing geometries, making gds doesn't make sense")

        if units == 'nms':
            scale = 1
        elif units == 'microns':
            scale = 10**-3
        else:
            raise ValueError('Invalid units')

        #scale to proper units
        sc_zmin = self.zmin * scale
        sc_zmax = self.zmax * scale
        sc_width = self.width * scale
        cL = (sc_zmax - sc_zmin)
        cH = self.gap(self.zmin) * scale / 2

        #make parametric functions
        paraTop = lambda x: (x * (sc_zmax - sc_zmin) + sc_zmin, scale * self.
                             gap(x * (self.zmax - self.zmin) + self.zmin
                                 ) / 2 + sc_width / 2)
        paraBottom = lambda x: (x * (sc_zmax - sc_zmin) + sc_zmin, -scale *
                                self.gap(x * (self.zmax - self.zmin) + self.
                                         zmin) / 2 - sc_width / 2)
        #dparaTop    = lambda x: (sc_zmax-sc_zmin, scale*(self.zmax-self.zmin)*self.dgap(x*(self.zmax-self.zmin)+self.zmin)/2)
        #dparaBottom = lambda x: (sc_zmax-sc_zmin, -scale*(self.zmax-self.zmin)*self.dgap(x*(self.zmax-self.zmin)+self.zmin)/2)

        sbend = False
        if sbend_h != 0 and sbend_v != 0:
            sbend = True
        sbendDown = lambda x: (sbend_h * x, -sbend_v / 2 *
                               (1 - np.cos(np.pi * x)))
        sbendUp = lambda x: (sbend_h * x, sbend_v / 2 *
                             (1 - np.cos(np.pi * x)))
        dsbendDown = lambda x: (sbend_h, -np.pi * sbend_v / 2 * np.sin(np.pi *
                                                                       x))
        dsbendUp = lambda x: (sbend_h, np.pi * sbend_v / 2 * np.sin(np.pi * x))

        #write to GDS
        pathTop = gdspy.Path(
            sc_width, (sc_zmin - extra - sbend_h, cH + sc_width / 2 + sbend_v))
        pathTop.segment(extra, '+x')
        if sbend: pathTop.parametric(sbendDown, dsbendDown)
        pathTop.parametric(paraTop, relative=False)
        if sbend: pathTop.parametric(sbendUp, dsbendUp)
        pathTop.segment(extra, '+x')

        pathBottom = gdspy.Path(
            sc_width,
            (sc_zmin - extra - sbend_h, -cH - sc_width / 2 - sbend_v))
        pathBottom.segment(extra, '+x')
        if sbend: pathBottom.parametric(sbendUp, dsbendUp)
        pathBottom.parametric(paraBottom, relative=False)
        if sbend: pathBottom.parametric(sbendDown, dsbendDown)
        pathBottom.segment(extra, '+x')

        gdspy.current_library = gdspy.GdsLibrary()
        path_cell = gdspy.Cell('C0')
        path_cell.add(pathTop)
        path_cell.add(pathBottom)

        if view:
            gdspy.LayoutViewer(cells='C0')

        if filename is not None:
            writer = gdspy.GdsWriter(filename, unit=1.0e-6, precision=1.0e-9)
            writer.write_cell(path_cell)
            writer.close()
Пример #29
0
# give the disks an alignment mark since they will be written with a different dose
alignment_cross_disc = alignment_mark(10, 100, ld_disc)

align_cell = gdspy.Cell('alignment marks')
align_cell.add([alignment_cross, alignment_cross_ebeam, alignment_cross_disc])
alignment_cell = gdspy.CellArray(align_cell, 2, 2, (18000, 16000),
                                 (-9000, -8000))
main.add(alignment_cell)

# now add alignment marks for the dicing street for each chip
DSE_alignment_cross = alignment_mark(20, 200, ld_opt)
DSE_cell = gdspy.Cell('DSE alignment marks')
DSE_cell.add(DSE_alignment_cross)
DSE1 = gdspy.CellArray(DSE_cell, 2, 2, (7000, 4000),
                       (X_MIN - 500, Y_MAX - 2000))
DSE2 = gdspy.CellArray(DSE_cell, 2, 2, (7000, 4000),
                       (X_RIGHT - 500, Y_MAX - 2000))
DSE3 = gdspy.CellArray(DSE_cell, 2, 2, (7000, 4000),
                       (X_MIN - 500, Y_MIN - 2000))
main.add([DSE1, DSE2, DSE3])

main_ref = gdspy.CellReference(main)

final = gdspy.Cell('Final')
final.add(main_ref)
#gdspy.top_level()

gdspy.write_gds('07-19-20_disks_rings.gds')
gdspy.LayoutViewer()
Пример #30
0
                            elbow_point=(0, 0),
                            joint_point=(0, 100),
                            trace=coupled_cpw_trace,
                            gap=coupled_cpw_gap),
        cpw.CPW(outline=[(0, 0), (0, 500), (300, 500), (300, 700)], trace=coupled_cpw_trace,
                gap=coupled_cpw_gap),
        cpw.CPWRoundedOpen(joint_point=(0, 0),
                           open_point=(0, 100),
                           trace=coupled_cpw_trace,
                           gap=coupled_cpw_gap,
                           # Use default ground=None because this CPW will be drawn negative
                           # Use default open_at_start=False because this is the last Segment
                           )
    ])
    halfwave_cpw.draw(cell=main_cell, origin=(-1500, coupled_cpw_distance), layer=2)

    # Save the gds file and return the library object
    gds_filename = 'cpw.gds'
    if not os.path.exists(output_directory):
        os.mkdir(output_directory)
    full_filename = os.path.join(output_directory, gds_filename)
    library.write_gds(outfile=full_filename)  # This will overwrite an existing file!
    print("gdspy saved {}".format(full_filename))
    return library


if __name__ == '__main__':
    library = main(output_directory='.')
    gdspy.LayoutViewer(library)
    print("The gdspy.GdsLibrary object is called 'library'")