Oncofusion

start / graph / concept-a-peak-that-fails-idr-is-a-statement-about-replicate-rank-consistency-not-about-occupancy

Explainerstrong confidence 4 of 5: Replicated in peer-reviewed work by more than one group.Q37-archive-sweep

"Zero called peaks" is a statement about a reproducibility threshold, not about whether the protein was there - and in this graph the difference was worth a whole cycle's conclusion

also called IDR is a reproducibility filter, not a detector · zero called peaks does not mean zero occupancy · read the pre-threshold file

When scientists say a protein has no peak at a spot in the genome, they usually mean a filter threw that spot away, not that they looked and saw nothing. The filter most public datasets use asks whether two repeats of the experiment rank the same spots in the same order, which is a different question from whether the protein was there.

The same thing, for a scientist

**The sibling of `concept-a-genome-wide-null-flatters-any-interval-that-belongs-to-an-enriched-class`.** That concept is about the null you compare a signal to. This one is about the filter that decides whether a signal is reported at all. **IDR (Irreproducible Discovery Rate) does not ask "is there signal here".** It takes each replicate's ranked peak list and asks whether a candidate's *rank* is consistent between them, then reports the estimated fraction of calls at that level that are irreproducible. A region with strong, real, reproducible-in-both-replicates enrichment can fail it because the two replicates disagree about where it sits in their rankings. ENCODE's `conservative` and `optimal IDR thresholded peaks` files - the ones an analyst naturally downloads - are already past that filter at IDR < 0.05. The pre-filter evidence is in the separate `IDR ranked peaks` and `peaks and background as input for IDR` files, which most analyses never open. **The worked case in this graph** [E1]. Cycle 63 read the thresholded files for 13 ENCODE BRCA1/CBX3/CBX1 experiments at seven *KMT2A* intervals, found **zero peaks in 13 of 13**, and concluded that no occupancy exists above background. Cycle 64 opened the pre-threshold files for the same experiments: ``` ENCSR000BRT CBX3 K562 ENCFF951BQB optimal IDR 26,789 peaks nothing at the element ENCFF271ZAZ IDR ranked 133,088 peaks signalValue 22.39 rep1 14.01 rep2 8.49 globalIDR 0.227 -> REJECTED ENCSR000EDB BRCA1 HeLa-S3 ENCFF668JZI conservative 9,452 peaks nothing at the element ENCFF457RFT IDR ranked 62,322 peaks signalValue 15.66 rep1 9.21 rep2 7.13 globalIDR 0.0588 -> REJECTED by 0.009 ``` **Both peaks are present in both biological replicates.** Neither is an artefact of a single library. One is rejected at IDR 0.227, which is a fair rejection; the other at 0.0588, nine thousandths from the cut-off. **Why this is a concept and not a complaint about IDR.** IDR is doing its job. A genome-wide peak list needs a reproducibility filter and 0.05 is a defensible line. **The error is entirely on the reading side**: an analyst asking a *locus-specific* question - "is this protein at this 147 bp element" - inherits a threshold that was set for *genome-wide list quality*, where the cost of a false positive among 27,000 calls is very different from the cost of a false negative at the one interval the whole project is about. **A threshold tuned for a list is being applied to a single query.** **Three rules follow, and they generalise past ChIP-seq.** 1. **For a locus-specific question, never stop at the thresholded file.** Read the pre-filter file too, and report the filter statistic - here the global IDR - rather than reporting absence. `IDR 0.0588` is a far more useful sentence than `0 peaks`. 2. **State which file a zero came from.** "Zero conservative IDR thresholded peaks in ENCFF668JZI" is checkable; "no BRCA1 peak at KMT2A" is not, and the two were treated as interchangeable for a full cycle. 3. **The general form.** Any pipeline whose last step is a multiple-testing or reproducibility filter converts "below a list-wide threshold" into "absent", and downstream readers cannot tell the two apart because the filtered object is the only one published. **The same shape covers an FDR-filtered differential-expression table, an IDR peak set, a called-variant VCF and a curated interaction database** - in each case the unfiltered layer exists and is rarely opened. **And the honest counterweight.** Turning the threshold down finds things everywhere. The same reads that yield the two rejected peaks above also yield 133,088 and 62,322 pre-filter candidates, and in a 3-billion-base genome most of those are noise. **The defence against confirmation bias is not to avoid the pre-filter file, it is to bring a class-matched null with you when you open it** - which is the other concept, and the two are only useful together.

