def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position # elems += i3.SRef(reference=markers_from_Rik(), # transformation=i3.Translation((x0, y0))) for j in range(0, 6, 1): elems += i3.SRef( reference=markers_from_Rik(name=("nima{}".format(j))), transformation=i3.Translation( (x0 + 5000 + 700 / 2, y0 - 2500 + 5000 * j))) elems += i3.SRef(reference=markers_from_Rik(), transformation=i3.Translation( (x0 + 5000 + 750 * 3 + 700 / 2, y0 - 2500 + 5000 * j))) elems += i3.SRef(reference=markers_from_Rik(), transformation=i3.Translation( (x0 + 5000 + 750 * 6 + 700 / 2, y0 - 2500 + 5000 * j))) elems += i3.SRef( reference=markers_from_Rik(name=("nimafan{}".format(j))), transformation=i3.Translation( (x0 - 5000 - 700 / 2, y0 - 2500 + 5000 * j))) elems += i3.SRef(reference=markers_from_Rik(), transformation=i3.Translation( (x0 - 5000 - 750 * 3 + 700 / 2, y0 - 2500 + 5000 * j))) elems += i3.SRef(reference=markers_from_Rik(), transformation=i3.Translation( (x0 - 5000 - 750 * 6 + 700 / 2, y0 - 2500 + 5000 * j))) return elems
def _generate_elements(self, elems): for counter, child in enumerate(self.DC_list): name = child.name elems += i3.PolygonText( layer=i3.TECH.PPLAYER.WG.TEXT, text="{}_{}".format(name, self.cell.wg_t1.name), # coordinate=(1300.0, 100.0), alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=20.0, transformation=i3.Translation( (1500, 100 + 10000 * counter))) elems += i3.PolygonText( layer=i3.TECH.PPLAYER.WG.TEXT, text="{} {}".format(name, self.cell.wg_t1.name), # coordinate=(-2000, -150), alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=200.0, transformation=i3.Rotation( (0.0, 0.0), 90.0) + i3.Translation( (450 + 2900, -2000 + 10000 * counter))) # for j in range (-1,2,1): # for i in range(0,4,1): # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=( # 100+j*6000, -3000+100+10000*i),box_size=(100, 100)) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=( # 100+j*6000, -3000 - 100 + 10000 * i), box_size=(100, 100)) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=( # 100+j*6000, -3000 + 100 + 6000 * 3+3000), box_size=(100, 100)) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=( # 100+j*6000, -3000 - 100 + 6000 * 3+3000), box_size=(100, 100)) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=( # 300, -3000 + 100 + 6000 * 3 + 3000), box_size=(100, 100)) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, center=( # 300, -3000 - 100 ), box_size=(100, 100)) return elems
def ringcircuit3(radius, gap, wg_ring_width, wg_coupler_width, angle, lx, ly, tl, gwgw, gsl, gp, gdc): gwg = gratingwaveguide(gwgw) g = grating(gwg, gsl, gp, gdc) r = ring3(radius, gap, wg_ring_width, wg_coupler_width, angle) wgt = WireWaveguideTemplate() wgt.Layout(core_width=wg_coupler_width, cladding_width=wg_coupler_width + 6) t = taper(gwg, wgt, tl) circuit = PlaceAndAutoRoute(child_cells={ "grating1": g, "taper1": t, "ring": r, "taper2": t, "grating2": g }) circuit_layout = circuit.Layout( child_transformations={ "grating1": i3.Translation((gsl / 2.0, ly)), "taper1": i3.Translation((gsl, ly)), "ring": i3.Translation((gsl + tl + lx / 2.0, radius + gap + wg_ring_width / 2.0 + wg_coupler_width / 2.0)), "taper2": i3.Rotation(rotation_center=(0.0, 0.0), rotation=180, absolute_rotation=False) + i3.Translation((gsl + 2 * tl + lx, ly)), "grating2": i3.Rotation(rotation_center=(0.0, 0.0), rotation=180, absolute_rotation=False) + i3.Translation((gsl * 3 / 2.0 + 2 * tl + lx, ly)) }) return circuit
def _default_child_transformations(self): trans = dict() column = 10000 # trans["dircoup1"] = (1650, 0) # trans["dircoup2"] = (4950, 0) # trans['mzi_22_22_0'] = (0, 0) trans['ring0'] = (1500, 0) trans['ring1'] = (1500, 0 + column) trans['ring2'] = (1500, 0 + 2 * column) # trans['ring3'] = (1500, 0 + 3 * column) trans["taper0"] = (0, 4000) trans["taper1"] = (0, -4000) trans["taper2"] = i3.HMirror(0) + i3.Translation((4000, 2500)) trans["taper3"] = i3.HMirror(0) + i3.Translation((4000, -2500)) trans["taper4"] = (0, 4000 + column) trans["taper5"] = (0, -4000 + column) trans["taper6"] = i3.HMirror(0) + i3.Translation((4000, 2500 + column)) trans["taper7"] = i3.HMirror(0) + i3.Translation((4000, -2500 + column)) trans["taper8"] = (0, 4000 + 2 * column) trans["taper9"] = (0, -4000 + 2 * column) trans["taper10"] = i3.HMirror(0) + i3.Translation((4000, 2500 + 2 * column)) trans["taper11"] = i3.HMirror(0) + i3.Translation((4000, -2500 + 2 * column)) return trans
def _default_child_transformations(self): trans = dict() row = 3000 trans["CHILD0"] = (0, 0) trans["CHILD1"] = i3.HMirror(2500) - i3.Translation((5000, 0)) trans['CHILD2'] = (-15000, -5000) trans['CHILD3'] = (-15000, 0) trans['CHILD4'] = (-15000, 2000 + row * 1) trans['CHILD5'] = (-15000, 2000 + row * 2) trans['CHILD6'] = (-15000, 2000 + row * 3) trans['CHILD7'] = (-15000, 2000 + row * 4) trans['CHILD8'] = (-15000, 2000 + row * 5) trans['CHILD9'] = (-15000, 2000 + row * 6) trans['CHILD10'] = i3.Rotation(rotation=180) + i3.Translation( (15000, 0)) trans['CHILD11'] = i3.Rotation(rotation=180) + i3.Translation( (15000, 5000)) trans['CHILD12'] = i3.Rotation(rotation=180) + i3.Translation( (15000, 5000 + row * 1)) trans['CHILD13'] = i3.Rotation(rotation=180) + i3.Translation( (15000, 5000 + row * 2)) trans['CHILD14'] = i3.Rotation(rotation=180) + i3.Translation( (15000, 5000 + row * 3)) trans['CHILD15'] = i3.Rotation(rotation=180) + i3.Translation( (15000, 5000 + row * 4)) trans['CHILD16'] = i3.Rotation(rotation=180) + i3.Translation( (15000, 5000 + row * 5)) trans['CHILD17'] = i3.Rotation(rotation=180) + i3.Translation( (15000, 5000 + row * 6)) # trans['CHILD14'] = (-15000, 0 + row * -1) # trans['CHILD15'] = (-15000, 0 + row * 0) # trans['CHILD16'] = (-15000, 0 + row * 1) # trans['CHILD17'] = (-15000, 0 + row * 2) # trans['CHILD18'] = (-15000, 0 + row * 3) # trans['CHILD19'] = (-15000, 0 + row * 4) # trans['CHILD20'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 0)) # trans['CHILD21'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 1)) # trans['CHILD22'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 2)) # trans['CHILD23'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 3)) # trans['CHILD24'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 4)) # trans['CHILD25'] = i3.Rotation(rotation=180) + i3.Translation((15000, 0 + row * 5)) return trans
def _default_child_transformations(self): child_transformations = { "MMI1b": (1300, 0), "WGup": (0, 4000), "WGuptaper": (0, 4000), "WGdown": (0, -4000), "WGdowntaper": (0, -4000), "WGuptaper2": i3.HMirror() + i3.Translation((3000, 2000)), "WGdowntaper2": i3.HMirror() + i3.Translation((3000, -6000)), "WGup2": (2850, 2000), "WGdown2": (2850, -6000), "dummy1": (1300, -300), "DWGup": (0, 20900), "DWGuptaper": (0, 20900), "DWGdown": (0, -4300), "DWGdowntaper": (0, -4300), "DWGuptaper2": i3.HMirror() + i3.Translation((3000, 20900)), "DWGdowntaper2": i3.HMirror() + i3.Translation((3000, -6300)), "DWGup2": (2850, 20900), "DWGdown2": (2850, -6300) } return child_transformations
def _default_child_transformations(self): d = {} for counter, child in enumerate(self.child_cells): # We get the layoutview of the childcell spiral = self.child_cells[child].get_default_view(self) # isz_0 = spiral.instances['Spiral0'].reference.inner_size #sx=isz_0[1]+200 #print 'sx = ',sx #print("inner_size = {}".format(isz_0, isz_1)) number = self.n if self.tipo == 1: sx = 200 d['Spirals' + str(counter)] = i3.Translation( translation=(0.0, (counter) * sx)) #+i3.i3.HMirror() if self.tipo == 2: sx = 100 d['Spirals' + str(counter)] = i3.Translation( translation=(0.0, -(counter) * sx)) #+i3.i3.HMirror() return d
def _generate_instances(self, insts): for cnt, mmi in enumerate(self.mmis): si = mmi.size_info() t = i3.Translation(translation=(0, cnt * self.mmi_sep)) if cnt % 2 == 0: transformation = i3.HMirror( mirror_plane_x=si.center[0]) + t else: transformation = t insts += i3.SRef(name="mmi_{}".format(cnt), reference=mmi, transformation=transformation) return insts
def _default_child_transformations(self): trans = dict() column = 3000 # trans["dircoup1"] = (1650, 0) # trans["dircoup2"] = (4950, 0) # trans['mzi_22_22_0'] = (0, 0) trans['ring0'] = (1300, -2000) # trans['ring1'] = i3.VMirror(0) + i3.Translation((1300, 2000)) trans['ring1'] = (1300 + column, -2000) # trans['ring2'] = (1500, 0 + 2 * column) # trans['ring3'] = (1500, 0 + 3 * column) trans["taper0"] = (0, -4000) trans["taper1"] = i3.HMirror(0) + i3.Translation((3000, -3500)) trans["taper2"] = (0 + column, -3500) trans["taper3"] = i3.HMirror(0) + i3.Translation( (3000 + column, -4000)) return trans
def _default_child_transformations(self): child_transformations = { # "MMI1b": (1300, 0), # "WGup": (0, 4000), # "WGuptaper": (0, 4000), # "WGdown": (0, -4000), # "WGdowntaper": (0, -4000), # "WGuptaper2": i3.HMirror() + i3.Translation((3300, 2000)), # "WGdowntaper2": i3.HMirror() + i3.Translation((3300, -6000)), # "WGup2": (3150, 2000), # "WGdown2": (3150, -6000), "dummy1": (1450, -300), "DWGup": (0, 20750), "DWGuptaper": (0, 20750), "DWGdown": (0, -4150), "DWGdowntaper": (0, -4150), "DWGuptaper2": i3.HMirror() + i3.Translation((3300, 20750)), "DWGdowntaper2": i3.HMirror() + i3.Translation((3300, -6150)), "DWGup2": (3150, 20750), "DWGdown2": (3150, -6150) } return child_transformations
def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(6250, -500), box_size=(500, 500)) elems += i3.Rectangle(layer=self.layer, center=(6250, 1000), box_size=(500, 500)) elems += i3.Rectangle(layer=self.layer2, center=(9950, 1000), box_size=(4100, self.width)) # heaters elems += i3.Rectangle(layer=self.layer3, center=(9950, 1000), box_size=(3900, self.width+20)) # heaters during plating elems += i3.Rectangle(layer=self.layer, center=(9950 - 4100 / 2+50, 1000), box_size=(100, self.width)) # heaters butt left elems += i3.Rectangle(layer=self.layer, center=(9950 + 4100 / 2 - 50, 1000), box_size=(100, self.width)) # heaters butt right elems += i3.Rectangle(layer=self.layer, center=(9950 - 4100 / 2 + 50-750, 1000), box_size=(1400, 100)) # left elems += i3.Rectangle(layer=self.layer, center=(9950 - 4100 / 2 + 50 - 750-450, -500), box_size=(500, 100)) elems += i3.Rectangle(layer=self.layer, center=(9950 + 4100 / 2 - 50, 1000 - (500+self.width) / 2), box_size=(100, 500)) elems += i3.Rectangle(layer=self.layer, center=(9450, 1000-self.width/2-450), box_size=(4900, 100)) elems += i3.Rectangle(layer=self.layer, center=(5050 + 4100 / 2 - 50, -550+(1000-self.width/2+50)/2), box_size=(100, 1000-self.width/2+50)) elems += i3.PolygonText(layer=i3.TECH.PPLAYER.WG.TEXT, text="width_{}".format(self.width), # coordinate=(1300.0, 100.0), alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=400.0, transformation=i3.Translation((8000, 0)) ) return elems
def _default_child_transformations(self): d = {} for counter, child in enumerate(self.Spiral_list): ip = child.ports["in"].position #print self.child_cells['InPort' + str(counter)].ports["out"].position #print self.child_cells['OutPort' + str(counter)].ports.position print '----------------' print 'spiral length:', child.total_length print 'counter: ', counter #print ip op = child.ports["out"].position #print op print 'The lateral size of the spiral is', op[0] - ip[0] print 'The type of mask is: ', self.tipo print 'The number of widths is: ', self.n print 'The number of lengths is: ', self.lengths print 'The width number is: ', self.width print '----------------' iz = child.inner_size sx = iz[1] + 200 #sx=1200 if self.tipo == 1: d['Spiral' + str(counter)] = i3.Translation( translation=(-(op[0] - ip[0]) / 2, self.n * counter * sx)) d['InPort' + str(counter)] = i3.HMirror() + i3.Translation( translation=(-self.chip_length / 2.0 - self.couplingWG_l, self.n * counter * sx)) d['OutPort' + str(counter)] = i3.Translation( translation=(self.chip_length / 2.0 + self.couplingWG_l, self.n * counter * sx)) if self.tipo == 2: d['Spiral' + str(counter)] = i3.Translation( translation=(-(op[0] - ip[0]) / 2, -(self.n + 0.5) * counter * sx)) #d['InPort' + str(counter)] = i3.HMirror()+ i3.Translation(translation=(-self.chip_length*(3/4)-self.couplingWG_l, -(self.n+0.5)*counter*sx)) #d['OutPort' + str(counter)] = i3.Rotation(rotation=90) + i3.Translation(translation=((op[0]-ip[0])/2+2*self.R+(((self.n+0.5)*counter+self.width)*sx/4), self.chip_length*(3/4)+(self.width+counter-(((counter+1)-1.0)%self.lengths))*sx)) d['InPort' + str(counter)] = i3.HMirror() + i3.Translation( translation=(-self.chip_length * (1 / 2) - 2000, -(self.n + 0.5) * counter * sx)) d['OutPort' + str(counter)] = i3.Rotation( rotation=90) + i3.Translation(translation=( (op[0] - ip[0]) / 2 + 2 * self.R + (((self.n + 0.5) * counter + self.width) * sx / 4), 3000 + self.chip_length * (3 / 4) + (self.width + counter - (((counter + 1) - 1.0) % self.lengths)) * sx)) #For awg's #if self.tipo==2: #d['Spiral' + str(counter)] = i3.Translation(translation=(-(op[0]-ip[0])/2, -(self.n+0.5)*counter*sx)) #d['InPort' + str(counter)] = i3.HMirror()+ i3.Translation(translation=(-self.chip_length*(3/4.0), -(self.n+0.5)*counter*sx)) #d['OutPort' + str(counter)] = i3.Rotation(rotation=90) + i3.Translation(translation=((op[0]-ip[0])/2+2*self.R #+(((self.n+0.5)*counter+self.width)*sx/100.0) #, self.chip_length*(2/4.0)+ #(self.width+counter-(((counter+1)-1.0)%self.lengths))*sx)) return d
def _default_child_transformations(self): # generate grid x = np.linspace(0, self.cell.x_footprint, self.cell.n_blocks_x) y = np.linspace(0, self.cell.y_footprint, self.cell.n_blocks_y) # generate positions from functions.position_coordinates import generate_positions coords = generate_positions(x, y, self.type) return { "blk_w_tee{}".format(cnt): i3.Translation(coords[cnt]) for cnt in range(self.n_blocks_x * self.n_blocks_y) }
def _default_child_transformations(self): trans = dict() from routing.transforms import relative_placer trans["sp_0_0"] = i3.Rotation(rotation=30.0) + i3.Translation( translation=(10.0, 10.0)) trans["sp_1_0"] = relative_placer( self.child_cells, trans, "sp_0_0:out1", "sp_1_0:in1", (self.spacing_x, -self.spacing_y / 2), 0.0) trans["sp_1_1"] = relative_placer( self.child_cells, trans, "sp_0_0:out2", "sp_1_1:in1", (self.spacing_x, +self.spacing_y / 2), 0.0) return trans
def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position x = 6200 y = 8000 Height = 300 elems += i3.PolygonText(layer=self.layer, text="1N", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0, y0)) ) elems += i3.PolygonText(layer=self.layer, text="5J", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 1 * x, y0 + 1 * y+700)) ) elems += i3.PolygonText(layer=self.layer, text="4W", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 0 * x, y0 + 1 * y)) ) elems += i3.PolygonText(layer=self.layer, text="2E", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 1 * x, y0 + 0 * y+1100)) ) elems += i3.PolygonText(layer=self.layer, text="3W", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 2 * x, y0 + 0 * y)) ) elems += i3.PolygonText(layer=self.layer, text="6E", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 2 * x, y0 + 1 * y)) ) return elems
def _generate_elements(self, elems): for counter in range(0, 24, 1): elems += i3.PolygonText( layer=i3.TECH.PPLAYER.WG.TEXT, text="{}".format(str(counter)), # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=70.0, transformation=i3.Translation( (5700, 1100 + 150 * counter))) if counter == 11 or counter == 13 or counter == 15: continue elems += i3.PolygonText( layer=i3.TECH.PPLAYER.WG.TEXT, text="{}".format(str(counter)), # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=70.0, transformation=i3.Translation((400, 100 + 150 * counter))) return elems
def _default_child_transformations(self): trans = dict() trans["dircoup1"] = (1650, 0) trans["dircoup2"] = (4950, 0) trans["dummy1"] = (1450, -300) trans["dummy2"] = (4750, -300) # for counter in range(0, 8, 1): # print counter # trans['straight' + str(counter)] = (2000 * (counter + 1), 0) # trans["taper" + str(counter)] = (0, 2000 * (counter + 1)) trans["straight0"] = (0, 4000) trans["straight1"] = (0, -4000) trans["straight2"] = (3150, 2000) trans["straight3"] = (3150, -6000) trans["straight4"] = (3300, 2000) trans["straight5"] = (3300, -6000) trans["straight6"] = (6450, 4000) trans["straight7"] = (6450, -4000) trans["taper0"] = (150, 4000) trans["taper1"] = (150, -4000) trans["taper2"] = i3.HMirror(150) + i3.Translation((2850, 2000)) trans["taper3"] = i3.HMirror(150) + i3.Translation((2850, -6000)) trans["taper4"] = (3450, 2000) trans["taper5"] = (3450, -6000) trans["taper6"] = i3.HMirror(150) + i3.Translation((6150, 4000)) trans["taper7"] = i3.HMirror(150) + i3.Translation((6150, -4000)) trans["straight8"] = (0, 4150) trans["straight9"] = (0, -4150) trans["straight10"] = (3150, 4150) trans["straight11"] = (3150, -6150) trans["straight12"] = (3300, 4150) trans["straight13"] = (3300, -6150) trans["straight14"] = (6450, 4150) trans["straight15"] = (6450, -4150) trans["taper8"] = (150, 4150) trans["taper9"] = (150, -4150) trans["taper10"] = i3.HMirror(150) + i3.Translation((2850, 4150)) trans["taper11"] = i3.HMirror(150) + i3.Translation((2850, -6150)) trans["taper12"] = (3450, 4150) trans["taper13"] = (3450, -6150) trans["taper14"] = i3.HMirror(150) + i3.Translation((6150, 4150)) trans["taper15"] = i3.HMirror(150) + i3.Translation((6150, -4150)) return trans
def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position for i in range(0, 4, 1): for j in range(0, 3, 1): elems += i3.Rectangle(layer=self.layer, center=(x0 + i * 6000, y0 + j * 7000), box_size=(100, 100)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 200 + i * 6000, y0 + j * 7000), box_size=(100, 100)) elems += i3.Rectangle(layer=self.layer, center=(x0 + i * 6000, y0 + 200 + j * 7000), box_size=(100, 100)) elems += i3.Rectangle(layer=self.layer, center=(x0 + i * 6000 + 200, y0 + 200 + j * 7000), box_size=(100, 100)) for k in range(0, 20, 1): elems += i3.Rectangle( layer=self.layer, center=(-1000 + 0 + i * 6000, 1000 + 10 * k + j * 7000), box_size=(500, 0.6 + 0.2 * k)) elems += i3.PolygonText( layer=self.layer, text="{}".format(str(k)), # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=7.0, transformation=i3.Translation( (-1000 + 260 + i * 6000, 1000 + 3 + 10 * k + j * 7000))) elems += i3.Rectangle(layer=i3.TECH.PPLAYER.NONE.DOC, center=(9000, 7500), box_size=(21000, 16000)) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.CONTACT.PILLAR, center=(8500, 7500), # box_size=(22000, 18000)) return elems
def combine_connectors(connector_functions=[], transformations=[]): """ :param connector_functions: List of routing functions that you want aggregate :param transformations: : List transformations for the intermediate points relative to the starting port :return: new_routing function. shape and connector_kwargs are unused in the new function. """ if len(connector_functions) != len(transformations) + 1: raise Exception( "The length of the transformation array need to be equal to the length of the routing functions - 1" ) cleaned_transformations = [] for t in transformations: if isinstance(t, tuple): cleaned_transformations.append((i3.Translation(t))) else: cleaned_transformations.append(t) def new_function(start_port, end_port, name=None, shape=None, connector_kwargs={}): start_ports = [start_port] + [ i3.OpticalPort(trace_template=start_port.trace_template, position=(0.0, 0.0)).transform(transformation=t) for t in cleaned_transformations ] end_ports = [ p.modified_copy(angle=p.angle + 180.0) for p in start_ports[1:] ] + [end_port] traces = [] for cnt, (cf, sp, ep) in enumerate( zip(connector_functions, start_ports, end_ports)): seg_name = "{}_segment_{}".format(name, cnt) traces.append(cf(start_port=sp, end_port=ep, name=seg_name)) return TraceChainWithCenterLine(name=name, traces=traces) return new_function
def __example1(cls): from technologies import silicon_photonics from picazzo3.fibcoup.curved import FiberCouplerCurvedGrating from picazzo3.routing.place_route import PlaceComponents from ipkiss3 import all as i3 from routing.route_through_control_points import RouteManhattanControlPoints # Placing the components of the circuit gr = FiberCouplerCurvedGrating() circuit = PlaceComponents(child_cells={ 'gr': gr, 'grb1': gr, 'grb2': gr }) circuit_layout = circuit.Layout( child_transformations={ 'gr': (0, 0), 'grb1': (-100, 0), 'grb2': i3.Rotation(rotation=180.0) + i3.Translation((+100, 0)) }) # We now use the placed components and make waveguides. control_points = [(-40, 20), (50, 0)] route = RouteManhattanControlPoints( input_port=circuit_layout.instances['grb1'].ports['out'], output_port=circuit_layout.instances['grb2'].ports['out'], control_points=control_points, rounding_algorithm=None) wire = i3.RoundedWaveguide() wl = wire.Layout(shape=route) # We create a new placecomponents with the wire included. circuit_child_cells = dict(circuit.child_cells) circuit_child_cells['wire'] = wire circuit_with_wire = PlaceComponents(child_cells=circuit_child_cells) circuit_with_wire_layout = circuit_with_wire.Layout( child_transformations=circuit_layout.child_transformations) circuit_with_wire_layout.visualize()
def _default_child_transformations(self): # print self.cell.mmi1_12.get_default_view(i3.LayoutView).length # print self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['in1'].x # print self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x # a = self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x - self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['in1'].x a = self.cell.mmi1_21.get_default_view(i3.LayoutView).ports['out'].x child_transformations = {"MMI1a": (a + 490, 0), "taper": (a, 0), "taper2": i3.HMirror(0.0) + i3.Translation((a + 490, 0)) # "WGup": (0, 4000), # "WGuptaper": (0, 4000), # "WGdown": (0, -4000), # "WGdowntaper": (0, -4000), # "WGuptaper2": i3.HMirror() + i3.Translation((3400, 4000)), # "WGdowntaper2": i3.HMirror() + i3.Translation((3400, -4000)), # "WGup2": (3250, 4000), # "WGdown2": (3250, -4000) } return child_transformations
def _generate_elements(self, elems): for counter, child in enumerate(self.DC_list): name = child.name # aa = child.layout.trace_length() elems += i3.PolygonText( layer=i3.TECH.PPLAYER.WG.TEXT, text="{}".format(name), # coordinate=(4650.0, 100.0), alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=150.0, transformation=i3.Translation( (300 + 3500 * counter, -3200))) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.WG.TEXT, # center=(0, 0), # box_size=(500, 300)) return elems
def _get_components(self): # 1. calculate the transformations of the rings based on their properties #circuitWidth = block_layout.size_info() #circuit_x_gap = 2000.0 #separation = abs(circuitWidth.west) + abs(circuitWidth.east)+ circuit_x_gap t1 = i3.Translation( (0 * 0, 0.0)) # i3.Translation((separation*0, 0.0)) # 2. Generating the instances circuit_1 = i3.SRef(name="t_1", reference=self.block, transformation=t1) circuit_2 = i3.SRef(name="t_2", reference=self.vacuum, transformation=t1) return circuit_1, circuit_2
def relative_placer(childcell_dict, transformation_dict, port1, port2, translation=(0.0, 0.0), rotation=0.0): port_strings = [port1, port2] layouts = [] ports = [] instance_names = [] for p in port_strings: instance_name, port_name = p.split(":") instance_names.append([instance_name]) layouts.append(childcell_dict[instance_name].get_default_view( i3.LayoutView)) ports.append(layouts[-1].ports[port_name]) return i3.Rotation(rotation_center=ports[1], rotation=rotation) + \ i3.vector_match_transform(ports[1], ports[0]) + \ i3.Translation(translation=translation) + transformation_dict[instance_names[0][0]]
def _generate_elements(self, elems): elems += i3.PolygonText( layer=i3.TECH.PPLAYER.WG.TEXT, text='Name={}_port_15'.format( self.cell.mmi1_21.get_default_view(i3.LayoutView).name), coordinate=(200.0, 100.0), alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=20.0) elems += i3.PolygonText( layer=i3.TECH.PPLAYER.WG.TEXT, text='Name={}_port_15'.format( self.cell.mmi1_21.get_default_view(i3.LayoutView).name), # coordinate=(-4000.0, -1650.0), alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=200.0, transformation=i3.Rotation((0.0, 0.0), 90.0) + i3.Translation( (-2050, -2000))) return elems
def _default_child_transformations(self): trans = dict() column = 4000 # trans['ring0'] = (600, 0) # trans['ring1'] = (600, 1 * column) # trans['ring2'] = (600, 2 * column) # # trans['ring3'] = (1300, 8000 + 2 * column ) for i in range(0, 5, 1): trans["taperH{}".format(i)] = (0, column * i + 100 * self.offset) trans["taperV{}".format(i)] = i3.Rotation( rotation=-90) + i3.Translation( (4000 + column * i - 100 * self.offset, 20000)) trans["recH{}".format(i)] = (900, column * i + 100 * self.offset) trans["recV{}".format(i)] = (4000 + column * i - 100 * self.offset, 20000 - 900) # trans["taper0"] = (0, 0) # trans["taper1"] = i3.HMirror(0) + i3.Translation((2500, -1500)) # trans["taper2"] = i3.HMirror(0) + i3.Translation((2500, 1500)) # # trans["taper3"] = (0, 1 * column) # trans["taper4"] = i3.HMirror(0) + i3.Translation((2500, -1500 + 1 * column)) # # trans["taper5"] = i3.HMirror(0) + i3.Translation((2500, 1500 + 1 * column)) # # trans["taper6"] = (0, 2 * column) # trans["taper7"] = i3.HMirror(0) + i3.Translation((2500, -1500 + 2 * column)) # trans["taper8"] = i3.HMirror(0) + i3.Translation((2500, 1500 + 2 * column)) # # trans["taper9"] = (0, 3800 + 2 * column) # # trans["taper10"] = i3.HMirror(0) + i3.Translation((2500, -1500 + 3 * column)) # # trans["taper11"] = i3.HMirror(0) + i3.Translation((3000, 6500+ 2 * column)) # # trans["taper12"] = i3.HMirror(0) + i3.Translation((3000, 9500+ 2 * column)) return trans
def _generate_instances(self, insts): # includes the get components and the waveguides the_rings = self._get_components() insts += the_rings wg_in_layout, wg_pass_layout = self.wgs # wg_pass_layout, wg_ring_layout insts += i3.SRef(reference=wg_in_layout, name="wg_in") # ok so now I grab the last ring from the rings and use it to determine its position last_ring = the_rings[-1] east_side_ring = last_ring.size_info().east # and I get the waveguide properties for ring and coupler, to give correct outside gap ring_core_width = self.wg_ring_template.core_width ring_clad_width = self.wg_ring_template.cladding_width bus_wg_core_width = self.wg_coupler_template.core_width bus_wg_clad_width = self.wg_coupler_template.cladding_width final_x_spot = (east_side_ring - ring_clad_width/2.) + ring_core_width/2. \ + self.external_gap + bus_wg_core_width/2. # rather than making a new waveguide we can mirror the previous structure into the final position # thus we need to determine the difference in the core position of the original structure # with the *negative* position of the final x position, and then the mirror will flip it around bus_core_pos = wg_in_layout.size_info( ).east - bus_wg_clad_width / 2. # now we translate the original structure to the desired negative position, and horizontally mirror around 0 output_transformation = i3.HMirror() + i3.Translation( (-1. * (-final_x_spot - bus_core_pos), 0.)) # finally we perform the SRef on the previous layout and transform it with a new name insts += i3.SRef(reference=wg_in_layout, name="wg_out", transformation=output_transformation) return insts
def _default_child_transformations(self): trans = dict() row = 5000 trans["CHILD0"] = (0, 0) #MMI trans["CHILD1"] = i3.HMirror(2500) - i3.Translation( (5000, 0)) #MMI trans["CHILD2"] = i3.HMirror(0) + i3.Translation((20000, 0)) # MMI trans["CHILD3"] = i3.Translation((16000, 10000)) # MMI trans['CHILD4'] = i3.VMirror(0) + i3.Translation( (16000, 20000)) #MMI trans['CHIL0'] = (-16000, -4000 + row * 0) trans['CHIL1'] = (-16000, -4000 + row * 1) trans['CHIL2'] = (-16000, -4000 + row * 2) trans['CHIL3'] = (-16000, -4000 + row * 3) trans['CHIL4'] = (-16000, -4000 + row * 4) trans['CHIL5'] = (-16000, -4000 + row * 5) trans['CHIL6'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 0)) trans['CHIL7'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 1)) trans['CHIL8'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 2)) trans['CHIL9'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 3)) trans['CHIL10'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 4)) trans['CHIL11'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 5)) trans['CHIL12'] = (4000, -4000 + row * 0) trans['CHIL13'] = (4000, -4000 + row * 1) trans['CHIL14'] = (4000, -4000 + row * 2) trans['CHIL15'] = (4000, -4000 + row * 3) trans['CHIL16'] = (4000, -4000 + row * 4) trans['CHIL17'] = (4000, -4000 + row * 5) trans['CHIL18'] = (-16000, -4000 + row * 0) trans['CHIL19'] = (-16000, -4000 + row * 1) trans['CHIL20'] = (-16000, -4000 + row * 2) trans['CHIL21'] = (-16000, -4000 + row * 3) trans['CHIL22'] = (-16000, -4000 + row * 4) trans['CHIL23'] = (-16000, -4000 + row * 5) trans['CHIL24'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 0)) trans['CHIL25'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 1)) trans['CHIL26'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 2)) trans['CHIL27'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 3)) trans['CHIL28'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 4)) trans['CHIL29'] = i3.Rotation(rotation=180) + i3.Translation( (16000, -1000 + row * 5)) # for _ in np.arange(10): # trans['CHIL{}'.format(_)] = NotImplemented for _ in range(30, 36, 1): trans['CHIL{}'.format(_)] = (4000, -4000 + row * (_ - 30)) # trans['CHIL30'] = (4000, -4000 + row * 0) # trans['CHIL31'] = (4000, -4000 + row * 1) # trans['CHIL32'] = (4000, -4000 + row * 2) # trans['CHIL33'] = (4000, -4000 + row * 3) # trans['CHIL34'] = (4000, -4000 + row * 4) # trans['CHIL35'] = (4000, -4000 + row * 5) # trans['CHILD23'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 0)) # trans['CHILD24'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 1)) # trans['CHILD25'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 2)) # trans['CHILD26'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 3)) # trans['CHILD27'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 4)) # trans['CHILD28'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 5)) # trans['CHILD29'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 6)) # trans['CHILD32'] = (-14500, -3000 + row * 0) # trans['CHILD33'] = (-14500, -3000 + row * 1) # trans['CHILD34'] = (-14500, -3000 + row * 2) # trans['CHILD35'] = (-14500, -3000 + row * 3) # trans['CHILD36'] = (-14500, -3000 + row * 4) # trans['CHILD37'] = (-14500, -3000 + row * 5) # trans['CHILD38'] = (-14500, -3000 + row * 6) # trans['CHILD39'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 0)) # trans['CHILD40'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 1)) # trans['CHILD41'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 2)) # trans['CHILD42'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 3)) # trans['CHILD43'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 4)) # trans['CHILD44'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 5)) # trans['CHILD45'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 6)) # trans['CHILD46'] = (-2500, -3000 + row * 0) # trans['CHILD47'] = (-2500, -3000 + row * 1) # trans['CHILD48'] = (-2500, -3000 + row * 2) # trans['CHILD49'] = (-2500, -3000 + row * 3) # trans['CHILD50'] = (-2500, -3000 + row * 4) # trans['CHILD51'] = (-2500, -3000 + row * 5) # trans['CHILD52'] = (-2500, -3000 + row * 6) # trans['CHILD53'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 0)) # trans['CHILD54'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 1)) # trans['CHILD55'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 2)) # trans['CHILD56'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 3)) # trans['CHILD57'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 4)) # trans['CHILD58'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 5)) # trans['CHILD59'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 6)) # # trans['CHILD60'] = (-14500, -3000 + row * 0) # trans['CHILD61'] = (-14500, -3000 + row * 1) # trans['CHILD62'] = (-14500, -3000 + row * 2) # trans['CHILD63'] = (-14500, -3000 + row * 3) # trans['CHILD64'] = (-14500, -3000 + row * 4) # trans['CHILD65'] = (-14500, -3000 + row * 5) # trans['CHILD66'] = (-14500, -3000 + row * 6) # trans['CHILD67'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 0)) # trans['CHILD68'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 1)) # trans['CHILD69'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 2)) # trans['CHILD70'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 3)) # trans['CHILD71'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 4)) # trans['CHILD72'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 5)) # trans['CHILD73'] = i3.Rotation(rotation=180) + i3.Translation((14500, 0 + row * 6)) # trans['CHILD74'] = (-2500, -3000 + row * 0) # trans['CHILD75'] = (-2500, -3000 + row * 1) # trans['CHILD76'] = (-2500, -3000 + row * 2) # trans['CHILD77'] = (-2500, -3000 + row * 3) # trans['CHILD78'] = (-2500, -3000 + row * 4) # trans['CHILD79'] = (-2500, -3000 + row * 5) # trans['CHILD80'] = (-2500, -3000 + row * 6) # trans['CHILD81'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 0)) # trans['CHILD82'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 1)) # trans['CHILD83'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 2)) # trans['CHILD84'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 3)) # trans['CHILD85'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 4)) # trans['CHILD86'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 5)) # trans['CHILD87'] = i3.Rotation(rotation=180) + i3.Translation((26500, 0 + row * 6)) return trans
} return child_transformations def _default_bend_radius(self): bend_radius = 300 return bend_radius mmmi1 = v6(name="PP1") mmmi1_layout = mmmi1.Layout(length2=92) mmmi2 = v6(name="PP2") mmmi2_layout = mmmi2.Layout(length2=97) mmmi3 = v6(name="PP3") mmmi3_layout = mmmi3.Layout(length2=102) prr = PlaceAndAutoRoute(child_cells={ "cell_1": mmmi1, "cell_2": mmmi2, "cell_3": mmmi3 }) prr_layout = prr.Layout( child_transformations={ "cell_1": i3.HMirror(0.0) + i3.Translation((3300, 0)), "cell_2": i3.Translation((3300, 0)), "cell_3": i3.HMirror(0.0) + i3.Translation((9900, 0)) }) prr_layout.visualize(annotate=True) prr_layout.write_gdsii("2_2_MMI2112_V6_line_20.gds")
def _generate_instances(self, insts): # Generates taper clip # make my OWN custom waveguide trace template # wg_trace = f_MyIMECWaveguideTemplate(core_width=self.taper_prop_dict['width1'], # cladding_width=self.taper_prop_dict['width1'] + 2.0 * self.taper_prop_dict['width_etch']) # make waveguide wg = i3.Waveguide(trace_template=StripWgTemplate(), name=self.name + '_WG') wg_round = i3.RoundedWaveguide(trace_template=StripWgTemplate(), name=self.name + '_WG_ROUND') # how much to translate bends left/right # t_left = i3.Translation((self.bend_radius + (float(self.n_rows)/2.0) )) t_left = i3.Translation((-2.5 * self.bend_radius, 0.0)) t_right = i3.Translation((2.5 * self.bend_radius, 0.0)) # draw taper pair rows for ii in range(self.n_rows): # add rows tp_rows_layout = TaperPairRow(name=self.name + '_TProw' + str(ii)).get_default_view( i3.LayoutView) tp_rows_layout.set( taper_prop_dict=self.taper_prop_dict, connect_length=self.connect_length, pair_connect_length=self.pair_connect_length, n_pairs=self.n_taper_pairs_per_row) # set translation t = i3.Translation((0.0, float(ii) * self.row_spacing)) # place taper pair row tp_row_name = self.name + '_TP_ROW' + str(ii) insts += i3.SRef(name=tp_row_name, reference=tp_rows_layout, transformation=t) # draw connecting arcs if ii > 0: if (ii % 2) == 1: # bend on the right # make shape bend row_name = self.name + '_TP_ROW' + str(ii - 1) shape_bend = i3.ShapeBend(start_point=insts[row_name]. ports['right'].position, radius=self.bend_radius, start_angle=-90.05, end_angle=90.05, angle_step=0.1) # add 180 deg bend wg_copy = i3.Waveguide( trace_template=StripWgTemplate(), name=self.name + '_arc_r' + str(ii)) arc_name = self.name + '_arc' + str(ii) insts += i3.SRef( name=arc_name, reference=wg_copy.Layout(shape=shape_bend), transformation=t_right) # connect bottom wgs # get coords in_port_coords = insts[arc_name].ports['in'].position out_port_coords = insts[row_name].ports[ 'right'].position # draw bezier curve bez = BezierCurve( N=100, P0=(in_port_coords[0] + 0.01, in_port_coords[1]), P1=(in_port_coords[0] - self.bend_radius / 2.0, in_port_coords[1]), P2=(out_port_coords[0] + self.bend_radius / 2.0, out_port_coords[1]), P3=(out_port_coords[0] - 0.01, out_port_coords[1]), R=(-self.bend_radius, +self.bend_radius), dy_dx=(0.0, -0.0)) bez_coords = bez.bezier_coords() # make ipkiss shape s = i3.Shape(bez_coords) # add bottom wg connector wg_copy = i3.Waveguide( trace_template=StripWgTemplate(), name=self.name + '_arc_r_con' + str(ii)) insts += i3.SRef(name=self.name + '_con_wg_r_b_' + str(ii), reference=wg_copy.Layout(shape=s)) # connect top wgs next_row_name = self.name + '_TP_ROW' + str(ii) in_port_coords = insts[arc_name].ports['out'].position out_port_coords = insts[next_row_name].ports[ 'right'].position # draw bezier curve bez = BezierCurve( N=500, P0=(in_port_coords[0] + 0.01, in_port_coords[1]), P1=(in_port_coords[0] - self.bend_radius / 2.0, in_port_coords[1]), P2=(out_port_coords[0] + self.bend_radius / 2.0, out_port_coords[1]), P3=(out_port_coords[0] - 0.01, out_port_coords[1]), R=(self.bend_radius, -self.bend_radius), dy_dx=(0.0, -0.0)) bez_coords = bez.bezier_coords() # make ipkiss shape s = i3.Shape(bez_coords) # add wg bend wg_copy = i3.Waveguide( trace_template=StripWgTemplate(), name=self.name + '_bez_r' + str(ii)) insts += i3.SRef(name=self.name + '_con_wg_r_t_' + str(ii), reference=wg_copy.Layout(shape=s)) else: # bend on the left # make shape bend row_name = self.name + '_TP_ROW' + str(ii - 1) shape_bend = i3.ShapeBend(start_point=( insts[row_name].ports['left'].position), radius=self.bend_radius, start_angle=90.05, end_angle=-90.05, angle_step=0.1, clockwise=False) # add 180 deg bend wg_copy = i3.Waveguide( trace_template=StripWgTemplate(), name=self.name + '_arc_l' + str(ii)) arc_name = self.name + '_arc' + str(ii) insts += i3.SRef( name=arc_name, reference=wg_copy.Layout(shape=shape_bend), transformation=t_left) # connect bottom wgs # get coords in_port_coords = insts[arc_name].ports['out'].position out_port_coords = insts[row_name].ports[ 'left'].position # draw bezier curve bez = BezierCurve( N=100, P0=(in_port_coords[0] - 0.01, in_port_coords[1]), P1=(in_port_coords[0] + self.bend_radius / 2.0, in_port_coords[1]), P2=(out_port_coords[0] - self.bend_radius / 2.0, out_port_coords[1]), P3=(out_port_coords[0] + 0.01, out_port_coords[1]), R=(-self.bend_radius, +self.bend_radius), dy_dx=(0.0, -0.0)) bez_coords = bez.bezier_coords() # make ipkiss shape s = i3.Shape(bez_coords) # add bottom wg connector wg_copy = i3.Waveguide( trace_template=StripWgTemplate(), name=self.name + '_arc_l_con' + str(ii)) insts += i3.SRef(name=self.name + '_con_wg_l_b_' + str(ii), reference=wg_copy.Layout(shape=s)) # connect top wgs next_row_name = self.name + '_TP_ROW' + str(ii) in_port_coords = insts[arc_name].ports['in'].position out_port_coords = insts[next_row_name].ports[ 'left'].position # draw bezier curve bez = BezierCurve( N=500, P0=(in_port_coords[0] - 0.01, in_port_coords[1]), P1=(in_port_coords[0] + self.bend_radius / 2.0, in_port_coords[1]), P2=(out_port_coords[0] - self.bend_radius / 2.0, out_port_coords[1]), P3=(out_port_coords[0] + 0.01, out_port_coords[1]), R=(-self.bend_radius, +self.bend_radius), dy_dx=(0.0, -0.0)) bez_coords = bez.bezier_coords() # make ipkiss shape s = i3.Shape(bez_coords) # add wg bend wg_copy = i3.Waveguide( trace_template=StripWgTemplate(), name=self.name + '_bez_l' + str(ii)) insts += i3.SRef(name=self.name + '_con_wg_l_t_' + str(ii), reference=wg_copy.Layout(shape=s)) # end if bend # end drawing connecting arcs # end for ii in range(self.rows) # # connect the input grating # # pick grating layout to return # grating_layout = { # 'FGCCTE_FC1DC_625_313': FGCCTE_FC1DC_625_313().Layout(), # 'FGCCTE_FCWFC1DC_630_378': FGCCTE_FCWFC1DC_630_378().Layout(), # 'FGCCTM_FC1DC_984_492': FGCCTM_FC1DC_984_492().Layout(), # }[self.grating_name] # # # # # place bottom grating # # always assuming bottom grating starts on the left # bot_grating_name = self.name+'_bot_grating' # t = i3.vector_match_transform( grating_layout.ports['waveguide'], # insts[self.name + '_TP_ROW0'].ports['left'] ) + \ # i3.Translation( ( -self.bot_gc_connect_length, 0.0 ) ) # # insts += i3.SRef( name = bot_grating_name, # reference = grating_layout, # transformation = t ) # # # connect bottom grating to taper # route_wg_bot = i3.RouteManhattan( input_port = insts[bot_grating_name].ports['waveguide'], # output_port = insts[self.name + '_TP_ROW0'].ports['left'] ) # # # add wg # wg_bot = i3.Waveguide( trace_template = StripWgTemplate(), name = self.name + '_WG_BOT') # insts += i3.SRef(name=self.name + '_connect_wg_bot', reference=wg_bot.Layout(shape=route_wg_bot)) # # # # # place top grating # top_grating_name = self.name + '_top_grating' # if (self.n_rows % 2) == 1: # # even # of rows, output is to the right # t = i3.vector_match_transform( grating_layout.ports['waveguide'], # insts[self.name + '_TP_ROW' + str(self.n_rows-1)].ports['right'], # mirrored = True ) + \ # i3.Translation((self.top_gc_connect_length, 0.0)) # # insts += i3.SRef( name = top_grating_name, # reference = grating_layout, # transformation = t) # # # connect top grating to taper # route_wg_top = i3.RouteManhattan( input_port = insts[top_grating_name].ports['waveguide'], # output_port = insts[self.name + '_TP_ROW' + str(self.n_rows-1)].ports['right']) # # # add wg # wg_top = i3.Waveguide( trace_template = StripWgTemplate(), name = self.name + '_WG_TOP') # insts += i3.SRef(name=self.name + '_connect_wg_top', reference=wg_top.Layout(shape=route_wg_top)) # # else: # # odd # of rows, output is to the left # t = i3.vector_match_transform( grating_layout.ports['waveguide'], # insts[self.name + '_TP_ROW' + str(self.n_rows-1)].ports['left'], # mirrored = False ) + \ # i3.Translation((-self.top_gc_connect_length, 0.0)) # # insts += i3.SRef( name = top_grating_name, # reference = grating_layout, # transformation = t) # # # connect top grating to taper # route_wg_top = i3.RouteManhattan( input_port = insts[top_grating_name].ports['waveguide'], # output_port = insts[self.name + '_TP_ROW' + str(self.n_rows-1)].ports['left']) # # # add wg # wg_top = i3.Waveguide( trace_template = StripWgTemplate(), name = self.name + '_WG_TOP') # insts += i3.SRef(name=self.name + '_connect_wg_top', reference=wg_top.Layout(shape=route_wg_top)) return insts