Output files - glarue/intronIC GitHub Wiki
intronIC will automatically generate a set of output files. A brief description of the contents of each file follows (numbered lists represent the columns within each file).
Note: The meta.iic and score_info.iic files include column headers by default. Use --no-headers to omit headers if needed for compatibility with legacy pipelines. All .iic data tables are tab-delimited.
Intron label format: the intron name/label (first column of most files) has the form {SpAbbr}-{gene}@{transcript}_{index}({family_size}){tags} — e.g. HomSap-ENSG00000141837@ENST00000614285_1(47). HomSap is a 3+3-character species abbreviation (first three letters of genus + species); the gene and transcript IDs come from the annotation; _1 is the intron's ordinal within the transcript; (47) is the number of introns in that transcript. Optional trailing ;[…] tags encode special conditions (for example [c:-1], a corrected boundary).
For many use-cases, the most important files will be:
-
score_info.iic- the authoritative per-intron feature+call matrix (the call column istype_id; the motif probability isP_motif) -
bed.iic- BED file of intron coordinates, with the adjudicated calling score (adjusted_score, 0–100) in the 5th column -
meta.iic- metadata file with intron info such as parent transcript/gene, ordinal index, phase, CDS-relative position, etc. -
introns.iic- full intron sequences, with the (first-pass) SVM score in the 2nd column
A mapping table of unique, scored intron labels and their corresponding duplicate intron labels:
ENST00000359596:intron_38433875_38440744 ENST00000355481:intron_38433875_38440744
- scored intron key (
<transcript>:intron_<start>_<stop>) - duplicate intron key sharing those coordinates
A mapping table in the same two-column format as dupe_map.iic (no header), pairing each scored intron key with an overlapping intron key that was excluded in its favour — one row per excluded member. Written only when overlapping introns are found (normally absent).
- representative (retained) intron key
- excluded overlapping intron key
All of the annotated intron sequences, including any introns not meeting scoring criteria (e.g. too short, including non-ATCG characters in scoring regions, etc.; includes duplicate introns if run with -d):
HomSap-ENSG00000141837@ENST00000614285_1(47);[c:-1] 100.0 AGCGAAGACAACGTGGTGAGAAAATACGCCAAAAAGATCACCGAATGGCC ATATCCTTTTGCCCGAACCCCAGCAGCAGCTGCGCCTCCC[...]TCTTTTCTTTGAACAAGATTTTTCCTTAATTCCCCAATAC TCCCTTTGAATATATGATTTTAGCCACCATCATAGCGAATTGCATCGTCC
(the intron sequence is shown truncated as [...]; real rows carry the full sequence)
- label (without score tag)
- score: the first-pass SVM U12-type probability (0–100), or
NAif unscored. This is not the adjudicated call; usetype_idinscore_info.iic/meta.iicfor the final U12-type/U2-type label - upstream (5′ exon) sequence (50 nt by default, set with
--flank-len) - intron sequence
- downstream (3′ exon) sequence (50 nt by default, set with
--flank-len)
This file (name, score, upstream flank, intron seq, downstream flank) is also the input format for -q/--sequence-file re-scoring mode.
A BED format file of intron coordinates with the adjudicated calling score and labels:
19 13455212 13505931 HomSap-ENSG00000141837@ENST00000614285_1(47);[c:-1] 100 - corrected
- genomic region (e.g. 'chr1')
- start coordinate (0-indexed)
- end coordinate (1-indexed)
- label (with any coordinate-correction tag, e.g.
[c:-1]; no score tag) -
adjusted_score: the adjudicated 0–100 calling scale (synced fromscore_info.iicafter adjudication);≥ 50⟺u12.NAif unscored - strand
- attributes (comma-separated flag list, same as
meta.iiccolumn 16)
Note: The BED file is not created when using sequence-only input (-q flag), as BED format requires real genomic coordinates.
A human-readable run log (<name>.iic.log) of the information generated during operation, including total number of introns processed, excluded, etc., the per-species adjudication summary, and total number of U12-type introns identified. This file is not machine-parseable; use the JSON/TSV outputs for data.
Additional metadata for each intron (ordered by increasing U12-type score):
HomSap-ENSG00000141837@ENST00000614285_1(47);[c:-1] 10.0000 AT-AC GCC|ATATCCTTTT...TTTTCCTTAATT/TTTTCCTTAATT...AATAC|TCC CACCTCCAACACCCTTCTTTTCTTTGAACAAGAT[TTTTCCTTAATT]CCCAATAC -12 50719 ENST00000614285 ENSG00000141837 1 47 0.039 2 u12 cds corrected
- label
-
rel_score: signed, centered on the 90% high-confidence threshold, range ≈ [−90, +10];> 0marks a high-confidence U12-type call.rel_score < 0means "below the 90% threshold", not "U2-type". Synced fromscore_info.iic - terminal dinucleotides (e.g.
GT-AG,AT-AC) -
motif_schematic: motif string (5′, U12/U2 BPS, 3′) -
bp_context: BPS location in the context of the 3′ end - bp_offset: branch point adenosine position relative to 3'SS (e.g. -13)
- length (bp)
- parent transcript
- parent gene
- ordinal position in transcript
- total introns in transcript
-
frac_pos: CDS-relative position = (CDS length upstream of the intron) / (total CDS length), in [0, 1] (e.g.0.039for an intron near the 5′ end of the coding sequence,0.5at the midpoint). Exon-only (UTR) introns have no CDS position and areNA - phase (0, between codons; 1, after the first base of a codon; 2, after the second base of a codon)
-
type_id: binary classification (u12oru2), synced fromscore_info.iic(the authoritative call). Au12label may include introns with probabilities well below the high-confidence threshold; filter onrel_score > 0for high-confidence calls only - genomic feature used to define the intron (e.g.
cds,exon) - attributes (comma-separated tags indicating special conditions, e.g.
noncanonical,corrected,not_longest_isoform,duplicate)
The authoritative per-intron feature + call matrix: 35 tab-separated columns with a header row (omit with --no-headers). It contains only scored introns (omitted introns appear in meta.iic/bed.iic/introns.iic, not here; join on the name column). Rows are written in two stages: the base writer emits columns 1–26, then the species adjudicator re-reads the file, appends columns 27–35, and overwrites rel_score (col 2) and adjusted_score (col 25). Two missing-value sentinels are used: base columns write NA; the appended adjudicator columns write lowercase nan.
Columns marked [S] are per-species constants (identical on every row); all others are per-intron.
| # | Column | Meaning |
|---|---|---|
| 1 | name |
intron label |
| 2 | rel_score |
(adjudicator-overwritten) = adjusted_score − 90; range ≈ [−90, +10]; > 0 ⇔ high-confidence U12-type |
| 3 | svm_score |
first-pass ensemble U12-type probability ×100 (isotonic). Not the call column |
| 4 | 5'_seq |
5′SS sequence used for scoring |
| 5 | 5'_raw |
5′SS raw motif log-odds (U12/U2), background-corrected |
| 6 | bp_seq |
branch-point sequence (U12 BPS model) |
| 7 | bp_seq_u2 |
branch-point sequence (U2 BPS model) |
| 8 | bp_raw |
branch-point raw motif log-odds, background-corrected |
| 9 | 3'_seq |
3′SS sequence used for scoring |
| 10 | 3'_raw |
3′SS raw motif log-odds, background-corrected |
| 11 | decision_dist |
first-pass SVM decision distance; > 0 ⇒ first-pass u12 |
| 12 | bp_offset |
branch-point adenosine distance from 3′SS (negative int, e.g. −13) |
| 13 | bp_scan_confidence |
confidence of the BPS scan pick |
| 14 | ppt_ct |
polypyrimidine-tract score (fraction pyrimidine) |
| 15 | ppt_raw |
PPT raw log-odds |
| 16 | core_3'_raw |
core-3′ raw log-odds (NA on every row in the shipped bundle) |
| 17 | fit_u12 |
absolute goodness-of-fit to the U12 model |
| 18 | fit_u2 |
absolute goodness-of-fit to the U2 model |
| 19 | fit_u12_5' |
U12 fit, 5′SS component |
| 20 | fit_u12_bp |
U12 fit, branch-point component |
| 21 | fit_u12_3' |
U12 fit, 3′SS component |
| 22 | min_fit_bp_3 |
min(fit_u12_bp, fit_u12_3') (robust conjunctive fit) |
| 23 | ppt_longest_run |
longest pyrimidine run in the PPT window |
| 24 | ppt_t_weighted |
T-weighted PPT score |
| 25 | adjusted_score |
(adjudicator-overwritten) = 100·q_eff·P_motif (q_eff = 0 iff NOT_DETECTED); the 0–100 calling scale |
| 26 | ensemble_sigma |
SD of per-intron probability across the 42 ensemble models (uncertainty) |
| 27 | P_motif |
authoritative motif probability σ(2.796·margin − 1.178) on the ensemble margin; species-agnostic, Platt-calibrated |
| 28 |
z_excess [S]
|
primary species statistic: Poisson significance of the strong-call count vs the genome's own U2-type tail |
| 29 |
cs_p95 [S]
|
95th pct of the un-clipped call margins (call strength); strength-gate co-fallback |
| 30 |
p_gumbel_p95 [S]
|
primary strength driver: per-genome Gumbel tail-prob at cs_p95; ≤ 0.01 ⇒ DETECTED |
| 31 |
cs_p95_lo [S]
|
bootstrap CI lower bound of cs_p95 (annotation, not a gate) |
| 32 |
cs_p95_hi [S]
|
bootstrap CI upper bound of cs_p95 (annotation) |
| 33 |
motif_category [S]
|
authoritative species gate: DETECTED / INCONCLUSIVE / NOT_DETECTED / UNASSESSABLE
|
| 34 | bg_fdr |
report-only background FDR of each call against this genome's own U2 tail (see below); nan for non-calls. Gates nothing |
| 35 | type_id |
resolved call u12/u2 (never NA) |
Reading the call: key off P_motif (27) + motif_category (33) + type_id (35). type_id = u12 iff P_motif ≥ 0.5 and motif_category ≠ NOT_DETECTED. svm_score (3) is a different calibration than P_motif and is not the call; don't threshold it.
The columns q, P_adj, P_adj_lo and P_adj_hi were removed in the 2026-07 schema (38 → 35 columns). All four were deterministic functions of P_motif + motif_category: q was a per-species constant, and P_adj_lo/P_adj_hi were bit-identical to P_adj. adjusted_score is now computed directly as 100·q_eff·P_motif.
bg_fdr (col 34) — report-only background surprisal. For each strong call (P_motif ≥ 0.90), the fraction of the calls at least that strong which the genome's own U2 tail already accounts for. It is the per-intron decomposition of z_excess, computed from the same fitted tail, with a Benjamini-Hochberg step-up so it is monotone in call strength. Read ~1 as "indistinguishable from this genome's background" and ≪1 as "the background cannot account for it". It is nan for non-calls (those are the background — rank them with P_motif) and whenever the U2 tail cannot be referenced.
bg_fdr is populated even when the calling columns are zeroed, which is its main use: it is the only column that distinguishes a NOT_DETECTED genome whose calls are uniformly background from one that holds a genuine outlier. In Symbiodinium natans all 109 strong calls sit at bg_fdr = 1 (its best call is weaker than the maximum its own background is expected to produce), while Phytophthora infestans — also NOT_DETECTED, also fully zeroed — holds one call at 6.9e-3. Neither z_excess nor P_motif separates those two: P_motif saturates, reading 1.0000 at the top of both. Within a DETECTED genome it identifies which calls carry the signal.
bg_fdr is report-only per intron — no intron's own call depends on its own bg_fdr. Since v3.1 the minimum over a genome's calls does feed one per-species decision: the low-k escape hatch, which spares a genome with only one or two strong calls from being zeroed when the background cannot explain the strongest of them.
Per-species aggregate summary written alongside each output (27 keys, all always present; adjudicator statistics become JSON null when the genome's U2-type tail can't be referenced):
| Field | Meaning |
|---|---|
total_introns |
Introns written to output (superset; includes unscored/omitted rows) |
threshold |
High-confidence / rel_score-centering threshold (90.0). Not the call boundary — the U12-type call is adjusted_score ≥ 50
|
total_genes |
Genes processed |
total_introns_generated |
All introns generated from CDS across isoforms, pre-dedup/filter |
total_scored |
Introns scored + classified (= u12_count + u2_count) |
pretrained |
Always true on the classify path |
model_path |
Absolute path of the loaded model .pkl
|
streaming_mode |
per_contig or in_memory
|
normalizer_used |
"none (raw features)" — legacy/no-op field |
u12_count |
Scored U12-type calls (type_id == u12) |
u2_count |
Scored U2-type calls |
high_confidence_u12 |
Strong U12-type subset (rel_score > 0 ≡ P_motif ≥ 0.9); ≤ u12_count
|
u12_percentage |
u12_count / total_scored · 100 |
high_confidence_percentage |
high_confidence_u12 / total_scored · 100 |
u12_boundaries |
Terminal-dinucleotide tally over U12-type calls (top-20). AT-AC = the diagnostic minor subtype |
u2_boundaries |
Same over U2-type calls |
high_confidence_u12_boundaries |
Dinucleotide tally over the HC U12-type subset |
high_confidence_u12_by_feature |
HC U12-type split by cds/exon (sums to high_confidence_u12) |
motif_category |
Species gate (DETECTED/INCONCLUSIVE/NOT_DETECTED/UNASSESSABLE) |
z_excess |
Primary population statistic (null if the U2-type tail can't be fit) |
cs_p95 |
Call strength (95th pct of the call margins) |
p_gumbel_p95 |
Strength-gate driver (per-genome Gumbel outlier prob) |
cs_p95_lo |
CI annotation on cs_p95
|
motif_called_u12 |
Ungated count (P_motif ≥ 0.5 ignoring motif_category); equals u12_count unless NOT_DETECTED
|
feature_type |
Extraction features: cds / exon / both
|
confident_u12_motif |
high_confidence_u12 iff DETECTED, else 0 (the "safe to headline" HC count) |
substrate_quality |
Report-only per-genome intron-substrate QC + confidence (nested object, 6 fields below); null if the U2-type background is too small to assess |
Totals nest: total_introns_generated ⊋ total_introns ⊋ total_scored; u12_count + u2_count == total_scored; high_confidence_u12 ⊆ u12_count.
The substrate_quality object is a report-only confidence/QC layer — it annotates a genome and flags annotation problems, but never changes a U12/U2 call. Read it together with motif_category and the snRNA evidence: a low signal from a polluted annotation (a real bearer whose gene models carry junk introns) is a different thing from a degenerate splicing signal (a divergent, snRNA-absent genome).
| Field | Meaning |
|---|---|
canonical_terminus_fraction |
Fraction of classified introns with a canonical terminus (GT-AG / GC-AG / AT-AC). Real bearers exceed 0.90 in ~99.8% of cases across every clade, so a value below ~0.85 indicates annotation pollution (junk gene models), not biology |
annotation_quality |
clean (≥0.92) / suspect (0.85–0.92) / poor (<0.85) / unassessed — categorical of the above |
background_structure_ic |
Composition-relative, structure-weighted information content (bits) of the U2-type background splice logos. Low values mean the genome's splicing signal is poorly defined |
splicing_signal |
well_defined / degenerate (degenerate when background_structure_ic falls below the corpus-calibrated floor) |
population_confidence |
Combined per-genome label: coherent / low_signal / terminus_smear / low_signal+smear / unassessed
|
substrate_confidence |
A soft 0–1 confidence multiplier from annotation quality (1.0 for a clean annotation, falling toward 0 as the canonical-terminus fraction drops). A downstream consumer may use it to down-weight a motif-only detection; it is never a hard gate |
Typical reads: annotation_quality = poor/suspect on a confirmed bearer flags the assembly/annotation for review (e.g. polyploid or repeat-rich genomes with over-predicted gene models), not the biology; splicing_signal = degenerate on an snRNA-absent genome marks the divergent / ambiguous detections (e.g. dinoflagellates). An all-unassessed block just means the genome had too small a U2-type background to assess.
A per-species adjudicator sidecar (emitted by the pmotif_adjudicated bundle) holding the fitted U2-tail model and the numbers behind motif_category. Always-present keys include params_version, platt_a/platt_c, call_threshold (0.90), u2_threshold (0.50), n_u2, n_call, z_excess, cs_p95, p_gumbel_p95, motif_category, call_margins (the per-call ensemble margins), assessable/reason, and the EVT tail-selection parameters evt_tail_pct (90.0) and evt_tail_frac (0.10). When the genome has ≥ 200 U2-type introns it also carries the fitted EVT tail (med, mad, q90, lam, exp_max, q_tail, plus a pre-binned U2-type histogram). This sidecar drives the per-species tail-model diagnostic plot (.plot.tail_model.iic.png), which shows the U2-type background margins, the fitted U2-type tail extrapolated into the call region, and the U12-type calls that escape it.
intronIC renders a set of per-species diagnostic plots (PNG) in background-corrected raw-motif-log-odds space. Two are always produced; the rest are conditional.
| File | Emitted | Contents |
|---|---|---|
.plot.hex.iic.png |
always | Density hexbin of the intron cloud in 5′SS-raw × BPS-raw space |
.plot.scatter.iic.png |
always | U12-type confidence-tier scatter over the U2-type background (5′SS × BPS), with marginal distributions |
.plot.scatter3d.iic.png |
when 3′SS scores are present | Two-view 3-D scatter of the 5′SS × BPS × 3′SS motif axes |
.plot.score_histogram.iic.png |
when calling scores exist | Log-y histogram of the calling score (adjusted_score) with the 90% threshold line |
.plot.tail_model.iic.png |
when the tail_model.iic.json sidecar and a U2-type population exist |
Adjudicator diagnostic (see tail_model.iic.json): U2-type background margins, the fitted tail extrapolated into the call region, and the U12-type calls |
.plot.scatter_raw.iic.png |
only when motif_category == NOT_DETECTED
|
Companion scatter for suppressed genomes: introns coloured by per-intron 100·P_motif (pre-adjudication), so motif-strong introns hidden by the NOT_DETECTED call stay visible; the subtitle keeps the true call counts |
(Plots suffixed .AUC.iic.png, .ref_hex.iic.png, .plot.training_scatter.iic.png, and .plot.decision_surface.iic.png are produced only when training a model, never by a classification run.)
The species-agnostic, Platt-calibrated probability that an intron's motif is U12-type, P_motif = σ(2.796·margin − 1.178) on the SVM ensemble margin. It does not depend on how many U12-type introns the genome has, so you can threshold it post-hoc at whatever confidence you need:
P_motif |
adjusted_score (non-NOT_DETECTED genome) |
Interpretation |
|---|---|---|
| ≥ 0.9 | ≥ 90 | High-confidence U12-type (rel_score > 0) |
| 0.5–0.9 | 50–90 | Called U12-type, intermediate confidence |
| < 0.5 | < 50 | Called U2-type |
svm_score (column 3 of score_info.iic) is a different isotonic calibration retained for auditability; it is not the call — use P_motif / type_id.
adjusted_score = 100·q_eff·P_motif, where q_eff ∈ {0,1} is the binary effective gate (q = 0 only when the genome's motif_category is NOT_DETECTED, else q = 1). So in any non-NOT_DETECTED genome adjusted_score = 100·P_motif; in a NOT_DETECTED genome all calls are zeroed. The call is adjusted_score ≥ 50 ⟺ u12. This is the adjudicated calling scale.
rel_score = adjusted_score − 90 (range ≈ [−90, +10]). It is signed and centered on the 90% high-confidence threshold, not on the U12-type/U2-type boundary: rel_score > 0 ⇔ adjusted_score > 90 ⇔ high-confidence U12-type. rel_score < 0 means "below the 90% threshold", not "anti-U12-type" — a U2-type call and a sub-high-confidence U12-type call are both negative.
Each motif region's raw score is a background-corrected log-odds ratio log₂(P(seq | U12) / P(seq | U2)), with a different natural range per region. v3 scores these raw log-odds directly — there is no per-species z-normalization (5'_raw, bp_raw, 3'_raw in score_info.iic). See Technical Details for the scoring approach.
The authoritative per-intron call is type_id (score_info.iic col 35, or meta.iic col 14). Filtering on rel_score > 0 selects the high-confidence U12-type subset.
# All U12-type calls, from meta.iic (col 14 = type_id)
awk -F'\t' '$14=="u12"' species.meta.iic
# High-confidence U12-type introns, from meta.iic (col 2 = rel_score, > 0 ⇔ adjusted_score > 90)
awk -F'\t' '($2!="NA" && $2>0)' species.meta.iic
# From bed.iic (col 5 = adjusted_score, the adjudicated calling scale)
awk '$5 >= 50' species.bed.iic
# Count high-confidence U12-type introns
awk -F'\t' '($2!="NA" && $2>0)' species.meta.iic | wc -l# AT-AC introns only
awk '($3 == "AT-AC")' species.meta.iic
# High-confidence U12-type AT-AC introns
awk '($2 > 5 && $3 == "AT-AC")' species.meta.iic
# U12-type introns in first half of transcript
awk '($2>0 && $12 < 50)' species.meta.iic# Intron sequences with a strong first-pass score (col 2 = svm_score, a rough proxy —
# for the authoritative call, filter meta.iic on type_id and join on the label).
awk -F'\t' '$2!="NA" && $2 > 90 {print ">"$1"\n"$4}' species.introns.iic > u12.fasta