コード例 #1
0
    def test_export_import(self):
        waveguide = Waveguide([0, 0], 0, 1)
        for i_bend in range(9):
            waveguide.add_bend(angle=np.pi, radius=60 + i_bend * 40)
        offset = (10, 10)
        angle = np.pi

        cell = Cell('test')
        cell.add_to_layer(1, waveguide)

        sub_cell = Cell('sub_cell')
        sub_cell.add_to_layer(2, waveguide)
        cell.add_cell(sub_cell, origin=(0, 0), angle=0)

        sub_cell2 = Cell('sub_cell2')
        sub_cell2.add_to_layer(3, waveguide)
        cell.add_cell(sub_cell2, origin=offset, angle=angle)

        cell.save(grid_steps_per_micron=10000)

        def assert_almost_equal_shapely(a, b, tolerance=2e-4):
            self.assertTrue(a.buffer(tolerance).contains(b))
            self.assertTrue(b.buffer(tolerance).contains(a))

        assert_almost_equal_shapely(
            waveguide.get_shapely_object(), GDSIIImport('test.gds', 'test', 1).get_shapely_object())

        assert_almost_equal_shapely(
            waveguide.get_shapely_object(), GDSIIImport('test.gds', 'test', 2).get_shapely_object())

        assert_almost_equal_shapely(
            translate(rotate(waveguide.get_shapely_object(), angle, use_radians=True, origin=(0, 0)),
                      *offset), GDSIIImport('test.gds', 'test', 3).get_shapely_object())

        self.assertTrue(GDSIIImport('test.gds', 'test', 1, 2).get_shapely_object().is_empty)
コード例 #2
0
def _example():
    from gdshelpers.geometry.chip import Cell
    from gdshelpers.parts.splitter import Splitter
    from gdshelpers.parts.coupler import GratingCoupler

    port = Port([0, 0], 0, 1)
    path = Waveguide.make_at_port(port)

    path.add_straight_segment(10)
    path.add_bend(np.pi / 2, 10, final_width=0.5)
    path.add_bend(-np.pi / 2, 10, final_width=1)
    path.add_arc(np.pi * 3 / 4, 10, )

    splitter = Splitter.make_at_root_port(path.current_port, 30, 10)
    path2 = Waveguide.make_at_port(splitter.right_branch_port)
    path2.add_bend(-np.pi / 4, 10)

    n = 10
    path2.add_parameterized_path(lambda t: (n * 10 * t, np.cos(n * 2 * np.pi * t) - 1),
                                 path_derivative=lambda t: (n * 10, -n * 2 * np.pi * np.sin(n * 2 * np.pi * t)),
                                 width=lambda t: np.cos(n * 2 * np.pi * t) * 0.2 + np.exp(-t) * 0.3 + 0.5,
                                 width_function_supports_numpy=True)
    path2.add_straight_segment(10, width=[.5, .5, .5])
    print(path2.length)
    print(path2.length_last_segment)

    path2.add_cubic_bezier_path((0, 0), (5, 0), (10, 10), (5, 10))
    path2.add_bend(-np.pi, 40)

    coupler1 = GratingCoupler([100, 50], 0, 1, np.deg2rad(30), [10, 0.1, 2, 0.1, 2], start_radius_absolute=True)

    path3 = Waveguide((0, -50), np.deg2rad(0), 1)
    path3.add_bezier_to(coupler1.port.origin, coupler1.port.inverted_direction.angle, bend_strength=50)

    splitter2 = Splitter.make_at_left_branch_port(splitter.left_branch_port, 30, 10, wavelength_root=2)

    path4 = Waveguide.make_at_port(splitter2.root_port)
    path4.add_straight_segment(20)
    path4.width = 1
    path4.add_straight_segment(20)

    empty_path = Waveguide.make_at_port(path4.current_port)

    whole_layout = (path, splitter, path2, splitter2, coupler1, path3, path4, empty_path)

    layout = Cell('LIBRARY')
    cell = Cell('TOP')
    cell.add_to_layer(1, *whole_layout)
    cell.add_to_layer(2, empty_path)
    cell.add_to_layer(4, splitter.root_port.debug_shape)

    layout.add_cell(cell)

    cell_df = Cell('TOP_DF')
    cell_df.add_to_layer(1, convert_to_positive_resist(whole_layout, buffer_radius=1.5))
    layout.add_cell(cell_df)

    layout.save('output.gds')
    cell.show()
