Skip to content

Reading the output

Every field, and the order to read them in.


Files

results/
├── comparison.json              side-by-side across samples, after `openbiota run-all`
└── <sample>/
    ├── <sample>_report.pdf      the Gut Health Test Metagenomic Report, ~330 pages
    ├── summary.txt              the same content as text, one section per subject
    ├── results.json             every number, machine-readable
    ├── run.log                  versions, flags, timings, reference fingerprints
    ├── depth_check.json         rarefaction, after `openbiota depth-check`
    ├── taxonomy/                species profile and cached Bowtie2 alignment
    ├── alignments/              raw and per-panel DIAMOND hits
    └── depth/                   rarefaction scratch, regenerable
File Contents
<sample>_report.pdf The report, in two parts (see below). Part A puts every reading in front of the reader as a graphic in fourteen short sections; Part B breaks each one down and, under each, shows what the human research says about changing it. Every percentile uses one seven-band scale (notably low → notably high). Two finished examples: sample-reports/
summary.txt Full technical summary, one section per subject
results.json Everything in the text report, plus more, machine-readable
run.log Versions, flags, timings, reference set sizes, stage progress
depth_check.json Saturation analysis, if openbiota depth-check has been run
comparison.json Cross-sample table, if openbiota run-all was used
alignments/hits_all_<mate>.tsv Raw DIAMOND output
alignments/hits_<panel>_<mate>.tsv Per-panel view, with role and organism appended
taxonomy/metaphlan.*.tsv Species profile, plus the cached alignment so re-profiling is instant

The directory name is the sample name, which comes from the FASTQ filename — so SAMPLE2_A02_1.fastq.gz produces results/SAMPLE2_A02/SAMPLE2_A02_report.pdf. Renaming the input renames the output; --sample overrides it.

alignments/ and depth/ together account for most of the disk a run uses and are fully regenerable; openbiota prune --alignments --yes clears them.

Subsampled runs write to results/<sample>.subsampleN/ so smoke-test and full-run caches do not invalidate each other.

Exit status is 1 if any [ERROR] diagnostic fired, so the tool composes into a pipeline.


The report's two parts

Part A — at a glance (sections 1–14, about 55 pages). Every reading as a graphic, nothing deep; the full organism list sits here because "what else is in there" is the question that follows "what is flagged".

§ What it shows
1 Summary: gut-health dial, what stood out (index, missing/depleted/expanded organisms, most notable functions, top pattern), every function as a bar, community donut
– Table of contents
2 What stood out, in prose: the flagged organisms, the functions, the evidence-card tally, the age estimate
3 Your gut community: composition by class, diversity and evenness as neutral range strips (none has a favourable direction on its own)
4 Your microbial groups at a glance: the curated groups (butyrate producers, mucin degraders, oral-origin, opportunists …) on reference bars, each with its level against the typical carrier
5 Organisms that need attention — one rule, organisms.verdict, applied once to every organism on its one share and its rank among the reference adults who carry it: overgrown (an opportunist at or above the 90th percentile among carriers; any non-beneficial organism at or above the 97th; an opportunist most people do not carry that is several times above the people who do), worth watching (a conditional resident between the 90th and 97th; an opportunist fewer than one in ten adults carry), depleted (a beneficial organism at or below the 10th), missing (commonly carried, not detected where the detection model says it should have been), depleted, worth watching (expanded, or uncommon to carry). Each with its share, the typical carrier's level, its deviation and its rank among carriers
6 Your organisms, classified: every organism detected, one share of the whole each, largest first; the thirty most abundant described one by one; the organisms furthest above and below the reference; then the full table with class, share, level against the typical carrier, how many reference adults carry it, percentile, strain
7 Pathogens: every target searched, graded (see below), with each bacterial call reconciled against the organism inventory
8 Estimated biological age of biota: point estimate on the training-support histogram, conformal intervals, what moved it, the model card
9 Your microbial functions at a glance: every gene-capacity pathway on the seven-band bar
10 Resemblance to published disease patterns at a glance: shape verdict (diffuse vs specific), ranked table of every scored pattern
11 Biofilm-related potential
12 Your gut mycobiome
13 Gut-skin axis
14 What you can do about it: one line per evidence card — what fired, what was studied, evidence lane (A–E, X), for/against count, status

Part B — in detail (sections 15–28). Each reading broken down; under each one an evidence card block.

