Let's start by creating a layout for the device we're going to analyze.

Before you start add the following to ~/.gdsfactory/gdsfactoryplus.toml:

[tool.gdsfactoryplus.api]
key = "{your-api-key}"

[tool.gdsfactoryplus.hub]
host = "https://{organization}.hub.gdsfactory.com"

Imports

import getpass
from itertools import chain
from pathlib import Path

import gdsfactory as gf
import gfhub
import pandas as pd
from gdsfactory.gpdk import PDK

PDK.activate()
user = getpass.getuser()
print(user)
runner

Client

client = gfhub.Client()

A cutback layout

Let's create a layout with many cutbacks to measure propagation losses.

@gf.cell(check_ports=False)
def cutback() -> gf.Component:
    """Returns a component cutback sweep."""
    size = (6050, 4100)
    losses = (0, 1, 2)
    cutback_sweep = gf.components.cutback_loss_mmi1x2(
        component=gf.components.mmi1x2(), loss=losses
    )
    cutback_sweep_gratings = [gf.routing.add_fiber_array(c) for c in cutback_sweep]

    for loss, c in zip(losses, cutback_sweep_gratings, strict=False):
        c.name = f"loss_{loss}db"
    c = gf.pack(
        cutback_sweep_gratings, max_size=size, add_ports_prefix=False, spacing=2
    )
    c = gf.grid(c) if len(c) > 1 else c[0]
    return c


c = cutback()
c

png

Clean up (optional)

Let's delete any existing files from this project so you can start fresh.

# Delete existing project files
gds_files = client.query_files(name="cutback.gds", tags=["project:cutback", user])
csv_files = client.query_files(
    name="cutback_device_table.csv", tags=["project:cutback", user]
)
for file in chain(gds_files, csv_files):
    client.delete_file(file["id"])

Our first upload

We can easily upload this to the hub:

path = c.write_gds("cutback.gds")
uploaded = client.add_file(str(path), tags=["project:cutback", user])

Device Table

cell_glob = "loss_*db"
info_keys = ("components",)

iterator = c.kdb_cell.begin_instances_rec()
iterator.targets = cell_glob
data = []
for _ in iterator:
    _c = c.kcl[iterator.inst_cell().cell_index()]
    _disp = (iterator.trans() * iterator.inst_trans()).disp
    row = [_c.name, _disp.x * _c.kcl.dbu, _disp.y * _c.kcl.dbu]
    info = _c.info.model_dump()
    for key in info_keys:
        row.append(info.get(key))
    data.append(row)

df = pd.DataFrame(data=data, columns=["cell", "x", "y", *info_keys])
df
cell x y components
0 loss_2db 33.835 116.310 816
1 loss_1db 529.485 116.310 400
2 loss_0db 516.910 714.861 16

Device table

We can upload this device table:

csv_path = Path("cutback_device_table.csv")
df.to_csv(csv_path, index=False)
client.add_file(csv_path, tags=["project:cutback", user])
csv_path.unlink(missing_ok=True)

NOTE: we could also automatically generate this device table with a pipeline. You'll learn how to create and trigger pipelines in later notebooks.