Skip to content

Curate reference tree: remove recombinant/frameshifted/low-quality sequences#465

Merged
ivan-aksamentov merged 11 commits into
masterfrom
update-cva16
Jul 24, 2026
Merged

Curate reference tree: remove recombinant/frameshifted/low-quality sequences#465
ivan-aksamentov merged 11 commits into
masterfrom
update-cva16

Conversation

@nneune

@nneune nneune commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Manually curated the dataset to improve reference tree quality:

  • Removed recombinant sequences (including several from Xu et al.), keeping only recurring circulating recombinant forms (e.g. a 5'UTR recombinant) rather than singletons, to preserve tree diversity without introducing long branches.
  • Removed frameshifted and other low-quality sequences, but retained frameshifted sequences that show normal evolution and tree topology.
  • Updated CHANGELOG.md to document the curation rationale.

@ivan-aksamentov

ivan-aksamentov commented Jul 21, 2026

Copy link
Copy Markdown
Member

⚠️ AI-generated content below. Verify all claims.

Testing

Try in Nextclade Web:

Science

Taxonomy, genome, and reference [click to expand]

Coxsackievirus A16 (CVA16) belongs to genus Enterovirus, species Enterovirus A, family Picornaviridae -- a positive-sense single-stranded RNA virus and one of the major causative agents of hand, foot, and mouth disease (HFMD) in children.

The CVA16 genome is approximately 7,400 nt and encodes a single polyprotein processed by viral proteases into structural proteins (VP4, VP2, VP3, VP1 in P1) and non-structural proteins (2A-2C in P2, 3A-3D in P3). VP1 is the standard molecular typing target for enteroviruses (Oberste et al., J Clin Microbiol 1999; Chen et al., PLoS ONE 2013).

The dataset uses a Static Inferred Ancestor (SIA) as reference rather than the historical G-10 prototype strain (U05876.1), which diverges substantially from circulating strains. The upstream workflow constructs this ancestor by outgroup-rooting a CVA16 phylogeny, reconstructing the ingroup MRCA, and filling alignment gaps from the prototype reference (inference workflow).

Lineage nomenclature and recombination [click to expand]

CVA16 genotypes are defined by VP1 phylogeny. Chen et al. (2013) established genotypes A (prototype G-10) and B, with B subdivided into B1a, B1b, and B1c. A recent synthesis recognizes genotypes A, B, and D, with B1/B2 under B and B1a/B1b/B1c under B1 (Han et al., Virus Evol 2024). Hassel et al. (2017) identified clade D with intertype recombinant origin.

Whole-genome classifications differ because recombination changes phylogenetic relationships outside VP1. Han et al. identified recombinant forms RF-A through RF-E from the 3D region, while another whole-genome analysis proposed G-a through G-e (Chu et al., Heliyon 2024). Both B1a and B1b contain sequences from other Enterovirus A donors in the 5'UTR and P2/P3 regions (Chen et al., 2013). The dataset's approach of removing singleton recombinants while retaining recurring circulating recombinant forms is standard curation practice.

The upstream workflow explicitly classifies excluded accessions as recombinant outliers, frameshifted sequences, or UTR-associated outliers (curation commit).

Epidemiological context and tree coverage [click to expand]

B1a, B1b, and B1c remain epidemiologically relevant. B1b dominated a long-term mainland China dataset (Han et al., Virus Evol 2020), while B1a predominated among Thai CVA16 sequences through 2022 (Noisumdaeng and Puthavathana, Sci Rep 2023). In Hangzhou, B1c rose sharply during 2024 (Xu et al., Front Microbiol 2025).

The curated tree spans 1997-2025 with 741 tips. Year distribution shows strong representation in 2008-2024, with 2024 having the most tips (111). The 2020 dip (2 tips) reflects reduced surveillance during the COVID-19 pandemic. One 2025 tip (PZ117058) extends coverage to recent circulation.

The dataset is maintained by ENPEN (European Non-Polio Enterovirus Network), with the workflow at enterovirus-phylo/nextclade_a16. All sequence data is from GenBank; no restricted sources are identified.

Blocking issues

Correctness concerns worth addressing before merge.

🔴 H1. Nucleotide mutation labels emptied without documentation [click to expand]

The nucMutLabelMap in pathogen.json was emptied from 3,883 entries to 0 [src]. This map associates nucleotide mutations with clade labels and feeds the privateMutations QC rule, where weightLabeledSubstitutions: 1.5 applies a scoring multiplier to labeled mutations [src].

The generated data_output/index.json continues to advertise mutLabels as a dataset capability despite the empty map [src].

Nextclade uses these maps to label private mutations in the UI and tabular output. Labeled substitutions receive distinct QC weights to flag potential contamination, co-infection, or recombination (mutation-label documentation, private-mutation algorithm).

Effect: all former clade-associated private mutations become unlabeled and receive weight 1 instead of 1.5. User-visible mutation annotations disappear, QC scores change, and the index metadata becomes misleading. Neither the PR description nor the CHANGELOG mention this change.

Fix: regenerate nucMutLabelMap from the curated tree so labels reflect the new topology. If removal is intentional, also remove the weightLabeledSubstitutions configuration and document the user-facing change in the CHANGELOG.

Non-blocking issues

Convention drift and minor inconsistencies. Fix if time allows.

🟡 M1. Broken JSON indentation in pathogen.json [click to expand]

Several sections have inconsistent indentation compared to the base version [src]:

  • aaMutLabelMap and nucMutLabelMap at indent level 2 (should be 4, as children of mutLabels)
  • snpClusters closing brace at indent 2 (should be 4) [src]
  • qc closing brace at indent 0 (should be 2) [src]
  • cdsOrderPreference array collapsed to a single line

Effect: valid JSON, but confusing for future manual edits. Likely artifacts of manual editing after deleting the large nucMutLabelMap block.

Fix: reformat with jq '.' pathogen.json or equivalent.

🟡 M2. Recombinant clade nomenclature lacks explicit mapping [click to expand]

The README states that recombinant forms C-F are "also referred to as B2, B3, and D" [src]. The tree contains clades A, B1, B1a, B1b, B1c, C, D, E, F, and the parent label RFs. Published nomenclatures are not directly interchangeable:

The current text does not establish how dataset clades C-F map to these systems.

Fix: add a compact mapping table giving each dataset clade, the genomic region used to define it, the corresponding published designation, and a defining citation. If C-F are dataset-specific labels, state that explicitly.

🟡 M3. No `meta.bugs` or `meta["source code"]` URLs in pathogen.json [click to expand]

Neither meta.bugs nor meta["source code"] are set. The README provides the workflow URL (https://github.com/enterovirus-phylo/nextclade_a16) and issues link. The sibling EV-D68 dataset also lacks these fields.

Fix: add "meta": { "bugs": "...", "source code": "..." } pointing to the upstream workflow repository.

🔵 L1. "Xu et al." citation not identifiable from CHANGELOG [click to expand]

The CHANGELOG references "Xu et al." without a publication year or title [src]. The upstream workflow's testing file A16_XuQ.csv and excluded accessions (PX448* series) identify this as Qihao Xu's analysis of Hangzhou CVA16 sequences (Xu et al., Front Microbiol 2025).

Fix: replace with "Xu et al. (2025)."

🔵 L2. Trailing whitespace in README [click to expand]

git diff --check reports trailing whitespace on the B1a/B1b/B1c paragraph [src].

Fix: remove trailing space and rebuild generated output.

Clade distribution

9 clades, 783 -> 741 tips [click to expand]
Clade Base Curated Removed Added Delta
A 1 1
B1 39 39
B1a 373 344 ${\color{red}\text{-29}}$ ${\color{red}\text{-29}}$
B1b 242 231 ${\color{red}\text{-12}}$ ${\color{green}\text{+1}}$ ${\color{red}\text{-11}}$
B1c 98 96 ${\color{red}\text{-3}}$ ${\color{green}\text{+1}}$ ${\color{red}\text{-2}}$
C 3 3
D 22 22
E 2 2
F 2 2
Total 783 741 ${\color{red}\text{-44}}$ ${\color{green}\text{+2}}$ ${\color{red}\text{-42}}$

All clades retained. Removals concentrated in B1a and B1b.

Notes

Click to expand
  • Reference representation: both ancestral_sequence (SIA) and prototype U05876 are tree leaves, avoiding runtime placement artifacts.
  • Example panel: 32 example sequences, all non-empty with no N or gap characters. Lengths 891-7,410 nt. 21 are tree leaves; 11 are placed at runtime.
  • Annotations: all 11 CDS lengths divisible by 3. GFF3 coordinates match meta.genome_annotations in tree.json exactly. Reference sequence is 7,413 nt with zero ambiguous bases.
  • Configuration: defaultCds set to VP1 (standard enterovirus typing target). cdsOrderPreference lists all 11 mature proteins in polyprotein order. minSeedCover: 0.80 is tighter than sibling EV-D68 (0.40).
  • Tree integrity: 1,481 uniquely named nodes, 741 leaves. No duplicate names, empty children arrays, or orphaned internal nodes.
  • Generated output: source and generated copies are byte-identical. The generated archive contains the expected dataset files, and data_output/index.json registers the unreleased version.
  • README cleanup: removed stale "currently working on improving multiple virus assignment" statement.

@nneune
nneune had a problem deploying to refs/heads/update-cva16 July 22, 2026 09:08 — with GitHub Actions Error
@nneune
nneune temporarily deployed to refs/pull/465/merge July 22, 2026 09:08 — with GitHub Actions Inactive
@nneune
nneune had a problem deploying to refs/heads/update-cva16 July 22, 2026 09:15 — with GitHub Actions Error
@nneune
nneune temporarily deployed to refs/pull/465/merge July 22, 2026 09:15 — with GitHub Actions Inactive
nextstrain-bot and others added 2 commits July 22, 2026 09:16
…on the inferred reference sequence

Previous builds inferred the tree's root sequence independently of the
dataset reference, causing mismatched mutations at the root and a
Nextclade preprocessing error. The tree is now rebuilt with ancestral
reconstruction anchored to the reference (inferred ancestral) sequence.
@nneune
nneune had a problem deploying to refs/heads/update-cva16 July 22, 2026 13:11 — with GitHub Actions Error
@nneune
nneune had a problem deploying to refs/pull/465/merge July 22, 2026 13:11 — with GitHub Actions Failure
@nneune
nneune deployed to refs/pull/465/merge July 22, 2026 13:29 — with GitHub Actions Active
@ivan-aksamentov

Copy link
Copy Markdown
Member

Thank you! My autocomplete machines are much happier now! The rest are nice to haves, but not a big deal.


⚠️ AI-generated content below. Verify all claims.

Re-review of the updated branch:

  • Prior review targeted a991b115; the branch has since advanced to 7e9a9870.
  • The blocker (H1) and both formatting findings (M1, L2) are resolved.
  • Three documentation findings (M2, M3, L1) remain.

Testing

Try in Nextclade Web:

Resolved since last review

✅ H1 (was blocking). nucMutLabelMap restored [click to expand]

The map was regenerated from the curated tree and now holds 3,882 label entries (base master had 3,883; the single dropped key 619G and several B1a/B1b/B1c relabelings correspond to the removed/re-placed tips) [commit b67d41b].

qc.privateMutations.weightLabeledSubstitutions: 1.5 is therefore active again, and data_output/index.json advertising mutLabels is now accurate.

✅ M1. pathogen.json reformatting [click to expand]

The file is now consistently 2-space indented; the empty aaMutLabelMap: {} block was removed entirely rather than left mis-indented.

✅ L2. Trailing whitespace [click to expand]

Trailing whitespace on the B1a/B1b/B1c README paragraph removed [commit 71bf286].

Other changes in this revision

Not tied to prior findings.

🆕 C1. Tree/reference consistency [click to expand]

The upstream workflow now copies the inferred ancestor to dataset/reference.fasta so the reference and the tree root are the same sequence (Snakefile change; dataset commit 00ba506).

The ancestral_sequence leaf now sits at divergence 0.0 with 0 private mutations, so users analyzing the reference get no spurious QC flags.

🆕 C2. Example panel expanded [click to expand]

Two example sequences containing alignment deletions were added to exercise gap handling [commit c558844]; the panel is now 34 sequences.

Non-blocking issues

Documentation-only; none affect data correctness.

Already reported (unaddressed since the prior review):

🟡 M2. Recombinant clade nomenclature lacks explicit mapping [click to expand]

The README still states that recombinant forms C-F are "also referred to as B2, B3, and D" [src]. Four dataset labels (C, D, E, F) are mapped onto three names (B2, B3, D), so the correspondence is ambiguous. Published nomenclatures are not directly interchangeable:

Fix: add a compact mapping table giving each dataset clade (A, B1, B1a, B1b, B1c, C, D, E, F), the genomic region used to define it, the corresponding published designation, and a defining citation. If C-F are dataset-specific labels, state that explicitly.

🟡 M3. No meta.bugs or meta["source code"] in pathogen.json [click to expand]

pathogen.json has no meta block at all [src]. The README carries the workflow URL (https://github.com/enterovirus-phylo/nextclade_a16) and an issues link, but the machine-readable config does not. The sibling EV-D68 dataset also omits these fields, so this is a collection-wide convention gap rather than a regression.

Fix: add "meta": { "bugs": "https://github.com/enterovirus-phylo/nextclade_a16/issues", "source code": "https://github.com/enterovirus-phylo/nextclade_a16" }, ideally to both ENPEN datasets for consistency.

🔵 L1. "Xu et al." citation lacks a year in CHANGELOG [click to expand]

The CHANGELOG references "several recombinants from Xu et al." without a year or title [src]. The upstream exclude.txt lists PX448978/PX449037 (the PX448*/PX449* Hangzhou series) and the testing file A16_XuQ.csv identifies this as Qihao Xu's analysis of Hangzhou CVA16 sequences (Xu et al., Front Microbiol 2025).

Fix: replace with "Xu et al. (2025)".

New in this revision:

🔵 L3. Reference identifiers are inconsistent across files [click to expand]

Three files name the reference differently: GFF3 seqid is U05876.1, tree meta.genome_annotations[].seqid is resources/reference.gbk, and the reference FASTA header is ancestral_sequence. This surfaced during the tree/reference re-rooting introduced in this revision (commit 00ba506).

Effect: none on processing -- Nextclade maps annotations by CDS name, and the dataset is already released with these values, so this is cosmetic.

Fix: harmonize the three identifiers (all to ancestral_sequence, or to the coordinate-system accession U05876.1) if the upstream workflow is touched again. Not worth a dedicated change on its own.

Clade distribution

10 clades, 783 -> 740 tips [click to expand]
Clade Base (master) Curated (7e9a9870) Removed Added Delta
A 1 1
B1 39 39
B1a 373 343 ${\color{red}\text{-30}}$ ${\color{red}\text{-30}}$
B1b 242 231 ${\color{red}\text{-12}}$ ${\color{green}\text{+1}}$ ${\color{red}\text{-11}}$
B1c 98 96 ${\color{red}\text{-3}}$ ${\color{green}\text{+1}}$ ${\color{red}\text{-2}}$
C 3 3
D 22 22
E 2 2
F 2 2
unassigned 1 1
Total 783 740 ${\color{red}\text{-45}}$ ${\color{green}\text{+2}}$ ${\color{red}\text{-43}}$
  • All 9 named clades retained; removals concentrated in B1a and B1b.
  • The single unassigned tip is the SIA root leaf (ancestral_sequence), which carries no clade membership by design.
  • Curated total is 740, vs the prior review's 741, because commit 00ba506 re-rooted the reconstruction and shifted one tip.

Notes

Click to expand
  • N1. Reference representation (now clean). ancestral_sequence is a tree leaf at divergence 0.0 with 0 branch mutations; the prototype U05876 is also a leaf (div 0.243, 957 muts). No runtime-placement artifacts for either. This is the concrete payoff of the tree/reference re-rooting fix.
  • N2. Annotations. GFF3 defines 11 CDS (VP4->3D); all lengths are divisible by 3, and coordinates match meta.genome_annotations in tree.json exactly. Reference is 7,413 nt with zero ambiguous bases.
  • N3. Label map integrity. nucMutLabelMap keys are all well-formed (<pos><ALT>, positions 11-7413), no empty label lists, labels drawn from the clade set. Regenerated to match the curated topology.
  • N4. Example panel. 34 examples, lengths 592-7,410 nt; 21 are tree leaves, 13 placed at runtime. 6 now contain gap/N characters, added deliberately to exercise gap handling.
  • N5. Generated output. Source and data_output/.../unreleased/ copies are byte-identical for all text files except pathogen.json, which differs only by the rebuild-injected version block (tag: unreleased) -- expected. The dataset.zip members are SHA-256-identical to the unpacked files.
  • N6. Collection registration. enpen/enterovirus/cva16 is present in data/enpen/collection.json and data_output/index.json registers the unreleased version.
  • N7. Sibling comparison (EV-D68). cva16 uses minSeedCover: 0.80 vs ev-d68's 0.40, and nucMutLabelMap 3,882 vs 2,057. Both ENPEN datasets carry an effectively empty aaMutLabelMap and omit meta URLs (see M3).
  • N8. tree.json has no trailing newline, matching the sibling ev-d68 tree -- consistent within the collection, not a regression.
  • N9. Cross-check with peer reviewer (Codex). An independent re-review reached the same conclusions: H1 resolved (3,882 labels, index consistent, reference at divergence 0), M2/M3/L1 remaining, clade table 783 -> 740.

add year to citation in CHANGELOG and add meta.bugs and source code to pathogen.json
@nneune
nneune had a problem deploying to refs/pull/465/merge July 22, 2026 14:51 — with GitHub Actions Error
@nneune
nneune deployed to refs/heads/update-cva16 July 22, 2026 14:51 — with GitHub Actions Active
@emmahodcroft

emmahodcroft commented Jul 24, 2026

Copy link
Copy Markdown
Member

Wow this is an amazing review bot - very cool Ivan!!

@emmahodcroft
emmahodcroft self-requested a review July 24, 2026 08:34

@emmahodcroft emmahodcroft left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nadia and I walked through the dataset yesterday, and I'm very happy with it. Thanks for the hard work on this Nadia!
(and thanks for the great bot-review suggestions Ivan - amazing that it can catch so much!)

@ivan-aksamentov
ivan-aksamentov merged commit 6d13d58 into master Jul 24, 2026
@ivan-aksamentov
ivan-aksamentov deleted the update-cva16 branch July 24, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants