def produce(self, layout, layers, parameters, cell): # coerce parameters (make consistent) self._layers = layers self.cell = cell self._param_values = parameters self.layout = layout # cell: layout cell to place the layout # LayerSiN: which layer to use # r: radius # w: waveguide width # length units in dbu from math import pi, cos, sin from SiEPIC.utils import arc_wg, arc_wg_xy from SiEPIC._globals import PIN_LENGTH from SiEPIC.utils.layout import layout_waveguide2 from SiEPIC.extend import to_itype # fetch the parameters TECHNOLOGY = get_technology_by_name('EBeam') dbu = self.layout.dbu ly = self.layout LayerSiN = ly.layer(self.silayer) LayerSlab = ly.layer(self.slayer) # LayerNN = ly.layer(self.nlayer) LayerNPPN = ly.layer(self.npplayer) LayerVCN = ly.layer(self.vclayer) LayerMN = ly.layer(self.mlayer) LayerPinRecN = ly.layer(self.pinrec) LayerDevRecN = ly.layer(self.devrec) TextLayerN = ly.layer(self.textl) ## define parameters for phase shifter overlay = to_itype(self.overlay, dbu) overlay_ebl = to_itype(self.overlay_ebl, dbu) ## define waveguide related parameters radius_um, adiab, bezier = 5, 1, 0.2 w = to_itype(self.width, dbu) #waveguide width, default 0.5 um l = to_itype(self.length, dbu) #pahse shifter length, default 150 um npp_d = to_itype(self.npp_distance, dbu) #npp to center waveguide distance sw = (npp_d + w / 2) * 2 #twice of npp_d that is defined above in_rib = to_itype( self.input_rib_width, dbu ) #the slab width of the input/output waveguide to the phase shifter in_taper = to_itype( self.in_taper_length, dbu ) #the input waveguide to phase shifter dimension transfer taper length, default 15 edge_slab_width = to_itype( 4, dbu ) #width of the 90 nm slab that is outside of all the folding waveguide, default 2 * 2um npp_width = to_itype(self.npp_width, dbu) #npp width, default 5 um ## define waveguide folding parameters folding_n = int(round((self.fold_number - 1) / 2)) # folding waveguide number on one side folding_w1 = w + 50 # one of the folding waveguide width folding_w2 = w - 50 # the other one of the folding waveguide width folding_gap = to_itype(2, dbu) # the gap between two folding waveguide routing_step = to_itype( radius_um, dbu) # define how large the U shape should be, default 20 ## define node related parameters contact_size = to_itype(self.vc_w, dbu) # square NPP size, for VC purpose pin_text_size = to_itype(0.4, dbu) # pin text size metal_routing_distance_to_node = to_itype( 30, dbu) # *** calculate from PCell parameters *** metal_routing_width = to_itype(self.m_w, dbu) # width of metal vc_to_npp_exclusion = to_itype( self.overlay, dbu) # VC boundary to NPP boundary distance ps_sl_w = sw + 2 * contact_size + folding_n * 2 * ( w + folding_gap + overlay_ebl ) # overall pahse shifter 90nm slab width # measure the total length of the waveguides total_waveguide_length = 0 ## define strip to slab transfer taper parameters N = 100 # Number of points for the input/output slab taper order = 3 # input/output slab taper curve pts = [Point(-l / 2, 0), Point(l / 2, 0)] total_waveguide_length += layout_waveguide2(TECHNOLOGY, self.layout, self.cell, ['Si'], [w * dbu], [0], pts, radius_um, adiab, bezier) wg2 = pya.Box(-l / 2, -ps_sl_w / 2, l / 2, ps_sl_w / 2) wg3 = pya.Box(-l / 2, npp_d + w / 2, l / 2, npp_d + w / 2 + npp_width) wg4 = pya.Box(-l / 2, -npp_d - w / 2, l / 2, -npp_d - w / 2 - npp_width) self.cell.shapes(LayerNPPN).insert(wg3) self.cell.shapes(LayerNPPN).insert(wg4) if self.io_wg_type: in_slab = to_itype(self.input_slab_width, dbu) else: in_slab = in_rib if folding_n > 0: ps_sl_w = contact_size * 2 + sw * 2 + ( folding_w1 + folding_w2 + folding_gap * 2) * folding_n + edge_slab_width wg2 = pya.Box(-l / 2, -ps_sl_w / 2, l / 2, ps_sl_w / 2) self.cell.shapes(LayerSlab).insert(wg2) pts = [ Point(-l / 2 - in_taper, -w / 2), Point(-l / 2, -w / 2), Point(-l / 2, w / 2), Point(-l / 2 - in_taper, w / 2) ] # fix waveguide width mismatch for left center input taper self.cell.shapes(LayerSiN).insert(Polygon(pts)) # add input slab taper pts = [] for i in range(0, N + 1): pts.append( Point( -l / 2 - in_taper + in_taper / N * i, w / 2 + ((sw / 2 + contact_size - w) / (N**order)) * (i**order))) for i in range(0, N + 1): pts.append( Point( -l / 2 - in_taper + in_taper / N * (N - i), -w / 2 - ((sw / 2 + contact_size - w) / (N**order)) * ((N - i)**order))) self.cell.shapes(LayerSlab).insert(Polygon(pts)) # add output strip taper pts = [ Point(l / 2 + in_taper, -w / 2), Point(l / 2, -w / 2), Point(l / 2, w / 2), Point(l / 2 + in_taper, w / 2) ] #wg2 = pya.Box(-l/2,-4/2/dbu,l/2,4/2/dbu) self.cell.shapes(LayerSiN).insert(Polygon(pts)) total_waveguide_length += in_taper * dbu # add input slab taper pts = [] for i in range(0, N + 1): pts.append( Point(l / 2 + in_taper - in_taper / N * i, (w - overlay_ebl) / 2 + ((sw / 2 + contact_size - (w - overlay_ebl)) / (N**order)) * (i**order))) for i in range(0, N + 1): pts.append( Point( l / 2 + in_taper / N * i, -(w - overlay_ebl) / 2 - ((sw / 2 + contact_size - (w - overlay_ebl)) / (N**order)) * ((N - i)**order))) self.cell.shapes(LayerSlab).insert(Polygon(pts)) for i in range(0, folding_n): y_coordinate = contact_size + sw + 2 * vc_to_npp_exclusion # move up/down the position according to vc_to_npp_exclusion y_move = i * (folding_w1 + folding_w2 + folding_gap * 2) / 2 + y_coordinate if i % 2: folding_w = folding_w2 else: folding_w = folding_w1 # waveguide in the heated region pts = [Point(-l / 2, y_move), Point(l / 2, y_move)] total_waveguide_length += layout_waveguide2( TECHNOLOGY, self.layout, self.cell, ['Si'], [folding_w * dbu], [0], pts, radius_um, adiab, bezier) pts = [Point(-l / 2, -y_move), Point(l / 2, -y_move)] total_waveguide_length += layout_waveguide2( TECHNOLOGY, self.layout, self.cell, ['Si'], [folding_w * dbu], [0], pts, radius_um, adiab, bezier) # add upper left input taper pts = [ Point(-l / 2 - in_taper, -w / 2 + y_move), Point(-l / 2, -folding_w / 2 + y_move), Point(-l / 2, folding_w / 2 + y_move), Point(-l / 2 - in_taper, w / 2 + y_move) ] #wg2 = pya.Box(-l/2,-4/2/dbu,l/2,4/2/dbu) self.cell.shapes(LayerSiN).insert(Polygon(pts)) total_waveguide_length += in_taper * dbu # slab cubic taper pts = [] for ii in range(0, N + 1): pts.append( Point(-l / 2 - in_taper + in_taper / N * ii, (w - overlay_ebl) / 2 + ((2 / dbu - (w - overlay_ebl)) / (N**order)) * (ii**order) + y_move)) for ii in range(0, N + 1): pts.append( Point( -l / 2 - in_taper + in_taper / N * (N - ii), -(w - overlay_ebl) / 2 - ((2 / dbu - (w - overlay_ebl)) / (N**order)) * ((N - ii)**order) + y_move)) self.cell.shapes(LayerSlab).insert(Polygon(pts)) if (i != folding_n - 1): # add below left taper y_move = -y_move pts = [ Point(-l / 2 - in_taper, -w / 2 + y_move), Point(-l / 2, -folding_w / 2 + y_move), Point(-l / 2, folding_w / 2 + y_move), Point(-l / 2 - in_taper, w / 2 + y_move) ] #wg2 = pya.Box(-l/2,-4/2/dbu,l/2,4/2/dbu) self.cell.shapes(LayerSiN).insert(Polygon(pts)) total_waveguide_length += in_taper * dbu # slab cubic taper pts = [] for ii in range(0, N + 1): pts.append( Point(-l / 2 - in_taper + in_taper / N * ii, (w - overlay_ebl) / 2 + ((2 / dbu - (w - overlay_ebl)) / (N**order)) * (ii**order) + y_move)) for ii in range(0, N + 1): pts.append( Point( -l / 2 - in_taper + in_taper / N * (N - ii), -(w - overlay_ebl) / 2 - ((2 / dbu - (w - overlay_ebl)) / (N**order)) * ((N - ii)**order) + y_move)) self.cell.shapes(LayerSlab).insert(Polygon(pts)) # add upper right taper y_move = -y_move pts = [ Point(l / 2 + in_taper, -w / 2 + y_move), Point(l / 2, -folding_w / 2 + y_move), Point(l / 2, folding_w / 2 + y_move), Point(l / 2 + in_taper, w / 2 + y_move) ] #wg2 = pya.Box(-l/2,-4/2/dbu,l/2,4/2/dbu) self.cell.shapes(LayerSiN).insert(Polygon(pts)) total_waveguide_length += in_taper * dbu # slab cubic taper pts = [] for ii in range(0, N + 1): pts.append( Point(l / 2 + in_taper - in_taper / N * ii, (w - overlay_ebl) / 2 + ((2 / dbu - (w - overlay_ebl)) / (N**order)) * (ii**order) + y_move)) for ii in range(0, N + 1): pts.append( Point( l / 2 + in_taper / N * ii, -(w - overlay_ebl) / 2 - ((2 / dbu - (w - overlay_ebl)) / (N**order)) * ((N - ii)**order) + y_move)) self.cell.shapes(LayerSlab).insert(Polygon(pts)) else: y_move = -y_move # add input strip taper pts = [ Point(-l / 2 - in_taper, -w / 2 + y_move), Point(-l / 2, -folding_w / 2 + y_move), Point(-l / 2, folding_w / 2 + y_move), Point(-l / 2 - in_taper, w / 2 + y_move) ] #wg2 = pya.Box(-l/2,-4/2/dbu,l/2,4/2/dbu) self.cell.shapes(LayerSiN).insert(Polygon(pts)) total_waveguide_length += in_taper * dbu # add input slab taper pts = [] for i in range(0, N + 1): pts.append( Point( -l / 2 - in_taper + in_taper / N * i, in_slab / 2 + ((edge_slab_width - in_slab) / (N**order)) * (i**order) + y_move)) for i in range(0, N + 1): pts.append( Point( -l / 2 - in_taper + in_taper / N * (N - i), -in_slab / 2 - ((edge_slab_width - in_slab) / (N**order)) * ((N - i)**order) + y_move)) self.cell.shapes(LayerSlab).insert(Polygon(pts)) # add output strip taper y_move = -y_move pts = [ Point(l / 2 + in_taper, -w / 2 + y_move), Point(l / 2, -folding_w / 2 + y_move), Point(l / 2, folding_w / 2 + y_move), Point(l / 2 + in_taper, w / 2 + y_move) ] #wg2 = pya.Box(-l/2,-4/2/dbu,l/2,4/2/dbu) self.cell.shapes(LayerSiN).insert(Polygon(pts)) total_waveguide_length += in_taper * dbu # add input slab taper pts = [] for i in range(0, N + 1): pts.append( Point( l / 2 + in_taper - in_taper / N * i, in_slab / 2 + ((edge_slab_width - in_slab) / (N**order)) * (i**order) + y_move)) for i in range(0, N + 1): pts.append( Point( l / 2 + in_taper / N * i, -in_slab / 2 - ((edge_slab_width - in_slab) / (N**order)) * ((N - i)**order) + y_move)) self.cell.shapes(LayerSlab).insert(Polygon(pts)) # Pin on the left side: wg_start = -(l / 2 + in_taper + routing_step * folding_n * 3 + w) p1 = [ Point(wg_start + PIN_LENGTH / 2, -y_move), Point(wg_start - PIN_LENGTH / 2, -y_move) ] p1c = Point(wg_start, -y_move) self.set_p1 = p1c self.p1 = p1c pin = Path(p1, w) self.cell.shapes(LayerPinRecN).insert(pin) t = Trans(Trans.R0, wg_start, -y_move) text = Text("pin1", t) shape = self.cell.shapes(LayerPinRecN).insert(text) shape.text_size = pin_text_size # Waveguide to route to port, new in SiEPIC-Tools v0.3.64 pts = [ Point(-l / 2 - in_taper, -y_move), Point(wg_start, -y_move) ] if self.io_wg_type: waveguide_length = layout_waveguide2( TECHNOLOGY, self.layout, self.cell, ['Si', 'Si - 90 nm rib'], [w * dbu, in_slab * dbu], [0, 0], pts, radius_um, adiab, bezier) else: waveguide_length = layout_waveguide2( TECHNOLOGY, self.layout, self.cell, ['Si'], [w * dbu], [0], pts, radius_um, adiab, bezier) # Pin & Waveguide on the right side: wg_end = l / 2 + in_taper + routing_step * folding_n * 3 + w p2 = [ Point(wg_end - PIN_LENGTH / 2, y_move), Point(wg_end + PIN_LENGTH / 2, y_move) ] p2c = Point(wg_end, y_move) self.set_p2 = p2c self.p2 = p2c pin = Path(p2, w) self.cell.shapes(LayerPinRecN).insert(pin) t = Trans(Trans.R0, wg_end, y_move) text = Text("pin2", t) shape = self.cell.shapes(LayerPinRecN).insert(text) shape.text_size = pin_text_size # Waveguide to route to port, new in SiEPIC-Tools v0.3.64 pts = [ Point(l / 2 + in_taper, y_move), Point(wg_end, y_move) ] if self.io_wg_type: total_waveguide_length += layout_waveguide2( TECHNOLOGY, self.layout, self.cell, ['Si', 'Si - 90 nm rib'], [w * dbu, in_slab * dbu], [0, 0], pts, radius_um, adiab, bezier) else: total_waveguide_length += layout_waveguide2( TECHNOLOGY, self.layout, self.cell, ['Si'], [w * dbu], [0], pts, radius_um, adiab, bezier) # add below right taper y_move = -y_move pts = [ Point(l / 2 + in_taper, -w / 2 + y_move), Point(l / 2, -folding_w / 2 + y_move), Point(l / 2, folding_w / 2 + y_move), Point(l / 2 + in_taper, w / 2 + y_move) ] #wg2 = pya.Box(-l/2,-4/2/dbu,l/2,4/2/dbu) self.cell.shapes(LayerSiN).insert(Polygon(pts)) total_waveguide_length += in_taper * dbu pts = [] for ii in range(0, N + 1): pts.append( Point(l / 2 + in_taper - in_taper / N * ii, (w - overlay_ebl) / 2 + ((2 / dbu - (w - overlay_ebl)) / (N**order)) * (ii**order) + y_move)) for ii in range(0, N + 1): pts.append( Point( l / 2 + in_taper / N * ii, -(w - overlay_ebl) / 2 - ((2 / dbu - (w - overlay_ebl)) / (N**order)) * ((N - ii)**order) + y_move)) self.cell.shapes(LayerSlab).insert(Polygon(pts)) # add metal contact and folded waveguides for i in range(-folding_n, folding_n): y_coordinate = contact_size + sw + 2 * vc_to_npp_exclusion # move up/down the position according to vc_to_npp_exclusion if i < 0: y_origin = (i + 1) * (folding_w1 + folding_w2 + folding_gap * 2) / 2 - y_coordinate if i == 0: y_origin = 0 if i > 0: y_origin = (i - 1) * (folding_w1 + folding_w2 + folding_gap * 2) / 2 + y_coordinate if (i + 1) < 0: y_end = (i + 2) * (folding_w1 + folding_w2 + folding_gap * 2) / 2 - y_coordinate if (i + 1) == 0: y_end = 0 if (i + 1) > 0: y_end = i * (folding_w1 + folding_w2 + folding_gap * 2) / 2 + y_coordinate # Calculate the Folded waveguide vertices if (i + folding_n) % 2: # Waveguides on the left side if y_origin + routing_step * 2 - y_end < 2 * radius_um: y_routing = max(routing_step * 2, y_end - y_origin) else: y_routing = y_end + routing_step * 2 path = Path([ Point(-l / 2 - in_taper, y_origin), Point( -l / 2 - in_taper - routing_step * (1.5 * folding_n - 1.5 * i + 1.5), y_origin), Point( -l / 2 - in_taper - routing_step * (1.5 * folding_n - 1.5 * i + 1.5), y_routing), Point( -l / 2 - in_taper - routing_step * (1.5 * folding_n - 1.5 * i - 0.5), y_routing), Point( -l / 2 - in_taper - routing_step * (1.5 * folding_n - 1.5 * i - 0.5), y_end), Point(-l / 2 - in_taper, y_end) ], 0) else: # Waveguides on the right side if y_origin - y_end + routing_step * 2 < 2 * radius_um: y_routing = -max(routing_step * 2, y_end - y_origin) else: y_routing = y_origin - routing_step * 2 path = Path([ Point(l / 2 + in_taper, y_origin), Point( l / 2 + in_taper + routing_step * (1.5 * folding_n + 1.5 * i + 1), y_origin), Point( l / 2 + in_taper + routing_step * (1.5 * folding_n + 1.5 * i + 1), y_routing), Point( l / 2 + in_taper + routing_step * (1.5 * folding_n + 1.5 * i + 3), y_routing), Point( l / 2 + in_taper + routing_step * (1.5 * folding_n + 1.5 * i + 3), y_end), Point(l / 2 + in_taper, y_end) ], 0) # Draw the waveguide geometry, new in SiEPIC-Tools v0.3.64 path.unique_points() pts = path.get_points() total_waveguide_length += layout_waveguide2( TECHNOLOGY, self.layout, self.cell, ['Si'], [w * dbu], [0], pts, radius_um, adiab, bezier) for i in range(0, self.segments + 1): wg_temp_upper = pya.Box( (l - contact_size) / self.segments * i - l / 2 - vc_to_npp_exclusion, sw / 2, (l - contact_size) / self.segments * i - l / 2 + contact_size + vc_to_npp_exclusion, sw / 2 + contact_size + 2 * vc_to_npp_exclusion) #self.cell.shapes(LayerNN).insert(wg_temp_upper) self.cell.shapes(LayerNPPN).insert(wg_temp_upper) # self.cell.shapes(LayerNN).insert(wg_temp_upper) wg_temp_upper = pya.Box( (l - contact_size) / self.segments * i - l / 2 - 2 * vc_to_npp_exclusion, sw / 2, (l - contact_size) / self.segments * i - l / 2 + contact_size + 2 * vc_to_npp_exclusion, sw / 2 + contact_size + 3 * vc_to_npp_exclusion) self.cell.shapes(LayerSlab).insert(wg_temp_upper) vc_temp_upper = pya.Box( (l - contact_size) / self.segments * i - l / 2, sw / 2 + vc_to_npp_exclusion, (l - contact_size) / self.segments * i - l / 2 + contact_size, sw / 2 + contact_size + vc_to_npp_exclusion) self.cell.shapes(LayerVCN).insert(vc_temp_upper) wg_temp_lower = pya.Box( (l - contact_size) / self.segments * i - l / 2 - vc_to_npp_exclusion, -sw / 2, (l - contact_size) / self.segments * i - l / 2 + contact_size + vc_to_npp_exclusion, -sw / 2 - contact_size - 2 * vc_to_npp_exclusion) #self.cell.shapes(LayerNN).insert(wg_temp_lower) self.cell.shapes(LayerNPPN).insert(wg_temp_lower) wg_temp_lower = pya.Box( (l - contact_size) / self.segments * i - l / 2 - 2 * vc_to_npp_exclusion, -sw / 2, (l - contact_size) / self.segments * i - l / 2 + contact_size + 2 * vc_to_npp_exclusion, -sw / 2 - contact_size - 3 * vc_to_npp_exclusion) self.cell.shapes(LayerSlab).insert(wg_temp_lower) # self.cell.shapes(LayerNN).insert(wg_temp_lower) vc_temp_lower = pya.Box( (l - contact_size) / self.segments * i - l / 2, -sw / 2 - vc_to_npp_exclusion, (l - contact_size) / self.segments * i - l / 2 + contact_size, -sw / 2 - contact_size - vc_to_npp_exclusion) self.cell.shapes(LayerVCN).insert(vc_temp_lower) metal_temp = pya.Box( (l - contact_size) / self.segments * i - l / 2 - vc_to_npp_exclusion, -sw / 2 - contact_size - metal_routing_distance_to_node * (i % 2) - 2 * vc_to_npp_exclusion, (l - contact_size) / self.segments * i - l / 2 + contact_size + vc_to_npp_exclusion, sw / 2 + contact_size + metal_routing_distance_to_node * ((i + 1) % 2) + 2 * vc_to_npp_exclusion) self.cell.shapes(LayerMN).insert(metal_temp) metal_routing = Path([ Point(-l / 2, -sw / 2 - metal_routing_distance_to_node - contact_size), Point(l / 2, -sw / 2 - metal_routing_distance_to_node - contact_size) ], metal_routing_width) self.cell.shapes(LayerMN).insert(metal_routing) metal_routing = Path([ Point(-l / 2, sw / 2 + metal_routing_distance_to_node + contact_size), Point(l / 2, sw / 2 + metal_routing_distance_to_node + contact_size) ], metal_routing_width) self.cell.shapes(LayerMN).insert(metal_routing) if folding_n > 0: dev = Box( wg_start, -sw / 2 - metal_routing_distance_to_node - contact_size - metal_routing_width, wg_end, sw / 2 + metal_routing_distance_to_node + contact_size + metal_routing_width) self.cell.shapes(LayerDevRecN).insert(dev) t = Trans(0, False, Point(0, 0)) text = Text ( \ 'Waveguide Length=%.3fu' %(total_waveguide_length), t, 3*w, -1) shape = self.cell.shapes(LayerDevRecN).insert(text)
def produce_impl(self): from SiEPIC.utils.layout import layout_waveguide2 from SiEPIC.utils import angle_vector from math import cos, sin, pi, sqrt import pya from SiEPIC.extend import to_itype TECHNOLOGY = get_technology_by_name('GSiP') dbu = self.layout.dbu wg_width = to_itype(self.width, dbu) path = self.path.to_itype(dbu) if not (len(self.layers) == len(self.widths) and len(self.layers) == len(self.offsets) and len(self.offsets) == len(self.widths)): raise Exception( "There must be an equal number of layers, widths and offsets") path.unique_points() pts = path.get_points() # Draw the waveguide geometry, new in SiEPIC-Tools v0.3.64 waveguide_length = layout_waveguide2(TECHNOLOGY, self.layout, self.cell, self.layers, self.widths, self.offsets, pts, self.radius, self.adiab, self.bezier) pts = path.get_points() LayerPinRecN = self.layout.layer(TECHNOLOGY['PinRec']) t1 = Trans(angle_vector(pts[0] - pts[1]) / 90, False, pts[0]) self.cell.shapes(LayerPinRecN).insert( Path([Point(-50, 0), Point(50, 0)], wg_width).transformed(t1)) self.cell.shapes(LayerPinRecN).insert(Text("pin1", t1, 0.3 / dbu, -1)) t = Trans(angle_vector(pts[-1] - pts[-2]) / 90, False, pts[-1]) self.cell.shapes(LayerPinRecN).insert( Path([Point(-50, 0), Point(50, 0)], wg_width).transformed(t)) self.cell.shapes(LayerPinRecN).insert(Text("pin2", t, 0.3 / dbu, -1)) LayerDevRecN = self.layout.layer(TECHNOLOGY['DevRec']) # Compact model information angle_vec = angle_vector(pts[0] - pts[1]) / 90 halign = 0 # left angle = 0 if angle_vec == 0: # horizontal halign = 2 # right angle = 0 dpt = Point(0, 0.2 * wg_width) if angle_vec == 2: # horizontal halign = 0 # left angle = 0 dpt = Point(0, 0.2 * wg_width) if angle_vec == 1: # vertical halign = 2 # right angle = 1 dpt = Point(0.2 * wg_width, 0) if angle_vec == -1: # vertical halign = 0 # left angle = 1 dpt = Point(0.2 * wg_width, 0) pt2 = pts[0] + dpt pt3 = pts[0] - dpt pt4 = pts[0] - 2 * dpt pt5 = pts[0] + 2 * dpt t = Trans(angle, False, pt5) text = Text('cellName=%s' % self.cellName, t, 0.1 * wg_width, -1) text.halign = halign shape = self.cell.shapes(LayerDevRecN).insert(text) t = Trans(angle, False, pt3) text = Text('Lumerical_INTERCONNECT_library=Design kits/%s' % self.CML, t, 0.1 * wg_width, -1) text.halign = halign shape = self.cell.shapes(LayerDevRecN).insert(text) t = Trans(angle, False, pt2) text = Text('Component=%s' % self.model, t, 0.1 * wg_width, -1) text.halign = halign shape = self.cell.shapes(LayerDevRecN).insert(text) t = Trans(angle, False, pts[0]) pts_txt = str( [[round(p.to_dtype(dbu).x, 3), round(p.to_dtype(dbu).y, 3)] for p in pts]).replace(', ', ',') text = Text ( \ 'Spice_param:wg_length=%.3fu wg_width=%.3fu points="%s" radius=%s' %\ (waveguide_length, self.width, pts_txt,self.radius ), t, 0.1*wg_width, -1 ) text.halign = halign shape = self.cell.shapes(LayerDevRecN).insert(text) t = Trans(angle, False, pt4) text = Text ( \ 'Length=%.3fu' %(waveguide_length), t, 0.5*wg_width, -1 ) text.halign = halign shape = self.cell.shapes(LayerDevRecN).insert(text)