Example #1
0
 def init_primitives( self ):
     Z0 = CPW( self.bl_vert.width, self.bl_vert.gap, DPoint(0,0), DPoint(0,0) )
     Z1 = CPW( self.bl_hor.width, self.bl_hor.gap, DPoint(0,0), DPoint(0,0) )
     self.tj_BL = TJunction_112( Z0,Z1, DPoint(0,0) + DPoint(0,Z0.b), Trans( Trans.M0 ) )
     self.bl_buttom = self.bl_hor.__class__( Z1, self.tj_BL.connections[2], self.bl_hor.params, trans_in=Trans(Trans.M0) )
     self.tj_BR = TJunction_112( Z0,Z1, self.bl_buttom.end + DPoint( Z0.b, Z1.b/2 ), Trans( Trans.R180 ) )
     self.bl_left = self.bl_vert.__class__( Z0, self.tj_BL.connections[1], self.bl_vert.params, trans_in=Trans(Trans.R90) )
     self.tj_TL = TJunction_112( Z0,Z1, self.bl_left.end + DPoint( -Z0.b/2,0 ) )
     self.bl_top = self.bl_hor.__class__( Z1, self.tj_TL.connections[2], self.bl_hor.params )
     self.tj_TR = TJunction_112( Z0,Z1, self.bl_top.end + DPoint( Z0.b,-Z1.b/2), Trans( Trans.R180*Trans.M0 ) )
     self.bl_right = self.bl_vert.__class__( Z0, self.tj_TR.connections[1], self.bl_vert.params, trans_in=Trans(Trans.R270) )
     self.primitives = {"tj_BL":self.tj_BL,"bl_buttom":self.bl_buttom,"tj_BR":self.tj_BR,"bl_left":self.bl_left,
                             "tj_TL":self.tj_TL,"bl_top":self.bl_top,"tj_TR":self.tj_TR,"bl_right":self.bl_right}
 def __init__(self, origin, trans_in=None):
     ## MUST BE IMPLEMENTED ##
     self.connections = []       # DPoint list with possible connection points
     self.angle_connections = [] #list with angle of connecting elements
     self.connection_ptrs = [] # pointers to connected structures represented by their class instances
     ## MUST BE IMLPEMENTED END ##
     self.origin = origin
     self.metal_region = Region()
     self.empty_region = Region()
     self.metal_regions = {}
     self.empty_regions = {}        
     self.metal_regions["default"] = self.metal_region
     self.empty_regions["default"] = self.empty_region
     
     self.metal_region.merged_semantics = False
     self.empty_region.merged_semantics = False
     self.DCplxTrans_init = None
     self.ICplxTrans_init = None
     
     if( trans_in is not None ):
     # if( isinstance( trans_in, ICplxTrans ) ): <==== FORBIDDEN
         if( isinstance( trans_in, DCplxTrans ) ):
             self.DCplxTrans_init = trans_in
             self.ICplxTrans_init = ICplxTrans().from_dtrans( trans_in )
         elif( isinstance( trans_in, CplxTrans ) ):
             self.DCplxTrans_init = DCplxTrans().from_itrans( trans_in )
             self.ICplxTrans_init = ICplxTrans().from_trans( trans_in )
         elif( isinstance( trans_in, DTrans ) ):
             self.DCplxTrans_init = DCplxTrans( trans_in, 1 )
             self.ICplxTrans_init = ICplxTrans( Trans().from_dtrans( trans_in ), 1 )
         elif( isinstance( trans_in, Trans ) ):
             self.DCplxTrans_init = DCplxTrans( DTrans().from_itrans( trans_in ), 1 )
             self.ICplxTrans_init = ICplxTrans( trans_in, 1 )
             
     self._init_regions_trans()
Example #3
0
    def __init__(self, origin, trans_in=None, inverse=False):
        ## MUST BE IMPLEMENTED ##
        self.connections = []  # DPoint list with possible connection points
        self.connection_edges = [
        ]  # indexes of edges that are intended to connect to other polygons
        # indexes in "self.connection_edges" where Sonnet ports
        # should be placed
        self.sonnet_port_connections = []
        self.angle_connections = []  # list with angle of connecting elements
        ## MUST BE IMLPEMENTED END ##

        self.connection_ptrs = [
        ]  # pointers to connected structures represented by their class instances

        self.origin = origin
        self.inverse = inverse
        # TODO: after Region.insert() and/or? metal_region + other_region
        #  there is width problem that initial region has dimensions
        #  Region().bbox() = ((-1,-1,1,1)) or something like that
        #  Hence, if you wish to take Region.bbox() of the resulting region
        #  You will get incorrect value due to initial region having
        #  something "blank" at the creation moment. This may be solved
        #  by either shrinking resulting region to shapes it contains,
        #  or by refusing of usage of empty `Region()`s
        self.metal_region = Region()
        self.empty_region = Region()
        self.metal_regions = OrderedDict()
        self.empty_regions = OrderedDict()
        self.metal_regions["default"] = self.metal_region
        self.empty_regions["default"] = self.empty_region

        self.metal_region.merged_semantics = True
        self.empty_region.merged_semantics = True
        self.DCplxTrans_init = None
        self.ICplxTrans_init = None

        if (trans_in is not None):
            # TODO: update with Klayouts new rules.
            # if( isinstance( trans_in, ICplxTrans ) ): <==== FORBIDDEN
            if (isinstance(trans_in, DCplxTrans)):
                self.DCplxTrans_init = trans_in
                self.ICplxTrans_init = ICplxTrans().from_dtrans(trans_in)
            elif (isinstance(trans_in, CplxTrans)):
                self.DCplxTrans_init = DCplxTrans().from_itrans(trans_in)
                self.ICplxTrans_init = ICplxTrans().from_trans(trans_in)
            elif (isinstance(trans_in, DTrans)):
                self.DCplxTrans_init = DCplxTrans(trans_in, 1)
                self.ICplxTrans_init = ICplxTrans(
                    Trans().from_dtrans(trans_in), 1)
            elif (isinstance(trans_in, Trans)):
                self.DCplxTrans_init = DCplxTrans(
                    DTrans().from_itrans(trans_in), 1)
                self.ICplxTrans_init = ICplxTrans(trans_in, 1)
            elif (isinstance(trans_in, ICplxTrans)):
                # not tested 14.08.2021
                self.DCplxTrans_init = DCplxTrans(trans_in)
                self.ICplxTrans_init = trans_in
        self._geometry_parameters = OrderedDict()
        self._init_regions_trans()
