예제 #1
0
def fang(wg_width, length, orientation):
    F = Device()
    w1 = wg_width
    X1 = CrossSection()
    X1.add(width=w1, offset=0, layer=30, ports=('in', 'out'))

    P = Path()
    P.append(pp.euler(radius=50,
                      angle=45))  # Euler bend (aka "racetrack" curve)
    fang = P.extrude(X1)
    fang = F.add_ref(fang)

    D = pg.taper(length=length,
                 width1=w1,
                 width2=0.000001,
                 port=None,
                 layer=30)
    taper = F.add_ref(D)
    taper.connect(port=1, destination=fang.ports['out'])

    #Defualt is RU, right up
    if orientation == 'RD':
        F.mirror(p1=[0, 0], p2=[1, 0])
    elif orientation == 'LU':
        F.mirror(p1=[0, 0], p2=[0, 1])
    elif orientation == 'LD':
        F.rotate(180, center=[0, 0])

    return F
예제 #2
0
def makeLineSpace(x0,y0,width, height,pitch,ymax, layer):
	#---------------------------------------------#
	# Creates a line space pattern in y-direction
	#	x0: x coordinate of the lower left line
	#	y0: y coordinate of the lower left line
	#	width: width of each line
	#	height: height of each line
	#	pitch: pitch of each line
	#	pitch > height
	#---------------------------------------------#
	if abs(pitch) < abs(height):
		print("pitch must be greater then height")
		return 
	LS = Device('linespace')
	if pitch > 0:
		while y0+height <= ymax:
			Li = makeLine(x0,y0,width,height,layer)
			LS.add_ref(Li)
			y0 += pitch
	elif pitch < 0:
		while y0+height >= -ymax:
                        Li = makeLine(x0,y0,width,height,layer)
                        LS.add_ref(Li)
                        y0 += pitch
	return y0, LS
예제 #3
0
def test_align():
    D = Device()
    # Create different-sized rectangles and add them to D then distribute them
    [
        D.add_ref(
            pg.rectangle(size=[n * 15 + 20, n * 15 + 20]).move((n, n * 4)))
        for n in [0, 2, 3, 1, 2]
    ]
    D.distribute(elements='all', direction='x', spacing=5, separation=True)
    # Align top edges
    D.align(elements='all', alignment='ymax')
    h = D.hash_geometry(precision=1e-4)
    assert (h == '38025959a80e46e47eabcf3f096c6273427dabc3')

    D = Device()
    # Create different-sized rectangles and add them to D then distribute them
    [
        D.add_ref(
            pg.rectangle(size=[n * 15 + 20, n * 15 + 20]).move((n, n * 4)))
        for n in [0, 2, 3, 1, 2]
    ]
    D.distribute(elements='all', direction='x', spacing=5, separation=True)
    # Align top edges
    D.align(elements='all', alignment='y')
    h = D.hash_geometry(precision=1e-4)
    assert (h == 'ed32ee1ce1f3da8f6216020877d6c1b64097c600')
예제 #4
0
def test_distribute():
    D = Device()
    # Create different-sized rectangles and add them to D
    [
        D.add_ref(
            pg.rectangle(size=[n * 15 + 20, n * 15 + 20]).move((n, n * 4)))
        for n in [0, 2, 3, 1, 2]
    ]
    # Distribute all the rectangles in D along the x-direction with a separation of 5
    D.distribute(
        elements='all',  # either 'all' or a list of objects
        direction='x',  # 'x' or 'y'
        spacing=5,
        separation=True)

    h = D.hash_geometry(precision=1e-4)
    assert (h == '1aa688d7dfb59e94d28dd0d9b8f324ff30281d70')

    D = Device()
    [
        D.add_ref(
            pg.rectangle(size=[n * 15 + 20, n * 15 + 20]).move((n, n * 4)))
        for n in [0, 2, 3, 1, 2]
    ]
    D.distribute(elements='all',
                 direction='x',
                 spacing=100,
                 separation=False,
                 edge='xmin')
    h = D.hash_geometry(precision=1e-4)
    assert (h == '18be0ef1db78095233d2f3ae5f065d9f453a6c07')
