コード例 #1
0
def _example():
    from gdshelpers.geometry.chip import Cell

    devicename = 'MZI'

    mzi = MachZehnderInterferometer(origin=(0, 0),
                                    angle=0,
                                    width=1.2,
                                    splitter_length=10,
                                    splitter_separation=5,
                                    bend_radius=50,
                                    upper_vertical_length=50,
                                    lower_vertical_length=0,
                                    horizontal_length=0)
    mzi_mmi = MachZehnderInterferometerMMI(origin=(300, 0),
                                           angle=0,
                                           width=1.2,
                                           splitter_length=33,
                                           splitter_width=7.7,
                                           bend_radius=50,
                                           upper_vertical_length=50,
                                           lower_vertical_length=0,
                                           horizontal_length=0)
    print(mzi_mmi.device_width)

    wg = Waveguide.make_at_port(mzi_mmi.port)
    wg.add_straight_segment(length=50)

    cell = Cell(devicename)
    cell.add_to_layer(1, mzi)
    cell.add_to_layer(1, mzi_mmi)
    cell.add_to_layer(1, wg)

    cell.save('%s.gds' % devicename)
コード例 #2
0
def Ring_Test(label, gap, ring_r, ring_wg_width=wg_width):
    cell = Cell('Ring_Test' + label)

    r_bend = 60 #bend_r
    r_eff = r_bend / euler_to_bend_coeff

    outports = [Port((opt_space * i, 0), np.pi / 2, std_coupler_params['width']) for i in (0, 1)]
    gratingcouplers = [GratingCoupler.make_traditional_coupler_at_port(outport, **std_coupler_params) for outport in
                       outports]

    port = outports[0].inverted_direction

    wg = Waveguide.make_at_port(port)
    wg.add_straight_segment(grating_added_taper_len, wg_width)
    # wgAdd_EulerBend(wg, np.pi / 2., r_eff, False)
    wg.add_bend(np.pi / 2., r_bend)

    dist_straight = opt_space - 2 * r_bend
    wg.add_straight_segment(dist_straight / 2.)

    ring_res = RingResonator.make_at_port(wg.current_port.inverted_direction, gap=gap, radius=ring_r, res_wg_width=ring_wg_width)

    wg.add_straight_segment(dist_straight / 2.)

    # wgAdd_EulerBend(wg, np.pi / 2., r_eff, False)
    wg.add_bend(np.pi / 2., r_bend)
    wg.add_straight_segment_until_y(outports[1].origin[1]-grating_added_taper_len)
    wg.add_straight_segment(grating_added_taper_len, std_coupler_params['width'])

    label_txt = Text((opt_space / 2., -6), 25, label, alignment='center-top')

    shapely_object = geometric_union(gratingcouplers + [label_txt] + [wg] + [ring_res])
    cell.add_to_layer(wg_layer, shapely_object)

    comments = Text((60, 40), 10,
                    'gap={:.2f}\nrad={:.2f}\nwg_width={:.2f}'.format(gap, ring_r, ring_wg_width),
                    alignment='center-top')
    cell.add_to_layer(comment_layer, comments)

    x_cords = []
    y_cords = []
    box_disty = 2
    for this_poly in shapely_object.geoms:
        temp_x_cords, temp_y_cords = this_poly.exterior.coords.xy
        x_cords = x_cords + list(temp_x_cords)
        y_cords = y_cords + list(temp_y_cords)
    x_max = max(x_cords) + box_dist
    x_min = min(x_cords) - box_dist
    y_max = max(y_cords) + box_disty
    y_min = min(y_cords) - box_disty
    box_size = (x_max - x_min, y_max - y_min)

    box = Waveguide(((x_min + x_max) / 2., y_min), np.pi / 2, box_size[0])
    box.add_straight_segment(box_size[1])
    total_box = geometric_union([box])
    cell.add_to_layer(wg_wf_layer, total_box)
    cell.add_to_layer(wg_reg_layer, total_box)

    return cell
コード例 #3
0
def Efficiency_Grating(label, period, ff, grating_angle = None):
    cell = Cell('GC_Test' + label)

    r_bend = 60 #bend_r
    r_eff = r_bend / euler_to_bend_coeff

    coupler_params = std_coupler_params.copy()
    coupler_params['grating_period'] = period
    coupler_params['grating_ff'] = ff
    if grating_angle is not None:
        coupler_params['full_opening_angle'] = grating_angle

    outports = [Port((opt_space * i, 0), np.pi / 2, std_coupler_params['width']) for i in (0, 1)]
    gratingcouplers = [GratingCoupler.make_traditional_coupler_at_port(outport, **coupler_params) for outport in
                       outports]

    port = outports[0].inverted_direction

    wg = Waveguide.make_at_port(port)
    wg.add_straight_segment(grating_added_taper_len, wg_width)
    wg.add_bend(np.pi / 2., r_bend)
    wg.add_straight_segment(opt_space - 2 * r_bend)
    wg.add_bend(np.pi / 2., r_bend)
    wg.add_straight_segment_until_y(outports[1].origin[1]-grating_added_taper_len)
    wg.add_straight_segment(grating_added_taper_len, std_coupler_params['width'])

    label_txt = Text((opt_space / 2., -6), 25, label, alignment='center-top')

    # self.shapely_object = geometric_union([wg] + [label] + gratingcouplers)
    shapely_object = geometric_union(gratingcouplers + [label_txt] + [wg])
    cell.add_to_layer(wg_layer, shapely_object)

    comments = Text((60, 40), 10,
                    'period={:.2f}\nff={:.2f}'.format(coupler_params['grating_period'],
                                                      coupler_params['grating_ff']),
                    alignment='center-top')
    cell.add_to_layer(comment_layer, comments)

    x_cords = []
    y_cords = []
    box_disty = 2  # 2.5 * marker_dims
    for this_poly in shapely_object.geoms:
        temp_x_cords, temp_y_cords = this_poly.exterior.coords.xy
        x_cords = x_cords + list(temp_x_cords)
        y_cords = y_cords + list(temp_y_cords)
    x_max = max(x_cords) + box_dist
    x_min = min(x_cords) - box_dist
    y_max = max(y_cords) + box_disty
    y_min = min(y_cords) - box_disty
    box_size = (x_max - x_min, y_max - y_min)

    box = Waveguide(((x_min + x_max) / 2., y_min), np.pi / 2, box_size[0])
    box.add_straight_segment(box_size[1])
    total_box = geometric_union([box])
    cell.add_to_layer(wg_wf_layer, total_box)
    cell.add_to_layer(wg_reg_layer, total_box)

    return cell
コード例 #4
0
def generate_bunch_of_guides(number_of_lines, line_widths, length):
    guides = Cell('guides')
    line_widths = iop.fill_list(number_of_lines, line_widths, sorting='ascending')

    for y in range(0, number_of_lines):
        guide = Waveguide.make_at_port(Port((0, y*5), 0, line_widths[y]))
        guide.add_straight_segment(length)
        guides.add_to_layer(1, guide)
    return guides
コード例 #5
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)
コード例 #6
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))
コード例 #7
0
    def test_frame(self):
        # Add frame
        cell = Cell('test_frame')
        cell.add_to_layer(4, box(0, 0, 10, 10))
        cell.add_frame(padding=10, line_width=1., frame_layer=5)
        self.assertEqual(cell.bounds, (-11, -11, 21, 21))
        self.assertEqual(cell.get_bounds(layers=[4]), (0, 0, 10, 10))
        self.assertEqual(cell.get_bounds(layers=[5]), (-11, -11, 21, 21))

        cell.add_frame(padding=10,
                       line_width=1.,
                       frame_layer=99,
                       bounds=(0, 0, 2, 3))
        self.assertEqual(cell.get_bounds(layers=[99]), (-11, -11, 13, 14))
コード例 #8
0
def _example():
    from gdshelpers.geometry.chip import Cell
    from gdshelpers.parts.waveguide import Waveguide
    from gdshelpers.parts.resonator import RingResonator

    # ==== create some sample structures (straight line with ring resonator)
    wg = Waveguide(origin=(0, 0), angle=np.deg2rad(-90), width=1)
    wg.add_straight_segment(length=5)
    wg.add_bend(np.pi / 2, 5)
    wg2 = Waveguide.make_at_port(wg.current_port)
    wg2.add_straight_segment(15)
    reso = RingResonator.make_at_port(port=wg2.current_port, gap=0.2, radius=5)
    wg2.add_straight_segment(length=15)
    coupler2 = GratingCoupler.make_traditional_coupler_from_database_at_port(
        wg2.current_port, db_id='si220', wavelength=1550)

    underetching_parts = geometric_union([wg2, reso, coupler2])
    structure = geometric_union([underetching_parts, wg])
    # create the holes with a radius of 0.5 microns, a distance of 2 microns to the structure borders and
    # a distance of 2 microns between the holes
    holes = create_holes_for_under_etching(underetch_parts=underetching_parts,
                                           complete_structure=structure,
                                           hole_radius=0.5,
                                           hole_distance=2,
                                           hole_spacing=3,
                                           hole_length=3)

    # create a cell with the structures in layer 1 and the holes in layer 2
    cell = Cell('CELL')
    cell.add_to_layer(1, structure)
    cell.add_to_layer(2, holes)
    # Show the cell
    cell.show()
