def define_elements(self, elems): from ipkiss.plugins.photonics.wg.basic import WgElDefinition if self.extension != 0.0: extended_start_width = self.start_wg_definition.wg_width + (self.end_wg_definition.wg_width-self.start_wg_definition.wg_width) * (self.extension + self.length- self.straight_extension)/self.length else: extended_start_width = self.end_wg_definition.wg_width end_wg_def = WgElDefinition(wg_width = extended_start_width, trench_width = self.end_wg_definition.trench_width, process = self.end_wg_definition.process) end_wg_def_ext = WgElDefinition(wg_width = extended_start_width+0.05, trench_width = self.end_wg_definition.trench_width-0.05, process = self.end_wg_definition.process) elems += WgElTaperLinear(start_position = (self.center[0] - self.extension ,self.center[1]), end_position = (self.center[0] + self.length, self.center[1]), start_wg_def = end_wg_def, end_wg_def = self.start_wg_definition, straight_extension = (0.0, 0.0)) if self.straight_extension > 0: elems += WgElTaperLinear(start_position = (self.center[0] - self.extension, self.center[1]), end_position = (self.center[0] - self.extension - self.straight_extension, self.center[1]), start_wg_def = end_wg_def, end_wg_def = end_wg_def_ext, straight_extension = (0.0, 0.0)) if self.straight_entrance > 0.0: elems += self.start_wg_definition(shape = [(self.center[0] + self.length ,self.center[1]), (self.center[0] + self.length + self.straight_entrance, self.center[1])]) return elems
def define_elements(self, elems): # draw tip ## Warning: end-waveguide definition is calculated using y_spacing and tip_width, only wg-width is extracted from wg_def wg_def_stop = WgElDefinition(wg_width = self.wg_def_end.wg_width, trench_width = 0.5*(self.y_spacing-self.wg_def_end.wg_width)-1.0) elems += WgElTaperLinear(start_position = (self.tip_length + self.tip_offset, 0.0), end_position = (self.tip_offset, 0.0), start_wg_def = self.wg_def_start, end_wg_def = wg_def_stop) if self.extension > 0: wg_def = WgElDefinition(wg_width = self.wg_def_end.wg_width, trench_width = 0.5*(self.y_spacing-self.wg_def_end.wg_width)-1.0, process = self.process) elems += wg_def([(self.tip_offset - self.extension , 0.0), (self.tip_offset, 0.0)]) #assist lines for tip for i in range(self.assist_lines): elems += Path(PPLayer(self.process, TECH.PURPOSE.LF.LINE), [(self.tip_length + self.tip_offset, 0.0 + (0.5*self.tip_start_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), (self.tip_offset, 0.0 + (0.5*self.tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), (self.tip_offset - self.extension, 0.0 + (0.5*self.tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), ], self.assist_width) elems += Path(PPLayer(self.process, TECH.PURPOSE.LF.LINE), [(self.tip_length + self.tip_offset, 0.0 - (0.5*self.tip_start_width+ (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), (self.tip_offset, 0.0 - (0.5*self.tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), (self.tip_offset- self.extension, 0.0 - (0.5*self.tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), ], self.assist_width) return elems
def define_elements(self, elems): # WG wg_def_stop = WgElDefinition(wg_width = self.wg_def_end.wg_width,trench_width = self.wg_def_start.trench_width) shallow_tip_width = self.wg_def_sh_end.wg_width shallow_tip_start_width = self.wg_def_sh_start.wg_width elems += WgElTaperLinear(start_position = (self.shallow_tip_length + self.tip_offset + self.tip_length, 0.0), end_position = (self.tip_offset + self.tip_length, 0.0), start_wg_def = self.wg_def_start, end_wg_def = self.wg_def_end) # FC s_o_length = self.tip_offset + self.tip_length # draw taper to tip wg_def_sh_start = WgElDefinition(wg_width = self.wg_def_sh_start.wg_width+1.0, trench_width = self.wg_def_start.trench_width) wg_def_sh_end = WgElDefinition(wg_width = self.wg_def_sh_end.wg_width, trench_width = 0.5*(self.y_spacing-self.wg_def_sh_end.wg_width)-1.0) elems += WgElTaperLinear( start_position = (self.shallow_tip_length + s_o_length, 0.0), end_position = (s_o_length, 0.0), start_wg_def = wg_def_sh_start, end_wg_def = wg_def_sh_end, process = self.shallow_process) if self.extension > 0: wg_def = WgElDefinition(wg_width = self.shallow_tip_width, trench_width = 0.5*(self.y_spacing-shallow_tip_width)-1.0, process = self.shallow_process) elems += wg_def([(s_o_length - self.extension , 0.0), (s_o_length, 0.0)]) #assist lines for tip for i in range(self.assist_lines): elems += Path(PPLayer(self.shallow_process, TECH.PURPOSE.LF.LINE), [(self.shallow_tip_length + s_o_length, (0.5*shallow_tip_start_width +0.5 + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), (s_o_length, + (0.5*shallow_tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), (s_o_length- self.extension , + (0.5*shallow_tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)) ], self.assist_width) elems += Path(PPLayer(self.shallow_process, TECH.PURPOSE.LF.LINE), [(self.shallow_tip_length + s_o_length, - (0.5*shallow_tip_start_width+0.5+ (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), (s_o_length, - (0.5*shallow_tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)), (s_o_length- self.extension , - (0.5*shallow_tip_width + (i+1)*(self.assist_width+ self.assist_spacing) - 0.5*self.assist_width)) ], self.assist_width) return elems
def define_elements(self, elems): # go over ports for i in range(len(self.struct_west_ports)): ip = self.struct_west_ports[i] # position tapers t_pos = (ip.position[0] - self.connect_length, self.__y_west__[i]) T = WgElTaperLinear(start_position=t_pos, end_position=(t_pos[0] - self.taper_length, t_pos[1]), start_wg_def=ip.wg_definition, end_wg_def=self.wg_definition) elems += T # draw straight waveguides elems += self.wg_definition( shape=[T.west_ports[0].position, (0.0, t_pos[1])]) # generic connector between structure port and taper port R = RouteToWestAtY(input_port=ip, y_position=T.east_ports[0].y, bend_radius=self.bend_radius, min_straight=self.minimum_straight, rounding_algorithm=self.rounding_algorithm) R.end_straight += R.out_ports[0].x - T.east_ports[0].x elems += RouteConnectorRounded(R) #blocking trenches elems += Line( PPLayer(self.wg_definition.process, TECH.PURPOSE.DF.TRENCH), (self.block_trench_position, 0.5 * self.wg_definition.wg_width + self.wg_definition.trench_width), (self.block_trench_position, 0.5 * self.y_spacing), self.block_trench_width) elems += Line( PPLayer(self.wg_definition.process, TECH.PURPOSE.DF.TRENCH), (self.block_trench_position, -0.5 * self.wg_definition.wg_width - self.wg_definition.trench_width), (self.block_trench_position, -0.5 * self.y_spacing), self.block_trench_width) for i in range(len(self.struct.east_ports)): op = self.struct_east_ports[i] # position tapers t_pos = (op.position[0] + self.connect_length, self.__y_east__[i]) T = WgElTaperLinear(start_position=t_pos, end_position=(t_pos[0] + self.taper_length, t_pos[1]), start_wg_def=op.wg_definition, end_wg_def=self.wg_definition) elems += T # draw straight waveguides elems += self.wg_definition( shape=[T.east_ports[0].position, (self.width, t_pos[1])]) # generic connector between structure port and taper port R = RouteToEastAtY(input_port=ip, y_position=T.west_ports[0].y, bend_radius=self.bend_radius, min_straight=self.minimum_straight, rounding_algorithm=self.rounding_algorithm) R.end_straight += -R.out_ports[0].x + T.west_ports[0].x elems += RouteConnectorRounded(R) return elems
def define_elements(self, elems): super(IoFibcoupGeneric, self).define_elements(elems) T = HMirror() # for east couplers for fc, pos, tf in self.west_fibcoups_transforms_and_positions: elems += SRef(fc, pos, tf) for fc, pos, tf in self.east_fibcoups_transforms_and_positions: elems += SRef(fc, pos, tf) #i = 0 #for ypos in self.y_west: #fc = self.west_fibcoups[i%len(self.west_fibcoups)] #west_fibcoup_position = (self.west_fibcoup_offsets[i%len(self.west_fibcoup_offsets)], ypos - fc.east_ports[0].y) #elems += SRef(fc, west_fibcoup_position) #i+= 1 #i = 0 #for ypos in self.y_east: #fc = self.east_fibcoups[i%len(self.east_fibcoups)] #east_fibcoup_position = (self.width - self.east_fibcoup_offsets[i%len(self.east_fibcoup_offsets)], ypos - fc.east_ports[0].y) #elems += SRef(fc, east_fibcoup_position, T) #i+= 1 i = 0 west_process_match = True shapes = [] wg_widths = [] trench_widths = [] radiuses = [] processes = [] # get westmost position for ports west = 100000000.0 for ip in self.struct_west_ports: west = min(west, ip.position.x) for i in range(len(self.struct_west_ports)): west_fibcoup = self.west_fibcoups[i % len(self.west_fibcoups)] west_fibcoup_port = west_fibcoup.east_ports[0] west_fibcoup_length = west_fibcoup_port.position[ 0] + self.west_fibcoup_offsets[i % len(self.west_fibcoup_offsets)] west_fibcoup_width = west_fibcoup_port.wg_definition.wg_width west_fibcoup_trench = west_fibcoup_port.wg_definition.trench_width west_connect_length = self.west_connect_lengths[i % len( self.west_connect_lengths)] west_taper_length = self.west_taper_lengths[i % len( self.west_taper_lengths)] west_trench_width = self.west_trench_widths[i % len( self.west_trench_widths)] west_fibcoup_taper_length = self.west_fibcoup_taper_lengths[ i % len(self.west_fibcoup_taper_lengths)] west_wg_width = self.west_wg_widths[i % len(self.west_wg_widths)] west_bend_radius = self.west_bend_radiuses[i % len( self.west_bend_radiuses)] west_minimum_straight = self.west_minimum_straights[i % len( self.west_minimum_straights)] west_process = west_fibcoup_port.wg_definition.process ip = self.struct_west_ports[i] if not ip.wg_definition.process == west_process: west_process_match = False # position center taper t_pos = (west - west_connect_length - TECH.WG.SHORT_STRAIGHT, self.y_west[i]) #small piece of waveguide at the end wg_def = WgElDefinition(wg_width=ip.wg_definition.wg_width, trench_width=ip.wg_definition.trench_width, process=west_process) W = wg_def([t_pos, (t_pos[0] + TECH.WG.SHORT_STRAIGHT, t_pos[1])]) elems += W # taper to the cleave waveguide start_wg_def1 = WgElDefinition( wg_width=ip.wg_definition.wg_width, trench_width=ip.wg_definition.trench_width, process=west_process) end_wg_def1 = WgElDefinition(wg_width=west_wg_width, trench_width=west_trench_width, process=west_process) T = WgElTaperLinear(start_position=t_pos, end_position=(t_pos[0] - west_taper_length, t_pos[1]), start_wg_def=start_wg_def1, end_wg_def=end_wg_def1) elems += T # draw cleave waveguide (the wider waveguide, connected to the grating coupler) wg_def = WgElDefinition(wg_width=west_wg_width, trench_width=west_trench_width, process=west_process) elems += wg_def([ T.west_ports[0].position, (west_fibcoup_length + west_fibcoup_taper_length, t_pos[1]) ]) # draw fibcoup taper (between grating coupler and the cleave waveguide) start_wg_def2 = WgElDefinition(wg_width=west_wg_width, trench_width=west_trench_width, process=west_process) end_wg_def2 = WgElDefinition(wg_width=west_fibcoup_width, trench_width=west_fibcoup_trench, process=west_process) elems += WgElTaperLinear(start_position=(west_fibcoup_length + west_fibcoup_taper_length, t_pos[1]), end_position=(west_fibcoup_length, t_pos[1]), start_wg_def=start_wg_def2, end_wg_def=end_wg_def2) # generic connector between structure port and taper port tp = W.east_ports[0] S = Shape( RouteToWestAtY(input_port=ip, y_position=tp.position.y, bend_radius=west_bend_radius, min_straight=west_minimum_straight)) if len(S) > 2: S[-2] = S[-2].translate(tp.position - S[-1]) S[-1] = tp.position shapes += [S] wg_widths += [ip.wg_definition.wg_width] trench_widths += [ip.wg_definition.trench_width] radiuses += [west_bend_radius] processes += [west_process] #blocking trenches elems += Line( PPLayer(west_process, TECH.PURPOSE.LF_AREA), (self.block_trench_position, t_pos[1] + 0.5 * west_wg_width + west_trench_width), (self.block_trench_position, t_pos[1] + 0.5 * self.y_spacing), self.block_trench_width) elems += Line( PPLayer(west_process, TECH.PURPOSE.LF_AREA), (self.block_trench_position, t_pos[1] - 0.5 * west_wg_width - west_trench_width), (self.block_trench_position, t_pos[1] - 0.5 * self.y_spacing), self.block_trench_width) if len(self.struct_west_ports): if self.west_merged_waveguides: # TO DO: Sort this out for different processes elems += WgElBundleConnectRoundedGeneric( shapes=shapes, wg_widths=wg_widths, trench_widths=trench_widths, bend_radii=radiuses, process=west_process) else: for (s, w, t, r, p) in zip(shapes, wg_widths, trench_widths, radiuses, processes): wg_def = WgElDefinition(wg_width=w, trench_width=t, process=p) connector_wg_def = WaveguidePointRoundedConnectElementDefinition( wg_definition=wg_def, bend_radius=r, manhattan=False) elems += connector_wg_def(shape=s) shapes = [] wg_widths = [] trench_widths = [] radiuses = [] processes = [] east_process_match = True # get rigthmost position for ports east = -100000000.0 for op in self.struct_east_ports: east = max(east, op.position.x) for i in range(len(self.struct_east_ports)): east_fibcoup = self.east_fibcoups[i % len(self.east_fibcoups)] east_fibcoup_port = east_fibcoup.east_ports[0] east_fibcoup_length = east_fibcoup_port.position[ 0] + self.east_fibcoup_offsets[i % len(self.east_fibcoup_offsets)] east_fibcoup_width = east_fibcoup_port.wg_definition.wg_width east_fibcoup_trench = east_fibcoup_port.wg_definition.trench_width east_connect_length = self.east_connect_lengths[i % len( self.east_connect_lengths)] east_taper_length = self.east_taper_lengths[i % len( self.east_taper_lengths)] east_trench_width = self.east_trench_widths[i % len( self.east_trench_widths)] east_fibcoup_taper_length = self.east_fibcoup_taper_lengths[ i % len(self.east_fibcoup_taper_lengths)] east_wg_width = self.east_wg_widths[i % len(self.east_wg_widths)] east_bend_radius = self.east_bend_radiuses[i % len( self.east_bend_radiuses)] east_minimum_straight = self.east_minimum_straights[i % len( self.east_minimum_straights)] east_process = east_fibcoup_port.wg_definition.process op = self.struct_east_ports[i] if not op.wg_definition.process == east_process: east_process_match = False # position taper t_pos = (east + east_connect_length + TECH.WG.SHORT_STRAIGHT, self.y_east[i]) wg_def = WgElDefinition(wg_width=op.wg_definition.wg_width, trench_width=op.wg_definition.trench_width, process=east_process) W = wg_def([t_pos, (t_pos[0] - TECH.WG.SHORT_STRAIGHT, t_pos[1])]) elems += W start_wg_def3 = WgElDefinition( wg_width=op.wg_definition.wg_width, trench_width=op.wg_definition.trench_width, process=east_process) end_wg_def3 = WgElDefinition(wg_width=east_wg_width, trench_width=east_trench_width, process=east_process) T = WgElTaperLinear(start_position=t_pos, end_position=(t_pos[0] + east_taper_length, t_pos[1]), start_wg_def=start_wg_def3, end_wg_def=end_wg_def3) elems += T # draw cleave waveguides wg_def = WgElDefinition(wg_width=east_wg_width, trench_width=east_trench_width, process=east_process) elems += wg_def([ T.east_ports[0].position, (self.width - east_fibcoup_length - east_fibcoup_taper_length, t_pos[1]) ]) # draw fibcoup taper start_wg_def4 = WgElDefinition(wg_width=east_wg_width, trench_width=east_trench_width, process=east_process) end_wg_def4 = WgElDefinition(wg_width=east_fibcoup_width, trench_width=east_fibcoup_trench, process=east_process) elems += WgElTaperLinear( start_position=(self.width - east_fibcoup_length - east_fibcoup_taper_length, t_pos[1]), end_position=(self.width - east_fibcoup_length, t_pos[1]), start_wg_def=start_wg_def4, end_wg_def=end_wg_def4) # generic connector between structure port and taper port tp = W.west_ports[0] S = Shape( RouteToEastAtY(input_port=op, y_position=tp.position.y, bend_radius=east_bend_radius, min_straight=east_minimum_straight)) if len(S) > 2: S[-2] = S[-2].translate(tp.position - S[-1]) S[-1] = tp.position shapes += [S] wg_widths += [op.wg_definition.wg_width] trench_widths += [op.wg_definition.trench_width] radiuses += [east_bend_radius] processes += [east_process] if len(self.struct_east_ports): if self.east_merged_waveguides: # TODO: Correct the bundling to support multiple process layers elems += WgElBundleConnectRoundedGeneric( shapes=shapes, wg_widths=wg_widths, trench_widths=trench_widths, bend_radii=radiuses, process=processes[0]) else: for (s, w, t, r, p) in zip(shapes, wg_widths, trench_widths, radiuses, processes): wg_def = WgElDefinition(wg_width=w, trench_width=t, process=p) connector_wg_def = WaveguidePointRoundedConnectElementDefinition( wg_definition=wg_def, bend_radius=r, manhattan=False) elems += connector_wg_def(shape=s) if not (west_process_match and east_process_match): if not (west_process_match or east_process_match): lr = "west and east" elif not west_process_match: lr = "west" else: lr = "east" LOG.warning( "Some of the %s ports of structure %s are not on the same process layer as the %s fiber couplers" % (lr, self.struct.name, lr)) return elems