§ What it shows
15 Your microbial groups in detail: every group card with its members, each member's share, level and percentile, and its evidence
16 Organisms that need attention, one by one: detection power, reference carriage, level, curated interpretation with citations, disease signatures it appears in, evidence cards; then the cross-checks where two measurements disagree
17 Which strain, not just which species: the marker fingerprint of each organism's dominant population, and its comparative placement among the reference genomes of its species (nearest genome, distance, mixture evidence)
18 Pathogens in detail
19 Your microbial functions in detail: result, percentile, reference band, what it means, the research behind it, what the research says about changing it
20 Resemblance to published disease patterns, in detail: every scored pattern, most resemblant first, module scores, feature table, confounders, evidence cards; patterns not scored, and why
21 Biofilm findings in full
22 Your gut mycobiome, in detail
23 Gut-skin axis, in detail
24 Your information and report context: the input register — what was supplied about the person and the sample, and what was missing
25 What this report cannot tell you
26 Sequencing quality and reference coverage: the reads, the QC gates, every detection method that ran and the reference release each used
27 How this test performs: measured accuracy of the engines on simulated communities with known composition
28 Technical data

Organisms, on one scale. Section 6 gives every organism one share of the whole, on the scale of the marker catalogue that measures the composition. A † marks a share divided among populations the whole-genome mapping tells apart within one marker species; a ° marks an organism the marker catalogue has no entry for, whose share is estimated from the whole-genome search and drawn from the unclassified band; within marks a population counted inside its relatives' shares above it; a § marks a share that includes what the marker catalogue had read under a relative the whole-genome competition rejected — the reads belong to the marked organism, so its share came with them, and the rejected name is printed beneath. Level is the deviation from the typical carrier — the median level among reference adults who carry the organism at all, printed in brackets — with the percentile among those carriers; the two are taken on the same distribution, so above the 50th percentile is always a positive deviation. Where fewer than ten reference adults carry an organism no rank is stated. Where the reference catalogue reads a species fivefold differently from the composition, the organism is ranked instead in the population of a lane whose reading agrees with the share (marked ‡, the population named); where none does, the row says not comparable.

