> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bravenlab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# End-to-end worked example

> One realistic scenario, start to finish — folder to pipeline to comparison — using nearly every function in the library.

This page follows one dataset all the way through Braven: a temperature sweep run across several read-out boards, each identified by a device key. It uses `log_config`, `log_summary`, `log_series`, `plot_series`, `device()`, `path_params()`, and `upload()` with a matplotlib Figure — the full set from [Write a pipeline script](/guides/write-a-pipeline-script).

## The shape of the flow

```mermaid theme={null}
flowchart LR
    A["Watcher / SDK\n(data arrives)"] --> B["Experiment\n(files + metadata)"]
    B --> C["Pipeline Run"]
    C --> D["Config & Summary\n(scalars)"]
    C --> E["Series & Figures\n(plottable)"]
    C --> F["Device\n(braven.device key)"]
    D --> G["Analysis\n(overlay across experiments)"]
    E --> G
    F --> H["Devices tab\n(history per device)"]
    G --> I["Report\n(saved & shareable)"]
```

## 1. The data on disk

Each board's run at each temperature lands as one CSV, dropped by the instrument's own software into a watched folder:

```
BoardCalibration/
  ├── run_boardS1_30C/
  │     └── boardS1_30C.csv
  ├── run_boardS1_50C/
  │     └── boardS1_50C.csv
  ├── run_boardS2_30C/
  │     └── boardS2_30C.csv
  └── run_boardS2_50C/
        └── boardS2_50C.csv
```

Each subfolder becomes one Experiment automatically — see [Ingest data](/guides/ingest-data). `30C` / `50C` in the filename is exactly the pattern `braven.path_params()` recognizes.

## 2. The pipeline script

Assigned once, to the `BoardCalibration` folder — every new subfolder runs this automatically.

```python theme={null}
# requirements: pandas numpy matplotlib

import re
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import braven

# --- Read the one file this experiment carries -----------------------------
filename = next(iter(braven.files))
df = pd.read_csv(filename)

# --- Pull the temperature straight from the filename ------------------------
params = braven.path_params()             # {"temperature": 30.0} from "...30C..."
temperature_c = params.get("temperature")
braven.log_config("temperature_c", str(temperature_c))

# --- Identify the physical board from the filename and tag everything to it -
board_match = re.search(r"board(\w+?)_\d", filename)
board_key = board_match.group(1) if board_match else "unknown"
board = braven.device(board_key, type="Read-out board")

board.log_config("temperature_c", str(temperature_c))

signal = df["signal"].to_numpy()
noise = df["noise"].to_numpy()
snr = float(np.mean(signal) / np.std(noise))
board.log_summary("snr", f"{snr:.3f}")

# Experiment-level summary — not tied to one board.
braven.log_summary("row_count", str(len(df)))

# --- Plottable curve, overlayable across every board/temperature combo ------
board.plot_series(
    "signal_vs_time",
    y=signal.tolist(),
    x=df["time"].tolist(),
    x_label="Time (s)",
    y_label=f"{board_key} @ {temperature_c:.0f}C",
)

# --- A rendered figure, auto-converted into an interactive companion -------
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9, 3.5))
ax1.plot(df["time"], signal)
ax1.set_title("Signal"); ax1.set_xlabel("Time (s)")
ax2.hist(noise, bins=30)
ax2.set_title("Noise distribution")
braven.upload(fig, f"{board_key}_{temperature_c:.0f}C_summary.png")
```

## 3. What shows up in the app

<Steps>
  <Step title="Experiments">
    Four experiments — one per file — each with a `temperature_c` Config value, a `row_count` Summary value, a two-panel Figure in its Images tab, and a `signal_vs_time` Series.
  </Step>

  <Step title="Devices">
    Two devices, `S1` and `S2` (type **Read-out board**), each accumulating an `snr` history across every temperature it's been run at — no manual linking step, because the script tagged them with `braven.device(board_key)`.
  </Step>

  <Step title="Analysis">
    Mark all four experiments visible, open Analysis, and ctrl+click each board's `signal_vs_time` series to build one chart with all four curves overlaid — instantly comparable across board and temperature. See [Analyze and compare](/guides/analyze-and-compare).
  </Step>

  <Step title="Reports">
    Once the comparison says what you want it to say, save it as a Report — a live KPI plot segment keeps referencing the same experiments, so it stays current if you add a `70C` run later. See [Reports](/guides/reports).
  </Step>
</Steps>

## Why this example uses `device()` instead of encoding the board into every key name

Compare `board.log_summary("snr", ...)` against the alternative of writing `braven.log_summary("snr_S1", ...)` per board. The device-scoped version keeps the metric name identical (`"snr"`) across every board — the device is a separate coordinate, not a suffix — which is what makes it possible to later query or plot "SNR across boards" as one consistent field instead of parsing it back out of ad-hoc key names.
