예제 #1
0
    def test_2_DTrans(self):

        a = pya.DTrans()
        b = pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5))
        ma = pya.DCplxTrans(a, 0.5)
        mb = pya.DCplxTrans(b, 2.0)
        u = pya.DCplxTrans(a)

        self.assertEqual(str(ma), "r0 *0.5 0,0")
        self.assertEqual(str(mb), "m135 *2 17,5")

        self.assertEqual(ma == mb, False)
        self.assertEqual(ma == ma, True)
        self.assertEqual(ma != mb, True)
        self.assertEqual(ma != ma, False)

        i = mb.inverted()

        self.assertEqual(str(i), "m135 *0.5 2.5,8.5")
        self.assertEqual(str(pya.DCplxTrans.from_s(str(i))), str(i))
        self.assertEqual(i * mb == u, True)
        self.assertEqual(mb * i == u, True)

        self.assertEqual(str(mb.trans(pya.DPoint(1, 0))), "17,3")
        self.assertEqual(str(mb.ctrans(2)), "4.0")
        self.assertEqual(str(i.ctrans(2)), "1.0")
예제 #2
0
    def test_5_Trans_Hash(self):

        t1 = pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5))
        t2 = pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-7, 5))
        t3 = pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-4, 5))
        t4a = pya.DTrans(pya.DTrans.M135, pya.DPoint(18, 5))
        t4b = pya.DTrans(pya.DTrans.R90, pya.DPoint(18, 5))

        self.assertEqual(t1.hash() == t2.hash(), True)
        self.assertEqual(t1.hash() == t3.hash(), False)
        self.assertEqual(t1.hash() == t4a.hash(), False)
        self.assertEqual(t1.hash() == t4b.hash(), False)
        self.assertEqual(hash(t1) == hash(t2), True)
        self.assertEqual(hash(t1) == hash(t3), False)
        self.assertEqual(hash(t1) == hash(t4a), False)
        self.assertEqual(hash(t1) == hash(t4b), False)
        self.assertEqual(t1.__hash__() == t2.__hash__(), True)
        self.assertEqual(t1.__hash__() == t3.__hash__(), False)
        self.assertEqual(t1.__hash__() == t4a.__hash__(), False)
        self.assertEqual(t1.__hash__() == t4b.__hash__(), False)

        # Transformations can't be used as hash keys currently
        if False:

            h = {t1: "t1", t3: "t3", t4a: "t4a", t4b: "t4b"}

            self.assertEqual(h[t1], "t1")
            self.assertEqual(h[t2], "t1")
            self.assertEqual(h[t3], "t3")
            self.assertEqual(h[t4a], "t4a")
            self.assertEqual(h[t4b], "t4b")
예제 #3
0
    def test_5_Trans_FuzzyCompare(self):

        t1 = pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5))
        t2 = pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-7, 5))
        t3 = pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-4, 5))
        t4a = pya.DTrans(pya.DTrans.M135, pya.DPoint(18, 5))
        t4b = pya.DTrans(pya.DTrans.R90, pya.DPoint(18, 5))

        self.assertEqual(t1 == t2, True)
        self.assertEqual(t1 != t2, False)
        self.assertEqual(t1 < t2, False)
        self.assertEqual(t2 < t1, False)

        self.assertEqual(t1 == t3, False)
        self.assertEqual(t1 != t3, True)
        self.assertEqual(t1 < t3, True)
        self.assertEqual(t3 < t1, False)

        self.assertEqual(t1 == t4a, False)
        self.assertEqual(t1 != t4a, True)
        self.assertEqual(t1 < t4a, True)
        self.assertEqual(t4a < t1, False)

        self.assertEqual(t1 == t4b, False)
        self.assertEqual(t1 != t4b, True)
        self.assertEqual(t1 < t4b, False)
        self.assertEqual(t4b < t1, True)
예제 #4
0
        def pcell(self, layout, cell=None, params=None):
            if cell is None:
                cell = layout.create_cell(self.name)

            cp = self.parse_param_args(params)
            origin, _, _ = CellWithPosition.origin_ex_ey(self,
                                                         params,
                                                         multiple_of_90=True)

            if from_library is not None:
                # Topcell must be same as filename
                gdscell = get_lib_cell(layout, cell_name, from_library)
            else:
                # BUG loading this file twice segfaults klayout
                layout2 = pya.Layout()
                layout2.read(os.path.join(gds_dir, filename))
                gdscell2 = layout2.cell(cell_name)
                gdscell = layout.create_cell(cell_name)
                gdscell.copy_tree(gdscell2)
                del gdscell2
                del layout2

            rot_DTrans = pya.DTrans.R0
            angle_multiple_90 = cp.angle_ex // 90
            rot_DTrans.rot = (angle_multiple_90) % 4

            cell.insert(
                pya.DCellInstArray(gdscell.cell_index(),
                                   pya.DTrans(rot_DTrans, origin)))

            return cell, {}
