Summarizing reports¶
gapit summary collapses one or more abricate-format report tables (including gapit screen
output) into a gene presence/absence matrix: one row per file, one column per gene. It replaces
abricate --summary.
Input reports are TSV or CSV with the standard 15-column header (#FILE SEQUENCE ...),
exactly what gapit screen writes. See ./screen.md for producing them and
./outputs.md for the output schemas.
Options¶
Transcribed from gapit summary --help (gapit 0.5.6):
| Flag | Type | Default | Description |
|---|---|---|---|
FILE... |
path(s) | stdin | Abricate-format report file(s) to summarize. At least one input: files, a piped table, or - for stdin. |
--identity / -i |
flag | off | Cells show %IDENTITY values (default: +/-). |
--coverage / -c |
flag | off | Cells show %COVERAGE values (default: +/-). |
--nopath |
flag | off | Basename row keys (FILE values / input filenames). |
--quiet |
flag | off | Silence stderr diagnostics. |
--format |
tsv|csv|json|md | tsv |
Output format. |
Dutch mode vs multi-file mode¶
Row keys depend on the input count, matching abricate's behavior:
- Exactly one report (dutch mode): rows are keyed by that report's
FILEcolumn, so you get one row per assembly inside the report. - More than one report: rows are keyed by the input filenames as given, one row per file.
A file with no hits still appears, with
NUM_FOUND 0.
$ gapit summary tests/data/summary/multi_sample.tsv
#FILE NUM_FOUND feature_a feature_b
aa_assembly.fa 1 + -
mm_assembly.fa 1 - +
zz_assembly.fa 1 + -
The same three assemblies summarized as separate reports instead would key by filename:
$ gapit summary tests/data/summary/sample_a.tsv tests/data/summary/sample_b.tsv tests/data/summary/empty.tsv
#FILE NUM_FOUND feature_a feature_b
tests/data/summary/empty.tsv 0 - -
tests/data/summary/sample_a.tsv 2 + +
tests/data/summary/sample_b.tsv 2 + +
Note the zero-hit file: it appears with NUM_FOUND 0 and . in every gene column. In
presence mode multiple hits on the same gene collapse to one +; with --identity or
--coverage their per-hit values join with ; in report order.
Piping screen output¶
gapit summary reads its table from stdin whenever stdin is not a terminal (piped or
redirected), so the screen stage can feed it directly — the canonical batch pipe. One
screen call over many assemblies writes one batched table (every row carries the same
DATABASE; the FILE column spans the whole batch), and a piped table counts as ONE
input, so dutch mode applies — one row per FILE value, the gene×file presence matrix:
$ gapit screen -d ecoli_dec *.fna --nopath --quiet | gapit summary
#FILE NUM_FOUND aggR astA escV pic stx2a uidA
dec_s1_aggR_pic_uidA.fna 3 + - - + - +
dec_s2_pic_astA_uidA.fna 3 - + - + - +
dec_s3_stx2a_escV_aggR_uidA.fna 4 + - + - + +
The same matrix gapit summary combined.tsv prints after
gapit screen -d ecoli_dec *.fna --output combined.tsv. Rules:
- Bare
gapit summaryat a terminal keeps printing help (exit 2); with a pipe or a redirect attached it reads stdin instead. gapit summary -is the explicit stdin marker — it reads stdin even with a terminal attached, until EOF.- Mixing
-with file arguments is a usage error (v1 takes either stdin or files, never both). - Non-UTF-8 stdin exits 5 with a
SUMMARY_MALFORMEDenvelope naming-; a malformed piped row names-and its line number.
Cell modes¶
By default cells carry the presence call: + when the file has at least one hit for the
gene, - when absent.
| Mode | Invocation | Cells |
|---|---|---|
| Presence (default) | gapit summary a.tsv b.tsv |
+ / - |
| Identity | --identity / -i |
each hit's %IDENTITY, ;-joined (. = absent) |
| Coverage | --coverage / -c |
each hit's %COVERAGE, ;-joined (. = absent) |
| Both | -ic (combined) |
each hit's identity/coverage, ;-joined (. = absent) |
The flags combine (-ic): each hit renders as identity/coverage. The chosen metric is
noted on stderr. --coverage reproduces the classic abricate --summary cell shape byte-for-byte —
the parity harness runs in this mode.
$ gapit summary tests/data/summary/sample_a.tsv tests/data/summary/sample_b.tsv
#FILE NUM_FOUND feature_a feature_b
sample_a.tsv 2 + +
sample_b.tsv 2 + +
Cells keep the original report strings verbatim; no reformatting or averaging happens.
NUM_FOUND counts distinct genes. The gene universe is the union of all GENE values across
all inputs, sorted lexicographically; a gene absent from a row shows ..
Input parsing¶
- Separator auto-detection, per file. Each input is read as TSV or CSV by sniffing its own first line, so you can mix tab and comma reports in one call without flags:
$ gapit summary tests/data/summary/sample_a.csv tests/data/summary/sample_b.csv --nopath
#FILE NUM_FOUND feature_a feature_b
sample_a.csv 2 + +
sample_b.csv 2 + +
- Duplicate inputs are skipped. A path listed twice (compared as given, before any basenaming) warns on stderr and is processed once:
$ gapit summary tests/data/summary/sample_a.tsv tests/data/summary/sample_a.tsv
WARNING: Skipping duplicate file: tests/data/summary/sample_a.tsv
#FILE NUM_FOUND feature_a feature_b
tests/data/summary/sample_a.tsv 2 + +
- Malformed input is a typed error, not silence. A missing file exits 5 with an
INPUT_NOT_FOUNDenvelope; a row too short for the header map exits 5 withSUMMARY_MALFORMED. - Header handling matches abricate's parser. The first row of the first file becomes the
column-name map. Lines whose first column starts with
#are then skipped as headers, so a conventional report contributes data rows only. Two quirks fall out of that rule: a noheader report's first row doubles as header map and data row, and a file whose key starts with#is skipped entirely (the check runs before--nopathbasenaming).
Output formats¶
--format tsv (default) and --format csv print the matrix above. --format json and
--format md emit the gapit.summary/1 document, which keeps every cell string and adds
machine-readable params:
$ gapit summary tests/data/summary/sample_a.tsv tests/data/summary/sample_b.tsv --format json --quiet
{
"schema": "gapit.summary/1",
"tool": {
"name": "gapit",
"version": "0.5.6"
},
"created_at": "2026-09-19T01:12:48Z",
"params": {
"metric": "%COVERAGE",
"nopath": false
},
"genes": [
"feature_a",
"feature_b"
],
"rows": [
{
"file": "tests/data/summary/sample_a.tsv",
"num_found": 2,
"cells": {
"feature_a": [
"99.50",
"52.00"
],
"feature_b": [
"76.00"
]
}
},
{
"file": "tests/data/summary/sample_b.tsv",
"num_found": 2,
"cells": {
"feature_a": [
"90.00"
],
"feature_b": [
"100.00"
]
}
}
]
}
Introspect the schema with gapit schema summary; field contracts live in
./outputs.md.
Notes¶
- Sort order is by key, not label. Rows sort by the row key exactly as given, before
--nopathbasenaming. With files spread over directories the basenamed labels can therefore appear unsorted:
$ gapit summary /tmp/gapit-demo/sortdemo/1dir/zeta.tsv /tmp/gapit-demo/sortdemo/2dir/mid.tsv --nopath
#FILE NUM_FOUND feature_a feature_b
zeta.tsv 1 + -
mid.tsv 1 - +
The order comes from 1dir/zeta.tsv < 2dir/mid.tsv, so zeta.tsv prints first even though
mid.tsv sorts earlier alphabetically. Without --nopath the full keys print in obvious
order:
$ gapit summary /tmp/gapit-demo/sortdemo/1dir/zeta.tsv /tmp/gapit-demo/sortdemo/2dir/mid.tsv
#FILE NUM_FOUND feature_a feature_b
/tmp/gapit-demo/sortdemo/1dir/zeta.tsv 1 + -
/tmp/gapit-demo/sortdemo/2dir/mid.tsv 1 - +
- Dutch mode keys come from the report. With one input, the row labels are the
FILEvalues found inside the report, not the report's own filename. --quietsuppresses the--identitynote and duplicate warnings, never stdout.