One judge of levels. Whether an organism's level needs attention is decided in exactly one place, openbiota.organisms.verdict, from its one share and its rank among the reference adults who carry it; the attention page is the set of organisms that rule flags, plus the organisms no method found that the reference adults commonly carry. No other section judges a level — the reference catalogue's own census ranks nothing on this page any more, because a second judge with its own estimator put the same organism on the page twice and moved the page whenever either judge changed. A population counted within a relative's share is judged as that relative when it is the same population under another catalogue's name (its reading within a factor of two of the relative's share), and on its own lane rank when it is a distinct population or the relative has no rank. A beneficial organism that is high is not a finding: a supplement being taken is not an overgrowth. The rule is tested branch by branch on synthetic organisms (tests/test_organisms.py), and on any run present the page is checked to be exactly the image of the rule (tests/test_attention.py).

One account of what is present. The pathogen screen aligns reads to its own 485 reference genomes, so sequence an organism shares with a relative the bundle carries no reference for lands on the nearest target and reads as a signal. Every named bacterial call is therefore checked against the organism inventory, which mapped the same reads competitively against every relative it found. A call the inventory found keeps its status and quotes the community share; one the inventory did not find, whose coverage is piled into conserved regions rather than spread across the genome (or whose call the competitive confirmation rejected), is reported under Sequence that belongs to relatives, not to these organisms, names the relatives that carry the reads, and stops counting as a finding. A call with genuine coverage that the inventory's catalogues cannot see — they have a detection floor this screen does not — is kept, and says so. pathogens.inventory_reconciliation records the outcome, and each record carries inventory_agreement, inventory_species, inventory_evenness and, where it applies, inventory_share_percent or inventory_relatives. Identity is deliberately not a gate: a genuine strain 1–2% divergent from its reference maps no better than a cross-mapped relative.

Sections ranked against a single reference catalogue — the biofilm cards and the disease-pattern tables — keep that catalogue's own readings, because that is what makes a percentile against its cohort mean anything, and say so where the pooled methods disagree with them.

Evidence cards. Each card names the exact intervention (strain and dose as

studied, diet protocol, drug, or clinical route), who it was studied in, the evidence for and against side by side with PMIDs/DOIs, the evidence lane (A guideline/label · B replicated RCT · C single or conflicting RCT · D non-randomised human · E animal/in vitro · X against), the applicability of the studied population to this sample, the safety rules that fired and which context fields would be needed to say more, and the phrases the report will not use. Where no human study shows that changing a reading changes an outcome, the card says no supported targeted intervention — that is a result, not a gap. Where FMT is the only route with evidence, the card says so and gives its regulatory status. Nothing on a card is a recommendation; the disclaimer is on every card.


Read it in this order

1. Diagnostics. An [ERROR] means the run is invalid. Zero rpoB makes every figure indeterminate; a dead butyrate positive control means something is broken upstream. Stop there.

2. The rpoB denominator. Everything is divided by it. The summary reports its yield per million read pairs and flags implausible values. An under-detected denominator inflates every pathway at once.

3. Stability flags. UNSTABLE means the fragment count is low enough that counting noise dominates, however precise the number looks.

4. The numbers. Per-gene values are more interpretable than the panel aggregate. Where a residue-consistent subset is reported, the headline is the upper bound and the subset is the tighter estimate.

5. The cross-pathway pattern. Everything elevated at once points at the denominator, not at biology.


Key fields

Copies per 100 bacterial genomes

The primary measurement. For a single-copy gene: 100 means essentially every bacterium carries it, 10 means roughly one in ten, 1 means roughly one in a hundred.

Percentile

Position within the reference cohort. The 60th percentile means 60% of cohort samples had a lower value. Requires refs/reference_ranges.json from openbiota cohort.

Bands

trace / low / moderate / high / very high are scan aids computed from the absolute value. The percentile is the meaningful comparison; the band is just a label.

Flags

Flag Meaning
ok Nothing to note
UNSTABLE Below the panel's minimum fragment count; counting noise dominates
LOW-ID Fragments average under 75% translated identity — matching distant relatives rather than the gene itself. Upper bound only.
few-refs Fewer than 25 reference sequences; a low value is weak evidence of absence
refs-capped Reference set hit its size cap; sensitivity is bounded by it
upper-bound Panel has an active-site filter that reads are mostly too short to apply
INDETERMINATE No rpoB denominator
extension Pathway beyond the original scope
none Nothing detected

Diagnostic codes

Code Level Meaning
rpob-zero error No denominator; every figure indeterminate
positive-control-zero error butyrate returned nothing; the run is invalid
rpob-low-yield / rpob-high-yield warn Denominator outside the plausible band
all-panels-elevated warn Everything high at once — a normalisation artefact
low-identity-<gene> warn Distant-homolog matching; see LOW-ID
implausible-<panel> warn More gene copies than there are genomes to carry them
residue-concordant-<gene> info The two independent residue checks agree
residue-discordant-<gene> warn They disagree; trust neither over the headline
unstable-<panel> info Below the stability threshold
refs-small-<gene> / refs-truncated-<gene> info Reference set size notes
unresolved-subjects warn Cached hits came from a different database; re-run with --force

Residue check

Reported in two halves for urdA.

Reference side — how many accepted fragments matched a reference that itself carries an acceptable active-site residue. Applies to every fragment.

Read side — of the fragments whose alignment reached the site, how many carried an acceptable residue. This is the published filter, applied where available. Typically a small percentage of fragments at 151 bp.

When both are available the report cross-checks them against each other, since they share no evidence.

Closest reference organisms

The reference sequences the reads matched best. This is not taxonomic identification — a read matching a Clostridium reference means the nearest sequence in the reference set came from one, nothing more.

Confidence tier

confirmed means the reading meets the criteria at which validation produced no false positives: at least 2 matching fragments and at least 75% mean translated identity. provisional means detected but below that bar — a possible signal rather than a reliable one. See VALIDATION.md.

What it means

Each pathway carries an explanation matching where the reading fell — above the 75th percentile, below the 25th, or in between. The text is specific to that metabolite and comes from interpretation.implications in its panel file, so the report and the panel definition cannot drift apart.

Community composition

Derived from the rpoB fragments, which are already computed as the denominator. Phylum-level proportions are reliable. Genus labels are nearest-reference matches. Proportions approximate cell fractions, not the DNA-mass fractions a read-count profiler like Kraken reports.


Profile similarity fields

Field Meaning
modules.<name>.score Weighted mean of feature values, −1 to +1
modules.<name>.percentile Rank of that score against the reference null
modules.<name>.weight_coverage Fraction of planned feature weight actually measured
combined.percentile The headline figure. Fraction of the matched reference less concordant with the pattern
confidence.grade HIGH / MODERATE / LOW / INSUFFICIENT
confidence.reasons_for_downgrade Why it is not higher, in plain language
abstention.abstained Whether the engine refused to score
abstention.what_would_change_this What to fix, if it did
cross_engine_checks[].verdict CONCORDANT / DISCORDANT / UNAVAILABLE
dysbiosis_anchor.score GMWI2. Positive leans healthy, negative leans disturbed
features[].v That feature's signed contribution, −1 to +1
features[].w/q/s/c Evidence weight, cohort independence, specificity, direction agreement
features[].reference_percentile Where the sample sits for that feature

A combined.percentile of 63 means the sample is more concordant with the profile's prespecified pattern than 63% of the matched reference set. It is not a 63% chance of having the condition.

Added by the v3 contract, on each profile result:

Field Meaning
status scored, low_coverage, not_computable or abstained
confidence_vector.* The dimensions behind the grade, kept separate rather than multiplied: technical_reliability, independent_feature_coverage, evidence_maturity, assay_transportability, population_transportability, empirical_specificity, literature_uniqueness_prior, out_of_distribution, direction_conflict, interval_width
confidence_vector.uncertainty_interval Bootstrap interval on the percentile
competing_profiles Other profile families that score within reach of this one
top_two_margin Percentile points between this profile and the next-highest family
modules.<name>.module_status / independent_cluster_coverage Whether a study module could be scored, and what fraction of its independent feature clusters were measured
modules.<name>.bound / would_bind_if Whether the module's evidence type has a measurement in this pipeline, and what would bind it if not
features[].evidence_type / claim_level What kind of measurement the feature is and what the source study could legitimately claim
features[].scoring_weight / audit_factor_wqsc Only w enters the score; w·q·s·c is recorded for audit

And alongside the profiles, under profile_similarity:

Field Meaning
ranked[] Every profile with status, percentile, concordance and maturity, highest first
shape_analysis.verdict specific, diffuse, quiet, mixed or unscored — the library-wide reading
shape_analysis.n_above_typical_band / n_notably_high How many profiles sit above the 75th / 95th percentile
shape_analysis.mean_specificity_of_high_scorers Whether the high scorers discriminate their own condition or track general disturbance
confounder_ledger.recorded / missing / profiles_abstained Which subject facts were supplied, which were not, and which profiles refused to score for want of them
withheld_opt_in_profiles Profiles skipped without --include-opt-in
community.groups[] Ten curated microbial groups: summed abundance, cohort percentile, prevalence, each member's own placement
community.species[] Every species named by the scoring lane: abundance, cohort percentile, prevalence, and which groups it belongs to

Full detail on the scoring: PROFILES.md.

Sequencing quality fields

sequencing_quality.gates is the spec 4.2 gate table.

Field Meaning
overall pass, warn, fail or unknown — the worst individual gate
usable_nonhost_pairs / depth_adequate / minimum_usable_pairs The prespecified depth floor (500,000 pairs) and whether it was met
gates[] One row per gate: gate, label, value, display, status, note. A gate that could not be measured is unknown, never pass
provenance Instrument, run, flowcell, lane and index read from the FASTQ headers, and the batch key they form

sequencing_quality.fastp is the parsed fastp report: pairs and bases in and out, Q20/Q30, GC, duplication rate, read-length profile, adapter-trimmed reads, insert-size peak, and whether the reads arrived pre-trimmed.

Extended catalogue fields

extended_catalogue is the MetaPhlAn 4 SGB inventory. It is reported, never scored — what_this_is says so in the file.

Field Meaning
n_sgbs_detected / n_species_detected / n_genera_detected Catalogue breadth in this sample
n_unnamed_sgbs / unnamed_sgb_percent Genome bins with no cultured representative, and their share of the sample
unclassified_percent What even this catalogue could not name
sgbs[] Every bin: sgb, species, genus, kingdom, percent, unnamed
bridge_to_scoring_lane Species named by both profilers, by MetaPhlAn 4 alone, and by MetaPhlAn 3 alone, with examples

Version identifiers

Two profile results are comparable only when all five of these match. They are all in results.json and on the technical page of the PDF.

Identifier Where
Pipeline version version
DIAMOND reference fingerprint run["reference fingerprint"]
MetaPhlAn database profile_similarity.taxonomic_engine.database
Reference cohort manifest profile_similarity.reference.taxonomic.manifest.manifest_id
Profile version profile_similarity.profiles.<name>.profile.version

results.json structure

tool, version, sample
measures, does_not_measure
run                     flags, timings, versions, fingerprints
input                   read counts, lengths, GC, quality, mate structure
normalisation           rpoB counts, the formula, indeterminate flag
search                  hit lines, mate collapse accounting
panels[]                per pathway:
  accepted_fragments, decoy_fragments, copies_per_100_genomes
  copies_per_100_genomes_residue_consistent
  aggregate_method, aggregate_from, stable, caveats
  genes[]               per gene: fragments, identity, references, residue_check
  decoys[]
reference_comparison    percentile, cohort quartiles, status per pathway
community_profile       phyla, genera, diversity indices
diagnostics[]           level, code, message
reference_entries       provenance for every reference set
profile_similarity      disease-pattern engine (see below)
microbiome_age          status, estimate, 80%/95% intervals, OOD detail,
                        contributions, model bundle id
findings_and_evidence
  findings              reference context, detection model, every species with
                        detection status/power, reference prevalence class,
                        percentile among carriers with 90% bootstrap interval,
                        BH q, bucket 1-7, curated interpretation; contradictions
  triggers[]            what fired (panel/group/profile/species, direction)
  evidence_summaries[]  per card: intervention identity, studied protocol,
                        supporting/against assertions with sources, lane,
                        applicability, safety verdict, display policy,
                        never_say, follow-up route, FMT status
  registry              digests of the intervention/safety/interpretation registries

Comparing over time

The same sample analysed twice gives the same answer; two samples from the same person weeks apart give a trend. That trend is more informative than any single value, because the method's systematic biases — reference set composition, identity floors, read length — are held constant across runs and largely cancel in a difference.

Keep results directories per timepoint and compare reference_comparison.panels.<name>.value across them.

Strain resolution (section 17)

Species profiling says an organism is present. Strain resolution says which one — and for much of gut biology that is the question that matters: whether an E. coli is a harmless resident or carries an intact Shiga-toxin operon is a strain-level question, not a species-level one.

The report resolves, for every organism with enough coverage, the dominant population's consensus across marker genes, at single-base resolution. In the supplied samples that is 49–78 organisms each, over 5.5–7.5 million callable bases.

What a fingerprint is, and is not

It is It is not
This sample's own population of that organism A match to a named laboratory strain
The dominant population Proof of a single strain — a minority population can be concealed
Comparable between specimens at base level A whole-genome identity claim from conserved markers
Evidence of an organism's identity Attribution of a separately detected toxin or resistance gene

An organism detected but not resolved is reported as exactly that. Absence of resolution is a limit of sequencing depth, not a finding about the organism.

How it is produced

The marker lane is a second pass over the reads, pinned to MetaPhlAn 4.1.1 and the mpa_vJun23_CHOCOPhlAnSGB_202403 database — the same pair that produced the sample's abundance profile. Mixing the 4.1 and 4.2 workflows is not supported and is actively prevented: a 4.2 strainphlan on PATH will not be used against 4.1 alignments.

# emit SAM alongside the usual outputs, in a fresh directory so an existing
# bowtie2 summary cannot cause the alignment to be skipped
metaphlan reads_1.fastq.gz,reads_2.fastq.gz --input_type fastq \
  --bowtie2db refs/metaphlan4_db --index mpa_vJun23_CHOCOPhlAnSGB_202403 \
  --nproc 32 -s sample.markers.sam.bz2 \
  --bowtie2out sample.markers.bowtie2.bz2 -o sample.markers.species.tsv

sample2markers.py -i sample.markers.sam.bz2 -o consensus_markers \
  -d refs/metaphlan4_db/mpa_vJun23_CHOCOPhlAnSGB_202403.pkl -n 32

samtools is a hard dependency of sample2markers.py.

What was asked for, and what came back

Every report now carries a completeness census: each registered resolution target with the state it actually reached. The distinction it preserves is the one that matters most in a screening report:

An unrun, failed or unavailable assay is never reported as a negative result.

States include completed, reference_unavailable (the tool or reference is not installed), incompatible_input (an RNA virus cannot be assayed from DNA sequencing, and adding reference sequences cannot change that) and scheduled (registered, with reference curation outstanding). The full per-target detail, with a reason for every non-terminal target, is in results.json under resolution_census.

Get sample report Get Free Report