from__future__importannotationsimportgdsfactoryasgffromgdsfactory.componentimportComponentfromgdsfactory.components.bend_circularimportbend_circular180fromgdsfactory.components.bend_eulerimportbend_euler180fromgdsfactory.components.component_sequenceimportcomponent_sequencefromgdsfactory.components.mmi2x2importmmi2x2fromgdsfactory.components.straightimportstraightfromgdsfactory.typingsimportComponentSpec,ComponentSpecOrList,CrossSectionSpec@gf.cell_with_childdefbendu_double(component:ComponentSpec,cross_section:CrossSectionSpec="xs_sc",bend180:ComponentSpec|ComponentSpecOrList=bend_circular180,port1:str="o1",port2:str="o2",)->ComponentSpec:"""Returns double bend. Args: component: for cutback. cross_section: specification (CrossSection, string or dict). bend180: ubend. If a list, each 180 bend is different. port1: name of first optical port. port2: name of second optical port. """xs=gf.get_cross_section(cross_section)xs_r2=xs.copy(radius=xs.radius-(component.ports[port1].y-component.ports[port2].y))bendu=gf.Component()ifisinstance(bend180,list):bend_r=bendu<<bend180[0](cross_section=xs)bend_r2=bendu<<bend180[1](cross_section=xs_r2)else:bend_r=bendu<<bend180(cross_section=xs)bend_r2=bendu<<bend180(cross_section=xs_r2,)bend_r2=bend_r2.move(origin=(0,0),destination=(0,component.ports[port1].y-component.ports[port2].y),)bendu.add_port("o1",port=bend_r.ports["o1"])bendu.add_port("o2",port=bend_r2.ports["o1"])bendu.add_port("o3",port=bend_r2.ports["o2"])bendu.add_port("o4",port=bend_r.ports["o2"])bendu.copy_child_info(component)returnbendu@gf.celldefstraight_double(component:ComponentSpec,cross_section:CrossSectionSpec="xs_sc",port1:str="o1",port2:str="o2",straight_length:float|None=None,)->ComponentSpec:"""Returns double straight. Args: component: for cutback. cross_section: specification (CrossSection, string or dict). port1: name of first optical port. port2: name of second optical port. straight_length: length of straight. """xs=gf.get_cross_section(cross_section)straight_double=gf.Component()straight_component=straight(length=straight_lengthorxs.radius*2,cross_section=xs)straight_component2=straight(length=straight_lengthorxs.radius*2,cross_section=xs)straight_r=straight_double<<straight_componentstraight_r2=straight_double<<straight_component2.mirror((1,0))straight_r2=straight_r2.move(origin=(0,0),destination=(0,-component.ports[port1].y+component.ports[port2].y),)straight_double.add_port("o1",port=straight_r.ports["o1"])straight_double.add_port("o2",port=straight_r2.ports["o1"])straight_double.add_port("o3",port=straight_r2.ports["o2"])straight_double.add_port("o4",port=straight_r.ports["o2"])returnstraight_double
[docs]@gf.celldefcutback_2x2(component:ComponentSpec=mmi2x2,cols:int=4,rows:int=5,port1:str="o1",port2:str="o2",port3:str="o3",port4:str="o4",bend180:ComponentSpec|ComponentSpecOrList=bend_circular180,mirror:bool=False,straight_length:float|None=None,cross_section:CrossSectionSpec="xs_sc",)->Component:"""Returns a daisy chain of splitters for measuring their loss. Args: component: for cutback. cols: number of columns. rows: number of rows. port1: name of first optical port. port2: name of second optical port. bend180: ubend. If a list, a different bend is used for each of the 2 ports. straight: waveguide spec to connect both sides. mirror: Flips component. Useful when 'o2' is the port that you want to route to. straight_length: length of the straight section between cutbacks. cross_section: specification (CrossSection, string or dict). """component=gf.get_component(component)bendu=bendu_double(component=component,cross_section=cross_section,bend180=bend180,port1=port1,port2=port2,)straight=straight_double(component=component,cross_section=cross_section,straight_length=straight_length,port1=port1,port2=port2,)# Define a map between symbols and (component, input port, output port)symbol_to_component={"A":(component,port1,port3),"B":(component,port4,port2),"D":(bendu,"o2","o3"),"C":(bendu,"o4","o1"),"-":(straight,"o1","o3"),"_":(straight,"o2","o4"),}# Generate the sequence of staircasess=""foriinrange(rows):s+="AB"*colsifmirror:s+="C"ifi%2==0else"D"else:s+="D"ifi%2==0else"C"s=s[:-1]s+="-_"foriinrange(rows):s+="AB"*colss+="D"if(i+rows)%2==0else"C"s=s[:-1]n=cols*rows*2seq=component_sequence(sequence=s,symbol_to_component=symbol_to_component)c=gf.Component()_=c<<seqc.add_port("o1",port=seq.named_references["A1"]["o1"])c.add_port("o2",port=seq.named_references["A1"]["o2"])c.add_port("o3",port=seq.named_references[f"B{n}"]["o2"])c.add_port("o4",port=seq.named_references[f"B{n}"]["o1"])c.copy_child_info(component)c.info["components"]=2*nreturnc