Skip to content

Notebook Execution

Use Notebooks to work with lot measurements in Python. The server prepares pandas frames for your scope; cells can use pandas, NumPy, DuckDB, SciPy, scikit-learn, PyArrow, and Plotly. You do not need a local Python installation.

  1. Open Notebooks, select a lot, and open an editable notebook or start a draft. Check that the status says server runtime ready. Execution requires editor access and a configured server runtime.
  2. Open Show Setup if the setup details are hidden. For an Analyze selection, choose Attach Current Live Scope, or choose an analysis and version under Saved Analysis, then Attach Saved Scope.
  3. Check Current Scope, including the lot, snapshot, selected dies, and limits. Run the cell below with its run button or Shift+Enter.
show(analysis_scope)
show({
"attached_rows": len(scope_test_results),
"source_artifact_rows": scope_test_results.attrs["stratum_source_row_count"],
"sampled": scope_test_results.attrs["stratum_sampled"],
"scope_status": scope_test_results.attrs["stratum_scope_status"],
})

Use Analyze in the same tab before attaching its live scope. The button uses that tab’s Analyze state, not a selection in another tab. To use work saved elsewhere, select its analysis and version under Saved Analysis instead. The list is for the chosen lot; attaching a saved scope also adopts that version’s snapshot.

Attaching the live scope captures it at that point; it is not a subscription to later brushes in Analyze. Attach again to use a changed selection or limits. Detach Analyze Scope returns to the chosen lot/snapshot without that explicit selection or scenario. It does not remove the lot’s data attachment.

Existing cell outputs can remain visible after an attachment changes. Rerun the cells before using their results for the new scope. server runtime ready reports service availability, not your permission to execute: a viewer can still receive Editor role required when running a cell.

Run All runs nonempty cells in order. Put imports and setup above dependent cells, and inspect errors before trusting later outputs. For saving code, versions, recovery, and sharing, see Saved Work And Sharing.

An attachment contains at most 250,000 measurement rows across all tests, selected by deterministic hash ordering after scope and retest filtering. It is not a 250,000-row allowance per test, and it is not every measurement in a large lot. Rows with null measurements are excluded. The account’s retest policy determines which eligible attempt supplies each die/test/return result.

The execution summary reports prepared or reused rows and flags sampled attachments. The same metadata is available in the result frames’ attrs:

Attribute Meaning
stratum_source_row_count Catalog row count of the source artifact, before selection and result filtering; zero if unavailable. Not an exact selected-population or selected-test denominator.
stratum_sampled The 250,000-row cap was reached and the source artifact has more rows. This is a conservative cap flag, not a measured sampling fraction.
stratum_scope_status complete, capped, empty_selection, or no_scope. complete describes the eligible attachment, not all raw attempts in the lot.

With selection inactive, the attachment covers the eligible lot population up to the cap. With selection active but empty, it contains no measurements. An empty selected_dies frame alone cannot distinguish those cases; check analysis_scope.selection_active. The no_scope status means no analysis scope was supplied; the Notebooks UI normally supplies a default lot scope.

Frame Contents
analysis_scope Context summary: lot, snapshot, selection state/counts, selected test/return, wafer focus, and scenario-limit count.
selected_dies Explicit selected identities: wafer number, X, Y.
selection_runs Compact selection ranges in the attached die index. They are not row ranges into the measurement frames.
scenario_limits Attached limits keyed by test_number and return_index.
scope_test_results All tests in the attached die scope, subject to filtering and the shared cap.
selected_test_results Rows from that attachment matching the selected test and return. Empty if no test is selected.

Wafer focus does not automatically narrow either result frame. Both include wafer/X/Y, site, test and return identity, result/unit, recorded limits and pass, effective limits and effective_pass, and retest_sequence. effective_* incorporates attached scenario limits, then account spec overrides, then recorded values. Recorded verdicts and limit membership can disagree. These are test-result fields, not a recomputation of full-die yield.

Keep MPR returns separate, and retain null return indices for PTR/FTR tests:

summary = (
scope_test_results
.groupby(["test_number", "return_index", "test_name", "unit"], dropna=False)
.agg(attached_n=("result", "count"), mean_result=("result", "mean"))
.reset_index()
)
show(summary)

To explicitly narrow the selected-test frame to the focused wafer:

focused_results = selected_test_results.copy()
wafer = st.context().get("selected_wafer_number")
if wafer is not None:
focused_results = focused_results.loc[focused_results["wafer_number"].eq(wafer)]
show(focused_results)

An empty result here can mean no test selected, no matching measurements, an empty die selection, or omitted rows in a capped attachment. Check scope and sampling metadata before treating it as a data-quality finding.

sql(...) runs DuckDB over the attached frames in this Python process. It does not call the SQL editor or query additional Parquet rows. The SQL editor’s portable views and current_scope_* helpers are not registered here. This example counts only the rows already attached:

show(sql("""
SELECT test_number, return_index, COUNT(*) AS attached_rows
FROM scope_test_results
GROUP BY test_number, return_index
ORDER BY test_number, return_index
"""))

st.tables() lists available frame names. st.scope_test_results() and st.selected_test_results() return fresh copies. show(...) displays a value; a cell’s final expression is also displayed automatically. Neither Python frame edits nor this local DuckDB connection apply limits to Analyze or write changes to the source lot.

The first cell prepares the attachment and starts a server process. Later cells reuse it while the scope and dataset identity remain unchanged. The summary separates preparation, runner round-trip, and execution time; peak memory is the process lifetime high-water mark, not memory used by that cell.

At each cell boundary, built-in frame names are rebound from the retained attachment. Ordinary pandas mutations to scope_test_results in one cell do not alter the next cell’s built-in frame or the registered SQL source. Keep derived work under your own variable, such as working = scope_test_results.copy(); that variable persists in the current process until a reset.

Changing scope or snapshot resets the runtime. Each editor has its own process; another tab does not share your variables. Leaving Notebooks or changing workspace releases it. A hidden tab releases an idle runtime after about a minute, without interrupting an already-running cell. The server also expires idle sessions, normally after 15 minutes, and may reclaim idle processes when capacity is needed.

A restarted or evicted runtime can rebuild its attachment, but cannot restore your Python variables. Rerun imports and setup cells before dependent cells. The normal per-cell execution timeout is 120 seconds; operators can configure it. A timeout discards the process. Retry Runtime rechecks availability, not a saved execution state. Old displayed outputs are not evidence that the new runtime has rerun the code, and outputs and variables are not saved versions.