Skip to content

newcastle: initial import - #475

Open
rneher wants to merge 8 commits into
masterfrom
newcastle
Open

newcastle: initial import#475
rneher wants to merge 8 commits into
masterfrom
newcastle

Conversation

@rneher

@rneher rneher commented Aug 14, 2026

Copy link
Copy Markdown
Member

No description provided.

@rneher
rneher had a problem deploying to refs/pull/475/merge August 14, 2026 18:56 — with GitHub Actions Failure
@rneher
rneher had a problem deploying to refs/heads/newcastle August 14, 2026 19:08 — with GitHub Actions Error
@rneher
rneher deployed to refs/pull/475/merge August 14, 2026 19:08 — with GitHub Actions Active
@rneher
rneher had a problem deploying to refs/heads/newcastle August 14, 2026 20:01 — with GitHub Actions Error
@rneher
rneher deployed to refs/pull/475/merge August 14, 2026 20:01 — with GitHub Actions Active
@rneher

rneher commented Aug 14, 2026

Copy link
Copy Markdown
Member Author

@rneher
rneher had a problem deploying to refs/heads/newcastle August 15, 2026 10:55 — with GitHub Actions Error
@rneher
rneher deployed to refs/pull/475/merge August 15, 2026 10:55 — with GitHub Actions Active
@ivan-aksamentov

Copy link
Copy Markdown
Member

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

First review of nextstrain/ndv/class-1/AB524405 and nextstrain/ndv/class-2/NC_075404 at head 0272c4ac.

Verdict: no blocking issues. 4 non-blocking findings (1 medium, 3 low) and 10 notes. Both datasets are structurally sound, build reproducibly, and classify correctly in a local Nextclade run.

Testing

Observed

This PR imports two new Newcastle disease virus (NDV) datasets under nextstrain/ndv/: class-1 (reference AB524405, goose/Alaska/415/91) and class-2 (reference NC_075404, chicken/N. Ireland/Ulster/67). Both register in data/nextstrain/collection.json and appear in generated data_output/. Each tree carries the primary clade at NDV class level (class 1/class 2) and the fine Dimitrov et al. 2019 genotype as a custom clade column genotype_label. Each dataset embeds a single tip of the opposite class as an outgroup, so a wrong-class query attaches there and is reported as the other class with no genotype.

The PR body is empty; author intent is captured in the two READMEs and CHANGELOGs. The observed diff matches that intent -- no undocumented functional changes, no claimed-but-absent items. All checks below were run against the checked-out head; the six-gene layout, coordinates, and codons are internally consistent across genome_annotation.gff3, reference.fasta, tree.json, and pathogen.json for both datasets.

Non-blocking issues

🟡 F1. README sibling-dataset cross-links point to non-existent paths [click to expand]

Both READMEs link to the sibling dataset with a relative path that does not resolve.

  • data/nextstrain/ndv/class-1/AB524405/README.md links [class 2 dataset](../class2).
  • data/nextstrain/ndv/class-2/NC_075404/README.md links [class 1 dataset](../class1).

From class-1/AB524405/README.md, ../class2 resolves to data/nextstrain/ndv/class-1/class2, which does not exist. The link is wrong on two counts: the directory is class-2 (with a dash) and it lives one directory higher, under its accession subdirectory. The correct relative targets are:

  • class-1 README -> ../../class-2/NC_075404
  • class-2 README -> ../../class-1/AB524405

Consequence: a reader following the "run such a sequence against the [class N dataset]" instruction reaches a broken link.

Suggestions:

  • Fix both relative links to ../../class-2/NC_075404 and ../../class-1/AB524405 respectively, or link to the absolute Nextclade dataset path instead.
🔵 F2. One class-1 example fails QC with 2,440 private substitutions [click to expand]

Running Nextclade on class-1/AB524405/sequences.fasta gives 19/20 examples QC good and one bad:

Example clade genotype_label private subs QC
MK516204.1 class 1 unassigned 2,440 bad

It is the only class-1 example not present as a tree leaf (19/20 are leaves). 2,440 private substitutions on a ~15.2 kb genome (~16% divergence from its nearest tree node, versus privateMutations.cutoff = 200) is far beyond intra-class-1 diversity and suggests the sequence is mislabeled, chimeric/recombinant, or low quality rather than a representative example. Example sequences are what users first analyze to gauge the dataset, so a wildly failing example is a poor first impression even though it does not affect the reference tree or classification of valid sequences.

Suggestions:

  • Verify MK516204.1 is a valid class-1 whole genome; if it is a curation artifact, drop it from the example set.
  • If it is intentionally included to demonstrate QC catching a bad sequence, keep it but consider adding a comment/curation note upstream.
