def resonator(position, cell, l_Zhigh, l_Zlow, t_Zhigh, t_Zlow): res = gdspy.Rectangle( (position.x, position.y + 0.5 * (t_Zlow - t_res)), (position.x + l_res, position.y + 0.5 * (t_Zlow - t_res) + t_res)) cell.add(res) position.x = position.x + l_res return cell
def bendLeftZhigh(position, cell, l_Zhigh, l_Zlow, t_Zhigh, t_Zlow): R_inner = 900 / 2 - gap_Zhigh R = R_inner + t_Zhigh l_residual = l_Zlow - numpy.pi * (R_inner + R) / 2 position.y = position.y + 0.5 * (t_Zlow - t_Zhigh) center_y = position.y - R_inner center_x = position.x Zlow1 = gdspy.Round((center_x, center_y), R, inner_radius=R_inner, initial_angle=-0.5 * numpy.pi, final_angle=-1.5 * numpy.pi, **spec) cell.add(Zlow1) l_residual = l_Zhigh - numpy.pi * (R_inner + R) / 2 position.y = center_y - R position.x = center_x Zlow2 = gdspy.Rectangle((position.x, position.y), (position.x + l_residual, position.y + t_Zhigh)) cell.add(Zlow2) position.x = position.x + l_residual position.y = position.y - 0.5 * (t_Zlow - t_Zhigh) return cell
def Generate(self, mode='up', circle=False, r=0, w=0): xres = self.x1 + 0.5 * self.d2 yres = self.y1 + 0.5 * self.d2 - 0.5 * self.d if mode == 'up' else self.y1 - 0.5 * self.d2 + 0.5 * self.d #print(yres) x2res = self.x2 - 0.5 * self.d2 r1, xr1, yr1 = self.Waveguide(xres, yres, x2res, self.length, self.d) r2, xr2, yr2 = self.Waveguide(xres, yres, x2res, self.length, self.d1) r3, xr3, yr3 = self.Waveguide(xres, yres, x2res, self.length, self.d2) print('r3: ', r3, 'xr3: ', xr3, 'yr3: ', yr3) self.restricted_area = r3 print('r ', r, 'w ', w) if circle: claw = self.Circular_Claw2(xr3, yr3, r, w) #claw = self.Circular_Claw(xr3, yr3) else: claw = self.Claw(xr3, yr3) #cell.add(claw) res_gen = gdspy.boolean( gdspy.boolean((gdspy.boolean( gdspy.boolean(r3, claw, 'or'), r2, 'not', layer=self.layer)), r1, 'or'), gdspy.Rectangle((xr3 - self.d / 2, yr3), (xr3 + self.d / 2, yr3 + 7)), 'or') if mode == 'up': #self.claw_center.x += 4 return res_gen else: #print(self.claw_center.x, (xres + x2res)*0.5) self.claw_center.y -= 2 * np.abs(self.claw_center.y - yres) self.claw_center.x += 2 * np.abs(self.claw_center.x - (xres + x2res) * 0.5) #print(self.claw_center) self.restricted_area.rotate(np.pi, [(xres + x2res) * 0.5, yres]) #self.claw_center.x -= 20 return res_gen.rotate(np.pi, [(xres + x2res) * 0.5, yres])
def power_strip(w, h, offset=[0,0], lay=[5,6]): power_cell = gdspy.Cell("POWER", True) contact_num_w = int((w-2*EN_VIA+SP_VIA)/(W_VIA+SP_VIA)) contact_num_h = int((h-2*EN_VIA+SP_VIA)/(W_VIA+SP_VIA)) contact_space_w = (w-EN_VIA-contact_num_w*W_VIA)/(contact_num_w-1)+W_VIA contact_space_h = (h-EN_VIA-contact_num_h*W_VIA)/(contact_num_h-1)+W_VIA if contact_space_w < SP_VIA + W_VIA: contact_num_w = contact_num_w - 1 contact_space_w = (h-2*EN_VIA-contact_num_w*W_VIA)/(contact_num_w-1)+W_VIA if contact_space_h < SP_VIA + W_VIA: contact_num_h = contact_num_h - 1 contact_space_h = (h-2*EN_VIA-contact_num_h*W_VIA)/(contact_num_h-1)+W_VIA contact_space_h = int(contact_space_h/GRID)*GRID contact_space_w = int(contact_space_w/GRID)*GRID x_offset = (w-W_VIA-contact_space_w*(contact_num_w-1))/2 + offset[0] y_offset = (h-W_VIA-contact_space_h*(contact_num_h-1))/2 + offset[1] x_offset = int(x_offset/GRID)*GRID y_offset = int(y_offset/GRID)*GRID for i in lay: met_layer = 'M' + str(i) m1_shape = gdspy.Rectangle((offset[0],offset[1]),(offset[0]+w,offset[1]+h),layer[met_layer],datatype[met_layer]) power_cell.add(m1_shape) if i != lay[-1]: contact_cell = contact(i) contact_array = gdspy.CellArray(contact_cell, contact_num_w, contact_num_h, [contact_space_w, contact_space_h], [x_offset, y_offset]) power_cell.add(contact_array) power_cell.flatten() return power_cell
def generate_squid(self): # print(self.squid_params) self.squid = squid3JJ.JJ_2( self.squid_params['x'], self.squid_params['y'], self.squid_params['a1'], self.squid_params['a2'], self.squid_params['b1'], self.squid_params['b2'], self.squid_params['c1'], self.squid_params['c2']) squid = self.squid.generate_JJ() rect = gdspy.Rectangle( (self.squid_params['x'] - self.squid.contact_pad_a_outer / 2, self.squid_params['y'] + 0 * self.squid.contact_pad_b_outer / 2), (self.squid_params['x'] + self.squid.contact_pad_a_outer / 2, self.squid_params['y'] - self.squid.contact_pad_b_outer), layer=self.total_layer) if self.Coaxmon1.center[0] == self.Coaxmon2.center[0]: path1 = gdspy.Polygon([ (self.squid_params['x'], self.squid_params['y']), (self.Coaxmon1.center[0], self.squid_params['y']), (self.Coaxmon1.center[0], self.squid_params['y'] - self.squid.contact_pad_b_outer), (self.squid_params['x'], self.squid_params['y'] - self.squid.contact_pad_b_outer) ]) rect = gdspy.boolean(rect, path1, 'or', layer=self.total_layer) # point1 = squid = gdspy.boolean(squid, squid, 'or', layer=self.JJ_layer) squid.rotate(self.squid_params['angle'], (self.squid_params['x'], self.squid_params['y'])) return squid, rect
def test_copy(): p = gdspy.Rectangle((0, 0), (1, 1)) q = gdspy.copy(p, 1, -1) assert set(p.points[:, 0]) == {0, 1} assert set(p.points[:, 1]) == {0, 1} assert set(q.points[:, 0]) == {1, 2} assert set(q.points[:, 1]) == {-1, 0} p = gdspy.PolygonSet([[(0, 0), (1, 0), (0, 1)], [(2, 2), (3, 2), (2, 3)]]) q = gdspy.copy(p, 1, -1) assert set(p.polygons[0][:, 0]) == {0, 1} assert set(p.polygons[0][:, 1]) == {0, 1} assert set(q.polygons[0][:, 0]) == {1, 2} assert set(q.polygons[0][:, 1]) == {-1, 0} assert set(p.polygons[1][:, 0]) == {2, 3} assert set(p.polygons[1][:, 1]) == {2, 3} assert set(q.polygons[1][:, 0]) == {3, 4} assert set(q.polygons[1][:, 1]) == {1, 2} l = gdspy.Label('text', (0, 1)) m = gdspy.copy(l, -1, 1) assert l.position[0] == 0 and l.position[1] == 1 assert m.position[0] == -1 and m.position[1] == 2 c = gdspy.CellReference('empty', (0, 1), ignore_missing=True) d = gdspy.copy(c, -1, 1) assert c.origin == (0, 1) assert d.origin == (-1, 2) c = gdspy.CellArray('empty', 2, 3, (1, 0), (0, 1), ignore_missing=True) d = gdspy.copy(c, -1, 1) assert c.origin == (0, 1) assert d.origin == (-1, 2)
def add_reservoir_to_shape(shape, x_width=2, y_height=0.5, position=(0, 0), layer=1, rotation=0): """ Takes a shape and adds a rectangle of specified width and height to some position :param shape: gp.PolygonSet :param x_width: in um :param y_height: in um :param position: (x, y) center of the rectangle :param layer: shapes are on layer 1 by default :param rotation: float in degrees :return: None """ reservoir = gp.Rectangle((-x_width / 2, -y_height / 2), (x_width / 2, y_height / 2), layer=layer).rotate(rotation * math.pi / 180) return gp.fast_boolean(shape, reservoir.translate(position[0], position[1]), 'or', layer=layer)
def bwToGDS(Width, Height, bwArray, layer, datatype): #Converts a black and white """ Args: Width: The width of the bmp in the GDSPY base units (1 unit = 1um by default) Height: The height of the bmp in the GDSPY base unit (1 unit = 1um by default) bwArray: The black and white image for layout layer: Layer the BMP should be placed on in the GDS Layout datatype: The datatype of the bmp when placed in the GDS Layout Returns: A GDSPY polygonset """ black = 0 #We assume that the material is already converted to a black only version. YRes = len(bwArray) XRes = len(bwArray[0]) pX = Width / XRes pY = Height / YRes rects = [] for i in range(len(bwArray)): for j in range(len(bwArray[0])): if bwArray[i][j] == black: rects.append( gdspy.Rectangle((pX * j, -pY * i), (pX * (j + 1), -pY * (i + 1)), layer, datatype)) patt = None try: patt = gdspy.boolean(rects[0], rects[1:], "or", max_points=0) print("Polygonset Successfully Generated") except: print("Polygonset is Empty! Check black value and try again") None return patt
def test_gather(): def same_points(x, y): for px, py in zip(x, y): for ptx, pty in zip(px, py): for cx, cy in zip(ptx, pty): if cx != cy: return False return True gdspy.current_library = gdspy.GdsLibrary() pts = [(0, 0), (1, 1), (1, 0)] ps1 = gdspy.Round((10, 10), 1, inner_radius=0.2) ps2 = gdspy.Path(0.1, (-1, -1), 2, 1).segment(2, "-x") c = gdspy.Cell("C1").add(gdspy.Rectangle((-4, 3), (-5, 4))) cr = gdspy.CellReference(c, (10, -10)) ca = gdspy.CellArray(c, 2, 1, (2, 0)) assert gdspy._gather_polys(None) == [] assert same_points(gdspy._gather_polys([pts]), [pts]) assert same_points(gdspy._gather_polys(ps1), ps1.polygons) assert same_points(gdspy._gather_polys(ps2), ps2.polygons) assert same_points(gdspy._gather_polys(cr), cr.get_polygons()) assert same_points(gdspy._gather_polys(ca), ca.get_polygons()) result = [pts] result.extend(ps2.polygons) result.extend(cr.get_polygons()) assert same_points(gdspy._gather_polys([pts, ps2, cr]), result)
def flip_vert(self): flip_cell = gdspy.Cell(self.cell.name, True) bounding_box = self.cell.get_bounding_box() x_sym_axis = bounding_box[0][0] + bounding_box[1][0] # Floating point error # Since gdsii precision is 5nm, here we only round to 1nm precision #x_sym_axis = round(x_sym_axis * 10000) / 10000.0 polydict = self.cell.get_polygons(by_spec=True) for key in polydict: layer, datatype = key for shape in polydict[key]: x_min = shape[0][0] y_min = shape[0][1] x_max = shape[2][0] y_max = shape[2][1] x_min_s = x_sym_axis - x_max x_max_s = x_sym_axis - x_min new_shape = gdspy.Rectangle([x_min_s, y_min], [x_max_s, y_max], layer, datatype=datatype) flip_cell.add(new_shape) self.cell = flip_cell #self.flatten() self.plus.flip_vert(x_sym_axis) self.minus.flip_vert(x_sym_axis)
def tessellate(cell, i=199, lyr=None): """ within a cell, an old layer is subtracted from the chip size, and is written to the new layer Args: cell - gdspy cell lyr - layer name Return: cell with inverted new layer and removed old layer """ mask = [] if lyr is None: layers = cell.get_polygons(by_spec=True) for l in layers: i = 199 while hole(cell, l): tessellate(cell, i, l) i = i - 1 return None polygons = cell.get_polygons(by_spec=True)[lyr] box_coord = cell.get_bounding_box() bbox = gdspy.Rectangle(box_coord[0], box_coord[1]) for p in polygons: mask.append(gdspy.Polygon(p)) cell.remove_polygons(lambda pts, layer, datatype: layer == lyr[0]) result = gdspy.fast_boolean(bbox, mask, 'and', max_points=i, layer=lyr[0]) # print(len(result.polygons)) cell.add(result)
def doping_layer(self): if self.nmos: doping_layer = layer['NP'] else: doping_layer = layer['PP'] # Define NP/PP and NW Shapes if self.l < dummy_l: self.dope_ll = [ -self.gate_space - en['NP']['PO'], -ex['PO']['OD'] - en['NP']['PO'] ] self.dope_ur = [ self.nf * self.gate_space + self.l + en['NP']['PO'], self.w + min_w['M1'] + self.gate_ext_len + en['PO']['CO'] - 0.5 * (min_w['M1'] - min_w['CO']) + en['NP']['PO'] ] self.nw_ll = [ -self.gate_space - en['PP']['PO'], -en['NW']['OD'][1] ] self.nw_ur = [ self.nf * self.gate_space + self.l + en['PP']['PO'], self.w + en['NW']['OD'][1] ] else: self.dope_ll = [ self.x_od1 - ex['NP']['OD'], -ex['PO']['OD'] - en['NP']['PO'] ] self.dope_ur = [ self.x_od2 + ex['NP']['OD'], self.w + min_w['M1'] + self.gate_ext_len + en['PO']['CO'] - 0.5 * (min_w['M1'] - min_w['CO']) + en['NP']['PO'] ] self.nw_ll = [self.x_od1 - en['NW']['OD'][0], -en['NW']['OD'][1]] self.nw_ur = [ self.x_od2 + en['NW']['OD'][0], self.w + en['NW']['OD'][1] ] # Shrink dope due to self.nf change # Draw NP/PP doping_shape = gdspy.Rectangle(self.dope_ll, self.dope_ur, doping_layer) self.cell.add(doping_shape) # For PMOS if not self.nmos: # Draw NW nw_shape = gdspy.Rectangle(self.nw_ll, self.nw_ur, layer['NW']) self.cell.add(nw_shape)
def addTLMStructures(lib, width=100, spacing=[50, 100, 150, 200], padding=5, name="TLM", offset=[0, 0], alignment='top', textSize=50): tempCell = lib.new_cell(name) if alignment == 'top': for i in range(len(spacing) + 1): if (i < len(spacing)): texti = gdspy.Text( str(spacing[i]) + 'u', textSize, [ offset[0] + i * width + sum(spacing[0:i]) + width / 2 + spacing[i] / 2, offset[1] - textSize ], layer=2) tempCell.add(texti) contacti = gdspy.Rectangle([ offset[0] + padding + i * width + sum(spacing[0:i]), offset[1] - padding - textSize ], [ offset[0] + padding + (i + 1) * width + sum(spacing[0:i]), offset[1] - textSize - padding - width ], layer=2) tempCell.add(contacti) filmRegion = gdspy.Rectangle([offset[0], offset[1] - textSize], [ offset[0] + 2 * padding + 5 * width + sum(spacing), offset[1] - textSize - 2 * padding - width ], layer=1) widthText = gdspy.Text( str(width) + 'u', textSize, [offset[0] - textSize * 4, offset[1] - textSize - width / 2], layer=2) tempCell.add(filmRegion) tempCell.add(widthText) return tempCell else: raise NotImplementedError
def Waveguide(self, x1, y1, length, d_given): # , x_e, y_e): delta = (d_given - self.d) / 2 r_outer = self.r_outer r_inner = (self.d1 * 1.7 - self.d) / 2 # Difference between the two should be self.d r = 0.5 * (r_outer + r_inner) width = self.width l_reserved = self.l_vert + self.l_coupl + 0.5 * np.pi * r + np.pi * r # 0.5 pi for the quarter circle to the vertical piece N = floor((self.length - l_reserved) / (np.pi * r + width)) # number of curves l_horiz = self.length - l_reserved - (np.pi * r + width) * (N) if l_horiz > width: self.l_vert += l_horiz - width l_horiz = width rect = gdspy.Rectangle((x1 + r_outer, y1 - delta), (x1 + r_outer + self.l_coupl + delta / 2.5, y1 + self.d + delta)) sector = gdspy.Round((x1 + r_outer, y1 + r_outer), r_outer + delta, r_inner - delta, initial_angle=0.5 * np.pi, final_angle=1.5 * np.pi, tolerance=0.01) result = gdspy.boolean(rect, sector, 'or') for i in range(N): rect = gdspy.Rectangle((x1 + r_outer, y1 + (r_outer + r_inner) * (i + 1) - delta), (x1 + r_outer + width, y1 + (r_outer + r_inner) * (i + 1) + self.d + delta)) xr = x1 + width + r_outer if i % 2 == 0 else x1 + r_outer yr = y1 + r_outer * 2 + (2 * r_inner + self.d) * i + r_inner sector = gdspy.Round((xr, yr), r_outer + delta, r_inner - delta, initial_angle=1.5 * np.pi if i % 2 == 0 else 0.5 * np.pi, final_angle=2.5 * np.pi if i % 2 == 0 else 1.5 * np.pi, tolerance=0.01) result = gdspy.boolean(result, gdspy.boolean(sector, rect, 'or'), 'or') i = N - 1 xr1 = x1 + r_outer if i % 2 == 1 else x1 + width + r_outer xr2 = x1 + r_outer + l_horiz if i % 2 == 1 else x1 + width + r_outer - l_horiz rect = gdspy.Rectangle((xr1, y1 + (r_outer + r_inner) * (N + 1) - delta), (xr2, y1 + (r_outer + r_inner) * (N + 1) + self.d + delta)) xr = xr2 yr = y1 + r_outer * 2 + (2 * r_inner + self.d) * N + r_inner # print(l_horiz, xr1, xr2, xr, yr) sector = gdspy.Round((xr, yr), r_outer + delta, r_inner - delta, initial_angle=1.5 * np.pi if i % 2 == 1 else np.pi, final_angle=2 * np.pi if i % 2 == 1 else 1.5 * np.pi, tolerance=0.01) result = gdspy.boolean(result, gdspy.boolean(sector, rect, 'or'), 'or') xr1 = xr + r_inner - delta if i % 2 == 1 else xr - r_inner + delta xr2 = xr + r_outer + delta if i % 2 == 1 else xr - r_outer - delta rect = gdspy.Rectangle((xr1, yr), (xr2, yr + self.l_vert)) result = gdspy.boolean(result, rect, 'or') if delta == 0: result = gdspy.boolean(result, gdspy.Rectangle((x1 + r_outer + self.l_coupl, y1), ( x1 + r_outer + self.l_coupl + (self.d1 - self.d) / 5, y1 + self.d)), 'or') # this defines the resonator end closest to the TL return result, (xr2 - xr1) * 0.5 + xr1, yr + self.l_vert
def Generate_contacts(self, layer): #first the two contacts contact_1 = gdspy.Rectangle( (self.x, self.y - self.length / 2 - self.padsize / 2), (self.x + self.padsize, self.y - self.length / 2 + self.padsize / 2)) contact_2 = gdspy.Rectangle( (self.x, self.y + self.length / 2 - self.padsize / 2), (self.x + self.padsize, self.y + self.length / 2 + self.padsize / 2)) #now the bridge itself. result = gdspy.boolean(contact_1, contact_2, 'or', layer=layer) return result
def render(self): """ Draws edge g metallization on chip :return: """ edge = 600 # fundamental constant - edge length r1 = gdspy.Rectangle((0, 0), (self.chip_geometry.sample_horizontal_size, self.chip_geometry.sample_vertical_size)) r2 = gdspy.Rectangle((edge, edge), (self.chip_geometry.sample_horizontal_size - edge, self.chip_geometry.sample_vertical_size - edge)) result = gdspy.boolean(r1, r2, 'not') for pad in self.pads.items(): pad = pad.get() to_bool = gdspy.Rectangle(pad['positive'].get_bounding_box()[0].tolist(), pad['positive'].get_bounding_box()[1].tolist()) result = gdspy.boolean(result, to_bool, 'not') result_restricted = gdspy.boolean(result, result, 'or', layer=self.layer_configuration.restricted_area_layer) return {'positive': result, 'restrict': result_restricted}
def hollow_box(size, border_width, layer=0): outer = gd.Rectangle((0, 0), size) inner = gd.Rectangle((border_width, border_width), (size[0] - border_width, size[1] - border_width)) hbox = gd.fast_boolean(outer, inner, 'not', layer=layer) ends = { 'A': (0, size[1] / 2), 'B': (size[0] / 2, 0), 'C': (size[0] / 2, size[1]), 'D': (size[0], size[1] / 2), 'CENTER': (size[0] / 2, size[1] / 2) } epsz = {'A': size[1], 'CENTER': None} return gtools.classes.GDStructure(hbox, ends, epsz)
def test_get_polygons4(tree): c3, c2, c1 = tree c3.add(gdspy.Rectangle((0, 0), (1, 1), 0, 0)) assert len(c3.get_polygons((0, 0))) == 7 assert len(c3.get_polygons((0, 0), 0)) == 1 assert len(c3.get_polygons((1, 1), 0)) == 0 assert len(c3.get_polygons((0, 0), 1)) == 1 assert len(c3.get_polygons((1, 1), 1)) == 6
def Generate_bridge(self, layer, mode, mirror_x, mirror_y): bridge = gdspy.Rectangle((self.x - self.length / 2, self.y + self.padsize / 2 - self.width / 2), (self.x + self.length / 2, self.y + self.padsize / 2 + self.width / 2)) if mode == 'down': bridge.mirror([mirror_x, mirror_y], [mirror_x + 100, mirror_y]) return bridge
def MakesStampFromMotif(self,top,motif,X0=0,Y0=0,\ Wst=X_SIZE,Hst=Y_SIZE,Xoff=X_OFF,step=100,titre="Stamp1"): """ add a stamp to the layer "top" filled with "motif" repeated as much as possible. (X0,Y0) bottom left position """ #Add a die outline, with exclusion, from gdspy geometries found at #http://gdspy.readthedocs.io/en/latest/ top.add( gdspy.Rectangle((X0, Y0), (X0 + X_SIZE, Y0 + Y_SIZE), layer=6, datatype=0)) top.add( gdspy.Rectangle((X0, Y0 + Y_SIZE - Xoff), (X0 + X_SIZE, Y0 + Y_SIZE), layer=7, datatype=0)) top.add( gdspy.Rectangle((X0, Y0), (X0 + X_SIZE, Y0 + Xoff), layer=7, datatype=0)) top.add( gdspy.Rectangle((X0, Y0), (X0 + Xoff, Y0 + Y_SIZE), layer=7, datatype=0)) top.add( gdspy.Rectangle((X0 + X_SIZE - Xoff, Y0), (X0 + X_SIZE, Y0 + Y_SIZE), layer=7, datatype=0)) """ fill the stamp with the motif """ #1 size of the motif: Wmotif = motif.get_bounding_box()[1, 0] - motif.get_bounding_box()[0, 0] Hmotif = motif.get_bounding_box()[1, 1] - motif.get_bounding_box()[0, 1] #2 how many? Nmotifs = int((Wst - 2 * Xoff) / (Wmotif + step)) dec = int(Wst - 2 * Xoff) % int(Wmotif + step) #3 plot : for i in range(Nmotifs): # print((i*(Wmotif+step)+X0+Xoff+0.5*dec, Y0+Xoff)) top.add( gdspy.CellReference( motif, (i * (Wmotif + step) + X0 + Xoff + 0.5 * dec, Y0 + Xoff)))
def bench_gdspy(): cell = gdspy.Cell("MAIN", exclude_from_current=True) for i in range(10000): cell.add(gdspy.Rectangle((i, 0), (i + 1, 1))) name = pathlib.Path(tempfile.gettempdir()) / "gsdpy.gds" lib = gdspy.GdsLibrary() lib.add(cell) lib.write_gds(name)
def ZhighBack(position, l_Zhigh, l_Zlow, t_Zhigh, t_Zlow): position.y = position.y + 0.5 * (t_Zlow - t_Zhigh) position.x = position.x - l_Zhigh Zhigh = gdspy.Rectangle((position.x, position.y), (position.x + l_Zhigh, position.y + t_Zhigh)) position.y = position.y - 0.5 * (t_Zlow - t_Zhigh) return Zhigh
def test_notempty(): name = 'cr_notempty' c = gdspy.Cell(name) ref = gdspy.CellReference(name, (1, -1), 90, 2, True) ref.translate(-1, 1) c.add(gdspy.Rectangle((0, 0), (1, 2), 2, 3)) assert ref.area() == 8 assert ref.area(True) == {(2, 3): 8} err = numpy.array(((0, 0), (4, 2))) - ref.get_bounding_box() assert numpy.max(numpy.abs(err)) < 1e-15 assert ref.origin[0] == ref.origin[1] == 0 r = gdspy.boolean(ref.get_polygons(), gdspy.Rectangle((0, 0), (4, 2)), 'xor', 1e-6, 0) assert r is None d = ref.get_polygons(True) assert len(d.keys()) == 1 r = gdspy.boolean(d[(2, 3)], gdspy.Rectangle((0, 0), (4, 2)), 'xor', 1e-6, 0) assert r is None
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()
def generate_coupler(self,coordinate,r_init,r_final,rect_end): #to fix bug bug=5 result = gdspy.Round(coordinate, r_init, r_final, initial_angle=(self.arc_start) * np.pi, final_angle=(self.arc_finish) * np.pi) rect = gdspy.Rectangle((coordinate[0]+r_final-bug,coordinate[1]-self.w/2),(coordinate[0]+rect_end+bug, coordinate[1]+self.w/2)) rect.rotate(self.phi*np.pi, coordinate) return gdspy.boolean(result,rect, 'or')
def Generate_bridge(self, layer): bridge = gdspy.Rectangle((self.x + self.padsize / 2 - self.width / 2, self.y - self.length / 2), (self.x + self.padsize / 2 + self.width / 2, self.y + self.length / 2), layer=layer) return bridge
def od25_layer(self): od25_p1 = [self.x_od1 - en_od_25, -en_od_25] od25_p2 = [self.x_od2 + en_od_25, self.w + en_od_25] od25_shape = gdspy.Rectangle(od25_p1, od25_p2, layer['OD_25']) self.cell.add(od25_shape) if self.ud18: od_25ud_shape = gdspy.Rectangle(od25_p1, od25_p2, layer['OD_25'], datatype=4) self.cell.add(od_25ud_shape) elif self.od33: od_25od_shape = gdspy.Rectangle(od25_p1, od25_p2, layer['OD_25'], datatype=3) self.cell.add(od_25od_shape)
def box(size, layer = 0, datatype = 0): box = gp.Rectangle((0, 0), size, layer = layer, datatype = datatype) ends = {'A': (0, size[1] / 2), 'B': (size[0] / 2, 0), 'C': (size[0] / 2, size[1]), 'D': (size[0], size[1] / 2), 'CENTER': (size[0] / 2, size[1] / 2), 'W': (0, 0), 'X': (size[0], 0), 'Y': (size[0], size[1]), 'Z': (0, size[1])} epsz = {'A': size[1], 'D': size[1], 'B': size[0], 'C': size[0], 'CENTER': None, 'W': size[0], 'X': size[0], 'Y': size[0], 'Z': size[0]} return gdst.classes.GDStructure(box, ends, epsz)
def gene_heater(lib, cellName='Heater', w_heater=3, l_heater=200, w_CT=10, w_wire=20, w_wg=0.5, w_etch=3, type_layout='positive'): # l_heater2 = l_heater - 100 # w_heater = 3 # w_CT = 10 # w_wire = w_CT*2 # w_wg = 0.45 # w_etch = 3 l_port = 20 l_Heater = l_heater + 2*l_port cell = lib.new_cell(cellName) # add middle long rect heater = gdspy.Rectangle((l_port, w_heater/2), (l_port+l_heater, -w_heater/2), **ld_heater) cell.add(heater) # add left rect and wire heater = gdspy.Rectangle((l_port+-w_CT/2, w_CT/2), (l_port+w_CT/2, -w_CT/2), **ld_heater) cell.add(heater) heater = gdspy.Rectangle((l_port+-w_wire/2, w_wire/2), (l_port+w_wire/2, -w_wire/2), **ld_wire) cell.add(heater) # add right rect and wire heater = gdspy.Rectangle((l_port+l_heater-w_CT/2, w_CT/2), (l_port+l_heater+w_CT/2, -w_CT/2), **ld_heater) cell.add(heater) heater = gdspy.Rectangle((l_port+l_heater-w_wire/2, w_wire/2), (l_port+l_heater+w_wire/2, -w_wire/2), **ld_wire) cell.add(heater) # add WG if type_layout == 'negative': Rect = gdspy.Rectangle((0, w_wg/2+w_etch), (l_Heater, w_wg/2), **ld_fulletch) cell.add(Rect) Rect = gdspy.Rectangle((0, -w_wg/2), (l_Heater, -w_wg/2-w_etch), **ld_fulletch) cell.add(Rect) if type_layout == 'positive': cell.add(wg_line(w_wg, l_Heater, w_etch=w_etch, type_layout='positive')) cell.add(buffer(wg_line(w_wg, l_Heater, w_etch=w_etch, type_layout='positive'))) return cell
def make_polygon(self, coords, layer=None, purpose=None, tuple=None): if tuple: layer_num = tuple[0] datatype = tuple[1] else: layer_num, datatype = self.get_layer_dtype_tuple(layer, purpose) corner1 = (coords[0], coords[1]) corner2 = (coords[2], coords[3]) return gp.Rectangle(corner1, corner2, layer_num, datatype)