Пример #1
0
    def init_primitives(self):

        R_index = 0
        L_index = 0
        origin = DPoint(0,0)
        
        prev_primitive_end = origin
        prev_primitive_end_angle = 0
        
        for i, symbol in enumerate(self._shape_string):
                              
            if( symbol == 'R' ):
                if( self._turn_angles[R_index] > 0 ):
                    turn_radius = self._turn_radiuses[R_index]
                else:
                    turn_radius =-self._turn_radiuses[R_index]
                                        
                cpw_arc = CPW_arc(self._cpw_parameters[i], prev_primitive_end, 
                          turn_radius, self._turn_angles[R_index], 
                            trans_in = DCplxTrans(1, prev_primitive_end_angle*180/pi, False, 0, 0))
                
                self.primitives["arc_"+str(R_index)] = cpw_arc
                R_index += 1    
                
            elif symbol == 'L':
            
                # Turns are reducing segments' lengths so as if there were no roundings at all
                
                # next 'R' segment if exists
                if( i+1 < self._N_elements
                    and self._shape_string[i+1] == 'R' 
                    and abs(self._turn_angles[R_index]) < pi ):
                            coeff = abs(tan(self._turn_angles[R_index]/2))
                            self._segment_lengths[L_index] -= self._turn_radiuses[R_index]*coeff
                # previous 'R' segment if exists
                if( i-1 > 0
                    and self._shape_string[i-1] == 'R' 
                    and abs(self._turn_angles[R_index-1]) < pi ):    
                        coeff = abs(tan(self._turn_angles[R_index-1]/2))
                        self._segment_lengths[L_index] -= self._turn_radiuses[R_index-1]*coeff
                        
                #if( self._segment_lengths[L_index] < 0 ):
                #    print(self._segment_lengths[L_index])
                #    print("CPW_RL_Path warning: segment length is less than zero")
                #    print("L_index = {}".format(L_index))

                    
                cpw = CPW(self._cpw_parameters[i].width, self._cpw_parameters[i].gap,
                        prev_primitive_end, prev_primitive_end + DPoint(self._segment_lengths[L_index], 0),
                            trans_in=DCplxTrans(1, prev_primitive_end_angle*180/pi, False, 0, 0))
                            
                self.primitives["cpw_"+str(L_index)] = cpw
                L_index += 1 
            
            primitive = list(self.primitives.values())[i]
            prev_primitive_end = primitive.end
            prev_primitive_end_angle = primitive.alpha_end
                
        self.connections = [origin, list(self.primitives.values())[-1].end]
        self.angle_connections = [0, list(self.primitives.values())[-1].alpha_end]
Пример #2
0
 def init_primitives( self ):
     self.arc1 = CPW_arc( self.Z0, DPoint(0,0), self.R1, pi/4 )
     self.cop1 = CPW( self.Z0.width, self.Z0.gap, self.arc1.end, self.arc1.end + DPoint( sin(pi/4), sin(pi/4) )*self.L1 )
     self.arc2 = CPW_arc( self.Z0, self.cop1.end, self.R2, pi/4, trans_in=DCplxTrans( 1,45,False,0,0 ) )
     self.cop2 = CPW( self.Z0.width, self.Z0.gap,  self.arc2.end, self.arc2.end + DPoint( 0,self.L2 ) )
     
     self.connections = [self.arc1.start,self.cop2.end]
     self.angle_connections = [self.arc1.alpha_start, self.cop2.alpha_end]
     
     self.primitives = {"arc1":self.arc1, "cop1":self.cop1, "arc2":self.arc2, "cop2":self.cop2}
Пример #3
0
    def _init_regions_trans(self):
        self.init_regions()  # must be implemented in every subclass

        dr_origin = DSimplePolygon([DPoint(0, 0)])
        if (self.DCplxTrans_init is not None):
            # constructor trans displacement
            dCplxTrans_temp = DCplxTrans(1, 0, False,
                                         self.DCplxTrans_init.disp)
            self.make_trans(dCplxTrans_temp)
            dr_origin.transform(dCplxTrans_temp)

            # rest of the constructor trans functions
            dCplxTrans_temp = self.DCplxTrans_init.dup()
            dCplxTrans_temp.disp = DPoint(0, 0)
            self.make_trans(dCplxTrans_temp)
            dr_origin.transform(dCplxTrans_temp)

        # translation to the old origin (self.connections are already contain proper values)
        self.make_trans(DCplxTrans(1, 0, False,
                                   self.origin))  # move to the origin
        self.origin += dr_origin.point(0)