🔵 F3. README says unlabeled sequences are reported as `unclassified`, but Nextclade reports `unassigned` [click to expand]

Both READMEs state: "A node is labelled with a genotype only when every sequence below it carries that genotype; everything else is reported as unclassified." The actual genotype_label value emitted by Nextclade (and stored on tree nodes) is unassigned, not unclassified (confirmed in the CLI output for MK516204.1 and in the tree node attributes). The opposite-class outgroup is reported with an empty genotype, as the READMEs otherwise describe.

Consequence: a user filtering or documenting on the literal output value will not find unclassified.

Suggestions:

  • Change "reported as unclassified" to "reported as unassigned" in both READMEs to match the emitted value.
🔵 F4. Class labels use Arabic numerals while genotypes and the source literature use Roman [click to expand]

The datasets label the two NDV classes as class 1 / class 2 (in attributes.name, the clade column, and shortcuts ndv-class-1/ndv-class-2), while the genotype scheme within the same datasets uses Roman numerals (I-XXI). The defining nomenclature (Dimitrov et al. 2019) and NDV literature refer to the two classes as "class I" and "class II". Mixing Arabic class labels with Roman genotype labels in the same output is internally inconsistent and diverges from the cited authority.

This is cosmetic and unambiguous, but the dataset path segment class-1/class-2 is immutable after release, so the choice is worth a conscious decision now.

Suggestions:

  • Consider class I / class II for the user-facing attributes.name and clade values to match the literature, independent of the URL-safe path segment.
  • If Arabic is deliberate (URL/shortcut friendliness), no path change is needed; the point is only the display labels.

Clade distribution

Primary clade is class-level only (each tree is ~99% its own class plus one opposite-class outgroup tip), so the meaningful distribution is the genotype_label custom clade. Both tables below are anchored to the PR head 0272c4ac (new submission).

class-1: 3 genotypes, 176 tips [click to expand]
Genotype Tips %
1.1.2 141 80.1
1.2 29 16.5
1.1.1 4 2.3
unassigned 1 0.6
class-2 outgroup (no genotype) 1 0.6
Total 176

Covers all three class-1 sub-genotypes of the Dimitrov 2019 scheme (1.1.1, 1.1.2, 1.2). The reference AB524405 itself carries no genotype (GenBank "lineage 6", pre-2019 nomenclature) and is the unassigned tip.

class-2: 46 genotypes, 690 tips [click to expand]

Top genotypes by tip count (of 46 distinct genotype_label values):

Genotype Tips %
VII.1.1 193 28.0
VI.2.1.1.2.2 62 9.0
VII.2 60 8.7
XVII 38 5.5
I.2 37 5.4
V.3 37 5.4
VI.2.1.1.2.1 31 4.5
VI.2.1.1.1 30 4.3
XIV.2 25 3.6
XXI.1.1 17 2.5
XIII.2.2 15 2.2
I.1.1 13 1.9
34 further genotypes (each 1-10 tips), incl. unassigned (2) and the class-1 outgroup (1) 132 19.1
Total 690

Broad coverage of genotypes I-XXI. The dominant lineage VII.1.1 (~28%) is the current panzootic poultry strain (Molouki et al., Curr Microbiol 2021); no single genotype exceeds 60%, and the pigeon-associated VI sub-lineages (Dimitrov et al. 2019) are well represented. Genotype XV is absent -- correctly, since Dimitrov 2019 excluded XV from the scheme (recombinant-only sequences), as noted in N9.

Validation summary

Validation checks [click to expand]

GFF3 annotation (both datasets)

  • 6/6 CDS (N, P, M, F, HN, L) divisible by 3, all ATG starts, all valid stop codons.
  • CDS coordinates match meta.genome_annotations in the corresponding tree.json (e.g. class-1 F 4556-6217, class-2 F 4544-6205).
  • Sequence IDs (AB524405.1, NC_075404.1) match reference.fasta headers.
  • genome_annotations[].seqid is a build-local path string (defaults/class1/reference.gb) -- cosmetic, see N10.

Reference (both datasets)

  • class-1: 15,198 nt; class-2: 15,186 nt. Both match GFF3 ##sequence-region and satisfy the NDV rule of six (15,198 = 6x2,533; 15,186 = 6x2,531).
  • Header first token matches GFF3 seqid and attributes["reference accession"] (modulo the .1 version suffix, which is display metadata).

