Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/configuration/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ Keys the server itself reads, independent of the frame outputs.
:::{important}
These tables list only keys the code actually reads. Configuration files in the wild, and the
superseded 2022 ICD, carry a number of keys that nothing reads any more: `IMDIR`, `BASENAME`,
`AUTODIR`, `DIRMODE`, `DAEMON`, `LONGERROR`, `TM_ZONE`, `TZ_ENV`, `ASYNCPORT`, `ASYNCGROUP` and
`START_PARAM` among them. Setting them has no effect. Image naming and location moved to the
`AUTODIR`, `DIRMODE`, `DAEMON`, `LONGERROR`, `TM_ZONE`, `TZ_ENV`, `ASYNCPORT` and `ASYNCGROUP`
among them. Setting them has no effect. Image naming and location moved to the
[frame output keys](frame-outputs.md).

Instrument modules read keys of their own, which are documented with the
[instrument](../instruments/index.md) rather than here.
:::

## Controller connection
Expand Down
30 changes: 27 additions & 3 deletions docs/instruments/cryoscope.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,35 @@ An H2RG on an Archon controller, reading in RXR mode.
Repository: [cryoscope-instrument](https://github.com/CaltechOpticalObservatories/cryoscope-instrument),
checked out at `camerad/Instruments/cryoscope`.

:::{note}
Expands in M4. The module defines a `CryoScope` interface deriving from `ArchonInterface`, with its
own exposure modes, and registers no additional instrument commands beyond the base set.
:::{warning}
This module does not currently build against the core. Its exposure mode instantiates
`ExposureModeTemplate` with two template parameters where the base declares one, and assigns to
`modetype` and `modeargs`, which are named `type` and `args` in
{source}`camerad/exposure_modes.h`. It was left behind by a refactor of the exposure mode base
class.

CI does not catch this, because the build workflow compiles the default target and only builds an
instrument when one is named explicitly.
:::

## What it defines

`CryoScope` derives from `ArchonInterface` and overrides `instrument_cmd`,
`configure_instrument`, `power`, `get_exposure_modes` and `set_exposure_mode`, plus a private
`setup_detector()`.

It registers no instrument-specific commands beyond the base set, and its exposure mode is still a
placeholder named `XXX`.

## Configuration

| Key | Meaning |
|---|---|
| `START_PARAM` | Archon parameter used to start the timing script |

`START_PARAM` is read only by this module, which is why it does not appear in the
[core key tables](../configuration/core.md).

## Build

```bash
Expand Down
123 changes: 97 additions & 26 deletions docs/instruments/hispec-tracking-camera.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
# HISPEC tracking camera

The HISPEC acquisition and tracking camera (ATC): an H2RG on an Archon controller. This is the most
complete instrument module and the one the emulator integration tests exercise.
The HISPEC acquisition and tracking camera (ATC): a 2048x2048 H2RG on an Archon controller. This is
the most complete instrument module and the one the emulator integration tests exercise.

Repository: [hispec-tracking-camera-instrument](https://github.com/CaltechOpticalObservatories/hispec-tracking-camera-instrument),
checked out at `camerad/Instruments/hispec_tracking_camera`.

:::{note}
Expands in M4 with the readout and operational modes, the ROI and guiding geometry rules, and the
full keyword table. What is here is verified against the current submodule.
:::

## Build

```bash
Expand All @@ -21,41 +16,110 @@ make

Shipped configuration is in the submodule's `config/`: `hispecatc.cfg` and `hispecatc.acf`.

## Three things called "mode"

The single most confusing thing about this module is that three unrelated settings are all called a
mode. They are selected by different commands and do different things.

Camera mode (`mode`)
: Names a `[MODE_*]` section of the loaded ACF. Selecting one loads that section's geometry
(`PIXELCOUNT`, `LINECOUNT`), its parameters, and its tapline layout (`TAPLINES`, `TAPLINE0..N`)
into the controller. This is the heavyweight one: it changes the shape of the data coming back.
Requires firmware to already be loaded.

Exposure mode (`exposure`)
: Selects the H2RG readout scheme. Implemented by setting the matching `mode_*` ACF parameter to 1
and every other one to 0, so the ACF must define all four.

| Argument | ACF parameter | Scheme |
|---|---|---|
| `utr_rr` | `mode_UTR_RR` | Up the ramp, reset-read |
| `utr_gr` | `mode_UTR_GR` | Up the ramp, guided read |
| `rx` | `mode_RX` | Reset-execute |
| `rxr` | `mode_RXR` | Reset-execute-read |

Acquisition mode (`exposuremode`)
: The base command, selecting which `Camera::ExposureMode` implementation drives acquisition. This
module provides `DEFAULT` and `AUTOFETCH`. See [architecture](../architecture/index.md) for what
an exposure mode is.

:::{tip}
`exposure` with no argument reports the current readout scheme. `mode` with no argument reports the
current camera mode. Neither changes anything when queried.
:::

## Instrument commands

These are reached through the normal command interface, and from Python via `instrument_cmd()`.
Reached through the normal command interface, and from Python via `instrument_cmd()`.

| Command | Purpose |
|---|---|
| `h2rg_init` | Initialize the H2RG |
| `mode` | Select the readout mode |
| `exposure` | Select the exposure mode |
| `autofetch_mode` | Control autofetch, where the controller pushes frames continuously |
| `freerun` | Continuous acquisition |
| `window_mode` | Windowed readout |
| `roi` | Set the region of interest |
| `h2rg_init` | Re-trigger the H2RG main reset and enable Pad B output with HIGHOHM |
| `mode` | Select or report the camera mode from the ACF |
| `exposure` | Select or report the H2RG readout scheme |
| `exposuremode` | Select the acquisition mode (base command) |
| `autofetch_mode` | Control autofetch, where the controller streams frames continuously |
| `freerun` | Arm (`1`) or disarm (`0`) continuous exposure |
| `window_mode` | Enter or leave windowed readout |
| `roi` | Set or report the region of interest |
| `take_stats` | Report pixel statistics |
| `debug` | Development diagnostics |

`instrument_commands()` enumerates them at runtime, which is the authoritative list for a given
build.
`instrument_commands()` enumerates them at runtime, which is authoritative for a given build.

## Readout modes
:::{note}
`h2rg_init` exists because the ACF defaults `Start` to 1, so it is already true at load time and
never sees the 0 to 1 edge the H2RG main reset needs. Running it after power-up re-triggers that
edge. It is not optional on a cold start.
:::

`mode` selects among the H2RG readout schemes, each backed by an ACF timing mode:
Setting `autofetch_mode` also resets the readout scheme to the default, so select `exposure` after
`autofetch_mode`, not before.

| Mode | ACF timing mode |
## Region of interest

`roi` takes four argument shapes:

| Form | Meaning |
|---|---|
| `utr_rr` | `mode_UTR_RR`, up-the-ramp, reset-read |
| `utr_gr` | `mode_UTR_GR`, up-the-ramp, guided read |
| `rx` | `mode_RX`, reset-execute |
| `rxr` | `mode_RXR`, reset-execute-read |
| `roi` | Report the current window as `vstart vstop hstart hstop` |
| `roi <height> <width>` | A centred region of that size |
| `roi <vstart> <vstop> <hstart> <hstop>` | An explicit region |
| `roi fullframe` | Return to the full 2048x2048 frame |

`window_mode` is the underlying toggle. Leaving window mode restores the saved `TAPLINES` and
`TAPLINE0` values, switches the camera back to the `DEFAULT` ACF mode to reset the internal buffer
geometry, and reapplies that mode's `PIXELCOUNT`. That teardown is why leaving window mode is not
simply the inverse of entering it, and why it needs the ACF to have a `DEFAULT` mode.

## Configuration

Alongside the [core keys](../configuration/index.md), this module reads its own:

| Key | Default | Meaning |
|---|---|---|
| `REFPIX_AMP` | `AM52` | Amplifier reading the reference channel, recorded as `REFPXAMP`. The reference channel's tapline moves with the camera mode; its amplifier does not. |
| `PIXEL_TIME_USEC` | built-in | Pixel time used to model the readout deadline, when the ACF does not supply one |
| `READOUT_MARGIN_MSEC` | built-in | Slack added to the computed per-frame readout deadline |

`PIXEL_TIME_USEC` and `READOUT_MARGIN_MSEC` set how long the acquisition thread waits for a frame
before calling it lost. Both must be positive, and a non-numeric value makes startup fail rather
than silently falling back.

Fixed in `configure_instrument()` rather than configured: the LVDS module is 10 and the detector's
maximum pixel index is 2047. The Archon socket is also tuned there for streaming, with `TCP_NODELAY`
and 1 MB buffers.

:::{warning}
`WRITE_TAPINFO_TO_FITS` appears in the shipped `hispecatc.cfg` but is read by nothing. Setting it
has no effect.
:::

## FITS keywords

The module carries its own keyword dictionary mapping each internal property to a keyword, comment,
type and default. It covers two cameras, ATC and SPEC, with separate defaults; the table below shows
the ATC default, falling back to the SPEC one where ATC has none.
type and default. It covers two cameras, ATC and SPEC, with separate defaults; the table shows the
ATC default, falling back to the SPEC one where ATC has none.

`python/tests/fits_header_check.py` validates a written file against this dictionary.

Expand All @@ -68,3 +132,10 @@ the ATC default, falling back to the SPEC one where ATC has none.
Generated from {source}`camerad/Instruments/hispec_tracking_camera/fits_header_dictionary.cpp`, so
it cannot drift from the dictionary the instrument actually writes.
:::

## Error reporting

Every error this module logs carries a one-line state summary, so a failure records the camera state
that produced it rather than leaving it to be reconstructed from surrounding log lines that a
concurrent command may have interleaved. Callers get a short reason; the log gets the root cause and
the state.
9 changes: 6 additions & 3 deletions docs/instruments/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ submodule is pinned, so a given `camera-interface` commit builds one specific in
| Instrument | Controller | Detector | State |
|---|---|---|---|
| [hispec_tracking_camera](hispec-tracking-camera.md) | Archon | H2RG | In active use. The reference implementation. |
| [cryoscope](cryoscope.md) | Archon | H2RG | Implemented, RXR mode |
| [cryoscope](cryoscope.md) | Archon | H2RG | Scaffolding, and does not currently build |
| `hispec` | Archon | | Repository exists, no sources yet |
| `deimos` | | | Repository exists, no sources yet |

:::{note}
`hispec` and `deimos` are currently README-only submodules. They are listed so the set is not
misleading about what exists; there is nothing to document until they carry sources.
`hispec` and `deimos` are README-only submodules today. They are listed so the set is not misleading
about what exists; there is nothing to document until they carry sources.

Only `hispec_tracking_camera` is built in CI, so the others can fall behind changes to the core
without anything noticing.
:::

```{toctree}
Expand Down
Loading