def ShallowMmiTaperedBasic(width, length, input_y_positions, output_y_positions, input_taper_widths , output_taper_widths, taper_length, wg_definition = TECH.WGDEF.FC_WIRE, **kwargs): """ a shallow-etch rectangular MMI with tapers """ mmi_wg_definition = WgElDefinition(wg_width = width, process = wg_definition.process, trench_width = wg_definition.trench_width) input_taper_definitions = [] for i in range(len(input_taper_widths)): input_taper_definitions += [WgElDefinition(wg_width = input_taper_widths[i], process = wg_definition.process, trench_width = wg_definition.trench_width)] output_taper_definitions = [] for i in range(len(output_taper_widths)): output_taper_definitions += [WgElDefinition(wg_width = output_taper_widths[i], process = wg_definition.process, trench_width = wg_definition.trench_width)] from picazzo.filters.mmi.layout import MmiBasic M = MmiBasic(mmi_wg_definition = mmi_wg_definition, length = length, input_y_positions = input_y_positions, output_y_positions = output_y_positions, input_wg_definitions = input_taper_definitions, output_wg_definitions = output_taper_definitions, **kwargs) return ShallowMmiTaperPorts(structure = M, taper_length = taper_length, end_wg_def = wg_definition)
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): from picazzo.filters.ring import RingRect180DropFilter from ipkiss.plugins.photonics.wg.basic import WgElDefinition huge_ring = RingRect180DropFilter( ring_wg_definition=WgElDefinition(wg_width=0.5), coupler_wg_definitions=[ WgElDefinition(wg_width=0.4), WgElDefinition(wg_width=0.6) ], coupler_spacings=[5.0, 5.0], straights=(60.0, 120.0), bend_radius=110.0) from picazzo.io.fibcoup import IoFibcoup from picazzo.fibcoup.uniform import UniformLineGrating grating = UniformLineGrating( origin=(0.0, 0.0), period=0.689, line_width=0.423, n_o_periods=20, wg_definition=WgElDefinition(wg_width=9.0), process=TECH.PROCESS.FC) ring_with_fibcoup = IoFibcoup(struct=huge_ring, offset=(0.0, 0.0), y_spacing=huge_ring.size_info().height, south_west=(0.0, 0.0), south_east=(1500.0, 0.0), fibcoup=grating) elems += SRef(reference=ring_with_fibcoup) 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
class InvertedTaperShallow(InvertedTaper): process = DefinitionProperty(fdef_name = "define_process") wg_def_sh_start = WaveguideDefProperty(default = WgElDefinition(wg_width = 1.0 ,trench_width = TECH.WG.TRENCH_WIDTH)) wg_def_sh_end = WaveguideDefProperty(default = WgElDefinition(wg_width = 0.080 ,trench_width = TECH.WG.TRENCH_WIDTH)) deep_process = ProcessProperty(default = TECH.PROCESS.WG) shallow_process = ProcessProperty(default = TECH.PROCESS.FC) shallow_tip_width = PositiveNumberProperty(default = 0.080) shallow_tip_start_width = PositiveNumberProperty(default = 1.0) shallow_tip_length = PositiveNumberProperty(default = 150.0) def define_process(self): return self.deep_process 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_ports(self, ports): wg_def = WgElDefinition(wg_width = self.shallow_tip_start_width, trench_width = self.wg_def_start.trench_width, process = self.deep_process) ports += [OpticalPort(position = (self.tip_length + self.tip_offset+ self.shallow_tip_length , 0.0), angle = 0.0, wg_definition = wg_def)] return ports
class InvertedTaper(FiberCoupler): process = ProcessProperty(default = TECH.PROCESS.WG) wg_def_start = WaveguideDefProperty(default = WgElDefinition(wg_width = TECH.WG.WIRE_WIDTH,trench_width = TECH.WG.TRENCH_WIDTH)) wg_def_end = WaveguideDefProperty(default = WgElDefinition(wg_width = 0.080 ,trench_width = 11.46)) tip_length = PositiveNumberProperty(default = 250.0) tip_offset = NonNegativeNumberProperty(default = 300.0) nitride_clearance = NonNegativeNumberProperty(default = 50.0) nitride_width = PositiveNumberProperty(default = 3.0) y_spacing = PositiveNumberProperty(default = 25.0) assist_lines = IntProperty(restriction = RESTRICT_NONNEGATIVE, default = 0) assist_spacing = PositiveNumberProperty(default = 0.160) assist_width = PositiveNumberProperty(default = 0.080) extension = NonNegativeNumberProperty(default = 1.0) 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_ports(self, prts): wg_def = WgElDefinition(wg_width = self.wg_def_start.wg_width, trench_width = self.wg_def_start.trench_width, process = self.process) prts += [OpticalPort(position = (self.tip_length + self.tip_offset, 0.0), angle = 0.0, wg_definition = wg_def)] return prts
def define_arm1(self): arm_name = self.name + "_arm1" from ipkiss.plugins.photonics.wg.basic import WgElDefinition wg_def = WgElDefinition() wg = wg_def(shape=[(0.0, 0.0), (self.arm_length, 0.0)]) wg_struct = Structure(name=arm_name, elements=[wg], ports=wg.ports) return wg_struct
def define_taper(self): start_wg_def = self.start_port.wg_definition.get_wg_definition_cross_section( ) end_wg_def = self.end_wg_def.get_wg_definition_cross_section() if start_wg_def.trench_width == 0.0: new_start_wg_def = WgElDefinition( wg_width=start_wg_def.shallow_wg_width, trench_width=start_wg_def.shallow_trench_width, process=start_wg_def.shallow_process) new_start_port = OpticalPort( position=self.start_port.position, wg_definition=new_start_wg_def, angle=self.start_port.angle) taper = WgElPortTaperFromShallow( start_port=new_start_port, end_wg_def=end_wg_def, length=self.length, straight_extension=self.straight_extension, shallow_process=start_wg_def.shallow_process) else: new_end_wg_def = WGFCWgElDefinition( trench_width=end_wg_def.trench_width, shallow_wg_width=end_wg_def.wg_width, shallow_trench_width=start_wg_def.shallow_trench_width, wg_width=end_wg_def.wg_width, shallow_process=start_wg_def.shallow_process) taper = WgElPortTaperLinear( start_port=self.start_port, end_wg_def=new_end_wg_def, length=self.length, straight_extension=self.straight_extension) return taper
def STANDARD_GRATING_1550_TM(process=TECH.PROCESS.FC): wg_def = WgElDefinition(wg_width=std_lin_grating_wg_width) return _ULG(name="std_grating_TM_1550", origin=(0.0, 0.0), period=std1550tm_grating_period, line_width=std1550tm_grating_trench, n_o_periods=std1550tm_grating_n_o_periods, wg_definition=wg_def, process=process)
def define_structure(self): twg = WgElDefinition(wg_width = self.taper_width, process = self.shallow_wg_definition.process, trench_width = self.shallow_wg_definition.trench_width) return ShallowMmi(width = self.width, length = self.length, input_y_positions = self.input_y_positions, output_y_positions = self.output_y_positions, wg_definition = twg)
def define_waveguides(self): waveguides = [] for (S,w,t, r) in zip(self.shapes, self.wg_widths, self.trench_widths, self.bend_radii): wg_def = WgElDefinition(wg_width = w, trench_width = t, process = self.process) connector_wg_def = WaveguidePointRoundedConnectElementDefinition(wg_definition = wg_def, bend_radius = r, manhattan = self.manhattan, rounding_algorithm = self.rounding_algorithm) waveguides.append(connector_wg_def(shape = S)) return waveguides
def define_ports(self, prts): wg_def = WgElDefinition(wg_width=self.wg_def_start.wg_width, trench_width=self.wg_def_start.trench_width, process=self.process) prts += [ OpticalPort(position=(self.tip_length + self.tip_offset, 0.0), angle=0.0, wg_definition=wg_def) ] return prts
def define_ports_coordinates(self): from ipkiss.plugins.photonics.wg.basic import WgElDefinition wg_def = WgElDefinition(wg_width=sqrt(3.0) * self.pitch, trench_width=TECH.WG.TRENCH_WIDTH, process=TECH.PROCESS.WG) port_row = 0.0 port_col = (0.5 * cos(pi / 12.0) * self.diameter + TECH.TECH.MINIMUM_LINE) / self.pitch return [((-port_col, port_row), -180, wg_def), ((port_col + self.n_o_periods - 1, port_row), 0.0, wg_def)]
def initialize(self): from ipkiss.plugins.photonics.wg.basic import WgElDefinition, Wg2ElDefinition self.WIRE = WgElDefinition(wg_width = TECH.FC.WIRE_WIDTH, trench_width = TECH.FC.TRENCH_WIDTH, process = TECH.PROCESS.FC) self.FC_WIRE2 = Wg2ElDefinition(wg_width = TECH.FC.WIRE_WIDTH, trench_width = TECH.FC.TRENCH_WIDTH, process = TECH.PROCESS.FC) self.DEFAULT = self.WIRE
def define_ports_coordinates(self): from ipkiss.plugins.photonics.wg.basic import WgElDefinition wg_def = WgElDefinition(wg_width=sqrt(3.0) * self.lattice_pitches[1] if self.port_width is None else self.port_width, trench_width=TECH.WG.TRENCH_WIDTH, process=TECH.PROCESS.WG) port_row = (len(self.unit_cells) - 1) / 2 if self.port_row is None else self.port_row port_col = self.port_offset / self.pitches[0] return [((-port_col, -port_row), -180, wg_def), ((port_col + self.n_o_periods - 1, -port_row), 0.0, wg_def)]
def initialize(self): from ipkiss.plugins.photonics.wg.basic import WgElDefinition, Wg2ElDefinition self.WIRE = WgElDefinition(wg_width=TECH.WG.WIRE_WIDTH, trench_width=TECH.WG.TRENCH_WIDTH, process=TECH.PROCESS.WG) self.WIRE2 = Wg2ElDefinition(wg_width=TECH.WG.WIRE_WIDTH, trench_width=TECH.WG.TRENCH_WIDTH, process=TECH.PROCESS.WG) self.DEFAULT = self.WIRE # FIXME -- old stuff to be removed !!! DEPRECATED----- self.WG_WIRE = self.WIRE self.WG_WIRE2 = self.WIRE2 self.FC_WIRE = WgElDefinition(wg_width=TECH.FC.WIRE_WIDTH, trench_width=TECH.FC.TRENCH_WIDTH, process=TECH.PROCESS.FC) self.FC_WIRE2 = Wg2ElDefinition(wg_width=TECH.FC.WIRE_WIDTH, trench_width=TECH.FC.TRENCH_WIDTH, process=TECH.PROCESS.FC)
def MmiTaperedBasic(width, length, input_y_positions, output_y_positions, input_taper_widths, output_taper_widths, taper_length, wg_definition=TECH.WGDEF.WIRE, **kwargs): """ a deep-etch rectangular MMI with tapers """ mmi_wg_definition = WgElDefinition(wg_width=width, process=wg_definition.process, trench_width=wg_definition.trench_width) input_taper_definitions = [] for i in range(len(input_taper_widths)): input_taper_definitions += [ WgElDefinition(wg_width=input_taper_widths[i], process=wg_definition.process, trench_width=wg_definition.trench_width) ] output_taper_definitions = [] for i in range(len(output_taper_widths)): output_taper_definitions += [ WgElDefinition(wg_width=output_taper_widths[i], process=wg_definition.process, trench_width=wg_definition.trench_width) ] M = MmiBasic(mmi_wg_definition=mmi_wg_definition, length=length, input_y_positions=input_y_positions, output_y_positions=output_y_positions, input_wg_definitions=input_taper_definitions, output_wg_definitions=output_taper_definitions, **kwargs) return TaperDeepPorts(structure=M, taper_length=taper_length, end_wg_def=wg_definition)
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 STANDARD_GRATING_1550_TM(): from picazzo.fibcoup.uniform import UniformLineGrating as _ULG from ipkiss.plugins.photonics.wg.basic import WgElDefinition std1550_grating_trench = 0.540 std1550_grating_period = 1.080 std1550_grating_n_o_periods = 16 std_lin_grating_wg_def = WgElDefinition(wg_width=10.0) G = _ULG(name="std_grating_1550_tm", origin=(0.0, 0.0), period=std1550_grating_period, line_width=std1550_grating_trench, n_o_periods=std1550_grating_n_o_periods, wg_definition=std_lin_grating_wg_def, process=TECH.PROCESS.FC) return G
def STANDARD_2DGRATING_1550_TE(): from picazzo.fibcoup.uniform_2d import SymmetricUniformRect2dGrating as _UG2D from ipkiss.plugins.photonics.wg.basic import WgElDefinition std1550_2dgrating_period = 0.605 std1550_2dgrating_hole_diameter = 0.390 # desired after litho: 370 std1550_2dgrating_n_o_periods = 19 std1550_2dgrating_wg_def = WgElDefinition(wg_width=12.0) std1550_2dgrating_wg_length = 11 # length of trench before the taper starts std1550_2dgrating_trench_overlap = 4 # length of overlap between taper and fiber coupler trench std1550_2dgrating_dev_angle = 3.1 # angle deviation w/respect to 90 degrees. G = _UG2D(name="std_2dgrating_1550", period=std1550_2dgrating_period, hole_diameter=std1550_2dgrating_hole_diameter, n_o_periods=std1550_2dgrating_n_o_periods, wg_definition=std1550_2dgrating_wg_def, wg_length=std1550_2dgrating_wg_length, dev_angle=std1550_2dgrating_dev_angle, process=TECH.PROCESS.WG) return G
def define_tapers(self): tapers = [] for P in self.__get_labeled_ports__(): if self.deep_only_width is None: deep_only_width = max(TECH.WG.SPACING, self.end_wg_def.wg_width, P.wg_definition.wg_width) else: deep_only_width = self.deep_only_width deep_only_wg = WgElDefinition( wg_width=deep_only_width, trench_width=P.wg_definition.trench_width, process=self.deep_process) tapers.append( WgElPortTaperFromShallow( start_port=P, end_wg_def=self.end_wg_def, length=self.taper_length, deep_process=self.deep_process, shallow_process=self.shallow_process, straight_extension=self.straight_extension, deep_only_wg_def=deep_only_wg)) return tapers
def define_deep_only_wg_def(self): return WgElDefinition(wg_width=1.5)
class IoCleave(__RoundedShape__, IoBlockAdapter): __name_prefix__ = "IoCleave" taper_length = PositiveNumberProperty(default=300.0) wg_definition = WaveguideDefProperty(default=WgElDefinition(wg_width=3.0)) connect_length = PositiveNumberProperty(default=40.0) min_straight = NonNegativeNumberProperty(default=TECH.WG.SHORT_STRAIGHT) block_trench_position = PositiveNumberProperty(default=650.0) block_trench_width = PositiveNumberProperty(default=5.0) 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_ports(self, ports): # should reflect number of in and outputs in center structure ports += [ OpticalPort(position=(0.0, ypos), wg_definition=self.wg_definition, angle=180.0) for ypos in self.__y_west__ ] ports += [ OpticalPort(position=(self.width, ypos), wg_definition=self.wg_definition, angle=180.0) for ypos in self.__y_east__ ] return ports
def __make_wg_element__(shape, wg_width, trench_width, process): wg_def = WgElDefinition(wg_width = wg_width , trench_width = trench_width, process = process) return wg_def(shape = shape)
def define_deep_only_wg_def(self): return WgElDefinition( wg_width=self.start_wg_def.wg_width + self.start_wg_def.trench_width * 2, trench_width=self.end_wg_def.trench_width)
def define_mmi_wg_definition(self): return WgElDefinition(wg_width=self.width, process=self.wg_definition.process, trench_width=self.wg_definition.trench_width)
elems = GratingCavityFilter.define_elements(self, elems) elems += self.bend_down_l elems += self.bend_down_r elems += self.bend_up_l elems += self.bend_up_r return elems def define_ports(self, ports): p1 = self.bend_down_l.west_ports[0] p2 = self.bend_up_l.west_ports[0] p3 = self.bend_down_r.east_ports[0] p4 = self.bend_up_r.east_ports[0] ports = [p1, p2, p3, p4] return ports if __name__ == '__main__': grating_unit_cell = WgGratingPeriodShallow( length=0.29, wg_definition=WgElDefinition(wg_width=0.45), shallow_process=TECH.PROCESS.FC) cavity1 = GratingCavity(wg_definition=WgElDefinition(wg_width=0.45), period=0.29, cavity_length=0.0, number_of_periods_left=10, number_of_periods_right=10, period_component=grating_unit_cell) from picazzo.aspects.visualization import * cavity1.visualize_2d()
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
def define_port(self): return OpticalPort(position=self.position, angle=self.angle, wg_definition=WgElDefinition(wg_width=self.width / 2.0, trench_width=0.0))
# i-depot BBIE 7396, 7556, 7748 # # Contact: [email protected] from technologies.si_photonics.picazzo.default import * from ipkiss.plugins.vfabrication import * from picazzo.filters.ring import RingRectSBend180DropFilter ring = RingRectSBend180DropFilter(straights=(TECH.WG.SHORT_STRAIGHT, TECH.WG.SHORT_STRAIGHT + 3.0), coupler_angles=[30.0, 10.0], coupler_spacings=[1.0, 0.8], coupler_lengths=[6.0, 2.0], coupler_radii=[3.0, 7.0]) ring.visualize_2d() ring.write_gdsii("ring.gds") from picazzo.fibcoup.line_grating import FiberCouplerGratingLine from ipkiss.plugins.photonics.wg.basic import WgElDefinition from picazzo.fibcoup.socket import BroadWgSocket wg_def = WgElDefinition(wg_width=5.0) socket = BroadWgSocket(wg_definition=wg_def, wg_length=15.0) C = FiberCouplerGratingLine(line_widths_positions=[(1.0, 1.0), (3.0, 3.0), (4.0, 7.0)], line_length=7.0, socket=socket) C.visualize_2d()