feat(prepro): Add deacon#6876
Conversation
Partly resolves #6758 Currently, user-submitted data are not read in by the nextclade preprocessing pipeline, causing them to be dropped form the submission process. Since we're now working to implement file sharing on Loculus, we need to make it so user-submitted files make it through the preprocessing pipeline as well. This PR makes it so user-submitted files are forwarded through the nextclade pipeline without any processing or checking of file contents. Future PRs will add functionality to, for example, check for host sequences in submitted raw reads. - `parse_ndjson` now also parses the file related information sent to preprocessing by the backend - `UnprocessedData` and `UnprocessedAfterNextclade` both get a `files` attribute - test factories in `factory_methods.py` can now be given files to add to test objects, also added a test case in `test_nextclade_preprocessing.py` that carries file information I created a preview to test whether files now make it through the nextclade pipeline. When I submit sequences to the preview with attached raw reads, this file now appears in the submission review page: <img width="1594" height="581" alt="grafik" src="https://github.com/user-attachments/assets/45a2c3a7-ef9a-4738-aec7-be8ef5717a1b" /> And also on the sequence details page after the sequence is released: <img width="1124" height="595" alt="grafik" src="https://github.com/user-attachments/assets/578e16c0-6f0e-4e9b-b5e2-2c544b826086" /> One thing I ran in to when implementing this is that you need to add file categories two times in the config: one time under `submissionDataTypes` (file categories that users are allowed to submit) and then again under a top-level `files` field (files accepted as outputs of prepro pipelines): ``` defaultOrganismConfig: &defaultOrganismConfig schema: &schema submissionDataTypes: &defaultSubmissionDataTypes consensusSequences: true maxSequencesPerEntry: 1 files: enabled: true categories: - name: raw_reads displayName: Raw reads ... files: - name: annotations displayName: Annotations - name: raw_reads displayName: Raw reads ``` Would it be nicer to always allow file categories listed under `submissionDataTypes.files` to be output but prepro? Or will we ever have cases where users submit one thing, prepro processes it, and then outputs another filetype? Probably safest to keep as-is for now but just wanted to flag since not doing this properly got me into a weird state where submissions stay in 'processing' indefinitely but never error because the backend doesn't accept the preprocessing output (it only logs errors in the backend). ~- [ ] All necessary documentation has been adapted.~ - [x] The implemented feature is covered by appropriate, automated tests. - [x] Any manual testing that has been done is documented (i.e. what exactly was tested?) 🚀 Preview: https://pass-files-through.loculus.org
Partially resolves #6758 This PR adds general functionality to validate user-submitted files in the nextclade preprocessing pipeline. How files are processed is determined based on the `FileCategory` and a simple switch statement. The PR introduces a function to validate a submission of raw sequencing reads as a first use case: ```python def validate_raw_reads_submission( files: list[FileIdAndName], ) -> tuple[list[ProcessingAnnotation], list[ProcessingAnnotation]]: ``` The validation is very basic for the moment, and only considers the number of submitted files and their files extensions. This could be built out in the future to include more robust checks. ## Alternative approaches Rather than having a switch statement on `FileCategory` in prepro to determine how different files are processed, we could define this in the `values.yaml`, similar to how we do for metadata fields. E.g.: ```yaml submissionDataTypes: files: enabled: true categories: - name: raw_reads displayName: Raw reads preprocessing: function: validate_raw_reads_submission ... ``` I decided against this for now to get a working version with a minimal diff, but I would be happy to implement this if people feel it's better. ### PR Checklist - [x] All necessary documentation has been adapted. - [x] The implemented feature is covered by appropriate, automated tests. - [ ] Any manual testing that has been done is documented (i.e. what exactly was tested?) 🚀 Preview: https://simple-fq-validation.loculus.org
|
@claude review |
|
Claude finished @maverbiest's task in 4m 0s —— View job Claude finished reviewing
CI is green (preprocessing-tests, which includes ruff + pytest, passed), so this is a design/logic-level review rather than a lint/test-failure review. Findings1. Debug-only preview overrides are still in the diff 2. Possible race between starting the Deacon server and using it 3. Only 4. Duplicated “magic” Deacon index identifiers 5. Minor: raw-reads-pipeline coverage moved out of Nits
Overall this is solid, well-tested work — the new |
|
|
||
| # Preview only: run just the west-nile preprocessing pipeline while testing the deacon | ||
| # host-depletion step. Each enabled organism runs its own prepro pod and fetches the | ||
| # ~3.1Gi panhuman index, so disabling the rest keeps startup and memory manageable. | ||
| # Deep-merges `enabled: false` onto the base defaultOrganisms entries. | ||
| defaultOrganisms: | ||
| cchf: | ||
| enabled: false | ||
| cchf-multi-ref: | ||
| enabled: false | ||
| dummy-organism: | ||
| enabled: false | ||
| dummy-organism-with-files: | ||
| enabled: false | ||
| ebola-sudan: | ||
| enabled: false | ||
| enteroviruses: | ||
| enabled: false | ||
| not-aligned-organism: | ||
| enabled: false |
There was a problem hiding this comment.
This would disable all preview organisms but west nile, which we don't want.
So needs to be reverted before going on main
| "type": "string", | ||
| "description": "Minimizer used for nextclade sort (if require_nextclade_sort_match or if segments are to be assigned using nextclade sort)" | ||
| }, | ||
| "deacon_max_host_proportion": { |
There was a problem hiding this comment.
we probably need to configure two thresholds.
- Which percentage of reads are flagged
- How many bp are flagged
|
|
||
|
|
||
| @dataclass | ||
| class DeaconSummary: |
There was a problem hiding this comment.
its also important to know how many bp were flagged
|
|
||
|
|
||
| @pytest.fixture | ||
| def mock_deacon(monkeypatch): |
There was a problem hiding this comment.
It might actually be good to create a little deacon index and example raw reads for testing. We also do that with nextclade as I noticed if we dont actually run nextclade in tests we miss things
Partially resolves #6758
Summary
This PR incorporates Deacon into the preprocessing pipeline. Deacon is used to check submitted raw reads files for host contamination and rejects files where the proportion of raw reads above a threshold configured via
preprocessing.configFile.deacon_max_host_proportionin the values.yaml.Details
FileIdAndName->FileIdAndNameAndReadUrl(same as the backend type). This is because prepro now needs to download raw reads from S3 so it needs the URLspanhuman-1.k31w15.idxthat's needed for host depletionDeaconSummary. This information is used for deciding to reject a file or notManual testing
I monitored the prepro logs in Grafana to confirm that:
I also started a preview to check that:
Here, the first submission has file
ERR17072040.fastq.gz, which is just west-nile sequences. The second submission (with the error) has the same file where I added 10000 reads sourced from the human reference genome:When the sequence is released, the raw reads file is accessible on the sequence details page:
PR Checklist
- [ ] All necessary documentation has been adapted.-> will be added in #6760🚀 Preview: Add
previewlabel to enable