Skip to content

Commit a1cc58d

Browse files
authored
Merge pull request #78 from UCLOrengoGroup/dev
Merging dev features before release
2 parents 62ca600 + e3be00b commit a1cc58d

28 files changed

Lines changed: 1554 additions & 162 deletions

.github/workflows/build-test-push.yml

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# build docker images from docker compose and push to docker hub
2-
32
name: Build, Test, and Push Docker Compose Images
43
on:
54
push:
@@ -9,6 +8,7 @@ on:
98
pull_request:
109
branches:
1110
- main
11+
- dev
1212
release:
1313
types:
1414
- published
@@ -17,7 +17,70 @@ permissions:
1717
packages: write
1818

1919
jobs:
20-
build:
20+
test:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v4
25+
26+
- name: Set up Java (for Nextflow)
27+
uses: actions/setup-java@v4
28+
with:
29+
distribution: temurin
30+
java-version: "21"
31+
32+
- name: Install Nextflow
33+
run: |
34+
curl -s https://get.nextflow.io | bash
35+
sudo mv nextflow /usr/local/bin/nextflow
36+
nextflow -version
37+
38+
- name: Install nf-test
39+
run: |
40+
curl -fsSL https://get.nf-test.com | bash
41+
sudo mv nf-test /usr/local/bin/nf-test
42+
nf-test version
43+
44+
- name: Build docker images for tests (amd64 only)
45+
run: |
46+
docker compose version
47+
docker compose build
48+
49+
- name: Tag local images for Nextflow test run
50+
run: |
51+
set -euxo pipefail
52+
TEST_TAG=ci-local
53+
docker tag domain-annotation-pipeline-cath-af-cli ghcr.io/uclorengogroup/domain-annotation-pipeline-cath-af-cli:${TEST_TAG}
54+
docker tag domain-annotation-pipeline-script ghcr.io/uclorengogroup/domain-annotation-pipeline-script:${TEST_TAG}
55+
docker tag domain-annotation-pipeline-ted-tools ghcr.io/uclorengogroup/domain-annotation-pipeline-ted-tools:${TEST_TAG}
56+
docker tag domain-annotation-pipeline-foldseek ghcr.io/uclorengogroup/domain-annotation-pipeline-foldseek:${TEST_TAG}
57+
58+
- name: Run test
59+
env:
60+
NXF_ANSI_LOG: "false"
61+
CONTAINER_TAG_NAME: ci-local
62+
NFT_DIFF_ARGS: "-u -U 5"
63+
run: |
64+
set -euxo pipefail
65+
nf-test test --profile +docker --ci
66+
67+
- name: Upload nf-test artifacts on failure
68+
if: failure()
69+
uses: actions/upload-artifact@v4
70+
with:
71+
name: nf-test-failure-${{ github.run_id }}-${{ github.run_attempt }}
72+
path: |
73+
.nf-test/tests/*/output
74+
.nf-test/tests/*/reports
75+
.nf-test/tests/*/meta
76+
.nextflow.log
77+
include-hidden-files: true
78+
if-no-files-found: warn
79+
retention-days: 7
80+
81+
push-images:
82+
needs: test
83+
if: github.event_name != 'pull_request'
2184
runs-on: ubuntu-latest
2285
steps:
2386
- name: Checkout repository
@@ -36,7 +99,7 @@ jobs:
3699
- name: Set up Docker Buildx
37100
uses: docker/setup-buildx-action@v3
38101

39-
- name: Build and push SGE-compatible images to GHCR (linux/amd64)
102+
- name: Build and push amd64 and arm64 images to GHCR
40103
env:
41104
GH_OWNER: ${{ github.repository_owner }}
42105
GIT_SHA: ${{ github.sha }}
@@ -54,23 +117,39 @@ jobs:
54117
echo "Building and pushing ${service} for linux/amd64..."
55118
IMAGE_BASE=ghcr.io/${OWNER_LOWER}/domain-annotation-pipeline-${service}
56119
57-
TAG_ARGS=(
120+
AMD64_TAG_ARGS=(
58121
--tag ${IMAGE_BASE}:sha-${GIT_SHA:0:8}
59122
--tag ${IMAGE_BASE}:linux-amd64-${DATE_TAG}
60123
--tag ${IMAGE_BASE}:${BRANCH_TAG}-latest
61124
--tag ${IMAGE_BASE}:linux-amd64-latest
62125
)
63126
127+
ARM64_TAG_ARGS=(
128+
--tag ${IMAGE_BASE}:sha-${GIT_SHA:0:8}-arm64
129+
--tag ${IMAGE_BASE}:linux-arm64-${DATE_TAG}
130+
--tag ${IMAGE_BASE}:${BRANCH_TAG}-arm64-latest
131+
--tag ${IMAGE_BASE}:linux-arm64-latest
132+
)
133+
64134
if [[ "${GITHUB_EVENT_NAME}" == "release" && -n "${RELEASE_TAG:-}" ]]; then
65135
RELEASE_TAG_SANITIZED=$(echo "${RELEASE_TAG}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9._-]/-/g')
66-
TAG_ARGS+=(--tag ${IMAGE_BASE}:${RELEASE_TAG_SANITIZED})
136+
AMD64_TAG_ARGS+=(--tag ${IMAGE_BASE}:${RELEASE_TAG_SANITIZED})
137+
ARM64_TAG_ARGS+=(--tag ${IMAGE_BASE}:${RELEASE_TAG_SANITIZED}-arm64)
67138
fi
68139
69140
docker buildx build \
70141
--platform linux/amd64 \
71-
"${TAG_ARGS[@]}" \
142+
"${AMD64_TAG_ARGS[@]}" \
72143
--push \
73144
docker/${service}
145+
146+
echo "Building and pushing ${service} for linux/arm64..."
147+
docker buildx build \
148+
--platform linux/arm64 \
149+
"${ARM64_TAG_ARGS[@]}" \
150+
--push \
151+
docker/${service}
152+
74153
docker buildx rm || true
75154
done
76155

.github/workflows/test-pipeline.yml

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name: Pipeline test (30 TED test IDs)
33

44
on:
5-
push:
5+
workflow_dispatch:
66

77
jobs:
88
test:
@@ -22,24 +22,40 @@ jobs:
2222
run: |
2323
curl -s https://get.nextflow.io | bash
2424
sudo mv nextflow /usr/local/bin/nextflow
25-
nextflow -version
25+
nextflow version
26+
27+
- name: Install nf-test
28+
run: |
29+
curl -fsSL https://get.nf-test.com | bash
30+
sudo mv nf-test /usr/local/bin/nf-test
31+
nf-test -version
2632
2733
- name: Build docker images for tests (temporary until GHCR default)
2834
run: |
2935
docker compose version
3036
docker compose build
3137
32-
- name: Run pipeline (docker,git_actions_test)
38+
- name: Run test
3339
env:
3440
NXF_ANSI_LOG: "false"
41+
NFT_DIFF_ARGS: "-u -U 5"
3542
run: |
3643
set -euxo pipefail
37-
rm -rf work .nextflow* results/git_actions_test || true
38-
nextflow run workflows/annotate.nf -profile docker,git_actions_test
44+
nf-test test --profile +docker --ci
45+
46+
- name: Upload nf-test artifacts on failure
47+
if: failure()
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: nf-test-failure-${{ github.run_id }}-${{ github.run_attempt }}
51+
path: |
52+
.nf-test/tests/*/output
53+
.nf-test/tests/*/reports
54+
.nf-test/tests/*/meta
55+
.nextflow.log
56+
include-hidden-files: true
57+
if-no-files-found: warn
58+
retention-days: 7
3959