Example #4
0
    def __init__(self, origin, trans_in=None, inverse=False):
        ## MUST BE IMPLEMENTED ##
        self.connections = []  # DPoint list with possible connection points
        self.connection_edges = [
        ]  # indexes of edges that are intended to connect to other polygons
        # indexes in "self.connection_edges" where Sonnet ports
        # should be placed
        self.sonnet_port_connections = []
        self.angle_connections = []  # list with angle of connecting elements
        ## MUST BE IMLPEMENTED END ##

        self.connection_ptrs = [
        ]  # pointers to connected structures represented by their class instances

        self.origin = origin
        self.inverse = inverse
        self.metal_region = Region()
        self.empty_region = Region()
        self.metal_regions = OrderedDict()
        self.empty_regions = OrderedDict()
        self.metal_regions["default"] = self.metal_region
        self.empty_regions["default"] = self.empty_region

        self.metal_region.merged_semantics = True
        self.empty_region.merged_semantics = True
        self.DCplxTrans_init = None
        self.ICplxTrans_init = None

        if (trans_in is not None):
            # if( isinstance( trans_in, ICplxTrans ) ): <==== FORBIDDEN
            if (isinstance(trans_in, DCplxTrans)):
                self.DCplxTrans_init = trans_in
                self.ICplxTrans_init = ICplxTrans().from_dtrans(trans_in)
            elif (isinstance(trans_in, CplxTrans)):
                self.DCplxTrans_init = DCplxTrans().from_itrans(trans_in)
                self.ICplxTrans_init = ICplxTrans().from_trans(trans_in)
            elif (isinstance(trans_in, DTrans)):
                self.DCplxTrans_init = DCplxTrans(trans_in, 1)
                self.ICplxTrans_init = ICplxTrans(
                    Trans().from_dtrans(trans_in), 1)
            elif (isinstance(trans_in, Trans)):
                self.DCplxTrans_init = DCplxTrans(
                    DTrans().from_itrans(trans_in), 1)
                self.ICplxTrans_init = ICplxTrans(trans_in, 1)
        self._geometry_parameters = OrderedDict()
        self._init_regions_trans()
Example #5
0
    def init_primitives(self):
        self.connections = [DPoint(0, 0), self.dr]
        self.angle_connections = [0, 0]

        self.coplanar1 = CPW(self.width, self.gap, DPoint(0, 0),
                             DPoint(0, 0) + DPoint(self.L1, 0), self.gndWidth)
        self.arc1 = CPWArc(self.coplanar1, self.coplanar1.end, self.R1,
                           self.gamma, self.gndWidth, Trans(Trans.M0))
        self.coplanar2 = CPW(
            self.width, self.gap, self.arc1.end, self.arc1.end +
            DPoint(cos(self.gamma), -sin(self.gamma)) * self.L2, self.gndWidth)
        self.arc2 = CPWArc(self.coplanar1, self.coplanar2.end, self.R2,
                           self.gamma, self.gndWidth,
                           DCplxTrans(1, -self.gamma * 180 / pi, False, 0, 0))
        self.coplanar3 = CPW(self.width, self.gap, self.arc2.end,
                             self.arc2.end + DPoint(L3, 0), self.gndWidth)
        self.arc3 = CPWArc(self.coplanar1, self.coplanar3.end, self.R2,
                           self.gamma, self.gndWidth)
        self.coplanar4 = CPW(
            self.width, self.gap, self.arc3.end,
            self.arc3.end + DPoint(cos(self.gamma), sin(self.gamma)) * self.L2,
            self.gndWidth)
        self.arc4 = CPWArc(self.coplanar1, self.coplanar4.end, self.R1,
                           self.gamma, self.gndWidth,
                           DCplxTrans(1, self.gamma * 180 / pi, True, 0, 0))
        self.coplanar5 = CPW(self.width, self.gap, self.arc4.end,
                             self.arc4.end + DPoint(self.L1, 0), self.gndWidth)
        self.primitives = {
            "coplanar1": self.coplanar1,
            "arc1": self.arc1,
            "coplanar2": self.coplanar2,
            "arc2": self.arc2,
            "coplanar3": self.coplanar3,
            "arc3": self.arc3,
            "coplanar4": self.coplanar4,
            "arc4": self.arc4,
            "coplanar5": self.coplanar5
        }
Example #6
0
def layout_waveguide2(TECHNOLOGY, layout, cell, layers, widths, offsets, pts, radius, adiab, bezier):
  '''
    Create a waveguide, in a specific technology
    inputs
    - TECHNOLOGY, layout, cell:
        from SiEPIC.utils import get_layout_variables
        TECHNOLOGY, lv, layout, cell = get_layout_variables()
    - layers: list of text names, e.g., ['Waveguide']
    - widths: list of floats in units Microns, e.g., [0.50]
    - offsets: list of floats in units Microns, e.g., [0]
    - pts: a list of pya.Points, e.g. 
        L=15/dbu
        pts = [Point(0,0), Point(L,0), Point(L,L)]
    - radius: in Microns, e.g., 5
    - adiab: 1 = Bezier curve, 0 = radial bend (arc)
    - bezier: the bezier parameter, between 0 and 0.45 (almost a radial bend)

    Note: bezier parameters need to be simulated and optimized, and will depend on 
        wavelength, polarization, width, etc.  TM and rib waveguides don't benefit from bezier curves
        most useful for TE 
  '''
  from SiEPIC.utils import arc_xy, arc_bezier, angle_vector, angle_b_vectors, inner_angle_b_vectors, translate_from_normal
  from SiEPIC.extend import to_itype
  from pya import Path, Polygon, Trans
  dbu = layout.dbu

  width=widths[0]
  turn=0
  waveguide_length = 0
  for lr in range(0, len(layers)):
    wg_pts = [pts[0]]
    layer = layout.layer(TECHNOLOGY[layers[lr]])
    width = to_itype(widths[lr],dbu)
    offset = to_itype(offsets[lr],dbu)
    for i in range(1,len(pts)-1):
      turn = ((angle_b_vectors(pts[i]-pts[i-1],pts[i+1]-pts[i])+90)%360-90)/90
      dis1 = pts[i].distance(pts[i-1])
      dis2 = pts[i].distance(pts[i+1])
      angle = angle_vector(pts[i]-pts[i-1])/90
      pt_radius = to_itype(radius,dbu)
      # determine the radius, based on how much space is available
      if len(pts)==3:
        pt_radius = min (dis1, dis2, pt_radius)
      else:
        if i==1:
          if dis1 <= pt_radius:
            pt_radius = dis1
        elif dis1 < 2*pt_radius:
          pt_radius = dis1/2
        if i==len(pts)-2:
          if dis2 <= pt_radius:
            pt_radius = dis2
        elif dis2 < 2*pt_radius:
          pt_radius = dis2/2
      # waveguide bends:
      if abs(turn)==1:
        if(adiab):
          wg_pts += Path(arc_bezier(pt_radius, 270, 270 + inner_angle_b_vectors(pts[i-1]-pts[i], pts[i+1]-pts[i]), bezier, DevRec='DevRec' in layers[lr]), 0).transformed(Trans(angle, turn < 0, pts[i])).get_points()
        else:
          wg_pts += Path(arc_xy(-pt_radius, pt_radius, pt_radius, 270, 270 + inner_angle_b_vectors(pts[i-1]-pts[i], pts[i+1]-pts[i]),DevRec='DevRec' in layers[lr]), 0).transformed(Trans(angle, turn < 0, pts[i])).get_points()
        
    wg_pts += [pts[-1]]
    wg_pts = pya.Path(wg_pts, 0).unique_points().get_points()
    wg_polygon = Polygon(translate_from_normal(wg_pts, width/2 + (offset if turn > 0 else - offset))+translate_from_normal(wg_pts, -width/2 + (offset if turn > 0 else - offset))[::-1])
    cell.shapes(layer).insert(wg_polygon)
  
    if layout.layer(TECHNOLOGY['Waveguide']) == layer:
      waveguide_length = wg_polygon.area() / width * dbu
  return waveguide_length