コード例 #3
0
    def test_empty_cell(self):
        # An empty cell should have 'None' as bounding box
        cell = Cell('test_cell')
        # self.assertEqual(cell.bounds, None)
        cell.add_to_layer(4, box(60, 0, 70, 10))
        self.assertEqual(cell.bounds, (60, 0, 70, 10))

        subcell = Cell('subcell')
        cell.add_cell(subcell, origin=(0, 0))
        # bounding box of cell should still be the the original bbox
        self.assertEqual(cell.bounds, (60, 0, 70, 10))
コード例 #4
0
    def test_coupler_apodized_period(self):
        coupler1 = GratingCoupler.make_traditional_coupler(
            origin=[0, 0],
            width=1,
            full_opening_angle=np.deg2rad(40),
            grating_period=3,
            grating_ff=0.5,
            n_gratings=22,
            ap_max_ff=0.25,
            n_ap_gratings=10,
            taper_length=22,
            angle=-0.5 * np.pi,
            ap_start_period=1.,
        )

        coupler2 = GratingCoupler.make_traditional_coupler(
            origin=[100, 0],
            width=1,
            full_opening_angle=np.deg2rad(40),
            grating_period=3,
            grating_ff=0.5,
            n_gratings=22,
            ap_max_ff=0.25,
            n_ap_gratings=10,
            taper_length=22,
            angle=-0.5 * np.pi,
            ap_start_period=3.,
        )

        coupler3 = GratingCoupler.make_traditional_coupler(
            origin=[200, 0],
            width=1,
            full_opening_angle=np.deg2rad(40),
            grating_period=3,
            grating_ff=0.5,
            n_gratings=22,
            ap_max_ff=0.25,
            n_ap_gratings=10,
            taper_length=22,
            angle=-0.5 * np.pi,
            ap_start_period=None,
        )

        self.assertAlmostEqual(coupler2.maximal_radius,
                               coupler3.maximal_radius)

        layout = Cell('LIBRARY')
        cell = Cell('TOP')
        cell.add_to_layer(1, coupler1)
        cell.add_to_layer(1, coupler2)
        cell.add_to_layer(1, coupler3)
        layout.add_cell(cell)
コード例 #5
0
    def test_bounds_subcell(self):
        cell = Cell('test_cell')

        subcell = Cell('subcell')
        subcell.add_to_layer(3, box(0, 0, 100, 100))
        cell.add_cell(subcell, origin=(100, 100))
        self.assertEqual(cell.bounds, (100, 100, 200, 200))

        cell.add_cell(subcell, origin=(500, 100), angle=np.pi)

        # cell.save('test_bounds_subcell')

        self.assertEqual(cell.bounds, (100, 0, 500, 200))
