Output files - glarue/intronIC GitHub Wiki

Output files

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 is type_id; the motif probability is P_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

dupe_map.iic

A mapping table of unique, scored intron labels and their corresponding duplicate intron labels:

ENST00000359596:intron_38433875_38440744	ENST00000355481:intron_38433875_38440744
  1. scored intron key (<transcript>:intron_<start>_<stop>)
  2. duplicate intron key sharing those coordinates

overlap_map.iic

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).

  1. representative (retained) intron key
  2. excluded overlapping intron key

introns.iic

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)

  1. label (without score tag)
  2. score: the first-pass SVM U12-type probability (0–100), or NA if unscored. This is not the adjudicated call; use type_id in score_info.iic/meta.iic for the final U12-type/U2-type label
  3. upstream (5′ exon) sequence (50 nt by default, set with --flank-len)
  4. intron sequence
  5. 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.

bed.iic

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
  1. genomic region (e.g. 'chr1')
  2. start coordinate (0-indexed)
  3. end coordinate (1-indexed)
  4. label (with any coordinate-correction tag, e.g. [c:-1]; no score tag)
  5. adjusted_score: the adjudicated 0–100 calling scale (synced from score_info.iic after adjudication); ≥ 50u12. NA if unscored
  6. strand
  7. attributes (comma-separated flag list, same as meta.iic column 16)

Note: The BED file is not created when using sequence-only input (-q flag), as BED format requires real genomic coordinates.

.iic.log

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.

meta.iic

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
  1. label
  2. rel_score: signed, centered on the 90% high-confidence threshold, range ≈ [−90, +10]; > 0 marks a high-confidence U12-type call. rel_score < 0 means "below the 90% threshold", not "U2-type". Synced from score_info.iic
  3. terminal dinucleotides (e.g. GT-AG, AT-AC)
  4. motif_schematic: motif string (5′, U12/U2 BPS, 3′)
  5. bp_context: BPS location in the context of the 3′ end
  6. bp_offset: branch point adenosine position relative to 3'SS (e.g. -13)
  7. length (bp)
  8. parent transcript
  9. parent gene
  10. ordinal position in transcript
  11. total introns in transcript
  12. frac_pos: CDS-relative position = (CDS length upstream of the intron) / (total CDS length), in [0, 1] (e.g. 0.039 for an intron near the 5′ end of the coding sequence, 0.5 at the midpoint). Exon-only (UTR) introns have no CDS position and are NA
  13. phase (0, between codons; 1, after the first base of a codon; 2, after the second base of a codon)
  14. type_id: binary classification (u12 or u2), synced from score_info.iic (the authoritative call). A u12 label may include introns with probabilities well below the high-confidence threshold; filter on rel_score > 0 for high-confidence calls only
  15. genomic feature used to define the intron (e.g. cds, exon)
  16. attributes (comma-separated tags indicating special conditions, e.g. noncanonical, corrected, not_longest_isoform, duplicate)

score_info.iic

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.

metrics.iic.json

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 > 0P_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.

tail_model.iic.json

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.

Plot files (.plot.*.iic.png)

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.)


Understanding the scores

P_motif (0–1) — the motif probability

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 (0–100) — the calling scale

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 ≥ 50u12. This is the adjudicated calling scale.

rel_score

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 > 0adjusted_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.

Raw motif log-odds

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.


Common operations

Finding U12-type introns

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

Extracting specific types

# 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

Converting to FASTA

# 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
⚠️ **GitHub.com Fallback** ⚠️