예제 #5
0
    def test_2_DPolygon(self):

        pts = [pya.DPoint(0, 0)]
        p = pya.DPolygon(pts, True)
        self.assertEqual(str(p), "(0,0)")

        arr = []
        for e in p.each_edge():
            arr.append(str(e))
        self.assertEqual(arr, ["(0,0;0,0)"])

        p = pya.DPolygon(pya.DBox(0, 0, 100, 100))
        p.insert_hole([pya.DPoint(0, 0), pya.DPoint(10, 0)], True)
        self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)")
        p.assign_hole(0, [pya.DPoint(0, 0), pya.DPoint(10, 0)])
        self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)")
        p.assign_hole(0, [pya.DPoint(0, 0), pya.DPoint(10, 0)], True)
        self.assertEqual(str(p), "(0,0;0,100;100,100;100,0/0,0;10,0)")

        pts = [pya.DPoint(0, 0), pya.DPoint(10, 0)]
        p = pya.DPolygon(pts, True)
        self.assertEqual(str(p), "(0,0;10,0)")
        self.assertEqual(str(pya.Polygon(p)), "(0,0;10,0)")

        p.hull = []
        self.assertEqual(str(p), "()")

        p.hull = [pya.DPoint(0, 0), pya.DPoint(10, 0)]
        self.assertEqual(str(p), "(0,0;10,0)")

        p.assign_hull([pya.DPoint(0, 0), pya.DPoint(10, 0)], True)
        self.assertEqual(str(p), "(0,0;10,0)")

        arr = []
        for e in p.each_edge():
            arr.append(str(e))
        self.assertEqual(arr, ["(0,0;10,0)", "(10,0;0,0)"])

        self.assertEqual(str(p.moved(1, 2)), "(1,2;11,2)")
        self.assertEqual(str(p.sized(2)), "(0,-2;0,2;10,2;10,-2)")
        self.assertEqual(str(p * 2), "(0,0;20,0)")
        self.assertEqual(str(p.transformed(pya.DTrans(pya.DTrans.R90))),
                         "(0,0;0,10)")

        pp = p.dup()
        pp.transform(pya.DTrans(pya.DTrans.R90))
        self.assertEqual(str(pp), "(0,0;0,10)")