コード例 #9
0
    def test_parallel_export(self):
        waveguide = Waveguide([0, 0], 0, 1)
        for i_bend in range(9):
            waveguide.add_bend(angle=np.pi, radius=60 + i_bend * 40)

        cells = [Cell('main')]
        for i in range(10):
            cell = Cell('sub_cell_' + str(i))
            cell.add_to_layer(waveguide)
            cells[-1].add_cell(cell, (10, 10))

        cells[0].save('serial.gds', library='gdshelpers', parallel=False)
        cells[0].save('parallel.gds', library='gdshelpers', parallel=True)

        self.assertTrue(filecmp.cmp('serial.gds', 'parallel.gds'))
コード例 #10
0
def generate_layout_cell(size=50, line_width=10):
    cell = Cell('templateMembraneAlign, size = {}, line_width = {}'.format(
        size, line_width))

    # ring, ring_location = iop.port_ring(15, 10, offset=(100, 200))
    corners = [-30, -10, -30, 10, 30, 10, 30, -10]
    shape, shape_port = iop.port_shape_cartesian(corners,
                                                 rotate=np.pi * 0,
                                                 port=Port((-100, 250), 0, 1),
                                                 offset=(100, 200))

    # ============================================
    cell.add_to_layer(1, shape)

    return cell
コード例 #11
0
ファイル: logo.py プロジェクト: philomathie/gdshelpers
def _example():
    from gdshelpers.geometry.chip import Cell

    kit_logo = KITLogo([0, 0], 1)
    wwu_logo = WWULogo([0, 0], 1, 1)

    cell = Cell('LOGOS')
    cell.add_to_layer(1, kit_logo)
    cell.add_to_layer(1, translate(wwu_logo.get_shapely_object(), 2.5))
    cell.show()
コード例 #12
0
def _example():
    text = Text([100, 100], 10, 'The quick brown fox jumps over the lazy dog\n123\n4567',
                alignment='left-bottom', angle=0.1)
    print(text.bounding_box)

    from gdshelpers.geometry.chip import Cell

    cell = Cell('FONTS')
    cell.add_to_layer(2, shapely.geometry.box(*text.bounding_box.reshape(4)))
    cell.add_to_layer(1, text)
    cell.show()
コード例 #13
0
ファイル: resonator.py プロジェクト: philomathie/gdshelpers
def _example():
    from gdshelpers.geometry.chip import Cell

    cell = Cell('test')

    wg1 = Waveguide.make_at_port(Port((0, 0), 0, 1.))
    wg1.add_straight_segment(100)
    ring1 = RingResonator.make_at_port(wg1.current_port,
                                       1.,
                                       50.,
                                       race_length=30,
                                       straight_feeding=True,
                                       draw_opposite_side_wg=True)

    wg2 = Waveguide.make_at_port(ring1.port)
    wg2.add_straight_segment(100)
    ring2 = RingResonator.make_at_port(wg2.current_port,
                                       1.,
                                       50.,
                                       vertical_race_length=30,
                                       straight_feeding=True,
                                       draw_opposite_side_wg=True)

    wg3 = Waveguide.make_at_port(ring2.port)
    wg3.add_straight_segment(100)
    ring3 = RingResonator.make_at_port(wg3.current_port,
                                       -1.,
                                       50.,
                                       vertical_race_length=30,
                                       straight_feeding=True,
                                       draw_opposite_side_wg=True)

    cell.add_to_layer(1, wg1, ring1, wg2, ring2, wg3, ring3)
    cell.show()
コード例 #14
0
def _example():
    from gdshelpers.geometry.chip import Cell
    from gdshelpers.parts.port import Port
    from gdshelpers.parts.waveguide import Waveguide
    from gdshelpers.parts.mode_converter import StripToSlotModeConverter

    wg_1 = Waveguide.make_at_port(
        Port(origin=(0, 0), angle=0,
             width=1.2))  # scalar as width -> strip waveguide
    wg_1.add_straight_segment(5)

    mc_1 = StripToSlotModeConverter.make_at_port(
        wg_1.current_port, 5, [0.4, 0.2, 0.4], 2,
        0.2)  # array as width -> slot waveguide

    wg_2 = Waveguide.make_at_port(mc_1.out_port)
    wg_2.add_bend(angle=np.pi, radius=5)

    mc_2 = StripToSlotModeConverter.make_at_port(
        wg_2.current_port, 5, 1, 2, 0.2)  # scalar as width -> strip waveguide

    wg_3 = Waveguide.make_at_port(mc_2.out_port)
    wg_3.add_straight_segment(5)

    cell = Cell('CELL')
    cell.add_to_layer(1, wg_1, mc_1, wg_2, mc_2, wg_3)
    cell.show()
コード例 #15
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))
コード例 #16
0
def _example():
    from gdshelpers.geometry.chip import Cell

    img = GdsImage([0, 0], "wolfram_monochrome_100.png", 10)

    cell = Cell('TEST_IMAGE')
    cell.add_to_layer(1, img)
    cell.show()
    return cell
コード例 #17
0
ファイル: grid.py プロジェクト: philomathie/gdshelpers
def _example():
    layout = GridLayout('Test layout\nwith very cool features' + 'long! ' * 50,
                        tight=False,
                        region_layer_type=None)

    layout.add_column_label_row(['c0', 'c1'], 'col_labels')

    layout.begin_new_row('row1')

    test_cell_1 = Cell('TC1')
    test_cell_1.add_to_layer(1, shapely.geometry.box(0, 00, 335, 125))

    test_cell_2 = Cell('TC2')
    # test_cell_2.add_to_layer(1, shapely.geometry.box(101, 101, 335, 125))
    test_cell_2.add_to_layer(1, shapely.geometry.box(0, 0, 600, 400))

    layout.add_to_row(test_cell_1, realign=False)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_1,
                      realign=True)  # , alignment='center-center')

    layout.begin_new_row('row2')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')

    layout.begin_new_row('row3')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')
    layout.add_to_row(test_cell_2, realign=True)  # , alignment='left-bottom')

    # layout.add_to_row(test_cell_1, realign=True)#, alignment='left-bottom')

    layout_cell, mapping = layout.generate_layout()

    layout_cell.show()
    layout_cell.save()
コード例 #18
0
def _example():
    from gdshelpers.geometry.chip import Cell

    wg = Waveguide((0, 0), 1, 1)
    wg.add_straight_segment(30)
    spiral = Spiral.make_at_port(wg.current_port, 2, 5, 50)
    wg2 = Waveguide.make_at_port(spiral.out_port)
    wg2.add_straight_segment(100)

    print(spiral.length)

    cell = Cell('Spiral')
    cell.add_to_layer(1, wg, spiral, wg2)
    cell.show()
コード例 #19
0
import numpy as np
from gdshelpers.geometry.chip import Cell
from gdshelpers.parts.text import Text
from gdshelpers.parts.marker import DLWMarker, SquareMarker, CrossMarker
from gdshelpers.parts.waveguide import Waveguide
from gdshelpers.parts.port import Port
from gdshelpers.geometry.shapely_adapter import geometric_union
from gdshelpers.parts.coupler import GratingCoupler
from gdshelpers.parts.spiral import Spiral
from shapely.geometry import Polygon
from utils import *
from parts import interferometer_and_fiber_array

cell = Cell('4x4 interferometer')

wg_width = 0.5
electrode_wg_sep = 62.5
second_x_middle = 8 * 2 * 127

inport_0 = Port((-electrode_wg_sep / 2 - 25, 0), np.pi / 2, wg_width)
inport_1 = Port((-electrode_wg_sep / 2, 0), np.pi / 2, wg_width)
inport_2 = Port((electrode_wg_sep / 2, 0), np.pi / 2, wg_width)
inport_3 = Port((electrode_wg_sep / 2 + 25, 0), np.pi / 2, wg_width)
device_inports = [inport_0, inport_1, inport_2, inport_3]

# fiber_array
gc_pitch = 127
wg_sep = 25
min_radius = 50
starting_point = second_x_middle / 2 - gc_pitch * 3.5
gc_y = 100
コード例 #20
0
ファイル: gdsii_export.py プロジェクト: fbeutel/gdshelpers
                                   (timestamp, ) * num):
                outfile.write(binary)
    else:
        for c in cells:
            outfile.write(
                _cell_to_gdsii_binary(c, grid_steps_per_unit, max_points,
                                      max_line_points, timestamp))
    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
コード例 #21
0
# fiber_array
gc_pitch = 127
wg_sep = 25
min_radius = 70
gc_starting_point = second_x_middle / 2 - gc_pitch * 3.5
gc_starting_point_2 = (0.5 * (first_x_middle_2 + second_x_middle_2) -
                       gc_pitch * 3.5)
gc_y = 100
grating_coupler_positions = [(gc_starting_point + idx * gc_pitch, gc_y)
                             for idx in range(8)]
grating_coupler_positions_2 = [(gc_starting_point_2 + idx * gc_pitch, gc_y)
                               for idx in range(8)]

# Adding Left 4x4 interferometer
left4x4_cell = Cell('4x4 interferometer_Left')

left_electrode_wf_layers = np.arange(110, 140 + 1, 10)
right_electrode_wf_layers = np.arange(150, 200 + 1, 10)

_, left_init_wf_point, left_in_bounds = interferometer_and_fiber_array(
    cell=left4x4_cell,
    inports=device_inports,
    gc_positions=grating_coupler_positions,
    electrode_length=1250,
    coupler_sep=0.5,
    coupler_length=30,
    sm_wg_width=wg_width,
    delay_lines=False,
    wg_layer=9,
    wf_layer=100,
コード例 #22
0
                                               datatype)
            if sub_geometry.is_empty:
                continue
            sub_geometry = scale(
                sub_geometry, *[reference.magnification] *
                2) if reference.magnification else sub_geometry
            sub_geometry = scale(
                sub_geometry, -1) if reference.x_reflection else sub_geometry
            sub_geometry = rotate(
                sub_geometry, reference.rotation,
                origin=(0, 0)) if reference.rotation else sub_geometry
            sub_geometry = translate(sub_geometry, *reference.origin)
            geometry.extend(sub_geometry)

        return MultiPolygon(geometry)

    def get_shapely_object(self):
        return self.get_as_shapely(self.cell_name, self.layer, self.datatype)


