Detection Workflow#
The systems subcommand detects biological systems in one or more pangenomes.
The entry point is panorama.systems.detection.launch(); the core logic lives in
panorama.systems.detection.
Prerequisites#
Detection requires that gene families have already been annotated: each
GeneFamily must carry HMM-hit metadata
(written by panorama annotation) so the detector knows which families are candidates
for each functional unit.
The pre-flight check panorama.systems.detection.check_pangenome_detection()
verifies this and raises early if the annotation source is missing or systems have
already been computed (use --force to overwrite).
Step-by-step pipeline#
1. Load models#
Models are parsed from the JSON model files
specified by --models. Each file yields one or more
Model objects, each containing a list of
FuncUnit objects and their associated
Family profiles.
2. Build the gene-context graph#
For each Pangenome, PANORAMA calls PPanGGOLiNβs
ppanggolin.context.searchGeneContext.compute_gene_context_graph to construct a
gene-context graph β a networkx graph in which:
nodes are
GeneFamilyobjectsedges connect families that co-occur within a genomic window (controlled by the
--windowand--transitivityparameters of the model)
This graph captures local genomic neighbourhood without committing to a fixed operon boundary.
3. Find functional units in the graph#
panorama.systems.detection.search_system_units() iterates over every
Model and calls
panorama.systems.detection.search_unit_in_context() for each
FuncUnit.
search_unit_in_context extracts connected components of the context graph that
contain at least one family matching the unitβs profile, then calls:
panorama.systems.detection.search_unit_in_cc()β tests each connected component for the presence of qualifying familiespanorama.systems.detection.search_unit_in_combination()β when a component contains multiple candidates, enumerates sub-combinations viapanorama.systems.detection.get_subcombinations()to find the minimal satisfying set
The result is a dict {FuncUnit β set[SystemUnit]} of candidate detections.
4. Apply quorum rules#
Before a full System is assembled,
two filters are applied:
Function |
Rule checked |
|---|---|
At least |
|
No |
If either check fails, the candidate is discarded.
5. Assemble System objects#
panorama.systems.detection.search_for_system() takes the passing
{FuncUnit β SystemUnit} mapping and constructs a
System object. Where multiple valid unit
combinations exist, panorama.systems.detection.get_system_unit_combinations()
enumerates them and each yields a separate System.
The full scan across all models and organisms is orchestrated by
panorama.systems.detection.search_systems() (single pangenome) and
panorama.systems.detection.search_systems_in_pangenomes() (parallel,
multi-pangenome via ThreadPoolExecutor + shared Lock).
6. Attach results to the pangenome#
panorama.systems.detection.write_systems_to_pangenome() iterates the detected
System objects and registers them on the
Pangenome via its _system_getter index.
panorama.systems.detection.write_systems_to_pangenomes() does the same across
all pangenomes in a Pangenomes container.
7. Persist to HDF5#
The launch function calls panorama.format.write_binaries.write_pangenome(),
which in turn calls panorama.format.write_binaries.write_systems_to_hdf5() to
serialise every System and SystemUnit into the pangenomeβs .h5 file.
See I/O Layer for the table schema.
Data-flow summary#
CLI args
β
ββ check_detection_args() validate & build need_info dict
ββ load_pangenomes() read .h5 files (parallel)
ββ Models (from JSON files) parse model definitions
β
ββ search_systems_in_pangenomes() ββ ThreadPoolExecutor βββΊ
β per pangenome:
ββ compute_gene_context_graph() PPanGGOLiN context graph
ββ search_system_units() find FuncUnit candidates
ββ check_for_needed_units() quorum check
ββ check_for_forbidden_unit() forbidden-unit check
ββ search_for_system() assemble System objects
β
ββ write_systems_to_pangenome() attach to Pangenome
β
ββ write_pangenome() persist to HDF5
Key parameters and their effect#
Parameter |
Model field |
Effect |
|---|---|---|
|
|
Maximum genomic distance (in genes) between families in the same context |
|
|
Extends neighbourhood transitively β larger values widen the search |
|
β |
Minimum Jaccard similarity for context graph edges; lower values are more permissive |
|
β |
Preset combining window + transitivity for convenience |
Note
Detection is run per-source: running panorama systems twice with different --source
values produces two independent sets of System objects stored under separate HDF5 groups.
Use --force to overwrite an existing source.