예제 #6
0
  def test_1_Trans(self):

    a = pya.Trans()
    b = pya.Trans( pya.Trans.M135, pya.Point( 17, 5 ))
    c = pya.Trans( 3, True, pya.Point( 17, 5 ))
    d = pya.Trans( pya.Point( 17, 5 ))
    e = pya.Trans( pya.Trans.M135 )
    e2 = pya.Trans.from_dtrans( pya.DTrans.M135 )
    f = pya.Trans( pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 )) )

    self.assertEqual( str(a), "r0 0,0" )
    self.assertEqual( str(pya.Trans.from_s(str(a))), str(a) )
    self.assertEqual( str(b), "m135 17,5" )
    self.assertEqual( str(c), "m135 17,5" )
    self.assertEqual( str(d), "r0 17,5" )
    self.assertEqual( str(e), "m135 0,0" )
    self.assertEqual( str(e2), "m135 0,0" )
    self.assertEqual( str(f), "m135 17,5" )
    self.assertEqual( str(pya.Trans.from_s(str(f))), str(f) )

    self.assertEqual( str(b.trans( pya.Point( 1, 0 ))), "17,4" )

    self.assertEqual( a == b, False )
    self.assertEqual( a == a, True )
    self.assertEqual( a != b, True )
    self.assertEqual( a != a, False )
    self.assertEqual( (d * e) == b, True )
    self.assertEqual( (e * d) == b, False )

    i = c.inverted()

    self.assertEqual( str(i), "m135 5,17" )
    self.assertEqual( (i * b) == a, True )
    self.assertEqual( (b * i) == a, True )

    c = pya.Trans( 3, True, pya.Point( 17, 5 ))
    self.assertEqual( str(c), "m135 17,5" )
    c.disp = pya.Point(1, 7)
    self.assertEqual( str(c), "m135 1,7" )
    c.angle = 1
    self.assertEqual( str(c), "m45 1,7" )
    c.rot = 3
    self.assertEqual( str(c), "r270 1,7" )
    c.mirror = True
    self.assertEqual( str(c), "m135 1,7" )

    self.assertEqual( str(e.trans( pya.Edge(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
    self.assertEqual( str(( e * pya.Edge(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
    self.assertEqual( str(e.trans( pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
    self.assertEqual( str(( e * pya.Box(0, 1, 2, 3) )), "(-3,-2;-1,0)" )
    self.assertEqual( str(e.trans( pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
    self.assertEqual( str(( e * pya.Text("text", pya.Vector(0, 1)) )), "('text',m135 -1,0)" )
    self.assertEqual( str(e.trans( pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
    self.assertEqual( str(( e * pya.Polygon( [ pya.Point(0, 1), pya.Point(2, -3), pya.Point(4, 5) ] ) )), "(-5,-4;-1,0;3,-2)" )
    self.assertEqual( str(e.trans( pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
    self.assertEqual( str(( e * pya.Path( [ pya.Point(0, 1), pya.Point(2, 3) ], 10 ) )), "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false" )
예제 #7
0
    def test_4_Trans(self):

        a = pya.Trans()
        m = pya.CplxTrans(a, 1.1)
        da = pya.DTrans()
        dm = pya.DCplxTrans(da, 1.1)

        self.assertEqual(str(m), "r0 *1.1 0,0")
        self.assertEqual(str(pya.DCplxTrans.from_s(str(m))), str(m))
        self.assertEqual(str(m.trans(pya.Point(5, -7))), "5.5,-7.7")

        im = pya.ICplxTrans(a, 0.5)
        im_old = im.dup()

        self.assertEqual(str(im), "r0 *0.5 0,0")
        self.assertEqual(str(pya.ICplxTrans.from_s(str(im))), str(im))
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "3,-4")

        im = pya.ICplxTrans(m)
        self.assertEqual(str(im), "r0 *1.1 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "6,-8")

        im = pya.ICplxTrans(dm)
        self.assertEqual(str(im), "r0 *1.1 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "6,-8")

        im.assign(im_old)
        self.assertEqual(str(im), "r0 *0.5 0,0")
        self.assertEqual(str(im.trans(pya.Point(5, -7))), "3,-4")

        self.assertEqual(str(pya.ICplxTrans(5, -7)), "r0 *1 5,-7")

        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, 5, -7)),
                         "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.Point(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.Vector(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5, pya.DVector(5, -7))),
            "r180 *1.5 5,-7")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans.R180, 1.5)),
                         "r180 *1.5 0,0")

        c = pya.ICplxTrans.from_dtrans(pya.DCplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
        c = pya.ICplxTrans.from_trans(pya.CplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
예제 #8
0
def place_cell(parent_cell, pcell, ports_dict, placement_origin, relative_to=None, transform_into=False):
    """ Places an pya cell and return ports with updated positions
    Args:
        parent_cell: cell to place into
        pcell, ports_dict: result of KLayoutPCell.pcell call
        placement_origin: pya.Point object to be used as origin
        relative_to: port name
            the cell is placed so that the port is located at placement_origin
        transform_into:
            if used with relative_into, transform the cell's coordinate system
            so that its origin is in the given port.

    Returns:
        ports(dict): key:port.name, value: geometry.Port with positions relative to parent_cell's origin
    """
    offset = pya.DVector(0, 0)
    port_offset = placement_origin
    if relative_to is not None:
        offset = ports_dict[relative_to].position
        port_offset = placement_origin - offset
        if transform_into:
            # print(type(pcell))
            offset_transform = pya.DTrans(pya.DTrans.R0, -offset)
            for instance in pcell.each_inst():
                instance.transform(offset_transform)
            pcell.transform_into(offset_transform)
        else:
            placement_origin = placement_origin - offset

    transformation = pya.DTrans(pya.Trans.R0, placement_origin)
    instance = pya.DCellInstArray(pcell.cell_index(), transformation)
    parent_cell.insert(instance)
    for port in ports_dict.values():
        port.position += port_offset

    return ports_dict
예제 #9
0
    def test_5_CplxTrans_Hash(self):

        t1 = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                            1.0)
        t2a = pya.DCplxTrans(
            pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-7, 5)), 1.0)
        t2b = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0 + 1e-11)
        t2c = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0)
        t2c.angle = t2c.angle + 1e-11
        t3a = pya.DCplxTrans(
            pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-4, 5)), 1.0)
        t3b = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0 + 1e-4)
        t3c = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0)
        t3c.angle = t3c.angle + 1e-4
        t4 = pya.DCplxTrans(pya.DTrans(pya.DTrans.R90, pya.DPoint(18, 5)), 1.0)

        self.assertEqual(t1.hash() == t2a.hash(), True)
        self.assertEqual(t1.hash() == t2b.hash(), True)
        self.assertEqual(t1.hash() == t2c.hash(), True)
        self.assertEqual(t1.hash() == t3a.hash(), False)
        self.assertEqual(t1.hash() == t3b.hash(), False)
        self.assertEqual(t1.hash() == t3c.hash(), False)
        self.assertEqual(t3a.hash() == t3b.hash(), False)
        self.assertEqual(t3a.hash() == t3c.hash(), False)
        self.assertEqual(t3b.hash() == t3c.hash(), False)
        self.assertEqual(t1.hash() == t4.hash(), False)

        # Transformations can't be used as hash keys currently
        if False:

            h = {t1: "t1", t3a: "t3a", t3b: "t3b", t3c: "t3c", t4: "t4"}

            self.assertEqual(h[t1], "t1")
            self.assertEqual(h[t2a], "t1")
            self.assertEqual(h[t2b], "t1")
            self.assertEqual(h[t2c], "t1")
            self.assertEqual(h[t3a], "t3a")
            self.assertEqual(h[t3b], "t3b")
            self.assertEqual(h[t3c], "t3c")
            self.assertEqual(h[t4], "t4")
예제 #10
0
            def wrapper_pcell(self, layout, cell=None, params=None):
                global layer_map_dict
                try:
                    layer_map_dict[layout]
                except KeyError:
                    layer_map_dict[layout] = pya.LayerMap()
                if cell is None:
                    # copy source code of class and all its ancestors
                    source_code = "".join(
                        [inspect.getsource(klass) for klass in self.__class__.__mro__ if issubclass(klass, KLayoutPCell)])

                    # Default params before instantiation
                    original_default_params = {name: value["default"]
                                               for name, value in self.param_definition.items()}

                    # Updated params after instantiation and placement
                    # (could be bigger than the original default)
                    if params is not None:
                        default_params = dict(self.default_params, **params)
                    else:
                        default_params = self.default_params

                    # Differential parameters (non-default)
                    diff_params = {}
                    for name, value in original_default_params.items():
                        if default_params[name] != value:
                            diff_params[name] = default_params[name]

                    long_hash_pcell = sha256((source_code +
                                              str(diff_params) +
                                              self.name).encode()).hexdigest()
                    short_hash_pcell = long_hash_pcell[0:7]
                    cache_fname = f'cache_{self.__class__.__qualname__}_{short_hash_pcell}'
                    # if short_hash_pcell in cell_cache.keys():  # already loaded
                    #     print(f"Preloaded {self.__class__.__name__}: {diff_params}")
                    #     cached_cell, ports_bytecode, cellname = cell_cache[short_hash_pcell]
                    #     ports = pickle.loads(ports_bytecode)
                    #     # print('read:', cell_index, ports, cellname)
                    #     newcell = layout.create_cell(cellname)
                    #     newcell.copy_tree(cached_cell)
                    #     # newcell.insert(pya.DCellInstArray(cell.cell_index(),
                    #     #                                   pya.DTrans(pya.Trans.R0, pya.DPoint(0, 0))))
                    #     return newcell, deepcopy(ports)

                    def read_layout(layout, gds_filename):
                        global layer_map_dict
                        load_options = pya.LoadLayoutOptions()
                        load_options.text_enabled = True
                        load_options.set_layer_map(layer_map_dict[layout], True)

                        # store and take away the cell names of all cells read so far
                        # (by setting the cell name to "" the cells basically become invisible for
                        # the following read)
                        # take out the pcells
                        cell_list = [cell for cell in layout.each_cell()]
                        cell_indices = {cell.name: cell.cell_index() for cell in cell_list}
                        for i in cell_indices.values():
                            layout.rename_cell(i, "")

                        lmap = layout.read(gds_filename, load_options)
                        # in the new layout, get all cells names
                        cell_names2 = [(cell.cell_index(), cell.name)
                                       for cell in layout.each_cell()]

                        # make those cells point to older cells
                        prune_cells_indices = []
                        for i_duplicate, name_cached_cell in cell_names2:
                            if name_cached_cell in cell_indices.keys():
                                if name_cached_cell.startswith('cache_'):
                                    for parent_inst_array in layout.cell(i_duplicate).each_parent_inst():
                                        cell_instance = parent_inst_array.child_inst()
                                        cell_instance.cell = layout.cell(
                                            cell_indices[name_cached_cell])
                                    prune_cells_indices.append(i_duplicate)
                                else:
                                    # print('RENAME', name_cached_cell)
                                    k = 1
                                    while (name_cached_cell + f"_{k}") in cell_indices.keys():
                                        k += 1
                                    layout.rename_cell(i_duplicate, name_cached_cell + f"_{k}")

                        for i_pruned in prune_cells_indices:
                            # print('deleting cell', layout.cell(i_pruned).name)
                            layout.prune_cell(i_pruned, -1)

                        # every conflict should have been caught above
                        for name, i in cell_indices.items():
                            layout.rename_cell(i, name)

                        layer_map_dict[layout] = lmap
                        return lmap

                    cache_fname_gds = cache_fname + '.gds'
                    cache_fname_pkl = cache_fname + '.klayout.pkl'

                    os.makedirs(cache_dir, mode=0o775, exist_ok=True)

                    cache_fpath_gds = os.path.join(cache_dir, cache_fname_gds)
                    cache_fpath_pkl = os.path.join(cache_dir, cache_fname_pkl)
                    if os.path.isfile(cache_fpath_gds) and os.path.isfile(cache_fpath_pkl):
                        with open(cache_fpath_pkl, 'rb') as file:
                            ports, read_short_hash_pcell, cellname = pickle.load(file)
                        if debug:
                            print(f"Reading from cache: {cache_fname}: {diff_params}, {cellname}")
                        else:
                            print('r', end='', flush=True)
                        if not layout.has_cell(cache_fname):
                            read_layout(layout, cache_fpath_gds)
                        retrieved_cell = layout.cell(cache_fname)
                        cell = layout.create_cell(cellname)
                        cell.insert(pya.DCellInstArray(retrieved_cell.cell_index(),
                                                       pya.DTrans(pya.Trans.R0, pya.DPoint(0, 0))))
                        # cell.move_tree(retrieved_cell)
                    else:
                        if layout.has_cell(cache_fname):
                            print(f"WARNING: {cache_fname_gds} does not exist but {cache_fname} is in layout.")

                        # populating .gds and .pkl
                        empty_layout = pya.Layout()
                        compiled_cell, ports = pcell(
                            self, empty_layout, cell=None, params=params)
                        if debug:
                            print(f"Writing to cache: {cache_fname}: {diff_params}, {compiled_cell.name}")
                        else:
                            print('w', end='', flush=True)
                        cellname, compiled_cell.name = compiled_cell.name, cache_fname
                        compiled_cell.write(cache_fpath_gds)
                        with open(cache_fpath_pkl, 'wb') as file:
                            pickle.dump((ports, short_hash_pcell, cellname), file)
                        read_layout(layout, cache_fpath_gds)

                        retrieved_cell = layout.cell(cache_fname)
                        cell = layout.create_cell(cellname)
                        cell.insert(pya.DCellInstArray(retrieved_cell.cell_index(),
                                                       pya.DTrans(pya.Trans.R0, pya.DPoint(0, 0))))

                else:
                    cell, ports = pcell(self, layout, cell=cell, params=params)
                return cell, ports
예제 #11
0
    def test_5_CplxTrans_FuzzyCompare(self):

        t1 = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                            1.0)
        t2a = pya.DCplxTrans(
            pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-7, 5)), 1.0)
        t2b = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0 + 1e-11)
        t2c = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0)
        t2c.angle = t2c.angle + 1e-11
        t3a = pya.DCplxTrans(
            pya.DTrans(pya.DTrans.M135, pya.DPoint(17 + 1e-4, 5)), 1.0)
        t3b = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0 + 1e-4)
        t3c = pya.DCplxTrans(pya.DTrans(pya.DTrans.M135, pya.DPoint(17, 5)),
                             1.0)
        t3c.angle = t3c.angle + 1e-4
        t4 = pya.DCplxTrans(pya.DTrans(pya.DTrans.R90, pya.DPoint(18, 5)), 1.0)

        self.assertEqual(t1 == t2a, True)
        self.assertEqual(t1 != t2a, False)
        self.assertEqual(t1 < t2a, False)
        self.assertEqual(t2a < t1, False)

        self.assertEqual(t1 == t2b, True)
        self.assertEqual(t1 != t2b, False)
        self.assertEqual(t1 < t2b, False)
        self.assertEqual(t2b < t1, False)

        self.assertEqual(t1 == t2c, True)
        self.assertEqual(t1 != t2c, False)
        self.assertEqual(t1 < t2c, False)
        self.assertEqual(t2c < t1, False)

        self.assertEqual(t1 == t3a, False)
        self.assertEqual(t1 != t3a, True)
        self.assertEqual(t1 < t3a, True)
        self.assertEqual(t3a < t1, False)

        self.assertEqual(t1 == t3b, False)
        self.assertEqual(t1 != t3b, True)
        self.assertEqual(t1 < t3b, False)
        self.assertEqual(t3b < t1, True)

        self.assertEqual(t1 == t3c, False)
        self.assertEqual(t1 != t3c, True)
        self.assertEqual(t1 < t3c, True)
        self.assertEqual(t3c < t1, False)

        self.assertEqual(t3a == t3b, False)
        self.assertEqual(t3a != t3b, True)
        self.assertEqual(t3a < t3b, False)
        self.assertEqual(t3b < t3a, True)

        self.assertEqual(t3a == t3c, False)
        self.assertEqual(t3a != t3c, True)
        self.assertEqual(t3a < t3c, False)
        self.assertEqual(t3c < t3a, True)

        self.assertEqual(t3b == t3c, False)
        self.assertEqual(t3b != t3c, True)
        self.assertEqual(t3b < t3c, True)
        self.assertEqual(t3c < t3b, False)

        self.assertEqual(t1 == t4, False)
        self.assertEqual(t1 != t4, True)
        self.assertEqual(t1 < t4, True)
        self.assertEqual(t4 < t1, False)
예제 #12
0
    def test_3_DTrans(self):

        c = pya.DCplxTrans(5.0, -7.0)
        self.assertEqual(str(c), "r0 *1 5,-7")

        c = pya.DCplxTrans(pya.DCplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), True)
        self.assertEqual(c.is_mag(), False)
        self.assertEqual(c.is_mirror(), True)
        self.assertEqual(c.rot(), pya.DCplxTrans.M135.rot())
        self.assertEqual(str(c.s_trans()), "m135 0,0")
        self.assertAlmostEqual(c.angle, 270)

        self.assertEqual(str(c.trans(pya.DEdge(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str((c * pya.DEdge(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str(c.trans(pya.DBox(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str((c * pya.DBox(0, 1, 2, 3))), "(-3,-2;-1,0)")
        self.assertEqual(str(c.trans(pya.DText("text", pya.DVector(0, 1)))),
                         "('text',m135 -1,0)")
        self.assertEqual(str((c * pya.DText("text", pya.DVector(0, 1)))),
                         "('text',m135 -1,0)")
        self.assertEqual(
            str(
                c.trans(
                    pya.DPolygon([
                        pya.DPoint(0, 1),
                        pya.DPoint(2, -3),
                        pya.DPoint(4, 5)
                    ]))), "(-5,-4;-1,0;3,-2)")
        self.assertEqual(
            str((c * pya.DPolygon(
                [pya.DPoint(0, 1),
                 pya.DPoint(2, -3),
                 pya.DPoint(4, 5)]))), "(-5,-4;-1,0;3,-2)")
        self.assertEqual(
            str(c.trans(pya.DPath(
                [pya.DPoint(0, 1), pya.DPoint(2, 3)], 10))),
            "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false")
        self.assertEqual(
            str((c * pya.DPath(
                [pya.DPoint(0, 1), pya.DPoint(2, 3)], 10))),
            "(-1,0;-3,-2) w=10 bx=0 ex=0 r=false")

        c = pya.DCplxTrans.from_itrans(pya.CplxTrans.M135)
        self.assertEqual(str(c), "m135 *1 0,0")

        c = pya.DCplxTrans(1.5)
        self.assertEqual(str(c), "r0 *1.5 0,0")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), True)
        self.assertEqual(c.is_mag(), True)
        self.assertEqual(c.is_mirror(), False)
        self.assertEqual(c.rot(), pya.DCplxTrans.R0.rot())
        self.assertEqual(str(c.s_trans()), "r0 0,0")
        self.assertAlmostEqual(c.angle, 0)

        c = pya.DCplxTrans(0.75, 45, True, 2.5, -12.5)
        self.assertEqual(str(c), "m22.5 *0.75 2.5,-12.5")
        c = pya.DCplxTrans(0.75, 45, True, pya.DPoint(2.5, -12.5))
        self.assertEqual(str(c), "m22.5 *0.75 2.5,-12.5")
        self.assertEqual(c.is_unity(), False)
        self.assertEqual(c.is_ortho(), False)
        self.assertEqual(c.is_mag(), True)
        self.assertEqual(c.rot(), pya.DCplxTrans.M0.rot())
        self.assertEqual(str(c.s_trans()), "m0 2.5,-12.5")
        self.assertAlmostEqual(c.angle, 45)

        self.assertEqual(str(c.ctrans(5)), "3.75")
        self.assertEqual(str(c.trans(pya.DPoint(12, 16))),
                         "17.3492424049,-14.6213203436")

        self.assertEqual(str(pya.DCplxTrans()), "r0 *1 0,0")
        self.assertEqual(pya.DCplxTrans().is_unity(), True)
        self.assertEqual((c * c.inverted()).is_unity(), True)

        c.mirror = False
        self.assertEqual(str(c), "r45 *0.75 2.5,-12.5")
        c.mag = 1.5
        self.assertEqual(str(c), "r45 *1.5 2.5,-12.5")
        c.disp = pya.DPoint(-1.0, 5.5)
        self.assertEqual(str(c), "r45 *1.5 -1,5.5")
        self.assertEqual(c.mag, 1.5)
        c.angle = 60
        self.assertEqual(str(c), "r60 *1.5 -1,5.5")
        self.assertEqual(("%g" % c.angle), "60")

        # Constructor variations
        self.assertEqual(str(pya.ICplxTrans()), "r0 *1 0,0")
        self.assertEqual(str(pya.ICplxTrans(1.5)), "r0 *1.5 0,0")
        self.assertEqual(str(pya.ICplxTrans(pya.Trans(1, False, 10, 20), 1.5)),
                         "r90 *1.5 10,20")
        self.assertEqual(str(pya.ICplxTrans(pya.Trans(1, False, 10, 20))),
                         "r90 *1 10,20")
        self.assertEqual(
            str(pya.ICplxTrans(1.5, 80, True, pya.Vector(100, 200))),
            "m40 *1.5 100,200")
        self.assertEqual(str(pya.ICplxTrans(1.5, 80, True, 100, 200)),
                         "m40 *1.5 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.Vector(100, 200))),
                         "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(100, 200)), "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans(100, 200))),
                         "r0 *1 100,200")
        self.assertEqual(str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5)),
                         "r0 *1.5 150,300")
        self.assertEqual(
            str(
                pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5,
                               pya.Vector(10, 20))), "r0 *1.5 160,320")
        self.assertEqual(
            str(pya.ICplxTrans(pya.ICplxTrans(100, 200), 1.5, 10, 20)),
            "r0 *1.5 160,320")

        self.assertEqual(str(pya.DCplxTrans()), "r0 *1 0,0")
        self.assertEqual(str(pya.DCplxTrans(1.5)), "r0 *1.5 0,0")
        self.assertEqual(
            str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02), 1.5)),
            "r90 *1.5 0.01,0.02")
        self.assertEqual(str(pya.DCplxTrans(pya.DTrans(1, False, 0.01, 0.02))),
                         "r90 *1 0.01,0.02")
        self.assertEqual(
            str(pya.DCplxTrans(1.5, 80, True, pya.DVector(0.1, 0.2))),
            "m40 *1.5 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(1.5, 80, True, 0.1, 0.2)),
                         "m40 *1.5 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DVector(0.1, 0.2))),
                         "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(0.1, 0.2)), "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2))),
                         "r0 *1 0.1,0.2")
        self.assertEqual(str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5)),
                         "r0 *1.5 0.15,0.3")
        self.assertEqual(
            str(
                pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5,
                               pya.DVector(0.01, 0.02))), "r0 *1.5 0.16,0.32")
        self.assertEqual(
            str(pya.DCplxTrans(pya.DCplxTrans(0.1, 0.2), 1.5, 0.01, 0.02)),
            "r0 *1.5 0.16,0.32")
