# czipeak 🔬

Peek into Zeiss CZI files — temporal and Z-stack metadata at a glance.
Part of the code is built with Claude Sonnet 4.6.
Example files are aquired at 
Caltech Biological Imaging Facility - Beckman Institute.

## Install

```bash
pip install czipeak
```

**Optional**: install `aicspylibczi` for faster CZI reading (preferred when available):

```bash
pip install czipeak[aics]
```

## Command-line

```bash
czipeak  path/to/file.czi

# verbose — print every per-frame timestamp (if present in file)
czipeak  path/to/file.czi  --verbose

# export timestamps to CSV (auto-named next to the file)
czipeak  path/to/file.czi  --csv
czipeak  path/to/file.czi  --csv  my_output.csv
```

### Example — 3-tile timelapse, no Z

```
────────────────────────────────────────────────────────────
  czipeak  —  CZI Metadata Inspector
────────────────────────────────────────────────────────────
  File                         Experiment-49.czi
  Size on disk                 8714.90 MB
  Axes                         STCYX0  shape=(3, 239, 1, ...)

────────────────────────────────────────────────────────────
  Temporal Analysis
────────────────────────────────────────────────────────────
  Time points (T)              239
  Tiles (scenes)               3
  Total acquisition time       9 h 56 min 42 s
  Δt  (actual mean)            150.43 s  =  2.507 min
  Frame rate                   0.00665 fps
```

### Example — Z-stack

```
────────────────────────────────────────────────────────────
  Z-Stack Info
────────────────────────────────────────────────────────────
  Z slices                     7
  dz  (step size)              0.8300 µm
  Z start                      -2.4900 µm
  Z end                         2.4900 µm
  Z range (total)               4.9800 µm
```

## Python API

```python
from czipeak import read_czi

meta = read_czi("path/to/file.czi")

# Temporal
print(meta.t_count)           # number of time points
print(meta.dt_actual_s)       # mean Δt in seconds
print(meta.total_duration_s)  # total acquisition time in seconds
print(meta.t_start)           # datetime (UTC)
print(meta.t_stop)            # datetime (UTC)

# Z-stack (None if no Z axis)
print(meta.z_count)           # number of Z slices
print(meta.dz_um)             # step size in µm
print(meta.z_start_um)        # first plane in µm
print(meta.z_end_um)          # last plane in µm
print(meta.z_range_um)        # total Z span in µm

# Tiles / scenes
print(meta.s_count)           # number of tiles
for sc in meta.scenes:
    print(sc["name"], sc["center"])

# Channels
for ch in meta.channels:
    print(ch["name"], ch["fluor"], ch["ex_nm"], ch["em_nm"])

# Pixel size
print(meta.dx_um, meta.dy_um)  # XY pixel size in µm
print(meta.magnification)       # e.g. "20"
```

## `CziMetadata` fields

| Field | Type | Description |
|---|---|---|
| `t_count` | `int` | Number of time points |
| `dt_actual_s` | `float` | Mean Δt (s), from stop − start ÷ (T−1) |
| `total_duration_s` | `float` | Total acquisition time (s) |
| `t_start` / `t_stop` | `datetime` | UTC start and last-frame times |
| `z_count` | `int` or `None` | Number of Z slices |
| `dz_um` | `float` or `None` | Z step size (µm) |
| `z_start_um` | `float` or `None` | First Z plane (µm) |
| `z_end_um` | `float` or `None` | Last Z plane (µm) |
| `z_range_um` | `float` or `None` | Total Z span (µm) |
| `s_count` | `int` or `None` | Number of tiles / scenes |
| `scenes` | `list[dict]` | Scene name + center position |
| `dx_um` / `dy_um` | `float` or `None` | XY pixel size (µm) |
| `magnification` | `str` or `None` | Objective magnification |
| `channels` | `list[dict]` | Name, fluor, ex/em wavelengths |
