Exemple #1
0
    def save(self,
             name=None,
             library=None,
             grid_steps_per_micron=1000,
             parallel=False,
             max_workers=None):
        """
        Exports the layout and creates an DLW-file, if DLW-features are used.

        :param name: The filename of the saved file. The ending of the filename defines the format.
            Currently .gds, .oasis and .dxf are supported.
        :param library: Name of the used library.
            Should stay `None` in order to select the library depending on the file-ending.
            The use of this parameter is deprecated and this parameter will be removed in a future release.
        :param grid_steps_per_micron: Defines the resolution
        :param parallel: Defines if parallelization is used (only supported in Python 3).
            Standard value will be changed to True in a future version.
            Deactivating can be useful for debugging reasons.
        :param max_workers: If parallel is True, this can be used to limit the number of parallel processes.
            This can be useful if you run into out-of-memory errors otherwise.
        """

        if library is not None:
            import warnings
            warnings.warn(
                'The use of the `library` parameter is deprecated. '
                'Instead, define the format by the file ending of the filename.',
                DeprecationWarning)

        if not name:
            name = self.name
        elif name.endswith('.gds'):
            name = name[:-4]
            library = library or 'gdshelpers'
        elif name.endswith('.oas'):
            name = name[:-4]
            library = library or 'fatamorgana'
        elif name.endswith('.dxf'):
            name = name[:-4]
            library = library or 'ezdxf'

        library = library or 'gdshelpers'

        if library == 'gdshelpers':
            from tempfile import NamedTemporaryFile
            import shutil

            with NamedTemporaryFile('wb', delete=False) as tmp:
                write_cell_to_gdsii_file(
                    tmp,
                    self,
                    grid_steps_per_unit=grid_steps_per_micron,
                    parallel=parallel,
                    max_workers=max_workers)
            shutil.move(tmp.name, name + '.gds')

        elif library == 'gdspy':
            import gdspy

            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor(max_workers=max_workers) as pool:
                    self.get_gdspy_cell(pool)
            else:
                self.get_gdspy_cell()

            self.get_gdspy_lib(
            ).precision = self.get_gdspy_lib().unit / grid_steps_per_micron
            gdspy_cells = self.get_gdspy_lib().cell_dict.values()
            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor(max_workers=max_workers) as pool:
                    binary_cells = pool.map(gdspy.Cell.to_gds, gdspy_cells,
                                            [grid_steps_per_micron] *
                                            len(gdspy_cells))
            else:
                binary_cells = map(gdspy.Cell.to_gds, gdspy_cells,
                                   [grid_steps_per_micron] * len(gdspy_cells))

            self.get_gdspy_lib().write_gds(name + '.gds',
                                           cells=[],
                                           binary_cells=binary_cells)
        elif library == 'fatamorgana':
            import fatamorgana
            layout = fatamorgana.OasisLayout(grid_steps_per_micron)

            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor(max_workers=max_workers) as pool:
                    cells = self.get_oasis_cells(grid_steps_per_micron, pool)
            else:
                cells = self.get_oasis_cells(grid_steps_per_micron)

            layout.cells = [cells[0]] + list(set(cells[1:]))

            with open(name + '.oas', 'wb') as f:
                layout.write(f)
        elif library == 'ezdxf':
            from gdshelpers.export.dxf_export import write_cell_to_dxf_file
            with open(name + '.dxf', 'w') as f:
                write_cell_to_dxf_file(f,
                                       self,
                                       grid_steps_per_micron,
                                       parallel=parallel)
        else:
            raise ValueError(
                'library must be either "gdshelpers", "gdspy", "fatamorgana" or "ezdxf"'
            )

        dlw_data = self.get_dlw_data()
        if dlw_data:
            with open(name + '.dlw', 'w') as f:
                json.dump(dlw_data, f, indent=True)
