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
6 changes: 1 addition & 5 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v5
Expand All @@ -46,9 +44,7 @@ jobs:

# autodoc imports the compiled module, so the Python API page cannot drift from the bindings
- name: Install camera_interface
run: |
pip install . \
--config-settings=cmake.define.INSTRUMENT=hispec_tracking_camera
run: pip install .

- name: Install documentation toolchain
run: pip install -r docs/requirements.txt
Expand Down
198 changes: 5 additions & 193 deletions .github/workflows/emulator-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,123 +7,12 @@ on:
branches: [ "main" ]

jobs:
frame-outputs-emulator-test:
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libccfits-dev libcfitsio-dev libcurl4-openssl-dev \
nlohmann-json3-dev libzmq3-dev \
libboost-thread-dev libboost-chrono-dev

- name: Build and install zmqpp from source
run: |
git clone --depth 1 https://github.com/zeromq/zmqpp.git /tmp/zmqpp
cd /tmp/zmqpp
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig

- name: Build and install ImageStreamIO from source
run: |
git clone --depth 1 https://github.com/milk-org/ImageStreamIO.git /tmp/ImageStreamIO
cd /tmp/ImageStreamIO
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig

- name: Build camerad, emulator, socksend, shm_reader
run: |
mkdir -p ${{github.workspace}}/build
cd ${{github.workspace}}/build
cmake -DCONTROLLER=archon -DINSTRUMENT=hispec_tracking_camera \
-DENABLE_SHM_OUTPUT=ON -DImageStreamIO_DIR=/usr/local/lib/cmake ..
make camerad emulator socksend shm_reader -j$(nproc)

- name: SHM + FITS frame outputs test
run: |
mkdir -p /tmp/ci_milk_shm /tmp/ci_fits_test

bin/camerad-emulator config/frame_outputs_test/frame_outputs_test.cfg -i generic &
sleep 2
bin/camerad --foreground --config config/frame_outputs_test/frame_outputs_test.cfg &
sleep 3

send() { bin/camerad-socksend -p 3131 -t 60 "$1"; }

send "open"
send "load"
send "power on"

# This cfg sets no LONGEXPOSURE, so a bare argument is sec; an explicit
# unit has to override that
send "exptime 1500 ms" | grep -q "^1.500" || { echo "unit suffix ignored"; exit 1; }

send "exptime 1.5"
resp=$(send "expose 1")
echo "expose -> $resp"
echo "$resp" | grep -q "DONE" || exit 1

# DONE only means camerad accepted the command, not that the writers
# succeeded -- shm_reader's exit code and the FITS headers are the
# real pass/fail signal
sleep 1
bin/camerad-shm-reader ci_frame_outputs_shm /tmp/ci_milk_shm
python3 python/tests/fits_header_check.py \
/tmp/ci_fits_test/ci_frame_outputs_*.fits --exptime 1.5

image_size() {
bin/camerad-shm-reader ci_frame_outputs_shm /tmp/ci_milk_shm \
| grep -o 'size=[0-9]*x[0-9]*' | head -1
}
before=$(image_size)

# read must refuse to fetch until capture is actually enabled
send "raw read" | grep -q "ERROR" || { echo "raw read ran with RAWENABLE=0"; exit 1; }

# The Archon captures raw alongside the frame, so enabling it has to
# precede the exposure it should appear in
send "raw set RAWENABLE 1"
resp=$(send "expose 1")
echo "expose -> $resp"
echo "$resp" | grep -q "DONE" || exit 1

resp=$(send "raw read")
echo "raw read -> $resp"
echo "$resp" | grep -q "DONE" || exit 1
sleep 1

# RAW has its own geometry, so it has to land in its own outputs rather
# than collide with the image file or resize the image's SHM stream
bin/camerad-shm-reader ci_frame_outputs_shm_raw /tmp/ci_milk_shm
ls /tmp/ci_fits_test/ci_frame_outputs_*_raw.fits

after=$(image_size)
test "$before" = "$after" || { echo "image stream changed: $before -> $after"; exit 1; }

pkill -f 'bin/camerad' || true
pkill -f 'bin/camerad-emulator' || true

python-module-emulator-test:
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Install dependencies
run: |
Expand Down Expand Up @@ -159,7 +48,7 @@ jobs:
run: |
mkdir -p ${{github.workspace}}/build
cd ${{github.workspace}}/build
cmake -DCONTROLLER=archon -DINSTRUMENT=hispec_tracking_camera \
cmake -DCONTROLLER=archon \
-DENABLE_SHM_OUTPUT=ON -DImageStreamIO_DIR=/usr/local/lib/cmake \
-DBUILD_PYTHON_MODULE=ON ..
make -j$(nproc)
Expand All @@ -175,7 +64,9 @@ jobs:
# asserts both writers itself since the SHM segment does not outlive it
PYTHONPATH=lib python3 python/tests/emulator_integration.py \
--config config/frame_outputs_test/frame_outputs_test.cfg \
--fits-dir /tmp/ci_fits_test
--fits-dir /tmp/ci_fits_test \
--shm-dir /tmp/ci_milk_shm \
--shm-segment ci_frame_outputs_shm

pkill -f 'bin/camerad-emulator' || true