예제 #5
0
def mmi1x2(wg_width=0.35,
           length_port=0.2,
           length_mmi=2.8,
           width_mmi=1.55,
           gap_mmi=0.4):

    D = Device()

    Port_wg = pg.taper(length=length_port,
                       width1=wg_width,
                       width2=wg_width,
                       layer=lys['wg_deep'])
    port_in = D.add_ref(Port_wg)
    MMI = pg.taper(length=length_mmi,
                   width1=width_mmi,
                   width2=width_mmi,
                   layer=lys['wg_deep'])
    mmi = D.add_ref(MMI)

    mmi.connect(port=1, destination=port_in.ports[2])

    port_up = D.add_ref(Port_wg)
    port_up.connect(port=1, destination=mmi.ports[2])
    port_up.movey(gap_mmi)

    port_down = D.add_ref(Port_wg)
    port_down.connect(port=1, destination=mmi.ports[2])
    port_down.movey(-gap_mmi)

    D.add_port(name=1, port=port_in.ports[1])
    D.add_port(name=2, port=port_up.ports[2])
    D.add_port(name=3, port=port_down.ports[2])

    return D
예제 #6
0
def wb_pad(x, y, pad, name):
    R = pg.rectangle(size=(pad, pad - 0.5), layer=70)

    D = Device()
    rect1 = D << R
    rect1.move([x, y])

    text_size = 20
    L = pg.text(text=name, size=text_size, layer=97, justify='center')
    D.add_ref(L).move((x + pad / 3, y))

    return D
예제 #7
0
def htron(nanowire_width = 0.15, nanowire_spacing = 0.1,
          meander_num_squares = 5000, heater_num_squares = 1):

    # Create blank device
    D = Device(name = 'htron')

    # Basic calculations
    extra_meander_width = 2
    extra_meander_height = 1
    area_per_meander_sq = (nanowire_width+nanowire_spacing)*nanowire_width
    meander_area = area_per_meander_sq*meander_num_squares
    meander_total_width = np.sqrt(meander_area/heater_num_squares)
    meander_total_height = heater_num_squares*meander_total_width
    meander_size = np.array([meander_total_width, meander_total_height])
    heater_size = meander_size

    meander_size = meander_size + [extra_meander_width,extra_meander_height]

    # meander_size = heater_size + np.array([meander_extra_width,0])
    meander_pitch = nanowire_width + nanowire_spacing
    # heater_standoff_y = 1

    # Create components
    Meander = pg.snspd_expanded(wire_width = nanowire_width, wire_pitch = meander_pitch, size = meander_size,
               terminals_same_side = False, connector_width = nanowire_width*4, layer = lys['m2_nw'])
    # heater_size_actual = heater_size + np.array([0, heater_standoff_y])
    Heater = pg.compass(size = heater_size, layer = lys['m3_res'])

    # Add references to components
    m = D.add_ref(Meander)
    h = D.add_ref(Heater)
    h.center = m.center


    # Record meta-information
    heater_area = heater_size[0]*heater_size[1]
    D.info['nanowire_width'] = nanowire_width
    D.info['nanowire_pitch'] = nanowire_width + nanowire_spacing
    D.info['meander_num_squares'] = np.round(m.info['num_squares'],2)
    D.info['meander_size'] = np.round((m.xsize, m.ysize),2).tolist()
    D.info['heater_size'] = np.round(heater_size,2).tolist()
    D.info['heater_area'] = np.round(heater_size[0]*heater_size[1],2)
    D.info['heater_num_squares'] = np.round(heater_num_squares,2)
    D.info['overlap_area'] = np.round(m.ysize*heater_size[0],1)
    D.info['overlap_num_squares'] = np.round(heater_area/area_per_meander_sq,1)

    D.add_port(name = 1, port = h.ports['N'])
    D.add_port(name = 2, port = h.ports['S'])
    D.add_port(name = 3, port = m.ports[1])
    D.add_port(name = 4, port = m.ports[2])

    return D
예제 #8
0
def main():

	#---- Example of using the templates---#
	D = Device()


	# Make a golden spiral with 1000 grids
	F = fibonacci(1000)
	D.add_ref(F)
	D.write_gds("spiral.gds")

	# Make a ring resonator
	D2 = Device()
	C = makeResonator()
	D2.add_ref(C)
	D2.write_gds("resonator.gds")