コード例 #6
0
def _example():
    from gdshelpers.geometry.chip import Cell
    from gdshelpers.geometry import geometric_union

    # Generate a coupler, which ought to be identical to
    # coupler_sn330_1550_bf_ff_ap( 0:0 1550 0.7 22 0.96 10 22 1 "active")
    # also known as
    # coupler_bf_ap_mff( 0:0 1 40.0 1.13 0.7 22 0.96 10 22 200 "active")
    coupler = GratingCoupler.make_traditional_coupler([150, 0],
                                                      1,
                                                      np.deg2rad(40),
                                                      1.13,
                                                      0.7,
                                                      22,
                                                      0.96,
                                                      10,
                                                      22,
                                                      angle=-np.pi)

    coupler2 = GratingCoupler.make_traditional_coupler_from_database([0, 0], 1,
                                                                     'sn330',
                                                                     1550)

    print(coupler.get_description_str())

    whole_layout = (coupler, coupler2)

    layout = Cell('LIBRARY')
    cell = Cell('TOP')
    cell.add_to_layer(1, *whole_layout)
    cell.add_to_layer(StandardLayers.parnamelayer1,
                      coupler.get_description_text())
    cell.add_to_layer(StandardLayers.parnamelayer1,
                      coupler2.get_description_text())

    cell.add_to_layer(1, coupler.get_description_text())
    cell.add_to_layer(1, coupler2.get_description_text())
    cell.add_to_layer(1, coupler2.get_description_text(side='left'))
    layout.add_cell(cell)

    # We could also easily generate a dark field layout out of this
    def make_dark_field(obj, buffer_size=1.5):
        return obj.buffer(buffer_size).difference(obj)

    cell_df = Cell('TOP_DF')
    cell_df.add_to_layer(2, make_dark_field(geometric_union(whole_layout)))
    layout.add_cell(cell_df)

    layout.save('coupler.gds')
    cell.show()
コード例 #7
0
ファイル: optical_codes.py プロジェクト: ydwu0810/gdshelpers
def _example():
    qr_code = QRCode([0, 0], 'A0.0', 1.0, version=1, error_correction=QRCode.ERROR_CORRECT_M)

    from gdshelpers.geometry.chip import Cell

    device = Cell('test')
    device.add_to_layer(1, qr_code)

    device.show()

    chip = Cell('optical_codes')
    chip.add_cell(device)
    chip.start_viewer()
    chip.save()
コード例 #8
0
    def test_cell_bounds(self):
        cell = Cell('test_cell')

        wg1 = Waveguide([0, 0], 0, 1)
        wg1.add_straight_segment(10)
        cell.add_to_layer(1, wg1)

        wg2 = Waveguide([40, 0], 0, 1)
        wg2.add_straight_segment(10)
        cell.add_to_layer(2, wg2)

        cell.add_region_layer(100, [1])
        cell.add_region_layer(101, [1, 2])

        self.assertTrue(100 in cell.layer_dict)
        self.assertEqual(cell.bounds, (0.0, -0.5, 50.0, 0.5))

        subcell = Cell('subcell')
        subcell.add_to_layer(3, box(0, 0, 60, 70))

        self.assertEqual(subcell.bounds, (0.0, 0, 60.0, 70))

        # add subcell
        cell.add_cell(subcell, origin=(0, 0))
        self.assertEqual(cell.bounds, (0.0, -0.5, 60.0, 70.))

        subcell2 = Cell('subcell2')
        subcell2.add_to_layer(3, box(0, 0, 60, 70))

        # add subcell at different origin
        cell.add_cell(subcell2, origin=(20, 0))
        self.assertEqual(cell.bounds, (0.0, -0.5, 80.0, 70.))

        # add object to subcell after adding the subcell to cell
        subcell2.add_to_layer(4, box(60, 0, 70, 10))
        self.assertEqual(subcell2.bounds, (0.0, 0, 70.0, 70))
        self.assertEqual(cell.bounds, (0.0, -0.5, 90.0, 70.))

        # check total region layer
        cell.add_region_layer(102)
        self.assertTrue(102 in cell.layer_dict)
        self.assertEqual(cell.get_bounds(layers=[102]), cell.bounds)