if __name__ == '__main__':
    from gdshelpers.parts.waveguide import _example
    from gdshelpers.geometry.chip import Cell

    _example()  # make sure the "output.gds" exists

    test_cell = Cell('test')
    test_cell.add_to_layer(1,
                           GDSIIImport('output.gds', cell_name='TOP', layer=1))
    test_cell.show()
コード例 #23
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()
コード例 #24
0
ファイル: snspd.py プロジェクト: philomathie/gdshelpers
def _example():
    from gdshelpers.geometry.chip import Cell

    cell = Cell('test')

    wg1 = Waveguide((0, 0), 0.5 * np.pi, 1.)
    wg1.add_straight_segment(10.)
    cell.add_to_layer(3, wg1)

    detector = SNSPD.make_at_port(wg1.current_port, nw_width=0.1, nw_gap=0.1, nw_length=70, passivation_buffer=0.2,
                                  waveguide_tapering=True)
    cell.add_to_layer(1, detector)
    cell.add_to_layer(2, detector.get_waveguide())
    cell.add_to_layer(5, detector.get_passivation_layer())

    # cell.add_to_layer(6, detector.right_electrode_port.debug_shape)
    # cell.add_to_layer(6, detector.left_electrode_port.debug_shape)
    wg2 = Waveguide.make_at_port(detector.current_port)
    wg2.add_straight_segment(20.)
    cell.add_to_layer(3, wg2)
    cell.save('SNSPD_test.gds')
    cell.show()