예제 #9
0
def poling_region(length=4000,
                  period=5,
                  dutycycle=0.4,
                  gap=25,
                  Lfinger=50,
                  layer=10,
                  pad_width=50):

    #Calculations
    Wfinger = period * dutycycle
    Nfinger = int(length / period) + 1
    length = Nfinger * period - (1 - dutycycle) * period

    P = Device('Poling Electrodes')

    #Positive side
    R = pg.rectangle([length, pad_width], layer=layer)
    F = pg.rectangle([Wfinger, Lfinger], layer=layer)
    P << R
    a = P.add_array(F, columns=Nfinger, rows=1, spacing=(period, 0))
    a.move([0, pad_width])

    #Negative side
    R2 = pg.rectangle([length, pad_width], layer=layer)
    r2 = P.add_ref(R2)
    r2.move([0, pad_width + Lfinger + gap])

    return P
예제 #10
0
def test_port_reference_manipulate():
    D = Device()
    D.add_port(name='test123', midpoint=(5.7, 9.2), orientation=37)
    d = D.add_ref(D).move([1, 1]).rotate(45)
    assert (np.allclose(d.ports['test123'].midpoint,
                        (-2.474873734152916, 11.950104602052654)))
    assert (d.ports['test123'].orientation == 37 + 45)
예제 #11
0
def test_write_and_import_gds():
    D = Device()
    D.add_ref(pg.rectangle(size=[1.5, 2.7], layer=[3, 2]))
    D.add_ref(pg.rectangle(size=[0.8, 2.5], layer=[9, 7]))
    D.add_array(pg.rectangle(size=[1, 2], layer=[4, 66]),
                rows=3,
                columns=2,
                spacing=[14, 7.5])
    D.add_array(pg.rectangle(size=[1.5, 2.5], layer=[4, 67]),
                rows=1,
                columns=2,
                spacing=[14, 7.5])
    D.add_polygon([[3, 4, 5], [6.7, 8.9, 10.15]], layer=[7, 8])
    D.add_polygon([[3, 4, 5], [1.7, 8.9, 10.15]], layer=[7, 9])
    precision = 1e-4
    unit = 1e-6
    h1 = D.hash_geometry(precision=precision)
    D.write_gds('temp.gds', precision=unit * precision, unit=1e-6)
    Dimport = pg.import_gds('temp.gds', flatten=False)
    h2 = Dimport.hash_geometry(precision=precision)
    assert (h1 == h2)
예제 #12
0
def triplet_pad(x, y, pad, pad_g, elec_m, elec, elec_s, e_e_gap, pos):
    R = pg.rectangle(size=(pad, pad), layer=70)

    D = Device()
    rect1 = D << R
    rect2 = D << R
    rect3 = D << R
    rect1.move([x, y])
    rect2.move([x - pad_g, y])
    rect3.move([x + pad_g, y])

    #middle connector pad
    xm1 = x - elec_m / 2
    xm2 = x - pad / 2
    xm3 = x + pad / 2
    xm4 = x + elec_m / 2
    xpts = (xm1 + pad / 2, xm2 + pad / 2, xm3 + pad / 2, xm4 + pad / 2)
    ypts = (y + pad + elec, y + elec, y + elec, y + pad + elec)
    if pos == 'u':
        ypts = (y - elec, y, y, y - elec)
    D.add_polygon([xpts, ypts], layer=70)

    text_size = 20
    L = pg.text(text='S', size=text_size, layer=97, justify='center')
    D.add_ref(L).move((x + pad / 3, y))

    #left connector pad
    xm1 = x - elec_m / 2 - e_e_gap - elec_s
    xm2 = x - pad / 2 - pad_g
    xm3 = x + pad / 2 - pad_g
    xm4 = x - elec_m / 2 - e_e_gap
    xpts = (xm1 + pad / 2, xm2 + pad / 2, xm3 + pad / 2, xm4 + pad / 2)
    ypts = (y + pad + elec, y + elec, y + elec, y + pad + elec)
    if pos == 'u':
        ypts = (y - elec, y, y, y - elec)
    D.add_polygon([xpts, ypts], layer=70)

    L = pg.text(text='G', size=text_size, layer=97, justify='center')
    D.add_ref(L).move((x - pad_g + +pad / 3, y))

    #left connector pad
    xm1 = x + elec_m / 2 + e_e_gap
    xm2 = x + pad / 2 + pad_g - pad
    xm3 = x + pad / 2 + pad_g
    xm4 = x + elec_m / 2 + e_e_gap + elec_s
    xpts = (xm1 + pad / 2, xm2 + pad / 2, xm3 + pad / 2, xm4 + pad / 2)
    ypts = (y + pad + elec, y + elec, y + elec, y + pad + elec)
    if pos == 'u':
        ypts = (y - elec, y, y, y - elec)
    D.add_polygon([xpts, ypts], layer=70)

    L = pg.text(text='G', size=text_size, layer=97, justify='center')
    D.add_ref(L).move((x + pad_g + +pad / 3, y))

    return D
