def _generate_instances(self, insts): # Generates taper pairs tp_name_list = [] for ii in range(self.n_pairs): # for each pair # draw taper pair layout tp_lay = TaperPair(name=self.name + '_tp' + str(ii)).get_default_view(i3.LayoutView) tp_lay.set(taper_prop_dict=self.taper_prop_dict, connect_length=self.connect_length) # set name tp_name = 'tp' + str(ii) tp_name_list.append(tp_name) # set transformation if ii > 0: # set transform t = i3.vector_match_transform( tp_lay.ports['left'], insts[ tp_name_list[ii - 1] ].ports['right']) \ + i3.Translation( ( self.pair_connect_length, 0.0 ) ) # print t # draw next taper pair insts += i3.SRef(name=tp_name, reference=tp_lay, transformation=t) # route wg route_wg = i3.RouteManhattan( input_port=insts[tp_name_list[ii - 1]].ports['right'], output_port=insts[tp_name_list[ii]].ports['left']) # # 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' + str(ii)) # add wg insts += i3.SRef(name=self.name + 'connect_wg' + str(ii), reference=wg.Layout(shape=route_wg)) else: # draw first taper pair insts += i3.SRef(name=tp_name, reference=tp_lay) # DEBUG # print insts # end if else return insts
def _get_components(self): res_x_dim = self._resonator_size_core_to_core() ring_gap = self.ring_gap ring_core_width = self.wg_ring_template.core_width ring_gap_list = self.ring_gap_list shifting_list = [0.] + ring_gap_list all_components = [] # and now crank an SRef for each Ring in a loop for ring in range(self.num_rings): # will translate the original ring over to the correct position, and iterate for number of rings # use an if statement for external gap list or not. Need an error if self.use_gap_list is False: this_transform = i3.Translation( ((res_x_dim + ring_gap + ring_core_width) * ring, 0.)) this_resonator = i3.SRef(name="R_" + str(ring), reference=self.resonator, transformation=this_transform) all_components.append(this_resonator) else: # sum previous elements of the shifting list for correct relative translation total_shift = sum(shifting_list[:(ring + 1)]) this_transform = i3.Translation( ((res_x_dim + ring_core_width) * ring + total_shift, 0.)) this_resonator = i3.SRef(name="R_" + str(ring), reference=self.resonator, transformation=this_transform) all_components.append(this_resonator) return all_components
def _generate_instances(self, insts): delta = self.trace_template.core_width + self.spacing bend_radius = self.bend_radius coupler_length = self.cell.get_default_view( i3.CircuitModelView).coupler_length shape = i3.Shape([ (-coupler_length / 2.0 - bend_radius, bend_radius), (-coupler_length / 2.0 - bend_radius, 0.0), (-coupler_length / 2.0, 0.0), (coupler_length / 2.0, 0.0), (coupler_length / 2.0 + bend_radius, 0.0), (coupler_length / 2.0 + bend_radius, bend_radius) ]) wg = i3.RoundedWaveguide(name=self.name + "_wg", trace_template=self.trace_template) wg_layout = wg.Layout(shape=shape) insts += i3.SRef(reference=wg_layout, name="wav_top", position=(0, delta / 2.0)) insts += i3.SRef(reference=wg_layout, name="wav_bot", transformation=i3.VMirror() + i3.Translation(translation=(0, -delta / 2.0))) return insts
def _generate_instances(self, insts): x_inc = self.mysingleObstacle.gap_btw_barriers * 1 + self.mysingleObstacle.obstacle_trap_radius * 2 y_inc = self.mysingleObstacle.obstacle_trap_radius * 2 + self.mysingleObstacle.gap_btw_barriers cycles_x = int(self.wholeTrapX / (self.mysingleObstacle.gap_btw_barriers + self.mysingleObstacle.obstacle_trap_radius * 2)) cycles_y = int(self.wholeTrapY / (y_inc)) insts += i3.ARef( reference=self.mysingleObstacle, origin=(0, 0.0 * self.cell.wholeTrapY), period=(x_inc, 0), n_o_periods=(cycles_x, 1), #transformation=i3.Rotation((0.0, 0.0), 40.0) ) xf = self.mysingleObstacle.gap_btw_barriers + self.mysingleObstacle.obstacle_trap_radius * 0.5 insts += i3.ARef( reference=self.mysingleObstacle, origin=(xf, y_inc), period=(x_inc, 0), n_o_periods=(cycles_x, 1), #transformation=i3.Rotation((0.0, 0.0), 40.0) ) insts += i3.SRef(reference=self.rightFilling, position=(cycles_x * x_inc, 0)) insts += i3.SRef(reference=self.leftFilling, position=(0, y_inc)) #transformation=i3.Rotation((0.0, 0.0), 40.0) print 'insts', insts return insts
def _generate_instances(self, insts): # includes the get components and the new waveguides insts += self._get_components() wg_in1_layout, wg_in2_layout, wg_out1_layout, wg_out2_layout = self.wgs insts += i3.SRef(reference=wg_in1_layout, name="wg_in1") insts += i3.SRef(reference=wg_in2_layout, name="wg_in2") insts += i3.SRef(reference=wg_out1_layout, name="wg_out1") insts += i3.SRef(reference=wg_out2_layout, name="wg_out2") return insts
def _generate_elements(self, elems): # # Center of the structure # (x0, y0) = self.position # # RELEASE c1 = Coupon(length=40) #2750 label A no need for shrink elems += i3.SRef(reference=c1, transformation=i3.Translation((0, 0))) Medphab = mmi_slots_cell_test() elems += i3.SRef(reference=Medphab) return elems
def _generate_instances(self, insts): # generates taper pair # generate left taper cell taper_layout_left = ParabolicTaper( name=self.name + '_TAPER_L').get_default_view(i3.LayoutView) taper_layout_left.set( length=self.taper_prop_dict['length'], width1=self.taper_prop_dict['width1'], width2=self.taper_prop_dict['width2'], width_etch=self.taper_prop_dict['width_etch']) # generate right taper cell taper_layout_right = ParabolicTaper( name=self.name + '_TAPER_R').get_default_view(i3.LayoutView) taper_layout_right.set( length=self.taper_prop_dict['length'], width1=self.taper_prop_dict['width1'], width2=self.taper_prop_dict['width2'], width_etch=self.taper_prop_dict['width_etch']) # draw taper pairs insts += i3.SRef(name=self.name + '_taper1', reference=taper_layout_left) t = i3.vector_match_transform(taper_layout_left.ports['right'], taper_layout_right.ports['right'], mirrored=True) + i3.Translation( (self.connect_length, 0.0)) insts += i3.SRef(name=self.name + '_taper2', reference=taper_layout_right, transformation=t) # route between tapers if self.connect_length > 0.0: route_tapers = i3.RouteManhattan( input_port=insts[self.name + '_taper1'].ports['right'], output_port=insts[self.name + '_taper2'].ports['right']) # # make my OWN custom waveguide trace template # wg_trace = f_MyIMECWaveguideTemplate( core_width = taper_layout_left.width2, # cladding_width = taper_layout_right.width2 + 2.0*taper_layout_right.width_etch ) # wg_lay = i3.Waveguide(trace_template=StripWgTemplate(), name=wg_name).get_default_view(i3.LayoutView) # make waveguide wg = i3.Waveguide(trace_template=StripWgTemplate(), name=self.name + '_WG') # add wg insts += i3.SRef(name=self.name + 'connect_wg', reference=wg.Layout(shape=route_tapers)) # end if self.connect_length > 0.0 return insts
def _generate_instances(self, insts): channel1 = microfluidics.Channel( trace_template=self.cell.channel_template) channel1_lo = channel1.Layout( shape=[(0, -self.tee_length), (0, self.tee_length)]) insts += i3.SRef(channel1_lo, position=(0, 0)) channel2 = microfluidics.Channel( trace_template=self.cell.channel_template) channel2_lo = channel2.Layout(shape=[(0, 0), (-self.tee_length, 0)]) insts += i3.SRef(channel2_lo, position=(self.tee_length, 0)) return insts
def _generate_instances(self, insts): swg_l, flyback_l, bend_l, taper_swg_l, taper_flyback_l = self._get_components( ) for ii in range(self.numrows): # Find component translations (for all numrows) t_swg = i3.Translation((0.0, ii * self.pitch)) t_taper_swg_w = vector_match_transform( taper_swg_l.ports["out"], swg_l.ports['in']) + t_swg t_taper_swg_e = vector_match_transform( taper_swg_l.ports["out"], swg_l.ports['out'], mirrored=True) + t_swg # Add instances (for all numrows) insts += i3.SRef(reference=swg_l, name="SidewallGratWg" + str(ii), transformation=t_swg) insts += i3.SRef(reference=taper_swg_l, name="SwgTaper_West" + str(ii), transformation=t_taper_swg_w) insts += i3.SRef(reference=taper_swg_l, name="SwgTaper_East" + str(ii), transformation=t_taper_swg_e) if ii < (self.numrows - 1): # Find component translations (for numrows-1) flyback_offset = self.grat_wg_width / 2 + self.spacing + self.flyback_wg_width / 2 t_flyback = i3.Translation( (0.0, ii * self.pitch + flyback_offset)) t_taper_flyback_w = vector_match_transform( taper_flyback_l.ports["out"], flyback_l.ports['in']) + t_flyback t_taper_flyback_e = vector_match_transform( taper_flyback_l.ports["out"], flyback_l.ports['out'], mirrored=True) + t_flyback t_bend_e = i3.VMirror() + vector_match_transform( bend_l.ports['in'], taper_swg_l.ports["in"], mirrored=True) + t_taper_swg_e t_bend_w = i3.VMirror() + vector_match_transform( bend_l.ports['out'], taper_flyback_l.ports["in"] ) + t_taper_flyback_w + i3.Translation((0.0, self.pitch)) # Add instances (for numrows-1) insts += i3.SRef(reference=flyback_l, name="FlybackWg" + str(ii), transformation=t_flyback) insts += i3.SRef(reference=taper_flyback_l, name="FlybackTaper_West" + str(ii), transformation=t_taper_flyback_w) insts += i3.SRef(reference=taper_flyback_l, name="FlybackTaper_East" + str(ii), transformation=t_taper_flyback_e) insts += i3.SRef(reference=bend_l, name="Bend_West" + str(ii), transformation=t_bend_w) insts += i3.SRef(reference=bend_l, name="Bend_East" + str(ii), transformation=t_bend_e) return insts
def _generate_instances(self, insts): insts += i3.SRef(reference=self.wgs_straights[0], name="in") insts += i3.SRef( reference=self.wgs_straights[1], name="out1", position=(self.length_straights + self.length_splitting_shape, -self.spacing / 2)) insts += i3.SRef( reference=self.wgs_straights[2], name="out2", position=(self.length_straights + self.length_splitting_shape, +self.spacing / 2)) return insts
def _generate_elements(self, elems): elems += i3.SRef(reference=PlaceMarkers()) elems += i3.SRef(reference=my_exe2(name="final")) generated1 = i3.TECH.PPLAYER.HFW - i3.TECH.PPLAYER.V12.PILLAR mapping = {generated1: i3.TECH.PPLAYER.M2.LINE} elems += i3.get_elements_for_generated_layers(elems, mapping) generated2 = i3.TECH.PPLAYER.WG.CLADDING - i3.TECH.PPLAYER.WG.CORE mapping = {generated2: i3.TECH.PPLAYER.WG.TEXT} elems += i3.get_elements_for_generated_layers(elems, mapping) # elems += i3.SRef(reference=ImportRik()) return elems
def _generate_instances(self, insts): # First create shapes # Break the channel that contain two obstacles into three segments # Obstacles need to intersect these three segments # Obs 1. Segment 1:2, Obs 2 Segment 2:3 #define points will be helpful to make schematic p1 = (self.cInp.x + 0.0, self.cInp.y + 0.0) p2 = ((self.gap_btw_barriers * 0.5 + self.obstacle_trap_radius), 0.0) p3 = ((self.gap_btw_barriers * 0.5 + self.obstacle_trap_radius), self.gap_btw_barriers + self.obstacle_trap_radius * 2) p4 = (0.0, self.gap_btw_barriers + self.obstacle_trap_radius * 2) sr1 = i3.Shape(points=[p1, p2, p3, p4], closed=True) #Internal holes as Circles #to do: define position of SC2 as a function of perpendicular GAP sc1 = i3.ShapeCircle(center=(self.cInp.x + 0.0, self.gap_btw_barriers * 0.5 + self.obstacle_trap_radius), radius=(self.obstacle_trap_radius)) #Define the boundaries for shapes br1 = i3.Boundary(layer=self.layer, shape=sr1) bc1 = i3.Boundary(layer=self.layer, shape=sc1) #Substruct boundaries and add to the element list b_sub = br1 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) return insts
def _generate_instances(self, insts): # includes the get components and the new waveguides insts += self._get_components() wg_in_layout, wg_pass_layout = self.wgs # wg_pass_layout, wg_ring_layout insts += i3.SRef(reference=wg_in_layout, name="wg_in") # insts += i3.SRef(reference=wg_pass_layout, name="wg_pass") # insts += i3.SRef(reference=wg_ring_layout, name="wg_ring") return insts
def _generate_instances(self, insts): for cnt in range(4): trans = i3.Translation(translation=(0.0, cnt * self.mmi_sep)) insts += i3.SRef(name="MMI_{}".format(cnt), reference=self.mmi, transformation=trans) return insts
def _generate_instances(self, insts): sr1 = i3.ShapeCircle(center=(0.0, 0.0), radius=self.radius) #, line_width = 200) sr2 = i3.ShapeCircle( center=(0.0, 0.0), radius=self.radius - self.vacuum_channel_circular) #, line_width = 200) #Rectangles sc1 = i3.ShapeRectangle( center=(self.cInp.x - self.radius, -self.radius), box_size=(self.radius * 2, self.radius * 2 + 100)) #100 has to be linked to channel input width)) #Define the boundaries for shapes br1 = i3.Boundary(layer=self.layer, shape=sr1) br2 = i3.Boundary(layer=self.layer, shape=sr2) bc1 = i3.Boundary(layer=self.layer, shape=sc1) #Substruct boundaries and add to the element list b_sub = br1 - br2 s = i3.Structure(elements=b_sub) b_sub = b_sub[0] - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) #Input channel - segment channel1 = microfluidics.Channel( trace_template=self.cell.channel_template) channel1_lo = channel1.Layout( shape=[(0, 0), (0, self.inlet_channel_length + self.vacuum_channel_circular * 0.5)]) insts += i3.SRef(channel1_lo, position=(0, self.radius - self.vacuum_channel_circular * 0.5), transformation=i3.Rotation((0.0, 0.0), 0.0)) return insts
def _generate_instances(self, insts): # edge coupler fname = '../josep/thermo_optic_phase_shifter.gds' heater_gds_lay = i3.GDSCell(filename=fname).Layout() insts += i3.SRef(name=self.name + '_HEAT', reference=heater_gds_lay) return insts
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 _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position # ADD RELEASE elems += i3.SRef(reference=Interface(pocket=False, tilt=False), transformation=i3.Translation( (x0, 0.0 * self.v_spacing + y0))) elems += i3.SRef(reference=Interface(pocket=True, tilt=False), transformation=i3.Translation( (x0, 1.0 * self.v_spacing + y0))) elems += i3.SRef(reference=Interface(pocket=False, tilt=True), transformation=i3.Translation( (x0, 2.0 * self.v_spacing + y0))) elems += i3.SRef(reference=Interface(pocket=True, tilt=True), transformation=i3.Translation( (x0, 3.0 * self.v_spacing + y0))) return elems
def _generate_instances(self, insts): # edge coupler fname = os.path.dirname( os.path.realpath(__file__)) + '/gds/aim_edge_coupler_si.gds' edge_coupler_gds_lay = i3.GDSCell(filename=fname).Layout() insts += i3.SRef(name=self.name + '_EDGE_COUPLER', reference=edge_coupler_gds_lay, flatten=True) return insts
def _generate_instances(self, insts): # Define some parameters gap = 0.2 core_width = wg_t_lo.core_width # Define a rounded waveguide wg = i3.RoundedWaveguide(name=self.name + '_wg1', trace_template=wg_t) wg.Layout(shape=[(-15, 3), (-10, 3), (-5, 0), (5, 0), (10, 3), (15, 3)]) # Define instances insts += i3.SRef(name='wg_top', reference=wg, position=(0, 0.5 * (core_width + gap))) insts += i3.SRef(name='wg_bottom', reference=wg, position=(0, -0.5 * (core_width + gap)), transformation=i3.VMirror()) return insts
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_instances(self, insts): insts += i3.SRef(reference=self.cross_marks[0]) insts += i3.SRef(reference=self.cross_marks[1]) vern_1_horz_trans = i3.VMirror() + \ i3.Translation((0, -self.cross_boundary_width * 0.5 - self.vern_cross_spacing - (self.vern_bar_length + self.vern_bar_extra_length) - self.vern_layer_gap)) insts += i3.SRef(reference=self.verniers[0], transformation=vern_1_horz_trans) vern_2_horz_trans = i3.Translation((0, -self.cross_boundary_width * 0.5 - self.vern_cross_spacing - (self.vern_bar_length + self.vern_bar_extra_length))) insts += i3.SRef(reference=self.verniers[1], transformation=vern_2_horz_trans) vern_1_vert_trans = i3.Rotation(rotation=90) + \ i3.Translation((-self.cross_boundary_width*0.5 - self.vern_cross_spacing - (self.vern_bar_length + self.vern_bar_extra_length) - self.vern_layer_gap, 0)) insts += i3.SRef(reference=self.verniers[0], transformation=vern_1_vert_trans) vern_2_vert_trans = i3.Rotation(rotation=270) + \ i3.Translation((-self.cross_boundary_width*0.5 - (self.vern_bar_length + self.vern_bar_extra_length) - self.vern_cross_spacing, 0)) insts += i3.SRef(reference=self.verniers[1], transformation=vern_2_vert_trans) return insts
def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 + 2000, y0 + 600 + (1800 - self.width) / 4), box_size=(self.length, (1800 - self.width) / 2)) elems += i3.Rectangle( layer=self.layer, center=(x0 + 6500 + 2000, y0 + 600 + self.width + (1800 - self.width) * 3 / 4), box_size=(self.length, (1800 - self.width) / 2)) elems += i3.SRef( reference=Interface_mmi12(pocket=self.pocket, tilt=self.tilt)) if self.pillar: self.label = "NO" for i in range(7): elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000, 600 + (1800 - self.width) / 2 + 30), #change box_size=(50, 60)) elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000, 600 + (1800 - self.width) / 2 + self.width - 30), #change box_size=(50, 60)) if self.width > 330: self.label += "W" if self.pocket: self.label += "_WP" if self.tilt: self.label += "WT" elems += i3.PolygonText( layer=self.layer_bool, text=self.label, coordinate=(8000, 2700), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=700.0) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
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 _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 _generate_instances(self, insts): channel_1_template = self.cell.channel_1_template.Layout( channel_width=self.cell.initial_width) channel_2_template = self.cell.channel_2_template.Layout( channel_width=self.cell.final_width) funnel = microfluidics.LinearWindowChannelTransition( start_trace_template=self.cell.channel_1_template, end_trace_template=self.cell.channel_2_template) funnel_layout = funnel.Layout( start_position=(0.0, 0.0), end_position=(self.cell.funnel_length, 0.0)) insts += i3.SRef(reference=funnel_layout, name='funnel', position=(0, 0)) return insts
def _generate_instances(self, elems): # insts): rectangle = i3.RoundedRectangle(layer=i3.TECH.PPLAYER.CH2.TRENCH, center=(0.0, 0.0), box_size=(self.tee_length, 2 * self.tee_length), radius=1.0) rectangle2 = i3.RoundedRectangle(layer=i3.TECH.PPLAYER.CH2.TRENCH, center=(0.5 * self.tee_length, 0.0), box_size=(self.tee_length, self.tee_length), radius=1.0) #boolean operation add main trap and 1st rectangle b_add = rectangle | rectangle2 s = i3.Structure(elements=b_add) elems += i3.SRef(s) return elems #insts
def _generate_instances(self, insts): # First create shapes # Break the channel that contain two obstacles into three segments # Obstacles need to intersect these three segments # Obs 1. Segment 1:2, Obs 2 Segment 2:3 #define points will be helpful to make schematic p1 = (self.cInp.x+0.0,self.cInp.y+0.0) p2 = ((self.gap_btw_barriers+self.obstacle_trap_length)*0.5,0.0) p3 = ((self.gap_btw_barriers+self.obstacle_trap_length)*0.5,self.channel_trap_width) p4 = (0.0,self.channel_trap_width) p5 = ((self.gap_btw_barriers+self.obstacle_trap_length)*1.5, 0.0) p6 = ((self.gap_btw_barriers+self.obstacle_trap_length)*2, 0.0) p7 = ((self.gap_btw_barriers+self.obstacle_trap_length)*2, self.channel_trap_width) p8 = ((self.gap_btw_barriers+self.obstacle_trap_length)*1.5,self.channel_trap_width) sr1 = i3.Shape(points = [p1,p2,p3,p4], closed =True) sr2 = i3.Shape(points = [p2,p5,p8,p3], closed =True) sr3 = i3.Shape(points = [p5,p6,p7,p8], closed =True) #Internal holes as Circles #to do: define position of SC2 as a function of perpendicular GAP sc1 = i3.ShapeCircle(center = (self.cInp.x+(self.gap_btw_barriers+self.obstacle_trap_length)*0.65, 0.0), radius = (self.obstacle_trap_width)) sc2 = i3.ShapeCircle(center = (self.cInp.x+(self.gap_btw_barriers+self.obstacle_trap_length)*1.35,self.cInp.y+self.channel_trap_width), radius = (self.obstacle_trap_width)) #Internal holes as Rectangles ''' sc1 = i3.ShapeRectangle(center = (self.cInp.x+(self.gap_btw_barriers +self.obstacle_trap_length)*0.5, self.cInp.y+self.obstacle_trap_width*0.5), box_size = (self.obstacle_trap_length, self.obstacle_trap_width)) sc2 = i3.ShapeRectangle(center = (self.cInp.x+(self.gap_btw_barriers +self.obstacle_trap_length)*1.5, self.cInp.y+self.channel_trap_width-self.obstacle_trap_width*0.5), box_size = (self.obstacle_trap_length, self.obstacle_trap_width)) ''' #Define the boundaries for shapes br1 = i3.Boundary(layer = self.layer, shape = sr1) br2 = i3.Boundary(layer = self.layer, shape = sr2) br3 = i3.Boundary(layer = self.layer, shape = sr3) bc1 = i3.Boundary(layer = self.layer, shape = sc1) bc2 = i3.Boundary(layer = self.layer, shape = sc2) #Substruct boundaries and add to the element list b_sub = br1-bc1 s= i3.Structure(elements = b_sub) insts += i3.SRef(s) b_sub = br2-bc1 b_sub = b_sub[0] - bc2 s= i3.Structure(elements = b_sub) insts += i3.SRef(s) b_sub = br3-bc2 s= i3.Structure(elements = b_sub) insts += i3.SRef(s) return insts
from aeponyx import technology from aeponyx.all import SWG450, SWG550, SWG1000, RWG450, RWG850, RoundedWireWaveguide, RoundedRibWaveguide from ipkiss3 import all as i3 shape = [(0, 0), (300, 0), (300, 300), (600, 300), (1000, 0)] wg1 = RoundedWireWaveguide(trace_template=SWG450()) wg1.Layout(shape=shape) wg2 = RoundedRibWaveguide(trace_template=RWG850()) wg2.Layout(shape=shape) lc = i3.LayoutCell() #lay = lc.Layout(elements=[i3.SRef(wg1, position=(0, 0)), # i3.SRef(wg2, position=(0, 500))]) lay = lc.Layout(elements=[i3.SRef(wg1, position=(0, 0))]) lay.write_gdsii('waveguides.gds') lay.visualize()
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