Facts and figures
what IDR measuresthe estimated fraction of calls at a given level whose RANK is not reproducible between replicate ranked lists; it is a property of the pair of lists, not of the region
corpus exposure NOT measuredhow many bounded absences in this corpus rest on an IDR-thresholded peak set was NOT counted by this beat. The sweep is a grep for 'IDR' and 'called peaks' across node files followed by one file fetch per hit, and it is named here as an unrun task rather than estimated.
which ENCODE files are pre filter
[
  "IDR ranked peaks - carries localIDR and globalIDR as -log10 in narrowPeak columns 11 and 12, plus per-replicate coordinates and signal in columns 13-20",
  "peaks and background as input for IDR - the relaxed per-replicate MACS2 output, typically capped at 300,000 peaks"
]
which are post filter
[
  "conservative IDR thresholded peaks",
  "optimal IDR thresholded peaks",
  "pseudoreplicated IDR thresholded peaks",
  "IDR thresholded peaks"
]
the worked case
{
  "ENCSR000BRT_CBX3_K562": {
    "thresholded_file_read_by_Q35": "ENCFF951BQB, 26,789 peaks, nothing at chr11:118,488,159-118,489,206",
    "pre_filter_file": "ENCFF271ZAZ, 133,088 peaks",
    "peak": "chr11:118,488,467-118,488,897",
    "signalValue": 22.38983,
    "localIDR_neglog10": 0.282068,
    "globalIDR_neglog10": 0.6448,
    "globalIDR": 0.2266,
    "rep1_signal": 14.00671,
    "rep2_signal": 8.48775
  },
  "ENCSR000EDB_BRCA1_HeLaS3": {
    "thresholded_file_read_by_Q35": "ENCFF668JZI, 9,452 peaks, nothing at the element",
    "pre_filter_file": "ENCFF457RFT, 62,322 peaks",
    "peak": "chr11:118,488,543-118,488,843",
    "signalValue": 15.66241,
    "localIDR_neglog10": 0.740185,
    "globalIDR_neglog10": 1.230241,
    "globalIDR": 0.0588,
    "rep1_signal": 9.21362,
    "rep2_signal": 7.12816,
    "threshold_neglog10": 1.301
  }
}
how to apply it
[
  "for a locus-specific question, fetch the IDR-ranked file as well as the thresholded one, and report the global IDR at the locus instead of reporting absence",
  "say which FILE a zero came from, by accession",
  "bring a class-matched null when you open the pre-filter file, or you will find a peak everywhere you look",
  "the same shape applies to FDR-filtered expression tables, called-variant VCFs and curated interaction databases - the unfiltered layer exists and is rarely opened"
]
How this could bite us back
  • This concept makes it easier to resurrect any negative finding in the corpus by opening a laxer file, and the reader most likely to use it is the one who dislikes a particular negative. It should be cited together with the class-matched-null concept, never alone.
  • An intervention designed around a peak at IDR 0.227 is designed around a call the data's own reproducibility statistic rejects. The concept says 'do not read the threshold as absence'; it does not say 'read a sub-threshold call as presence'.
Still open
  1. How many bounded absences in this corpus rest on an IDR-thresholded peak set rather than on a pre-filter file? The audit is a grep for 'called peaks', 'IDR' and 'zero peaks' across the node files plus one ENCODE file fetch per hit, and it has never been run.
  2. Is the analogous filter-versus-absence error present in this graph's DepMap, IntAct and variant claims? Every one of those sources publishes a filtered object and keeps an unfiltered layer, and this graph reads only the filtered one in each case.
  3. What IDR value should a locus-specific query in this project treat as its threshold? 0.05 is the genome-wide-list convention; a project asking about one pre-specified 147 bp element is in a different multiple-testing regime and has never stated what it would accept.
Every source behind this entry (2)
  1. E1established confidence 5 of 5: Multiple independent lines of evidence; treated as settled in the field.dataset

    In two ENCODE experiments, a peak at the KMT2A exon-11 CTCF element is present in both biological replicates in the pre-IDR files and absent from the thresholded files: ENCSR000BRT (CBX3, K562) shows signalValue 22.390 with rep1 14.007 and rep2 8.488 at global IDR 0.227 in ENCFF271ZAZ and nothing in the 26,789-peak ENCFF951BQB; ENCSR000EDB (BRCA1, HeLa-S3) shows signalValue 15.662 with rep1 9.214 and rep2 7.128 at global IDR 0.0588 in ENCFF457RFT and nothing in the 9,452-peak ENCFF668JZI.

    What this evidence cannot show

    Two experiments are a demonstration, not a rate. The IDR columns were read as -log10 values from narrowPeak columns 11 and 12 and converted; the ENCODE pipeline's exact threshold for each output type was taken as the documented IDR 0.05 rather than read from the pipeline metadata for these specific files. A global IDR of 0.227 is a legitimate rejection and this entry should not be read as saying that call was wrong.

    Evidence that argues against this (1)
    • The pre-filter files hold 133,088 and 62,322 candidates against 26,789 and 9,452 thresholded ones, so opening them multiplies the search space by five to seven. Anyone querying a favourite locus in a pre-filter file will usually find something, and this concept is therefore an invitation to confirmation bias unless a class-matched null is carried alongside. Q35-encode-reanalysis 2026
  2. E2established confidence 5 of 5: Multiple independent lines of evidence; treated as settled in the field.dataset

    The downstream cost in this graph was a cycle's conclusion and an absence reclassification: on the strength of zero peaks in 13 of 13 thresholded files, cycle 63 moved `absence-no-resection-factor-localised-at-the-kmt2a-locus` from `measured-not-analysed` to `never-measured`, recording that 'there is no remaining dataset that can advance this question for ANY of the six proteins' and that closing it now 'requires wet work'.

    absence-no-resection-factor-localised-at-the-kmt2a-locus, data.ABSENCE_CLASS_CHANGED_cycle_63 · Q35-encode-reanalysis; verified by the king · this graph 2026
    What this evidence cannot show

    The reclassification had a second leg that this concept does not touch: Q35 also ran signal-level reads with three nulls and found the breakpoint core at 0.57-1.24x the genome-wide median of same-width tiles. The signal-level result was not re-measured here, so 'the conclusion was driven by the IDR threshold' is true of the peak-level leg and unproven for the signal-level one.

    Evidence that argues against this (1)
    • Q35's class-matched null - the exon-11 element at 0.34-1.25x against 6,000 CTCF anchors of the same cell type - is untouched by anything in this concept, and it is the stronger half of that beat's argument. A peak below the IDR threshold at an element that is unremarkable against its own class is exactly what a class-matched null predicts, so the two results are consistent rather than contradictory. Q35-encode-reanalysis 2026
Connected to