예제 #13
0
def mzi(length, radius, angle, wg_width, Y_mmi):
    P1 = Path()
    P1.append(pp.euler(radius=radius, angle=-angle))
    P1.append(pp.euler(radius=radius, angle=angle))
    P1.append(pp.straight(length=length))
    P1.append(pp.euler(radius=radius, angle=angle))
    P1.append(pp.euler(radius=radius, angle=-angle))

    X = CrossSection()
    X.add(width=wg_width, offset=0, layer=30)
    waveguide_device1 = P1.extrude(X)

    E = Device('EOM_GHz')
    b1 = E.add_ref(waveguide_device1).move([0, -Y_mmi / 2])
    b2 = E.add_ref(waveguide_device1).move([0, -Y_mmi / 2])
    b2.mirror((0, 0), (1, 0))
    return E
예제 #14
0
def bonding_pads(margin, pad, chip_width, chip_height):
    num = 18
    sep = (chip_width - 2 * margin) / num
    P = pg.rectangle(size=(pad, pad), layer=3).move([margin, margin])
    P << pg.rectangle(size=(pad, pad), layer=3).move(
        [margin, chip_height - margin - pad])
    for i in range(1, int(num / 2)):
        P << pg.rectangle(size=(pad, pad), layer=3).move(
            [margin + i * sep, margin])
        P << pg.rectangle(size=(pad, pad), layer=3).move(
            [margin + i * sep, chip_height - margin - pad])

    E = Device('bonding_pads')
    b1 = E.add_ref(P)
    b2 = E.add_ref(P)
    b2.mirror((chip_width / 2, chip_height), (chip_width / 2, 0))

    return E, sep
예제 #15
0
def dcimthin(wg_width, off_chip, W, L_tp, W_tp, L_mmi, W_mmi, Y_mmi, length,
             radius, x_pos, y_pos, middle_e_width, e_e_gap):

    if e_e_gap == 9:
        angle = 12.5196846104787
    elif e_e_gap == 7:
        angle = 11.83919343835311
    elif e_e_gap == 11:
        angle = 13.165741242693

    # Parameters
    mmi_length = L_tp * 2 + L_mmi
    side_electrode_width = middle_e_width * 2

    eulerX = mod_euler(radius=radius, angle=angle)[1][0]
    racetrack_length = eulerX * 4 + length
    #mzi_length = racetrack_length + mmi_length*2
    side = x_pos
    #side = (chip_width - mzi_length)/2

    # Devices
    M = mzi(length, radius, angle, wg_width, Y_mmi)

    mmiL = mmi(W, L_tp, W_tp, L_mmi, W_mmi, Y_mmi)
    mmiR = mmi(W, L_tp, W_tp, L_mmi, W_mmi, Y_mmi)
    mmiR.mirror().move([mmi_length, 0])

    E = Device('EOM')
    #E << pg.rectangle(size=(side+off_chip,wg_width), layer=1).move([-off_chip,y_pos-wg_width/2])
    E << mmiL.move([side, y_pos])
    E << M.move([side + mmi_length, y_pos])
    E << mmiR.move([side + mmi_length + racetrack_length, y_pos])
    #E << pg.rectangle(size=(side+off_chip,wg_width), layer=1).move([side+mzi_length,y_pos-wg_width/2])

    e_left = side + mmi_length + 2 * eulerX

    #side_e_width
    R = pg.rectangle(size=(length, middle_e_width), layer=40)
    R2 = pg.rectangle(size=(length, side_electrode_width), layer=40)

    #top electrode
    h_top = middle_e_width / 2 + e_e_gap + y_pos
    E.add_ref(R2).move([e_left, h_top])

    #middle electrode
    E.add_ref(R).move([e_left, y_pos - middle_e_width / 2])

    #bottom electrode
    h_bot = -middle_e_width / 2 - side_electrode_width - e_e_gap + y_pos
    E.add_ref(R2).move([e_left, h_bot])
    return E, e_left