pathogen.json (both datasets)

  • defaultCds: "F" matches a GFF3 CDS; ignoredStopCodons positions all fall within HN (0-616 codons) and, for class-2, L (0-2204). ignoredFrameShifts empty.
  • Empty missingData/snpClusters disabled; qc capabilities in index.json (privateMutations, mixedSites, frameShifts, stopCodons) match the enabled modules.

tree.json (both datasets)

  • Valid Auspice v2 structure; colorings clade_membership, gt, year, country, genotype_label; clade_node_attrs = genotype_label (Dimitrov 2019, 2022 release).
  • Divergence trees (no num_date); year range class-1 1991-2020, class-2 1933-2021.
  • class-1 reference AB524405 is a tree leaf; class-2 reference NC_075404 is not a leaf but aligns to a node with 0 private mutations (see N7).
  • root_sequence absent in both -- non-blocking, see N5.

Generated output

  • Source vs data_output/.../unreleased/ text files (README, CHANGELOG, GFF3, reference.fasta, sequences.fasta) byte-identical for both datasets.
  • pathogen.json/tree.json differ only by the pipeline's injected version block -- expected.
  • Both datasets registered in collection.json and data_output/index.json.

Nextclade CLI run (nextstrain/nextclade:latest)

  • References: both QC good, 0 private mutations, 0 frameshifts, 0 stop-codon flags.
  • class-1 examples: 19/20 good, 1 bad (MK516204.1, see F2).
  • class-2 examples: 20/20 good.
  • No frameshifts or stop-codon QC flags across any example (so empty ignoredFrameShifts is correct; ignoredStopCodons did not trigger on this example set, see N4).

Notes

Click to expand
  • N1. The outgroup design is clever and correctly documented: each tree embeds one tip of the opposite class, so a wrong-class query attaches to it and is reported as the other class with no genotype, instead of being forced inside the wrong diversity. Verified in the tree structure and CLI behavior.
  • N2. Two-level classification: primary clade = NDV class; custom genotype_label column = fine Dimitrov genotype. Users receive both. A local run confirmed genotype calls (e.g. class-2 examples span I.1.1, I.2, V.2, V.3, VI.2.1.1.2.2, VII.1.1, XII.2, XIII, XIV.2, XIX, XVII, XXI.1.2).
  • N3. Both references are avirulent/lentogenic at the fusion-protein cleavage site (verified by translating reference.fasta): AB524405 = ...ERQER/L..., NC_075404 = ...GKQGR/L... -- both monobasic, consistent with class-I waterfowl viruses and the lentogenic Ulster vaccine strain. The polybasic motif is the virulence determinant (Peeters et al., J Virol 1999).
  • N4. ignoredStopCodons in HN (and L for class-2) correspond to the known HN C-terminal length polymorphism (strains encode HN of ~571/577/616 aa via stop-codon position; Rahman et al., Virol J 2010). They do not trigger on the example set but guard field sequences with truncated HN.
  • N5. root_sequence is absent from both tree.json. Functionally harmless: Nextclade uses reference.fasta, and the reference run yields 0 private mutations. Consistent with some released siblings (e.g. mpox) that also omit it.
  • N6. Example sets are almost entirely tree leaves (class-1 19/20, class-2 20/20), so QC is trivially good and runtime placement is barely exercised. Consider adding a few non-tree, genuinely novel example sequences.
  • N7. class-2 reference NC_075404 is not a tree tip yet aligns to a node with 0 private mutations; the README correctly notes it is peripheral genotype I.2.
  • N8. Path design nextstrain/ndv/class-{1,2}/<accession> includes the accession suffix, leaving room for alternate references -- good future-proofing for these immutable paths. Casing/separators (lowercase, dash) are consistent with the repo.
  • N9. Both READMEs mention genotype XV is absent. Worth stating the reason: Dimitrov 2019 excluded XV from the scheme entirely (it contained only recombinant sequences), so its absence is by definition, not a sampling gap.
  • N10. Cosmetic build residue: tree.json files lack a trailing newline and differ in formatting (class-1 pretty-printed, class-2 minified); meta.genome_annotations[].seqid carries a build-local path (defaults/class1/reference.gb). None affect function. pathogen.json omits a meta block (bugs/source-code/maintainers), which is consistent with several sibling datasets; the workflow and data-source links live in the README instead and both resolve.

Background

NDV taxonomy, genome, and the Dimitrov 2019 genotype scheme [click to expand]

Taxonomy and reference strains

