Hop atlas home · Overview · Changelog · Architecture · Adding_Data · Introgression · Ribbon · Dosage · Phylogeny · Bundle · Ingest · Ingest_Gbs · Ingest_Wgs · Ingest_Grasdi · Ingest_Rnaseq · Ingest_Assembly
Rendered from hop_atlas/ingest/ASSEMBLY.md (2026-10-13)
Status: reconstructed 2026-10-08 from project history. Read-only research; nothing was re-run.
- Every step cites the record it rests on.
- (inferred) marks a step that no record states outright.
- GAP marks a step for which no record exists.
- GENERIC = a reusable, parameterised tool. COPY-AND-EDIT = a dated record with hard-coded paths/lists that must be forked.
- Paths are relative to /workspace/annevo-monkeyflowers (= R/) unless they start with /data.
- M/ = .claude/projects/-workspace-annevo-monkeyflowers/memory/.
Related guides:
- hop_atlas/ADDING_DATA.md, the data type × atlas audit. Its "HiFi / assembly FASTA" row is expanded here.
- hop_atlas/components/{RIBBON,DOSAGE,INTROGRESSION}.md.
- annevo_eval/docs/APOLLO_ASSEMBLY_PROCESS.md, the only end-to-end own-build record.
| Assembly | Source / accession | Type | Held at | Catalog id |
|---|---|---|---|---|
| Apollo DIY phased (h1, h2) | own build from ENA PRJEB63995 (HiFi ERR11648705–709; Hi-C ERR11641228–271) | hifiasm --hic → YaHS, EC on |
/data/hop_data/Apollo_asm_hifiasm/hap{1,2}_yahs_scaffolds_final.fa; the rest is PBSS archive/apollo_asm_hifiasm/ |
apollo_asm_hifiasm{,_scaffolds,_bwa_index} |
| Apollo noEC (h1, h2) | own; YaHS --no-contig-ec on the same contigs |
figure-only variant | PBSS only; oriented copy /data/hop_data/Apollo_noEC_oriented/ (hand numbering) |
apollo_noEC_scaffolds, apollo_noEC_oriented_assembly |
Cascade per-homolog (cascade_h1/_h2) |
own, from the Dovetail contigs + PRJNA562558 Hi-C/CLR + ERR11608298 Illumina | HapCUT2 phase → YaHS per homolog → polish | PBSS archive/cascade_genomewide/gwd_sitefix/fasta/ |
none (TENTATIVE, v2 not promoted) |
| KR (cordifolius) ref-guided | Natsume draft GCA_000830395.1 → RagTag onto 21110M | ref-guided scaffold | annevo_eval/results/humulus/sexchrom/KR_refguided/ (the draft was deleted 2026-10-02) |
hop_draft_genomes_KR_SW |
| drHumLupu1.1 | NCBI GCF_963169125.1 (Sanger DToL) | external, primary only | /data/hop_data/ref_drHumLupu{,_bwa}/, annevo_eval/data/humulus/GCF_963169125.1/ |
drHumLupu1.1, ref_drHumLupu_bwa |
21110M (h1, h2) + male_ref composite |
Carey 2026, Zenodo 10.5281/zenodo.16326991 | external, phased | annevo_eval/data/humulus/Carey2026_sexchrom/Hl_lupulus_21110M/; /data/hop_data/ref_21110M_male/male_ref.fa |
carey2026_sexchrom |
| MN1421, MN586 (h1, h2) | Carey 2026, same Zenodo deposit | external, phased | .../Carey2026_sexchrom/Hl_{lupuloides_MN-1421,neomexicanus_MN-586}/, /data/hop_data/carey_wild_males/ |
carey2026_sexchrom |
| Saaz, HL1012 (Akagi 2025) | DDBJ pseudo-haploid PRJDB17943/17946 (PlantGarden); principal h1 PRJDB17944/17947; alternate h2 PRJDB17945/17948 | external | annevo_eval/data/humulus/{Saaz_akagi2025,Hl1012_akagi2025_male}/, /data/hop_data/akagi_{principal,alt}_haps/ |
saaz_akagi2025, hl1012_akagi2025_male, akagi_principal_haps, akagi_{saaz,hl1012}_h2 |
| Cascade HopBase Dovetail | hopbase.org content/cascadeDovetail/ |
external, uncollapsed diploid | annevo_eval/data/humulus/Cascade_hopbase/ |
cascade_hopbase |
| Carlsberg phased Apollo | NCBI GCA_060344715.1 (phase 1), GCA_060344695.1 (phase 2); released 2026-08-22 | external | /data/hop_data/carlsberg_apollo_phased/ |
none |
| OSU_HLup_v1 (Cascade) | NCBI GCA_023660075.1 | external, uncollapsed | /data/hop_data/cascade_contig_junctions/assembly/ |
none |
| Apollo haploid nrgene, Teamaker | GCA_964017075.1; HopBase Teamaker v1.0 | ANNEVO comparators only | annevo_eval/data/humulus/ |
apollo_haploid_nrgene, teamaker |
| Use | Assemblies |
|---|---|
| Ribbon atlas | legacy 13 + cascade_hopbase |
| v5 graph (13 haplotypes) | Apollo h1/h2, M21 h1/h2, drHumLupu, Saaz, Saaz_h2, HL1012, HL1012_h2, MN1421 h1/h2, MN586 h1/h2 (annevo_eval/docs/PANGENOME_V5.md) |
| Linear references | 21110M male_ref, drHumLupu, Apollo h1 Akagi, Apollo h2, Saaz h1, HL1012 h1, Cascade (hop_atlas/components/DOSAGE.md §1) |
| Introgression diagnostic catalogue | the same 13 haplotypes as the graph |
Not yet in any atlas: Cascade per-homolog, Carlsberg Apollo, OSU_HLup_v1. Wye Target and Pilgrim have no assembly.
APOLLO_ASSEMBLY_PROCESS.md §9 say the phased Apollo is embargoed. The Carlsberg GCAs above are public.annevo_eval/docs/SAAZ_1012_REPHASE_PLAN.md describes a "CLR blocker". The reads are HiFi and both haplotypes are public (M/saaz-1012-rephase-todo.md).Stage map (each one depends on the stage before it):
| Stage | Name | Needed for |
|---|---|---|
| S1a | Assemble (own-built) | everything below |
| S1b | Obtain (external) | everything below |
| S2 | QC | — |
| S3 | Numbering and orientation | every use below |
| S4 | Ribbon atlas row | — |
| S5 | Optional tracks | — |
| S6 | Linear alignment / dosage reference | — |
| S7 | Pangenome graph inclusion | — |
| S8 | Introgression diagnostic catalogue | — |
Branches after S3: - S4 → S5 is the ribbon atlas path. - S6, S7 and S8 are independent of each other. - S8 is a research change, and it invalidates every introgression call.
Reference record: Apollo, annevo_eval/docs/APOLLO_ASSEMBLY_PROCESS.md §2–3.
| Step | Tool + version | Flags | Site | Script |
|---|---|---|---|---|
| 0. Split the HiFi from the Iso-Seq | — | Pass only the assembly HiFi runs (Apollo: exactly 5). An abort guard is in the sbatch. | — | annevo_eval/cluster/apollo_eos/apollo_hifiasm.sbatch |
| 1. Redundancy pre-flight | minimap2 contig-vs-contig | Decide whether purge_dups is needed (Apollo: no) | annevo | Apollo_asm_hifiasm/analysis/run_preflight_redundancy.sh (now in the PBSS archive) |
| 2. Phased contigs | hifiasm 0.25.0-r726 | -o <x> -t 192 --write-ec --h1 <HiC R1,...> --h2 <HiC R2,...> <HiFi...> |
EOS: exclusive node, Pyxis hifiasm-pbss.sqsh, reads from PBSS. Apollo job 5641188: 3 h 36 m, 504 GB peak RSS |
apollo_hifiasm.sbatch; resume variant apollo_hifiasm_resume.sbatch reuses .ec.bin/.ovlp*.bin after the 4 h wall |
| 3. BWA index of each haplotype | bwa 0.7.19 | default | annevo (about 40 min per haplotype) | Apollo_asm_hifiasm/run_bwa_index_hic_scaffolding.sh (archived) |
| 4. Hi-C alignment | pbrun fq2bam 4.7.0-1 |
--ref <hap>.fa --in-fq <pairs + @RG> --no-markdups |
annevo, 2× A6000 | same |
| 5. Name-sort | samtools | sort -n -@16 |
annevo | same |
| 6. Scaffold | YaHS 1.2.2 (/data/bin/yahs) |
yahs <hap>.fa <hap>.hic.namesort.bam -o <hap>_yahs (defaults: contig EC on, no -e) |
annevo (about 15 min per haplotype) | Apollo_asm_hifiasm/run_hic_scaffold_yahs.sh (archived) |
| 6b. Optional noEC variant | YaHS 1.2.2 | --no-contig-ec (-e GATC gave a byte-identical result) |
annevo | M/apollo-phased-scaffolds.md |
Gotchas
- ENA/SRA labels are wrong. Iso-Seq is labelled "WGS", and Hi-C is labelled NovaSeq but is HiSeq 2500 PE101 (CLAUDE.md; M/sequencing-platform-labels-unreliable.md).
- pbrun cannot do the Hi-C -5SP recipe. That is the reason for the Juicebox QC gate in S2.
- The Cascade per-homolog build used CPU bwa mem -5SP instead (sync/2026-10-07/cascade_homolog_phasing/genomewide/PIPELINE.sh GW-A).
- An Apollo -5SP + -e GATC re-scaffold (post_assembly/edn5sp_assembly/) was started. GAP: no result is recorded.
- YaHS contig EC over-breaks HSR / telomere-rich chromosome ends. On Apollo, noEC recovers 14–15 Mb per haplotype. The catalog prefers targeted reattachment over adopting noEC wholesale (catalog apollo_noEC_scaffolds).
- Transfers: PBSS transfers now use aws s3 sync, not the s5cmd used in the sbatch (CLAUDE.md).
- Declare keepers at creation: annevo_eval/data_inventory/register_product.sh <path> "<why>" --feeds "<step>". Use --feeds for the .bin/.agp and name-sorted BAMs that a later curation step needs.
Variant: phased re-assembly from an existing collapsed or inflated assembly (Cascade per-homolog).
- Record: sync/2026-10-07/cascade_homolog_phasing/genomewide/{README.md,PIPELINE.sh,METHODS.md}, bundles scripts/bundle_gw{a,b,c,d}/, run on Lepton (scripts/lepton/RUNLOG.md).
- Chain: GW-A → GW-B → GW-C → GW-D.
- GW-A: Hi-C bwa mem -5SP to male_ref; CLR minimap2 -ax map-pb.
- GW-B: genetic phase + HAPCUT2 --hic 1; chimera breaks; Hi-C vote; yahs -e GATC -r 10000,...,10000000 per homolog.
- GW-C: Illumina + CLR polish with bcftools call --ploidy 1 → bcftools consensus.
- GW-D: gwd_build.py writes the per-homolog FASTA + flags BED.
- Entirely COPY-AND-EDIT. It needs a mapping cross for genetic phase.
- Phase 2 (v2) failed its held-out gate and is not promoted (assembly_eval/README.md).
Variant: reference-guided scaffold (KR).
- annevo_eval/results/humulus/sexchrom/KR_refguided/run_ragtag.sh: ragtag.py scaffold <21110M_male_karyotype.fa> <contigs≥10kb> --mm2-params "-x asm20 -t 20" -u.
- The synteny test came out repeat-confounded (H2_synteny_result.md).
| Source | Precedent script | Verification |
|---|---|---|
| NCBI GCA/GCF (FTP) | sync/2026-10-01/chr5_inversion_survey/scripts/s23_get_carlsberg_apollo.sh (wget -c of _genomic.fna.gz, assembly_report, stats, md5checksums.txt) |
md5sum -c |
| NCBI datasets API | annevo_eval/data/download_ncbi.sh (inferred, for GCA_964017075.1 / GCF_963169125.1; no log ties them together) |
— |
| Zenodo | annevo_eval/data/dl_carey2026_hop.sh + carey2026_hop_manifest.tsv |
md5 per file; GFF seqids must be a subset of the FASTA headers (Carey2026_sexchrom/README.md) |
| DDBJ / ENA per accession | /data/hop_data/akagi_principal_haps/fetch_principal_chr.sh (chromosomes only; unplaced contigs not pulled); /data/hop_data/akagi_alt_haps/fetch_alt_haps.sh |
— |
| PlantGarden | annevo_eval/data/humulus/Saaz_akagi2025/dl_saaz_akagi2025.sh, Hl1012_akagi2025_male/dl_hl1012_akagi2025.sh |
— |
| HopBase | annevo_eval/data/humulus/dl_cascade.sh |
none recorded |
Rules
- Put the download in its own new directory under /data/hop_data/ (the overlay is full; CLAUDE.md).
- Add a catalog.yaml entry, then run annevo_eval/data_inventory/refresh.sh.
- Record which product the deposit actually is: pseudo-haploid, principal, alternate, or uncollapsed diploid.
Gotchas
- Read the README before trusting a product label.
- Akagi "Saaz" / "HL1012" from PlantGarden are the pseudo-haploid, not haplotype 1. The v4/v5 graph uses the pseudo-haploid (M/saaz-1012-rephase-todo.md; catalog akagi_principal_haps).
- The HopBase Cascade and OSU_HLup_v1 are uncollapsed diploids about 40% inflated (M/cascade-assembly-inflated.md; annevo_eval/docs/CASCADE_DIAGNOSIS.md). Check total length and BUSCO D before use.
- Junk file: /data/hop_data/Apollo_haploid/apollo_hap.zip is an 847-byte invalid zip.
| Gate | Tool / script | Pass criterion (precedent) |
|---|---|---|
| Chromosome-scale structure | Apollo_asm_hifiasm/analysis/validate_scaffolds.py: chunks → drHumLupu minimap2 PAF; MINLEN 50 Mb, MAPQ ≥30, aln ≥20 kb |
top 10 scaffolds map 1:1 to the 10 distinct drHumLupu chromosomes, 0 fusions |
| Gene completeness | compleasm (0.2.6 in the Cascade evaluation), lineage eudicots_odb10 (N=2326): compleasm.py run -a <fa> -o <dir> -l eudicots -t 18 |
Apollo scaffolds: C=98.28 / 98.88%, unchanged from the contigs, so no loss from scaffolding. Inflation flag: D ≫ 2–3% (Cascade D=33.5%) |
| Hi-C contact map (reference-free) | Juicer/JBAT: run_juicer_hic.sh → hap{1,2}_JBAT.hic; noEC: run_juicer_hic_noEC.sh; render sync_archive/2026-07-19/apollo_noEC_hic_oriented/scripts/render_hic_oriented.py (skill hop-karyotype-hic) |
about 10 clean diagonal blocks per haplotype, scaffold edges on block edges, no off-diagonal bridge |
| Telomeres | /data/hop_data/repeat_karyotype_v4/v5b/telo_scan.py (TTTAGGG/CCCTAAA, merge ≤200 bp, ≥5 motifs; display ≥25) |
reported, not gated. Apollo: 2/20 (h1) and 5/20 (h2) capped ends |
| k-mer QV / completeness | meryl 1.4.2 + Merqury 1.4.1 (k=21), GenomeScope2 2.0.1 (sync/2026-10-07/cascade_homolog_phasing/genomewide/assembly_eval/PIPELINE.sh) |
no hap-mers without parental reads |
| Phasing sanity | HiFi 31-mer 1C/2C test (catalog apollo_asm_hifiasm_scaffolds, 2026-09-04); genetic phase vs assembled bases (Cascade phase_compare.py) |
— |
| Read-back reproducibility | re-align a chunk subset (subset_chunks.py --every 87 --phase 3) |
PAF lines byte-identical (Cascade: 1187/1187) |
Gotchas
- The Apollo JBAT .hic / .assembly files and the noEC FASTA/AGP are no longer on /data. They are in the PBSS archive apollo_asm_hifiasm/ (restore with archive.sh restore apollo_asm_hifiasm). The skill's paths therefore fail as written.
- Label the normalisation "Knight–Ruiz balanced", never "KR" (KR is a sample name; skill hop-karyotype-hic).
- Match Hi-C blocks to chromosomes by length rank (same skill).
Numbering standard
- Akagi is primary, with (Hand) in parentheses (M/hop-chromosome-numbering.md).
- Maps (CLAUDE.md; table sync_archive/2026-07-16/apollo_repeat_karyotype/chromosome_number_mapping.tsv):
- hand→Akagi: 1→8, 2→6, 3→3, 4→1, 5→4, 6→5, 7→9, 8→2, 9→7, X→X
- Akagi→drHumLupu: 1→1, 2→3, 3→4, 4→5, 5→6, 6→7, 7→2, 8→8, 9→9, X→X (NC_084793.1 = dr1 … NC_084802.1 = drX)
- Native names already in Akagi numbering:
- Saaz / HL1012 chrN_scaffold
- Carey Chr01.. (21110M, MN)
- DDBJ h2 accessions: decode table in M/v5-panel-canonical-coordinates.md
- drHumLupu keeps its NC_ names in the graph.
- Apollo noEC oriented files use hand numbering (/data/hop_data/Apollo_noEC_karyotype/hap{1,2}_scaf2hand.json).
Orientation: drHumLupu-forward by dominant-strand voting (CLAUDE.md)
1. Cut the assembly into 1 Mb chunks. Do not align whole contigs: minimap2 OOMs on the satellite-rich chromosomes.
2. Align with minimap2 -cx asm20 -I 8G --secondary=no against drHumLupu (minimap2 2.28-r1209 in the Cascade record).
3. Filter matches ≥5 kb and MAPQ ≥20 (the Cascade/atlas threshold; the noEC record used ≥20 kb / MAPQ ≥30).
4. For each scaffold, sum aligned bp per strand against the dominant chromosome. Reverse-complement the scaffold if the signed sum is negative.
Precedent scripts
| Precedent | Script(s) | Notes |
|---|---|---|
| Atlas recipe (Cascade) | /data/hop_data/cascade_dovetail_atlas/scripts/{subset_chunks.py,direct_vote.py,orient_fasta_and_gaps.py} |
Direct vote on every 5th chunk. Validation qc/oriented_fasta_validation.tsv: per-chromosome md5 before/after, 100 read-back probes with 0 mismatches, negative control 20/20 mismatches |
| Graph inputs | /data/hop_data/apollo_graph/v3_orient/orient_v3.sh |
Archived to PBSS (/data/hop_data/apollo_graph/ARCHIVED_TO_PBSS.txt). Saaz 98/338 contigs flipped, HL1012 64/164 |
| Graph inputs, h2 | /data/hop_data/akagi_alt_haps/orient_h2.sh |
h2 haplotypes, run locally: the Cactus container has no minimap2 |
| Apollo noEC | /data/hop_data/Apollo_noEC_oriented/make_oriented_assembly.py |
writes name_map.tsv + AGP |
| Dosage references | sync/2026-09-25/per_chromosome_dosage_multiref/scripts/00c_orientation_check.sh (+ 00f) |
1 Mb chunks every 10 Mb vs Apollo h1, with the 21110M Chr01–05+X reversal as a must-detect control |
| Panel spec | /data/hop_data/gbs_tags/panel/correspondence.py |
5 kb windows every 250 kb, MAPQ ≥20 → panel_canonical_spec.tsv (130 rows: haplotype, source_seq, akagi_chr, orient_to_drHumLupu_fwd, …). GAP: the window-extraction + minimap2 step is not scripted (sync/2026-08-28/gbs_tags/TASK3_V5_PANEL_TAG_UNIVERSE.md) |
AGP-aware rule. If the PAF is contig→reference but you are orienting scaffolds, contig strand = PAF strand × AGP W orientation (skill deepspace §4; sync_archive/2026-07-19/apollo_noEC_deepspace/FINDINGS.md). GAP: no standalone script does this.
QC gate. The orientation is a property of the file, not the sample, so treat every FASTA copy as untrusted (M/assembly-orientation-duplicates.md).
1. md5 each chromosome against the intended frame and test revcomp(a)==b.
2. Check that ribbons/dotplots against drHumLupu show no full-length hourglass.
Gotchas
- Same-name, same-length copies in mirrored frames:
- apollo_hap1_ref/apollo_hap1.fa (Chr05–09+X reverse-complemented);
- Saaz_1012_karyotype/saaz.fa, ref_saaz_female/saaz_ref.fa, ref_1012_male/hl1012_male.fa (chr1–5 reverse-complemented);
- the v5 M21 frame vs male_ref (7/11 chromosomes reverse-complemented).
- Composite votes can mislead on duplicated X. Cascade ChrX: the direct vote is (−), the vote composed through male_ref is (+). Scaffold_1533 carries two X copies in opposite orientation. The direct vote is authoritative (cascade_dovetail_atlas/atlas_input_manifest.json).
- MN haplotypes went into v4/v5 un-oriented, so MN coordinates are mirrored on Chr1–5 (+X). Sources disagree on exactly which: all four (M/v5-panel-canonical-coordinates.md) vs 3/4 (ASSAYS.md 09-22) vs "already correct" (v4_pangenome_provenance.sh). Unresolved; re-audit.
- Akagi-numbered ≠ drHumLupu-forward (annevo_eval/docs/ASSAYS.md 2026-09-22).
- The atlas backbone male_ref.fa is reversed vs drHumLupu on Chr01–05 and ChrX. RIBBON.md §1 omits X (/data/hop_data/deepspace_ribbons/tables/orientation_and_inversions.tsv).
- Fixing a mirrored VCF without re-aligning: new_pos = L − pos − len(REF) + 2, reverse-complement REF/ALT, then sort (M/assembly-orientation-duplicates.md).
- GAP: the script that produced v5_inputs_gz/{apollo,m21}_h{1,2}.akagi.fa.gz (rename to Akagi + orient) is not in the repo.
Record: /data/hop_data/cascade_dovetail_atlas/report/PIPELINE.sh ("documentation of what was run, paths hardcoded"); guide hop_atlas/components/RIBBON.md §3, §5.
Producing the inputs (copy /data/hop_data/cascade_dovetail_atlas/scripts/ to /data/hop_data/<asm>_atlas/ and edit Q, the scaffold lists and the hap names):
1. Backbone: REF=/data/hop_data/ref_21110M_male/male_ref.fa in its native frame. Record its sha256 (meta/male_ref.sha256).
2. Raw PAF: chunk the query into 1 Mb pieces and align them.
- chunk_stream.py <Q> --chunk 1000000 --keep <chromosome scaffolds> | minimap2 -cx asm20 --cs -t 20 -I 8G --secondary=no male_ref.asm20.mmi -
- minimap2 2.28-r1209.
- GAP: chunk_stream.py and male_ref.asm20.mmi lived in /workspace/joint_paintings_work/, which is gone. The equivalent chunkers are extract_chunks.py / subset_chunks.py (inferred substitute), and the .mmi must be rebuilt from male_ref.fa (inferred: minimap2 -x asm20 -d).
3. Reproducibility: subset_chunks.py --every 87 --phase 3 → re-align → PAF lines must be byte-identical.
4. Direct drHumLupu vote: subset_chunks.py --every 5 --phase 2 → minimap2 -cx asm20 ... drHumLupu.fa.gz → direct_vote.py.
5. Parse and orient: parse_cascade.py → orient_fasta_and_gaps.py → offchrom_and_candidates.py → segments.py → plot_qc.py. Filters: matches ≥5 kb, MAPQ ≥20.
- These write the five atlas inputs:
- compact/<hap>.tsv.gz (audit_ribbon_alignments.py columns, native coordinates)
- crosschrom/<hap>.json.gz (rows [qChromIdx,tChromIdx,a,b,u,v,sign,matches,mapq], already in the atlas frame)
- meta/<hap>_orientation_and_inversions.tsv (convention: flipped XOR referenceReversedFromDeposit == raw_to_canonical_flip)
- meta/<hap>_panel_spec.tsv (haplotype must equal the manifest alias)
- meta/<hap>_alignment_loss_audit.tsv
- They also write an oriented FASTA (fasta/<hap>.akagi_drfwd.fa.gz).
6. Producer manifest: atlas_input_manifest.json with files.<key>.{path,sha256}, frame, recipe, scaffold_map, integration_notes.
- GAP: the step that writes this manifest is not listed in PIPELINE.sh (inferred: written by parse_cascade.py or by hand).
7. Cascade-only C1 checks (c1_*.py, direct_c1_summary.py) are research steps, not part of ingest.
Adding the row (GENERIC): append an entry to annevo_eval/scripts/atlas_extra_assemblies.json.
- Keys: hap, label, short, alias, color, producer_manifest, compact, crosschrom, orientation, panel_spec, audit, caveat.
- The loader annevo_eval/scripts/atlas_extra_assemblies.py asserts that each path equals the producer manifest's path and that the sha256 matches.
- Consumers: build_ribbon_v2.py, build_ribbon_crosschrom.py, compare_candidates_crosschrom.py.
Build, test and deploy (GENERIC):
T=hop_atlas/tools/atlas_deploy.py
python3 $T stage ribbon --name add_<asm>
STG=/data/hop_data/atlas_stages/ribbon/add_<asm>
python3 $T build ribbon $STG # build_ribbon_v2 → crosschrom --render-only → summarize_crosschrom_panel → crosschrom --render-only
# → compare_candidates_crosschrom → plot_candidates_vs_placements → build_ribbon_similarity → add_nav
python3 $T test ribbon $STG # 6 verifiers + verify_ribbon_similarity → $STG/checks.txt
python3 $T deploy ribbon $STG --dry-run
python3 $T deploy ribbon $STG # needs PI approval; note it in hop_atlas/CHANGELOG.md
QC gates
- All verifiers PASS.
- The build_ribbon_v2.py assertion canonical orientation mismatch must not fire.
- Tests only when the PI asks (hop_atlas/README.md rule 3).
Gotchas
- build does not rebuild PAFs or per-assembly inputs.
- Inflated / uncollapsed assemblies: the backbone-uniqueness rule removes doubly covered intervals (Cascade: about 22% of the backbone). State this in caveat.
- Adding to the legacy 13 instead of the extra list means editing hard-coded lists in build_structural_ribbon_atlas.py (HAPS/LABEL/COL), audit_ribbon_alignments.py (NAMES), build_ribbon_v2.py (ALIAS), and /data/hop_data/deepspace_ribbons/{run_parse.sh,build_tables.py} + run_align_all.sh (RIBBON.md §3).
- The ribbon builder scripts in annevo_eval/scripts/ are not in git (RIBBON.md §6).
- Similarity view: it reads pair_distances_v2.tsv, which build_ribbon_v2.py produces, so a new row appears in it automatically (inferred from RIBBON.md §1).
| Track | Producer (precedent) | How the atlas joins it | Status for a new row |
|---|---|---|---|
| Repeats (11 elements) + telomere + HSR0 | /data/hop_data/repeat_karyotype_v4/run_blast_v4.sh (blastn -query horakova_panel_v4.fa -evalue 1e-20 -perc_identity 50 -outfmt "6 qseqid sseqid pident length qlen qstart qend sstart send evalue bitscore"); v5b/telo_scan.py; v5b/run_hsr0_telo.sh; merge v5b/build_repeat_tracks.py (HSPs ≤10 kb apart → arrays ≥200 bp; flips with panel_canonical_spec.tsv + gbs_tags/panel/<base>.sizes). Record: sync/2026-09-03/repeat_karyotype/PIPELINE_repeat_karyotype_2026-09-03.sh |
build_ribbon_v2.py reads /data/hop_data/repeat_karyotype_v4/v5b/repeat_tracks_v4.tsv by REV_ALIAS[haplotype] and asserts contig_len == row length |
GAP. build_repeat_tracks.py has a hard-coded HAPS dict. The Cascade raw BLAST (cascade_hopbase_v4.tsv, v5b/cascade_hopbase_hsr0.tsv) exists but is not wired in |
| NA/EU ancestry tiles | sync/2026-09-29/universal_introgression_atlas/ u03_support.py (U3) + u10_native_geometry.py (universal_tiles.tsv) |
joined by REV_ALIAS[frame]; lift=='ok' only |
GAP. The Cascade tiles that exist are in the deposit frame under alias "Cascade", not Cascade_hopbase, so they are skipped. A new alias that matches a tile frame without U3 rows raises a KeyError |
| F markers | sync/2026-09-28/f_segments/tables/B40_locations_all_frames.tsv → u03_support.py → U6_features.tsv (F_location) |
by frame | GAP (needs the assembly as a frame in f_segments) |
| Candidate loci | annevo_eval/scripts/atlas_candidate_loci.py |
drawn on M21 rows only | n/a for new rows |
| Karyotype figure (k-mer + BLAST + telomere + miniprot) | skill hop-karyotype-hic; sync_archive/2026-07-18/saaz_1012_karyotype/scripts/kmer_density.py; /data/hop_data/ref_21110M_karyotype/run.sh; /data/hop_data/Saaz_1012_karyotype/run_{kmer,miniprot}.sh |
not in the atlas | COPY-AND-EDIT |
| DEEPSPACE riparian | skill deepspace; annevo_eval/scripts/run_deepspace_noEC.R (clean_windows(..., refGenome="drHumLupu", preset="dist fast", minChrLen=1e7)) |
not in the atlas | GENERIC-ish; the inputs must be renamed and pre-oriented first |
Gotchas
- The old blast_repeat_map/*_blast.tsv files mix hand and Akagi numbering. Fingerprint each file with Saaz40: Chr08 means Akagi, Chr01 means hand (M/blast-panel-coordinate-systems.md).
- panel_consensus.fa has a wrong HuluTR120; use the v4 panel (REPEAT_KARYOTYPE_NOTE.md).
Build the reference. Template: sync/2026-09-11/apollo_hap1_akagi_linear/build_ref_apollo_h1.sh + finalize_ref.sh.
1. Decompress the exact FASTA used in the graph (/data/hop_data/v5_inputs_gz/<x>.fa.gz), or the S3-oriented FASTA, into a fresh directory. Never use a same-name copy (S3 gotchas).
2. Index it:
- samtools faidx;
- classic bwa index (bwa 0.7.17/0.7.18; annevo_eval/tools/bin/bwa); pbrun cannot read bwa-mem2 indexes;
- optional samtools dict (sync/2026-09-11/saaz_parental_refs/scripts/build_hl1012_oriented_index.sh).
3. Run bwa index detached (about 45–60 min) on a hard link of the FASTA.
- A killed run leaves .amb/.ann/.pac behind and looks complete (annevo_eval/docs/ASSAYS.md §4.2f).
4. Gates:
- GATE1: per-chromosome md5 equals the graph PanSN frame, on the same strand.
- GATE2: .ann length equals the .fai total.
- GATE3: a 150 bp probe re-aligns to its origin, with a negative control.
Stage the reference.
1. Copy it to PBSS s3://general-purpose/skothenhill/archive/ref_<name>/ with cluster/lepton_linear/upload_refs.sh.
- The script hard-codes three references. Add a case branch.
2. For Lepton, relay through AWS s3://bionemofw (annevo_eval/data_inventory/aws_bridge.sh) into fs1 /mnt/fs1/skothenhill/linear/shared/ref_<name>/. Lepton reads PBSS at about 0.02 MB/s (M/lepton-pbss-path-degraded.md).
Align (GENERIC).
- Write a new cluster/lepton_linear/config/<pop>_<ref>.env; never fork linear_job.sh (config/_common_notes.txt).
- Keys: REF_URI, REFBASE, REGION_SEQS (chromosomes in .fai order; asserted), SHEET_NAME, MARKDUP/GBS_BATCH, CALL_FF, MIN_MQ_SET, …
- Run upload_inputs.sh <cfg> → submit_linear.py <cfg> (README cluster/lepton_linear/README.md).
- Duplicates: GBS gets --no-markdups; WGS gets markdup. Gate: samtools view -c -f 1024.
Dosage multi-reference (COPY-AND-EDIT). Record: sync/2026-09-25/per_chromosome_dosage_multiref/{PIPELINE.sh,scripts/}.
- Build:
- 00a_build_saaz_ref.py (accession → Akagi, Chr01–05 reverse-complemented);
- 00b_build_refs_local.sh (HL1012 h1 X+Y + decoys via sync/2026-09-24/nor_xy_hic_hl1012/scripts/build_ref.py).
- Check: 00c/00f orientation.
- Upload: 00e_upload_refs.sh (md5 to ref_md5.tsv).
- Align and count: lepton/submit_pcd.py <ref> --bundle wgsmd (WGS markdup on), then count_one_v2.sh and ab_hist.py.
- Register: scripts/mr_config.py REFS[tag]={fai,seqs,label,frame} + ORDER. Add a branch in sexchrom_bins() for X/PAR/Y.
- Then edit the hard-coded lists in build_all_cn.sh, validate_cn.py, check_cn_browser.py (REFS,POPS), v1 build_all.py, build_cn.py (CALLSRC,FRAME,REFHAP) (DOSAGE.md §2–3).
- DOSAGE.md §3: "There is no tested procedure."
Competitive multi-reference (KR): sync/2026-09-30/cordifolius_KR_multiref/ m01_build_refs.py concatenates references with A_/B_/O_ prefixes.
Methods packages
- annevo_eval/methods/autosomal_dosage is reference-agnostic, but its PAR rule is hard-coded for the 21110M frame (234.0 Mb). Other frames treat X as xspec.
- annevo_eval/methods/sexchrom_dosage (pan-X k-mers drawn from 9 panel X assemblies) would need its k-mer sets rebuilt. GAP: no procedure for that (METHOD.md).
Gotchas
- The Wye 250 bp parents crashed pbrun. The fix was to trim, use --low-memory, and crop to 150 bp (09-25 README).
- The v1 dosage run used --no-markdups on WGS, which was wrong and was redone as wgsmd.
Versions so far (annevo_eval/docs/PANGENOME_V4.md, PANGENOME_V5.md, PANGENOME_ALIGNMENT_PROVENANCE.md):
| Version | Haplotypes | Added | Built by | Status |
|---|---|---|---|---|
| v1 | 2 | Apollo h1/h2 | EOS annevo_eval/scripts/apollo_pangenome_cactus_eos.sh |
inputs renamed but not oriented → fake inversions |
| v2 | 4 | + 21110M h1/h2 | EOS annevo_eval/cluster/apollo_graph/apollo_pangenome_v2.sbatch + apollo_dip_v2.seqfile |
all held alignments are v2 |
| v3 | 7 | + drHumLupu, Saaz, HL1012 | Lepton annevo_eval/cluster/apollo_mapping/lepton/lepton_cactus_v3.py |
— |
| v4 | 11 | + MN1421 h1/h2, MN586 h1/h2 | Lepton lepton_cactus_v4.py; provenance annevo_eval/scripts/v4_pangenome_provenance.sh |
— |
| v5 | 13 | + Saaz_h2, HL1012_h2 | Lepton lepton_cactus_v5_final.py, 24.2 h, gpu.8xh100-sxm |
current |
cluster/cascade_all13_v5/README_v2.md). No v6 exists.Steps (v5 as built)
1. Inputs: S3-oriented FASTA with Akagi names, gzipped into /data/hop_data/v5_inputs_gz/ and pushed to s3://bionemofw/users/skothenhill/hop_v5_inputs_gz/.
- The seqfile sample name becomes the PanSN prefix <sample>#0#<contig>. Contig names are not normalised.
2. Build:
cactus-pangenome <jobstore> v5.seqfile --outDir out --outName apollo_dip_v5 --reference Apollo_h1 Apollo_h2 M21_H1 M21_H2 drHumLupu MN1421_h1 MN586_h1 --vcf --gbz --gfa --giraffe clip --mgCores 128 --consCores 128
quay.io/comparative-genomics-toolkit/cactus:v2.9.3.--mgSplit (M/pangenome-tooling-versions.md).--reference, or clip drops it.minigraph -c runs 8.5 h as a single Toil job, longer than the EOS/ORD 4 h wall.annevo_eval/cluster/apollo_eos/v5_cactus_eos.sbatch, annevo_eval/cluster/apollo_ord/v5_cactus_ord.sbatch) but did not produce the graph.quay.io/vgteam/vg:v1.70.0: vg autoindex -G apollo_dip_v5.gbz -w giraffe -p apollo_dip_v5 -t 128 (lepton_v5_giraffe_index.py).hop_v5_index/.annevo_eval/scripts/v5_promote_all_reference.sh (vg gbwt --set-reference ×13). Node and edge counts must be unchanged. The .allref.gbwt is a 0-byte stub; never pass it to a tool.sync/2026-09-02/scripts/build_pansn_reference.py <seqfile> /data/hop_data/v5_inputs_gz <out>.--ref-paths must use name<TAB>length, and the @SQ count must be asserted (M/vg-refpaths-needs-explicit-lengths.md).tools/refpaths_fix.annevo_eval/scripts/pull_v5_graph_local.sh. /data/hop_data/apollo_graph/graph_v5/ is not on disk.Provenance consequences (PI directive 2026-07-26; PANGENOME_ALIGNMENT_PROVENANCE.md)
- A new graph version retrofits nothing. Every alignment or genotype must be re-aligned and re-genotyped and labelled *_v<N>_*.
- The PanSN FASTA, the dictionary and assembly_all_lengths.tsv must be rebuilt.
- So must everything downstream that uses graph coordinates (the GBS tag panel /data/hop_data/gbs_tags/panel/, inferred).
Known limits to re-check on any new graph
- vg call stalls: use the Zenith path instead (CLAUDE.md).
- Clipping fragments the graph: 1,055 components; 6.05 of 33.46 Gb clipped; the chr2 array 80% absent (M/v5-graph-clipping-fragmentation.md).
- No Y: all ChrY were clipped (M/v5-graph-has-no-y-chromosome.md).
- Chromosomes missing from the dictionary: 8 are excluded (ASSAYS.md).
- Memory: one vg giraffe uses about 110 GB RSS, so never run two.
How assemblies define the catalogue (annevo_eval/docs/INTROGRESSION_ATLAS_TECHNICAL.md §2; code in sync/2026-09-29/clade_ab_imputation/scripts/):
1. Whole-assembly PAFs: /data/hop_data/block_haplotype_identity/paf/<hap>.paf.gz (13 haplotypes vs male_ref.fa, minimap2 -cx asm20 --cs, 1 Mb chunks). GAP: minimap2 version unverified.
2. Parse: 01_paf_parse.py keeps primary, same-chromosome alignments per panel_canonical_spec.tsv, MAPQ ≥10.
3. Matrix: 03_build_matrix.py, depth-1 positions only.
4. Stage-1 clades: 04_stage1_clades.py + 05_stage1_eval.py, 5 Mb bins, ±0.2.
- A refs = drHumLupu, Saaz, HL1012.
- B refs = the four MN haplotypes.
5. Diagnostic sites: 06_diag_catalog.py. A site is diagnostic when ≥3 A haplotypes and ≥3 B haplotypes share different bases (29.2 M sites).
6. Successor catalogue: sync/2026-10-06/lineage_refinement/scripts/l01_hap_site_catalogue.py (71.9 M sites; hard-coded HAPS).
What adding an assembly means here
- Changing the haplotype catalogue or C00_groups.tsv invalidates all calls (hop_atlas/components/INTROGRESSION.md §4.4).
- You must re-run steps 2–5 for every cohort, plus c02t_separability.py, n03_ab_site_filter.py and n06_holdout.sh.
- By the build graph (inferred), it also invalidates:
- per-cohort counts;
- targets_* lists (targets_all.tsv.gz has no producer script: GAP);
- the KR and OSU forks;
- phasing;
- the viewer JSONs.
- The viewer JSONs have no generator (technical doc I-1).
- Decision: an assembly enters the catalogue only by explicit PI decision. Default ingest stops at S4–S6.
Gotcha. Polarity: A = REF on autosomes but B = REF on ChrX, because male_ref uses M21_H2's X (M/variants-only-site-selection-trap.md).
| Assembly | Built / obtained | Native names → Akagi | Orientation vs drHumLupu-forward | Ribbon | Graph | Linear / dosage reference | Special caveat |
|---|---|---|---|---|---|---|---|
| Apollo h1/h2 (DIY) | EOS hifiasm 0.25 --hic + YaHS 1.2.2 |
scaffold_N → Akagi via ref_frame_map_FINAL.tsv (sync/2026-09-11/apollo_apolloh1_linear/); rename script GAP |
v1 flips: h1 scaffold_{2,5,7,8,9,10}, h2 {2,3} | legacy 13 | v1–v5 (backbone) | ref_apollo_h1_bwa, apollo_h2 (09-25) |
EC over-breaks the ends; not T2T; never use apollo_hap1_ref/ |
| Apollo noEC | YaHS --no-contig-ec |
hand numbering | flips h1 {6,9,X}, h2 {2,8,9,X} | no | no | no | figure-only; FASTA/AGP/JBAT are PBSS-only |
| Cascade per-homolog | Lepton GW-A..D | from 21110M frame (inferred) | dotplots vs 21110M/drHumLupu with orient_votes.py |
no (GAP) | no | no | TENTATIVE; v2 failed its held-out gate; needs a cross for phase |
| Cascade HopBase | HopBase download | Scaffold_* → scaffold_map in the producer manifest |
Chr01–05, X flipped (direct vote) | extra row cascade_hopbase |
no | cascade (09-25) |
40% inflated; X duplicated in opposite orientation; no Y |
| drHumLupu | NCBI | NC_084793–802 kept; Akagi via CLAUDE.md map | defines the frame | legacy 13 | v3–v5 | ref_drHumLupu_bwa |
primary only; alternate GCA_963169115.1 not held |
| 21110M h1/h2 | Zenodo | already Akagi | male_ref reversed on Chr01–05+X(+Y); v5 M21 frame differs from male_ref on 7/11 |
legacy 13 (m21_h1/h2) + backbone |
v2–v5 | male_ref.fa (h1 Chr01–09+Y + h2 X) |
composite reference = cross-clade chimera |
| MN1421 / MN586 | Zenodo | already Akagi | reversed on Chr1–5(+X); un-oriented in v4/v5 | legacy 13 | v4–v5 | KR competitive (m01_build_refs.py) |
which haplotypes are mirrored is disputed; ChrY strand unresolved |
| Saaz / HL1012 (pseudo-haploid) | PlantGarden | chrN_scaffold = Akagi |
orient_v3.sh: 98/338, 64/164 contigs flipped |
legacy 13 | v3–v5 | — | v5 "Saaz" is the pseudo-haploid, not h1 |
| Saaz h1 / HL1012 h1 (principal) | ENA per accession | AP0315xx → Akagi | 00a Chr01–05 reverse-complemented |
no | no | saaz_h1, hl1012_h1 (09-25); saaz_parental_refs |
unplaced contigs not pulled |
| Saaz_h2 / HL1012_h2 | ENA batch | ENA|AP… kept in PanSN |
orient_h2.sh |
legacy 13 | v5 | — | HL1012_h2 has no sex chromosome |
| Carlsberg Apollo | NCBI FTP | Kale chr numbering (CP1499xx); map GAP | not oriented | no | no | no | not catalogued |
| KR ref-guided | RagTag onto 21110M | inherits 21110M | inherits | no | no | no | draft deleted 2026-10-02 |
v5_inputs_gz/{apollo,m21}_h{1,2}.akagi.fa.gz have no producing script. orient_v3.sh is archived to PBSS./workspace/joint_paintings_work/{chunk_stream.py,keep/*.keep,ref/male_ref.asm20.mmi} are gone, and the legacy 13 PAFs cannot be regenerated as recorded.Cascade_hopbase) would drop existing tiles.-5SP + -e GATC re-scaffold (edn5sp_assembly/): outcome unrecorded.*_JBAT.hic, noEC FASTA/AGP) are PBSS-only. The skill's local paths are stale.hop_adosage PAR rules are 21110M-only. The hop_xdosage k-mer set rebuild is undocumented.block_haplotype_identity/paf is unverified, and targets_all.tsv.gz has no producer.pansn_all13.fa.gz has 122 sequences and _v2 has 130..mmi procedure exists for linear references beyond the ribbon backbone.APOLLO_ASSEMBLY_PROCESS.md §9 still say the phased Apollo is embargoed.SAAZ_1012_REPHASE_PLAN.md still describes the CLR blocker.RIBBON.md §1 omits ChrX from the backbone flip.apollo_asm_hifiasm entry gives 114 GB RAM and says "BUSCO not run".What to generalise first (inferred from the gaps):
- orient_assembly.py: chunk → minimap2 → vote → oriented FASTA + name map + md5/read-back gate. It would replace the five precedent copies.
- ribbon_inputs.py: parameterised from the Cascade scripts, writing the five inputs + producer manifest.
- A track builder keyed on alias.
- A --ref registration helper covering upload_refs.sh + mr_config.py + the dosage lists.