예제 #16
0
def test_bbox():
    D = Device()
    D.add_polygon([(0, 0), (10, 0), (10, 10), (0, 10)], layer=2)
    assert (D._bb_valid == False)
    # Calculating the bbox should change _bb_valid to True once it's cached
    assert (D.bbox.tolist() == [[0, 0], [10, 10]])
    assert (D._bb_valid == True)

    E = Device()
    e1 = E.add_ref(D)
    e2 = E.add_ref(D)
    e2.movex(30)
    assert (E._bb_valid == False)
    assert (E.bbox.tolist() == [[0, 0], [40, 10]])
    assert (E._bb_valid == True)

    D.add_polygon([(0, 0), (100, 0), (100, 100), (0, 100)], layer=2)
    D.add_polygon([(0, 0), (100, 0), (100, 100), (0, 100)], layer=2)
    assert (E.bbox.tolist() == [[0, 0], [130, 100]])
    assert (e1.bbox.tolist() == [[0, 0], [100, 100]])
    assert (e2.bbox.tolist() == [[30, 0], [130, 100]])
예제 #17
0
def makeResonator(radius = 10, width = 0.5, space = 1.0):
	#------------------------
	# Make a ring resonator
	# radius: of the ring
	# width: of the ring and the line
	# space: space between the edge of the ring and the line
	#------------------------
	C= Device("Resonator")
	R = pg.ring(radius = radius, width = width)
	C.add_ref(R)
	L1 = makeLine(radius+space,-radius,width,2*radius)
	C.add_ref(L1)
	L2 = makeLine(-radius-space-width,-radius,width,2*radius)
	C.add_ref(L2)
	

	return C
예제 #18
0
Texpanded = pg.offset(T,
                      distance=2,
                      join_first=True,
                      precision=1e-6,
                      num_divisions=[1, 1],
                      layer=0)
Tshrink = pg.offset(T,
                    distance=-1.5,
                    join_first=True,
                    precision=1e-6,
                    num_divisions=[1, 1],
                    layer=0)

# Plot the original geometry, the expanded, and the shrunk versions
D = Device()
t1 = D.add_ref(T)
t2 = D.add_ref(Texpanded)
t3 = D.add_ref(Tshrink)
D.distribute([t1, t2, t3], direction='x', spacing=5)
qp(D)  # quickplot the geometry
create_image(D, 'offset')

# example-invert
import phidl.geometry as pg
from phidl import quickplot as qp

E = pg.ellipse(radii=(10, 5))
D = pg.invert(E, border=0.5, precision=1e-6, layer=0)
qp(D)  # quickplot the geometry
create_image(D, 'invert')
예제 #19
0
파일: ppe.py 프로젝트: niladri18/Phidl
# Define global variables
xmax = 500
ymax = 500
xmin = 0
ymin = 0
xm = (xmax-xmin)/2.0
ym = (ymax-ymin)/2.0

# Cover the entire macro
D.add_polygon([(0,0),(xmax,0),(xmax,ymax),(0,ymax) ], layer = 0)

## Place the pattern rec
Cross = makeCross(xm,ym,100,10, layer)
Cross.rotate(45,center = [xm,ym])
D.add_ref(Cross)

# calculate offset due to the cross
xoff = math.sqrt(100*50)
yoff = math.sqrt(100*50)

