---
myst:
html_meta:
"description lang=en": |
Description of PANORAMA's class architecture and its relationship with PPanGGOLiN
"keywords": |
Pangenomics, Python, Developer, Architecture, Classes, PPanGGOLiN
---
# Class Architecture
PANORAMA is built **on top of PPanGGOLiN**: every core domain object in PANORAMA extends a corresponding PPanGGOLiN
class rather than reimplementing it from scratch. This page maps the full class hierarchy, explains what each class
adds, and shows how the pieces fit together.
---
## Inheritance overview
```
PPanGGOLiN PANORAMA extension
──────────────────────────────────────────────────────
ppanggolin.pangenome.Pangenome → panorama.pangenomes.Pangenome
ppanggolin.geneFamily.GeneFamily → panorama.geneFamily.GeneFamily
ppanggolin.region.Region → panorama.region.Region
ppanggolin.region.Spot → panorama.region.Spot
ppanggolin.region.Module → panorama.region.Module
ppanggolin.region.GeneContext → panorama.region.GeneContext
ppanggolin.metadata.MetaFeatures → panorama.systems.system.SystemUnit
ppanggolin.metadata.MetaFeatures → panorama.systems.system.System
panorama.pangenomes.Pangenome → panorama.pangenomes.Pangenomes (container)
panorama.geneFamily.GeneFamily → panorama.geneFamily.Akin (cross-pangenome link)
```
---
## Pangenome layer
### `Pangenome` ({py:mod}`panorama.pangenomes`)
Extends `ppanggolin.pangenome.Pangenome`.
PPanGGOLiN's `Pangenome` already manages organisms, contigs, genes, gene families, RGPs, spots, and modules. PANORAMA's
subclass {py:class}`panorama.pangenomes.Pangenome` adds the systems layer on top:
| Addition | Purpose |
|-----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
| `_system_getter` / `_name2system` | Index detected {py:class}`System ` objects by ID and name |
| `systems_sources` | Track which annotation sources have been run |
| `add_file()` override | Validates that the file is HDF5 and reads PANORAMA-specific status fields via {py:func}`panorama.format.read_binaries.get_status` |
| `status["systems"]` | Extends PPanGGOLiN's status dict with a `"systems"` key |
The constructor takes a `name` (used throughout outputs) and an optional `taxid`.
### `Pangenomes` ({py:mod}`panorama.pangenomes`)
A plain PANORAMA class (no PPanGGOLiN parent) that acts as the **multi-pangenome container**
used by every comparative workflow: {py:class}`panorama.pangenomes.Pangenomes`.
| Feature | Details |
|---------------|-----------------------------------------------------------------------------------------------------------------------|
| Storage | Dict of `name →` {py:class}`Pangenome ` |
| Thread safety | Accepts a shared `multiprocessing.Manager().Lock()` via {py:func}`panorama.utils.init_lock` for concurrent HDF5 reads |
| Loading | Delegates per-pangenome loading to `ThreadPoolExecutor` (see {py:mod}`panorama.format.read_binaries`) |
| Input | Populated from a TSV file via {py:func}`panorama.utils.check_tsv_sanity` |
---
## Gene family layer
### `GeneFamily` ({py:mod}`panorama.geneFamily`)
Extends `ppanggolin.geneFamily.GeneFamily`.
Adds HMM-annotation state and cross-pangenome linkage on top of PPanGGOLiN's graph-node representation: {py:class}
`panorama.geneFamily.GeneFamily`.
| Addition | Purpose |
|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `_hmm`, `profile`, `optimized_profile` | Store the pyHMMER `HMM` object and search profiles used during annotation |
| `_units_getter` / `_systems_getter` | Index the {py:class}`SystemUnit ` and {py:class}`System ` objects that contain this family |
| `_akin` | Link to an {py:class}`Akin ` object representing equivalent families in other pangenomes |
### `Akin` ({py:mod}`panorama.geneFamily`)
A pure PANORAMA class (no PPanGGOLiN parent) that groups {py:class}`GeneFamily ` objects
from **different pangenomes** that have been determined to be functionally equivalent (by alignment or clustering). It
is the data structure behind cross-pangenome family comparison:
{py:class}`panorama.geneFamily.Akin`.
---
## Region layer
All four classes in {py:mod}`panorama.region` extend the matching PPanGGOLiN region class. At present they are thin
subclasses — their main purpose is to allow PANORAMA to inject additional attributes without patching PPanGGOLiN objects
directly.
| PANORAMA class | Extends | Key additions |
|-------------------------------------------------------|----------------------------------|-------------------------------------------------------------------------------|
| {py:class}`Region ` | `ppanggolin.region.Region` (RGP) | None — placeholder for future PANORAMA-specific state |
| {py:class}`Spot ` | `ppanggolin.region.Spot` | `pangenome` back-reference; `conserved_id` for cross-pangenome matching |
| {py:class}`Module ` | `ppanggolin.region.Module` | Tracks associated {py:class}`System ` objects |
| {py:class}`GeneContext ` | `ppanggolin.region.GeneContext` | Minimal extension used during system detection |
### `ConservedSpots` ({py:mod}`panorama.region`)
A pure PANORAMA class ({py:class}`panorama.region.ConservedSpots`) that groups {py:class}`Spot `
objects from different pangenomes that occupy the same conserved genomic locus. It is the output of
`panorama compare_spots`.
---
## Systems layer
The systems layer is entirely PANORAMA-specific — PPanGGOLiN has no equivalent.
### Model definitions ({py:mod}`panorama.systems.models`)
These classes parse and validate model JSON files before detection runs.
| Class | Role |
|---------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| {py:class}`Models ` | Top-level container; maps `source → {name → Model}` |
| {py:class}`Model ` | One system definition: name, quorum rules (`min_mandatory`, `min_total`), transitivity, window, and a list of `FuncUnit` objects |
| {py:class}`FuncUnit ` | One functional unit within a model: presence type (`mandatory`, `accessory`, `forbidden`, `neutral`) and the `Family` profiles that can fill it |
| {py:class}`Family ` | A named HMM/profile entry inside a `FuncUnit`; the leaf of the model tree |
{py:class}`Model ` and {py:class}`FuncUnit `
share behaviour via two private mixin bases (`_BasicFeatures`, `_ModFuFeatures`); {py:class}
`FuncUnit ` and {py:class}`Family `
share a third (`_FuFamFeatures`).
### Detected objects ({py:mod}`panorama.systems.system`)
These classes hold the **results** of running detection against a pangenome.
| Class | Extends | Role |
|---------------------------------------------------------------------|------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| {py:class}`SystemUnit ` | `ppanggolin.metadata.MetaFeatures` | One detected functional unit: links a {py:class}`FuncUnit ` model to the {py:class}`GeneFamily ` objects that satisfy it in a specific pangenome |
| {py:class}`System ` | `ppanggolin.metadata.MetaFeatures` | One detected system: groups {py:class}`SystemUnit ` objects and tracks their associated {py:class}`Spot `, {py:class}`Module `, and {py:class}`Region ` objects |
| {py:class}`ClusterSystems ` | — | Groups {py:class}`System ` objects from different pangenomes that represent the same biological system (used during comparison) |
Both {py:class}`SystemUnit ` and {py:class}`System `
extend PPanGGOLiN's `MetaFeatures`, which provides the generic metadata key/value store used for TSV and HDF5
serialisation.
---
## How the layers connect
```
Pangenomes
└─ Pangenome (one per input .h5 file)
├─ GeneFamily (extends ppanggolin GeneFamily)
│ └─ Akin (links equivalent families across pangenomes)
├─ Region / Spot / Module (extend ppanggolin region classes)
│ └─ ConservedSpots (groups Spots across pangenomes)
└─ System (PANORAMA-only)
└─ SystemUnit (one per satisfied FuncUnit)
└─ GeneFamily (the families that fill the unit)
Models (parsed before detection, not stored in Pangenome)
└─ Model
└─ FuncUnit
└─ Family
```
A {py:class}`System ` is created when the detection algorithm (in {py:mod}
`panorama.systems.detection`) finds that a set of gene families in a genomic window satisfies the quorum rules of a {py:
class}`Model `. Each satisfied {py:class}`FuncUnit `
becomes a {py:class}`SystemUnit `; the {py:class}
`SystemUnit ` objects are collected into a {py:class}
`System ` which is then attached to the {py:class}
`Pangenome `.
---
## Key PPanGGOLiN touchpoints
| PPanGGOLiN symbol | Where PANORAMA uses it |
|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|
| `ppanggolin.pangenome.Pangenome` | Base of {py:class}`panorama.pangenomes.Pangenome` |
| `ppanggolin.geneFamily.GeneFamily` | Base of {py:class}`panorama.geneFamily.GeneFamily` |
| `ppanggolin.region.{Region,Spot,Module,GeneContext}` | Bases of the four classes in {py:mod}`panorama.region` |
| `ppanggolin.metadata.MetaFeatures` | Base of {py:class}`SystemUnit ` and {py:class}`System ` |
| `ppanggolin.context.searchGeneContext` | Called by {py:mod}`panorama.systems.detection` to build the genomic-context graph used during detection |
| `ppanggolin.formats.*` | HDF5 read/write helpers extended by {py:mod}`panorama.format.read_binaries` and {py:mod}`panorama.format.write_binaries` |
```{note}
There is a known circular-import risk between `pangenomes.py` and `systems/system.py`.
If you need to import one from the other, use a **function-local import** rather than a
top-level one. `tests/conftest.py` documents the current workaround.
```