Expand All @@ -193,85 +84,6 @@ jobs:
PYTHONPATH=/tmp/camerad-prefix/lib python3 - <<'PY'
import camera_interface as ci
assert ci.__file__.startswith("/tmp/camerad-prefix/lib/"), ci.__file__
assert ci.instrument_name() == "hispec_tracking_camera", ci.instrument_name()
assert ci.instrument_name() == "none", ci.instrument_name()
print("imported", ci.__file__)
PY

cryoscope-emulator-test:
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libccfits-dev libcfitsio-dev libcurl4-openssl-dev \
nlohmann-json3-dev libzmq3-dev \
libboost-thread-dev libboost-chrono-dev

- name: Build and install zmqpp from source
run: |
git clone --depth 1 https://github.com/zeromq/zmqpp.git /tmp/zmqpp
cd /tmp/zmqpp
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig

- name: Build camerad and emulator
run: |
mkdir -p ${{github.workspace}}/build
cd ${{github.workspace}}/build
cmake -DCONTROLLER=archon -DINSTR=hispec_tracking_camera -DDETECTOR_TYPE=Hxrg ..
make camerad emulator socksend -j$(nproc)

- name: CryoScope synthetic test
run: |
bin/camerad-emulator config/cryoscope/cryoscope.cfg -i generic &
sleep 2
bin/camerad --foreground --config config/cryoscope/cryoscope.cfg &
sleep 3

send() { bin/camerad-socksend -p 3031 -t 60 "$1"; }

send "open"
send "load"
send "power on"
send "exptime 0.1"
resp=$(send "expose 1")
echo "expose -> $resp"
echo "$resp" | grep -q "DONE" || exit 1

pkill -f 'bin/camerad' || true
pkill -f 'bin/camerad-emulator' || true
sleep 1

- name: CryoScope FITS playback test
run: |
cp config/cryoscope/cryoscope.cfg /tmp/cryoscope_fits_test.cfg
echo "EMULATOR_DATADIR=config/cryoscope" >> /tmp/cryoscope_fits_test.cfg

bin/camerad-emulator /tmp/cryoscope_fits_test.cfg -i generic &
sleep 2
bin/camerad --foreground --config /tmp/cryoscope_fits_test.cfg &
sleep 3

send() { bin/camerad-socksend -p 3031 -t 60 "$1"; }

send "open"
send "load"
send "power on"
send "mode VIDEORXR"
send "exptime 0.1"
resp=$(send "expose 1")
echo "expose -> $resp"
echo "$resp" | grep -q "DONE" || exit 1

pkill -f 'bin/camerad' || true
pkill -f 'bin/camerad-emulator' || true
70 changes: 0 additions & 70 deletions .github/workflows/update-submodules.yml

This file was deleted.

3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,3 @@
[submodule "camerad/Instruments/hispec"]
path = camerad/Instruments/hispec
url = https://github.com/CaltechOpticalObservatories/hispec-instrument.git
[submodule "camerad/Instruments/lris2"]
path = camerad/Instruments/lris2
url = https://github.com/CaltechOpticalObservatories/lris2-camerad-instrument.git
1 change: 0 additions & 1 deletion camerad/Instruments/lris2
Submodule lris2 deleted from a8d637
2 changes: 1 addition & 1 deletion config/bias_test/bias_test.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ASYNCGROUP=none

ARCHON_IP=localhost
ARCHON_PORT=3132
DEFAULT_FIRMWARE=camerad/Instruments/hispec_tracking_camera/config/hispecatc.acf
DEFAULT_FIRMWARE=config/demo/demo.acf
EXPOSE_PARAM=Expose
ABORT_PARAM=abort
EXPTIME_MSEC_PARAM=exptime
Expand Down
2 changes: 1 addition & 1 deletion config/frame_outputs_test/frame_outputs_test.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ASYNCGROUP=none

ARCHON_IP=localhost
ARCHON_PORT=3132
DEFAULT_FIRMWARE=camerad/Instruments/hispec_tracking_camera/config/hispecatc.acf
DEFAULT_FIRMWARE=config/demo/demo.acf
EXPOSE_PARAM=Expose
ABORT_PARAM=abort
EXPTIME_MSEC_PARAM=exptime
Expand Down
13 changes: 11 additions & 2 deletions docs/_ext/camerad_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,10 @@ def _balanced_body(text: str, open_index: int) -> str:

@cache
def load_fits_keywords() -> list[FitsKeyword]:
text = _read(str(ATC_DICTIONARY.relative_to(REPO_ROOT)))
# Instruments live in their own repositories, so this source is often absent
if not ATC_DICTIONARY.is_file():
return []
text = ATC_DICTIONARY.read_text(encoding="utf-8")
block = _balanced_body(text, text.index("dictionary = {") + len("dictionary = "))

keywords = []
Expand Down Expand Up @@ -369,8 +372,14 @@ class CameradFitsKeywords(_TableDirective):
option_spec = {"widths": str}

def run(self) -> list[nodes.Node]:
keywords = load_fits_keywords()
if not keywords:
return [nodes.note("", nodes.paragraph(
text="This instrument's sources are not in this checkout, so its FITS "
"header dictionary cannot be listed here."))]

rows = []
for entry in load_fits_keywords():
for entry in keywords:
default = entry.default_atc or entry.default_spec
comment = entry.comment
if entry.enum_values:
Expand Down
Loading
Loading