CellDesigner model
pd2af.building.celldesigner.model
Build the AF model from clingo activity / influence atoms.
make_and_add_model is the model pass: it walks the activity atoms in
layer order (keptSpeciesKey → promotedSubunitKey) and populates context.model
with canonical, content-deduped compartments, templates, species and
modulations. When the forms of the same base entity merge (keep_species
off) each activity's species is stripped of its PTM decorations (recursively,
including subunits) by get_or_make_stripped_species; otherwise the input
species is kept, placed in its effective compartment by
get_or_make_species_in_compartment.
Which compartment a species goes in is _compartment_for_input_species: its
own, its complex's when it is a promoted subunit, or -- with the
drop_compartments option -- the input map's default compartment, whatever
the species' own. Every compartment then merges into that one, and species and
influences that become content-equal collapse through the shared cache.
The stateless get_or_make_* leaf helpers do the actual element
construction. Each interns the constructed element through a shared
content-keyed cache (register_or_reuse), so two content-equal elements
collapse to a single Python identity end-to-end. The canonicity policy is
"first-registered wins"; combined with the layer order above, a kept
input-map element is always the canonical instance for its content class,
never displaced by a freshly stripped one.
:mod:pd2af.core drives this pass through a
:class:pd2af.building.context.BuilderContext, then
the layout pass.
Functions:
| Name | Description |
|---|---|
collect_ancestor_compartments |
|
compartments_outermost_first |
|
find_default_compartment |
The default compartment of |
get_or_make_modulation |
Build a modulation and intern by content. |
get_or_make_species_in_compartment |
Canonical species for |
get_or_make_stripped_species |
Return a decoration-free canonical species for |
get_or_make_stripped_template |
Strip the PTM decorations from |
get_parent_complex_compartment |
Resolve a subunit's effective compartment. |
make_and_add_model |
Build |
collect_ancestor_compartments
compartments plus every compartment they are nested in, transitively.
Source code in src/pd2af/building/celldesigner/model.py
compartments_outermost_first
compartments sorted by nesting depth, so a container precedes its content.
Source code in src/pd2af/building/celldesigner/model.py
find_default_compartment
The default compartment of input_model, or None if it has none.
CellDesigner declares a compartment with id default in every map, and
it is the one the writer points a species with no compartment at. It is the
compartment every activity goes in under the drop_compartments option,
so the output still declares the compartment its species refer to.
Source code in src/pd2af/building/celldesigner/model.py
get_or_make_modulation
Build a modulation and intern by content.
Source code in src/pd2af/building/celldesigner/model.py
get_or_make_species_in_compartment
get_or_make_species_in_compartment(input_species: Any, compartment: Any, cache: dict, input_model_element_to_canonical_model_element: dict) -> Any
Canonical species for input_species placed in compartment.
Used with keep_species on, which keeps each PD species as its own
activity, for both activity-key kinds. A species already in
compartment — the usual keptSpeciesKey case — is its own canonical
instance, so it is registered as is and later
content-equal candidates collapse onto it. Otherwise the species is rebuilt
in compartment: a promoted subunit carries compartment=None
(inherited from the parent complex) and needs its complex's compartment
once it stands at top level, and the drop_compartments option puts
every species in the default compartment so that species differing only by
compartment collapse.
Two input species placed in the same compartment collapse via the cache; a rebuilt species that is content-equal to an already-cached kept one collapses onto that.
Records id(input_species) -> canonical in
input_model_element_to_canonical_model_element whenever the canonical
differs from the input — Pass 2's layout mapping copies use that dict to
substitute stale value references that still point at the input species.
Source code in src/pd2af/building/celldesigner/model.py
get_or_make_stripped_species
get_or_make_stripped_species(input_species: Any, compartment: Any, cache: dict, input_model_element_to_canonical_model_element: dict) -> Any
Return a decoration-free canonical species for input_species.
Used with keep_species off. Clears every post-translational decoration -- active (-> False), homomultimer (-> 1),
modifications, structural_states, and, via a stripped template,
modification_residues/regions -- sets the effective compartment,
and strips subunits recursively (a frozenset collapses subunits that
strip to equal content). Built with dataclasses.replace so the concrete
class and the input's real, reader-resolvable id_ are preserved;
content-equal stripped twins still intern to one canonical because id_
is compare=False. Records id(input) -> canonical when they differ so
Pass 2 can substitute stale references (mirrors
get_or_make_species_in_compartment).
Source code in src/pd2af/building/celldesigner/model.py
get_or_make_stripped_template
Strip the PTM decorations from input_template and intern by content.
Two distinct input templates that strip to the same content yield a single canonical stripped template.
Kept templates must already be registered in the cache (per pipeline
step (3), kept templates are collected before stripped ones are
built). When a stripped candidate is content-equal to a kept
template, register_or_reuse returns the kept canonical and no
duplicate enters the cache.
Source code in src/pd2af/building/celldesigner/model.py
get_parent_complex_compartment
Resolve a subunit's effective compartment.
Walks to its containing top-level species: subunits typically have no
compartment attribute of their own.
Source code in src/pd2af/building/celldesigner/model.py
make_and_add_model
make_and_add_model(context: BuilderContext, clingo_model: Any)
Build context.model from the clingo atoms (pass 1).