b914d581f876d486caf9404e715e4f61ada38195 mspeir Mon Aug 3 16:19:44 2026 -0700 singleCellSignalsPeaks: make every subtrack label unique, fix cell-class regressions The harmonized labels were not distinguishing tracks. build_long_label composed from cell type + condition + tissue, but the upstream steps discard the discriminators on purpose to keep the facets compact, so hg38 had 925 subtracks sharing only 401 distinct longLabels and mm10 629 sharing 359. Worst case: cortex-atac's MACS, enhancer and cell-type-specific peak sets all read "Astrocytes and oligodendrocytes (Cortex ATAC)", with the peak method surviving only in the raw shortLabel. Labels are now built from the harmonized cell type plus a variant descriptor that recovers what was dropped (peak method, grouping level, cohort, signal vs peaks), and anything still colliding is qualified with its source cluster code. shortLabels are rebuilt too -- the old ones were raw source strings up to 50 chars with underscores, ArchR filename tails and R-mangled names -- abbreviated through a curated word table to 22 chars, with compact tokens where the longLabel distinction would otherwise be invisible (SEA-AD region + ADNC, CATLAS aging age). All 925/587 longLabels are now unique; no shortLabel exceeds 22 chars or contains an underscore. Also fixed, found while verifying the above: - Correcting source misspellings in the cell types broke the curated lookups, which are keyed on those same misspelled strings, and 16 hg38 tracks silently lost their Cell_class and color. The class map and the hub_config tables now normalize their keys on load, and a cell type with no broad class is reported instead of becoming "unknown". - Nephron progenitor was classed as Neural progenitor: the decode tables give it the bare broad class "Progenitor" and that was blanket-mapped to neural. It is Six2+ kidney cap mesenchyme, so it is now Stromal. The HTML legend had been worded to match the bug. - The plural/case merge picked the most frequent form, which was inconsistent -- singular for 15 of 17 merged groups but plural for Megakaryocytes/Oligodendrocytes. It now prefers the singular. - Removed 42 byte-identical Allen basal-ganglia bigWigs (md5-verified) that were served from four grouping directories and rendered as four indistinguishable mm10 subtracks, freeing 4.4 GB. Where the four copies genuinely differ all are kept and told apart by the grouping-level descriptor. mm10 goes 629 -> 587 subtracks. - Corrected five stale per-dataset subtrack counts in the description pages and spelled out what ADNC means, noting that it grades neuropathology rather than symptoms. - The SEA-AD Dataset facet link used the collection name, which is not a served Cell Browser slug; it now points at sea-ad-mtg+cohort. - Dropped a dead placeholder variable and made the hardcoded hub-build path overridable. refs #37914 Co-Authored-By: Claude Opus 5 (1M context) diff --git src/hg/makeDb/scripts/singleCellSignalsPeaks/copySingleCellSignalsPeaksFiles.py src/hg/makeDb/scripts/singleCellSignalsPeaks/copySingleCellSignalsPeaksFiles.py index f54ff1839fe..9181b286aea 100644 --- src/hg/makeDb/scripts/singleCellSignalsPeaks/copySingleCellSignalsPeaksFiles.py +++ src/hg/makeDb/scripts/singleCellSignalsPeaks/copySingleCellSignalsPeaksFiles.py @@ -9,31 +9,35 @@ (resolved from the hub manifest by served relative path) to /hive/data/genomes//bed/singleCellSignalsPeaks/ The served subpath is preserved on purpose: some peak-file basenames repeat across datasets, so a flat directory would clobber them, and keeping the subpath lets the /gbdb//bbi/singleCellSignalsPeaks symlink resolve every bigDataUrl. It also copies the composite's facet metadata to /singleCellSignalsPeaks_metadata.tsv (the track's metaDataUrl target). Usage: copySingleCellSignalsPeaksFiles.py [--assembly hg38|mm10] [--dry-run] """ import re, os, shutil, argparse from urllib.parse import urlparse -HUB_BUILD = "/hive/users/mspeir/claude/cell-browser/all-tracks-hub-build" +# Where the hub build writes manifest.tsv. That machinery builds the whole Cell Browser +# super hub, not just this track, so it lives outside the kent tree; override with +# HUB_BUILD when it moves (or pass --manifest). +HUB_BUILD = os.environ.get( + "HUB_BUILD", "/hive/users/mspeir/claude/cell-browser/all-tracks-hub-build") TRACK = "singleCellSignalsPeaks" def load_relpath_to_abs(manifest, asm): m = {} with open(manifest) as fh: hdr = fh.readline().rstrip("\n").split("\t") ai, ui, asmi = hdr.index("abs_path"), hdr.index("track_url"), hdr.index("assembly") for line in fh: f = line.rstrip("\n").split("\t") if len(f) <= max(ai, ui, asmi) or f[asmi] != asm: continue m[urlparse(f[ui]).path.lstrip("/")] = f[ai] return m def main():