Skill Tracer
Skills › Scientific Agent Skills › geniml › consensus_peaks.md

consensus_peaks.md

350 lines · skills/geniml/references/consensus_peaks.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Consensus peaks and universe assessment
2
3Verified against `geniml==0.8.4` release source and official BEDbase
4documentation on 2026-10-01.
5

Consensus peaks and universe assessment

Verified against geniml==0.8.4 release source and official BEDbase documentation on 2026-10-01.

Raw lines 1 to 5
6## Method scope
7
8A Geniml universe is a reference interval vocabulary derived from coverage
9across a collection of BED files. Release 0.8.4 implements:
11- **CC**: coverage cutoff;
12- **CCF**: coverage cutoff with flexible core/boundary fields;
13- **ML**: maximum-likelihood flexible universe;
14- **HMM**: hidden-state model over start/core/end coverage.
16Primary source: Rymuza et al. (2024), *Methods for constructing and evaluating
17consensus genomic interval sets*,
18doi:[10.1093/nar/gkae685](https://doi.org/10.1093/nar/gkae685).
20The paper motivates and evaluates these methods; it does not make one method
21universally best. Choose using training-only data, assay-specific validation,
22resource constraints, and held-out universe-fit metrics.

Method scope

A Geniml universe is a reference interval vocabulary derived from coverage across a collection of BED files. Release 0.8.4 implements:

  • CC: coverage cutoff;
  • CCF: coverage cutoff with flexible core/boundary fields;
  • ML: maximum-likelihood flexible universe;
  • HMM: hidden-state model over start/core/end coverage.

Primary source: Rymuza et al. (2024), Methods for constructing and evaluating consensus genomic interval sets, doi:10.1093/nar/gkae685.

The paper motivates and evaluates these methods; it does not make one method universally best. Choose using training-only data, assay-specific validation, resource constraints, and held-out universe-fit metrics.

Raw lines 6 to 23
24## Non-negotiable input contract
26All source BED files and chromosome sizes must agree on:
28- assembly/accession and patch;
29- 0-based half-open BED coordinates;
30- chromosome/contig naming and inclusion policy;
31- sort order;
32- duplicate and overlap handling;
33- strand interpretation;
34- liftover provenance, if any.
36Reject malformed rows, negative starts, `end <= start`, coordinates beyond
37contig length, unknown contigs, mixed assemblies, and integer overflow before
38coverage generation. A chromosome name match alone is not proof of assembly
39compatibility.
41Build the universe only from the training patients/donors. If samples from a
42held-out patient contribute to coverage, the resulting vocabulary leaks test
43feature prevalence.
45```bash
46python skills/geniml/scripts/corpus_auditor.py \
47 --manifest data/train_manifest.tsv \
48 --group-column patient_id \
49 --split-column split \
50 --assembly-column assembly
51```

Non-negotiable input contract

All source BED files and chromosome sizes must agree on:

  • assembly/accession and patch;
  • 0-based half-open BED coordinates;
  • chromosome/contig naming and inclusion policy;
  • sort order;
  • duplicate and overlap handling;
  • strand interpretation;
  • liftover provenance, if any.

Reject malformed rows, negative starts, end <= start, coordinates beyond contig length, unknown contigs, mixed assemblies, and integer overflow before coverage generation. A chromosome name match alone is not proof of assembly compatibility.

Build the universe only from the training patients/donors. If samples from a held-out patient contribute to coverage, the resulting vocabulary leaks test feature prevalence.

python skills/geniml/scripts/corpus_auditor.py \
  --manifest data/train_manifest.tsv \
  --group-column patient_id \
  --split-column split \
  --assembly-column assembly
Raw lines 24 to 52
Runs code python skills/geniml/scripts/corpus_auditor.py :46
53## Coverage prerequisites
55Geniml consumes bigWig tracks in a local coverage directory. With the default
56prefix `all`, methods expect:
58```text
59all_start.bw
60all_core.bw
61all_end.bw
62```
64CC and CCF read `all_core.bw`. HMM and likelihood-based methods use
65start/core/end tracks. The tracks must share contigs and lengths with the
66checksummed chromosome-sizes file. CC, CCF, and HMM cast coverage to uint16:
67require finite nonnegative integer counts no greater than 65,535. Fractional
68coverage is truncated and larger counts can wrap. Do not feed normalized
69BigWigs into these methods without verifying the required count semantics.
71Official Geniml pages describe producing these tracks with the ecosystem's
72coverage tooling, but the current Gtars CLI has changed across releases. Do not
73emit or run a guessed `uniwig` command. Pin the exact Gtars/uniwig executable,
74capture its `--help`, and smoke-test its output naming on synthetic local BED
75data. Record:
77- tool version and binary SHA-256;
78- complete argv (not a shell-expanded wildcard);
79- chromosome-sizes SHA-256;
80- ordered input manifest and checksums;
81- smoothing/binning parameters;
82- output track sizes, contigs, lengths, and checksums.
84The bundled planner validates local inputs and emits the Geniml stage, but
85intentionally marks coverage generation as an external prerequisite:
87```bash
88python skills/geniml/scripts/consensus_plan.py \
89 --manifest data/train_manifest.tsv \
90 --chrom-sizes refs/GRCh38.chrom.sizes \
91 --assembly GRCh38 \
92 --method cc \
93 --cutoff 2 \
94 --output-dir work/consensus
95```
97It does not execute Geniml, Gtars, native binaries, or network requests.

Coverage prerequisites

Geniml consumes bigWig tracks in a local coverage directory. With the default prefix all, methods expect:

all_start.bw
all_core.bw
all_end.bw

CC and CCF read all_core.bw. HMM and likelihood-based methods use start/core/end tracks. The tracks must share contigs and lengths with the checksummed chromosome-sizes file. CC, CCF, and HMM cast coverage to uint16: require finite nonnegative integer counts no greater than 65,535. Fractional coverage is truncated and larger counts can wrap. Do not feed normalized BigWigs into these methods without verifying the required count semantics.

Official Geniml pages describe producing these tracks with the ecosystem's coverage tooling, but the current Gtars CLI has changed across releases. Do not emit or run a guessed uniwig command. Pin the exact Gtars/uniwig executable, capture its --help, and smoke-test its output naming on synthetic local BED data. Record:

  • tool version and binary SHA-256;
  • complete argv (not a shell-expanded wildcard);
  • chromosome-sizes SHA-256;
  • ordered input manifest and checksums;
  • smoothing/binning parameters;
  • output track sizes, contigs, lengths, and checksums.

The bundled planner validates local inputs and emits the Geniml stage, but intentionally marks coverage generation as an external prerequisite:

python skills/geniml/scripts/consensus_plan.py \
  --manifest data/train_manifest.tsv \
  --chrom-sizes refs/GRCh38.chrom.sizes \
  --assembly GRCh38 \
  --method cc \
  --cutoff 2 \
  --output-dir work/consensus

It does not execute Geniml, Gtars, native binaries, or network requests.

Raw lines 53 to 98
Runs code python skills/geniml/scripts/consensus_plan.py :88
99## Exact 0.8.4 CLI
101All shown CLI forms were checked against installed help. CC was executed on a
102synthetic BigWig; CCF, likelihood/ML, HMM, and assessment are source-verified
103illustrative templates, not completed end-to-end workflows in this review.
105The top-level command is `build-universe`, not `universe build`.

Exact 0.8.4 CLI

All shown CLI forms were checked against installed help. CC was executed on a synthetic BigWig; CCF, likelihood/ML, HMM, and assessment are source-verified illustrative templates, not completed end-to-end workflows in this review.

The top-level command is build-universe, not universe build.

Raw lines 99 to 106
107### CC
109```bash
110geniml build-universe cc \
111 --coverage-folder /absolute/project/coverage \
112 --coverage-prefix all \
113 --output-file /absolute/project/universe_cc.bed \
114 --cutoff 2 \
115 --merge 100 \
116 --filter-size 50
117```
119`--cutoff` is an integer. If omitted, release source uses mean base coverage
120for each chromosome. `--merge` merges nearby output segments; `--filter-size`
121removes shorter segments. The output file must not already exist.
122A tiny count-track smoke produced the exact expected BED interval. In contrast,
123all-zero selected positions, 0.5-valued tracks, and 65,536-valued tracks
124reproduced empty-selection IndexError failures. The release can leave partial
125output if a later chromosome fails; reconcile every requested chromosome.
127`merge=0, filter_size>0` enters the merging implementation and can split
128adjacent covered bases into individual bases. Until that upstream behavior is
129corrected, build with both zero and perform a separately validated BED
130length-filter/merge step when precise gap semantics matter.
132Do not claim `cutoff=number_of_files` is a strict sample intersection unless
133coverage generation contributes exactly one unit per sample at each base.
134Fragment/read coverage or duplicated intervals can violate that assumption.
136Python:
138```python
139from geniml.universe.cc_universe import cc_universe
141cc_universe(
142 cove="work/coverage",
143 file_out="work/universe_cc.bed",
144 cove_prefix="all",
145 merge=100,
146 filter_size=50,
147 cutoff=2,
149```

CC

geniml build-universe cc \
  --coverage-folder /absolute/project/coverage \
  --coverage-prefix all \
  --output-file /absolute/project/universe_cc.bed \
  --cutoff 2 \
  --merge 100 \
  --filter-size 50

--cutoff is an integer. If omitted, release source uses mean base coverage for each chromosome. --merge merges nearby output segments; --filter-size removes shorter segments. The output file must not already exist. A tiny count-track smoke produced the exact expected BED interval. In contrast, all-zero selected positions, 0.5-valued tracks, and 65,536-valued tracks reproduced empty-selection IndexError failures. The release can leave partial output if a later chromosome fails; reconcile every requested chromosome.

merge=0, filter_size>0 enters the merging implementation and can split adjacent covered bases into individual bases. Until that upstream behavior is corrected, build with both zero and perform a separately validated BED length-filter/merge step when precise gap semantics matter.

Do not claim cutoff=number_of_files is a strict sample intersection unless coverage generation contributes exactly one unit per sample at each base. Fragment/read coverage or duplicated intervals can violate that assumption.

Python:

from geniml.universe.cc_universe import cc_universe

cc_universe(
    cove="work/coverage",
    file_out="work/universe_cc.bed",
    cove_prefix="all",
    merge=100,
    filter_size=50,
    cutoff=2,
)
Raw lines 107 to 150
151### CCF
153```bash
154geniml build-universe ccf \
155 --coverage-folder /absolute/project/coverage \
156 --coverage-prefix all \
157 --output-file /absolute/project/universe_ccf.bed
158```
160Python:
162```python
163from geniml.universe.ccf_universe import ccf_universe
165ccf_universe(
166 cove="work/coverage",
167 file_out="work/universe_ccf.bed",
168 cove_prefix="all",
170```
172The stable source has no CCF `--confidence`, `--merge`, or `--filter-size`
173arguments. CCF writes BED9-like rows carrying core/boundary information; do
174not reduce them to BED3 before confirming downstream semantics.

CCF

geniml build-universe ccf \
  --coverage-folder /absolute/project/coverage \
  --coverage-prefix all \
  --output-file /absolute/project/universe_ccf.bed

Python:

from geniml.universe.ccf_universe import ccf_universe

ccf_universe(
    cove="work/coverage",
    file_out="work/universe_ccf.bed",
    cove_prefix="all",
)

The stable source has no CCF --confidence, --merge, or --filter-size arguments. CCF writes BED9-like rows carrying core/boundary information; do not reduce them to BED3 before confirming downstream semantics.

Raw lines 151 to 175
176### Likelihood model and ML universe
178The 0.8.4 likelihood command has no `build_model` subcommand:
180```bash
181geniml lh \
182 --model-file /absolute/project/model.tar \
183 --coverage-folder /absolute/project/coverage \
184 --coverage-prefix all \
185 --file-no 4
186```
188Then:
190```bash
191geniml build-universe ml \
192 --model-file /absolute/project/model.tar \
193 --coverage-folder /absolute/project/coverage \
194 --coverage-prefix all \
195 --output-file /absolute/project/universe_ml.bed
196```
198Python:
200```python
201from geniml.likelihood.build_model import main as build_likelihood
202from geniml.universe.ml_universe import ml_universe
204build_likelihood(
205 model_file="work/model.tar",
206 coverage_folder="work/coverage",
207 coverage_prefix="all",
208 file_no=4,
210ml_universe(
211 model_file="work/model.tar",
212 cove_folder="work/coverage",
213 cove_prefix="all",
214 file_out="work/universe_ml.bed",
216```
218Treat the `.tar` likelihood model as an untrusted archive if it is not locally
219created and checksummed. Inspect archive member names and reject absolute
220paths, `..`, links, devices, and excessive expansion before extraction.

Likelihood model and ML universe

The 0.8.4 likelihood command has no build_model subcommand:

geniml lh \
  --model-file /absolute/project/model.tar \
  --coverage-folder /absolute/project/coverage \
  --coverage-prefix all \
  --file-no 4

Then:

geniml build-universe ml \
  --model-file /absolute/project/model.tar \
  --coverage-folder /absolute/project/coverage \
  --coverage-prefix all \
  --output-file /absolute/project/universe_ml.bed

Python:

from geniml.likelihood.build_model import main as build_likelihood
from geniml.universe.ml_universe import ml_universe

build_likelihood(
    model_file="work/model.tar",
    coverage_folder="work/coverage",
    coverage_prefix="all",
    file_no=4,
)
ml_universe(
    model_file="work/model.tar",
    cove_folder="work/coverage",
    cove_prefix="all",
    file_out="work/universe_ml.bed",
)

Treat the .tar likelihood model as an untrusted archive if it is not locally created and checksummed. Inspect archive member names and reject absolute paths, .., links, devices, and excessive expansion before extraction.

Raw lines 176 to 221
222### HMM
224```bash
225geniml build-universe hmm \
226 --coverage-folder /absolute/project/coverage \
227 --coverage-prefix all \
228 --output-file /absolute/project/universe_hmm.bed
229```
231Use `--not-normalize` only after validating what scale the model expects.
232`--save-max-cove` adds maximum coverage information. The 0.8.4 CLI has no
233`--states` argument; the model structure is defined in source constants.
235Python:
237```python
238from geniml.universe.hmm_universe import hmm_universe
240hmm_universe(
241 coverage_folder="work/coverage",
242 out_file="work/universe_hmm.bed",
243 prefix="all",
244 normalize=True,
245 save_max_cove=False,
247```

HMM

geniml build-universe hmm \
  --coverage-folder /absolute/project/coverage \
  --coverage-prefix all \
  --output-file /absolute/project/universe_hmm.bed

Use --not-normalize only after validating what scale the model expects. --save-max-cove adds maximum coverage information. The 0.8.4 CLI has no --states argument; the model structure is defined in source constants.

Python:

from geniml.universe.hmm_universe import hmm_universe

hmm_universe(
    coverage_folder="work/coverage",
    out_file="work/universe_hmm.bed",
    prefix="all",
    normalize=True,
    save_max_cove=False,
)
Raw lines 222 to 248
249## Validate every output
251Universe builders do not replace input validation. After construction:
2531. Re-run BED validation against the same chromosome sizes.
2542. Confirm sorted, nonempty output and expected BED column count.
2553. Check region count, length distribution, covered bases, overlaps, and
256 duplicate coordinates.
2574. Confirm no unknown contigs or out-of-bounds ends.
2585. Record output SHA-256 and method parameters.
2596. Build a fresh Gtars tokenizer and record vocabulary/special-token sizes.
2607. Never reorder the universe after a model or token corpus has been created.
262Some 0.8.4 functions assume at least one selected base per chromosome and may
263index an empty result. Test sparse/empty chromosomes synthetically and fail
264closed rather than accepting a partial output.

Validate every output

Universe builders do not replace input validation. After construction:

  1. Re-run BED validation against the same chromosome sizes.
  2. Confirm sorted, nonempty output and expected BED column count.
  3. Check region count, length distribution, covered bases, overlaps, and duplicate coordinates.
  4. Confirm no unknown contigs or out-of-bounds ends.
  5. Record output SHA-256 and method parameters.
  6. Build a fresh Gtars tokenizer and record vocabulary/special-token sizes.
  7. Never reorder the universe after a model or token corpus has been created.

Some 0.8.4 functions assume at least one selected base per chromosome and may index an empty result. Test sparse/empty chromosomes synthetically and fail closed rather than accepting a partial output.

Raw lines 249 to 265
266## Assess fit to held-out collections
268The release CLI is:
270```bash
271geniml assess-universe \
272 --raw-data-folder /absolute/project/validation_beds \
273 --file-list /absolute/project/validation_files.txt \
274 --universe /absolute/project/universe_cc.bed \
275 --overlap \
276 --distance \
277 --distance-universe-to-file \
278 --folder-out /absolute/project/assessment \
279 --pref validation \
280 --no-workers 4
281```
283Available flags include:
285- `--overlap`;
286- `--distance`;
287- `--distance-flexible`;
288- `--distance-universe-to-file`;
289- `--distance-flexible-universe-to-file`;
290- `--save-to-file`;
291- `--save-each`.
293`--save-each` can generate large, sensitive per-interval outputs. Leave it off
294unless required and bound output size. The docs still show `geniml assess`;
295that is not the 0.8.4 top-level command.
297Python entry points include:
299```python
300from geniml.assess.assess import (
301 get_f_10_score,
302 get_mean_rbs,
303 run_all_assessment_methods,
305```
307F10, reciprocal-boundary-style distance summaries, and likelihood measure
308different properties. Compare multiple candidate universes on validation
309patients, then evaluate the chosen one once on test patients. Do not tune the
310cutoff, merging, or method on the test collection.

Assess fit to held-out collections

The release CLI is:

geniml assess-universe \
  --raw-data-folder /absolute/project/validation_beds \
  --file-list /absolute/project/validation_files.txt \
  --universe /absolute/project/universe_cc.bed \
  --overlap \
  --distance \
  --distance-universe-to-file \
  --folder-out /absolute/project/assessment \
  --pref validation \
  --no-workers 4

Available flags include:

  • --overlap;
  • --distance;
  • --distance-flexible;
  • --distance-universe-to-file;
  • --distance-flexible-universe-to-file;
  • --save-to-file;
  • --save-each.

--save-each can generate large, sensitive per-interval outputs. Leave it off unless required and bound output size. The docs still show geniml assess; that is not the 0.8.4 top-level command.

Python entry points include:

from geniml.assess.assess import (
    get_f_10_score,
    get_mean_rbs,
    run_all_assessment_methods,
)

F10, reciprocal-boundary-style distance summaries, and likelihood measure different properties. Compare multiple candidate universes on validation patients, then evaluate the chosen one once on test patients. Do not tune the cutoff, merging, or method on the test collection.

Raw lines 266 to 311
312## Reproducibility record
314Store:
316- ordered input manifest and grouping;
317- assembly/accession, chromosome sizes, coordinate and contig policy;
318- every input and coverage checksum;
319- exact coverage and Geniml argv;
320- Geniml, Gtars, pyBigWig, NumPy, HMM, Python, OS, and architecture versions;
321- method, cutoff/model, prefix, normalization, merge/filter parameters;
322- output and assessment checksums;
323- exclusions, failures, empty contigs, and liftover losses.
325Keep file names and sample labels redacted in portable reports.

Reproducibility record

Store:

  • ordered input manifest and grouping;
  • assembly/accession, chromosome sizes, coordinate and contig policy;
  • every input and coverage checksum;
  • exact coverage and Geniml argv;
  • Geniml, Gtars, pyBigWig, NumPy, HMM, Python, OS, and architecture versions;
  • method, cutoff/model, prefix, normalization, merge/filter parameters;
  • output and assessment checksums;
  • exclusions, failures, empty contigs, and liftover losses.

Keep file names and sample labels redacted in portable reports.

Raw lines 312 to 326
327## Migration corrections
329Remove or correct these stale patterns:
331- `geniml universe build ...` → `geniml build-universe ...`;
332- `geniml universe evaluate ...` → `geniml assess-universe ...`;
333- CCF `--confidence` → not present in 0.8.4;
334- HMM `--states` → not present in 0.8.4;
335- ML `--model-type gaussian|poisson` → not present in 0.8.4;
336- generic `build_universe(...)` → not exported by the stable universe module;
337- claims that a fixed percentage coverage is universally appropriate.

Migration corrections

Remove or correct these stale patterns:

  • geniml universe build ... → geniml build-universe ...;
  • geniml universe evaluate ... → geniml assess-universe ...;
  • CCF --confidence → not present in 0.8.4;
  • HMM --states → not present in 0.8.4;
  • ML --model-type gaussian|poisson → not present in 0.8.4;
  • generic build_universe(...) → not exported by the stable universe module;
  • claims that a fixed percentage coverage is universally appropriate.
Raw lines 327 to 338
339## Official sources
341- [Official consensus CLI guide](https://docs.bedbase.org/geniml/tutorials/create-consensus-peaks)
342 (undated; accessed 2026-10-01)
343- [Official consensus Python guide](https://docs.bedbase.org/geniml/notebooks/create-consensus-peaks-python)
344 (undated; accessed 2026-10-01)
345- [Official universe assessment guide](https://docs.bedbase.org/geniml/tutorials/assess-universe/)
346 (undated; fetch failed 2026-10-01; release source checked)
347- [Geniml v0.8.4 universe source](https://github.com/databio/geniml/tree/v0.8.4/geniml/universe)
348 (released 2026-01-14; accessed 2026-10-01)
349- [Primary consensus-universe paper](https://doi.org/10.1093/nar/gkae685)
350 (2024)

Official sources

Raw lines 339 to 350