Example #7
0
		empties.append( empty )

		qbit.place( cell, layer_photo, layer_el )
		qbits.append(qbit)

	# place top array of resonators with qBits
	N_top = N_bottom - 1
	delta = 1e6
	step_top = step_bot
	resonators = []
	qbits = []
	empties = []
	for i in range( N_top ):
		point = DPoint( contact_L + delta + step_bot/2 + i*step_top, CHIP.dy/2 + (Z0.width + Z_res.width)/2 + toLine )

		worm = EMResonator_TL2Qbit_worm( Z_res, point, L_coupling[i + N_bottom], L1[i + N_bottom], r, L2, N, Trans( Trans.M0 ) )
		worm.place( cell, layer_photo )
		resonators.append( worm )

		qbit_params = [a[i+N_bottom],b[i+N_bottom],
					   jos1_b,jos1_a,f1,d1,
					   jos2_b,jos2_a,f2,d2,
					   w, dCap,gap, square_a, dSquares, alum_over, B1_width]
		dy_qbit = -(worm.cop_tail.dr.abs() - square_a)/2 - square_a
		qbit_start = worm.end + DPoint( B1_width/2,0 )
		qbit = QBit_Flux_Сshunted_3JJ( worm.end + DPoint( qbit_coupling_gap + Z_res.width/2, dy_qbit ) , qbit_params, DCplxTrans( 1,90,False,0,0 ) )
		qbit_bbox = pya.DBox().from_ibox( qbit.metal_regions["photo"].bbox() )
		p1 = qbit.origin + DPoint(-qbit_coupling_gap,qbit.square_a/2)
		p2 = p1 + DPoint( qbit_bbox.width() + qbit_coupling_gap + qbit_gnd_gap, 0 )
		empty = CPW( 0, (square_a + 2*qbit_gnd_gap)/2, p1, p2 )
		empty.place( cell, layer_photo )
