"""Cells imported from the PDK."""fromfunctoolsimportcache,partialimportgdsfactoryasgffromgdsfactoryimportComponentfromgdsfactory.typingsimport(ComponentReference,ComponentSpec,CrossSectionSpec,Optional,)fromubcpdkimporttechfromubcpdk.configimportCONFIG,PATHfromubcpdk.import_gdsimportimport_gdsfromubcpdk.techimport(LAYER,add_pins_bbox_siepic,)um=1e-6@gf.celldefbend_euler(cross_section="strip",**kwargs)->Component:returngf.components.bend_euler(cross_section=cross_section,**kwargs)bend_euler180=partial(bend_euler,angle=180)bend=bend_euler
[docs]defstraight(length:float=10.0,npoints:int=2,cross_section:CrossSectionSpec="strip",**kwargs,)->Component:"""Returns a Straight waveguide. Args: length: straight length (um). npoints: number of points. cross_section: specification (CrossSection, string or dict). kwargs: additional cross_section arguments. .. code:: o1 -------------- o2 length """returngf.c.straight(length=length,npoints=npoints,cross_section=cross_section,**kwargs)
[docs]@gf.celldefmzi_heater(delta_length=10.0,length_x=320)->gf.Component:"""Returns MZI with heater. Args: delta_length: extra length for mzi arms. """return_mzi_heater(delta_length=delta_length,length_x=length_x)
defget_input_label_text(gc:ComponentReference,component_name:Optional[str]=None,username:str=CONFIG.username,)->str:"""Return label for port and a grating coupler. Args: gc: grating coupler reference. component_name: optional component name. username: for the label. """polarization=gc.info.get("polarization")wavelength=gc.info.get("wavelength")assertpolarization.upper()in["TE","TM",],f"Not valid polarization {polarization.upper()!r} in [TE, TM]"assert(isinstance(wavelength,int|float)and1.0<wavelength<2.0),f"{wavelength} is Not valid 1000 < wavelength < 2000"name=component_namename=clean_name(name)# return f"opt_{polarization.upper()}_{int(wavelength * 1000.0)}_device_{username}-{name}-{gc_index}-{port.name}"returnf"opt_in_{polarization.upper()}_{int(wavelength*1000.0)}_device_{username}-{name}"
[docs]defadd_fiber_array(component:ComponentSpec=straight,component_name:Optional[str]=None,gc_port_name:str="o1",with_loopback:bool=False,fanout_length:float=0.0,grating_coupler:ComponentSpec=gc_te1550,cross_section:CrossSectionSpec="strip",straight:ComponentSpec="straight",taper:ComponentSpec|None=None,**kwargs,)->Component:"""Returns component with grating couplers and labels on each port. Routes all component ports south. Can add align_ports loopback reference structure on the edges. Args: component: to connect. component_name: for the label. gc_port_name: grating coupler input port name 'o1'. with_loopback: True, adds loopback structures. fanout_length: None # if None, automatic calculation of fanout length. grating_coupler: grating coupler instance, function or list of functions. cross_section: spec. straight: straight component. taper: taper component. kwargs: cross_section settings. """c=gf.Component()ref=c<<gf.routing.add_fiber_array(straight=straight,bend=bend,component=component,component_name=component_name,grating_coupler=grating_coupler,gc_port_name=gc_port_name,with_loopback=with_loopback,fanout_length=fanout_length,cross_section=cross_section,taper=taper,**kwargs,)ref.drotate(-90)c.add_ports(ref.ports)c.copy_child_info(component)component_name=component_nameorcomponent.namegrating_coupler=gf.get_component(grating_coupler)label=get_input_label_text(gc=grating_coupler,component_name=component_name)c.add_label(position=c.ports["o1"].dcenter,text=label,layer=LAYER.TEXT)returnc
L=1.55/4/2/2.44
[docs]@gf.celldefdbg(w0:float=0.5,dw:float=0.1,n:int=100,l1:float=L,l2:float=L,)->gf.Component:"""Includes two ports. Args: w0: width. dw: delta width. n: number of elements. l1: length teeth1. l2: length teeth2. """c=gf.Component()s=gf.components.straight(length=l1,cross_section="strip")g=c<<gf.components.dbr(w1=w0-dw/2,w2=w0+dw/2,n=n,l1=l1,l2=l2,cross_section="strip",)s1=c<<ss2=c<<ss1.connect("o2",g.ports["o1"])s2.connect("o2",g.ports["o2"])c.add_port("o1",port=s1.ports["o1"])c.add_port("o2",port=s2.ports["o1"])c=add_pins_bbox_siepic(c)returnc
ring_double_heater=partial(gf.components.ring_double_heater,via_stack="via_stack_heater_mtop",straight=straight,length_y=0.2,cross_section_heater="heater_metal",cross_section_waveguide_heater="strip_heater_metal",cross_section="strip",coupler_ring=coupler_ring,)ring_single_heater=partial(gf.components.ring_single_heater,via_stack="via_stack_heater_mtop",straight=straight,cross_section_heater="heater_metal",cross_section_waveguide_heater="strip_heater_metal",cross_section="strip",coupler_ring=coupler_ring,)ebeam_dc_te1550=partial(gf.components.coupler,)taper=partial(gf.components.taper)ring_with_crossing=partial(gf.components.ring_single_dut,component=ebeam_crossing4_2ports,port_name="o4",bend=bend,cross_section="strip",)pad=partial(gf.components.pad,size=(75,75),layer=LAYER.M2_ROUTER,bbox_layers=(LAYER.PAD_OPEN,),bbox_offsets=(-1.8,),)defadd_label_electrical(component:Component,text:str,port_name:str="e2"):"""Adds labels for electrical port. Returns same component so it needs to be used as a decorator. """ifport_namenotincomponent.ports:port_names=[port.nameforportincomponent.ports]raiseValueError(f"No port {port_name!r} in {port_names}")component.add_label(text=text,position=component.ports[port_name].dcenter,layer=LAYER.TEXT)returncomponentpad_array=partial(gf.components.pad_array,pad=pad,spacing=(125,125))add_pads_rf=partial(gf.routing.add_electrical_pads_top,component="ring_single_heater",pad_array="pad_array",)add_pads_top=partial(gf.routing.add_pads_top,component=straight_heater_metal,)add_pads_bot=partial(gf.routing.add_pads_bot,component=straight_heater_metal,)
[docs]@cachedefadd_fiber_array_pads_rf(component:ComponentSpec="ring_single_heater",username:str=CONFIG.username,orientation:float=0,pad_yspacing:float=50,component_name:Optional[str]=None,**kwargs,)->Component:"""Returns fiber array with label and electrical pads. Args: component: to add fiber array and pads. username: for the label. orientation: for adding pads. pad_yspacing: for adding pads. component_name: for the label. kwargs: for add_fiber_array. """c0=gf.get_component(component)component_name=component_nameorc0.namecomponent_name=clean_name(component_name)text=f"elec_{username}-{component_name}_G"c1=add_pads_rf(component=c0,orientation=orientation,spacing=(0,pad_yspacing))add_label_electrical(component=c1,text=text)# ports_names = [port.name for port in c0.ports if port.orientation == orientation]# c1 = add_pads_top(component=c0, port_names=ports_names)returnadd_fiber_array(component=c1,component_name=component_name,**kwargs)
[docs]@cachedefadd_pads(component:ComponentSpec="ring_single_heater",username:str=CONFIG.username,**kwargs,)->Component:"""Returns fiber array with label and electrical pads. Args: component: to add fiber array and pads. username: for the label. kwargs: for add_fiber_array. """c0=gf.get_component(component)text=f"elec_{username}-{clean_name(c0.name)}_G"c0._locked=Falsec0=add_label_electrical(c0,text=text)returnadd_pads_rf(component=c0,**kwargs)
if__name__=="__main__":# c = straight_heater_metal()# c = thermal_phase_shifter0()# c = straight_one_pin()# c = ebeam_adiabatic_te1550()# c = ebeam_bdc_te1550()# c = gc_tm1550()# c = spiral()# c = add_pads_top()# c.pprint_ports()# c.pprint_ports()# c = straight()# c = terminator_short()# c = add_fiber_array_pads_rf(c)# c = ring_double(length_y=10)# c = ring_with_crossing()# c = straight_heater_metal()# c = add_fiber_array(straight_heater_metal)# c.pprint_ports()# c = coupler_ring()# c = dbr_cavity_te()# c = dbr_cavity()# c = ring_single(radius=12)# c = bend_euler()# c = mzi()# c = spiral()# c = pad_array()# c = bend_euler()# c = mzi_heater()# c = ring_with_crossing()# c = ring_single()# c = ring_double()# c = ring_double(radius=12, length_x=2, length_y=2)# c = straight()c=add_fiber_array_pads_rf(component_name="ring_single_heater")c.show()