class Layout(i3.LayoutView): metal1_size = i3.Size2Property(default=(50.0, 50.0)) metal2_size = i3.Size2Property(default=(50.0, 50.0)) via_pitch = i3.Size2Property(default=(2.0, 2.0)) metal1_layer = i3.LayerProperty(default=i3.TECH.PPLAYER.M1.LINE, locked=True) metal2_layer = i3.LayerProperty(default=i3.TECH.PPLAYER.M2.LINE, locked=True) def _generate_instances(self, insts): from numpy import floor via_span_x = min(self.metal1_size[0], self.metal2_size[0]) via_span_y = min(self.metal1_size[1], self.metal2_size[1]) periods_x = int(floor(via_span_x / self.via_pitch[0])) periods_y = int(floor(via_span_y / self.via_pitch[1])) insts += i3.ARef(reference=self.via, origin=(-0.5 * via_span_x + 0.5 * self.via_pitch[0], -0.5 * via_span_y + 0.5 * self.via_pitch[1]), period=self.via_pitch, n_o_periods=(periods_x, periods_y)) return insts def _generate_elements(self, elems): elems += i3.Rectangle(layer=self.metal1_layer, box_size=self.metal1_size) elems += i3.Rectangle(layer=self.metal2_layer, box_size=self.metal2_size) return elems def _generate_ports(self, ports): ports += i3.ElectricalPort(name="m1", position=(0.0, 0.0), shape=self.metal1_size, process=self.metal1_layer.process) ports += i3.ElectricalPort(name="m2", position=(0.0, 0.0), shape=self.metal2_size, process=self.metal2_layer.process) return ports
class PI(i3.PCell): _name_prefix = "PI" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=7000.0) width = i3.PositiveNumberProperty(default=630.0) pocket = i3.BoolProperty(default=False) tilt = i3.BoolProperty(default=False) # Recess label label = i3.StringProperty(default="PI_") class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500, y0 + 1000 + (3000 - self.width) / 4), box_size=(self.length, (3000 - self.width) / 2)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500, y0 + 1000 + self.width + (3000 - self.width) * 3 / 4), box_size=(self.length, (3000 - self.width) / 2)) elems += i3.SRef(reference=Interface(pocket=self.pocket, tilt=self.tilt)) for i in range(7): elems += i3.Rectangle(layer=self.layer, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 185), box_size=(50, 50)) elems += i3.Rectangle(layer=self.layer, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 185), box_size=(50, 50)) if self.pocket: self.label += "WP" if self.tilt: self.label += "WT" elems += i3.PolygonText(layer=self.layer_bool, text=self.label, coordinate=(6000, 4000), # 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
class Interface_mmi12(i3.PCell): _name_prefix = "INTERFACE_" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=2500) # shrink width = i3.PositiveNumberProperty(default=3000.0 * 0.6) pocket = i3.BoolProperty(default=False) tilt = i3.BoolProperty(default=False) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(x0 + 7500 + 2000+1500, y0 + 4500 - 1800+500), box_size=(10000, 1600)) # change # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.NONE.DOC, center=(x0 + 7500, y0 + 4500), # box_size=(15000, 1000)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 7500 + 2000+1500, y0 + 500 - 200-500), box_size=(10000, 1600)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 12500 + 1000 - 250, y0 + 2500 - 1000), # change box_size=(self.length, self.width)) elems +=i3.Rectangle(layer=self.layer, center=(x0+ 15250, y0+1500),box_size=(1500,1800)) #add if self.pocket: PO = i3.Rectangle(layer=self.layer_bool, center=(10001 + 2000, 2500 - 1000), box_size=(2, 160)) # change elems += PO generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) if self.tilt: # TI = i3.Rectangle(layer=self.layer_bool, center=(10001, 2500), box_size=(2, 160)) # elems += TI TI_shape = i3.Shape(points=[(10000.0 + 2000, 2470.0 - 1000), (10010.58 + 2000, 2530.0 - 1000), (10000.0 + 2000, 2530.0 - 1000)], closed=True) # change TI = i3.Boundary(layer=self.layer_bool, shape=TI_shape) elems += TI generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class SiN_NP(i3.PCell): _name_prefix = "SiN_NP" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.SIL.LINE) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=7000.0) width = i3.PositiveNumberProperty(default=330.0) pillar = i3.BoolProperty(default=False) tilt_0 = i3.BoolProperty(default=False) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(1500 - 20, 2500), box_size=(3000 - 40, 3000 - 40 * 2)) if self.tilt_0: elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 - 40 + 20 + 7.5, 2500), box_size=(self.length + 40 + 15, self.width - 40 * 2)) else: elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 - 40 + 20 + 5, 2500), box_size=(self.length + 40 + 10, self.width - 40 * 2)) if self.pillar: for i in range(7): elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 30), box_size=(130, 140)) elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 30), box_size=(130, 140)) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class dicingMarker(i3.PCell): _name_prefix = "markers" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW) # layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position for i in range(0, 4, 1): for j in range(0, 3, 1): elems += i3.Rectangle(layer=self.layer, center=(x0 + i * 6000, y0 + j * 7000), box_size=(100, 100)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 200 + i * 6000, y0 + j * 7000), box_size=(100, 100)) elems += i3.Rectangle(layer=self.layer, center=(x0 + i * 6000, y0 + 200 + j * 7000), box_size=(100, 100)) elems += i3.Rectangle(layer=self.layer, center=(x0 + i * 6000 + 200, y0 + 200 + j * 7000), box_size=(100, 100)) for k in range(0, 20, 1): elems += i3.Rectangle( layer=self.layer, center=(-1000 + 0 + i * 6000, 1000 + 10 * k + j * 7000), box_size=(500, 0.6 + 0.2 * k)) elems += i3.PolygonText( layer=self.layer, text="{}".format(str(k)), # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=7.0, transformation=i3.Translation( (-1000 + 260 + i * 6000, 1000 + 3 + 10 * k + j * 7000))) elems += i3.Rectangle(layer=i3.TECH.PPLAYER.NONE.DOC, center=(9000, 7500), box_size=(21000, 16000)) # elems += i3.Rectangle(layer=i3.TECH.PPLAYER.CONTACT.PILLAR, center=(8500, 7500), # box_size=(22000, 18000)) return elems
class AL_PI(i3.PCell): _name_prefix = "AL_PI" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CONTACT.PILLAR) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=7000.0) width = i3.PositiveNumberProperty(default=630.0) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(1500 - 20, 2500), box_size=(3000 - 40, 3000 - 40 * 2)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 - 40, 2500), box_size=(self.length, self.width - 40 * 2)) for i in range(7): elems += i3.Rectangle(layer=self.layer_bool, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 185), box_size=(130, 130)) elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 185), box_size=(130, 130)) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class Layout(i3.LayoutView): layer = i3.LayerProperty(default=i3.TECH.TRACE.DEFAULT_LAYER) #layer_c = i3.LayerProperty(default=i3.TECH.TRACE.DEFAULT_LAYER) def _default_layer(self): layer=PPLayer(process=i3.TECH.PROCESS.WG,purpose=i3.TECH.PURPOSE.LF.LINE) return layer def _generate_elements(self, elems): elems += i3.Rectangle(layer=self.layer, box_size=(self.heightchip,self.widthchip)) return elems
class Layout(i3.LayoutView): size = i3.Size2Property(default=(50.0, 50.0), doc="Size of the bondpad") metal_layer = i3.LayerProperty(default=i3.TECH.PPLAYER.M1.LINE, doc="Metal used for the bondpad") def _generate_elements(self, elems): elems += i3.Rectangle(layer=self.metal_layer, box_size=self.size) return elems def _generate_ports(self, ports): ports += i3.ElectricalPort(name="m1", position=(0.0, 0.0), shape=self.size, process=self.metal_layer.process) return ports
class Release(i3.PCell): _name_prefix = "RELEASE" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer lay_release = i3.Layer(number=4, name="release") layer = i3.LayerProperty(default=lay_release) # Mesa parameters length = i3.PositiveNumberProperty(default=800.0) width = i3.PositiveNumberProperty(default=40.0) release_margin = i3.PositiveNumberProperty(default=12.5) release_tether_period = i3.PositiveNumberProperty(default=45.0) release_tether_length = i3.PositiveNumberProperty(default=17.5) release_tether_width = i3.PositiveNumberProperty(default=8.0) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position # elems += i3.Rectangle(layer=self.layer, center=(x0, y0), # box_size=(self.length + self.release_margin, self.width + self.release_margin)) elems += i3.Rectangle(layer=self.layer, center=(300, 300), box_size=(200, 200)) rec = i3.Rectangle(layer=self.layer, center=(0, 0), box_size=(200, 200)) layer2 = i3.Layer(2) remove = i3.Wedge(layer=layer2, begin_coord=(-100, 0), end_coord=(-50, 0), begin_width=8, end_width=0.001) elems += rec elems += remove generated1 = self.layer - layer2 mapping = {generated1: self.layer} output_elems = i3.get_elements_for_generated_layers(elems, mapping) # # elems = elems | wedge, # haha = rec | remove, # elems += remove, # # elems +=rec, # elems = elems.extend(haha), return output_elems
class Layout(i3.LayoutView): #layer = i3.LayerProperty(default=i3.TECH.TRACE.DEFAULT_LAYER) layer_c = i3.LayerProperty(default=i3.TECH.TRACE.DEFAULT_LAYER) #def _default_layer(self): #layer=PPLayer(process=i3.TECH.PROCESS.WG,purpose=i3.TECH.PURPOSE.LF.LINE) #return layer def _default_layer_c(self): layer=PPLayer(process=i3.TECH.PROCESS.SK,purpose=i3.TECH.PURPOSE.DF_AREA) return layer def _generate_elements(self, elems): #elems += i3.Rectangle(layer=self.layer, box_size=(self.width, self.height)) elems += i3.Circle(layer=self.layer_c, center=(0.0, 0.0), radius=self.Diameter*0.5) return elems
class Release(i3.PCell): _name_prefix = "RELEASE" # Layer lay_release = i3.Layer(number=1, name="release") layer = i3.LayerProperty(default=lay_release) # Mesa parameters length = i3.PositiveNumberProperty(default=40.0) width = i3.PositiveNumberProperty(default=8.0) class Layout(i3.LayoutView): def _generate_elements(self, elems): elems += i3.Rectangle(layer=self.layer, center=(0, 0), box_size=(self.length, self.width)) return elems
class Obstacle_BooleanBoundary(i3.PCell): # Properties of trap width = 200 #i3.PositiveNumberProperty(default=200.,doc="width main channel") channel_template = microfluidics.ChannelTemplateProperty( default=microfluidics.ShortChannelTemplate().Layout(width=width), doc="Channel template of the tee") _name_prefix = "VacTrapV" # a prefix added to the unique identifier radius = i3.PositiveNumberProperty( default=400., doc="radius of the circular vacuum section collecting air") vacuum_channel_circular = i3.PositiveNumberProperty( default=100., doc="width of circular channel collecting air") inlet_channel_length = i3.PositiveNumberProperty( default=300., doc="length of inlet channel vac") offset_matching = i3.PositiveNumberProperty( default=50., doc="length of inlet channel vac") obstacles = i3.ChildCellProperty( doc='the single Obstacle child cell, which will be clonned many times', default=JoinedObstacles(wholeTrapX=width)) layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CH2.TRENCH, doc='Layer to drawn on') cInp = i3.Coord2Property(default=(0.0, 0.0), required=True) class Layout(i3.LayoutView): def _generate_instances(self, insts): width = 200.0 p1 = (-self.radius, -self.radius) #near cylinders p2 = (-self.radius, -2 * self.radius) #bottom p3 = (2 * self.radius, -2 * self.radius) #right p4 = (2 * self.radius, 0) #top p5 = (2 * self.radius + 500, 0) #out pax = (-width * 0.5 * math.cos(45), width * 0.5 * math.sin(45)) #generate a circle sr1 = i3.ShapeCircle(center=(0.0, 0.0), radius=self.radius) #, line_width = 200) br1 = i3.Boundary(layer=self.layer, shape=sr1) #s= i3.Structure(elements = br1) #rectangle sc1 = i3.ShapeRectangle(center=p1, box_size=(self.radius * 4, self.radius * 0.25)) bc1 = i3.Boundary(layer=self.layer, shape=sc1, transformation=i3.Rotation((0, 0), -45.0)) # was -35 #Substruct boundaries and add to the element list b_sub = br1 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) #Input channel - segment channel1 = microfluidics.Channel( trace_template=self.cell.channel_template) #channel_template = microfluidics.ShortChannelTemplate().Layout(width=200.0) channel1_lo = channel1.Layout(shape=[(self.inlet_channel_length + self.offset_matching * 0.5, 0), (0, 0)]) insts += i3.SRef( channel1_lo, position=(-(self.inlet_channel_length + self.radius), 0), transformation=i3.Rotation((0.0, 0.0), 0.0)) #############################routing from ipkiss.plugins.photonics.routing.manhattan import RouteManhattan channel_4 = microfluidics.RoundedChannel( trace_template=self.cell.channel_template) # used for routing channel_4_layout = channel_4.Layout() import operator p1Array = tuple(map(operator.add, p1, pax)) print 'p1: ', p1 print 'pax: ', pax print 'p1Array: ', p1Array #obstacles insts += i3.SRef(reference=self.obstacles, position=p1Array, transformation=i3.Rotation((0, 0), -45.0)) in_port_1 = microfluidics.FluidicPort( position=p1, trace_template=self.cell.channel_template) out_port_1 = microfluidics.FluidicPort( trace_template=self.cell.channel_template) in_port_1.angle_deg = 225 out_port_1.angle_deg = 45 in_port_2 = microfluidics.FluidicPort( position=p2, trace_template=self.cell.channel_template) in_port_2.angle_deg = 225 channel_4_layout.set(bend_radius=150.0, shape=RouteManhattan(input_port=in_port_2, points=[p2, p3, p4, p5], output_port=out_port_1, bend_radius=300.0)) insts += i3.SRef(name="Route_1", reference=channel_4) ##############################routing from ipkiss3.pcell.routing import RouteToAngle # create the route object channel_1 = microfluidics.RoundedChannel( trace_template=self.cell.channel_template) # used for routing channel_1_layout = channel_1.Layout() channel_1_layout.set(bend_radius=50.0, shape=RouteToAngle(input_port=in_port_1, start_straight=300, end_straight=300, angle_out=45)) #insts += i3.SRef(name = "Route_2", reference = channel_1) from ipkiss3.pcell.routing import RouteToEastAtMaxY, RouteToEastAtMinY, RouteToEastAtY # create the route object input_portx = i3.OpticalPort(name="in", position=(-self.radius, -self.radius), angle_deg=225.0) channel_x = microfluidics.RoundedChannel( trace_template=self.cell.channel_template) # used for routing channel_x_layout = channel_x.Layout() channel_x_layout.set(bend_radius=150.0, shape=RouteToEastAtY(input_port=input_portx, start_straight=200, end_straight=200, y_position=-2 * self.radius)) insts += i3.SRef(name="Route_x", reference=channel_x) return insts #Thach added to define one inlet and one outlet def _generate_ports( self, ports): # Use _generate_ports method to define ports #ports += i3.InFluidicPort(name = "in", position = (0., 10.), angle = 180.0) ports += i3.OpticalPort(name="in", position=(0., self.radius + self.inlet_channel_length), angle=180.0) #ports += i3.OutFluidicPort(name ="out", position = (30., 10.), angle = 0.0) #ports += i3.OpticalPort(name ="out", position = ((self.obstacle_trap_length+self.gap_btw_barriers)*2, self.channel_trap_width*0.5), angle = 0.0) return ports
class Obstacle_Left(i3.PCell): layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CH2.TRENCH, doc='Layer to drawn on') # Properties of trap obstacle_trap_radius = i3.PositiveNumberProperty( default=10., doc="width or radius of obstacle") gap_btw_barriers = i3.PositiveNumberProperty(default=10., doc="gap between obstacles") cInp = i3.Coord2Property(default=(0.0, 0.0), required=True) class Layout(i3.LayoutView): 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 #Thach added to define one inlet and one outlet def _generate_ports( self, ports): # Use _generate_ports method to define ports ports += i3.OpticalPort(name="in", position=(0., self.obstacle_trap_radius + self.gap_btw_barriers), angle=180.0) ports += i3.OpticalPort( name="out", position=((self.gap_btw_barriers * 1.5 + self.obstacle_trap_radius * 3), self.obstacle_trap_radius + self.gap_btw_barriers), angle=0.0) return ports
class NP_mmi12(i3.PCell): _name_prefix = "NP_" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) layer2 = i3.LayerProperty(default=i3.TECH.PPLAYER.WG.TEXT) # Mesa parameters length = i3.PositiveNumberProperty(default=160.0) width = i3.PositiveNumberProperty(default=120.0) pillar = i3.BoolProperty(default=False) pocket = i3.BoolProperty(default=False) tilt = i3.BoolProperty(default=False) double = i3.BoolProperty(default=True) # Recess label label = i3.StringProperty(default="NP") class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position width2 = 450.0 elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 + 2000 + 2000, 600 + (1800 - width2) / 4), box_size=(3000, (1800 - width2) / 2)) elems += i3.Rectangle(layer=self.layer, center=(x0 + 6500 + 2000 + 2000, y0 + 600 + width2 + (1800 - width2) * 3 / 4), box_size=(3000, (1800 - width2) / 2)) elems += i3.SRef( reference=Interface_mmi12(pocket=self.pocket, tilt=self.tilt)) if self.pillar: self.label = "NO" for i in range(4): elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 550, 1275 + self.width / 2), box_size=(self.length, self.width)) elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 550, 1725 - self.width / 2), # change box_size=(self.length, self.width)) if self.double: elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1275 + self.width / 2), box_size=(self.length, self.width)) elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1725 - self.width / 2), # change box_size=(self.length, self.width)) if self.width > 120: 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=(10800, 2600), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=400.0) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) if self.pillar: for i in range(4): elems += i3.Rectangle( layer=self.layer2, center=(10000 - 725 - i * 750 + 2000 + 550, 1275 + self.width / 2), box_size=(self.length + 10, self.width + 10)) elems += i3.Rectangle( layer=self.layer2, center=(10000 - 725 - i * 750 + 2000 + 550, 1725 - self.width / 2), # change box_size=(self.length + 10, self.width + 10)) if self.double: elems += i3.Rectangle( layer=self.layer2, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1275 + self.width / 2), box_size=(self.length + 10, self.width + 10)) elems += i3.Rectangle( layer=self.layer2, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1725 - self.width / 2), # change box_size=(self.length + 10, self.width + 10)) return elems
class Obstacle_BooleanBoundary(i3.PCell): # Properties of trap channel_template = microfluidics.ChannelTemplateProperty( default=microfluidics.ShortChannelTemplate(), doc="Channel template of the tee") _name_prefix = "VacTrapV" # a prefix added to the unique identifier radius = i3.PositiveNumberProperty( default=400., doc="radius of the circular vacuum section collecting air") vacuum_channel_circular = i3.PositiveNumberProperty( default=100., doc="width of circular channel collecting air") inlet_channel_length = i3.PositiveNumberProperty( default=300., doc="length of inlet channel vac") layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CH2.TRENCH, doc='Layer to drawn on') cInp = i3.Coord2Property(default=(0.0, 0.0), required=True) class Layout(i3.LayoutView): 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 #Thach added to define one inlet and one outlet def _generate_ports( self, ports): # Use _generate_ports method to define ports #ports += i3.InFluidicPort(name = "in", position = (0., 10.), angle = 180.0) ports += i3.OpticalPort(name="in", position=(0., self.radius + self.inlet_channel_length), angle=180.0) #ports += i3.OutFluidicPort(name ="out", position = (30., 10.), angle = 0.0) #ports += i3.OpticalPort(name ="out", position = ((self.obstacle_trap_length+self.gap_btw_barriers)*2, self.channel_trap_width*0.5), angle = 0.0) return ports
class AL_NP(i3.PCell): _name_prefix = "AL_NP" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CONTACT.PILLAR) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters offset = i3.PositiveNumberProperty(default=20) # width = i3.PositiveNumberProperty(default=79) # pillar = i3.BoolProperty(default=False) reservoir = i3.BoolProperty(default=False) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position # width2 = 338 + 15 + 15 elems += i3.Rectangle(layer=self.layer, center=(8750 - 15 - 10 + 5, 1500), box_size=(500 - 40, 1800 - 100)) elems += i3.Rectangle(layer=self.layer, center=(10500 - 15 - 10, 1500), box_size=(3000 + 50, 145)) elems += i3.Rectangle(layer=self.layer, center=(8750 - 15 - 10 + 5 + 2420 - 150, 1000 - 120), box_size=(2000, 500 - 40)) #extra pad elems += i3.Rectangle( layer=self.layer_bool, center=(8750 - 15 - 10 + 5 + 2420 - 150 + 998, 1000 - 120 + 620), box_size=(4, 145)) #extra shrink on the interface for i in range(4): elems += i3.Rectangle(layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 350 + self.offset, 1316 + 72.75), box_size=(145, 77.5)) elems += i3.Rectangle( layer=self.layer, center=(10000 - 725 - i * 750 + 2000 + 350 + self.offset, 1684 - 72.75), # change box_size=(145, 77.5)) # Avoid solder spill on facet elems += i3.Rectangle(layer=self.layer_bool, center=(12000 - 20, 1500), box_size=(40, 50)) elems += i3.Rectangle(layer=self.layer_bool, center=(12000 - 750 * 2, 1500), box_size=(80, 50)) elems += i3.Rectangle(layer=self.layer_bool, center=(12000 - 750 * 3, 1500), box_size=(80, 50)) elems += i3.Rectangle(layer=self.layer_bool, center=(12000 - 750 * 4, 1500), box_size=(80, 50)) # reservoir if self.reservoir: for i in range(3): elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1572.5 + 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1427.5 - 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1572.5 + 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1427.5 - 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1572.5 + 20), box_size=(149, 40)) elems += i3.Rectangle(layer=self.layer, center=(-750 * i + 12000 - 750, 1427.5 - 20), box_size=(149, 40)) elems += i3.PolygonText( layer=self.layer, text="RE", coordinate=(12000, 2600), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=400.0) # Markers bigsquare = 16.5 smallsquare = 11.5 for i in range(-3, 0, 2): elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78, 1568.75), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5, 1572 - 32), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 57, 1572 - 32), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78, 1568.75 - 57.5), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75, 1572.5 - 13.25), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5, 1572.5 - 13.25), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75, 1572.5 - 13.25 - 38.5), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5, 1572.5 - 13.25 - 38.5), box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75-80), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5, 1572 - 32-80), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57, 1572 - 32-80), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75 - 57.5-80), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-2.5, 1572.5 - 13.25-80-2.5), box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5+2.5, 1572.5 - 13.25-80-2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-2.5, 1572.5 - 13.25 - 38.5-80+2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5+2.5, 1572.5 - 13.25 - 38.5-80+2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-594, 1572 - 32), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57-594, 1572 - 32), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 57.5), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-594-2.5, 1572.5 - 13.25-2.5), box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5-594+2.5, 1572.5 - 13.25-2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-594-2.5, 1572.5 - 13.25 - 38.5+2.5), # box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5-594+2.5, 1572.5 - 13.25 - 38.5+2.5), # box_size=(bigsquare, bigsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78 - 594, 1568.75 - 80), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 594, 1572 - 32 - 80), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 57 - 594, 1572 - 32 - 80), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78 - 594, 1568.75 - 57.5 - 80), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 594, 1572.5 - 13.25 - 80), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 - 594, 1572.5 - 13.25 - 80), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 594, 1572.5 - 13.25 - 38.5 - 80), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 - 594, 1572.5 - 13.25 - 38.5 - 80), box_size=(smallsquare, smallsquare)) for i in range(-2, 1, 2): # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5, 1572-32), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-57, 1572-32), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78, 1568.75-57.5), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75, 1572.5-13.25), box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-38.5, 1572.5 - 13.25), box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75, 1572.5 - 13.25-38.5), box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75-38.5, 1572.5 - 13.25-38.5), box_size=(smallsquare, smallsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78, 1568.75 - 80), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5, 1572 - 32 - 80), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 57, 1572 - 32 - 80), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78, 1568.75 - 57.5 - 80), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 2.5, 1572.5 - 13.25 - 80 - 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 + 2.5, 1572.5 - 13.25 - 80 - 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle( layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 2.5, 1572.5 - 13.25 - 38.5 - 80 + 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle( layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 + 2.5, 1572.5 - 13.25 - 38.5 - 80 + 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78 - 594, 1568.75), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 594, 1572 - 32), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 49.5 - 57 - 594, 1572 - 32), box_size=(9, 9)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 78 - 594, 1568.75 - 57.5), box_size=(9, 9.5)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 594 - 2.5, 1572.5 - 13.25 - 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle(layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 - 594 + 2.5, 1572.5 - 13.25 - 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle( layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 594 - 2.5, 1572.5 - 13.25 - 38.5 + 2.5), box_size=(bigsquare, bigsquare)) elems += i3.Rectangle( layer=self.layer_bool, center=(750 * i + 12000 - 58.75 - 38.5 - 594 + 2.5, 1572.5 - 13.25 - 38.5 + 2.5), box_size=(bigsquare, bigsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 80), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5-594, 1572 - 32 - 80), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 49.5 - 57-594, 1572 - 32 - 80), box_size=(7, 7)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 78-594, 1568.75 - 57.5 - 80), box_size=(7, 7.5)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 -594, 1572.5 - 13.25 - 80 ), # box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 - 38.5 -594, 1572.5 - 13.25 - 80 ), # box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, center=(750*i+12000 - 58.75 -594, 1572.5 - 13.25 - 38.5 - 80 ), # box_size=(smallsquare, smallsquare)) # elems += i3.Rectangle(layer=self.layer_bool, # center=(750*i+12000 - 58.75 - 38.5 -594, 1572.5 - 13.25 - 38.5 - 80 ), # box_size=(smallsquare, smallsquare)) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class SiN_NP(i3.PCell): _name_prefix = "SiN_NP" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.SIL.LINE) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) # Mesa parameters length = i3.PositiveNumberProperty(default=180.0) width = i3.PositiveNumberProperty(default=79.0) tilt = i3.PositiveNumberProperty(default=10.0) pillar = i3.BoolProperty(default=True) double = i3.BoolProperty(default=True) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(8750 - 15 - 10 + 5, 1500), box_size=(500 - 40, 1800 - 100)) elems += i3.Rectangle(layer=self.layer, center=(10500 - 15 - 10 + self.tilt / 2, 1500), box_size=(3000 + 50 + self.tilt, 450 - 15 * 2)) elems += i3.Rectangle(layer=self.layer, center=(8750 - 15 - 10 + 5 + 2420 - 150, 1000 - 120), box_size=(2000, 500 - 40)) # extra SiN pad # for i in range(4): # elems += i3.Rectangle(layer=self.layer, # center=( # 10000 - 725 - i * 750 + 2000 + 350, 1316+72.75), # box_size=(145, 77.5)) # elems += i3.Rectangle(layer=self.layer, center=( # 10000 - 725 - i * 750 + 2000 + 350, 1684-72.75), # change # box_size=(145, 77.5)) if self.pillar: for i in range(4): elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750 + 2000 + 550, 1316 + self.width / 2 - 11.0 / 2), box_size=(self.length + 30, self.width + 30 + 11)) elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750 + 2000 + 550, 1684 - self.width / 2 + 11.0 / 2), # change box_size=(self.length + 30, self.width + 30 + 11)) if self.double: elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1316 + self.width / 2 - 11.0 / 2), box_size=(self.length + 30, self.width + 30 + 11)) elems += i3.Rectangle( layer=self.layer_bool, center=(10000 - 725 - i * 750 + 2000 + 550 - 400, 1684 - self.width / 2 + 11.0 / 2), # change box_size=(self.length + 30, self.width + 30 + 11)) # if self.tilt_0: # elems += i3.Rectangle(layer=self.layer, # center=(x0 + 6500 - 40 + 20 + 7.5, 2500), # box_size=(self.length + 40 + 15, self.width - 40 * 2)) # else: # elems += i3.Rectangle(layer=self.layer, # center=(x0 + 6500 - 40 + 20 + 5, 2500), # box_size=(self.length + 40 + 10, self.width - 40 * 2)) # # if self.pillar: # for i in range(7): # elems += i3.Rectangle(layer=self.layer_bool, # center=(10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + 30), # box_size=(130, 140)) # elems += i3.Rectangle(layer=self.layer_bool, center=( # 10000 - 725 - i * 750, 1000 + (3000 - self.width) / 2 + self.width - 30), # box_size=(130, 140)) generated1 = self.layer - self.layer_bool mapping = {generated1: self.layer} elems = i3.get_elements_for_generated_layers(elems, mapping) return elems
class label(i3.PCell): _name_prefix = "label" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.HFW) # layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position x = 6200 y = 8000 Height = 300 elems += i3.PolygonText(layer=self.layer, text="1N", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0, y0)) ) elems += i3.PolygonText(layer=self.layer, text="5J", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 1 * x, y0 + 1 * y+700)) ) elems += i3.PolygonText(layer=self.layer, text="4W", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 0 * x, y0 + 1 * y)) ) elems += i3.PolygonText(layer=self.layer, text="2E", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 1 * x, y0 + 0 * y+1100)) ) elems += i3.PolygonText(layer=self.layer, text="3W", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 2 * x, y0 + 0 * y)) ) elems += i3.PolygonText(layer=self.layer, text="6E", # coordinate=(1300.0, 100.0), # alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=Height, transformation=i3.Translation((x0 + 2 * x, y0 + 1 * y)) ) return elems
class Layout(AutoPlaceAndConnect.Layout): metal1_layer = i3.LayerProperty( doc="layer used for the electrical links") metal1_width = i3.PositiveNumberProperty( default=5, doc="Width of the metal1 paths") electrical_routes = i3.ListProperty( doc= "routes used for the electical connections. Is has the same length as electical links. None will use Routemanhatan" ) def _default_metal1_layer(self): return i3.TECH.PPLAYER.M1.LINE def _default_electrical_routes(self): return [None] * len(self.electrical_links) @i3.cache() def _get_final_electrical_routes(self): final_routes = [] for c, r in zip(self.electrical_links, self.electrical_routes): if r is None: inst1, port1 = self._resolve_inst_port(c[0]) inst2, port2 = self._resolve_inst_port(c[1]) route = i3.RouteManhattan(input_port=port1, output_port=port2, angle_out=0.0, angle_in=0.0, rounding_algorithm=None) final_routes.append(route) else: final_routes.append(r) return final_routes @i3.cache() def _get_electrical_route_elements(self): els = [] for r in self._get_final_electrical_routes(): els += i3.Path(layer=self.metal1_layer, shape=r, line_width=self.metal1_width) return els def _generate_elements(self, elems): elems = super(APAC.Layout, self)._generate_elements(elems) elems.extend(self._get_electrical_route_elements()) return elems def _generate_ports(self, ports): connected_links = [p[0].replace(':', '_') for p in self.links] + [ p[1].replace(':', '_') for p in self.links ] connected_links.extend( [p[0].replace(':', '_') for p in self.connectors] + [p[1].replace(':', '_') for p in self.connectors]) for key, val in self._get_child_cell_instances().iteritems(): if key in self.child_cells.keys(): for p in val.ports: name = "{}_{}".format(key, p.name) if name not in connected_links: ext_key = '{}:{}'.format(key, p.name) if ext_key in self.cell.external_port_names: name = self.cell.external_port_names[ext_key] if p.domain is i3.ElectricalDomain and name not in self.propagated_electrical_ports: pass else: ports.append(p.modified_copy(name=name)) return ports
class Heater(i3.PCell): _name_prefix = "Heater" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(default=i3.TECH.PPLAYER.N.LINE) layer_bool = i3.LayerProperty(default=i3.TECH.PPLAYER.NONE.DOC) layer2 = i3.LayerProperty(default=i3.TECH.PPLAYER.FC.TRENCH) layer3 = i3.LayerProperty(default=i3.TECH.PPLAYER.FC.HOLE) # Mesa parameters length = i3.PositiveNumberProperty(default=180.0) width = i3.PositiveNumberProperty(default=150.0) class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position elems += i3.Rectangle(layer=self.layer, center=(6250, -500), box_size=(500, 500)) elems += i3.Rectangle(layer=self.layer, center=(6250, 1000), box_size=(500, 500)) elems += i3.Rectangle(layer=self.layer2, center=(9950, 1000), box_size=(4100, self.width)) # heaters elems += i3.Rectangle(layer=self.layer3, center=(9950, 1000), box_size=(3900, self.width+20)) # heaters during plating elems += i3.Rectangle(layer=self.layer, center=(9950 - 4100 / 2+50, 1000), box_size=(100, self.width)) # heaters butt left elems += i3.Rectangle(layer=self.layer, center=(9950 + 4100 / 2 - 50, 1000), box_size=(100, self.width)) # heaters butt right elems += i3.Rectangle(layer=self.layer, center=(9950 - 4100 / 2 + 50-750, 1000), box_size=(1400, 100)) # left elems += i3.Rectangle(layer=self.layer, center=(9950 - 4100 / 2 + 50 - 750-450, -500), box_size=(500, 100)) elems += i3.Rectangle(layer=self.layer, center=(9950 + 4100 / 2 - 50, 1000 - (500+self.width) / 2), box_size=(100, 500)) elems += i3.Rectangle(layer=self.layer, center=(9450, 1000-self.width/2-450), box_size=(4900, 100)) elems += i3.Rectangle(layer=self.layer, center=(5050 + 4100 / 2 - 50, -550+(1000-self.width/2+50)/2), box_size=(100, 1000-self.width/2+50)) elems += i3.PolygonText(layer=i3.TECH.PPLAYER.WG.TEXT, text="width_{}".format(self.width), # coordinate=(1300.0, 100.0), alignment=(i3.TEXT_ALIGN_LEFT, i3.TEXT_ALIGN_LEFT), font=2, height=400.0, transformation=i3.Translation((8000, 0)) ) return elems
class Layout(DropRingAtWavelength.Layout): layer_heater = i3.LayerProperty() angle_gap = i3.AngleProperty(default=90.0) width_m1 = i3.AngleProperty(default=4.0) def _default_layer_heater(self): return i3.TECH.PPLAYER.M1.LINE def _generate_elements(self, elems): elems = super(DropRingAtWavelength.Layout, self)._generate_elements(elems) r = self.directional_coupler.bend_radius dcl = self.directional_coupler.coupler_length # Metal 1 ring_s = i3.RingSegment(layer=self.layer_heater, center=(-dcl / 2.0, r), angle_start=180, angle_end=270, inner_radius=r - self.width_m1 / 2.0, outer_radius=r + self.width_m1 / 2.0) elems += ring_s trans = [ i3.HMirror(), i3.VMirror(mirror_plane_y=self._get_distance_between_dc() / 2.0) ] trans.append(trans[0] + trans[1]) for t in trans: elems += ring_s.transform_copy(t) straights = i3.Path(layer=self.layer_heater, shape=[(-r - dcl / 2.0, r), (-r - dcl / 2.0, self._get_distance_between_dc() - r)], line_width=self.width_m1) elems += straights elems += straights.transform_copy(trans[0]) top = i3.Path(layer=self.layer_heater, shape=[(-dcl / 2.0, self._get_distance_between_dc()), (dcl / 2.0, self._get_distance_between_dc())], line_width=self.width_m1) elems += top return elems def _generate_ports(self, ports): ports = super(DropRingAtWavelength.Layout, self)._generate_ports(ports) port_loc = i3.Coord2( (-self.directional_coupler.coupler_length / 2.0 - self.width_m1 / 2.0, 0.0)) pin = i3.ElectricalPort(process=self.layer_heater.process, name="el_in", position=port_loc) ports += pin ports += pin.transform_copy( transformation=i3.HMirror()).modified_copy(name="el_out") return ports
class Obstacle_BooleanBoundary(i3.PCell): layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CH1.TRENCH, doc='Layer to drawn on') # Properties of trap channel_trap_width = i3.PositiveNumberProperty(default=50., doc="width of trap") obstacle_trap_width = i3.PositiveNumberProperty(default=25., doc="width of obstacle") obstacle_trap_length = i3.PositiveNumberProperty(default=30., doc="length of trap") gap_btw_barriers = i3.PositiveNumberProperty(default=20., doc="gap between obstacles") cInp = i3.Coord2Property(default = (0.0,0.0),required = True) class Layout(i3.LayoutView): 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 #Thach added to define one inlet and one outlet def _generate_ports(self, ports): # Use _generate_ports method to define ports #ports += i3.InFluidicPort(name = "in", position = (0., 10.), angle = 180.0) ports += i3.OpticalPort(name = "in", position = (0., self.channel_trap_width*0.5), angle = 180.0) #ports += i3.OutFluidicPort(name ="out", position = (30., 10.), angle = 0.0) ports += i3.OpticalPort(name ="out", position = ((self.obstacle_trap_length+self.gap_btw_barriers)*2, self.channel_trap_width*0.5), angle = 0.0) return ports
class AlignmentMarker(i3.PCell): _name_prefix = "ALIGNMENT MARKER" # Center of the structure position = i3.Coord2Property(default=(0.0, 0.0)) # Layer layer = i3.LayerProperty(required=True) # Complement complement = i3.BoolProperty(default=False) # Protection protection = i3.BoolProperty(default=False) # Marker parameters cross_length = i3.PositiveNumberProperty(default=150.0) cross_width = i3.PositiveNumberProperty(default=16.0) cross_margin = i3.PositiveNumberProperty(default=4.0) vernier_length = i3.PositiveNumberProperty(default=30.0) vernier_width = i3.PositiveNumberProperty(default=8.0) vernier_period = i3.PositiveNumberProperty(default=20.25) vernier_left_center = i3.Coord2Property(default=(-121.0, 24.0)) vernier_top_center = i3.Coord2Property(default=(-6.0, 119.0)) vernier_complement_length = i3.PositiveNumberProperty(default=18.0) vernier_complement_long_length = i3.PositiveNumberProperty(default=28.0) vernier_complement_width = i3.PositiveNumberProperty(default=10.0) vernier_complement_shift = i3.PositiveNumberProperty(default=9.0) vernier_complement_period = i3.PositiveNumberProperty(default=20) protection_length = i3.PositiveNumberProperty(default=300.0) protection_width = i3.PositiveNumberProperty(default=320.0) # Layer text layer_text = i3.StringProperty(default="Mesa") class Layout(i3.LayoutView): def _generate_elements(self, elems): # Center of the structure (x0, y0) = self.position shift = 0.5 * self.cross_width + self.cross_margin square_length = 0.5 * self.cross_length - shift if (self.complement == False and self.protection == False): # Add cross elems += i3.Rectangle(layer=self.layer, center=(x0, y0), box_size=(self.cross_length, self.cross_width)) elems += i3.Rectangle(layer=self.layer, center=(x0, y0), box_size=(self.cross_width, self.cross_length)) # Add rectangles left VERNIER elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1]), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] + self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] + 2.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] + 3.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] + 4.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] - self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] - 2.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] - 3.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_left_center[0], self.vernier_left_center[1] - 4.0 * self.vernier_period), box_size=(self.vernier_length, self.vernier_width)) # Add rectangles top VERNIER elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0], self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] + 2.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] + 3.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] + 4.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] - 2.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] - 3.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) elems += i3.Rectangle(layer=self.layer, center=(self.vernier_top_center[0] - 4.0 * self.vernier_period, self.vernier_top_center[1]), box_size=(self.vernier_width, self.vernier_length)) # Add TEXT elems += i3.PolygonText(layer=self.layer, coordinate=(x0, y0 - 100.0), text=self.layer_text, height=35.0) elif (self.complement == True and self.protection == False): # Add squares elems += i3.Rectangle( layer=self.layer, center=(x0 - 0.25 * self.cross_length - 0.5 * shift, y0 + 0.25 * self.cross_length + 0.5 * shift), box_size=(square_length, square_length)) elems += i3.Rectangle( layer=self.layer, center=(x0 + 0.25 * self.cross_length + 0.5 * shift, y0 + 0.25 * self.cross_length + 0.5 * shift), box_size=(square_length, square_length)) elems += i3.Rectangle( layer=self.layer, center=(x0 - 0.25 * self.cross_length - 0.5 * shift, y0 - 0.25 * self.cross_length - 0.5 * shift), box_size=(square_length, square_length)) elems += i3.Rectangle( layer=self.layer, center=(x0 + 0.25 * self.cross_length + 0.5 * shift, y0 - 0.25 * self.cross_length - 0.5 * shift), box_size=(square_length, square_length)) # Add rectangles left VERNIER elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_long_length, self.vernier_left_center[1]), box_size=(self.vernier_complement_long_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_long_length, self.vernier_left_center[1]), box_size=(self.vernier_complement_long_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 2.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 2.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 3.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 3.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 4.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] + 4.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 2.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 2.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 3.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 3.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 4.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_left_center[0] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length, self.vernier_left_center[1] - 4.0 * self.vernier_complement_period), box_size=(self.vernier_complement_length, self.vernier_complement_width)) # Add rectangles top VERNIER elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0], self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_long_length), box_size=(self.vernier_complement_width, self.vernier_complement_long_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0], self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_long_length), box_size=(self.vernier_complement_width, self.vernier_complement_long_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 2.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 2.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 3.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 3.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 4.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] + 4.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 2.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 2.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 3.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 3.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 4.0 * self.vernier_complement_period, self.vernier_top_center[1] - self.vernier_complement_shift - 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) elems += i3.Rectangle( layer=self.layer, center=(self.vernier_top_center[0] - 4.0 * self.vernier_complement_period, self.vernier_top_center[1] + self.vernier_complement_shift + 0.5 * self.vernier_complement_length), box_size=(self.vernier_complement_width, self.vernier_complement_length)) else: elems += i3.Rectangle(layer=self.layer, center=(x0 - 43.5, y0 + 11.5), box_size=(self.protection_length, self.protection_width)) return elems
class Vacuum_BooleanBoundary(i3.PCell): layer = i3.LayerProperty(default=i3.TECH.PPLAYER.CH1.TRENCH, doc='Layer to drawn on') # Properties of vacuum feature_width = i3.PositiveNumberProperty(default=50., doc="width of trap") feature_height = i3.PositiveNumberProperty(default=50., doc="width of trap") gap_horiz = i3.PositiveNumberProperty(default=30., doc="width of obstacle") gap_vertical = i3.PositiveNumberProperty(default=30., doc="length of trap") vacuum_width = i3.PositiveNumberProperty(default=20., doc="gap between obstacles") cInp = i3.Coord2Property(default=(0.0, 0.0), required=True) class Layout(i3.LayoutView): def _generate_instances(self, insts): # First create shapes # Break the block containig the feature into two segments # Block need to intersect these two segments # Feature 1. Segment 1:2 #define points will be helpful to make schematic p1 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (-0.5), 0.0) p2 = (self.cInp.x + 0.0, self.cInp.y + 0.0) p3 = (self.cInp.x, self.feature_height * 0.5 + self.vacuum_width) p4 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (-0.5), self.feature_height * 0.5 + self.vacuum_width) p5 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (0.5), 0.0) p6 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (0.5), self.feature_height * 0.5 + self.vacuum_width) p7 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (-0.5), -(self.feature_height * 0.5 + self.vacuum_width)) p8 = (self.cInp.x, -(self.feature_height * 0.5 + self.vacuum_width)) p9 = ((self.feature_width + self.gap_horiz + self.vacuum_width) * (0.5), -(self.feature_height * 0.5 + self.vacuum_width)) sr1 = i3.Shape(points=[p1, p2, p3, p4], closed=True) sr2 = i3.Shape(points=[p2, p5, p6, p3], closed=True) sr3 = i3.Shape(points=[p7, p8, p2, p1], closed=True) sr4 = i3.Shape(points=[p8, p9, p5, p2], closed=True) #Internal holes as Circles #It is needed to 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.cInp.y), box_size=(self.feature_width + self.gap_horiz, self.feature_height + self.gap_vertical)) #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) br4 = i3.Boundary(layer=self.layer, shape=sr4) 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) b_sub = br2 - bc1 b_sub = b_sub[0] - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) b_sub = br3 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) b_sub = br4 - bc1 s = i3.Structure(elements=b_sub) insts += i3.SRef(s) return insts #Thach added to define one inlet and one outlet def _generate_ports( self, ports): # Use _generate_ports method to define ports ''' #ports += i3.InFluidicPort(name = "in", position = (0., 10.), angle = 180.0) ports += i3.OpticalPort(name = "in", position = (0., self.channel_trap_width*0.5), angle = 180.0) #ports += i3.OutFluidicPort(name ="out", position = (30., 10.), angle = 0.0) ports += i3.OpticalPort(name ="out", position = ((self.obstacle_trap_length+self.gap_btw_barriers)*2, self.channel_trap_width*0.5), angle = 0.0) ''' return ports