Metadata-Version: 2.5
Name: bamsolve
Version: 0.1.3
Summary: Predict photonic circuits with AI: fields, S-parameters and n_eff from a GDS.
Project-URL: Homepage, https://bamsolve.com
License-Expression: MIT
Requires-Python: >=3.9
Requires-Dist: numpy>=1.22
Description-Content-Type: text/markdown

# bamsolve

Predict photonic circuits with AI. The API is free during the public alpha.

## Get started

1. Install the package:

```bash
python -m pip install --upgrade bamsolve
```

2. Enter your email at https://bamsolve.com/#get-key. Copy the API key shown on the page.
3. Run the example below. It downloads a ready-to-use GDS and asks for your key with hidden input.

```python
from getpass import getpass
from urllib.request import urlretrieve
from bamsolve import Layer, Stack, bamsolve, pred

urlretrieve(
    "https://bamsolve.com/examples/ebeam_y_1550.gds",
    "ebeam_y_1550.gds",
)
bamsolve(api_key=getpass("Bamsolve API key: "))

stack = Stack(clad=1.444, layers={(1, 0): Layer(n=3.48, z=(0.0, 0.22))})
dev = stack("ebeam_y_1550.gds")
res = pred(dev, inputs={((1, 10), "TE", 1.55)})

print("S shape:", res.S.shape)  # (1, 3, 3)
print("Upper-arm power:", abs(res.S[0, 1, 0]) ** 2)
print("Lower-arm power:", abs(res.S[0, 2, 0]) ** 2)
res.export_s("ebeam_y_1550.s3p")
```

The example is a 15 µm silicon Y-branch with three ports.
Its core is on GDS layer/datatype `(1, 0)`. Port `opt1` is at the left end
on `(1, 10)`. Port `opt2` is at the upper-right end on `(1, 11)`.
Port `opt3` is at the lower-right end on `(1, 12)`.
The `z` bounds and wavelength are in micrometres. Refractive indices have no units.

This device includes a split and two curved arms. A full 3D FDTD test must
resolve these features, the core thickness, and the surrounding cladding.
A direct full-matrix calculation also needs a separate input at each port.
This takes more work than a straight-waveguide check. The tutorial does not
give an FDTD runtime for your computer; runtime depends on the mesh,
simulation duration, and hardware.

`res.S` contains every input and output port for the returned polarization,
with shape `(wavelength, output_port, input_port)`. In this example, array
index `0` is the left port, index `1` is the upper-right port, and index `2`
is the lower-right port. The input tuple
selects the field shown in `res.E`; it does not restrict the S-matrix to one column.
`res.n_eff` holds the effective index. `res.E` is a complex array indexed as
`[y, x]`, on the coordinates `res.y` and `res.x` in micrometres.

For more than one input, pass a list of input tuples. The updated API returns
each input in `res.results`, including inputs that have the same polarization.
Each item has `excitation_id`, `port_index`, `port_name`, `wavelengths`, `S`,
and `E`. The top-level fields retain the primary result. `res.by_pol` gives
the first result for each polarization; use `res.results` for all inputs.

Set `include_vector_fields=True` in `pred` to request complex `Ex`, `Ey`, and
`Ez` arrays. These arrays use `[x, y, z]` order and the coordinates `x`, `y`,
and `z`. `field_wavelength_um` identifies the field wavelength. The S matrix
has a separate wavelength axis. Vector fields are omitted by default to limit
response size. A server that cannot return a requested result gives an error.

`physics_status` reports the solver status. An unavailable physics solver returns
HTTP 503; this is not a completed prediction. Array shapes and successful file
export do not establish physical accuracy.

`Layer.slab` requires an explicit `slab_polygon` footprint in micrometres.
The solver must support that geometry. `Layer.priority` specifies material
overlap priority. Unsupported or ambiguous geometry gives an error.

`res.export_s` accepts Touchstone `.sNp`, `.json`, and `.npz`. JSON and NPZ
retain the returned sample order and complex S values.

Read the [Get started tutorial](https://bamsolve.com/docs.html#get-started)
for downloadable scripts, a simple straight-waveguide check, port instructions, and plotting.
You can also [create the straight GDS with gdstk](https://bamsolve.com/examples/make_straight.py).
The downloaded GDS does not require gdstk to run a prediction.

## Check the exported file

Install an independent Touchstone reader with `python -m pip install scikit-rf`, then run:

```python
import numpy as np
import skrf

network = skrf.Network("ebeam_y_1550.s3p")
assert np.allclose(network.s, res.S, atol=1e-7)
print(network.f)  # Frequency in Hz
```

This checks file compatibility. It does not independently validate the predicted physics.

## API configuration

The default API address is https://api.bamsolve.com.

You can set `BAMSOLVE_API_KEY` before starting Python instead of entering the key
in your script. Keep the key out of source control and shared notebooks.

To use a custom server, set its URL before you call `pred`:

```python
bamsolve(api_key="bsk_...", url="https://YOUR_API_HOST")
```

You can also set the `BAMSOLVE_URL` environment variable before you import the module.