## Top left 1
x0 = 10
y0 = ym
y0, LS1 = makeLineSpace(x0,y0, 240 - xoff ,10,20,ym + yoff, layer)
D.add_ref(LS1)
## Top left 2
x0 = 10
y0 = y0 
y0, LS1 = makeLineSpace(x0,y0,240,10,20,500, layer)
D.add_ref(LS1)
예제 #20
0
def eom_sym(wg_width, length, middle_e_width, e_e_gap, chip_width, offset,
            radius):
    euler_y = mod_euler(radius=radius, angle=-45)[1][1]
    euler_x = mod_euler(radius=radius, angle=-45)[1][0]
    wg_wg_sep = (middle_e_width + e_e_gap) / 2 - 2 * euler_y
    straight = wg_wg_sep * np.sqrt(2)
    if wg_wg_sep < 0:
        raise Exception(
            "middle_e_width is set too small with respect to Euler radius")

    left = chip_width / 2 - length / 2 - 2 * euler_x - wg_wg_sep + offset
    right = left

    P1 = Path()
    P1.append(pp.straight(length=left))
    P1.append(mod_euler(radius=radius, angle=-45)[0])
    P1.append(pp.straight(length=straight))
    P1.append(mod_euler(radius=radius, angle=45)[0])
    P1.append(pp.straight(length=length))
    P1.append(mod_euler(radius=radius, angle=45)[0])
    P1.append(pp.straight(length=straight))
    P1.append(mod_euler(radius=radius, angle=-45)[0])
    P1.append(pp.straight(length=right))

    X = CrossSection()
    X.add(width=wg_width, offset=0, layer=1)
    waveguide_device1 = P1.extrude(X)

    E = Device('EOM_GHz')
    b1 = E.add_ref(waveguide_device1)
    b2 = E.add_ref(waveguide_device1)
    b2.mirror((0, 0), (1, 0))

    square = middle_e_width * 0.6
    square_rec_offset = (middle_e_width - square) / 2
    e_left = left + 2 * euler_x + wg_wg_sep
    e_right = left + 2 * euler_x + wg_wg_sep + length - square

    #side_e_width
    R = pg.rectangle(size=(length, middle_e_width), layer=10)
    S = pg.rectangle(size=(square, square), layer=2)

    #top electrode
    h_top = middle_e_width / 2 + e_e_gap
    E.add_ref(R).move([e_left, h_top])
    E.add_ref(S).move([e_left, h_top + square_rec_offset])
    E.add_ref(S).move([e_right, h_top + square_rec_offset])

    #middle electrode
    E.add_ref(R).move([e_left, -middle_e_width / 2])
    E.add_ref(S).move([e_left, -square / 2])
    E.add_ref(S).move([e_right, -square / 2])

    #bottom electrode
    h_bot = -3 * middle_e_width / 2 - e_e_gap
    E.add_ref(R).move([e_left, h_bot])
    E.add_ref(S).move([e_left, h_bot + square_rec_offset])
    E.add_ref(S).move([e_right, h_bot + square_rec_offset])
    #E << R
    return E
예제 #21
0
elec_s = 28 * um
#side_e_width
pad_m = 1.5 * mm

#RF pads
n_rf = 4  #number of RF pobres
spacing = 300
xoff = chip_width - (n_rf * 2 * spacing - pad) - pad_m
yoff = height - pad  #-pad/2

#Initial device setup
D = Device('mac')
D << pg.rectangle(size=(chip_width, height), layer=0)

L = pg.text(text='MAC CHIP REV # 0', size=40, layer=30, justify='center')
D.add_ref(L).move((1.8 * mm, yoff))
D.write_gds('mac_0.gds')

# Length matching math and constants

# In[3]:

#Lower arm (a and phi) path lengths
a_to_phi = 450.934996607 * um
phi_len = 14 * mm - 0.169 * um
phi_to_co = 15603.1440005 * um