コード例 #25
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()
コード例 #26
0
def Demux_active(coupler_sep,
                 coupler_length,
                 Mod_length,
                 electrodes_sep,
                 label,
                 exp_wg_width=wg_Expwidth,
                 grating_coupler_period=std_coupler_params['grating_period']):
    cell = Cell('Demux_active' + label)

    x_in = 0
    y_in = 0

    MZ_length = Mod_length + 50

    wg_sep = mod_params['wg_sep']
    wg_sep_out = 60
    wg_sep_small = 10

    wg_width_in_mod = wg_Expwidth
    taper_length = l_Exptaper

    ##Generating input and output grating couplers

    coupler_params = std_coupler_params.copy()
    coupler_params['grating_period'] = grating_coupler_period

    for j in range(4):
        incoupler = GratingCoupler.make_traditional_coupler(
            (x_in + j * opt_space, y_in), **coupler_params)
        cell.add_to_layer(wg_layer, incoupler)

    outcouplers = []
    empty_gratcouplers = 0

    for j in range(4):
        outcoupler = GratingCoupler.make_traditional_coupler(
            (x_in + (j + 4 + empty_gratcouplers) * opt_space, y_in),
            **coupler_params)
        outcouplers.append(outcoupler)
        cell.add_to_layer(wg_layer, outcoupler)

    ###Generating waveguides

    inports = [
        Port((x_in + j * opt_space, y_in), np.deg2rad(90),
             std_coupler_params['width']) for j in (0, 1, 2, 3)
    ]
    wg = [Waveguide.make_at_port(inport) for inport in inports]

    x_ref0 = x_in + 1.5 * opt_space
    # y_ref0 = y_in - 3*bend_r

    x_refout = x_ref0 + (4 + empty_gratcouplers) * opt_space

    x_lastout = x_in + (7 + empty_gratcouplers) * opt_space
    x_centre = (x_in + x_lastout) / 2.
    y_start_epads = y_in - MZ_length - 930

    ########## Input Connections

    for j in range(4):
        # adding final tapers as suggested by Munster, SP 21/10/21
        wg[j].add_straight_segment(grating_added_taper_len,
                                   final_width=wg_width)
        wg[j].add_bend(np.pi / 2.0, bend_r + j * wg_sep_small)
        wg[j].add_straight_segment_until_x(x_in - bend_r - 1)
        wg[j].add_bend(np.pi / 2.0, bend_r + j * wg_sep_small)
        wg[j].add_straight_segment(grating_added_taper_len + 20)
        wg[j].add_bend(np.pi / 2.0, bend_r + j * wg_sep_small)
        wg[j].add_straight_segment_until_x(x_ref0 - (j - 1.5) * wg_sep_out -
                                           bend_r)
        wg[j].add_bend(-np.pi / 2.0, bend_r)

    y_ref0 = wg[-1].current_port.origin[1] - 1
    for j in range(4):
        wg[j].add_straight_segment_until_y(y_ref0)

        ########## Zero-th MZI
        mzi0_xstart = x_ref0
        mzi0_ystart = y_ref0

    for j in (1, 2):
        wgAdd_EulerSBend(wg[j],
                         offset=(j - 1.5) * (wg_sep_out - wg_sep),
                         radius=bend_r)

        ##directional coupler with sinusoidal s-bend
        x_length = 60
        y_length = wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - (j - 1) * (
            wg_sep - wg_width - coupler_sep)
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))
        wg[j].add_straight_segment(coupler_length)
        y_length = -(wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - (j - 1) *
                     (wg_sep - wg_width - coupler_sep))
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))

        #add taper to multimode wg
        wg[j].add_straight_segment(taper_length, final_width=wg_width_in_mod)

        ###reference port for electrodes in MZI
        ref_port0 = wg[j].current_port

        ###straight section
        wg[j].add_straight_segment(MZ_length)

        #add taper to single-mode wg
        wg[j].add_straight_segment(taper_length, final_width=wg_width)

        ##directional coupler with sinusoidal s-bend
        x_length = 60
        y_length = wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - (j - 1) * (
            wg_sep - wg_width - coupler_sep)
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))
        wg[j].add_straight_segment(coupler_length)
        y_length = -(wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - (j - 1) *
                     (wg_sep - wg_width - coupler_sep))
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))

        wgAdd_EulerSBend(wg[j],
                         offset=-(j - 1.5) * (wg_sep_out - wg_sep),
                         radius=bend_r)

    mzi0_xend = x_ref0
    mzi0_yend = wg[j].current_port.origin[1]
    for j in (0, 3):
        wg[j].add_straight_segment(l_Exptaper, final_width=exp_wg_width)
        wg[j].add_straight_segment_until_y(mzi0_yend + l_Exptaper)
        wg[j].add_straight_segment(l_Exptaper, final_width=wg_width)

    ########## Turn
    for j in range(4):
        wg[j].add_bend(np.pi / 2.0, bend_r + j * wg_sep_small)
        wg[j].add_straight_segment(l_Exptaper, final_width=exp_wg_width)
        wg[j].add_straight_segment_until_x(x_refout - 1.5 * wg_sep_out -
                                           bend_r + j *
                                           (wg_sep_out - wg_sep_small) -
                                           l_Exptaper)
        wg[j].add_straight_segment(l_Exptaper, final_width=wg_width)
        wg[j].add_bend(np.pi / 2.0, bend_r + j * wg_sep_small)

    ########## First MZI (left)
    mzi1_xstart = wg[0].current_port.origin[0]
    mzi1_ystart = wg[0].current_port.origin[1]

    for j in (0, 1):
        wgAdd_EulerSBend(wg[j],
                         offset=(j - 0.5) * (wg_sep_out - wg_sep),
                         radius=bend_r)

        #directional coupler with sinusoidal s-bend
        x_length = 60
        y_length = wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - j * (
            wg_sep - wg_width - coupler_sep)
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))
        wg[j].add_straight_segment(coupler_length)
        y_length = -(wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - j *
                     (wg_sep - wg_width - coupler_sep))
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))

        # add taper to multimode wg
        wg[j].add_straight_segment(taper_length, final_width=wg_width_in_mod)

        ###reference port for electrodes in MZI
        ref_port1 = wg[j].current_port

        ###straight section
        wg[j].add_straight_segment(MZ_length)

        # add taper to single-mode wg
        wg[j].add_straight_segment(taper_length, final_width=wg_width)

        ##directional coupler with sinusoidal s-bend
        x_length = 60
        y_length = wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - j * (
            wg_sep - wg_width - coupler_sep)
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))
        wg[j].add_straight_segment(coupler_length)
        y_length = -(wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - j *
                     (wg_sep - wg_width - coupler_sep))
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))

        wgAdd_EulerSBend(wg[j],
                         offset=-(j - 0.5) * (wg_sep_out - wg_sep),
                         radius=bend_r)

    ########## Second MZI (left)
    mzi1_xstart = wg[2].current_port.origin[0]
    mzi1_ystart = wg[2].current_port.origin[1]

    for j in (2, 3):
        wgAdd_EulerSBend(wg[j],
                         offset=(j - 2.5) * (wg_sep_out - wg_sep),
                         radius=bend_r)

        ##directional coupler with sinusoidal s-bend
        x_length = 60
        y_length = wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - (j - 2) * (
            wg_sep - wg_width - coupler_sep)
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))
        wg[j].add_straight_segment(coupler_length)
        y_length = -(wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - (j - 2) *
                     (wg_sep - wg_width - coupler_sep))
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))

        # add taper to multimode wg
        wg[j].add_straight_segment(taper_length, final_width=wg_width_in_mod)

        ###reference port for electrodes in MZI
        ref_port2 = wg[j].current_port

        ###straight section
        wg[j].add_straight_segment(MZ_length)

        # add taper to single-mode wg
        wg[j].add_straight_segment(taper_length, final_width=wg_width)

        ##directional coupler with sinusoidal s-bend
        x_length = 60
        y_length = wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - (j - 2) * (
            wg_sep - wg_width - coupler_sep)
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))
        wg[j].add_straight_segment(coupler_length)
        y_length = -(wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - (j - 2) *
                     (wg_sep - wg_width - coupler_sep))
        wg[j].add_parameterized_path(
            path=lambda t: (t * x_length, .5 *
                            (np.cos(np.pi * t) - 1) * y_length),
            path_derivative=lambda t:
            (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))

        wgAdd_EulerSBend(wg[j],
                         offset=-(j - 2.5) * (wg_sep_out - wg_sep),
                         radius=bend_r)

    ########## Output Connections

    for j in range(4):
        wg[j].add_straight_segment((3 - j) * wg_sep_small + 1)
        wg[j].add_bend(-np.pi / 2.0, bend_r)
        wg[j].add_straight_segment_until_x(x_lastout + bend_r + 1)
        wg[j].add_bend(np.pi / 2.0, bend_r + j * wg_sep_small)
        wg[j].add_straight_segment(grating_added_taper_len + 20)
        wg[j].add_bend(np.pi / 2.0, bend_r + j * wg_sep_small)
        wg[j].add_straight_segment_until_x(x_lastout - j * (opt_space) +
                                           bend_r + j * wg_sep_small)
        wg[j].add_bend(np.pi / 2.0, bend_r + j * wg_sep_small)
        wg[j].add_straight_segment(grating_added_taper_len,
                                   final_width=std_coupler_params['width'])

        #
    for j in range(4):
        cell.add_to_layer(wg_layer, wg[j])

    ##MODULATORs ELECTRODES

    electr_width = mod_params['electrode_width']
    sep_econns = mod_params['electrode_sep_y']
    cross_width = mod_params['crossing_width']
    pads_pitch = mod_params['connector_probe_pitch']
    pads_width = mod_params['connector_probe_dims'][0]
    pads_width_gnd = mod_params['connector_probe_dims_gnd'][0]
    pads_len = mod_params['connector_probe_dims'][1] - 200
    min_safedist_from_wg = 22

    x_start_epads = x_centre - 3 * pads_pitch

    #### ELECTRODES IN ZEROTH MZI
    x_safe_dist = ref_port0.origin[
        0] - min_safedist_from_wg - pads_width - wg_sep / 2.0 - wg_sep_out

    ##left ground electrode
    Inport = Port((ref_port0.origin[0] - electrodes_sep / 2.0 - wg_sep / 2.0,
                   ref_port0.origin[1]), np.deg2rad(-90), electr_width)
    g_left0 = Waveguide.make_at_port(Inport)
    g_left0.add_straight_segment(Mod_length - cross_width / 2. -
                                 2 * sep_econns)
    g_left0._current_port.angle = g_left0.current_port.angle - np.pi / 2.0
    g_left0._current_port.origin[
        0] = g_left0.current_port.origin[0] + g_left0.current_port.width / 2.0
    g_left0._current_port.width = cross_width
    g_left0.add_straight_segment_until_x(x_safe_dist + wg_sep_out)
    g_left0.add_straight_segment(wg_sep, electr_width)
    g_left0.add_straight_segment_until_x(x_safe_dist)

    g_left0.add_straight_segment(2 * sep_econns)
    g_left0._current_port.angle = g_left0.current_port.angle + np.pi / 2.0
    g_left0._current_port.origin[
        1] = g_left0.current_port.origin[1] + g_left0.current_port.width / 2.0
    g_left0.add_straight_segment_until_y(y_start_epads - 2 * sep_econns)
    g_left0._current_port.angle = g_left0.current_port.angle + np.pi / 2.0
    g_left0._current_port.origin[
        0] = g_left0.current_port.origin[0] - g_left0.current_port.width / 2.0
    g_left0._current_port.origin[
        1] = g_left0.current_port.origin[1] + g_left0.current_port.width / 2.0
    g_left0.add_straight_segment_until_x(x_start_epads)

    g_left0._current_port.angle = g_left0.current_port.angle - np.pi / 2.0
    g_left0._current_port.origin[0] = g_left0.current_port.origin[
        0]  #+ pads_width_gnd / 2.0
    # g_left0._current_port.origin[1] = g_left0.current_port.origin[1] + g_left0.current_port.width / 2.0
    g_left0._current_port.width = pads_width_gnd
    g_left0.add_straight_segment(pads_len)

    cell.add_to_layer(electrode_layer, g_left0)

    ## signal electrode
    Inport = Port((ref_port0.origin[0] + wg_sep / 2.0, ref_port0.origin[1]),
                  np.deg2rad(-90), electr_width - electrodes_sep)
    s0 = Waveguide.make_at_port(Inport)
    s0.add_straight_segment(Mod_length - cross_width / 2. - sep_econns)
    s0._current_port.angle = s0.current_port.angle - np.pi / 2.0
    s0._current_port.origin[
        0] = s0.current_port.origin[0] + s0.current_port.width / 2.0
    s0._current_port.width = cross_width
    s0.add_straight_segment_until_x(x_safe_dist + wg_sep_out)
    s0.add_straight_segment(wg_sep, electr_width)
    s0.add_straight_segment_until_x(x_safe_dist)

    s0.add_straight_segment(sep_econns)
    s0._current_port.angle = s0.current_port.angle + np.pi / 2.0
    s0._current_port.origin[
        1] = s0.current_port.origin[1] + s0.current_port.width / 2.0
    s0.add_straight_segment_until_y(y_start_epads - sep_econns)
    s0._current_port.angle = s0.current_port.angle + np.pi / 2.0
    s0._current_port.origin[
        0] = s0.current_port.origin[0] - s0.current_port.width / 2.0
    s0.add_straight_segment_until_x(x_start_epads + pads_pitch)
    #
    s0._current_port.angle = s0.current_port.angle - np.pi / 2.0
    s0._current_port.origin[0] = s0.current_port.origin[0]  #+ pads_width / 2.0
    s0._current_port.origin[
        1] = s0.current_port.origin[1] + s0.current_port.width / 2.0
    s0._current_port.width = pads_width
    s0.add_straight_segment_until_y(g_left0.current_port.origin[1] + 50)

    cell.add_to_layer(electrode_layer, s0)

    # ##right ground electrode
    Inport = Port(
        (ref_port0.origin[0] + wg_sep + wg_sep / 2.0 + electrodes_sep / 2.0,
         ref_port0.origin[1]), np.deg2rad(-90), electr_width)
    g_right0 = Waveguide.make_at_port(Inport)
    g_right0.add_straight_segment(Mod_length - cross_width / 2.)
    g_right0._current_port.angle = g_right0.current_port.angle - np.pi / 2.0
    g_right0._current_port.origin[0] = g_right0.current_port.origin[
        0] + g_right0.current_port.width / 2.0
    g_right0._current_port.width = cross_width
    g_right0.add_straight_segment_until_x(x_safe_dist + wg_sep_out)
    g_right0.add_straight_segment(wg_sep, electr_width)
    g_right0.add_straight_segment_until_x(x_safe_dist)

    g_right0._current_port.angle = g_right0.current_port.angle + np.pi / 2.0
    g_right0._current_port.origin[1] = g_right0.current_port.origin[
        1] + g_right0.current_port.width / 2.0
    g_right0.add_straight_segment_until_y(y_start_epads)
    g_right0._current_port.angle = g_right0.current_port.angle + np.pi / 2.0
    g_right0._current_port.origin[0] = g_right0.current_port.origin[
        0] - g_right0.current_port.width / 2.0
    g_right0.add_straight_segment_until_x(x_start_epads + 2 * pads_pitch)

    g_right0._current_port.angle = g_right0.current_port.angle - np.pi / 2.0
    g_right0._current_port.origin[0] = g_right0.current_port.origin[
        0]  #+ 5. #+ pads_width_gnd / 2.0
    g_right0._current_port.origin[1] = g_right0.current_port.origin[
        1] + g_right0.current_port.width / 2.0
    g_right0._current_port.width = pads_width_gnd
    g_right0.add_straight_segment_until_y(g_left0.current_port.origin[1])
    g_right0._current_port.angle = g_right0.current_port.angle - np.pi / 2.0
    g_right0._current_port.origin[0] = g_right0.current_port.origin[
        0] + g_right0.current_port.width / 2.0
    g_right0._current_port.width = pads_width / 2.
    g_right0._current_port.origin[1] = g_right0.current_port.origin[
        1] - g_right0._current_port.width / 2.
    # g_right0.add_straight_segment(2 * pads_pitch + pads_width)
    g_right0.add_straight_segment(2 * pads_pitch + pads_width_gnd)

    cell.add_to_layer(electrode_layer, g_right0)

    # #### ELECTRODES FOR FIRST MZI
    elec_offset = 90
    x_safe_dist = ref_port1.origin[
        0] + min_safedist_from_wg + pads_width + wg_sep / 2.0 + 2 * wg_sep_out

    ##right ground electrode
    Inport = Port(
        (ref_port1.origin[0] + wg_sep - wg_sep / 2.0 + electrodes_sep / 2.0,
         ref_port1.origin[1] + MZ_length - elec_offset), np.deg2rad(-90),
        electr_width)
    g_right1 = Waveguide.make_at_port(Inport)
    g_right1.add_straight_segment(Mod_length - cross_width / 2. -
                                  2 * sep_econns)
    g_right1._current_port.angle = g_right1.current_port.angle + np.pi / 2.0
    g_right1._current_port.origin[0] = g_right1.current_port.origin[
        0] - g_right1.current_port.width / 2.0
    g_right1._current_port.width = cross_width
    g_right1.add_straight_segment_until_x(x_safe_dist - wg_sep_out)
    g_right1.add_straight_segment(wg_sep, electr_width)
    g_right1.add_straight_segment_until_x(x_safe_dist)

    g_right1.add_straight_segment(2 * sep_econns)
    g_right1._current_port.angle = g_right1.current_port.angle - np.pi / 2.0
    g_right1._current_port.origin[1] = g_right1.current_port.origin[
        1] + g_right1.current_port.width / 2.0
    g_right1.add_straight_segment_until_y(y_start_epads - 2 * sep_econns)
    g_right1._current_port.angle = g_right1.current_port.angle - np.pi / 2.0
    g_right1._current_port.origin[0] = g_right1.current_port.origin[
        0] + g_right1.current_port.width / 2.0
    g_right1.add_straight_segment_until_x(x_start_epads + 4 * pads_pitch)

    g_right1._current_port.angle = g_right1.current_port.angle + np.pi / 2.0
    g_right1._current_port.origin[0] = g_right1.current_port.origin[
        0]  #+ 5. #+ pads_width_gnd / 2.0
    g_right1._current_port.origin[1] = g_right1.current_port.origin[
        1] + g_right1.current_port.width / 2.0
    g_right1._current_port.width = pads_width_gnd
    g_right1.add_straight_segment_until_y(g_left0.current_port.origin[1])
    g_right1._current_port.angle = g_right1.current_port.angle - np.pi / 2.0
    g_right1._current_port.origin[0] = g_right1.current_port.origin[
        0] + g_right1.current_port.width / 2.0
    g_right1._current_port.width = pads_width / 2.
    g_right1._current_port.origin[1] = g_right1.current_port.origin[
        1] - g_right1._current_port.width / 2.
    g_right1.add_straight_segment(2 * pads_pitch + pads_width)

    cell.add_to_layer(electrode_layer, g_right1)

    ## signal electrode
    Inport = Port((ref_port1.origin[0] - wg_sep / 2.0,
                   ref_port1.origin[1] + MZ_length - elec_offset),
                  np.deg2rad(-90), electr_width - electrodes_sep)
    s1 = Waveguide.make_at_port(Inport)
    s1.add_straight_segment(Mod_length - cross_width / 2. - sep_econns)
    s1._current_port.angle = s1.current_port.angle + np.pi / 2.0
    s1._current_port.origin[
        0] = s1.current_port.origin[0] - s1.current_port.width / 2.0
    s1._current_port.width = cross_width
    s1.add_straight_segment_until_x(x_safe_dist - wg_sep_out)
    s1.add_straight_segment(wg_sep, electr_width)
    s1.add_straight_segment_until_x(x_safe_dist)

    s1.add_straight_segment(sep_econns)
    s1._current_port.angle = s1.current_port.angle - np.pi / 2.0
    s1._current_port.origin[
        1] = s1.current_port.origin[1] + s1.current_port.width / 2.0
    s1.add_straight_segment_until_y(y_start_epads - sep_econns)
    s1._current_port.angle = s1.current_port.angle - np.pi / 2.0
    s1._current_port.origin[
        0] = s1.current_port.origin[0] + s1.current_port.width / 2.0
    s1.add_straight_segment_until_x(x_start_epads + 3 * pads_pitch)

    s1._current_port.angle = s1.current_port.angle + np.pi / 2.0
    s1._current_port.origin[0] = s1.current_port.origin[0]  #+ pads_width / 2.0
    s1._current_port.origin[
        1] = s1.current_port.origin[1] + s1.current_port.width / 2.0
    s1._current_port.width = pads_width
    s1.add_straight_segment_until_y(g_left0.current_port.origin[1] + 50)

    cell.add_to_layer(electrode_layer, s1)

    # ##left ground electrode
    Inport = Port(
        (ref_port1.origin[0] - wg_sep - wg_sep / 2.0 - electrodes_sep / 2.0,
         ref_port1.origin[1] + MZ_length - elec_offset), np.deg2rad(-90),
        electr_width)
    g_left1 = Waveguide.make_at_port(Inport)
    g_left1.add_straight_segment(Mod_length - cross_width / 2.)
    g_left1._current_port.angle = g_left1.current_port.angle + np.pi / 2.0
    g_left1._current_port.origin[
        0] = g_left1.current_port.origin[0] - g_left1.current_port.width / 2.0
    g_left1._current_port.width = cross_width
    g_left1.add_straight_segment_until_x(x_safe_dist - wg_sep_out)
    g_left1.add_straight_segment(wg_sep, electr_width)
    g_left1.add_straight_segment_until_x(x_safe_dist)

    g_left1._current_port.angle = g_left1.current_port.angle - np.pi / 2.0
    g_left1._current_port.origin[
        1] = g_left1.current_port.origin[1] + g_left1.current_port.width / 2.0
    g_left1.add_straight_segment_until_y(y_start_epads)
    g_left1._current_port.angle = g_left1.current_port.angle - np.pi / 2.0
    g_left1._current_port.origin[
        0] = g_left1.current_port.origin[0] + g_left1.current_port.width / 2.0
    g_left1.add_straight_segment_until_x(x_start_epads + 2 * pads_pitch)

    # g_left1._current_port.angle = g_left1.current_port.angle + np.pi / 2.0
    # g_left1._current_port.origin[0] = g_left1.current_port.origin[0] + pads_width_gnd / 2.0
    # g_left1._current_port.origin[1] = g_left1.current_port.origin[1] + g_left1.current_port.width / 2.0
    # g_left1._current_port.width = pads_width_gnd
    # g_left1.add_straight_segment_until_y(g_left0.current_port.origin[1])

    cell.add_to_layer(electrode_layer, g_left1)

    # #### ELECTRODES FOR SECOND MZI
    # x_safe_dist = x_safe_dist + 3*sep_econns

    ##right ground electrode
    Inport = Port(
        (ref_port2.origin[0] + wg_sep - wg_sep / 2.0 + electrodes_sep / 2.0,
         ref_port2.origin[1] + elec_offset), np.deg2rad(90), electr_width)
    g_right2 = Waveguide.make_at_port(Inport)
    g_right2.add_straight_segment(Mod_length - cross_width / 2. -
                                  2 * sep_econns)
    g_right2._current_port.angle = g_right2.current_port.angle - np.pi / 2.0
    g_right2._current_port.origin[0] = g_right2.current_port.origin[
        0] - g_right2.current_port.width / 2.0
    g_right2._current_port.width = cross_width
    g_right2.add_straight_segment_until_x(x_safe_dist - wg_sep_out)
    g_right2.add_straight_segment(wg_sep, electr_width)
    g_right2.add_straight_segment_until_x(x_safe_dist)

    g_right2.add_straight_segment(3 * sep_econns)
    g_right2._current_port.angle = g_right2.current_port.angle - np.pi / 2.0
    g_right2._current_port.origin[1] = g_right2.current_port.origin[
        1] + g_right2.current_port.width / 2.0
    g_right2.add_straight_segment_until_y(y_start_epads - 2 * sep_econns)
    g_right2._current_port.angle = g_right2.current_port.angle - np.pi / 2.0
    g_right2._current_port.origin[0] = g_right2.current_port.origin[
        0] + g_right2.current_port.width / 2.0
    g_right2.add_straight_segment_until_x(x_start_epads + 4 * pads_pitch)

    # g_right2._current_port.angle = g_right2.current_port.angle + np.pi / 2.0
    # g_right2._current_port.origin[0] = g_right2.current_port.origin[0] #+ pads_width_gnd / 2.0
    # g_right2._current_port.origin[1] = g_right2.current_port.origin[1] + g_right2.current_port.width / 2.0
    # g_right2._current_port.width = pads_width_gnd
    # g_right2.add_straight_segment_until_y(g_left0.current_port.origin[1])

    cell.add_to_layer(electrode_layer, g_right2)

    ## signal electrode
    Inport = Port((ref_port2.origin[0] - wg_sep / 2.0,
                   ref_port2.origin[1] + elec_offset), np.deg2rad(90),
                  electr_width - electrodes_sep)
    s2 = Waveguide.make_at_port(Inport)
    s2.add_straight_segment(Mod_length - cross_width / 2. - sep_econns)
    s2._current_port.angle = s2.current_port.angle - np.pi / 2.0
    s2._current_port.origin[
        0] = s2.current_port.origin[0] - s2.current_port.width / 2.0
    s2._current_port.width = cross_width
    s2.add_straight_segment_until_x(x_safe_dist - wg_sep_out)
    s2.add_straight_segment(wg_sep, electr_width)
    s2.add_straight_segment_until_x(x_safe_dist)

    s2.add_straight_segment(4 * sep_econns)
    s2._current_port.angle = s2.current_port.angle - np.pi / 2.0
    s2._current_port.origin[
        1] = s2.current_port.origin[1] + s2.current_port.width / 2.0
    s2.add_straight_segment_until_y(y_start_epads - 3 * sep_econns)
    s2._current_port.angle = s2.current_port.angle - np.pi / 2.0
    s2._current_port.origin[
        0] = s2.current_port.origin[0] + s2.current_port.width / 2.0
    s2.add_straight_segment_until_x(x_start_epads + 5 * pads_pitch)
    #
    s2._current_port.angle = s2.current_port.angle + np.pi / 2.0
    s2._current_port.origin[0] = s2.current_port.origin[0]  #+ pads_width / 2.0
    s2._current_port.origin[
        1] = s2.current_port.origin[1] + s2.current_port.width / 2.0
    s2._current_port.width = pads_width
    s2.add_straight_segment_until_y(g_left0.current_port.origin[1] + 50)

    cell.add_to_layer(electrode_layer, s2)

    # ##left ground electrode
    Inport = Port(
        (ref_port2.origin[0] - wg_sep - wg_sep / 2.0 - electrodes_sep / 2.0,
         ref_port2.origin[1] + elec_offset), np.deg2rad(90), electr_width)
    g_left2 = Waveguide.make_at_port(Inport)
    g_left2.add_straight_segment(Mod_length - cross_width / 2.)
    g_left2._current_port.angle = g_left2.current_port.angle - np.pi / 2.0
    g_left2._current_port.origin[
        0] = g_left2.current_port.origin[0] - g_left2.current_port.width / 2.0
    g_left2._current_port.width = cross_width
    g_left2.add_straight_segment_until_x(x_safe_dist - wg_sep_out)
    g_left2.add_straight_segment(wg_sep, electr_width)
    g_left2.add_straight_segment_until_x(x_safe_dist)

    g_left2.add_straight_segment(5 * sep_econns)
    g_left2._current_port.angle = g_left2.current_port.angle - np.pi / 2.0
    g_left2._current_port.origin[
        1] = g_left2.current_port.origin[1] + g_left2.current_port.width / 2.0
    g_left2.add_straight_segment_until_y(y_start_epads - 4 * sep_econns)
    g_left2._current_port.angle = g_left2.current_port.angle - np.pi / 2.0
    g_left2._current_port.origin[
        0] = g_left2.current_port.origin[0] + g_left2.current_port.width / 2.0
    # g_left2._current_port.origin[1] = g_left2.current_port.origin[1] + g_left2.current_port.width / 2.0
    g_left2.add_straight_segment_until_x(x_start_epads + 6 * pads_pitch)
    g_left2._current_port.origin[
        1] = g_left2.current_port.origin[1] - g_left2.current_port.width / 2.0

    g_left2._current_port.angle = g_left2.current_port.angle + np.pi / 2.0
    g_left2._current_port.origin[0] = g_left2.current_port.origin[
        0]  #+ 5. #+ pads_width_gnd / 2.0
    g_left2._current_port.origin[
        1] = g_left2.current_port.origin[1] + g_left2.current_port.width
    g_left2._current_port.width = pads_width_gnd
    g_left2.add_straight_segment_until_y(g_left0.current_port.origin[1])
    g_left2._current_port.angle = g_left2.current_port.angle - np.pi / 2.0
    g_left2._current_port.origin[
        0] = g_left2.current_port.origin[0] + g_left2.current_port.width / 2.0
    g_left2._current_port.width = pads_width / 2.
    g_left2._current_port.origin[
        1] = g_left2.current_port.origin[1] - g_left2._current_port.width / 2.
    g_left2.add_straight_segment(2 * pads_pitch + pads_width)

    cell.add_to_layer(electrode_layer, g_left2)

    #
    #
    #
    # ###WRITE FIELDs waveguide
    #
    # outer_corners = [(x_in - 80, y_in + 160), (x_in + 5 * 127 + 60, y_in + 160),
    #                  (x_in + 5 * 127 + 60, y_in + 160 - 1040), (x_in - 80, y_in + 160 - 1040)]
    # polygon1 = Polygon(outer_corners)
    # cell.add_to_layer(wg_wf_layer, polygon1)
    # outer_corners = [(x_in - 80, y_in + 160 - 1040), (x_in + 5 * 127 + 60, y_in + 160 - 1040),
    #                  (x_in + 5 * 127 + 60, y_in + 160 - 1040 - (MZ_length + 2*taper_length + 660 - 1040)),
    #                  (x_in - 80, y_in + 160 - 1040 - ((MZ_length + 2*taper_length + 660 - 1040)))]
    # polygon2 = Polygon(outer_corners)
    # cell.add_to_layer(wg_wf_layer, polygon2)
    # polygon = geometric_union([polygon1, polygon2])
    # cell.add_to_layer(wg_reg_layer, polygon)
    #
    # ###WRITE FIELDs electrodes
    #
    # outer_corners = [(x_in - 210, y_in - 100), (x_in + 5 * 127 + 140, y_in - 100),
    #                  (x_in + 5 * 127 + 140, y_in - 100 - 1040), (x_in - 210, y_in - 100 - 1040)]
    # polygon1 = Polygon(outer_corners)
    # cell.add_to_layer(electrode_wf_layer, polygon1)
    # outer_corners = [(x_in - 210, y_in - 100 - 1040), (x_in + 5 * 127 + 140, y_in - 100 - 1040),
    #                  (x_in + 5 * 127 + 140, y_in - 100 - 1040 - (MZ_length + 2*taper_length + 762 - 1040)),
    #                  (x_in - 210, y_in - 100 - 1040 - (MZ_length + 2*taper_length + 762 - 1040))]
    # polygon2 = Polygon(outer_corners)
    # cell.add_to_layer(electrode_wf_layer, polygon2)
    # polygon = geometric_union([polygon1, polygon2])
    # cell.add_to_layer(electrode_reg_layer, polygon)
    #
    # ####Local markers
    #
    # ### first set on layer 3
    # positions = [(x_in, y_in - 320), (x_in + 5 * 127 - 60, y_in - 320), (x_in + 5 * 127 - 60, y_in - 320 - 450)]
    # marker = [SquareMarker.make_marker(position, 20) for position in positions]
    # cell.add_to_layer(3, geometric_union(marker))
    # marker = [SquareMarker.make_marker(position, 30) for position in positions]
    # cell.add_to_layer(9, geometric_union(marker))
    # marker = [SquareMarker.make_marker(position, 40) for position in positions]
    # cell.add_to_layer(15, geometric_union(marker))
    #
    # ### second set on layer 4
    # positions = [(x_in, y_in - 320 - 150), (x_in + 5 * 127 - 60, y_in - 320 - 150), (x_in + 5 * 127-60, y_in - 320 - 300)]
    # marker = [SquareMarker.make_marker(position, 20) for position in positions]
    # cell.add_to_layer(marker_layer_1, geometric_union(marker))
    # marker = [SquareMarker.make_marker(position, 30) for position in positions]
    # cell.add_to_layer(wg_layer, geometric_union(marker))
    # marker = [SquareMarker.make_marker(position, 40) for position in positions]
    # cell.add_to_layer(marker_protection_layer, geometric_union(marker))

    ###Label
    device_label = Text(origin=(x_in, y_in - 700),
                        height=30,
                        text=label,
                        alignment='center-bottom',
                        angle=np.pi)
    cell.add_to_layer(wg_layer, device_label)

    ###Device Info
    info_text = ('Mod_length = %.1f um\nElectrodes_sep = %.1f nm\nCoupler_length= %.1f um\n') \
                % (Mod_length, electrodes_sep, coupler_length)
    device_info = Text(origin=(x_in, y_in - 850),
                       height=20,
                       text=info_text,
                       alignment='center-bottom',
                       angle=np.pi)
    cell.add_to_layer(comment_layer, device_info)

    return cell
