Consensus output files¶
The files written by fiberhmm-consensus (lattice
recaller) and fiberhmm-transfer. Coordinates are
reference, 0-based half-open, except pooled (--pool-loci) runs, which use
the oriented window frame 0 … width.
Run directory¶
out/classes/
classes.tsv one row per class × channel
molecules.tsv.gz one row per class × channel × scored molecule
broader.tsv.gz molecules best explained by wider protection
families.tsv the standard report table (one row per class and dataset)
calls.tsv every native call and its class
families.svg class spans
report.html report (with report_data.json)
manifest.json parameters, mode, channels, warnings, timings, recaller summary
evidence.json.gz the complete prepared payload, for replay
result.json.gz the frozen result
bams/ family-tagged BAMs (unless --no-bam)
With several BED windows the top level holds report.html, regions.json
(one entry per window: name, output, status, seconds) and one
window_NNNNNN/ run directory per window. Every BAM + BED/--region run also
writes consensus_run.json (the run contract --continue checks, with one
entry per attempt), logs/window_NNNNNN.log (one log per window) and, in each
window directory (the output directory itself for a single window),
unit_complete.json: the completion marker written last, with the unit
digest, window, status, seconds and the size and SHA-256 of every file the
window wrote.
See Long runs and resuming. bams/ holds
NNN_<dataset>.families.bam (CSI-indexed) and bam_exports.json (per-output
counts of annotations, matched and written alignments, scope and source
windows; and the exported families).
classes.tsv¶
| Column | Meaning |
|---|---|
class_id, group |
class and its overlap group |
channel, dataset, strand |
dataset::strand; strand is CT/GA for DAF, pooled for Hia5 |
start, end |
class span (median discovery edges) |
L0, L1, R0, R1 |
left and right edge boxes on this channel (contracted if edge contraction was kept) |
status, unscored_reason |
supported / unsupported / unscored, and why a pair is unscored |
calls, stability |
discovery calls in the class; its prediction strength, averaged over the split-halves |
molecules |
molecules scored (for unscored rows: molecules in the window) |
prevalence, prevalence_edge, prevalence_loose |
core, edge and loose tiers |
prevalence_lower_bound |
Wilson 95% lower bound of the core prevalence |
broader, other_shape, accessible |
the remaining mixture weights |
support_gain_nats, supported |
held-out likelihood gain and the support verdict |
resolution_nats, resolved |
expected evidence per molecule and the resolution verdict |
spots |
learned internal spots, position:rate |
edge_contraction |
the kept contraction, or why it was rejected (from <channel>: … in a transfer) |
unknown_accessible_fraction |
the channel's accessible fraction for unknown sites |
efficiency |
per-channel efficiency factor, when efficiency_calibration is on |
order_robustness, robust |
only with --robust N (recaller.order_replicates): the fraction of the N+1 read orders in which the class was found and supported, and whether that reaches recaller.order_robust_fraction (default 1: every order). See Reproducibility |
Unscored rows leave the estimate columns empty.
molecules.tsv.gz¶
| Column | Meaning |
|---|---|
class_id, channel, unit_id |
class, channel and molecule |
posterior |
EM class posterior |
log_bf |
log of posterior odds over prior odds |
label |
member, non_member or abstain (threshold recaller.bf_threshold) |
tier |
core for members; edge / loose for non-members counted in those tiers; empty otherwise |
start, end |
the molecule's own call for the class (lattice midpoint edges), when it has one |
edge_range |
l0-l1,r0-r1: how far each edge can move before a mark contradicts it |
broader.tsv.gz¶
Molecules best explained (posterior ≥ 0.5) by protection wider than every class of a group, for example a nucleosome over the site.
| Column | Meaning |
|---|---|
group, classes |
overlap group and its classes (;-separated) |
channel, unit_id, posterior |
channel, molecule, broader-protection posterior |
start, end, edge_range |
the best broader stretch and its edge ranges |
families.tsv and calls.tsv¶
The standard report tables shared with FiberBrowser.
families.tsv:stage,dataset,family(class id),start,end,width,source_units(members),edge_uncertainty(edge boxes as JSON),fit_flags,classification_counts(per channel: eligible units, i.e. molecules spanning the scoring window, compatible and primary units and calls),trusted_strand,core_resolution.calls.tsv: one row per native call:chrom,genomic_start,genomic_end,stage,dataset,unit_id,read_name,source_start,source_end,compatible_families,status(for examplelattice_unassigned),window.
manifest.json¶
Top-level keys include schema, status, cr_mode (lattice_recaller),
region, parameters (every group, with defaults filled in; the read-order
controls order_replicates and order_robust_fraction only when that check
is on),
input_digest, mode / mode_realized (CR), realized_channels,
data_warnings, seconds, datasets, input_files, pooling (the pooling
receipt of a CL-CR run) and recaller:
classes,unsupported_classes,unscored_classes,unscored(class, channel, reason, molecules);dropped_by_core_rule(span and core width of each dropped candidate);tilesand per-tilediscoverydiagnostics (k chosen, prediction strength per k, merges, andresplits: each candidate that failed the core rule and was clustered again, with its core width, k and children);order_robustness, only with--robust N:orderings(N+1),replicates(N),salts(0 is the default order),robust_fraction,rule,matching,discovered_per_ordering,supported_per_ordering,robust_classes,robust_supported_classes,supported_classesandseconds.
result.json.gz¶
The frozen result FiberBrowser reads: schema fiberhmm.consensus.v1,
cr_mode: lattice_recaller, the manifest, the per-dataset catalog and
records, and recaller:
classes: geometry andstatusof every class (andorder_robustnessandrobustwith--robust N, also on each catalog family);rows: the scored rows ofclasses.tsv, with full-precision spot rates;unscored.
Each record has proposals (native calls with any class label) and
recaller_calls, the recaller's own per-molecule calls: a class call has
tier (core/edge/loose), interval, lattice_interval,
consensus_interval, edge_range and edge_source (native when a
labelled native call supplies the edges); a broader call is a
wider-protection stretch. A transfer adds a transfer block.
Transfer files¶
| File | Content |
|---|---|
frozen_classes.json.gz |
lattice-recaller catalog, schema fiberhmm.frozen_classes.lattice_recaller.v1: frame, parameters, tiles, classes, datasets, channels (per-channel boxes and spots), spot_precision, training_molecule_hashes, provenance, score_semantics, content_sha256 |
frozen_models.json.gz |
staged-engine bundle, schema fiberhmm.frozen_families.v1 |
transfer_summary.tsv |
one row per window × class × channel: window, chrom, window_start, window_end, window_strand, source_channel, then every classes.tsv column |
transfer_manifest.json |
schema fiberhmm.transfer_run.lattice_recaller.v1: catalog, catalog_sha256, catalog_schema, source_provenance, frame, refitted (false), rediscovered (false), preparation_parameters, dataset_map, include_training_molecules, windows, bams, chip_label, apply_code |
transfer_exclusions.json |
training molecules excluded from scoring |
chip_evaluation.json |
with --chip-bed: AUROC and average precision per class and channel |
The schema string fiberhmm.consensus.v1 is shared by the lattice recaller
and the staged engine; FiberBrowser checks it, and cr_mode tells the two
engines apart.
Frozen lattice transfer loads and scores one BED window at a time, retaining only compact annotation plans for aggregate BAM export. Raw evidence memory no longer grows with the number of target windows. Its scoring worker pool is reused across windows, so imports and JIT warm-up are paid per worker.
Independent NFR windows¶
fiberhmm-nfr --bam reads.bam --bed sites.bed --cores 8 --output nfr-sites
runs independent BED windows with a persistent worker pool. Each window writes
its normal single-region files to window_XXXXXX; regions.json lists them in
BED order. --window-jobs 1 runs sequentially. NFR detection is independent in
each window; explicit --nfr and --classes inputs require a single --region.
The output directory must be new or empty; this command does not implement
consensus's --continue protocol.
Molecule depth budgets¶
The lattice recaller samples independently within each dataset and chemical channel
(CT/GA for DAF; pooled orientations for Hia5). recaller.max_discovery_molecules
defaults to 0 (all molecules) per discovery tile, recaller.max_quantification_molecules defaults
to 0 (all eligible molecules) per class-group scoring window, and
recaller.sample_seed defaults to 1. Both caps are off by default.
For deep data (thousands of reads per site), 2000 is a good opt-in cap for each
phase; set either cap to 0 to use all eligible molecules for that phase.
The corresponding CLI flags use hyphens. These controls apply to every independent
BED/region job and to tiles within pooled analyses. Historical fitted engines do
not implement these sampling controls; explicit CLI sampling flags require
--engine lattice_recaller.
Sampling keeps the lowest SHA-256 priorities of the seed and read name (unit ID when no name exists), with unit ID breaking equal-name ties. Priorities do not include tile coordinates or input order. Overlapping tiles with the same eligible molecules therefore select the same set; when their candidate sets differ, the priorities remain the same, but their lowest-N sets can differ. Shallow strata keep all eligible molecules. The final cap follows input filters and duplicate collapse. Tile overlap/site-count checks, and quantification spanning checks, precede the cut; likelihood arrays are constructed only for the selected molecules.
When all active phases have finite budgets, BAM preparation first scans only
names, flags, MAPQ and alignment spans. Each dataset/tile retains a prefix of the
same read-name hashes, initially 1.5 times its discovery budget. The internal
loader_sampling.margin argument can change this margin. All alignments with a
selected name are retained together, so full-record identities and equal-name
tie breaks remain unchanged. Unselected names bypass tag/sequence decoding and
native replay. BAM blocks still need decompression; the BAM index cannot index
read-name hashes.
Hia5 has one pooled chemical channel. DAF CT/GA cannot reliably be inferred from alignment flags without inspecting assay tags. DAF therefore advances a common hash frontier (initially provisioning both channels) until each chemical channel has enough usable molecules, or that window's candidates are exhausted. It never guesses CT/GA from orientation. Rare or absent channels, heavy PCR collapse, or stringent spanning filters can require the full candidate population. After collapse and filtering, short windows take the next deterministic tranche. Decoded reads and native replay results are cached across tranches. Selected raw BAM records are reused for native replay, avoiding another regional BAM scan. When the projected sample already covers at least 90% of candidates, preparation loads them all without those caches; this avoids sampling overhead near the budget. Once classes are known, their actual scoring windows can request further tranches before quantification, including frozen transfer's fixed windows. NFR preparation does the equivalent for detected or explicitly supplied NFRs. The final phase cap still selects exactly the lowest N eligible molecules. Changing the margin does not change that selection in the absence of sample-dependent duplicate families or repeated locus views.
Duplicate collapse is restricted to the sampled reads: aliases outside the sample are not collapsed against it. Each distinct read name receives an independent, evidence-independent hash, so duplicate aliases have independent inclusion priorities and the retained aliases can still be collapsed normally. This is a sampling approximation, not full-population PCR family reconstruction: an omitted alias can change a family's representative or membership. Such families are an exception to exact agreement with full-load post-collapse capping.
An uncapped active phase requires all observations. Thus 2000/0, 0/2000 and
0/0 keep the original loader path; frozen transfer needs only its quantification
budget. Full-population efficiency calibration also disables loader sampling.
Sampled evidence exports contain only decoded molecules; increasing a budget or
requesting unlimited analysis requires reloading the BAM, not replaying that
saved evidence as if it represented the whole population.
manifest.molecule_sampling is a list of window records. Each records phase,
window, the two caps and seed, and strata: stratum (dataset::channel),
available, discovery, quantification, and per-phase short flags. A count is null for the other phase
because discovery tiles and class-group scoring windows need not coincide.
Quantification records also identify group. The denominator explains that
prevalence uses the eligible molecules actually quantified, also recorded in
classes.tsv:molecules, not the full dataset depth. Capping does not rediscover
the catalogue. Warnings state how many molecules were used out of those available.
read_sample_cap records the controls and all_units reflects selection.
manifest.loader_sampling (NFR: detection.loader_sampling) contains the loader
receipts, also saved under each source's load.loader_sampling in evidence.
reads_seen counts fetched regional BAM records, eligible_reads counts records
after the cheap flag/MAPQ gate, and reads_decoded counts records sent to the
expensive decoder. decode_attempts counts decoding across all tranches (cached
reads are not decoded again). usable_after_collapse counts retained evidence
units; windows[].strata gives eligible counts, filled budgets (used), and
short/exhausted flags for each loader scope. Actual discovery/quantification
use is in molecule_sampling, whose available denominator is now the loaded
eligible sample, not an estimate of full BAM depth. DAF's pre-decode per-channel
reads_seen is null because its channel is unknown; shared dataset counts and
exact decoded CT/GA counts are reported instead. No full-depth chemical counts
are invented from alignment orientation. Pooled BED receipts preserve the
original genomic loading windows in pooling.window_preparation.
When both caps are 0, sampling metadata and controls are omitted to preserve
legacy output bytes (apart from the existing wall-clock timing fields). Absent
sampling controls in a saved receipt mean uncapped on resume/frozen-catalog replay;
new runs also default to no sampling. For deep data (thousands of reads per site), 2000 is a good cap for each phase. Frozen-class transfer may override only
these three recaller controls; class geometry and spots remain fixed.
The NFR engine exposes the same controls in NFROptions / the nfr JSON group.
It samples the run's detection profile and each NFR's variant discovery, then
independently samples callable molecules for quantification of the fixed variant
catalogue. Non-callable reads do not consume a variant budget. Its result and
manifest store equivalent window/stratum records in
detection.molecule_sampling, with purpose and (for variants) nfr identifying
the scope. nfrs[].callable and variant by_channel[].n are the actual sampled
prevalence denominators. The detection profile's denominator is the sampled
callable coverage at each position. Both caps at zero preserve legacy NFR bytes.