예제 #13
0
def layout_text(cell, layer_text, position, text_string, size):
    ''' Layout documentation text in layer_text. Not a polygon. Will not be printed. '''
    dtext = pya.DText(str(text_string), pya.DTrans(
        pya.DTrans.R0, position.x, position.y))
    dtext.size = size
    cell.shapes(layer_text).insert(dtext)
예제 #14
0
CARAVEL_GDS_PATH = "./gds/caravel.gds"
USER_GDS_PATH = "./gds/user_project_wrapper.gds"

# ly = pya.CellView.active().cell.layout
ly = pya.Layout()
ly.read(CARAVEL_GDS_PATH)
TOP = ly.cell("caravel")

# x, y = 326.38500, 1382.01000
for each in TOP.each_inst():
    if "user_project_wrapper" in (each.cell.name):
        x, y = each.dtrans.disp.x, each.dtrans.disp.y
        print("Placing module at (%f,%f)" % (x, y))

ly.delete_cell(ly.cell_by_name("user_project_wrapper"))

ly.read(USER_GDS_PATH)
tiles = ly.cell('user_project_wrapper')

TOP.insert(
    pya.DCellInstArray(tiles.cell_index(),
                       pya.DTrans(pya.DTrans.R0, pya.DPoint(x, y))))

for c in ly.top_cells():
    if c.name != "caravel":
        print("removing cell " + c.name)
        ly.delete_cell(c.cell_index())