コード例 #27
0
    device_info = Text(origin=(x_in, y_in - 850),
                       height=20,
                       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')
コード例 #28
0
def MZI_active_with_phase(coupler_sep, coupler_length, MZ_length, electrodes_sep, label):
    cell = Cell('MZI_active_withphase'+label)

    x_in = 0
    y_in = 0

    wg_sep = mod_params['wg_sep']

    wg_width_in_mod = wg_Expwidth
    taper_length = l_Exptaper

    ##Generating input and output grating couplers

    coupler_params = std_coupler_params.copy()

    for j in (0, 1):
        incoupler = GratingCoupler.make_traditional_coupler((x_in + j * opt_space, y_in), **coupler_params)
        cell.add_to_layer(wg_layer, incoupler)

    outcouplers = []
    for j in (3, 4):
        outcoupler = GratingCoupler.make_traditional_coupler((x_in + j * opt_space, y_in), **coupler_params)
        outcouplers.append(outcoupler)
        cell.add_to_layer(wg_layer, outcoupler)

    ###Generating waveguides

    inports = [Port((x_in + j * opt_space, y_in), np.deg2rad(90), std_coupler_params['width']) for j in (0, 1)]
    wg = [Waveguide.make_at_port(inport) for inport in inports]

    for j in (0, 1):
        # adding final tapers as suggested by Munster, SP 21/10/21
        wg[j].add_straight_segment(grating_added_taper_len, final_width=wg_width)
        # wg[j].add_straight_segment(bend_r-grating_added_taper_len)

        wg[j].add_bend(-np.pi / 2.0, bend_r + (1 - j) * wg_sep)
        wg[j].add_straight_segment((1 - j) * (opt_space - wg_sep))
        wg[j].add_bend(-np.pi / 2.0, bend_r + (1 - j) * wg_sep)

        wg[j].add_straight_segment(bend_r)

        ##directional coupler with sinusoidal s-bend
        x_length = 60
        y_length = wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - j * (wg_sep - wg_width - coupler_sep)
        wg[j].add_parameterized_path(path=lambda t: (t * x_length, .5 * (np.cos(np.pi * t) - 1) * y_length),
                                     path_derivative=lambda t: (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))
        wg[j].add_straight_segment(coupler_length)
        y_length = -(wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - j * (wg_sep  - wg_width - coupler_sep))
        wg[j].add_parameterized_path(path=lambda t: (t * x_length, .5 * (np.cos(np.pi * t) - 1) * y_length),
                                     path_derivative=lambda t: (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))

        #add taper to multimode wg
        wg[j].add_straight_segment(taper_length, final_width=wg_width_in_mod)

        ###reference port for electrodes in MZI
        ref_port = wg[j].current_port

        ###reference port for electrodes in PHASE
        ref_port_ph = wg[j].current_port

        ###straight section
        wg[j].add_straight_segment(MZ_length)

        #add taper to single-mode wg
        wg[j].add_straight_segment(taper_length, final_width=wg_width)

        ##directional coupler with sinusoidal s-bend
        x_length = 60
        y_length = wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - j * (wg_sep  - wg_width - coupler_sep)
        wg[j].add_parameterized_path(path=lambda t: (t * x_length, .5 * (np.cos(np.pi * t) - 1) * y_length),
                                     path_derivative=lambda t: (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))
        wg[j].add_straight_segment(coupler_length)
        y_length = -(wg_sep / 2.0 - (coupler_sep + wg_width) / 2.0 - j * (wg_sep  - wg_width - coupler_sep))
        wg[j].add_parameterized_path(path=lambda t: (t * x_length, .5 * (np.cos(np.pi * t) - 1) * y_length),
                                     path_derivative=lambda t: (x_length, -np.pi * .5 * np.sin(np.pi * t) * y_length))



        x_dist_inout=2*mod_params['electrode_width'] + 15
        wg[j].add_straight_segment(10)
        wg[j].add_bend(np.pi/2., bend_r + j * wg_sep)
        wg[j].add_straight_segment(x_dist_inout+wg_sep)
        wg[j].add_bend(np.pi, bend_r + j * wg_sep)
        wg[j].add_bend(-np.pi / 2., bend_r + (1-j) * wg_sep)
        wg[j].add_straight_segment_until_y(inports[0].y - 3*bend_r)
        wg[j].add_bend(-np.pi / 2., bend_r + (1 - j) * wg_sep)
        wg[j].add_straight_segment_until_x(outcouplers[-1].origin[0]+bend_r)
        wg[j].add_bend(np.pi / 2., bend_r + j * wg_sep)

        wg[j].add_straight_segment_until_y(inports[0].y)
        wg[j].add_straight_segment(grating_added_taper_len)
        wg[j].add_bend(np.pi / 2., bend_r + j* wg_sep)
        wg[j].add_straight_segment_until_x(outcouplers[1-j].origin[0]+(bend_r + j * wg_sep))
        wg[j].add_bend(np.pi / 2., bend_r + j*wg_sep)
        # # adding final tapers as suggested by Munster, SP 21/10/21
        wg[j].add_straight_segment(grating_added_taper_len, final_width=std_coupler_params['width'])

    for j in (0, 1):
        cell.add_to_layer(wg_layer, wg[j])

    ##MODULATOR ELECTRODES


    #### ELECTRODES IN MZI

    electr_width = mod_params['electrode_width']
    sep_econns = mod_params['electrode_sep_y']
    cross_width = mod_params['crossing_width']
    pads_pitch = mod_params['connector_probe_pitch']
    pads_width = mod_params['connector_probe_dims'][0]
    pads_width_gnd = mod_params['connector_probe_dims_gnd'][0]
    pads_len = mod_params['connector_probe_dims'][1]
    min_safedist_from_wg = 22
    x_safe_dist = ref_port.origin[0] - min_safedist_from_wg - pads_width

    ##left ground electrode
    Inport = Port((ref_port.origin[0] - electrodes_sep / 2.0 - wg_sep / 2.0, ref_port.origin[1]), np.deg2rad(-90), electr_width)
    g_left = Waveguide.make_at_port(Inport)
    g_left.add_straight_segment(MZ_length - cross_width/2. - 2 * sep_econns)
    g_left._current_port.angle = g_left.current_port.angle - np.pi / 2.0
    g_left._current_port.origin[0] = g_left.current_port.origin[0] + g_left.current_port.width / 2.0
    g_left.add_straight_segment_until_x(x_safe_dist)
    g_left.add_straight_segment(2 * pads_pitch + (pads_width-pads_width_gnd/2.))
    g_left._current_port.angle = g_left.current_port.angle + np.pi / 2.0
    g_left._current_port.origin[0] = g_left.current_port.origin[0] + pads_width_gnd / 2.0
    g_left._current_port.width = pads_width_gnd

    g_left.add_straight_segment(pads_len)
    cell.add_to_layer(electrode_layer, g_left)

    ## signal electrode
    Inport = Port((ref_port.origin[0] + wg_sep / 2.0, ref_port.origin[1]), np.deg2rad(-90), electr_width - electrodes_sep)
    s = Waveguide.make_at_port(Inport)
    s.add_straight_segment(MZ_length - cross_width/2. - sep_econns)
    s._current_port.angle = s.current_port.angle - np.pi / 2.0
    s._current_port.origin[0] = s.current_port.origin[0] + s.current_port.width / 2.0
    s._current_port.width = cross_width
    s.add_straight_segment(wg_sep+5)
    s.add_straight_segment(wg_sep, electr_width)
    s.add_straight_segment_until_x(x_safe_dist)
    s.add_straight_segment(pads_pitch+ (pads_width-pads_width_gnd/2.))
    s._current_port.angle = s.current_port.angle + np.pi / 2.0
    s._current_port.origin[0] = s.current_port.origin[0] + pads_width / 2.0
    s._current_port.width = pads_width

    s.add_straight_segment_until_y(g_left.current_port.origin[1] + 50)
    cell.add_to_layer(electrode_layer, s)

    ##right ground electrode
    Inport = Port((ref_port.origin[0] + wg_sep + wg_sep / 2.0 + electrodes_sep / 2.0, ref_port.origin[1]), np.deg2rad(-90), electr_width)
    g_right = Waveguide.make_at_port(Inport)
    g_right.add_straight_segment(MZ_length - cross_width/2.)
    g_right._current_port.angle = g_right.current_port.angle - np.pi / 2.0
    g_right._current_port.origin[0] = g_right.current_port.origin[0] + g_right.current_port.width / 2.0
    g_right._current_port.width = cross_width
    g_right.add_straight_segment(2*wg_sep+5)
    g_right.add_straight_segment(wg_sep, electr_width)
    g_right.add_straight_segment_until_x(x_safe_dist)
    g_right.add_straight_segment(pads_width_gnd/2.)
    g_right._current_port.angle = g_right.current_port.angle + np.pi / 2.0
    g_right._current_port.origin[0] = g_right.current_port.origin[0] + pads_width_gnd / 2.0
    g_right._current_port.width = pads_width_gnd
    g_right.add_straight_segment_until_y(g_left.current_port.origin[1])
    g_right._current_port.angle = g_right.current_port.angle - np.pi / 2.0
    g_right._current_port.origin[0] = g_right.current_port.origin[0] + g_right.current_port.width / 2.0
    g_right._current_port.width = pads_width / 2.
    g_right._current_port.origin[1] = g_right.current_port.origin[1] - g_right._current_port.width / 2.
    g_right.add_straight_segment(2 * pads_pitch + pads_width)

    cell.add_to_layer(electrode_layer, g_right)



    #### ELECTRODES FOR PHASE
    ref_port_ph = deepcopy(ref_port)
    ref_port_ph.origin[0] = ref_port.origin[0] + 2*wg_sep + x_dist_inout
    x_safe_dist_ph = ref_port_ph.origin[0] + min_safedist_from_wg + pads_width
    x_startpos_pads_ph = s._current_port.origin[0] + 4*pads_pitch + (pads_width_gnd - pads_width)/2. + (pads_width-pads_width_gnd/2.)
    y_startpos_pads_ph = s._current_port.origin[1] +280

    ##right ground electrode
    Inport = Port((ref_port_ph.origin[0] + electrodes_sep / 2.0 + wg_sep / 2.0, ref_port.origin[1]), np.deg2rad(-90), electr_width)
    g_right_ph = Waveguide.make_at_port(Inport)
    g_right_ph.add_straight_segment(MZ_length - cross_width/2. - 2 * sep_econns)
    g_right_ph._current_port.angle = g_right_ph.current_port.angle + np.pi / 2.0
    g_right_ph._current_port.origin[0] = g_right_ph.current_port.origin[0] - g_right_ph.current_port.width / 2.0
    g_right_ph.add_straight_segment_until_x(x_startpos_pads_ph)
    g_right_ph._current_port.angle = g_right_ph.current_port.angle - np.pi / 2.0
    g_right_ph._current_port.origin[0] = g_right_ph.current_port.origin[0] - g_right_ph.current_port.width / 2.0
    g_right_ph.add_straight_segment_until_y(y_startpos_pads_ph-2*sep_econns+ g_right_ph.current_port.width)
    g_right_ph._current_port.origin[0] = g_right_ph._current_port.origin[0] - (pads_width_gnd- g_right_ph.current_port.width) / 2.0
    g_right_ph._current_port.width = pads_width_gnd
    g_right_ph.add_straight_segment_until_y(g_left._current_port.origin[1])

    cell.add_to_layer(electrode_layer, g_right_ph)

    ## signal electrode
    Inport = Port((ref_port_ph.origin[0] - wg_sep / 2.0, ref_port_ph.origin[1]), np.deg2rad(-90), electr_width - electrodes_sep)
    s_ph = Waveguide.make_at_port(Inport)
    s_ph.add_straight_segment(MZ_length - cross_width/2. - sep_econns)
    s_ph._current_port.angle = s.current_port.angle + np.pi / 2.0
    s_ph._current_port.origin[0] = s_ph.current_port.origin[0] - s_ph.current_port.width / 2.0
    s_ph._current_port.width = cross_width
    s_ph.add_straight_segment(wg_sep+5)
    s_ph.add_straight_segment(wg_sep, electr_width)
    s_ph.add_straight_segment_until_x(x_startpos_pads_ph - sep_econns)
    s_ph._current_port.angle = s_ph.current_port.angle - np.pi / 2.0
    s_ph._current_port.origin[0] = s_ph.current_port.origin[0] - s_ph.current_port.width / 2.0
    s_ph.add_straight_segment_until_y(y_startpos_pads_ph-sep_econns)
    s_ph._current_port.angle = s_ph.current_port.angle - np.pi / 2.0
    s_ph._current_port.origin[1] = s_ph.current_port.origin[1] + s_ph.current_port.width / 2.0

    s_ph.add_straight_segment_until_x(s.current_port.origin[0] + 3*pads_pitch-pads_width / 2.0)
    s_ph._current_port.angle = s_ph.current_port.angle + np.pi / 2.0
    s_ph._current_port.origin[0] = s_ph.current_port.origin[0] + pads_width / 2.0
    s_ph._current_port.width = pads_width
    s_ph.add_straight_segment_until_y(s.current_port.origin[1])
    cell.add_to_layer(electrode_layer, s_ph)

    ##left ground electrode
    Inport = Port((ref_port_ph.origin[0] - wg_sep - wg_sep / 2.0 - electrodes_sep / 2.0, ref_port_ph.origin[1]), np.deg2rad(-90), electr_width)
    g_left_ph = Waveguide.make_at_port(Inport)
    g_left_ph.add_straight_segment(MZ_length - cross_width/2.)
    g_left_ph._current_port.angle = g_left_ph.current_port.angle + np.pi / 2.0
    g_left_ph._current_port.origin[0] = g_left_ph.current_port.origin[0] - g_left_ph.current_port.width / 2.0
    g_left_ph._current_port.width = cross_width
    g_left_ph.add_straight_segment(2*wg_sep+5)
    g_left_ph.add_straight_segment(wg_sep, electr_width)
    g_left_ph.add_straight_segment_until_x(x_startpos_pads_ph - 2*sep_econns)
    g_left_ph._current_port.angle = g_left_ph.current_port.angle - np.pi / 2.0
    g_left_ph._current_port.origin[0] = g_left_ph.current_port.origin[0] - g_left_ph.current_port.width / 2.0
    g_left_ph.add_straight_segment_until_y(y_startpos_pads_ph)

    g_left_ph._current_port.angle = g_left_ph.current_port.angle - np.pi / 2.0
    g_left_ph._current_port.origin[1] = g_left_ph.current_port.origin[1] + g_left_ph.current_port.width / 2.0
    g_left_ph.add_straight_segment_until_x(s.current_port.origin[0] + 2*pads_pitch - pads_width / 2.0)
    g_left_ph._current_port.angle = g_left_ph.current_port.angle + np.pi / 2.0
    g_left_ph._current_port.origin[0] = g_left_ph.current_port.origin[0] + pads_width_gnd / 2.0
    g_left_ph._current_port.width = pads_width_gnd
    g_left_ph.add_straight_segment_until_y(g_right_ph.current_port.origin[1])

    g_left_ph._current_port.angle = g_left_ph.current_port.angle + np.pi / 2.0
    g_left_ph._current_port.origin[0] = g_left_ph.current_port.origin[0] - g_left_ph.current_port.width / 2.0
    g_left_ph._current_port.width = pads_width / 2.
    g_left_ph._current_port.origin[1] = g_left_ph.current_port.origin[1] - g_left_ph._current_port.width / 2.
    g_left_ph.add_straight_segment(2 * pads_pitch + pads_width)

    cell.add_to_layer(electrode_layer, g_left_ph)



    ###WRITE FIELDs waveguide

    outer_corners = [(x_in - 80, y_in + 160), (x_in + 5 * 127 + 60, y_in + 160),
                     (x_in + 5 * 127 + 60, y_in + 160 - 1040), (x_in - 80, y_in + 160 - 1040)]
    polygon1 = Polygon(outer_corners)
    cell.add_to_layer(wg_wf_layer, polygon1)
    outer_corners = [(x_in - 80, y_in + 160 - 1040), (x_in + 5 * 127 + 60, y_in + 160 - 1040),
                     (x_in + 5 * 127 + 60, y_in + 160 - 1040 - (MZ_length + 2*taper_length + 660 - 1040)),
                     (x_in - 80, y_in + 160 - 1040 - ((MZ_length + 2*taper_length + 660 - 1040)))]
    polygon2 = Polygon(outer_corners)
    cell.add_to_layer(wg_wf_layer, polygon2)
    polygon = geometric_union([polygon1, polygon2])
    cell.add_to_layer(wg_reg_layer, polygon)

    ###WRITE FIELDs electrodes

    outer_corners = [(x_in - 210, y_in - 100), (x_in + 5 * 127 + 140, y_in - 100),
                     (x_in + 5 * 127 + 140, y_in - 100 - 1040), (x_in - 210, y_in - 100 - 1040)]
    polygon1 = Polygon(outer_corners)
    cell.add_to_layer(electrode_wf_layer, polygon1)
    outer_corners = [(x_in - 210, y_in - 100 - 1040), (x_in + 5 * 127 + 140, y_in - 100 - 1040),
                     (x_in + 5 * 127 + 140, y_in - 100 - 1040 - (MZ_length + 2*taper_length + 762 - 1040)),
                     (x_in - 210, y_in - 100 - 1040 - (MZ_length + 2*taper_length + 762 - 1040))]
    polygon2 = Polygon(outer_corners)
    cell.add_to_layer(electrode_wf_layer, polygon2)
    polygon = geometric_union([polygon1, polygon2])
    cell.add_to_layer(electrode_reg_layer, polygon)

    ####Local markers

    ### first set on layer 3
    positions = [(x_in, y_in - 320), (x_in + 5 * 127 - 60, y_in - 320), (x_in + 5 * 127 - 60, y_in - 320 - 450)]
    marker = [SquareMarker.make_marker(position, 20) for position in positions]
    cell.add_to_layer(3, geometric_union(marker))
    marker = [SquareMarker.make_marker(position, 30) for position in positions]
    cell.add_to_layer(9, geometric_union(marker))
    marker = [SquareMarker.make_marker(position, 40) for position in positions]
    cell.add_to_layer(15, geometric_union(marker))

    ### second set on layer 4
    positions = [(x_in, y_in - 320 - 150), (x_in + 5 * 127 - 60, y_in - 320 - 150), (x_in + 5 * 127-60, y_in - 320 - 300)]
    marker = [SquareMarker.make_marker(position, 20) for position in positions]
    cell.add_to_layer(marker_layer_1, geometric_union(marker))
    marker = [SquareMarker.make_marker(position, 30) for position in positions]
    cell.add_to_layer(wg_layer, geometric_union(marker))
    marker = [SquareMarker.make_marker(position, 40) for position in positions]
    cell.add_to_layer(marker_protection_layer, geometric_union(marker))

    ###Label
    device_label = Text(origin=(x_in, y_in - 700), height=30,
                        text=label, alignment='center-bottom', angle=np.pi)
    cell.add_to_layer(wg_layer, device_label)

    ###Device Info
    info_text = ('MZ_length = %.1f um\nElectrodes_sep = %.1f nm\nCoupler_length= %.1f um\n') \
                % (MZ_length, electrodes_sep, coupler_length)
    device_info = Text(origin=(x_in, y_in - 850), height=20, text=info_text, alignment='center-bottom' , angle=np.pi)
    cell.add_to_layer(comment_layer, device_info)

    return cell
コード例 #29
0
ファイル: ntron.py プロジェクト: philomathie/gdshelpers
        x_off = self.origin[0] + np.cos(self._angle) * x - np.sin(
            self._angle) * y
        y_off = self.origin[1] + np.sin(self._angle) * x + np.cos(
            self._angle) * y

        return Port((x_off, y_off), self._angle - np.pi / 2,
                    self._outer_channel_width)


if __name__ == '__main__':
    from gdshelpers.geometry.chip import Cell

    part1 = Ntron(origin=(5, -5),
                  angle=0,
                  gate_width_1=0.3,
                  gate_width_2=0.06,
                  choke_width_1=0.06,
                  choke_width_2=0.015,
                  choke_length_2=0.06,
                  choke_length_3=0.03)
    wgdrain = Waveguide.make_at_port(part1.port_drain)
    wgdrain.add_straight_segment(0.5)
    wggate = Waveguide.make_at_port(part1.port_gate)
    wggate.add_straight_segment(0.5)
    wgsource = Waveguide.make_at_port(part1.port_source)
    wgsource.add_straight_segment(0.5)
    cell = Cell('_channel')
    cell.add_to_layer(1, part1)
    cell.show()
コード例 #30
0
    info_text = ('MZ_length = %.1f um\nElectrodes_sep = %.1f nm\nCoupler_length= %.1f um\n') \
                % (MZ_length, electrodes_sep, coupler_length)
    device_info = Text(origin=(x_in, y_in - 850), height=20, 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('Modulators_Tests')


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

    coupler_sep = 0.4
    coupler_length = 22
    electrodes_sep = 1.1

    for j, MZ_length in enumerate(np.linspace(500, 1250, 4)):
        temp_cell = MZI_active_with_phase(coupler_sep, coupler_length, MZ_length, electrodes_sep, 'D%i' % j)
        temp_cell.name = 'MZI_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 * 1000, -1500))