Newcastle disease virus is a negative-sense, non-segmented ssRNA virus (Baltimore Group V) in the order Mononegavirales, family Paramyxoviridae, subfamily Avulavirinae, genus Orthoavulavirus. The species is now the ICTV binomial Orthoavulavirus javaense (formerly Avian orthoavulavirus 1 / Avian avulavirus 1 / avian paramyxovirus type 1); the genus and subfamily were established in the ICTV Mononegavirales 2019 update.

  • class-1 reference AB524405: 15,198 nt, isolate goose/Alaska/415/91, a waterfowl-origin low-virulence class-I genome (GenBank "lineage 6"; Tsunekuni et al., Virus Genes 2010).
  • class-2 reference NC_075404: 15,186 nt RefSeq, isolate chicken/N. Ireland/Ulster/67 -- the classic lentogenic Ulster strain, historically a live vaccine strain (RefSeq notes it is identical to AY562991).

Genome organization

Six genes in order 3'-N-P-M-F-HN-L-5'. NDV replicates efficiently only when the genome length is a multiple of six (the "rule of six"; Krishnamurthy & Samal, J Gen Virol 1998) -- both references comply. The P gene undergoes co-transcriptional RNA editing to yield P/V/W proteins (Steward et al., J Gen Virol 1993). The HN gene shows C-terminal length polymorphism across strains (Rahman et al., Virol J 2010), which is why the datasets carry HN ignoredStopCodons. The fusion (F) protein cleavage site is the molecular determinant of virulence and the standard typing target; a polybasic motif (e.g. 112-RRQKR/F-117) marks virulent (velo/mesogenic) strains, a monobasic motif (e.g. 112-GKQGR/L-117) marks avirulent (lentogenic) strains (Peeters et al., J Virol 1999).

Clade / lineage classification

The datasets use the unified nomenclature of Dimitrov et al., Infect Genet Evol 2019 (PMID 31200111, PMC6876278), based on complete F-gene coding sequences. It splits NDV into two classes (mean inter-class F-gene distance ~59%): class I is a single genotype with sub-genotypes 1.1.1/1.1.2/1.2, and class II comprises genotypes I-XXI (XV excluded as recombinant-only). Genotype thresholds are >10% mean distance (genotype) and >5% (sub-genotype) with >=70% bootstrap and >=4 epidemiologically independent isolates. class I is genetically less diverse and, with a single reported exception, avirulent in wild waterfowl; class II carries the virulent poultry strains and a wide virulence range. Genotype VII (VII.1.1, VII.2) drives the current poultry panzootic (Molouki et al. 2021); genotype VI viruses are the pigeon paramyxoviruses (PPMV-1). Data provenance: GenBank plus the NDVconsortium/NDV_Sequence_Datasets curated set, built by the nextstrain/newcastle-disease-virus workflow (both URLs resolve).

@ivan-aksamentov

Copy link
Copy Markdown
Member

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

Amendment to the review above: F4 is restated below. The original wording was too broad -- it implied the genotype numbering is uniformly Roman and that the dataset mixes an Arabic class with Roman genotypes. That is not correct: the numbering is mixed by the scheme itself (class I genotype 1, sub-genotypes 1.1.1/1.1.2/1.2, Arabic; class II genotypes I-XXI, Roman), and is by design. The corrected finding narrows the point to the class label only. Severity is unchanged, and all other findings and notes stand.

Non-blocking issues (revised)

🔵 F4. Class labels use Arabic numerals where both cited sources use Roman (`class I`/`class II`) [click to expand]

Supersedes the F4 in the review above.

The datasets label the two NDV classes as class 1 / class 2 (in attributes.name and the clade column). Both sources the READMEs cite for the nomenclature write the classes in Roman:

  • Dimitrov et al. 2019 defines "class I" and "class II".
  • The NDV consortium's May 2022 release, on which the genotype set is based, names its files NDV_CG_class_I_177_May_09_2022 and NDV_CG_class_II_691_May_09_2022 (NDVconsortium/NDV_Sequence_Datasets) -- the two complete-genome sets (177 and 691 sequences) that this PR's trees (176 and 690 tips, plus one outgroup each) are drawn from.

The genotype numbering itself is not the issue: the scheme is Arabic for class I (genotype 1, sub-genotypes 1.1.1/1.1.2/1.2) and Roman for class II (I-XXI) by design. The narrow point is the class label. Writing the class in Arabic (class 1) also collides visually with the Arabic class-I genotype 1; Roman class I would keep the class distinct from that genotype.

This is a display-label choice, not a path change: the URL-safe path segment class-1/class-2 and the ndv-class-1/ndv-class-2 shortcuts can stay as they are.

Suggestions:

  • Consider class I / class II for the user-facing attributes.name and clade values, to match both cited sources and disambiguate from genotype 1.
  • If Arabic is deliberate, no change is needed; flagging only because these labels appear in every result and the path is immutable after release.

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.

3 participants