You can add a label per automated alignment structure.
However this only works well for fiber array only or electrical probing only, so we don't recommend it.
from functools import partial
import json
import gdsfactory as gf
from gdsfactory.generic_tech import get_generic_pdk
from gdsfactory.labels import add_label_ehva, add_label_json
This is deprecated, we recommend exposing all ports and writing the test manifest directly. However you can also do automatic testing by adding labels the devices that you want to test. GDS labels are not fabricated and are only visible in the GDS file.
Lets review some different automatic labeling schemas:
Most gdsfactory examples add south grating couplers on the south and RF or DC signals to the north. However if you need RF and DC pads, you have to make sure RF pads are orthogonal to the DC Pads. For example, you can use EAST/WEST for RF and NORTH for DC.
Each alignment site includes a label with the measurement and analysis settings:
The default settings can be stored in a separate CSV file
info = dict(
doe="mzis",
analysis="mzi_phase_shifter",
measurement="optical_loopback2_heater_sweep",
measurement_settings=json.dumps(dict(v_max=5)),
)
c = gf.components.mzi_phase_shifter()
c = gf.components.add_fiber_array_optical_south_electrical_north(c)
c.info.update(info)
c = add_label_json(c)
c.plot()
c.labels
json.loads(c.labels[0].text)
c = gf.components.spiral_inner_io_fiber_array(
length=20e3,
)
c = gf.labels.add_label_json(c)
info = dict(
measurement="optical_loopback2",
doe="spiral_sc",
measurement_settings=json.dumps(dict(wavelength_alignment=1560)),
)
c.info.update(info)
c.plot()
json.loads(c.labels[0].text)
Labels follow format opt_in_{polarization}_{wavelength}_device_{username}_({component_name})-{gc_index}-{port.name}
and you only need to label the laser input port of the fiber array.
This also includes one label per test site.
mmi = gf.components.mmi2x2()
mmi_te_siepic = gf.labels.add_fiber_array_siepic(component=mmi)
mmi_te_siepic.plot()
mmi_te_siepic.ports
labels = mmi_te_siepic.get_labels()
for label in labels:
print(label.text)
add_label_ehva_demo = partial(add_label_ehva, die="demo_die")
mmi = gf.c.mmi2x2(length_mmi=2.2)
mmi_te_ehva = gf.routing.add_fiber_array(mmi)
mmi_te_ehva = add_label_ehva_demo(mmi_te_ehva)
mmi_te_ehva.plot()
labels = mmi_te_ehva.get_labels(depth=0)
for label in labels:
print(label.text)
One advantage of the EHVA formats is that you can track any changes on the components directly from the GDS label, as the label already stores any changes of the child device, as well as any settings that you specify.
Settings can have many levels of hierarchy, but you can still access any children setting with :
notation.
grating_coupler:
function: grating_coupler_elliptical_trenches
settings:
polarization: te
taper_angle: 35
add_label_ehva_demo = partial(
add_label_ehva,
die="demo_die",
)
mmi = gf.components.mmi2x2(length_mmi=10)
mmi_te_ehva = gf.routing.add_fiber_array(
mmi,
get_input_labels_function=None,
)
mmi_te_ehva = add_label_ehva_demo(mmi_te_ehva)
mmi_te_ehva.plot()
labels = mmi_te_ehva.get_labels(depth=0)
for label in labels:
print(label.text)
import gdsfactory as gf
@gf.cell
def wg():
c = gf.Component()
c.info["doe"] = "phase_shifter_rings_te"
c.info["test_sequence"] = "optical_loopback_electrical_sweep"
c.info["data_analysis"] = "extract_vpi"
return c
c = wg()
c.pprint()
gdspath = c.write_gds("demo.gds", with_metadata=True)
You can use GDS labels to store device information such as settings and port locations.
The advantage of GDS labels is that they are all stored in the same file.
We define a single label for each test site (Device Under Test), and the label contains all the measurement and data analysis information.
test_info_mzi_heaters = dict(
doe="mzis_heaters",
analysis="mzi_heater_phase_shifter_length",
measurement="optical_loopback4_heater_sweep",
)
test_info_ring_heaters = dict(
doe="ring_heaters_coupling_length",
analysis="ring_heater",
measurement="optical_loopback2_heater_sweep",
)
mzis = [
gf.components.mzi2x2_2x2_phase_shifter(length_x=lengths)
for lengths in [100, 200, 300]
]
rings = [
gf.components.ring_single_heater(length_x=length_x) for length_x in [10, 20, 30]
]
mzis_te = []
for mzi in mzis:
mzi_te = gf.components.add_fiber_array_optical_south_electrical_north(
mzi,
electrical_port_names=["top_l_e2", "top_r_e2"],
)
mzi_te.info.update(test_info_mzi_heaters)
mzi_te = gf.labels.add_label_json(mzi_te)
mzis_te.append(mzi_te)
rings_te = []
for ring in rings:
ring_te = gf.components.add_fiber_array_optical_south_electrical_north(
ring,
electrical_port_names=["l_e2", "r_e2"],
)
ring_te.info.update(test_info_ring_heaters)
ring_te = gf.labels.add_label_json(ring_te)
rings_te.append(ring_te)
c = gf.pack(mzis_te + rings_te)[0]
c.plot()
Each Device Under Test (test site) has a JSON test label with all the settings.
You can define a Test manifest (also known as Test sequence) in CSV automatically from the labels.
import pandas as pd
gdspath = c.write_gds()
csvpath = gf.labels.write_labels.write_labels_gdstk(
gdspath, debug=True, prefixes=["{"], layer_label="TEXT"
)
df = pd.read_csv(csvpath)
df
As you can see there are 6 devices with optical and electrical ports.
You can turn each label into a test manifest CSV file to interface with your lab instrumentation functions.
Each measurement will use a different measurement
procedure and settings measurement_settings
The default measurement settings for each functions can also be defined in a separate CSV file and easily editable with Excel or LibreOffice.
from gdsfactory.labels.write_test_manifest import write_test_manifest
dm = write_test_manifest(csvpath)
dm