Пример #4
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.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 = CPW_arc(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 = CPW_arc(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 = CPW_arc(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
        }
Пример #5
0
    def _init_primitives_trans(self):
        self.init_primitives()  # must be implemented in every subclass
        dr_origin = DSimplePolygon([DPoint(0, 0)])
        if (self.DCplxTrans_init is not None):
            # constructor trans displacement
            dCplxTrans_temp = DCplxTrans(1, 0, False,
                                         self.DCplxTrans_init.disp)
            self.make_trans(dCplxTrans_temp)
            dr_origin.transform(dCplxTrans_temp)

            # rest of the constructor trans functions
            dCplxTrans_temp = self.DCplxTrans_init.dup()
            dCplxTrans_temp.disp = DPoint(0, 0)
            self.make_trans(dCplxTrans_temp)
            dr_origin.transform(dCplxTrans_temp)

        dCplxTrans_temp = DCplxTrans(1, 0, False, self.origin)
        self.make_trans(dCplxTrans_temp)  #move to the origin
        self.origin += dr_origin.point(0)

        # FOLLOWING CYCLE GIVES WRONG INFO ABOUT FILLED AND ERASED AREAS
        for element in self.primitives.values():
            self.metal_region += element.metal_region
            self.empty_region += element.empty_region
Пример #6
0
 def init_regions( self ):
     self.connections = [DPoint(0,0),self.dr]
     self.start = DPoint(0,0)
     self.end = self.start + self.dr
     alpha = atan2( self.dr.y, self.dr.x )
     self.angle_connections = [alpha,alpha]
     alpha_trans = ICplxTrans().from_dtrans( DCplxTrans( 1,alpha*180/pi,False, self.start ) )
     
     metal_poly = DSimplePolygon( [DPoint(0,-self.width/2),
                                                    DPoint(self.dr.abs(),-self.width/2), 
                                                    DPoint(self.dr.abs(),self.width/2),
                                                    DPoint(0,self.width/2)] )
     self.connection_edges = [3,1]
     self.metal_region.insert( klayout.db.SimplePolygon().from_dpoly( metal_poly ) )
     if( self.gap != 0 ):
         self.empty_region.insert( klayout.db.Box( Point().from_dpoint(DPoint(0,self.width/2)), Point().from_dpoint(DPoint( self.dr.abs(), self.width/2 + self.gap )) ) )
         self.empty_region.insert( klayout.db.Box( Point().from_dpoint(DPoint(0,-self.width/2-self.gap)), Point().from_dpoint(DPoint( self.dr.abs(), -self.width/2 )) ) )
     self.metal_region.transform( alpha_trans )
     self.empty_region.transform( alpha_trans )
Пример #7
0
 def init_regions( self ):
     self.connections = [DPoint(0,0),self.dr]
     self.start = DPoint(0,0)
     self.end = self.start + self.dr
     self.L0 = self.start.distance(self.end) / (self.N_air_bridges +1)
     alpha = atan2( self.dr.y, self.dr.x )
     self.angle_connections = [alpha,alpha]
     alpha_trans = ICplxTrans().from_dtrans( DCplxTrans( 1,alpha*180/pi,False, self.start ) )
     for i in range(self.N_air_bridges):
         self.air_bridge = klayout.db.DBox( DPoint((i+1)*self.L0, -self.b/2 - 2e3), DPoint((i+1)*self.L0+2e3, self.b/2 + 2e3) ) 
         self.metal_region.insert( klayout.db.Box().from_dbox( self.air_bridge ) )
         
         self.air_bridge_2 = klayout.db.DBox( DPoint((i+1)*self.L0-self.b/4+1e3, -self.b/2 - 2e3), DPoint((i+1)*self.L0+1e3+self.b/4, -self.b/2 - 4e3) ) 
         self.metal_region.insert( klayout.db.Box().from_dbox( self.air_bridge_2 ) )
         
         self.air_bridge_3 = klayout.db.DBox( DPoint((i+1)*self.L0-self.b/4+1e3, self.b/2 + 2e3), DPoint((i+1)*self.L0+1e3+self.b/4, self.b/2 + 4e3) ) 
         self.metal_region.insert( klayout.db.Box().from_dbox( self.air_bridge_3 ) )
    
     self.metal_region.transform( alpha_trans )
Пример #8
0
 def init_regions(self):
     self.connections = [DPoint(0, 0), DPoint(self.dr.abs(), 0)]
     self.angle_connections = [0, 0]
     alpha = atan2(self.dr.y, self.dr.x)
     self.angle_connections = [alpha,alpha]
     alpha_trans = DCplxTrans(1, alpha*180/pi, False, 0, 0)
     
     m_poly = DSimplePolygon([DPoint(0,-self.Z0.width/2), DPoint(self.dr.abs(), -self.Z1.width/2), 
                                 DPoint(self.dr.abs(),self.Z1.width/2), DPoint(0,self.Z0.width/2)] )
     e_poly1 = DSimplePolygon([DPoint(0,-self.Z0.b/2), DPoint(self.dr.abs(), -self.Z1.b/2), 
                                 DPoint(self.dr.abs(),-self.Z1.width/2), DPoint(0,-self.Z0.width/2)] )
     e_poly2 = DSimplePolygon([DPoint(0,self.Z0.b/2), DPoint(self.dr.abs(),self.Z1.b/2), 
                                 DPoint(self.dr.abs(),self.Z1.width/2), DPoint(0,self.Z0.width/2)] )
     
     m_poly.transform(alpha_trans)
     e_poly1.transform(alpha_trans)
     e_poly2.transform(alpha_trans)
     
     self.metal_region.insert(SimplePolygon.from_dpoly(m_poly))
     self.empty_region.insert(SimplePolygon.from_dpoly(e_poly1))
     self.empty_region.insert(SimplePolygon.from_dpoly(e_poly2))
Пример #9
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 = {}
        self.empty_regions = {}
        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._init_regions_trans()
Пример #10
0
    def init_primitives(self):

        origin = DPoint(0, 0)

        self.c_wave = CWave(origin,
                            self.r_out,
                            self.dr,
                            self.n_semiwaves,
                            self.s,
                            self.alpha,
                            self.r_curve,
                            n_pts=self.n_pts_cwave)
        self.primitives["c_wave"] = self.c_wave

        Z1_start = origin + DPoint(0, self.r_in + self.gap1 + self.width1 / 2)
        Z1_end = Z1_start + DPoint(0, -self.gap1 - self.width1 / 2 + self.dr)
        self.cpw1 = CPW(self.Z1.width, self.Z1.gap, Z1_start, Z1_end)
        self.primitives["cpw1"] = self.cpw1

        Z2_start = origin - DPoint(0, self.r_in + self.gap2 + self.width2 / 2)
        Z2_end = Z2_start - DPoint(0, -self.gap2 - self.width2 / 2 + self.dr)
        self.cpw2 = CPW(self.Z2.width, self.Z2.gap, Z2_start, Z2_end)
        self.primitives["cpw2"] = self.cpw2

        if isinstance(self.params, dict):
            self.c_wave_2_cpw_adapter = CWave2CPW(self.c_wave,
                                                  self.params,
                                                  n_pts=self.n_pts_arcs)
        else:
            # not recommended
            self.c_wave_2_cpw_adapter = CWave2CPW(self.c_wave,
                                                  self.params[7:15],
                                                  n_pts=self.n_pts_arcs)
        self.primitives["c_wave_2_cpw_adapter"] = self.c_wave_2_cpw_adapter

        p_squid = None
        squid_trans_in = None

        if not self.squid_pos:
            if (self.c_wave.n_segments % 2 == 1):
                squid_trans_in = DCplxTrans(1, -self.c_wave.alpha * 180 / pi,
                                            False, 0, 0)
                p_squid = origin
            else:
                squid_trans_in = None
                second_parity = self.c_wave.n_segments / 2
                y_shift = self.c_wave.L0 * sin(
                    self.c_wave.alpha) - self.c_wave.r_curve * (
                        1 / cos(self.c_wave.alpha) - 1)
                if (second_parity % 2 == 0):
                    p_squid = origin + DPoint(0, y_shift)
                else:
                    p_squid = origin + DPoint(0, -y_shift)
        else:
            squid_trans_in = None
            p_squid = origin - DPoint(
                self.squid_pos * (self.r_out - 1.8 * self.dr), 0)

        self.squid = Squid(p_squid, self.squid_params, trans_in=squid_trans_in)
        self.primitives["qubit"] = self.squid

        self.connections = [Z1_end, Z2_end]
        self.angle_connections = [pi / 2, 3 / 2 * pi]
Пример #11
0
class Element_Base():
    '''
    @brief: base class for simple single-layer or multi-layer elements and objects that are consisting of
            several polygons.
            metal_region polygons will be added to the design
            empty_region polygons will be erased from the background with 
            metal region polygons already added.

    '''
    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 = {}
        self.empty_regions = {}
        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._init_regions_trans()

    def init_regions(self):
        raise NotImplementedError

    # first it makes trans_init displacement
    # then the rest of the trans_init
    # then displacement of the current state to the origin
    # after all, origin should be updated
    def _init_regions_trans(self):
        self.init_regions()  # must be implemented in every subclass

        dr_origin = DSimplePolygon([DPoint(0, 0)])
        if (self.DCplxTrans_init is not None):
            # constructor trans displacement
            dCplxTrans_temp = DCplxTrans(1, 0, False,
                                         self.DCplxTrans_init.disp)
            self.make_trans(dCplxTrans_temp)
            dr_origin.transform(dCplxTrans_temp)

            # rest of the constructor trans functions
            dCplxTrans_temp = self.DCplxTrans_init.dup()
            dCplxTrans_temp.disp = DPoint(0, 0)
            self.make_trans(dCplxTrans_temp)
            dr_origin.transform(dCplxTrans_temp)

        # translation to the old origin (self.connections are already contain proper values)
        self.make_trans(DCplxTrans(1, 0, False,
                                   self.origin))  # move to the origin
        self.origin += dr_origin.point(0)

    def make_trans(self, dCplxTrans):
        if (dCplxTrans is not None):
            iCplxTrans = ICplxTrans().from_dtrans(dCplxTrans)
            self.metal_region.transform(iCplxTrans)
            self.empty_region.transform(iCplxTrans)
            self._update_connections(dCplxTrans)
            self._update_alpha(dCplxTrans)

    def _update_connections(self, dCplxTrans):
        if (dCplxTrans is not None):
            # the problem is, if i construct polygon with multiple points
            # their order in poly_temp.each_point() doesn't coinside with the
            # order of the list that was passed to the polygon constructor
            # so, when i perform transformation and try to read new values through poly_temp.each_point()
            # they values are rearranged
            # solution is: i need to create polygon for each point personally, and the initial order presists
            for i, pt in enumerate(self.connections):
                poly_temp = DSimplePolygon([pt])
                poly_temp.transform(dCplxTrans)
                self.connections[i] = poly_temp.point(0)

    def _update_alpha(self, dCplxTrans):
        if (dCplxTrans is not None):
            dCplxTrans_temp = dCplxTrans.dup()
            dCplxTrans_temp.disp = DPoint(0, 0)

            for i, alpha in enumerate(self.angle_connections):
                poly_temp = DSimplePolygon([DPoint(cos(alpha), sin(alpha))])
                poly_temp.transform(dCplxTrans_temp)
                pt = poly_temp.point(0)
                self.angle_connections[i] = atan2(pt.y, pt.x)

    def _update_origin(self, dCplxTrans):
        if (dCplxTrans is not None):
            poly_temp = DSimplePolygon([self.origin])
            poly_temp.transform(dCplxTrans)
            self.origin = poly_temp.point(0)

    def place(self, dest, layer_i=-1, region_name=None, merge=False):
        r_cell = None
        metal_region = None
        empty_region = None
        if (region_name == None):
            metal_region = self.metal_region
            empty_region = self.empty_region
        else:
            if (region_name in self.metal_regions):
                metal_region = self.metal_regions[region_name]
            else:
                metal_region = Region()

            if (region_name in self.empty_regions):
                empty_region = self.empty_regions[region_name]
            else:
                empty_region = Region()

        if (layer_i != -1):
            r_cell = Region(dest.begin_shapes_rec(layer_i))
            temp_i = dest.layout().layer(
                klayout.db.LayerInfo(PROGRAM.LAYER1_NUM, 0))
            r_cell += metal_region
            r_cell -= empty_region

            if (merge is True):
                r_cell.merge()

            dest.shapes(temp_i).insert(r_cell)
            dest.layout().clear_layer(layer_i)
            dest.layout().move_layer(temp_i, layer_i)
            dest.layout().delete_layer(temp_i)
        if (layer_i == -1
            ):  # dest is interpreted as instance of Region() class
            dest += metal_region
            dest -= empty_region
            if (merge is True):
                dest.merge()

    def add_sonnet_port(self, connection_idx):
        '''
        @brief: sets internal marker that during export to Sonnet
                   the port should be placed at the connection edge
                   with an index 'connection_idx' 
        '''
        print(self.connections)
        self.sonnet_port_connections.append(self.connections[connection_idx])
Пример #12
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
        }