def init_half(self, origin, side=-1): # side = -1 is left, 1 is right up_st_gap = self.sq_area / (2 * self.sq_len) low_st_gap = up_st_gap + self.low_lead_w * 2.5 up_st_start_p = self.primitives["p_ext_up"].connections[1] low_st_start_p = self.primitives["p_ext_down"].connections[1] up_st_start = up_st_start_p + DVector(side * up_st_gap / 2, 0) up_st_stop = origin + DVector(side * up_st_gap / 2, self.bridge / 2) low_st_start = low_st_start_p + DVector(side * low_st_gap / 2, 0) low_st_stop = origin + DVector(side * (low_st_gap / 2 - self.b_ext), -self.bridge / 2) Z_low = CPWParameters(self.j_length, 0) Z_low2 = CPWParameters(self.low_lead_w, 0) len_ly = (low_st_stop - low_st_start).y - Z_low2.width / 2 len_lb = side * (low_st_start - low_st_stop).x - Z_low2.width / 2 suff = "_left" if side < 0 else "_right" self.primitives["upp_st" + suff] = Kolbaska(up_st_start, up_st_stop, self.j_width, self.j_width / 4) self.primitives["upp_st_thick" + suff] = Kolbaska( up_st_start, up_st_stop + DPoint(0, 400), self.low_lead_w, self.low_lead_w / 2) self.primitives["low_st" + suff] = CPW_RL_Path(low_st_start, 'LR', Z_low2, Z_low2.width/2,\ [len_ly],[side * pi/2],trans_in = DTrans.R90) self.primitives["low_st_jj" + suff] = CPW(Z_low.width, Z_low.gap, low_st_stop + DPoint(side * (self.b_ext - Z_low2.width/2),\ -self.j_length/2), low_st_stop + DPoint(0, -self.j_length/2))
def draw_el_protection(self): protection_a = 300e3 for squid in (self.squids + self.test_squids): self.region_el_protection.insert(pya.Box().from_dbox( pya.DBox( squid.origin - 0.5 * DVector(protection_a, protection_a), squid.origin + 0.5 * DVector(protection_a, protection_a))))
def init_primitives(self): origin = DPoint(0, 0) pars = self.params up_pad_center = origin + DVector(0, pars.pads_distance / 2) down_pad_center = origin + DVector(0, -pars.pads_distance / 2) self.pad_down = Circle(down_pad_center, pars.pad_r, n_pts=pars.n, offset_angle=pi / 2) self.primitives["pad_down"] = self.pad_down self.p_ext_down = Kolbaska(down_pad_center, origin + DPoint(0, -pars.sq_len / 2), pars.p_ext_width, pars.p_ext_r) self.primitives["p_ext_down"] = self.p_ext_down self.pad_up = Circle(up_pad_center, pars.pad_r, n_pts=pars.n, offset_angle=-pi / 2) self.primitives["pad_up"] = self.pad_up self.p_ext_up = Kolbaska(up_pad_center, origin + DVector(0, pars.sq_len / 2), pars.p_ext_width, pars.p_ext_r) self.primitives["p_ext_up"] = self.p_ext_up origin = DPoint(0, 0) if self.side == 0: self.init_half(origin, side=1) # right self.init_half(origin, side=-1) # left else: self.init_half(origin, side=self.side)
def init_half(self, origin, side=-1): # side = -1 is left, 1 is right pars = self.params j_width = pars.j_width_1 if side < 0 else pars.j_width_2 j_length = pars.j_length if side < 0 else pars.j_length_2 suff = "_left" if side < 0 else "_right" up_st_gap = pars.sq_area / (2 * pars.sq_len) # exact correction in first row # additional extension to isolate jj's from intermediate bottom polygons # without correction horizontal faces of jj's will be adjacent # to thick intemediate polygons low_st_gap = up_st_gap + ((pars.j_length + pars.j_length_2) / 2 + pars.intermediate_width) + \ 2 * pars.intermediate_width ### upper and lower vertical intermediate and jj leads ### ## top leads ## upper_leads_extension = j_width / 4 # upper intemediate lead up_st_start = self.primitives["p_ext_up"].connections[1] + \ DVector(side * up_st_gap / 2, 0) up_st_stop = origin + \ DVector(side * up_st_gap / 2, pars.bridge / 2 + upper_leads_extension) # top jj lead self.primitives["upp_st" + suff] = Kolbaska(up_st_start, up_st_stop, j_width, upper_leads_extension) # top intermediate lead upper_thin_part_len = 4 * pars.bridge + pars.intermediate_width / 2 self.primitives["upp_st_thick" + suff] = Kolbaska( up_st_start, up_st_stop + DPoint(0, upper_thin_part_len), pars.intermediate_width, pars.intermediate_width / 2) ## bottom leads ## low_st_start = self.primitives["p_ext_down"].connections[1] + \ DVector(side * low_st_gap / 2, 0) low_st_stop = origin + \ DVector(side * (low_st_gap / 2 + 2 * pars.intermediate_width), -pars.bridge / 2 - pars.intermediate_width / 2) len_ly = (low_st_stop - low_st_start).y # bottom intermediate lead self.primitives["low_st" + suff] = CPW_RL_Path( low_st_start, 'LR', CPWParameters(pars.intermediate_width, 0), pars.intermediate_width / 2, [len_ly], [side * pi / 2], trans_in=DTrans.R90) # bottom jj lead (horizontal) low_st_end = self.primitives["low_st" + suff].connections[1] low_st_jj_start = low_st_end + DPoint( 0, -j_length / 2 + pars.intermediate_width / 2) low_st_jj_stop = low_st_jj_start + DPoint(-side * pars.b_ext, 0) self.primitives["low_st_jj" + suff] = Kolbaska(low_st_jj_start, low_st_jj_stop, j_length, j_length / 2)
def init_primitives(self): origin = DPoint(0, 0) # square box that clears out the area of the mark self.primitives["empty_box"] = Rectangle(DPoint( -self.leaf_outer, -self.leaf_outer), 2 * self.leaf_outer, 2 * self.leaf_outer, inverse=True) self.primitives["cross"] = Cross( DPoint(-self.cross_out_a / 2, -self.cross_out_a / 2), self.cross_in_a, self.cross_out_a) Z = CPWParameters(self.leaf_outer - self.leaf_inner, 0) for i in range(self.leafs_N): start_angle = i * (self.leaf_angle + self.empty_leaf_angle) - self.leaf_angle / 2 trans = DCplxTrans(1, start_angle + 90, False, 0, -self.avg_r) self.primitives["leaf_" + str(i)] = CPW_arc(Z, origin, self.avg_r, self.leaf_angle * pi / 180, trans_in=trans) Z_empty = CPWParameters(0, self.empty_rings_width / 2) for i in range(1, self.empty_rings_N + 1): r = self.leaf_inner + (self.leaf_outer - self.leaf_inner) / ( self.empty_rings_N + 1) * i self.primitives["empty_ring_" + str(i)] = CPW_arc( Z_empty, DVector(0, -r), r, 2 * pi)
def draw_xmons_and_resonators(self): for resonator, xmon_fork_penetration, xmon_dy_Cg_coupling in zip( self.resonators, self.xmon_fork_penetration_list, self.xmon_dys_Cg_coupling): xmon_center = (resonator.fork_y_cpw1.end + resonator.fork_y_cpw2.end) / 2 + \ DVector(0, -xmon_dy_Cg_coupling) xmon_center += DPoint( 0, -(self.cross_len + self.cross_width / 2) + xmon_fork_penetration) self.xmons.append( XmonCross(xmon_center, self.cross_len_x, self.cross_width_x, self.cross_gnd_gap_x, sideY_length=self.cross_len_y, sideY_width=self.cross_width_y, sideY_gnd_gap=self.cross_gnd_gap_y)) self.xmons[-1].place(self.region_ph) resonator.place(self.region_ph) xmonCross_corrected = XmonCross(xmon_center, sideX_length=self.cross_len_x, sideX_width=self.cross_width_x, sideX_gnd_gap=self.cross_gnd_gap_x, sideY_length=self.cross_len_y, sideY_width=self.cross_width_y, sideY_gnd_gap=min( self.cross_gnd_gap_y, self.xmon_fork_gnd_gap)) xmonCross_corrected.place(self.region_ph)
def draw_xmons_and_resonators(self): for resonator, fork_y_span, xmon_dy_Cg_coupling in \ list(zip( self.resonators, self.fork_y_spans, self.xmon_dys_Cg_coupling )): xmon_center = (resonator.fork_x_cpw.start + resonator.fork_x_cpw.end) / 2 + \ DVector(0, -xmon_dy_Cg_coupling - resonator.fork_metal_width / 2) # changes start # xmon_center += DPoint( 0, -(self.cross_len_y + self.cross_width_x / 2 + min(self.cross_gnd_gap_y, self.xmon_fork_gnd_gap)) + FABRICATION.OVERETCHING ) self.xmons.append( XmonCross(xmon_center, self.cross_len_x, self.cross_width_x + 2 * FABRICATION.OVERETCHING, self.cross_gnd_gap_x - 2 * FABRICATION.OVERETCHING, sideY_length=self.cross_len_y, sideY_width=self.cross_width_y + 2 * FABRICATION.OVERETCHING, sideY_gnd_gap=self.cross_gnd_gap_y - 2 * FABRICATION.OVERETCHING) ) self.xmons[-1].place(self.region_ph) resonator.place(self.region_ph) xmonCross_corrected = XmonCross( xmon_center, sideX_length=self.cross_len_x, sideX_width=self.cross_width_x + 2 * FABRICATION.OVERETCHING, sideX_gnd_gap=self.cross_gnd_gap_x - 2 * FABRICATION.OVERETCHING, sideY_length=self.cross_len_y, sideY_width=self.cross_width_y + 2 * FABRICATION.OVERETCHING, sideY_gnd_gap=min(self.cross_gnd_gap_y, self.xmon_fork_gnd_gap) - 2 * FABRICATION.OVERETCHING) xmonCross_corrected.place(self.region_ph)
def draw_inductor_for_fl_line(design, fl_line_idx): cpwrl_fl = self.cpw_fl_lines[fl_line_idx] cpwrl_fl_inductor_start = cpwrl_fl.end + \ DVector(0, -design.current_line_width / 2) cpwrl_fl_inductor = CPW( cpw_params=CPWParameters(width=design.current_line_width, gap=0), start=cpwrl_fl_inductor_start, end=cpwrl_fl_inductor_start + DVector(2 * abs(design.flux_lines_x_shifts[fl_line_idx]), 0)) cpwrl_fl_inductor.place(design.region_ph) cpwrl_fl_inductor_empty_box = Rectangle( origin=cpwrl_fl.end + DVector(0, -design.current_line_width - 2 * design.z_md_fl.gap), width=cpwrl_fl_inductor.dr.abs(), height=2 * design.z_md_fl.gap, inverse=True) cpwrl_fl_inductor_empty_box.place(design.region_ph)
def init_regions(self): dpts_arr = [DPoint(self.r*cos(2*pi*i/self.n_pts+self._offset_angle),self.r*sin(2*pi*i/self.n_pts+self._offset_angle)) for i in range(0,self.n_pts)] if( self.solid == True ): self.metal_region.insert( SimplePolygon().from_dpoly( DSimplePolygon(dpts_arr) ) ) else: self.empty_region.insert( SimplePolygon().from_dpoly( DSimplePolygon(dpts_arr) ) ) self.connections.extend([self.center, self.center + DVector(0,-self.r)]) self.angle_connections.extend([0, 0])
def init_primitives(self): origin = DPoint(0, 0) self._up_pad_center = origin + DVector(0, self.pads_distance / 2) self._down_pad_center = origin + DVector(0, -self.pads_distance / 2) self.primitives["pad_down"] = Circle(self._down_pad_center, self.pad_side, n_pts=self.n, offset_angle=pi / 2) self.primitives["p_ext_down"] = Kolbaska(self._down_pad_center, origin + DVector(0,-self.sq_len/2),\ self.p_ext_width,self.p_ext_r) self.primitives["pad_up"] = Circle(self._up_pad_center, self.pad_side, n_pts=self.n, offset_angle=-pi / 2) self.primitives["p_ext_up"] = Kolbaska(self._up_pad_center, origin + DVector(0,self.sq_len/2),\ self.p_ext_width,self.p_ext_r) if self.side == 0: self.init_half(origin, side=1) # right self.init_half(origin, side=-1) # left else: self.init_half(origin, side=self.side)
def init_regions(self): origin = DPoint(0, 0) dpts_arr = [DPoint(self.r * cos(2 * pi * i / self.n_pts + self._offset_angle), self.r * sin(2 * pi * i / self.n_pts + self._offset_angle)) for i in range(0, self.n_pts)] circle_polygon = SimplePolygon().from_dpoly(DSimplePolygon(dpts_arr)) if self.inverse: self.empty_region.insert(circle_polygon) else: self.metal_region.insert(circle_polygon) self.connections.extend([origin, origin + DVector(0, -self.r)]) self.angle_connections.extend([0, 0])
def init_regions( self ): d_alpha = (self.alpha_end - self.alpha_start)/(self.n_pts - 1) alphas = [(self.alpha_start + d_alpha*i) for i in range(0,self.n_pts)] dpts_arr = [DPoint(self.r*cos(alpha),self.r*sin(alpha)) for alpha in alphas] dpts_arr.append( DPoint(0,0) ) if( self.solid == True ): self.metal_region.insert( SimplePolygon().from_dpoly( DSimplePolygon(dpts_arr) ) ) else: self.empty_region.insert( SimplePolygon().from_dpoly( DSimplePolygon(dpts_arr) ) ) self.connections.extend([self._center, self._center+DVector(0, -self.r)]) self.angle_connections.extend([0,0])
def draw_xmons_and_resonators(self, q_idx): for i, (resonator, fork_y_span, xmon_dy_Cg_coupling) in \ enumerate( list( zip( self.resonators, self.fork_y_spans, self.xmon_dys_Cg_coupling ) ) ): xmon_center = \ ( resonator.fork_x_cpw.start + resonator.fork_x_cpw.end ) / 2 + \ DVector( 0, -xmon_dy_Cg_coupling - resonator.fork_metal_width / 2 ) # changes start # xmon_center += DPoint( 0, -(self.cross_len_y + self.cross_width_x / 2 + self.cross_gnd_gap_y)) self.xmons.append( XmonCross(xmon_center, sideX_length=self.cross_len_x, sideX_width=self.cross_width_x, sideX_gnd_gap=self.cross_gnd_gap_x, sideY_length=self.cross_len_y, sideY_width=self.cross_width_y, sideY_gnd_gap=self.cross_gnd_gap_y, sideX_face_gnd_gap=self.cross_gnd_gap_x, sideY_face_gnd_gap=self.cross_gnd_gap_y)) if i == q_idx: self.xmons[-1].place(self.region_ph) resonator.place(self.region_ph) xmonCross_corrected = XmonCross( xmon_center, sideX_length=self.cross_len_x, sideX_width=self.cross_width_x, sideX_gnd_gap=self.cross_gnd_gap_x, sideY_length=self.cross_len_y, sideY_width=self.cross_width_y, sideY_gnd_gap=max( 0, self.fork_x_span - 2 * self.fork_metal_width - self.cross_width_y - max(self.cross_gnd_gap_y, self.fork_gnd_gap)) / 2) if i == q_idx: xmonCross_corrected.place(self.region_ph)
def draw_el_dc_contacts(self, squids: AsymSquid = None): # if argument is omitted, use all squids stored in `self.squids` if squids is None: squids = self.squids + self.test_squids for squid in squids: r_pad = squid.params.pad_r center_up = squid.pad_up.center + DPoint(0, r_pad) center_down = squid.pad_down.center + DPoint(0, -r_pad) big_circle_r = 1.5 * r_pad self.el_dc_contacts.append( [Circle(center_up, big_circle_r), Circle(center_down, big_circle_r)] ) for contact in self.el_dc_contacts[-1]: contact.place(self.region_el2) # DC contacts has to have intersection with empty layer in photo litography # to ensure that first e-beam layer does not broke at the step between # substrate and photolytography polygons. # Following rectangle pads are cutted from photo region to ensure # DC contacts are covering aforementioned level step. squid_pad_r = squid.params.pad_r squid_pads_d = squid.params.pads_distance - 2 * squid_pad_r rec_width = 1.6 * squid_pad_r - 2 * FABRICATION.OVERETCHING rec_height = 1.6 * squid_pad_r - FABRICATION.OVERETCHING # Rectangle for top DC contact pad p1 = squid.origin + DVector(-rec_width / 2, squid_pads_d / 2) + \ DVector(0, -FABRICATION.OVERETCHING) rec_top = Rectangle(p1, rec_width, rec_height, inverse=True) rec_top.place(self.region_ph) # Rectangle for bottom DC contact pad p2 = squid.origin + DVector(-rec_width / 2, -squid_pads_d / 2) + \ DVector(0, FABRICATION.OVERETCHING) rec_bot = Rectangle(p2, rec_width, -rec_height, inverse=True) rec_bot.place(self.region_ph)
def draw_microwave_drvie_lines(self): self.cont_lines_y_ref = self.xmons[0].cpw_bempt.end.y - 200e3 tmp_reg = self.region_ph # place caplanar line 1md _p1 = self.contact_pads[0].end _p2 = _p1 + DPoint(1e6, 0) _p3 = self.xmons[0].cpw_l.end + DVector(-1e6, 0) _p4 = self.xmons[0].cpw_l.end + DVector(-66.2e3, 0) _p5 = _p4 + DVector(11.2e3, 0) self.cpwrl_md1 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5], cpw_parameters=[self.z_md_fl] * 5 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius) self.cpwrl_md1.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md1) # place caplanar line 2md _p1 = self.contact_pads[3].end _p2 = _p1 + DPoint(0, 500e3) _p3 = DPoint(self.xmons[1].cpw_b.end.x + self.md234_cross_bottom_dx, self.cont_lines_y_ref) _p4 = DPoint(_p3.x, self.xmons[1].cpw_b.end.y - self.md234_cross_bottom_dy) _p5 = _p4 + DPoint(0, 10e3) self.cpwrl_md2 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5], cpw_parameters=[self.z_md_fl] * 5 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius) self.cpwrl_md2.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md2) # place caplanar line 3md _p1 = self.contact_pads[5].end _p2 = _p1 + DPoint(0, 500e3) _p3 = _p2 + DPoint(-2e6, 2e6) _p5 = DPoint(self.xmons[2].cpw_b.end.x + self.md234_cross_bottom_dx, self.cont_lines_y_ref) _p4 = DPoint(_p5.x, _p5.y - 1e6) _p6 = DPoint(_p5.x, self.xmons[2].cpw_b.end.y - self.md234_cross_bottom_dy) _p7 = _p6 + DPoint(0, 10e3) self.cpwrl_md3 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5, _p6, _p7], cpw_parameters=[self.z_md_fl] * 8 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius) self.cpwrl_md3.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md3) # place caplanar line 4md _p1 = self.contact_pads[7].end _p2 = _p1 + DPoint(-3e6, 0) _p3 = DPoint(self.xmons[3].cpw_b.end.x + self.md234_cross_bottom_dx, self.cont_lines_y_ref) _p4 = DPoint(_p3.x, self.xmons[3].cpw_b.end.y - self.md234_cross_bottom_dy) _p5 = _p4 + DPoint(0, 10e3) self.cpwrl_md4 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5], cpw_parameters=[self.z_md_fl] * 5 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius) self.cpwrl_md4.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md4) # place caplanar line 5md _p1 = self.contact_pads[9].end _p2 = _p1 + DPoint(0, -0.5e6) _p3 = _p2 + DPoint(1e6, -1e6) _p4 = self.xmons[4].cpw_r.end + DVector(1e6, 0) _p5 = self.xmons[4].cpw_r.end + DVector(66.2e3, 0) _p6 = _p5 + DVector(11.2e3, 0) self.cpwrl_md5 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5, _p6], cpw_parameters=[self.z_md_fl] * 8 + [CPWParameters(width=0, gap=self.z_md_fl.b / 2)], turn_radiuses=self.ctr_lines_turn_radius, ) self.cpwrl_md5.place(tmp_reg) self.cpw_md_lines.append(self.cpwrl_md5)
def init_regions(self): self.metal_regions["bridges_1"] = Region( ) # region with ground contacts self.empty_regions["bridges_1"] = Region() # remains empty self.metal_regions["bridges_2"] = Region() # remains empty self.empty_regions["bridges_2"] = Region( ) # region with erased bridge area center = DPoint(0, 0) self.connections = [center] self.angle_connections = [0] # init metal region of ground touching layer top_gnd_center = center + DPoint( 0, self.gnd2gnd_dy / 2 + self.gnd_touch_dy / 2) p1 = top_gnd_center + DPoint(-self.gnd_touch_dx / 2, -self.gnd_touch_dy / 2) p2 = p1 + DVector(self.gnd_touch_dx, self.gnd_touch_dy) top_gnd_touch_box = pya.DBox(p1, p2) self.metal_regions["bridges_1"].insert( pya.Box().from_dbox(top_gnd_touch_box)) bot_gnd_center = center + DPoint( 0, -(self.gnd2gnd_dy / 2 + self.gnd_touch_dy / 2)) p1 = bot_gnd_center + DPoint(-self.gnd_touch_dx / 2, -self.gnd_touch_dy / 2) p2 = p1 + DVector(self.gnd_touch_dx, self.gnd_touch_dy) bot_gnd_touch_box = pya.DBox(p1, p2) self.metal_regions["bridges_1"].insert( pya.Box().from_dbox(bot_gnd_touch_box)) # init empty region for second layout layer # points start from left-bottom corner and goes in clockwise direction p1 = bot_gnd_touch_box.p1 + DPoint(-self.surround_gap, -self.surround_gap) p2 = p1 + DPoint( 0, self.surround_gap + self.gnd_touch_dy + self.transition_len - self.surround_gap) # top left corner + `surrounding_gap` + `transition_length` p3 = bot_gnd_touch_box.p1 + DPoint(0, bot_gnd_touch_box.height()) + \ DPoint(0, self.transition_len) bl_pts_list = [p1, p2, p3] # bl stands for bottom-left ''' exploiting symmetry of reflection at x and y axes. ''' # reflecting at x-axis tl_pts_list = list(map(lambda x: DTrans.M0 * x, bl_pts_list)) # tl stands for top-left # preserving order tl_pts_list = reversed( list(tl_pts_list)) # preserving clockwise points order # converting iterator to list l_pts_list = list(itertools.chain(bl_pts_list, tl_pts_list)) # l stands for left # reflecting all points at y-axis r_pts_list = list(map(lambda x: DTrans.M90 * x, l_pts_list)) r_pts_list = list( reversed(r_pts_list)) # preserving clockwise points order # gathering points pts_list = l_pts_list + r_pts_list # concatenating proper ordered lists empty_polygon = DSimplePolygon(pts_list) self.empty_regions["bridges_2"].insert( SimplePolygon.from_dpoly(empty_polygon))
def draw_test_structures(self): new_pars_squid = AsymSquidParams( pad_r=5e3, pads_distance=30e3, p_ext_width=10e3, p_ext_r=200, sq_len=15e3, sq_area=200e6, j_width_1=94, j_width_2=347, intermediate_width=500, b_ext=1e3, j_length=94, n=20, bridge=180, j_length_2=250 ) struct_centers = [DPoint(1e6, 4e6), DPoint(8.7e6, 5.7e6), DPoint(6.5e6, 2.7e6)] for struct_center in struct_centers: ## JJ test structures ## # test structure with big critical current test_struct1 = TestStructurePads(struct_center) test_struct1.place(self.region_ph) text_reg = pya.TextGenerator.default_generator().text("48.32 nA", 0.001, 50, False, 0, 0) text_bl = test_struct1.empty_rectangle.origin + DPoint( test_struct1.gnd_gap, -4 * test_struct1.gnd_gap ) text_reg.transform(ICplxTrans(1.0, 0, False, text_bl.x, text_bl.y)) self.region_ph -= text_reg test_jj = AsymSquid(test_struct1.center, new_pars_squid, side=1) self.test_squids.append(test_jj) test_jj.place(self.region_el) # test structure with low critical current test_struct2 = TestStructurePads(struct_center + DPoint(0.3e6, 0)) test_struct2.place(self.region_ph) text_reg = pya.TextGenerator.default_generator().text("9.66 nA", 0.001, 50, False, 0, 0) text_bl = test_struct2.empty_rectangle.origin + DPoint( test_struct2.gnd_gap, -4 * test_struct2.gnd_gap ) text_reg.transform(ICplxTrans(1.0, 0, False, text_bl.x, text_bl.y)) self.region_ph -= text_reg test_jj = AsymSquid(test_struct2.center, new_pars_squid, side=-1) self.test_squids.append(test_jj) test_jj.place(self.region_el) # test structure for bridge DC contact test_struct3 = TestStructurePads(struct_center + DPoint(0.6e6, 0)) test_struct3.place(self.region_ph) text_reg = pya.TextGenerator.default_generator().text("DC", 0.001, 50, False, 0, 0) text_bl = test_struct3.empty_rectangle.origin + DPoint( test_struct3.gnd_gap, -4 * test_struct3.gnd_gap ) text_reg.transform(ICplxTrans(1.0, 0, False, test_struct3.center.x, text_bl.y)) self.region_ph -= text_reg test_bridges = [] for i in range(3): bridge = Bridge1(test_struct3.center + DPoint(50e3 * (i - 1), 0), gnd_touch_dx=20e3) test_bridges.append(bridge) bridge.place(self.region_bridges1, region_name="bridges_1") bridge.place(self.region_bridges2, region_name="bridges_2") # bandages test structures test_dc_el2_centers = [ DPoint(2.5e6, 2.4e6), DPoint(4.2e6, 1.6e6), DPoint(9.0e6, 3.8e6) ] for struct_center in test_dc_el2_centers: test_struct1 = TestStructurePads(struct_center) test_struct1.place(self.region_ph) text_reg = pya.TextGenerator.default_generator().text("Bandage", 0.001, 40, False, 0, 0) text_bl = test_struct1.empty_rectangle.origin + DPoint( test_struct1.gnd_gap, -4 * test_struct1.gnd_gap ) text_reg.transform(ICplxTrans(1.0, 0, False, text_bl.x, text_bl.y)) self.region_ph -= text_reg rec_width = 10e3 rec_height = test_struct1.rectangles_gap + 2 * FABRICATION.OVERETCHING + 2 * rec_width p1 = struct_center - DVector(rec_width / 2, rec_height / 2) dc_rec = Rectangle(p1, rec_width, rec_height) dc_rec.place(self.region_el2)
self.region_ph = filled_reg + other_regs def split_polygons_in_layers(self, max_pts=200): self.region_ph = split_polygons(self.region_ph, max_pts) self.region_bridges2 = split_polygons(self.region_bridges2, max_pts) for poly in self.region_ph: if poly.num_points() > max_pts: print("exists photo") for poly in self.region_ph: if poly.num_points() > max_pts: print("exists bridge2") if __name__ == "__main__": design = Design5Q("testScript") design.draw() # crop middle (xmon[1] and xmon[2]) p1 = design.xmons[1].center - DVector(252.5e3, 500e3) p2 = design.xmons[2].center + DVector(252.5e3, 200e3) crop_box = pya.Box().from_dbox(pya.DBox(p1, p2)) design.crop(crop_box, design.layer_ph) # crop left-most Xmon and it's cpump line # dx = design.xmons[0].center.x - design.cpwrl_md1_end.start.x # p1 = design.xmons[0].center - DVector(dx, 200e3) # p2 = design.xmons[0].center + DVector(250e3 - dx%10e3, 200e3) # crop_box = pya.Box().from_dbox(pya.DBox(p1, p2)) # design.crop(crop_box, design.layer_ph) design.show()
L_coupling, L0, L1, r, N, tail_shape=res_tail_shape, tail_turn_radiuses=r, tail_segment_lengths=tail_segment_lengths, tail_turn_angles=tail_turn_angles, tail_trans_in=tail_trans_in, fork_x_span=fork_x_span, fork_y_span=fork_y_span, fork_metal_width=fork_metal_width, fork_gnd_gap=fork_gnd_gap) xmon_center_test = (worm_test.fork_y_cpw1.end + worm_test.fork_y_cpw2.end) / 2 + DVector( 0, -xmon_dy_Cg_coupling) xmon_center_test += DPoint( 0, -(cross_len_y + cross_width_x / 2) + xmon_fork_penetration) xmonCross_test = XmonCross(xmon_center_test, sideX_length=cross_len_x, sideX_width=cross_width_x, sideX_gnd_gap=cross_gnd_gap_x, sideY_length=cross_len_y, sideY_width=cross_width_y, sideY_gnd_gap=cross_gnd_gap_y) tmp_reg = Region() worm_test.place(tmp_reg) xmonCross_test.place(tmp_reg) bbox = tmp_reg.bbox() import math
CHIP.dy = 2 * bbox.height() chip_p1 = DPoint(bbox.center()) + DPoint(-0.5 * CHIP.dx, -0.5 * CHIP.dy) chip_p2 = DPoint(bbox.center()) + DPoint(0.5 * CHIP.dx, 0.5 * CHIP.dy) chip_box = pya.Box(DPoint(0, 0), DPoint(CHIP.dx, CHIP.dy)) # forming resonator's tail upper side open-circuited for simulation p1 = worm.cop_tail.start p2 = p1 + DPoint(0, 20e3) empty_cpw_tail_start = CPW(0, Z_res.b / 2, p1, p2) # placing all objects in proper order and translating them to origin cell.shapes(layer_photo).insert(chip_box) # translating all objects so that chip.p1 at coordinate origin translation_trans = DCplxTrans(-DVector(chip_p1)) xmonCross.make_trans(translation_trans) xmonCross.place(cell, layer_photo) worm.make_trans(translation_trans) worm.place(cell, layer_photo) empty_cpw_tail_start.place(cell, layer_photo) empty_cpw_tail_start.make_trans(translation_trans) empty_cpw_tail_start.place(cell, layer_photo) xmonCross_corrected = XmonCross(xmon_center, cross_width, cross_len, xmon_fork_gnd_gap) xmonCross_corrected.make_trans(translation_trans) xmonCross_corrected.place(cell, layer_photo)
def draw_bridges(self): bridges_step = 150e3 fl_bridges_step = 150e3 # for resonators for resonator in self.resonators: for name, res_primitive in resonator.primitives.items(): if "coil0" in name: # skip L_coupling coplanar. # bridgyfy all in "coil0" except for the first cpw that # is adjacent to readout line and has length equal to `L_coupling` for primitive in list( res_primitive.primitives.values())[1:]: Bridge1.bridgify_CPW(primitive, bridges_step, dest=self.region_bridges1, dest2=self.region_bridges2) continue elif "fork" in name: # skip fork primitives continue else: # bridgify everything else Bridge1.bridgify_CPW(res_primitive, bridges_step, dest=self.region_bridges1, dest2=self.region_bridges2) # for contact wires for key, val in self.__dict__.items(): if "cpwrl_md" in key: Bridge1.bridgify_CPW(val, bridges_step, dest=self.region_bridges1, dest2=self.region_bridges2) elif "cpwrl_fl" in key: Bridge1.bridgify_CPW( val, fl_bridges_step, dest=self.region_bridges1, dest2=self.region_bridges2, avoid_points=[squid.origin for squid in self.squids], avoid_distance=400e3) for cpw_fl in self.cpw_fl_lines: bridge_center1 = cpw_fl.end + DVector(0, -40e3) br = Bridge1(center=bridge_center1, trans_in=Trans.R90) br.place(dest=self.region_bridges1, region_name="bridges_1") br.place(dest=self.region_bridges2, region_name="bridges_2") # for readout waveguide bridgified_primitives_idxs = list(range(2)) bridgified_primitives_idxs += list( range(2, 2 * (len(self.resonators) + 1) + 1, 2)) bridgified_primitives_idxs += list( range(2 * (len(self.resonators) + 1) + 1, len(self.cpwrl_ro_line.primitives.values()))) for idx, primitive in enumerate( self.cpwrl_ro_line.primitives.values()): if idx in bridgified_primitives_idxs: Bridge1.bridgify_CPW(primitive, bridges_step, dest=self.region_bridges1, dest2=self.region_bridges2)
def draw_test_structures(self): struct_centers = [ DPoint(1e6, 4e6), DPoint(8.7e6, 5.7e6), DPoint(6.5e6, 2.7e6) ] for struct_center in struct_centers: ## JJ test structures ## # test structure with big critical current test_struct1 = TestStructurePads(struct_center) test_struct1.place(self.region_ph) text_reg = pya.TextGenerator.default_generator().text( "48.32 nA", 0.001, 50, False, 0, 0) text_bl = test_struct1.empty_rectangle.origin + DPoint( test_struct1.gnd_gap, -4 * test_struct1.gnd_gap) text_reg.transform(ICplxTrans(1.0, 0, False, text_bl.x, text_bl.y)) self.region_ph -= text_reg test_jj = AsymSquidDCFlux(test_struct1.center, SQUID_PARAMETERS, side=1) self.test_squids.append(test_jj) test_jj.place(self.region_el) # test structure with low critical current test_struct2 = TestStructurePads(struct_center + DPoint(0.3e6, 0)) test_struct2.place(self.region_ph) text_reg = pya.TextGenerator.default_generator().text( "9.66 nA", 0.001, 50, False, 0, 0) text_bl = test_struct2.empty_rectangle.origin + DPoint( test_struct2.gnd_gap, -4 * test_struct2.gnd_gap) text_reg.transform(ICplxTrans(1.0, 0, False, text_bl.x, text_bl.y)) self.region_ph -= text_reg test_jj = AsymSquidDCFlux(test_struct2.center, SQUID_PARAMETERS, side=-1) self.test_squids.append(test_jj) test_jj.place(self.region_el) # test structure for bridge DC contact test_struct3 = TestStructurePads(struct_center + DPoint(0.6e6, 0)) test_struct3.place(self.region_ph) text_reg = pya.TextGenerator.default_generator().text( "DC", 0.001, 50, False, 0, 0) text_bl = test_struct3.empty_rectangle.origin + DPoint( test_struct3.gnd_gap, -4 * test_struct3.gnd_gap) text_reg.transform( ICplxTrans(1.0, 0, False, test_struct3.center.x, text_bl.y)) self.region_ph -= text_reg test_bridges = [] for i in range(3): bridge = Bridge1(test_struct3.center + DPoint(50e3 * (i - 1), 0), gnd_touch_dx=20e3) test_bridges.append(bridge) bridge.place(self.region_bridges1, region_name="bridges_1") bridge.place(self.region_bridges2, region_name="bridges_2") # bandages test structures test_dc_el2_centers = [ DPoint(2.5e6, 2.4e6), DPoint(4.2e6, 1.6e6), DPoint(9.0e6, 3.8e6) ] for struct_center in test_dc_el2_centers: test_struct1 = TestStructurePads(struct_center) test_struct1.place(self.region_ph) text_reg = pya.TextGenerator.default_generator().text( "Bandage", 0.001, 40, False, 0, 0) text_bl = test_struct1.empty_rectangle.origin + DPoint( test_struct1.gnd_gap, -4 * test_struct1.gnd_gap) text_reg.transform(ICplxTrans(1.0, 0, False, text_bl.x, text_bl.y)) self.region_ph -= text_reg rec_width = 10e3 rec_height = test_struct1.rectangles_gap + 2 * rec_width p1 = struct_center - DVector(rec_width / 2, rec_height / 2) dc_rec = Rectangle(p1, rec_width, rec_height) dc_rec.place(self.region_el2)
def init_ph_el_conn_pads(self, leg_side=0): ''' draw top contact pad ''' origin = DPoint(0, 0) pars = self.params top_pad_center = origin + DVector(0, pars.pads_distance / 2) self.pad_top = Circle(top_pad_center, pars.pad_r, n_pts=pars.n, offset_angle=np.pi / 2) self.primitives["pad_top"] = self.pad_top self.top_ph_el_conn_pad = DPathCL( pts=[top_pad_center, origin + DPoint(0, pars.sq_dy / 2)], width=pars.contact_pad_width) self.primitives["top_ph_el_conn_pad"] = self.top_ph_el_conn_pad ''' draw bottom DC flux line ''' if leg_side == 1 or leg_side == 0: # print(self.bot_inter_lead_dx) self.bot_dc_flux_line_right = CPWRLPath( origin=origin + DPoint( pars.flux_line_dx / 2, -(pars.sq_dy / 4 + pars.flux_line_dy) - pars.flux_line_outer_width / 2), shape="LRL", cpw_parameters=[ CPWParameters(width=pars.flux_line_contact_width, gap=0), CPWParameters(smoothing=True), CPWParameters(width=pars.flux_line_outer_width, gap=0) ], turn_radiuses=max(pars.flux_line_outer_width, pars.flux_line_contact_width), segment_lengths=[ pars.flux_line_dy + pars.flux_line_outer_width, pars.flux_line_dx / 2 - self.bot_inter_lead_dx ], turn_angles=[np.pi / 2], trans_in=Trans.R90) self.primitives["bot_dc_flux_line_right"] = \ self.bot_dc_flux_line_right if leg_side == 0 or leg_side == -1: self.bot_dc_flux_line_left = CPWRLPath( origin=origin + DPoint( -pars.flux_line_dx / 2, -(pars.sq_dy / 4 + pars.flux_line_dy) - pars.flux_line_outer_width / 2), shape="LRL", cpw_parameters=[ CPWParameters(width=pars.flux_line_contact_width, gap=0), CPWParameters(smoothing=True), CPWParameters(width=pars.flux_line_outer_width, gap=0) ], turn_radiuses=max(pars.flux_line_outer_width, pars.flux_line_contact_width), segment_lengths=[ pars.flux_line_dy + pars.flux_line_outer_width, pars.flux_line_dx / 2 - self.bot_inter_lead_dx ], turn_angles=[-np.pi / 2], trans_in=Trans.R90) self.primitives["bot_dc_flux_line_left"] = \ self.bot_dc_flux_line_left
# p2 = my_design.sfs.connections[1] # # CPW(start=p1, end=p1 + DPoint(0, b - p1.y), cpw_params=My_Design.Z_narrow).place(my_design.region_ph) # CPW(start=p2, end=p2 + DPoint(0, -p2.y), cpw_params=My_Design.Z).place(my_design.region_ph) # my_design.show() # # freqs = np.linspace(1e9, 5e9, 300) # my_design.set_fixed_parameters(freqs) # my_design.set_swept_parameters( {"simBox": [SimulationBox(a, b, 100+20*k, 100+20*k) for k in range(11)]} ) # my_design.simulate_sweep() # my_design.save() my_design.draw() alpha = 2.0 dr = DVector(my_design.sfs.r_out, my_design.sfs.r_out) p1 = my_design.sfs_center - dr p2 = p1 + dr * alpha box = pya.Box().from_dbox(DBox(p1, p2)) my_design.crop(pya.Box().from_dbox(DBox(p1, p2))) my_design.region_ph.trans freqs = np.linspace(1e9, 5e9, 300) my_design.set_fixed_parameters(freqs) my_design.set_swept_parameters({ "simBox": [ SimulationBox(box.width(), box.height(), 200 + 2 * i, 100 + 1 * i) for i in range(6) ] }) my_design.simulate_sweep()
def __bridgify_CPW(self, cpw, bridges_step, dest=None, bridge_layer1=-1, bridge_layer2=-1, dest2=None, avoid_points=[], avoid_distance=0): """ Function puts bridge patterns to fabricate bridges on coplanar waveguide `cpw` with bridges having period of `bridges_step` along coplanar's wave propagation direction. Bridges are distributed over coplanar starting with its center. Parameters ---------- cpw : Union[CPW, CPWArc, DPathCPW] instance of coplanar class to be bridged during fabrication bridges_step : float distance between centers of bridges in nm dest : pya.Cell cell to place bridge polygons at bridge_layer1 : int index of the layer in the `cell` with ground touching polygons bridge_layer2 : int index of the layer in the `cell` with empty polygons avoid_points : list[Union[DPoint,Point,Vector, DVector]] list points that you wish to keep bridges away avoid_distance : float distance in nm where there will be no bridges near the `avoid_points` Returns ------- None """ if isinstance(cpw, CPW): # recursion base alpha = atan2(cpw.dr.y, cpw.dr.x) cpw_len = cpw.dr.abs() if cpw_len < (self.bridge_width + self.surround_gap): return cpw_dir_unit_vector = cpw.dr / cpw.dr.abs() # bridge with some initial dimensions tmp_bridge = Bridge1(DPoint(0, 0)) bridge_width = tmp_bridge.gnd_touch_dx + 2 * tmp_bridge.surround_gap # number of additional bridges on either side of center additional_bridges_n = int( (cpw_len / 2 - bridge_width / 2) // bridges_step) bridge_centers = [] for i in range(-additional_bridges_n, additional_bridges_n + 1): bridge_center = cpw.start + ( cpw_len / 2 + i * bridges_step) * cpw_dir_unit_vector avoid = False for avoid_point in avoid_points: if (avoid_point - bridge_center).abs() < avoid_distance: avoid = True break if not avoid: bridge_centers.append(bridge_center) bridges = [] for center in bridge_centers: bridges.append( Bridge1(center, trans_in=DCplxTrans(1, alpha / pi * 180, False, 0, 0))) for bridge in bridges: bridge.place(dest=dest, layer_i=bridge_layer1, region_name="bridges_1") if dest2 is not None: bridge.place(dest=dest2, layer_i=bridge_layer2, region_name="bridges_2") else: bridge.place(dest=dest, layer_i=bridge_layer2, region_name="bridges_2") elif isinstance(cpw, CPWArc): # only 1 bridge is placed, in the middle of an arc alpha_mid = cpw.alpha_start + cpw.delta_alpha / 2 - np.pi / 2 # unit vector from a center of the arc to its mid point v_arc_mid = DVector(np.cos(alpha_mid), np.sin(alpha_mid)) arc_mid = cpw.center + cpw.R * v_arc_mid # tangent vector to the center of a bridge v_arc_mid_tangent = DCplxTrans(1, 90, False, 0, 0) * v_arc_mid alpha = np.arctan2(v_arc_mid_tangent.y, v_arc_mid_tangent.x) bridge = Bridge1(center=arc_mid, trans_in=DCplxTrans(1, alpha / pi * 180, False, 0, 0)) bridge.place(dest=dest, layer_i=bridge_layer1, region_name="bridges_1") if dest2 is not None: bridge.place(dest=dest2, layer_i=bridge_layer2, region_name="bridges_2") else: bridge.place(dest=dest, layer_i=bridge_layer2, region_name="bridges_2") elif isinstance(cpw, CPWRLPath) or isinstance(cpw, Coil_type_1)\ or isinstance(cpw, DPathCPW): for name, primitive in cpw.primitives.items(): if isinstance(primitive, CPW): Bridge1.bridgify_CPW(primitive, bridges_step, dest, bridge_layer1, bridge_layer2, dest2=dest2, avoid_points=avoid_points, avoid_distance=avoid_distance) else: # do nothing for other shapes return
if __name__ == "__main__": resolution_dx = 4e3 resolution_dy = 4e3 for k in list(range(5))[1:2]: ### DRAWING SECTION START ### design = Design5Q("testScript") design.draw(q_idx=k) worm = design.resonators[k] xmonCross = design.xmons[k] worm_start = list(worm.primitives.values())[0].start # draw open end at the resonators start p1 = worm_start - DVector(design.Z_res.b / 2, 0) rec = Rectangle(p1, design.Z_res.b, design.Z_res.b / 2, inverse=True) rec.place(design.region_ph) if worm_start.x < xmonCross.center.x: dr = (worm_start - xmonCross.cpw_r.end) else: dr = (worm_start - xmonCross.cpw_l.end) dr.x = abs(dr.x) dr.y = abs(dr.y) center = (worm_start + xmonCross.center) / 2 box_side_x = 8 * xmonCross.sideX_length box_side_y = 8 * xmonCross.sideY_length dv = DVector(box_side_x / 2, box_side_y / 2)
def draw_flux_control_lines(self): tmp_reg = self.region_ph # place caplanar line 1 fl _p1 = self.contact_pads[1].end _p2 = self.contact_pads[1].end + DPoint(1e6, 0) _p3 = DPoint(self.squids[0].bot_dc_flux_line_left.start.x, self.cont_lines_y_ref) _p4 = DPoint(_p3.x, self.xmons[0].center.y - self.xmons[0].cpw_l.b / 2) self.cpwrl_fl1 = DPathCPW( points=[_p1, _p2, _p3, _p4], cpw_parameters=self.z_md_fl, turn_radiuses=self.ctr_lines_turn_radius, ) self.cpwrl_fl1.place(tmp_reg) self.cpw_fl_lines.append(self.cpwrl_fl1) # place caplanar line 2 fl _p1 = self.contact_pads[2].end _p2 = self.contact_pads[2].end + DPoint(1e6, 0) _p3 = DPoint(self.squids[1].bot_dc_flux_line_left.start.x, self.cont_lines_y_ref) _p4 = DPoint(_p3.x, self.xmons[1].cpw_bempt.end.y) self.cpwrl_fl2 = DPathCPW( points=[_p1, _p2, _p3, _p4], cpw_parameters=self.z_md_fl, turn_radiuses=self.ctr_lines_turn_radius, ) self.cpwrl_fl2.place(tmp_reg) self.cpw_fl_lines.append(self.cpwrl_fl2) # place caplanar line 3 fl _p1 = self.contact_pads[4].end _p2 = self.contact_pads[4].end + DPoint(0, 1e6) _p3 = _p2 + DPoint(-1e6, 1e6) _p4 = DPoint(self.squids[2].bot_dc_flux_line_left.start.x, self.cont_lines_y_ref) _p5 = DPoint(_p4.x, self.xmons[2].cpw_bempt.end.y) self.cpwrl_fl3 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5], cpw_parameters=self.z_md_fl, turn_radiuses=self.ctr_lines_turn_radius, ) self.cpwrl_fl3.place(tmp_reg) self.cpw_fl_lines.append(self.cpwrl_fl3) # place caplanar line 4 fl _p1 = self.contact_pads[6].end _p2 = self.contact_pads[6].end + DPoint(-1.5e6, 0) _p3 = DPoint(self.squids[3].bot_dc_flux_line_left.start.x, self.cont_lines_y_ref) _p4 = DPoint(_p3.x, self.xmons[3].cpw_bempt.end.y) self.cpwrl_fl4 = DPathCPW( points=[_p1, _p2, _p3, _p4], cpw_parameters=self.z_md_fl, turn_radiuses=self.ctr_lines_turn_radius, ) self.cpwrl_fl4.place(tmp_reg) self.cpw_fl_lines.append(self.cpwrl_fl4) # place caplanar line 5 fl _p1 = self.contact_pads[8].end _p2 = self.contact_pads[8].end + DPoint(-0.3e6, 0) _p4 = DPoint(self.squids[4].bot_dc_flux_line_left.start.x, self.cont_lines_y_ref) _p3 = _p4 + DVector(2e6, 0) _p5 = DPoint(_p4.x, self.xmons[4].center.y - self.xmons[4].cpw_l.b / 2) self.cpwrl_fl5 = DPathCPW( points=[_p1, _p2, _p3, _p4, _p5], cpw_parameters=self.z_md_fl, turn_radiuses=self.ctr_lines_turn_radius, ) self.cpwrl_fl5.place(tmp_reg) self.cpw_fl_lines.append(self.cpwrl_fl5)
def init_primitives(self): # introducing shorthands for long-named variables origin = DPoint(0, 0) pars = self.squid_params # (TC) Top contact polygon tc_p1 = DPoint( 0, pars.squid_dy / 2 + pars.SQT_dy + pars.TCW_dy + pars.TC_dy) tc_p2 = tc_p1 + DVector(0, -pars.TC_dy) self.TC = CPW(start=tc_p1, end=tc_p2, width=pars.TC_dx, gap=0) self.primitives["TC"] = self.TC # (TCW) Top contact wire tcw_p1 = self.TC.end tcw_p2 = tcw_p1 + DVector(0, -pars.TCW_dy) self.TCW = CPW(start=tcw_p1, end=tcw_p2, width=pars.TCW_dx, gap=0) self.primitives["TCW"] = self.TCW # (SQT) squid loop top sqt_p1 = origin + DVector(-pars.SQT_dx / 2, pars.squid_dy / 2 + pars.SQT_dy / 2) sqt_p2 = sqt_p1 + DVector(pars.SQT_dx, 0) self.SQT = CPW(start=sqt_p1, end=sqt_p2, width=pars.SQT_dy, gap=0) self.primitives["SQT"] = self.SQT # (SQLTT) squid loop left top thick sqltt_p1 = self.SQT.start + DVector(pars.SQLTT_dx / 2, -pars.SQT_dy / 2) sqltt_p2 = sqltt_p1 + DVector(0, -pars.SQLTT_dy) self.SQLTT = CPW(start=sqltt_p1, end=sqltt_p2, width=pars.SQLTT_dx, gap=0) self.primitives["SQLTT"] = self.SQLTT # (SQLTJJ) squid loop left top JJ sqltjj_p1 = self.SQLTT.end sqltjj_p2 = sqltjj_p1 + DVector(0, -pars.SQLTJJ_dy) self.SQLTJJ = CPW(start=sqltjj_p1, end=sqltjj_p2, width=pars.SQLTJJ_dx, gap=0) self.primitives["SQLTJJ"] = self.SQLTJJ # (SQB) squid bottom sqb_p1 = origin + DVector(-pars.squid_dx / 2 - pars.SQLBT_dx, -pars.squid_dy / 2 - pars.SQB_dy / 2) sqb_p2 = sqb_p1 + DVector( pars.squid_dx + pars.SQLBT_dx + pars.SQRBT_dx, 0) self.SQB = CPW(start=sqb_p1, end=sqb_p2, width=pars.SQB_dy, gap=0) self.primitives["SQB"] = self.SQB # (SQLBT) squid left bottom thick sqlbt_p1 = self.SQB.start + \ DVector(pars.SQLBT_dx / 2, pars.SQB_dy / 2) + \ DVector(0, pars.SQLBT_dy) sqlbt_p2 = sqlbt_p1 + DVector(0, -pars.SQLBT_dy) self.SQLBT = CPW(start=sqlbt_p1, end=sqlbt_p2, width=pars.SQLBT_dx, gap=0) self.primitives["SQLBT"] = self.SQLBT # (SQLBJJ) squid left botton JJ if ((pars.SQLBT_dx / 2 + pars.SQLBJJ_dx + pars.SQLTJJ_dx) < pars.JJC): raise Warning("please, increase SQLBJJ_dy is too low") sqlbjj_p1 = self.SQLBT.start + DVector(pars.SQLBT_dx / 2, -pars.SQLBJJ_dy / 2) sqlbjj_p2 = sqlbjj_p1 + DVector(pars.SQLBJJ_dx, 0) self.SQLBJJ = CPW(start=sqlbjj_p1, end=sqlbjj_p2, width=pars.SQLBJJ_dy, gap=0) self.primitives["SQLBJJ"] = self.SQLBJJ # (SQRTT) squid loop right top thick sqrtt_p1 = self.SQT.end + DVector(-pars.SQRTT_dx / 2, -pars.SQT_dy / 2) sqrtt_p2 = sqrtt_p1 + DVector(0, -pars.SQRTT_dy) self.SQRTT = CPW(start=sqrtt_p1, end=sqrtt_p2, width=pars.SQRTT_dx, gap=0) self.primitives["SQRTT"] = self.SQRTT # (SQRTJJ) squid loop right top JJ sqrtjj_p1 = self.SQRTT.end sqrtjj_p2 = sqrtjj_p1 + DVector(0, -pars.SQRTJJ_dy) self.SQRTJJ = CPW(start=sqrtjj_p1, end=sqrtjj_p2, width=pars.SQRTJJ_dx, gap=0) self.primitives["SQRTJJ"] = self.SQRTJJ # (SQRBT) squid right bottom thick sqrbt_p1 = self.SQB.end + \ DVector(-pars.SQRBT_dx / 2, pars.SQB_dy / 2) + \ DVector(0, pars.SQRBT_dy) sqrbt_p2 = sqrbt_p1 + DVector(0, -pars.SQRBT_dy) self.SQRBT = CPW(start=sqrbt_p1, end=sqrbt_p2, width=pars.SQRBT_dx, gap=0) self.primitives["SQRBT"] = self.SQRBT # (SQRBJJ) squid right botton JJ if ((pars.SQRBT_dx / 2 + pars.SQRBJJ_dx + pars.SQRTJJ_dx) < pars.JJC): raise Warning("please, increase SQLBJJ_dy is too low") sqrbjj_p1 = self.SQRBT.start + DVector(-pars.SQRBT_dx / 2, -pars.SQRBJJ_dy / 2) sqrbjj_p2 = sqrbjj_p1 + DVector(-pars.SQRBJJ_dx, 0) self.SQRBJJ = CPW(start=sqrbjj_p1, end=sqrbjj_p2, width=pars.SQRBJJ_dy, gap=0) self.primitives["SQRBJJ"] = self.SQRBJJ ''' following code can enclude multiple bottom connections ''' if isinstance(pars.bot_wire_x, list): pass else: pars.bot_wire_x = [pars.bot_wire_x] for i, x in enumerate(pars.bot_wire_x): # (BC) bottom contact polygon bc_p1 = DPoint(x, -pars.squid_dy / 2 - pars.BCW_dy) bc_p2 = bc_p1 + DVector(0, -pars.BC_dy) name = "BC" + str(i) setattr(self, name, CPW(start=bc_p1, end=bc_p2, width=pars.BC_dx, gap=0)) self.primitives[name] = getattr(self, name) # (BCW) Bottom contact wire bcw_p1 = getattr(self, "BC"+str(i)).start + \ DVector(0, pars.BCW_dy) bcw_p2 = bcw_p1 + DVector(0, -pars.BCW_dy) name = "BCW" + str(i) setattr(self, name, CPW(start=bcw_p1, end=bcw_p2, width=pars.BCW_dx, gap=0)) self.primitives[name] = getattr(self, name) # (BCE) bottom contact extension if x < (-pars.SQB_dx / 2 + pars.BCW_dx / 2): bce_p1 = getattr(self, "BCW"+str(i)).start + \ DVector(-pars.BCW_dx/2, pars.SQB_dy/2) bce_p2 = self.SQB.start elif x > (pars.SQB_dx / 2 - pars.BCW_dx / 2): bce_p1 = getattr(self, "BCW" + str(i)).start + \ DVector(pars.BCW_dx / 2, pars.SQB_dy / 2) bce_p2 = self.SQB.end else: continue name = "BCE" + str(i) setattr(self, name, CPW(start=bce_p1, end=bce_p2, width=pars.SQB_dy, gap=0)) self.primitives[name] = getattr(self, name)