コード例 #9
0
    def test_export_import(self):
        waveguide = Waveguide([0, 0], 0, 1)
        for i_bend in range(9):
            waveguide.add_bend(angle=np.pi, radius=60 + i_bend * 40)
        offset = (10, 10)
        angle = np.pi

        cell = Cell('test')
        cell.add_to_layer(1, waveguide)

        sub_cell = Cell('sub_cell')
        sub_cell.add_to_layer(2, waveguide)
        cell.add_cell(sub_cell, origin=(0, 0), angle=0)

        sub_cell2 = Cell('sub_cell2')
        sub_cell2.add_to_layer(3, waveguide)
        cell.add_cell(sub_cell2, origin=offset, angle=angle)

        cell.save(library='gdshelpers', grid_steps_per_micron=10000)

        self.assertTrue(waveguide.get_shapely_object().almost_equals(
            GDSIIImport('test.gds', 'test',
                        1).get_shapely_object(), decimal=3))
        self.assertTrue(waveguide.get_shapely_object().almost_equals(
            GDSIIImport('test.gds', 'test',
                        2).get_shapely_object(), decimal=3))

        self.assertTrue(
            translate(
                rotate(waveguide.get_shapely_object(),
                       angle,
                       use_radians=True,
                       origin=(0, 0)),
                *offset).almost_equals(GDSIIImport('test.gds', 'test',
                                                   3).get_shapely_object(),
                                       decimal=3))

        self.assertTrue(
            GDSIIImport('test.gds', 'test', 1,
                        2).get_shapely_object().is_empty)
コード例 #10
0
    def test_dlw(self):
        # Make sure that cells with DLW data only exist once
        top = Cell('parent_cell')
        child = Cell('child1')

        wg1 = Waveguide([0, 0], 0, 1)
        wg1.add_straight_segment(10)
        child.add_to_layer(1, wg1)

        # This should be ok, as child contains no DLW data
        top.add_cell(child, [0, 0])
        top.add_cell(child, [100, 0])

        child2 = Cell('child2')
        child2.add_to_layer(1, wg1)
        child2.add_dlw_taper_at_port("foo",
                                     1,
                                     wg1.current_port,
                                     taper_length=40.)

        top.add_cell(child2, [0, 0])
        with self.assertRaises(ValueError):
            top.add_cell(child2, [100, 0])
