d07356d76401059fbe6c2d0890b1490546a62a4e max Mon Sep 14 02:54:50 2026 -0700 hg38 Fiber-seq: reissued GM12878 data and a nucleosome density track, refs #36210 The lab reprocessed GM12878 (PM00001) and replaced the files in place under the same hash directory. Ten of its twelve files changed; a size sweep over all 41 samples confirmed no other sample is affected. This fixes the two placeholder haplotype accessibility bigWigs that covered a single base, so that overlay now draws real data for the sample that comes up by default. Its peak calls changed substantially as well, 429,883 source peaks before and 196,742 now, which is noted on the description page since figures made from the first version of the track will not reproduce for GM12878. The downloader now fetches into <file>.part and moves it into place when complete. It used curl -C - straight onto the final file, which is right for an interrupted transfer and silently corrupting when the server has replaced the file: it would have appended the tail of the new 5.2 GB hap1 file to the 512-byte stub, and the size check afterwards would have passed. It also takes an optional list of accessions now, to refresh one sample without walking all 41. Nucleosome density (all.nucleosome.coverage.bw) was sent separately and is not in the lab's own hub. It is on the server for all 41 samples and is added as a seventh data type in the compendium. Unlike every other wiggle here it is a read depth rather than a percentage, so it cannot take fixed viewLimits: the genome-wide mean runs from 25 to 142 across samples with sequencing depth and single loci reach 1.7e5. It is drawn with autoScale, which the description page explains, and reads as the complement of the accessibility signal. diff --git src/hg/makeDb/scripts/fiberSeq/fiberSeqTrackDb.py src/hg/makeDb/scripts/fiberSeq/fiberSeqTrackDb.py index b80b193465b..f71e5574b7b 100755 --- src/hg/makeDb/scripts/fiberSeq/fiberSeqTrackDb.py +++ src/hg/makeDb/scripts/fiberSeq/fiberSeqTrackDb.py @@ -186,56 +186,57 @@ s = byAcc[acc] out += stanza(8, [ "track fiberSeqAcc_%s" % acc, "parent fiberSeqAcc", "type bigWig", "bigDataUrl %s/%s/all.percent.accessible.bw" % (gbdb, acc), "color %s" % color, "shortLabel %s" % s["sample"], "longLabel %s Fiber-seq percent-accessible chromatin, both haplotypes" % s["sample"], ]) return out def compendium(gbdb, dataUrlDir, samples): - """One faceted composite over all six per-sample data types. + """One faceted composite over all seven per-sample data types. Accessibility and CpG methylation are read off the same molecules in the same experiment, so they belong in one table: the user picks a sample once, and cartDump.c assigns priority with the data element as the outer loop and - the data type as the inner one, which keeps a sample's six subtracks + the data type as the inner one, which keeps a sample's seven subtracks contiguous in the image. Split across two composites they would draw as an accessibility block followed by a methylation block, and comparing the two for one sample would mean reading across every other sample. """ out = stanza(4, [ "track fiberSeqCompendium", "parent fiberSeq", "compositeTrack faceted", "type bigWig", "shortLabel Fiber-seq Compendium", - "longLabel Fiber-seq accessibility, FIRE peaks and CpG methylation " - "in %d samples" % len(samples), + "longLabel Fiber-seq accessibility, peaks, nucleosomes and CpG " + "methylation in %d samples" % len(samples), "metaDataUrl %s/fiberSeqCompendium_metadata.tsv" % dataUrlDir, "colorSettingsUrl %s/fiberSeqCompendium_colors.json" % dataUrlDir, "primaryKey Accession", # Declared order sets the order of the data type checkboxes, and of the # subtracks within each sample. No data type name may contain an # underscore: hgTrackUi globs "<composite>_*_<dataType>_sel". 'dataTypes acc|"Percent accessible" peaks|"FIRE peaks" ' - 'hap|"Haplotype accessibility" cpg|"CpG methylation" ' + 'hap|"Haplotype accessibility" nuc|"Nucleosome density" ' + 'cpg|"CpG methylation" ' 'cpgHap|"Haplotype CpG" cpgDiff|"CpG haplotype difference"', "defaultSortField Accession", "defaultGroupBy sample", "maxCheckboxes 50", "noInherit on", "visibility hide", "priority 2", ]) for i, s in enumerate(samples): acc, name = s["accession"], s["sample"] # A clean cross-product on a first visit: three samples, and the three # data types that answer the question the merge is for, accessibility # next to methylation. on = "on" if acc in DEFAULT_SELECTED else "off" @@ -288,69 +289,91 @@ "scoreFilterLimits 0:1000", "mouseOver <b>%s FIRE peak</b><br>FIRE score: ${signalValue}" "<br>-log10 FDR: ${qValue}<br>Score: ${score}" % name, "onlyVisibility dense", pri(1), ]) out += hapOverlay(gbdb, acc, name, "hap", "hap1.percent.accessible.bw", "hap2.percent.accessible.bw", "%s Hap1/2" % name, "%s Fiber-seq percent accessible, haplotype 1 (blue) " "and 2 (orange)" % name, "%s Fiber-seq percent accessible, haplotype" % name, "maximum", pri(2)) + # Nucleosome density is read depth, not a percentage, so unlike every + # other wiggle here it cannot have fixed viewLimits: the per-sample mean + # runs from 25 (PS00971) to 142 (GM12878) purely with sequencing depth, + # and single loci spike into the hundred thousands. autoScale per + # window is the only setting that shows all 41 samples usefully, and + # absolute values are not comparable between samples anyway. + out += stanza(8, [ + "track fiberSeqCompendium_%s_nuc" % acc, + "parent fiberSeqCompendium off", + "type bigWig", + "bigDataUrl %s/%s/all.nucleosome.coverage.bw" % (gbdb, acc), + "shortLabel %s Nuc" % name, + "longLabel %s Fiber-seq nucleosome density, both haplotypes" % name, + "color 0,158,115", + "autoScale on", + "alwaysZero on", + "windowingFunction mean", + "maxHeightPixels 100:40:8", + "onlyVisibility full", + pri(3), + ]) + out += stanza(8, [ "track fiberSeqCompendium_%s_cpg" % acc, "parent fiberSeqCompendium %s" % on, "type bigWig 0 100", "bigDataUrl %s/%s/cpg.combined.bw" % (gbdb, acc), "shortLabel %s CpG" % name, "longLabel %s CpG methylation, both haplotypes" % name, "color 0,0,0", "viewLimits 0:100", "autoScale off", "windowingFunction mean", "maxHeightPixels 100:40:8", "onlyVisibility full", - pri(3), + pri(4), ]) out += hapOverlay(gbdb, acc, name, "cpgHap", "cpg.hap1.bw", "cpg.hap2.bw", "%s CpG Hap1/2" % name, "%s CpG methylation, haplotype 1 (blue) and 2 (orange)" % name, "%s CpG methylation, haplotype" % name, - "mean", pri(4)) + "mean", pri(5)) out += stanza(8, [ "track fiberSeqCompendium_%s_cpgDiff" % acc, "parent fiberSeqCompendium off", "container multiWig", "aggregate solidOverlay", "showSubtrackColorOnUi on", "type bigWig -100 100", "viewLimits -100:100", "autoScale off", "windowingFunction mean", "maxHeightPixels 100:50:8", "shortLabel %s CpG diff" % name, "longLabel %s CpG methylation difference between haplotypes, " "by significance threshold" % name, "onlyVisibility full", - pri(5), + pri(6), ]) # Least significant first, so the more significant levels draw on top. for i, (fname, label, color) in enumerate(DIFF_LEVELS): out += stanza(12, [ "track fiberSeqCompendium_%s_cpgDiff_l%d" % (acc, i), "parent fiberSeqCompendium_%s_cpgDiff" % acc, "type bigWig", "bigDataUrl %s/%s/%s" % (gbdb, acc, fname), "color %s" % color, "shortLabel %s %s" % (name, label), "longLabel %s CpG haplotype difference, %s" % (name, label), ]) return out @@ -414,25 +437,25 @@ f.write("# Fiber-seq: chromatin accessibility, FIRE regulatory elements and CpG\n" "# methylation from PacBio HiFi Fiber-seq, Stergachis and Vollger labs.\n" "# Generated by hg/makeDb/scripts/fiberSeq/fiberSeqTrackDb.py.\n" "# Do not edit by hand, edit the script and regenerate.\n\n") f.write(stanza(0, [ "track fiberSeq", "superTrack on show", "shortLabel Fiber-seq", "longLabel Fiber-seq chromatin accessibility, regulatory elements and CpG methylation", "group regulation", "priority 2.5", ])) f.write(accOverlay(args.gbdb_dir, samples)) f.write(compendium(args.gbdb_dir, args.gbdb_dir, samples)) - # Per sample: acc, peaks, cpg, three container stanzas (hap, cpgHap, + # Per sample: acc, peaks, nuc, cpg, three container stanzas (hap, cpgHap, # cpgDiff) and their 2 + 2 + 4 children. - nSub = len(DEFAULT_OVERLAY) + len(samples) * (3 + 3 + 8) + nSub = len(DEFAULT_OVERLAY) + len(samples) * (4 + 3 + 8) print("wrote %s" % raPath) print(" %d samples, %d track stanzas" % (len(samples), nSub + 3)) print(" metadata and colors in %s" % args.data_dir) if __name__ == "__main__": main()