c_leg = 5.00436311264
#upper arm (b*c) path lengths
b_to_c = 314.158991993 * um
c_len = c_leg + 40 + c_leg + 14174.808 + c_leg + 40 + c_leg
예제 #22
0
def rfpm(wg_width, length, middle_e_width, e_e_gap):

    side_electrode_width = middle_e_width * 2

    P = Path()
    P.append(pp.straight(length=length))

    X = CrossSection()
    X.add(width=wg_width, offset=0, layer=30)
    RFPM = Device()
    RFPM << P.extrude(X)
    Rt = pg.rectangle(size=(length, side_electrode_width), layer=40)
    Rm = pg.rectangle(size=(length, middle_e_width), layer=40)
    Rb = pg.rectangle(size=(length, side_electrode_width), layer=40)
    RFPM << Rt.move([0, e_e_gap / 2])
    RFPM << Rm.move([0, -middle_e_width - e_e_gap / 2])
    RFPM << Rb.move(
        [0, -middle_e_width - side_electrode_width - e_e_gap - e_e_gap / 2])

    square = middle_e_width * 0.9
    side_height = side_electrode_width * 0.9
    square_rec_offset = (side_electrode_width - side_height) / 2
    square_rec_offset_m = (middle_e_width - square) / 2
    e_left = 0
    e_right = e_left + length - square

    #side_e_width
    R = pg.rectangle(size=(length, middle_e_width), layer=40)
    R2 = pg.rectangle(size=(length, side_electrode_width), layer=40)
    S = pg.rectangle(size=(square, square), layer=50)
    S2 = pg.rectangle(size=(square, side_height), layer=50)

    #top electrode
    h_top = e_e_gap / 2
    RFPM.add_ref(S2).move([e_left, h_top + square_rec_offset])
    RFPM.add_ref(S2).move([e_right, h_top + square_rec_offset])

    #middle electrode
    h_mid = -middle_e_width - e_e_gap / 2
    RFPM.add_ref(S).move([e_left, h_mid + square_rec_offset_m])
    RFPM.add_ref(S).move([e_right, h_mid + square_rec_offset_m])

    #bottom electrode
    h_bot = -middle_e_width - side_electrode_width - e_e_gap - e_e_gap / 2
    RFPM.add_ref(S2).move([e_left, h_bot + square_rec_offset])
    RFPM.add_ref(S2).move([e_right, h_bot + square_rec_offset])

    return RFPM
예제 #23
0
from phidl import Device

# Create `T`, an ellipse and rectangle which will be offset (expanded / contracted)
T = Device()
e = T << pg.ellipse(radii = (10,5), layer = 1)
r = T << pg.rectangle(size = [15,5], layer = 2)
r.move([3,-2.5])

Texpanded = pg.offset(T, distance = 2, join_first = True, precision = 1e-6, 
        num_divisions = [1,1], layer = 0)
Tshrink = pg.offset(T, distance = -1.5, join_first = True, precision = 1e-6, 
        num_divisions = [1,1], layer = 0)

# Plot the original geometry, the expanded, and the shrunk versions
D = Device()
t1 = D.add_ref(T)
t2 = D.add_ref(Texpanded)
t3 = D.add_ref(Tshrink)
D.distribute([t1,t2,t3], direction = 'x', spacing = 5)
qp(D) # quickplot the geometry
create_image(D, 'offset')

# example-invert
import phidl.geometry as pg
from phidl import quickplot as qp

E = pg.ellipse(radii = (10,5))
D = pg.invert(E, border = 0.5, precision = 1e-6, layer = 0)
qp(D) # quickplot the geometry
create_image(D, 'invert')
예제 #24
0
def eom(wg_width, off_chip, W, L_tp, W_tp, L_mmi, W_mmi, Y_mmi, length, radius,
        x_pos, y_pos, middle_e_width, e_e_gap):

    if e_e_gap == 9:
        angle = 12.814353309
    elif e_e_gap == 7:
        angle = 12.1500390158
    elif e_e_gap == 11:
        angle = 13.4465651249

    # Parameters
    mmi_length = L_tp * 2 + L_mmi
    side_electrode_width = middle_e_width * 2

    eulerX = mod_euler(radius=radius, angle=angle)[1][0]
    racetrack_length = eulerX * 4 + length
    #mzi_length = racetrack_length + mmi_length*2
    side = x_pos
    #side = (chip_width - mzi_length)/2

    # Devices
    M = mzi(length, radius, angle, wg_width, Y_mmi)

    mmiL = mmi(W, L_tp, W_tp, L_mmi, W_mmi, Y_mmi)
    mmiR = mmi(W, L_tp, W_tp, L_mmi, W_mmi, Y_mmi)
    mmiR.mirror().move([mmi_length, 0])

    E = Device('EOM')
    #E << pg.rectangle(size=(side+off_chip,wg_width), layer=1).move([-off_chip,y_pos-wg_width/2])
    E << mmiL.move([side, y_pos])
    E << M.move([side + mmi_length, y_pos])
    E << mmiR.move([side + mmi_length + racetrack_length, y_pos])
    #E << pg.rectangle(size=(side+off_chip,wg_width), layer=1).move([side+mzi_length,y_pos-wg_width/2])

    square = middle_e_width * 0.9
    side_height = side_electrode_width * 0.9
    square_rec_offset = (side_electrode_width - side_height) / 2
    e_left = side + mmi_length + 2 * eulerX
    e_right = e_left + length - square

    #side_e_width
    R = pg.rectangle(size=(length, middle_e_width), layer=40)
    R2 = pg.rectangle(size=(length, side_electrode_width), layer=40)
    S = pg.rectangle(size=(square, square), layer=50)
    S2 = pg.rectangle(size=(square, side_height), layer=50)

    #top electrode
    h_top = middle_e_width / 2 + e_e_gap + y_pos
    E.add_ref(R2).move([e_left, h_top])
    E.add_ref(S2).move([e_left, h_top + square_rec_offset])
    E.add_ref(S2).move([e_right, h_top + square_rec_offset])

    #middle electrode
    E.add_ref(R).move([e_left, y_pos - middle_e_width / 2])
    E.add_ref(S).move([e_left, y_pos - square / 2])
    E.add_ref(S).move([e_right, y_pos - square / 2])

    #bottom electrode
    h_bot = -middle_e_width / 2 - side_electrode_width - e_e_gap + y_pos
    E.add_ref(R2).move([e_left, h_bot])
    E.add_ref(S2).move([e_left, h_bot + square_rec_offset])
    E.add_ref(S2).move([e_right, h_bot + square_rec_offset])
    return E
