Source code for gdsfactory.components.ge_detector_straight_si_contacts
"""Straight Ge photodetector."""
from __future__ import annotations
from functools import partial
import gdsfactory as gf
from gdsfactory.component import Component
from gdsfactory.components.taper import taper as taper_func
from gdsfactory.components.via_stack import via_stack_slab_m2, via_stack_slab_m3
from gdsfactory.cross_section import pn_ge_detector_si_contacts
from gdsfactory.typings import ComponentSpec, CrossSectionSpec
_taper = partial(taper_func, length=20.0, width1=0.5, width2=0.8, cross_section="xs_sc")
[docs]
@gf.cell
def ge_detector_straight_si_contacts(
length: float = 80.0,
cross_section: CrossSectionSpec = pn_ge_detector_si_contacts,
via_stack: ComponentSpec | tuple[ComponentSpec, ComponentSpec] = via_stack_slab_m3,
via_stack_width: float = 10.0,
via_stack_spacing: float = 5.0,
via_stack_offset: float = 0.0,
taper: ComponentSpec | None = _taper,
) -> Component:
"""Returns a straight Ge on Si detector with silicon contacts.
There are no contacts on the Ge. These detectors could have lower
dark current and sensitivity compared to those with contacts in the
Ge. See Chen et al., "High-Responsivity Low-Voltage 28-Gb/s Ge p-i-n
Photodetector With Silicon Contacts", Journal of Lightwave Technology 33(4), 2015.
https://doi.org/10.1109/JLT.2014.2367134
Args:
length: total length of the waveguide including the tapers.
cross_section: for the waveguide.
via_stack: for the via_stacks. First element
via_stack_width: width of the via_stack.
via_stack_spacing: spacing between via_stacks.
via_stack_offset: with respect to the detector
taper: optional taper to transition from the input waveguide \
into the absorption region.
"""
c = Component()
if taper:
taper = gf.get_component(taper)
length -= 2 * taper.get_ports_xsize()
if type(via_stack) is tuple:
via_stack_top = via_stack[0]
via_stack_bot = via_stack[1]
else:
via_stack_top = via_stack
via_stack_bot = via_stack
wg = c << gf.components.straight(
cross_section=cross_section,
length=length,
)
if taper:
t1 = c << taper
t1.connect("o2", wg["o1"], allow_width_mismatch=True)
c.add_port("o1", port=t1["o1"])
else:
c.add_ports(wg.get_ports_list())
via_stack_length = length
via_stack_top = c << via_stack_top(
size=(via_stack_length, via_stack_width),
)
via_stack_bot = c << via_stack_bot(
size=(via_stack_length, via_stack_width),
)
via_stack_bot.xmin = wg.xmin
via_stack_top.xmin = wg.xmin
via_stack_top.ymin = +via_stack_spacing / 2 + via_stack_offset
via_stack_bot.ymax = -via_stack_spacing / 2 + via_stack_offset
c.add_ports(via_stack_bot.ports, prefix="bot_")
c.add_ports(via_stack_top.ports, prefix="top_")
return c
if __name__ == "__main__":
c = ge_detector_straight_si_contacts(
via_stack=(via_stack_slab_m3, via_stack_slab_m2), via_stack_offset=0
)
c.show(show_ports=True)