Example #8
0
def layout_waveguide2(TECHNOLOGY, layout, cell, layers, widths, offsets, pts,
                      radius, adiab, bezier):
    from SiEPIC.utils import arc_xy, arc_bezier, angle_vector, angle_b_vectors, inner_angle_b_vectors, translate_from_normal
    from SiEPIC.extend import to_itype
    from pya import Path, Polygon, Trans
    dbu = layout.dbu

    width = widths[0]
    turn = 0
    waveguide_length = 0
    for lr in range(0, len(layers)):
        wg_pts = [pts[0]]
        layer = layout.layer(TECHNOLOGY[layers[lr]])
        width = to_itype(widths[lr], dbu)
        offset = to_itype(offsets[lr], dbu)
        for i in range(1, len(pts) - 1):
            turn = (
                (angle_b_vectors(pts[i] - pts[i - 1], pts[i + 1] - pts[i]) +
                 90) % 360 - 90) / 90
            dis1 = pts[i].distance(pts[i - 1])
            dis2 = pts[i].distance(pts[i + 1])
            angle = angle_vector(pts[i] - pts[i - 1]) / 90
            pt_radius = to_itype(radius, dbu)
            # determine the radius, based on how much space is available
            if len(pts) == 3:
                pt_radius = min(dis1, dis2, pt_radius)
            else:
                if i == 1:
                    if dis1 <= pt_radius:
                        pt_radius = dis1
                elif dis1 < 2 * pt_radius:
                    pt_radius = dis1 / 2
                if i == len(pts) - 2:
                    if dis2 <= pt_radius:
                        pt_radius = dis2
                elif dis2 < 2 * pt_radius:
                    pt_radius = dis2 / 2
            # waveguide bends:
            if abs(turn) == 1:
                if (adiab):
                    wg_pts += Path(
                        arc_bezier(
                            pt_radius,
                            270,
                            270 + inner_angle_b_vectors(
                                pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                            float(bezier),
                            DevRec='DevRec' in layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()
                else:
                    wg_pts += Path(
                        arc_xy(-pt_radius,
                               pt_radius,
                               pt_radius,
                               270,
                               270 + inner_angle_b_vectors(
                                   pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                               DevRec='DevRec' in layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()

        wg_pts += [pts[-1]]
        wg_pts = pya.Path(wg_pts, 0).unique_points().get_points()
        wg_polygon = Polygon(
            translate_from_normal(
                wg_pts, width / 2 + (offset if turn > 0 else -offset)) +
            translate_from_normal(
                wg_pts, -width / 2 + (offset if turn > 0 else -offset))[::-1])
        cell.shapes(layer).insert(wg_polygon)

        if layout.layer(TECHNOLOGY['Waveguide']) == layer:
            waveguide_length = wg_polygon.area() / width * dbu
    return waveguide_length
    qbits = []
    empties = []
    for i in range(N_top):
        point = DPoint(contact_L + delta + step_bot / 2 + i * step_top,
                       CHIP.dy / 2 + Z0.b / 3)
        L_coupling = 100e3
        L1 = 280e3
        r = 50e3
        L2 = 270e3
        N = 4
        width_res = 4.8e3
        gap_res = 2.6e3
        Z_res = CPW(width_res, gap_res, origin, origin)
        worm = EMResonator_TL2Qbit_worm(Z_res, point, L_coupling,
                                        L1_list[i + N_bottom], r, L2, N,
                                        gnd_width, Trans(Trans.M0))
        worm.place(cell, layer_photo)
        resonators.append(worm)

        qbit_params = [
            a_list[N_bottom + i], a_list[N_bottom + i], jos1_b, jos1_a, f1, d1,
            jos2_b, jos2_a, f2, d2, w, B1_width, B1_height, B2_width, B5_width,
            B6_width, B6_height, B7_width, B7_height, dCap, gap
        ]
        qbit_start = worm.end + DPoint(B1_width / 2, 0)
        qbit = QBit_Flux_2(qbit_start, qbit_params,
                           DCplxTrans(1, 180, False, 0, 0))
        qbit.place(cell, layer_el)
        qbits.append(qbit)

        qbit_bbox = pya.DBox().from_ibox(qbit.metal_region.bbox())
Example #10
0
    def init_regions(self):

        self.metal_regions["photo"] = Region()
        self.empty_regions["photo"] = Region()
        self.metal_regions["ebeam"] = Region()
        self.empty_regions["ebeam"] = Region()
        self.metal_regions["patch"] = Region()
        self.empty_regions["patch"] = Region()
        self.metal_regions["litho"] = Region()
        self.empty_regions["litho"] = Region()

        w_frame, g_frame = self._frame_cpw_params.width, self._frame_cpw_params.gap
        l_frame = self._frame_length

        metal_points1 = [
            DPoint(g_frame, g_frame),
            DPoint(g_frame + w_frame, g_frame),
            DPoint(g_frame + w_frame, g_frame + l_frame),
            DPoint(g_frame + w_frame / 2 + 3e3, g_frame + l_frame),
            DPoint(g_frame + w_frame / 2 + 3e3, g_frame + l_frame - 7e3),
            DPoint(g_frame + w_frame / 2 - 3e3, g_frame + l_frame - 7e3),
            DPoint(g_frame + w_frame / 2 - 3e3, g_frame + l_frame),
            DPoint(g_frame, g_frame + l_frame)
        ]
        metal_poly1 = DSimplePolygon(metal_points1)

        self.metal_regions["photo"].insert(metal_poly1)

        metal_points2 = [
            DPoint(g_frame, 2 * g_frame + l_frame),
            DPoint(g_frame + w_frame / 2 - 3e3, 2 * g_frame + l_frame),
            DPoint(g_frame + w_frame / 2 - 3e3, 2 * g_frame + l_frame + 7e3),
            DPoint(g_frame + w_frame / 2 + 3e3, 2 * g_frame + l_frame + 7e3),
            DPoint(g_frame + w_frame / 2 + 3e3, 2 * g_frame + l_frame),
            DPoint(g_frame + w_frame, 2 * g_frame + l_frame),
            DPoint(g_frame + w_frame, 2 * g_frame + 2 * l_frame),
            DPoint(g_frame, 2 * g_frame + 2 * l_frame)
        ]
        metal_poly2 = DSimplePolygon(metal_points2)

        self.metal_regions["photo"].insert(metal_poly2)

        protect_points = [
            DPoint(0, 0),
            DPoint(2 * g_frame + w_frame, 0),
            DPoint(2 * g_frame + w_frame, 3 * g_frame + 2 * l_frame),
            DPoint(0, 3 * g_frame + 2 * l_frame)
        ]

        protect_poly = DSimplePolygon(protect_points)
        protect_region = Region(protect_poly)

        empty_region = protect_region - self.metal_regions["photo"]

        self.empty_regions["photo"].insert(empty_region)

        self.connections = [
            DPoint(0, 0),
            DPoint(g_frame + 0.5 * w_frame, 1.5 * g_frame + l_frame)
        ]

        if not self._use_cell:

            squid = SQUIDManhattan(self.connections[1],
                                   self._w_JJ, self._h_JJ, \
                                   self._asymmetry, 180, self._JJ_site_span * 1.5, \
                                   squid_width_top=6.2e3, squid_width_bottom=4e3)

            if self._first_jj and self._second_jj:
                squid_metal = squid.metal_region
                self.metal_regions["ebeam"].insert(squid_metal)
            elif self._first_jj:
                rec = [
                    self.connections[1] + DPoint(0, -self._JJ_site_span / 2),
                    self.connections[1] +
                    DPoint(self._JJ_site_span / 2, -self._JJ_site_span / 2),
                    self.connections[1] +
                    DPoint(self._JJ_site_span / 2, self._JJ_site_span / 2),
                    self.connections[1] + DPoint(0, self._JJ_site_span / 2),
                ]
                self.metal_regions["ebeam"].insert(squid.metal_region)
                self.empty_regions["ebeam"].insert(Region(DSimplePolygon(rec)))
            elif self._second_jj:
                rec = [
                    self.connections[1] + DPoint(0, -self._JJ_site_span / 2),
                    self.connections[1] +
                    DPoint(-self._JJ_site_span / 2, -self._JJ_site_span / 2),
                    self.connections[1] +
                    DPoint(-self._JJ_site_span / 2, self._JJ_site_span / 2),
                    self.connections[1] + DPoint(0, self._JJ_site_span / 2),
                ]
                self.metal_regions["ebeam"].insert(squid.metal_region)
                self.empty_regions["ebeam"].insert(Region(DSimplePolygon(rec)))

        else:
            squid = SQUIDManhattan(DPoint(0, 0),
                                   self._w_JJ, self._h_JJ, \
                                   self._asymmetry, 180, self._JJ_site_span * 1.5, \
                                   squid_width_top=6.2e3, squid_width_bottom=4e3)

            # instance = Instance()
            # print(squid._cell.cell_index())
            trans = Trans(int(self._origin.x + g_frame + 0.5 * w_frame),
                          int(self._origin.y + 1.5 * g_frame + l_frame))
            arr = CellInstArray(squid._cell.cell_index(), trans)
            # print(arr.size())
            # instance.cell_inst = arr
            app = pya.Application.instance()
            cur_cell = app.main_window().current_view().active_cellview().cell
            cur_cell.insert(arr)

        rec1_points = [
            DPoint(g_frame + w_frame / 2 - 4e3, 2 * g_frame + l_frame - 1e3),
            DPoint(g_frame + w_frame / 2 - 4e3, 2 * g_frame + l_frame + 12e3),
            DPoint(g_frame + w_frame / 2 + 4e3, 2 * g_frame + l_frame + 12e3),
            DPoint(g_frame + w_frame / 2 + 4e3, 2 * g_frame + l_frame - 1e3)
        ]
        rec1_poly = DSimplePolygon(rec1_points)
        rec2_points = [
            DPoint(g_frame + w_frame / 2 - 4e3, g_frame + l_frame - 12e3),
            DPoint(g_frame + w_frame / 2 - 4e3, g_frame + l_frame + 1e3),
            DPoint(g_frame + w_frame / 2 + 4e3, g_frame + l_frame + 1e3),
            DPoint(g_frame + w_frame / 2 + 4e3, g_frame + l_frame - 12e3)
        ]
        rec2_poly = DSimplePolygon(rec2_points)

        self.metal_regions["ebeam"].insert(squid.metal_region)
        self.metal_regions["ebeam"].insert(rec1_poly)
        self.metal_regions["ebeam"].insert(rec2_poly)

        rec1_points = [
            DPoint(g_frame + w_frame / 2 - 6e3, 2 * g_frame + l_frame + 3.5e3),
            DPoint(g_frame + w_frame / 2 - 6e3,
                   2 * g_frame + l_frame + 18.5e3),
            DPoint(g_frame + w_frame / 2 + 6e3,
                   2 * g_frame + l_frame + 18.5e3),
            DPoint(g_frame + w_frame / 2 + 6e3, 2 * g_frame + l_frame + 3.5e3)
        ]
        rec2_points = [
            DPoint(g_frame + w_frame / 2 - 6e3, g_frame + l_frame - 18.5e3),
            DPoint(g_frame + w_frame / 2 - 6e3, g_frame + l_frame - 3.5e3),
            DPoint(g_frame + w_frame / 2 + 6e3, g_frame + l_frame - 3.5e3),
            DPoint(g_frame + w_frame / 2 + 6e3, g_frame + l_frame - 18.5e3)
        ]
        rec1_poly = DSimplePolygon(rec1_points)
        rec2_poly = DSimplePolygon(rec2_points)
        self.metal_regions["patch"].insert(rec1_poly)
        self.metal_regions["patch"].insert(rec2_poly)

        rec1_points = [
            DPoint(g_frame + w_frame / 2 - 150e3, g_frame + l_frame - 150e3),
            DPoint(g_frame + w_frame / 2 - 150e3, g_frame + l_frame + 150e3),
            DPoint(g_frame + w_frame / 2 + 150e3, g_frame + l_frame + 150e3),
            DPoint(g_frame + w_frame / 2 + 150e3, g_frame + l_frame - 150e3)
        ]
        rec1_poly = DSimplePolygon(rec1_points)
        self.metal_regions["litho"].insert(rec1_poly)
Example #11
0
 def init_primitives( self ):
     self.connections = [DPoint(0,0),self.dr]
     self.angle_connections = [0,0]
     
     self.coplanar1 = CPW( self.width, self.gap, DPoint(0,0), DPoint(0,0) + DPoint(self.L1,0), self.gndWidth )
     self.arc1 = CPW_arc( self.coplanar1, self.coplanar1.end, self.R1, self.gamma1, self.gndWidth, Trans( Trans.M0 ) )        
     self.coplanar2 = CPW( self.width, self.gap, self.arc1.end, self.arc1.end + DPoint( cos(self.gamma1),-sin(self.gamma1) )*self.L2, self.gndWidth )
     self.arc2 = CPW_arc( self.coplanar1, self.coplanar2.end, self.R2, self.gamma1, self.gndWidth, DCplxTrans( 1,-self.gamma1*180/pi,False,0,0 ) )
     self.coplanar3 = CPW( self.width, self.gap, self.arc2.end, self.arc2.end + DPoint( self.L3, 0 ), self.gndWidth )
     self.arc3 = CPW_arc( self.coplanar1, self.coplanar3.end, self.R3, self.gamma2, self.gndWidth )
     self.coplanar4 = CPW( self.width, self.gap, self.arc3.end, self.arc3.end + DPoint( cos(self.gamma2),sin(self.gamma2) )*self.L4, self.gndWidth )
     self.arc4 = CPW_arc( self.coplanar1, self.coplanar4.end, self.R4, self.gamma2, self.gndWidth, DCplxTrans( 1,self.gamma2*180/pi,True,0,0 ) )        
     self.coplanar5 = CPW( self.width, self.gap, self.arc4.end, self.arc4.end + DPoint(self.L5,0), self.gndWidth )
     self.arc5 = CPW_arc( self.coplanar1, self.coplanar5.end, self.R4, self.gamma2, self.gndWidth, Trans( Trans.M0 ) )
     self.coplanar6 = CPW( self.width, self.gap, self.arc5.end, self.arc5.end + DPoint( cos(self.gamma2),-sin(self.gamma2) )*self.L4, self.gndWidth )
     self.arc6 = CPW_arc( self.coplanar1, self.coplanar6.end, self.R3, self.gamma2, self.gndWidth, DCplxTrans( 1,-self.gamma2*180/pi, False,0,0 ) )
     self.coplanar7 = CPW( self.width, self.gap, self.arc6.end, self.arc6.end + DPoint( self.L3,0 ), self.gndWidth )
     self.arc7 = CPW_arc( self.coplanar1, self.coplanar7.end, self.R2, self.gamma1, self.gndWidth )
     self.coplanar8 = CPW( self.width, self.gap, self.arc7.end, self.arc7.end + DPoint( cos(self.gamma1),sin(self.gamma1) )*self.L2, self.gndWidth )
     self.arc8 = CPW_arc( self.coplanar1, self.coplanar8.end, self.R1, self.gamma1, self.gndWidth, DCplxTrans( 1,self.gamma1*180/pi,True,0,0 ) )        
     self.coplanar9 = CPW( self.width, self.gap, self.arc8.end, self.arc8.end + DPoint( self.L1,0 ), self.gndWidth )
     self.primitives = {"coplanar1":self.coplanar1,"coplanar2":self.coplanar2,"coplanar3":self.coplanar3,
                             "coplanar4":self.coplanar4,"coplanar5":self.coplanar5,"coplanar6":self.coplanar6,
                             "coplanar7":self.coplanar7,"coplanar8":self.coplanar8,"coplanar9":self.coplanar9,
                             "arc1":self.arc1,"arc2":self.arc2,"arc3":self.arc3,"arc4":self.arc4,
                             "arc5":self.arc5,"arc6":self.arc6,"arc7":self.arc7,"arc8":self.arc8}
Example #12
0
    def init_regions(self):

        self.metal_regions["photo"] = Region()
        self.empty_regions["photo"] = Region()
        self.metal_regions["ebeam"] = Region()
        self.empty_regions["ebeam"] = Region()

        w_frame, g_frame = self._frame_cpw_params.width, self._frame_cpw_params.gap
        l_frame = self._frame_length

        metal_points1 = [
            DPoint(g_frame, g_frame),
            DPoint(g_frame + w_frame, g_frame),
            DPoint(g_frame + w_frame, g_frame + l_frame),
            DPoint(g_frame, g_frame + l_frame)
        ]
        metal_poly1 = DSimplePolygon(metal_points1)

        self.metal_regions["photo"].insert(metal_poly1)

        metal_points2 = [
            DPoint(g_frame, 2 * g_frame + l_frame),
            DPoint(g_frame + w_frame, 2 * g_frame + l_frame),
            DPoint(g_frame + w_frame, 2 * g_frame + 2 * l_frame),
            DPoint(g_frame, 2 * g_frame + 2 * l_frame)
        ]
        metal_poly2 = DSimplePolygon(metal_points2)

        self.metal_regions["photo"].insert(metal_poly2)

        protect_points = [
            DPoint(0, 0),
            DPoint(2 * g_frame + w_frame, 0),
            DPoint(2 * g_frame + w_frame, 3 * g_frame + 2 * l_frame),
            DPoint(0, 3 * g_frame + 2 * l_frame)
        ]

        protect_poly = DSimplePolygon(protect_points)
        protect_region = Region(protect_poly)

        empty_region = protect_region - self.metal_regions["photo"]

        self.empty_regions["photo"].insert(empty_region)

        self.connections = [
            DPoint(0, 0),
            DPoint(g_frame + 0.5 * w_frame, 1.5 * g_frame + l_frame)
        ]

        if not self._use_cell:

            squid = SQUIDManhattan(self.connections[1],
                                   self._w_JJ, self._h_JJ, \
                                   self._asymmetry, 150, self._JJ_site_span * 1.5, \
                                   squid_width_top=6.2e3, squid_width_bottom=4e3)

            self.metal_regions["ebeam"].insert(squid.metal_region)
        else:
            squid = SQUIDManhattan(DPoint(0, 0),
                                   self._w_JJ, self._h_JJ, \
                                   self._asymmetry, 150, self._JJ_site_span * 1.5, \
                                   squid_width_top=6.2e3, squid_width_bottom=4e3)
            # instance = Instance()
            # print(squid._cell.cell_index())
            trans = Trans(int(self._origin.x + g_frame + 0.5 * w_frame),
                          int(self._origin.y + 1.5 * g_frame + l_frame))
            arr = CellInstArray(squid._cell.cell_index(), trans)
            # print(arr.size())
            # instance.cell_inst = arr
            app = pya.Application.instance()
            cur_cell = app.main_window().current_view().active_cellview().cell
            cur_cell.insert(arr)
Example #13
0
    def init_regions(self):

        self.metal_regions["photo"] = Region()
        self.empty_regions["photo"] = Region()
        self.metal_regions["ebeam"] = Region()
        self.empty_regions["ebeam"] = Region()

        w_tmon, g_tmon = self.tmon_cpw_params.width, self.tmon_cpw_params.gap
        arms_len = self._arms_len
        JJ_arm_len = self._JJ_arm_len
        JJ_site_span = self._JJ_site_span

        coupling_pads_len = self._coupling_pads_len
        h_JJ, w_JJ = self._h_JJ, self._w_JJ
        asymmetry = self._asymmetry

        protect_points = [DPoint(0, 0),
                DPoint(-arms_len+g_tmon, 0),
                DPoint(-arms_len+g_tmon, -coupling_pads_len/2+w_tmon/2),
                DPoint(-arms_len-g_tmon-w_tmon, -coupling_pads_len/2+w_tmon/2),
                DPoint(-arms_len-g_tmon-w_tmon, coupling_pads_len/2+w_tmon/2+2*g_tmon),
                DPoint(-arms_len+g_tmon, coupling_pads_len/2+w_tmon/2+2*g_tmon),
                DPoint(-arms_len+g_tmon, 2*g_tmon+w_tmon),
                DPoint(-w_tmon/2-g_tmon, 2*g_tmon+w_tmon),
                DPoint(-w_tmon/2-g_tmon, g_tmon+w_tmon+JJ_arm_len+JJ_site_span),
                \
                DPoint(w_tmon/2+g_tmon, g_tmon+w_tmon+JJ_arm_len+JJ_site_span),
                DPoint(w_tmon/2+g_tmon, 2*g_tmon+w_tmon),
                DPoint(arms_len-g_tmon, 2*g_tmon+w_tmon),
                DPoint(arms_len-g_tmon, coupling_pads_len/2+w_tmon/2+2*g_tmon),
                DPoint(arms_len+g_tmon+w_tmon, coupling_pads_len/2+w_tmon/2+2*g_tmon),
                DPoint(arms_len+g_tmon+w_tmon, -coupling_pads_len/2+w_tmon/2),
                DPoint(arms_len-g_tmon, -coupling_pads_len/2+w_tmon/2),
                DPoint(arms_len-g_tmon, 0)]

        protect_region = Region(DSimplePolygon(protect_points))

        metal_points = [DPoint(0, g_tmon),
                DPoint(-arms_len, g_tmon),
                DPoint(-arms_len, g_tmon-coupling_pads_len/2+w_tmon/2),
                DPoint(-arms_len-w_tmon, g_tmon-coupling_pads_len/2+w_tmon/2),
                DPoint(-arms_len-w_tmon, g_tmon+coupling_pads_len/2+w_tmon/2),
                DPoint(-arms_len, g_tmon+coupling_pads_len/2+w_tmon/2),
                DPoint(-arms_len, g_tmon+w_tmon),
                DPoint(-w_tmon/2, g_tmon+w_tmon),
                DPoint(-w_tmon/2, g_tmon+w_tmon+JJ_arm_len),
                \
                DPoint(w_tmon/2, g_tmon+w_tmon+JJ_arm_len),
                DPoint(w_tmon/2, g_tmon+w_tmon),
                DPoint(arms_len, g_tmon+w_tmon),
                DPoint(arms_len, g_tmon+coupling_pads_len/2+w_tmon/2),
                DPoint(arms_len+w_tmon, g_tmon+coupling_pads_len/2+w_tmon/2),
                DPoint(arms_len+w_tmon, g_tmon-coupling_pads_len/2+w_tmon/2),
                DPoint(arms_len, g_tmon-coupling_pads_len/2+w_tmon/2),
                DPoint(arms_len, g_tmon)]

        metal_poly = DSimplePolygon(metal_points)
        self.metal_regions["photo"].insert(metal_poly)

        empty_region = protect_region - self.metal_regions["photo"]

        self.empty_regions["photo"].insert(empty_region)

        if not self._use_cell:

            squid = SQUIDManhattan(DPoint(0, g_tmon + w_tmon + JJ_arm_len + JJ_site_span / 2),
                                   self._w_JJ, self._h_JJ, \
                                   self._asymmetry, 150, JJ_site_span * 1.5, \
                                   squid_width_top=6.2e3, squid_width_bottom=4e3)

            self.metal_regions["ebeam"].insert(squid.metal_region)
        else:
            squid = SQUIDManhattan(DPoint(0, 0),
                                   self._w_JJ, self._h_JJ, \
                                   self._asymmetry, 150, JJ_site_span * 1.5, \
                                   squid_width_top=6.2e3, squid_width_bottom=4e3)
            # instance = Instance()
            # print(squid._cell.cell_index())
            trans = Trans(
                int(self._origin.x),
                int(self._origin.y + g_tmon + w_tmon + JJ_arm_len +
                    JJ_site_span / 2))
            arr = CellInstArray(squid._cell.cell_index(), trans)
            # print(arr.size())
            # instance.cell_inst = arr
            app = pya.Application.instance()
            cur_cell = app.main_window().current_view().active_cellview().cell
            cur_cell.insert(arr)

        self.connections = [
            DPoint(0, 0),
            DPoint(0, g_tmon + w_tmon + JJ_arm_len + JJ_site_span)
        ]
Example #14
0
def layout_waveguide4(cell, dpath, waveguide_type, debug=True):

    if debug:
        print('SiEPIC.utils.layout.layout_waveguide4: ')
        print(' - waveguide_type: %s' % (waveguide_type))

    # get the path and clean it up
    layout = cell.layout()
    dbu = layout.dbu
    dpath = dpath.to_itype(dbu)
    dpath.unique_points()
    pts = dpath.get_points()
    dpts = dpath.get_dpoints()

    # Load the technology and all waveguide types
    from SiEPIC.utils import load_Waveguides_by_Tech
    technology_name = layout.technology_name
    waveguide_types = load_Waveguides_by_Tech(technology_name)
    if debug:
        print(' - technology_name: %s' % (technology_name))
        print(' - waveguide_types: %s' % (waveguide_types))

    # Load parameters for the chosen waveguide type
    params = [t for t in waveguide_types if t['name'] == waveguide_type]
    if type(params) == type([]) and len(params) > 0:
        params = params[0]
    else:
        print('error: waveguide type not found in PDK waveguides')
        raise Exception(
            'error: waveguide type (%s) not found in PDK waveguides' %
            waveguide_type)

    # compound waveguide types:
    if 'compound_waveguide' in params:
        # find the singlemode and multimode waveguides:
        if 'singlemode' in params['compound_waveguide']:
            singlemode = params['compound_waveguide']['singlemode']
        else:
            raise Exception(
                'error: waveguide type (%s) does not have singlemode defined' %
                waveguide_type)
        if 'multimode' in params['compound_waveguide']:
            multimode = params['compound_waveguide']['multimode']
        else:
            raise Exception(
                'error: waveguide type (%s) does not have multimode defined' %
                waveguide_type)
        params_singlemode = [
            t for t in waveguide_types if t['name'] == singlemode
        ]
        params_multimode = [
            t for t in waveguide_types if t['name'] == multimode
        ]
        if type(params_singlemode) == type([]) and len(params_singlemode) > 0:
            params_singlemode = params_singlemode[0]
        else:
            raise Exception(
                'error: waveguide type (%s) not found in PDK waveguides' %
                singlemode)
        if type(params_multimode) == type([]) and len(params_multimode) > 0:
            params_multimode = params_multimode[0]
        else:
            raise Exception(
                'error: waveguide type (%s) not found in PDK waveguides' %
                multimode)
        # find the taper
        if 'taper_library' in params[
                'compound_waveguide'] and 'taper_cell' in params[
                    'compound_waveguide']:
            taper = layout.create_cell(
                params['compound_waveguide']['taper_cell'],
                params['compound_waveguide']['taper_library'])
            if not taper:
                raise Exception(
                    'Cannot import cell %s : %s' %
                    (params['compound_waveguide']['taper_cell'],
                     params['compound_waveguide']['taper_library']))
        else:
            raise Exception(
                'error: waveguide type (%s) does not have taper cell and library defined'
                % waveguide_type)
        from pya import Trans, CellInstArray
        '''
        find sections of waveguides that are larger than (2 x radius + 2 x taper_length)
         - insert two tapers
         - insert multimode straight section
         - insert singlemode waveguides (including bends) before
        '''
        import math
        from SiEPIC.extend import to_itype
        from pya import Point
        radius = to_itype(params_singlemode['radius'], dbu)
        taper_length = taper.find_pins()[0].center.distance(
            taper.find_pins()[1].center)
        min_length = 2 * radius + 2 * taper_length
        offset = radius
        wg_sm_segment_pts = []
        wg_last = 0
        waveguide_length = 0
        for ii in range(1, len(dpts)):
            start_point = dpts[ii - 1]
            end_point = dpts[ii]
            distance_points = end_point.distance(start_point)
            if distance_points < min_length:
                # single mode segment, keep track
                if ii == 1:
                    wg_sm_segment_pts.append(pts[ii - 1])
                wg_sm_segment_pts.append(pts[ii])
                if ii == len(pts) - 1:
                    subcell = layout.create_cell("Waveguide_sm_%s" % ii)
                    cell.insert(CellInstArray(subcell.cell_index(), Trans()))
                    waveguide_length += layout_waveguide3(subcell,
                                                          wg_sm_segment_pts,
                                                          params_singlemode,
                                                          debug=True)
            else:
                # insert two tapers and multimode waveguide
                angle = math.atan2(
                    (end_point.y - start_point.y),
                    (end_point.x - start_point.x)) / math.pi * 180
                if ii == 1:
                    wg_first = offset
                else:
                    wg_first = 0
                if ii == len(pts) - 1:
                    wg_last = offset
                if round(angle) % 360 == 270.0:
                    t = Trans(Trans.R270, start_point.x,
                              start_point.y - offset + wg_first)
                    t2 = Trans(Trans.R90, end_point.x,
                               end_point.y + offset - wg_last)
                    wg_start_pt = Point(
                        start_point.x,
                        start_point.y - offset - taper_length + wg_first)
                    wg_end_pt = Point(
                        end_point.x,
                        end_point.y + offset + taper_length - wg_last)
                if round(angle) % 360 == 90.0:
                    t = Trans(Trans.R90, start_point.x,
                              start_point.y + offset - wg_first)
                    t2 = Trans(Trans.R270, end_point.x,
                               end_point.y - offset + wg_last)
                    wg_start_pt = Point(
                        start_point.x,
                        start_point.y + offset + taper_length - wg_first)
                    wg_end_pt = Point(
                        end_point.x,
                        end_point.y - offset - taper_length + wg_last)
                if round(angle) % 360 == 180.0:
                    t = Trans(Trans.R180, start_point.x - offset + wg_first,
                              start_point.y)
                    t2 = Trans(Trans.R0, end_point.x + offset - wg_last,
                               end_point.y)
                    wg_start_pt = Point(
                        start_point.x - offset - taper_length + wg_first,
                        start_point.y)
                    wg_end_pt = Point(
                        end_point.x + offset + taper_length - wg_last,
                        end_point.y)
                if round(angle) % 360 == 0.0:
                    t = Trans(Trans.R0, start_point.x + offset - wg_first,
                              start_point.y)
                    t2 = Trans(Trans.R180, end_point.x - offset + wg_last,
                               end_point.y)
                    wg_start_pt = Point(
                        start_point.x + offset + taper_length - wg_first,
                        start_point.y)
                    wg_end_pt = Point(
                        end_point.x - offset - taper_length + wg_last,
                        end_point.y)
                inst_taper = cell.insert(CellInstArray(taper.cell_index(), t))
                inst_taper = cell.insert(CellInstArray(taper.cell_index(), t2))
                waveguide_length += taper_length * 2
                subcell = layout.create_cell("Waveguide_mm_%s" % ii)
                cell.insert(CellInstArray(subcell.cell_index(), Trans()))
                waveguide_length += layout_waveguide3(subcell,
                                                      [wg_start_pt, wg_end_pt],
                                                      params_multimode,
                                                      debug=True)
                # compound segment
                if ii > 1:
                    wg_sm_segment_pts.append(t.disp.to_p())
                    subcell = layout.create_cell("Waveguide_sm_%s" % ii)
                    cell.insert(CellInstArray(subcell.cell_index(), Trans()))
                    waveguide_length += layout_waveguide3(subcell,
                                                          wg_sm_segment_pts,
                                                          params_singlemode,
                                                          debug=True)
                    wg_sm_segment_pts = [t2.disp.to_p(), pts[ii]]
                else:
                    wg_sm_segment_pts = [t2.disp.to_p(), pts[ii]]

    else:
        # primitive waveguide type
        waveguide_length = layout_waveguide3(cell, pts, params, debug=True)

    return waveguide_length
Example #15
0
def layout_waveguide2(TECHNOLOGY, layout, cell, layers, widths, offsets, pts,
                      radius, adiab, bezier):
    from SiEPIC.utils import arc_xy, arc_bezier, angle_vector, angle_b_vectors, inner_angle_b_vectors, translate_from_normal
    from SiEPIC.extend import to_itype
    from pya import Path, Polygon, Trans
    dbu = layout.dbu

    if 'Errors' in TECHNOLOGY:
        error_layer = layout.layer(TECHNOLOGY['Errors'])
    else:
        error_layer = None

    width = widths[0]
    turn = 0
    waveguide_length = 0
    for lr in range(0, len(layers)):
        wg_pts = [pts[0]]
        layer = layout.layer(TECHNOLOGY[layers[lr]])
        width = to_itype(widths[lr], dbu)
        offset = to_itype(offsets[lr], dbu)
        for i in range(1, len(pts) - 1):
            turn = (
                (angle_b_vectors(pts[i] - pts[i - 1], pts[i + 1] - pts[i]) +
                 90) % 360 - 90) / 90
            dis1 = pts[i].distance(pts[i - 1])
            dis2 = pts[i].distance(pts[i + 1])
            angle = angle_vector(pts[i] - pts[i - 1]) / 90
            pt_radius = to_itype(radius, dbu)
            error_seg1 = False
            error_seg2 = False
            # determine the radius, based on how much space is available
            if len(pts) == 3:
                # simple corner, limit radius by the two edges
                if dis1 < pt_radius:
                    error_seg1 = True
                if dis2 < pt_radius:
                    error_seg2 = True
                pt_radius = min(dis1, dis2, pt_radius)
            else:
                if i == 1:
                    # first corner, limit radius by first edge, or 1/2 of second one
                    if dis1 < pt_radius:
                        error_seg1 = True
                    if dis2 / 2 < pt_radius:
                        error_seg2 = True
                    pt_radius = min(dis1, dis2 / 2, pt_radius)
                elif i == len(pts) - 2:
                    # last corner, limit radius by second edge, or 1/2 of first one
                    if dis1 / 2 < pt_radius:
                        error_seg1 = True
                    if dis2 < pt_radius:
                        error_seg2 = True
                    pt_radius = min(dis1 / 2, dis2, pt_radius)
                else:
                    if dis1 / 2 < pt_radius:
                        error_seg1 = True
                    if dis2 / 2 < pt_radius:
                        error_seg2 = True
                    pt_radius = min(dis1 / 2, dis2 / 2, pt_radius)

            if error_seg1 or error_seg2:
                if not error_layer:
                    # we have an error, but no Error layer
                    print('- SiEPIC:layout_waveguide2: missing Error layer')
                # and pt_radius < to_itype(radius,dbu):
                elif layer == layout.layer(TECHNOLOGY['Waveguide']):
                    # add an error polygon to flag the incorrect bend
                    if error_seg1:
                        error_pts = pya.Path([pts[i - 1], pts[i]], width)
                        cell.shapes(error_layer).insert(error_pts)
                    if error_seg2:
                        error_pts = pya.Path([pts[i], pts[i + 1]], width)
                        cell.shapes(error_layer).insert(error_pts)
    #                error_pts = pya.Path([pts[i-1], pts[i], pts[i+1]], width)
    #                cell.shapes(error_layer).insert(error_pts)
    # waveguide bends:
            if abs(turn) == 1:
                if (adiab):
                    wg_pts += Path(
                        arc_bezier(
                            pt_radius,
                            270,
                            270 + inner_angle_b_vectors(
                                pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                            float(bezier),
                            DevRec='DevRec' in layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()
                else:
                    wg_pts += Path(
                        arc_xy(-pt_radius,
                               pt_radius,
                               pt_radius,
                               270,
                               270 + inner_angle_b_vectors(
                                   pts[i - 1] - pts[i], pts[i + 1] - pts[i]),
                               DevRec='DevRec' in layers[lr]),
                        0).transformed(Trans(angle, turn < 0,
                                             pts[i])).get_points()

        wg_pts += [pts[-1]]
        wg_pts = pya.Path(wg_pts, 0).unique_points().get_points()
        wg_polygon = Polygon(
            translate_from_normal(
                wg_pts, width / 2 + (offset if turn > 0 else -offset)) +
            translate_from_normal(
                wg_pts, -width / 2 + (offset if turn > 0 else -offset))[::-1])
        cell.shapes(layer).insert(wg_polygon)

        if layout.layer(TECHNOLOGY['Waveguide']) == layer:
            waveguide_length = wg_polygon.area() / width * dbu

    return waveguide_length
Example #16
0
def layout_waveguide3(cell, pts, params, debug=True):

    if debug:
        print('SiEPIC.utils.layout.layout_waveguide3: ')

    layout = cell.layout()
    dbu = layout.dbu
    technology_name = layout.technology_name
    from SiEPIC.utils import get_technology_by_name
    TECHNOLOGY = get_technology_by_name(technology_name)

    from SiEPIC.extend import to_itype
    wg_width = to_itype(params['width'], dbu)
    radius = float(params['radius'])
    model = params['model']
    cellName = 'Waveguide2'
    CML = params['CML']

    if debug:
        print(' - waveguide params: %s' % (params))

    if 'compound_waveguide' in params:
        print('error: this function cannot handle compound waveguides')
        raise Exception(
            'error: this function cannot handle compound waveguides (%s)' %
            waveguide_type)

    # draw the waveguide
    waveguide_length = layout_waveguide2(
        TECHNOLOGY, layout, cell, [wg['layer'] for wg in params['component']],
        [wg['width'] for wg in params['component']],
        [wg['offset'] for wg in params['component']], pts, radius,
        params['adiabatic'], params['bezier'])

    # Draw the marking layers
    from SiEPIC.utils import angle_vector
    LayerPinRecN = layout.layer(TECHNOLOGY['PinRec'])

    make_pin(cell, 'opt1', pts[0], wg_width, LayerPinRecN,
             angle_vector(pts[0] - pts[1]) % 360)
    make_pin(cell, 'opt2', pts[-1], wg_width, LayerPinRecN,
             angle_vector(pts[-1] - pts[-2]) % 360)

    from pya import Trans, Text, Path, Point
    '''
    t1 = Trans(angle_vector(pts[0]-pts[1])/90, False, pts[0])
    cell.shapes(LayerPinRecN).insert(Path([Point(-10, 0), Point(10, 0)], wg_width).transformed(t1))
    cell.shapes(LayerPinRecN).insert(Text("opt1", t1, 0.3/dbu, -1))
    
    t = Trans(angle_vector(pts[-1]-pts[-2])/90, False, pts[-1])
    cell.shapes(LayerPinRecN).insert(Path([Point(-10, 0), Point(10, 0)], wg_width).transformed(t))
    cell.shapes(LayerPinRecN).insert(Text("opt2", t, 0.3/dbu, -1))
    '''

    LayerDevRecN = layout.layer(TECHNOLOGY['DevRec'])

    # Compact model information
    angle_vec = angle_vector(pts[0] - pts[1]) / 90
    halign = 0  # left
    angle = 0
    dpt = Point(0, 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] - 6 * dpt
    pt5 = pts[0] + 2 * dpt

    t = Trans(angle, False, pt3)
    text = Text('Lumerical_INTERCONNECT_library=Design kits/%s' % CML, t,
                0.1 * wg_width, -1)
    text.halign = halign
    shape = cell.shapes(LayerDevRecN).insert(text)
    t = Trans(angle, False, pt2)
    text = Text('Component=%s' % model, t, 0.1 * wg_width, -1)
    text.halign = halign
    shape = cell.shapes(LayerDevRecN).insert(text)
    t = Trans(angle, False, pt5)
    text = Text('cellName=%s' % cellName, t, 0.1 * wg_width, -1)
    text.halign = halign
    shape = 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=%.9f wg_width=%.3g points="%s" radius=%.3g' %
        (waveguide_length * 1e-6, wg_width * 1e-9, pts_txt, radius * 1e-6), t,
        0.1 * wg_width, -1)
    text.halign = halign
    shape = cell.shapes(LayerDevRecN).insert(text)
    t = Trans(angle, False, pt4)
    text = Text('Length=%.3f (microns)' % (waveguide_length), t,
                0.5 * wg_width, -1)
    text.halign = halign
    shape = cell.shapes(LayerDevRecN).insert(text)

    return waveguide_length
        qbits.append(qbit)

    # place top array of resonators with qBits
    N_top = N_bottom - 1
    delta = 1e6
    step_top = step_bot
    resonators = []
    qbits = []
    empties = []
    for i in range(N_top):
        point = DPoint(contact_L + delta + step_bot / 2 + i * step_top,
                       CHIP.dy / 2 + (Z0.width + Z_res.width) / 2 + toLine)

        worm = EMResonator_TL2Qbit_worm(Z_res, point, L_coupling[i + N_bottom],
                                        L1[i + N_bottom], r, L2, N,
                                        Trans(Trans.M0))
        worm.place(cell, layer_photo)
        resonators.append(worm)

        qbit_params = [
            a[i + N_bottom], b[i + N_bottom], jos1_b, jos1_a, f1, d1, jos2_b,
            jos2_a, f2, d2, w, dCap, gap, square_a, dSquares, alum_over,
            B1_width
        ]
        dy_qbit = -(worm.cop_tail.dr.abs() - square_a) / 2 - square_a
        qbit_start = worm.end + DPoint(B1_width / 2, 0)
        qbit = QBit_Flux_Сshunted_3JJ(
            worm.end + DPoint(qbit_coupling_gap + Z_res.width / 2, dy_qbit),
            qbit_params, DCplxTrans(1, 90, False, 0, 0))
        qbit_bbox = pya.DBox().from_ibox(qbit.metal_regions["photo"].bbox())
        p1 = qbit.origin + DPoint(-qbit_coupling_gap, qbit.square_a / 2)
Example #18
0
ly.prune_subcells(cell_top.cell_index(), 1000)

#%%Define Layer mapping and floor plan
LayerSiN = ly.layer(lib[layer_Si220])
fpLayerN = cell_top.layout().layer(lib[layer_floorplan])
TextLayerN = cell_top.layout().layer(lib[layer_text])
# Draw the floor plan
ly_height = 350
ly_width = 600
cell_top.shapes(fpLayerN).insert(Box(0, 0, ly_width / dbu, ly_height / dbu))

#%%Import Grating couplers
GC_imported = ly.create_cell("Grating_Coupler_13deg_TE_1550_Oxide",
                             pdk).cell_index()
GC_pitch = 127
t = Trans(Trans.R0, 0.5 * ly_width / dbu,
          (0.5 * ly_height - GC_pitch / 2) / dbu)
cell_top.insert(
    CellInstArray(GC_imported, t,
                  DPoint(0, GC_pitch).to_itype(dbu), Point(0, 0), 2, 1))

#%%draw waveguide connecting grating couplers
path = [[0.5 * ly_width, 0.5 * ly_height - GC_pitch / 2]]  # start point
path.append([0.5 * ly_width + 50, 0.5 * ly_height - GC_pitch / 2])
path.append([0.5 * ly_width + 50, 0.5 * ly_height + GC_pitch / 2])
path.append([0.5 * ly_width, 0.5 * ly_height + GC_pitch / 2])  # end point
path = DPath([DPoint(each[0], each[1]) for each in path], 0.5)
path = path.to_itype(dbu)
pts = path.get_points()

widths = [0.5]
layers = ['Waveguide']