40-
- name: Compare final_results.tsv to expected
41-
run: |
42-
set -euxo pipefail
43-
diff -U 0 <(sort assets/test_ids/final_results.tsv) <(sort results/git_actions_test/final_results.tsv)
4460

4561

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
tools/
33
domain_assignments*.tsv
44
results/
5+
reports/
56
# nextflow
67
.nextflow/
78
work/
@@ -117,6 +118,8 @@ repo-key.pub
117118
.nextflow/
118119
work/
119120
.nextflow.log*
121+
.nf-test/
122+
nf-test
120123

121124
# local build dir
122125
domain_assignments*.tsv
@@ -126,3 +129,5 @@ assets/uniprot_ids_100.csv
126129
assets/uniprot_1000.txt
127130
assets/bfvd.zip
128131
foldseek/assets/
132+
133+

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
This file records major behavioural and configuration changes.
44

5+
## 2026-07-10 (Chris Wyatt) — Config restructure & composable profiles
6+
- New `conf/base.config` (always loaded): a universal per-process resource floor (`cpus=1`, `memory=2.GB*attempt`) so every module has a baseline, plus a correctness fix pinning the chunk producers (`chunk_ids_by_zip`/`light_chunk_consensus_by_zip`) to `scratch=false` — node-local scratch was deleting their mapping-file outputs and breaking `filter_pdb_from_zip`/`chop_pdb_from_zip`.
7+
- Per-process HPC resource ladders / retries remain in `conf/singularity.config` (HPC runs use singularity).
8+
- Profiles are now composable: added a standalone `container` profile; `cs_cluster` is generic + label-aware (requests `gpu=true` for `sge_gpu_high`, `avx2=yes` for foldseek) and runs on shared `/SAN` (`scratch=false`); `orengo` restored as a composable profile for backward compatibility. Compose e.g. `-profile <data>,singularity,cs_cluster`.
9+
- `cs_cluster` Singularity image cache now honours `NXF_SINGULARITY_CACHEDIR` (falls back to `$HOME/.apptainer/pull`); removed the unused `singularity_image_dir` param.
10+
- Added `test_154` profile: 154-id TED test set read from a public S3 bucket `s3://excon/protein-domain-annotation/zip/` using anonymous access (`aws.client.anonymous`) — no AWS login needed.
11+
12+
## 2026-06-22 (Chris Wyatt) — TED segmentation concurrency
13+
- Split `run_ted_segmentation` into three modules so Chainsaw runs concurrently with the Merizo→UniDoc chain (Chainsaw is independent; UniDoc inherits Merizo's chopping). New modules: `run_ted_merizo_unidoc` and `run_ted_chainsaw` (both GPU), and `run_ted_consensus` (CPU, `sge_low`) which joins the three choppings by `chunk_id` and computes consensus.
14+
- Cuts this step's wall time to roughly `max(merizo+unidoc, chainsaw) + consensus`, at the cost of two GPU slots per chunk. Pipeline outputs are unchanged; the original `modules/run_ted_segmentation.nf` is retained but no longer used.
15+
16+
## 2026-06-22 (Chris Wyatt)
17+
- Updated for Nextflow 25.10+/26 (see README). Fixed `--chunk_size` which broke under v26 (now coerced to an integer before validation).
18+
- Execution reports (timeline, report, trace, DAG) are now generated automatically into a timestamped `reports/` folder — no need to pass `-with-timeline`/`-with-report`/`-with-trace`.
19+
520
## 2025-10-31 (Nick Edmunds)
621
- Added this changelog to track key updates.
722
- To run on the server must include a link to: -c /SAN/orengolab/bfvd/code/domain-annotation-pipeline/nextflow.config

README.md

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pip install --upgrade pip
1616
pip install nextflow
1717
```
1818

19+
**Nextflow version:** use **25.10 or newer** (tested with 25.10.3 and 26.04.4). These releases use Nextflow's strict (v2) config parser, which `nextflow.config` is written for. If `pip install nextflow` gives you an older release, set the version explicitly, e.g. `NXF_VER=26.04.4 nextflow run ...`.
20+
1921
Install Docker
2022
https://docs.docker.com/compose/install/
2123

@@ -34,6 +36,46 @@ Note: either docker or singularity must be supplied as one the the profile argum
3436
nextflow run workflows/annotate.nf -profile debug,docker
3537
```
3638

39+
### Profiles
40+
41+
Runs are configured by composing profiles with `-profile a,b,c`: pick **one container engine**, add a **cluster** profile on HPC, and a **data/mode** profile for the inputs.
42+
43+
| Group | Profiles | Sets |
44+
|-------|----------|------|
45+
| Container engine *(pick one)* | `docker`, `singularity` | how containers run (also loads the `/app` script paths) |
46+
| Cluster *(optional, HPC/SGE)* | `cs_cluster`, `myriad_cluster`, `orengo` | executor + submit options (scratch, GPU, avx2) |
47+
| Data / mode | `debug`, `benchmark_test`, `stub_run`, `test_154`, … | test inputs / run parameters |
48+
49+
A basic resource floor for every process lives in `conf/base.config` (always applied). The fuller per-process memory/retry ladders are HPC settings in `conf/singularity.config`, so they apply when you include the `singularity` profile — hence `-profile singularity,<cluster>` for real HPC jobs. (`container` is also available as a standalone profile: script paths only, for composing with a self-contained cluster profile such as `orengo`.)
50+
51+
```bash
52+
# Local, Docker, bundled test data
53+
nextflow run workflows/annotate.nf -profile debug,docker
54+
55+
# UCL CS cluster — Singularity, runs on shared /SAN (no node-local scratch)
56+
nextflow run workflows/annotate.nf -profile singularity,cs_cluster --input_zip_dir <dir>
57+
58+
# UCL Myriad cluster
59+
nextflow run workflows/annotate.nf -profile singularity,myriad_cluster --input_zip_dir <dir>
60+
61+
# Orengo-lab CS cluster — node-local scratch, project/avx2/GPU
62+
nextflow run workflows/annotate.nf -profile singularity,orengo --input_zip_dir <dir>
63+
64+
# 154-id TED test set read from a public S3 bucket (no AWS login needed)
65+
nextflow run workflows/annotate.nf -profile test_154,singularity,cs_cluster
66+
```
67+
68+
### Execution reports
69+
70+
Execution timeline, report, trace and DAG files are generated **automatically** on every run — you do **not** need to pass `-with-timeline`, `-with-report`, `-with-trace` or `-with-dag`. They are written to the `reports/` folder (or under `--results_dir` if you set it) and the filenames include a per-launch timestamp, so successive runs never overwrite each other:
71+
72+
```
73+
reports/execution_timeline_<timestamp>.html
74+
reports/execution_report_<timestamp>.html
75+
reports/execution_trace_<timestamp>.txt
76+
reports/pipeline_dag_<timestamp>.html
77+
```
78+
3779
## Preparing data
3880

3981
The pipeline expects two inputs:
@@ -152,6 +194,34 @@ ted_stub_chain_ids.zip
152194

153195
The default files are currently set up to run a test set of 50 chain ids, producing a final results output of 100 domains.
154196

197+
## Automated tests (nf-test)
198+
199+
The pipeline has an [nf-test](https://www.nf-test.com/) (`tests/`) that runs the full `annotate.nf` workflow against the test data located in `./assets/test_ids` and checks the results against a pre-generated snapshot.
200+
201+
Install nf-test:
202+
203+
```bash
204+
curl -fsSL https://get.nf-test.com | bash
205+
```
206+
207+
Move `nf-test` to the `bin` folder in you `$PATH`.
208+
209+
Run the test locally:
210+
211+
```bash
212+
nf-test test --profile +docker
213+
```
214+
215+
If the outputs are consistent with the pre-existing snapshot, the test will succeed.
216+
217+
If a change intentionally alters pipeline outputs, generate a new snapshot with:
218+
219+
```bash
220+
nf-test test --update-snapshot
221+
```
222+
223+
Note: nf-test isn't wired into CI yet — `test-pipeline.yml` and `build-test-push.yml` run the pipeline directly with `-profile docker,git_actions_test` rather than through nf-test. The idea is to replace it the nf-test at some point.
224+
155225
## Running on HPC
156226

157227
## Install (with singularity)
@@ -209,9 +279,10 @@ singularity pull domain-annotation-pipeline-ted-tools_latest.sif docker://ghcr.i
209279
singularity pull domain-annotation-pipeline-foldseek_latest.sif docker://ghcr.io/uclorengogroup/domain-annotation-pipeline-foldseek:main-latest
210280
```
211281

212-
The directory containing these singularity images can be added to your config file, or passed directly to nextflow:
282+
You normally **don't** need to pull these manually — with `-profile singularity`, Nextflow pulls each image into its cache on first run. Control **where** they're stored (and share them across runs and users) with the `NXF_SINGULARITY_CACHEDIR` environment variable:
213283

214284
```bash
215-
nextflow run workflows/annotate -profile singularity \
216-
--singularity_image_dir "/path/to/singularity_images"
285+
export NXF_SINGULARITY_CACHEDIR=/path/to/shared/singularity_cache
217286
```
287+
288+
The `cs_cluster` profile (see below) honours this variable, falling back to `$HOME/.apptainer/pull` when it is unset. (The old `--singularity_image_dir` flag is no longer wired up — set the cache via the environment variable instead.)

assets/test_ids/30-ted-ids.zip

65.6 KB
Binary file not shown.

assets/test_ids/final_results.tsv

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,10 @@ A0A008_01 4579eb972b3c1762bd1d1fec24cfa006 high 57-320 264 1 40 8 9 17 23 11.41
4646
A0A002_01 fa6ce13b0cef05776b985792f9b1b804 med 325-410_462-563 188 2 40 7 10 17 23 11.387 0.285 89.9639 proteome-tax_id-67581-0_v4 Streptomyces viridosporus cellular organisms (no rank), Bacteria (domain), Bacillati (kingdom), Actinomycetota (phylum), Actinomycetes (class), Kitasatosporales (order), Streptomycetaceae (family), Streptomyces (genus) 0.65248 False 2ff7A00 4.1e-19 0.8901 3.40.50.300 H 0.979 0.971 91.05
4747
A0A000_01 150d4a3366dff240048b39a8901f229d high 54-288 235 1 39 13 7 20 19 12.397 0.316 96.88 proteome-tax_id-67581-0_v4 Streptomyces viridosporus cellular organisms (no rank), Bacteria (domain), Bacillati (kingdom), Actinomycetota (phylum), Actinomycetes (class), Kitasatosporales (order), Streptomycetaceae (family), Streptomyces (genus) 0.86546 True 6hrhA01 4.089e-34 0.9761 3.40.640.10 H 0.991 0.951 97.16
4848
A0A000_02 e4bc15472c520f667a60762ee3a889a1 high 290-389 100 1 12 3 3 6 6 11.604 0.296 95.586 proteome-tax_id-67581-0_v4 Streptomyces viridosporus cellular organisms (no rank), Bacteria (domain), Bacillati (kingdom), Actinomycetota (phylum), Actinomycetes (class), Kitasatosporales (order), Streptomycetaceae (family), Streptomyces (genus) 0.9507 True 2bwnB01 7.664e-08 0.8815 3.90.1150.10 H 0.91 0.572 78.05
49+
A0A009E3I5_01 a99a762ce7240ff800352b0b7313200e high 6-30_38-70 58 2 9 1 4 5 4 9.808 0.349 81.7419 0.32405 True 28.97
50+
A0A009E8H7_01 78df653bd15aaf1a1482d4d5dd2291a8 high 9-56 48 1 5 3 0 3 2 10.292 0.309 59.7269 0.63986 True 26.22
51+
A0A009E8H8_01 aefdd5d66a782edd91eca69333dac6e1 high 21-67 47 1 3 2 0 2 1 9.233 0.397 68.0209 0.080558 False 27.25
52+
A0A009E9Q4_01 ea2e0d063dcd92eda724f53107932ee0 high 22-61 40 1 4 3 0 3 1 10.524 0.275 84.638 0.36831 True 2w25A01 0.4087 0.662 1.10.10 T 0.95 0.75 79.33
53+
A0A009E9Q4_02 295fcf62d6729ac7c2531e29752557cb high 93-127 35 1 6 2 2 4 2 9.1 0.312 73.0903 0.032186 True 27.89
54+
A0A009ECM9_01 8609fefdf4edba2fef3cc4d3de0636c5 high 8-66 59 1 9 2 3 5 4 11.552 0.332 90.0792 0.56246 True 4py5A01 0.2214 0.64 3.30.310 T 0.898 0.833 84.16
55+
A0A009ED70_01 04f5a1c5b737ceab8de2af812661cf34 med 2-47 46 1 9 1 3 4 5 9.067 0.324 81.2983 0.52 True 1twfI02 0.3513 0.5461 N 0.913 0.618 53.56

0 commit comments

Comments
 (0)