예제 #25
0
# First we create the waveguides.  As you can see from the waveguide() function
# definition, the waveguide() function creates another Device ("WG").
# This can be thought of as the waveguide() function creating another GDS cell,
# only this one has some geometry inside it.
#
# Let's create two of these Devices by calling the waveguide() function
WG1 = waveguide(width=10, height=1)
WG2 = waveguide(width=12, height=2)

# Now we've made two waveguides Device WG1 and WG2, and we have a blank
# device D. We can add references from the devices WG1 and WG2 to our blank
# device byz using the add_ref() function.
# After adding WG1, we see that the add_ref() function returns a handle to our
# reference, which we will label with lowercase letters wg1 and wg2.  This
# handle will be useful later when we want to move wg1 and wg2 around in D.
wg1 = D.add_ref(WG1)  # Using the function add_ref()
wg2 = D << WG2  # Using the << operator which is identical to add_ref()

# Alternatively, we can do this all on one line
wg3 = D.add_ref(waveguide(width=14, height=3))

qp(D)  # quickplot it!

#==============================================================================
# Creating polygons
#==============================================================================
# Create and add a polygon from separate lists of x points and y points
# e.g. [(x1, x2, x3, ...), (y1, y2, y3, ...)]
poly1 = D.add_polygon([(8, 6, 7, 9), (6, 8, 9, 5)])

# Alternatively, create and add a polygon from a list of points
예제 #26
0
# First we create the waveguides.  As you can see from the waveguide() function
# definition, the waveguide() function creates another Device ("WG").
# This can be thought of as the waveguide() function creating another GDS cell,
# only this one has some geometry inside it.
#
# Let's create two of these Devices by calling the waveguide() function
WG1 = waveguide(width=10, height=1)
WG2 = waveguide(width=12, height=2)

# Now we've made two waveguides Device WG1 and WG2, and we have a blank
# device D. We can add references from the devices WG1 and WG2 to our blank
# device byz using the add_ref() function.
# After adding WG1, we see that the add_ref() function returns a handle to our
# reference, which we will label with lowercase letters wg1 and wg2.  This
# handle will be useful later when we want to move wg1 and wg2 around in D.
wg1 = D.add_ref(WG1)
wg2 = D.add_ref(WG2)

# Alternatively, we can do this all on one line
wg3 = D.add_ref(waveguide(width=14, height=3))

quickplot(D)

#==============================================================================
# Creating polygons
#==============================================================================
# Create and add a polygon from separate lists of x points and y points
# e.g. [(x1, x2, x3, ...), (y1, y2, y3, ...)]
poly1 = D.add_polygon([(8, 6, 7, 9), (6, 8, 9, 5)])

# Alternatively, create and add a polygon from a list of points