# Fixing sharp angles in the layout of a directional coupler¶

This example shows how to use layout operations to stub acute angles of a directional coupler. Stubbing of acute angles is an important step in the design process that makes sure your device passes the design rule checks (DRCs).

First we import a directional coupler from picazzo:

from technologies import silicon_photonics
import ipkiss3.all as i3
from picazzo3.wg.dircoup.cell import BendDirectionalCoupler

dc = BendDirectionalCoupler(name="myDC")
dc_lay = dc.Layout(manhattan=False,
straight_after_bend=5.0,
bend_angle=30)
dc_lay.visualize()


The layout can be checked on acute angles using get_acute_angle_points:

acute_points = i3.get_acute_angle_points(dc_lay)
for layer in acute_points:
for point_data in acute_points[layer]:
point, _, angle = point_data
print("Acute point ({:.2f}, {:.2f}) with {:.2f} degrees angle found in layer {}"
.format(point[0], point[1], angle, layer))


Out:

Acute point (8.95, -1.56) with 89.94 degrees angle found in layer PPLAYER WG-LFAREA
Acute point (6.24, 0.00) with 300.06 degrees angle found in layer PPLAYER WG-LFAREA
Acute point (8.95, 1.56) with 89.94 degrees angle found in layer PPLAYER WG-LFAREA
Acute point (-8.95, 1.56) with 89.94 degrees angle found in layer PPLAYER WG-LFAREA
Acute point (-6.24, 0.00) with 300.06 degrees angle found in layer PPLAYER WG-LFAREA
Acute point (-8.95, -1.56) with 89.94 degrees angle found in layer PPLAYER WG-LFAREA
Acute point (7.72, -3.68) with 89.98 degrees angle found in layer PPLAYER WG-LFLIN
Acute point (7.95, -3.29) with 89.99 degrees angle found in layer PPLAYER WG-LFLIN
Acute point (-7.95, -3.29) with 89.99 degrees angle found in layer PPLAYER WG-LFLIN
Acute point (-7.72, -3.68) with 89.98 degrees angle found in layer PPLAYER WG-LFLIN
Acute point (7.95, 3.29) with 89.99 degrees angle found in layer PPLAYER WG-LFLIN
Acute point (7.72, 3.68) with 89.98 degrees angle found in layer PPLAYER WG-LFLIN
Acute point (-7.72, 3.68) with 89.98 degrees angle found in layer PPLAYER WG-LFLIN
Acute point (-7.95, 3.29) with 89.99 degrees angle found in layer PPLAYER WG-LFLIN


Rounding errors and grid snapping have caused some 90-degree angles to be slightly acute. Since these are not angles that need to be stubbed, the angle_treshold argument can be used to avoid this.

acute_points = i3.get_acute_angle_points(dc_lay, angle_threshold=0.1)
for layer in acute_points:
for point_data in acute_points[layer]:
point, _, angle = point_data
print("Acute point ({:.2f}, {:.2f}) with {:.2f} degrees angle found in layer {}"
.format(point[0], point[1], angle, layer))


Out:

Acute point (6.24, 0.00) with 300.06 degrees angle found in layer PPLAYER WG-LFAREA
Acute point (-6.24, 0.00) with 300.06 degrees angle found in layer PPLAYER WG-LFAREA


The stub elements can be inspected using get_stub_elements:

elems_add, elems_subt = i3.get_stub_elements(dc_lay,
angle_threshold=0.1,
stub_width=0.5)

stubs_lay.visualize()


In some cases the stub elements turn out to be too small due to grid snapping. Therefore it is also possible to specify the grow_amount argument:

elems_add, elems_subt = i3.get_stub_elements(dc_lay,
angle_threshold=0.1,
stub_width=0.5,
grow_amount=0.5)

stubs_lay.visualize()


To stub the acute angles and create the new layout we can use stub_acute_angles. There are several ways to do this:

• By default, all acute angles on all layers are stubbed.
elems = i3.stub_acute_angles(dc_lay,
angle_threshold=0.1,
stub_width=0.5)
stubbed_layout = i3.LayoutCell().Layout(elements=elems, ports=dc_lay.ports)

• Specify which stub elements to add and subtract using the stub_elements argument.
elems = i3.stub_acute_angles(dc_lay,
stubbed_layout = i3.LayoutCell().Layout(elements=elems, ports=dc_lay.ports)

• Specify the layer(s) on which to stub the acute angles.
elems = i3.stub_acute_angles(dc_lay,
angle_threshold=0.1,
stub_width=0.5,

stubbed_layout.visualize()