コード例 #11
0
    def test_bounds_rotation(self):
        import numpy.testing as np_testing

        cell1 = Cell('test_cell')
        cell1.add_to_layer(1, box(10, 10, 30, 20))
        np_testing.assert_almost_equal(cell1.bounds, (10, 10, 30, 20))

        cell2 = Cell('root_cell')
        cell2.add_cell(cell1, angle=0.5 * np.pi)
        np_testing.assert_almost_equal(cell2.bounds, (-20, 10, -10, 30))

        cell3 = Cell('root_cell')
        cell3.add_cell(cell1, angle=1.5 * np.pi)
        np_testing.assert_almost_equal(cell3.bounds, (10, -30, 20, -10))

        cell4 = Cell('root_cell')
        cell4.add_cell(cell1, angle=1 * np.pi)
        np_testing.assert_almost_equal(cell4.bounds, (-30, -20, -10, -10))

        # For manually testing the bounds rotation, uncomment the following code and look at the resulting GDS
        """
コード例 #12
0
ファイル: gdsii_export.py プロジェクト: fbeutel/gdshelpers
    outfile.write(pack('>2H', 4, 0x0400))  # ENDLIB N0_DATA


if __name__ == '__main__':
    from gdshelpers.parts.port import Port
    from gdshelpers.parts.waveguide import Waveguide
    from gdshelpers.geometry.chip import Cell

    device_cell = Cell('cell')
    start_port = Port(origin=(10, 0), width=1, angle=0)
    waveguide = Waveguide.make_at_port(start_port)
    for i_bend in range(9):
        waveguide.add_bend(angle=np.pi, radius=60 + i_bend * 40)
    device_cell.add_dlw_taper_at_port('A', 2, waveguide.in_port, 30)
    device_cell.add_dlw_taper_at_port('B', 2, waveguide.current_port, 30)
    device_cell.add_to_layer(1, waveguide)

    sub_cell = Cell('sub_cell')
    sub_cell.add_to_layer(1, waveguide)

    sub_cell.add_to_layer(3, LineString(((0, 0), (100, 100))))

    line = LineString(((0, 0), (-100, 100)))
    line.width = 3
    sub_cell.add_to_layer(3, line)

    device_cell.add_cell(sub_cell, origin=(10, 10), angle=np.pi / 2)

    with open('gdsii_export.gds', 'wb') as file:
        write_cell_to_gdsii_file(file, device_cell, parallel=True)
コード例 #13
0
        'BS%i' % x,
        2 * int(num / 2.),
        add_xlength=0.,
        add_ylength=add_ylength_list[x],
        sep=5.,
        r_curve=70.,
        coupler_sep=0.5,
        coupler_length=30,
        MZ_length=1250,
        electrodes_sep=1.1,
        return_xmax=True,
        dx_adj=dx_adj_list[x],
        exp_wg_width=wg_Expwidth,
        grating_coupler_period=std_coupler_params['grating_period'])
    timebin_cell.add_cell(temp_cell,
                          origin=temp_pos + np.array((dev_dist_list[x], 0)),
                          angle=np.pi)
    temp_pos = np.array(
        (temp_pos[0] + x_max + dev_dist_list[x], OriginTests[1]))

# #######################################################
# ### ADDING DEMUX SETUP

demux_cell = Cell('Demux')

OriginTests = (1460, 1120)

coupler_sep = 0.5
coupler_length = 30  # old value
electrode_length = 1250
コード例 #14
0
                       text=info_text,
                       alignment='center-bottom',
                       angle=np.pi)
    cell.add_to_layer(comment_layer, device_info)

    return cell


#######################################################################################
if __name__ == "__main__":
    devices = []

    #### ADD Modulators
    global_cell = Cell('Demux_Tests')

    # global_cell.add_to_layer(marker_protection_layer, device.get_markers_protection())

    coupler_sep = 0.5
    coupler_length = 30
    electrodes_sep = 1.1

    for j, MZ_length in enumerate(np.linspace(1250, 1500, 2)):
        temp_cell = Demux_active(coupler_sep, coupler_length, MZ_length,
                                 electrodes_sep, 'D%i' % j)
        temp_cell.name = 'Demux_test_' + str(j)
        # global_cell.add_cell(temp_cell, origin=(-2000 + j * 1000, -1500), angle=np.pi)
        global_cell.add_cell(temp_cell, origin=(-2000 + j * 3000, -1500))

    print('starting device saving')
    global_cell.save('tests_Demux.gds')
    print('done saving')
コード例 #15
0
ファイル: grid.py プロジェクト: philomathie/gdshelpers
    def generate_layout(self, cell_name='GRID_LAYOUT'):
        """
        Generate a layout cell.

        :param cell_name: Name of the generated layout cell
        :return: Tuple of a cell, containing the layout and a dictionary mapping each unique id to the position inside
                 the cell.
        """
        self._finish_row()

        max_columns = 0
        column_properties = dict()
        row_properties = dict()
        # Find limits
        for row_id, row_dict in enumerate(self._rows):
            row_properties[row_id] = {'max_height': 0}

            for column_id, item in enumerate(row_dict['items']):
                max_columns = max(column_id, max_columns)

                if column_id not in column_properties:
                    column_properties[column_id] = {'max_width': 0}

                column_properties[column_id]['max_width'] = max(
                    column_properties[column_id]['max_width'],
                    item['bbox'][1][0])
                row_properties[row_id]['max_height'] = max(
                    row_properties[row_id]['max_height'], item['bbox'][1][1])

        layout_cell = Cell(cell_name)
        pos = [0, self.vertical_spacing]
        limits = [0., 0.]
        mapping = dict()
        for row_id, row_dict in enumerate(self._rows):
            pos[0] = self.horizontal_spacing
            pos[1] = self._next_y_align(pos[1])

            max_height = row_properties[row_id]['max_height']
            for column_id, item in enumerate(row_dict['items']):
                max_width = column_properties[column_id][
                    'max_width'] if not self.tight else item['bbox'][1][0]
                free_space_box = np.array(
                    ((0, 0), (max_width, max_height))) + pos

                offset = (item['alignment'].calculate_offset(item['bbox']) -
                          item['alignment'].calculate_offset(free_space_box))

                origin = offset + item['offset']

                item_unique_id = item['id']
                if item_unique_id is not None:
                    assert item_unique_id not in mapping, 'Recurring cell id, use unique values!'
                    mapping[item_unique_id] = origin

                if self.region_layer_type == 'cell' and item[
                        'allow_region_layer']:
                    # rl_box = shapely.geometry.box(pos[0], pos[1],
                    #                               self._next_x_align(pos[0] + max_width),
                    #                               self._next_y_align(pos[1] + max_height))
                    new_bbox = item['bbox'] + offset
                    delta = new_bbox[1, :] - new_bbox[0, :]
                    delta_x = self._next_x_align(delta[0])
                    delta_y = self._next_y_align(delta[1])

                    rl_box = shapely.geometry.box(new_bbox[0][0],
                                                  new_bbox[0][1],
                                                  new_bbox[0][0] + delta_x,
                                                  new_bbox[0][1] + delta_y)
                    layout_cell.add_to_layer(self.region_layer, rl_box)

                if item['cell']:
                    if isinstance(item['cell'], Cell):
                        layout_cell.add_cell(item['cell'], origin=origin)
                    else:
                        layout_cell.add_to_layer(
                            self.text_layer, translate(item['cell'], *origin))

                next_x_pos = pos[0] + max_width + self.horizontal_spacing
                limits[0] = max(next_x_pos, limits[0])
                pos[0] = self._next_x_align(next_x_pos)

            next_y_pos = pos[1] + max_height + self.vertical_spacing
            limits[1] = max(next_y_pos, limits[1])
            pos[1] = next_y_pos

        if self.title:
            # If there is enough space for the title text until next alignment, use it
            tmp_text_obj = Text([0, 0], self.text_size,
                                self.title).get_shapely_object()
            title_vertical_space = (tmp_text_obj.bounds[3] +
                                    0.7 * self.text_size) + self.line_width
            title_horizontal_space = (tmp_text_obj.bounds[2] +
                                      self.text_size) + self.line_width
            limits[0] = max(limits[0], title_horizontal_space)

            if self.align_title_line:
                title_vertical_space = self._next_y_align(
                    title_vertical_space) - self.line_width / 2.

            if (self._next_y_align(pos[1]) -
                    limits[1]) >= title_vertical_space:
                limits[1] = pos[1] - title_vertical_space
            else:
                pos[1] = self._next_y_align(limits[1] + title_vertical_space)
                limits[1] = pos[1] - title_vertical_space

            # Paint vertical line
            if self.frame_layer:
                line = shapely.geometry.LineString([
                    (self.line_width, limits[1]),
                    (self._next_x_align(limits[0]) - self.line_width,
                     limits[1])
                ])
                line = line.buffer(self.line_width)
                layout_cell.add_to_layer(self.frame_layer, line)

            title = Text([self.horizontal_spacing, (pos[1] + limits[1]) / 2.],
                         self.text_size,
                         self.title,
                         alignment='left-center')
            layout_cell.add_to_layer(self.text_layer, title)
        else:
            pos[1] = self._next_y_align(pos[1] + self.line_width)

        # Draw the frame
        if self.frame_layer:
            frame = shapely.geometry.box(0, 0, self._next_x_align(limits[0]),
                                         pos[1])
            frame = frame.difference(frame.buffer(-self.line_width))
            layout_cell.add_to_layer(self.frame_layer, frame)

        if self.region_layer_type == 'layout':
            frame = shapely.geometry.box(0, 0, self._next_x_align(limits[0]),
                                         pos[1])
            layout_cell.add_to_layer(self.region_layer, frame)

        return layout_cell, mapping