ly.write("./gds/caravel_merged.gds")
예제 #15
0
horizontal = np.concatenate((
  np.array([0, 4, 4]),
  np.full(6, 4)))   # Pad to total length 9 with 4's

vertical = np.concatenate((
  np.array([16, 20, 20]),
  np.full(6, 20)))  # Pad to total length 9 with 20's

# Generate the spiral and instantiate its cell
paths.delay_spiral_geo(layout, rib, sp, 
  turns=4, 
  spacing=2.5, 
  vertical=vertical,
  horizontal=horizontal,
  horizontal_mode='symmetric',
  vertical_mode='symmetric',
  quad_shift=0,
  start_turn=1, 
  start_angle=0, 
  end_angle=0,
  radial_shift=4.80, 
  n_pts=5000)
  
top.insert(pya.DCellInstArray(
  sp.cell_index(),
  pya.DTrans(pya.DVector(0, 30))
))


layout.write(my_constants.gds_models_path + 'test_spiral.gds')
예제 #16
0
  def test_1_DPolygon(self):

    a = pya.DPolygon()
    self.assertEqual( str(a), "()" )
    self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
    self.assertEqual( a.is_box(), False )

    b = a.dup()
    a = pya.DPolygon( [ pya.DPoint( 0, 1 ), pya.DPoint( 1, 5 ), pya.DPoint( 5, 5 ) ] )
    self.assertEqual( str(a), "(0,1;1,5;5,5)" )
    self.assertEqual( str(a * 2), "(0,2;2,10;10,10)" )
    self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
    self.assertEqual( a.is_box(), False )
    self.assertEqual( a.num_points_hull(), 3 )
    c = a.dup()

    self.assertEqual( a == b, False )
    self.assertEqual( a == c, True )
    self.assertEqual( a != b, True )
    self.assertEqual( a != c, False )

    a = pya.DPolygon( pya.DBox( 5, -10, 20, 15 ) )
    self.assertEqual( a.is_box(), True )
    self.assertEqual( str(a), "(5,-10;5,15;20,15;20,-10)" )
    self.assertEqual( str(pya.Polygon(a)), "(5,-10;5,15;20,15;20,-10)" )
    self.assertEqual( a.num_points_hull(), 4 )
    self.assertEqual( a.area(), 15*25 )
    self.assertEqual( a.perimeter(), 80 )
    self.assertEqual( a.inside( pya.DPoint( 10, 0 ) ), True )
    self.assertEqual( a.inside( pya.DPoint( 5, 0 ) ), True )
    self.assertEqual( a.inside( pya.DPoint( 30, 0 ) ), False )

    arr = []
    for p in a.each_point_hull():
      arr.append( str(p) )
    self.assertEqual( arr, ["5,-10", "5,15", "20,15", "20,-10"] )

    b = a.dup()

    self.assertEqual( str(a.moved( pya.DPoint( 0, 1 ) )), "(5,-9;5,16;20,16;20,-9)" )
    self.assertEqual( str(a.moved( 0, 1 )), "(5,-9;5,16;20,16;20,-9)" )
    aa = a.dup()
    aa.move( 1, 0 )
    self.assertEqual( str(aa), "(6,-10;6,15;21,15;21,-10)" )
    a.move( pya.DPoint( 1, 0 ) )
    self.assertEqual( str(a), "(6,-10;6,15;21,15;21,-10)" )

    b = b.transformed( pya.DTrans( pya.DTrans.R0, pya.DPoint( 1, 0 )) )
    self.assertEqual( str(b), "(6,-10;6,15;21,15;21,-10)" )

    m = pya.DCplxTrans( pya.DTrans(), 1.5 )
    self.assertEqual( type(a.transformed(m)).__name__, "DPolygon" )
    self.assertEqual( str(a.transformed(m)), "(9,-15;9,22.5;31.5,22.5;31.5,-15)" )

    m = pya.VCplxTrans( 1000.0 )
    self.assertEqual( type(a.transformed(m)).__name__, "Polygon" )
    self.assertEqual( str(a.transformed(m)), "(6000,-10000;6000,15000;21000,15000;21000,-10000)" )

    a.hull = [ pya.DPoint( 0, 1 ), pya.DPoint( 1, 1 ), pya.DPoint( 1, 5 ) ]
    self.assertEqual( str(a.bbox()), "(0,1;1,5)" )

    self.assertEqual( a.holes(), 0 )
    a.insert_hole( [ pya.DPoint( 1, 2 ), pya.DPoint( 2, 2 ), pya.DPoint( 2, 6 ) ] )
    self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
    self.assertEqual( str(pya.DPolygon.from_s(str(a))), str(a) )
    self.assertEqual( a.area(), 0 )
    self.assertEqual( a.num_points_hole(0), 3 )
    self.assertEqual( a.holes(), 1 )
    self.assertEqual( str(a.point_hull(1)), "1,5" )
    self.assertEqual( str(a.point_hull(0)), "0,1" )
    self.assertEqual( str(a.point_hull(100)), "0,0" )
    self.assertEqual( str(a.point_hole(0, 100)), "0,0" )
    self.assertEqual( str(a.point_hole(0, 1)), "2,2" )
    self.assertEqual( str(a.point_hole(1, 1)), "0,0" )
    a.compress(False);
    self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )
    a.compress(True);
    self.assertEqual( str(a), "(0,1;1,5;1,1/1,2;2,2;2,6)" )

    b = a.dup()
    b.assign_hole(0, pya.DBox( 10, 20, 20, 60 ))
    self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60)" )
    b.insert_hole(pya.DBox( 10, 20, 20, 60 ))
    self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60;10,60/10,20;20,20;20,60;10,60)" )
    self.assertEqual( b.is_box(), False )

    b = a.dup()
    b.assign_hole(0, [ pya.DPoint( 10, 20 ), pya.DPoint( 20, 20 ), pya.DPoint( 20, 60 ) ])
    self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" )
    b.assign_hole(1, [ pya.DPoint( 15, 25 ), pya.DPoint( 25, 25 ), pya.DPoint( 25, 65 ) ])
    self.assertEqual( str(b), "(0,1;1,5;1,1/10,20;20,20;20,60)" )
    b.insert_hole( [ pya.DPoint( 1, 2 ), pya.DPoint( 2, 2 ), pya.DPoint( 2, 6 ) ] )
    self.assertEqual( str(b), "(0,1;1,5;1,1/1,2;2,2;2,6/10,20;20,20;20,60)" )
    b.assign_hole(0, [ pya.DPoint( 15, 25 ), pya.DPoint( 25, 25 ), pya.DPoint( 25, 65 ) ])
    self.assertEqual( str(b), "(0,1;1,5;1,1/15,25;25,25;25,65/10,20;20,20;20,60)" )

    arr = []
    for p in a.each_point_hole(0):
      arr.append( str(p) )

    self.assertEqual( arr, ["1,2", "2,2", "2,6"] )

    arr = []
    for p in a.each_edge():
      arr.append( str(p) )
    self.assertEqual( arr, ["(0,1;1,5)", "(1,5;1,1)", "(1,1;0,1)", "(1,2;2,2)", "(2,2;2,6)", "(2,6;1,2)"] )

    # Ellipse constructor
    p = pya.DPolygon.ellipse( pya.DBox(-10000, -20000, 30000, 40000), 200 )
    self.assertEqual(p.num_points(), 200)
    self.assertEqual(str(p.bbox()), "(-10000,-20000;30000,40000)")
    self.assertEqual(int(p.area()), 1884645544)    # roughly box.area*PI/4
    
    p = pya.DPolygon.ellipse( pya.DBox(-10000, -20000, 30000, 40000), 4 )
    self.assertEqual(str(p), "(10000,-20000;-10000,10000;10000,40000;30000,10000)")