Exemple #2
0
    def save(self,
             name=None,
             library=None,
             grid_steps_per_micron=1000,
             parallel=False):
        """
        Exports the layout and creates an DLW-file, if DLW-features are used.

        :param name: The filename of the saved file. The ending of the filename defines the format.
            Currently .gds, .oasis and .dxf are supported.
        :param library: Name of the used library.
            Should stay `None` in order to select the library depending on the file-ending.
            The use of this parameter is deprecated and this parameter will be removed in a future release.
        :param grid_steps_per_micron: Defines the resolution
        :param parallel: Defines if parallelization is used (only supported in Python 3).
            Standard value will be changed to True in a future version.
            Deactivating can be useful for debugging reasons.
        """

        if library is not None:
            import warnings
            warnings.warn(
                'The use of the `library` parameter is deprecated. '
                'Instead, define the format by the file ending of the filename.',
                DeprecationWarning)

        if not name:
            name = self.name
        elif name.endswith('.gds'):
            name = name[:-4]
            library = library or 'gdshelpers'
        elif name.endswith('.oasis'):
            name = name[:-6]
            library = library or 'fatamorgana'
        elif name.endswith('.dxf'):
            name = name[:-4]
            library = library or 'ezwriter'

        library = library or 'gdshelpers'

        if library == 'gdshelpers':
            from tempfile import NamedTemporaryFile
            import shutil

            with NamedTemporaryFile('wb', delete=False) as tmp:
                write_cell_to_gdsii_file(
                    tmp,
                    self,
                    grid_steps_per_unit=grid_steps_per_micron,
                    parallel=parallel)
            shutil.move(tmp.name, name + '.gds')

        elif library == 'gdspy':
            import gdspy

            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor() as pool:
                    self.get_gdspy_cell(pool)
            else:
                self.get_gdspy_cell()

            self.get_gdspy_lib(
            ).precision = self.get_gdspy_lib().unit / grid_steps_per_micron
            gdspy_cells = self.get_gdspy_lib().cell_dict.values()
            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor() as pool:
                    binary_cells = pool.map(gdspy.Cell.to_gds, gdspy_cells,
                                            [grid_steps_per_micron] *
                                            len(gdspy_cells))
            else:
                binary_cells = map(gdspy.Cell.to_gds, gdspy_cells,
                                   [grid_steps_per_micron] * len(gdspy_cells))

            self.get_gdspy_lib().write_gds(name + '.gds',
                                           cells=[],
                                           binary_cells=binary_cells)
        elif library == 'fatamorgana':
            import fatamorgana
            layout = fatamorgana.OasisLayout(grid_steps_per_micron)

            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor() as pool:
                    cells = self.get_oasis_cells(grid_steps_per_micron, pool)
            else:
                cells = self.get_oasis_cells(grid_steps_per_micron)

            layout.cells = [cells[0]] + list(set(cells[1:]))

            # noinspection PyUnresolvedReferences
            def replace_names_by_ids(oasis_layout):
                name_id = {}
                for cell_id, cell in enumerate(oasis_layout.cells):
                    if cell.name.string in name_id:
                        raise RuntimeError(
                            'Each cell name should be unique, name "' +
                            cell.name.string + '" is used multiple times')
                    name_id[cell.name.string] = cell_id
                    cell.name = cell_id
                for cell in oasis_layout.cells:
                    for placement in cell.placements:
                        placement.name = name_id[placement.name.string]

                oasis_layout.cellnames = {v: k for k, v in name_id.items()}

            # improves performance for reading oasis file and workaround for fatamorgana-bug
            replace_names_by_ids(layout)

            with open(name + '.oas', 'wb') as f:
                layout.write(f)
        elif library == 'ezdxf':
            from gdshelpers.export.dxf_export import write_cell_to_dxf_file
            with open(name + '.gds', 'wb') as f:
                write_cell_to_dxf_file(f,
                                       self,
                                       grid_steps_per_micron,
                                       parallel=parallel)
        else:
            raise ValueError('library must be either "gdspy" or "fatamorgana"')

        dlw_data = self.get_dlw_data()
        if dlw_data:
            with open(name + '.dlw', 'w') as f:
                json.dump(dlw_data, f, indent=True)
Exemple #3
0
    def save(self, name=None, library=None, grid_steps_per_micron=1000, parallel=False):
        """
        Exports the layout and creates an DLW-file, if DLW-features are used.

        :param name: Optionally, the filename of the saved file (without ending).
        :param library: Name of the used library.
            Currently, for gds-export gdspy and gdscad are supported, for oasis-export fatamorgana is supported.
        :param grid_steps_per_micron: Defines the resolution
        :param parallel: Defines if palatalization is used (only supported in Python 3).
            Standard value will be changed to True in a future version.
            Deactivating can be useful for debugging reasons.
        """

        if not name:
            name = self.name
        elif name.endswith('.gds'):
            name = name[:-4]
            library = library or gds_library
        elif name.endswith('.oasis'):
            name = name[:-6]
            library = library or 'fatamorgana'

        library = library or gds_library

        if library == 'gdspy':
            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor() as pool:
                    self.get_gdspy_cell(pool)
            else:
                self.get_gdspy_cell()

            self.get_gdspy_lib().precision = self.get_gdspy_lib().unit / grid_steps_per_micron
            gdspy_cells = self.get_gdspy_lib().cell_dict.values()
            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor() as pool:
                    binary_cells = pool.map(gdspy.Cell.to_gds, gdspy_cells, [grid_steps_per_micron] * len(gdspy_cells))
            else:
                binary_cells = map(gdspy.Cell.to_gds, gdspy_cells, [grid_steps_per_micron] * len(gdspy_cells))

            self.get_gdspy_lib().write_gds(name + '.gds', cells=[], binary_cells=binary_cells)
        elif library == 'gdscad':
            layout = gdsCAD.core.Layout(precision=1e-6 / grid_steps_per_micron)
            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor() as pool:
                    layout.add(self.get_gdscad_cell(pool))
            else:
                layout.add(self.get_gdscad_cell())
            layout.save(name + '.gds')
        elif library == 'fatamorgana':
            layout = fatamorgana.OasisLayout(grid_steps_per_micron)

            if parallel:
                from concurrent.futures import ProcessPoolExecutor
                with ProcessPoolExecutor() as pool:
                    cells = self.get_oasis_cells(grid_steps_per_micron, pool)
            else:
                cells = self.get_oasis_cells(grid_steps_per_micron)

            layout.cells = [cells[0]] + list(set(cells[1:]))

            # noinspection PyUnresolvedReferences
            def replace_names_by_ids(oasis_layout):
                name_id = {}
                for cell_id, cell in enumerate(oasis_layout.cells):
                    if cell.name.string in name_id:
                        raise RuntimeError(
                            'Each cell name should be unique, name "' + cell.name.string + '" is used multiple times')
                    name_id[cell.name.string] = cell_id
                    cell.name = cell_id
                for cell in oasis_layout.cells:
                    for placement in cell.placements:
                        placement.name = name_id[placement.name.string]

                oasis_layout.cellnames = {v: k for k, v in name_id.items()}

            # improves performance for reading oasis file and workaround for fatamorgana-bug
            replace_names_by_ids(layout)

            with open(name + '.oas', 'wb') as f:
                layout.write(f)
        else:
            raise ValueError('library must be either "gdscad", "gdspy" or "fatamorgana"')

        dlw_data = self.get_dlw_data()
        if dlw_data:
            with open(name + '.dlw', 'w') as f:
                json.dump(dlw_data, f, indent=True)

        with open(name + '.desc', 'w') as f:
            json.dump(self.get_desc(), f, indent=True)