예제 #17
0
    pya.DPoint(50, 50),
    pya.DPoint(40.5, 60.6),
    pya.DPoint(0, 50)
]
dpath1 = pya.DPath(dpts, 4, 5, 0, True)
top.shapes(l1).insert(pya.Path.from_dpath(dpath1))
#DCplxTrans
#倍数,逆时针度数,是否绕x翻转,平移x,平移y
tr = pya.DCplxTrans(10, 45, False, 1000, 1000)
#xxx.transform(tr)#本身改变
#xxx.transformed(tr)本身不变返回新的
#对一个点pt做变换的方法
#pya.DEdge(pya.DPoint(),pt).transformed(DCplxTrans).p2

#DText
text1 = pya.DText("TEST_Text", pya.DTrans(-10, -10), 100, 1)
top.shapes(l1).insert(pya.Text.from_dtext(text1))
#a text can be printed @ruby
#it dose not work in python
#lib.layout.pcell_declaration can't be found
'''
begin
ly = RBA::Layout.new
 top = ly.add_cell("TOP")

 # find the lib
 lib = RBA::Library.library_by_name("Basic")
 lib || raise("Unknown lib 'Basic'")

 # find the pcell
 pcell_decl = lib.layout.pcell_declaration("TEXT")
예제 #18
0
sp = layout.create_cell("spiral")  # create cell for a delay spiral
rib = layout.layer(1, 0)  # create strip waveguide layer

horizontal = np.concatenate(
    (np.array([0, 4, 8]), np.full(6, 8)))  # Pad to total length 9 with 8's

vertical = np.concatenate(
    (np.array([16, 20, 24]), np.full(6,
                                     24)))  # Pad to total length 9 with 24's

# Generate the spiral and instantiate its cell
paths.delay_spiral_geo(layout,
                       rib,
                       sp,
                       turns=4,
                       spacing=2.5,
                       vertical=vertical,
                       horizontal=horizontal,
                       horizontal_mode='symmetric',
                       vertical_mode='symmetric',
                       quad_shift=0,
                       start_turn=1,
                       start_angle=0,
                       end_angle=0,
                       radial_shift=4.80,
                       n_pts=5000)

top.insert(pya.DCellInstArray(sp.cell_index(), pya.DTrans(pya.DVector(0, 30))))

layout.write(my_constants.gds_models_path + 'test_spiral.gds')