Biological Concepts¶
This page explains the key biological and software design concepts a developer needs to understand before extending REvoDesign. Each entry links to the relevant API reference for deeper detail.
Biological Concepts¶
1. Mutant¶
A Mutant is the core data model representing a point mutation or a set of mutations on a protein sequence. It extends RosettaPy.common.mutation.Mutant (RpMutant) via simple inheritance and adds REvoDesign-specific fields.
- Fields: Inherits
mutations(a list ofMutationobjects, each specifying position, wild-type residue, and mutant residue), plus REvoDesign additions:mutant_score(float, the computed fitness score),pdb_fp(str, path to the mutated PDB file), andmutant_description(str, a human-readable label). - Construction: Created directly or via helper functions in
REvoDesign.tools.mutant_tools(extract_mutants_from_mutant_id,extract_mutant_from_sequences). The.emptyproperty checks whether the mutant carries any mutations. - Role: Mutants flow through the entire design pipeline -- generated by a designer, packed by a mutate runner, scored by a scorer, collected into a tree, evaluated interactively, and visualized in PyMOL.
API reference: REvoDesign.common
2. MutantTree¶
MutantTree provides hierarchical navigation across mutant designs organized by branch. It is the data structure that backs the interactive evaluation UI.
- Structure: A
dict[str, dict[str, Mutant]]mapping branch IDs to mutant IDs toMutantobjects. Each branch corresponds to an exploration trajectory (e.g., one round of design). - Navigation:
current_branch_idandcurrent_mutant_idtrack the user's position in the tree. Utilities likerefresh_mutants(),all_mutant_objects,all_mutant_scores, andall_mutant_idsprovide bulk access. - Integration: The
MutateRunnerAbstract.mutated_pdb_mapping()static method associates output PDB file paths back to theirMutantobjects in the tree. The evaluator (Evaluator) uses the tree to walk through scored designs.
API reference: REvoDesign.common
3. Designers (Gimmicks)¶
Designers are external design/scoring tools wrapped as subclasses of ExternalDesignerAbstract. They are colloquially called "gimmicks" inside the Magician orchestration system.
ExternalDesignerAbstract: An abstract class (extendingThirdPartyModuleAbstract) that defines the contract for a designer or scorer. Key class-level flags control behavior:scorer_only: bool-- ifTrue, the gimmick can only score, not generate new designs.prefer_lower: bool-- whether lower scores are better (for ranking).-
no_need_to_score_wt: bool-- whether the wild-type sequence needs no separate scoring. -
Core methods (subclasses override as needed):
designer(*args, **kwargs)-- generate new mutant designs.scorer(mutant, **kwargs) -> float-- evaluate a single mutant's fitness.parallel_scorer(mutants, nproc, **kwargs) -> list[Mutant]-- parallelized batch scoring viajoblib.Parallel.-
initialize()-- one-time setup (load models, verify credentials). -
Discovery: Subclasses are auto-discovered in the
REvoDesign.magician.designerspackage byDESIGNER_REGISTRY(aPluginRegistry). Each subclass must setname: strto a unique identifier. To be listed as installed, setinstalled: bool = True. -
Available designers:
ProteinMPNN(ProteinMPNN-based sequence design via ColabDesign, exported asColabDesigner_MPNN),Cartesian-ddG(Cartesian ddG scoring, exported asddg), and theopenkineticsOpenMM-based kinetic/thermodynamic scorer suite. -
Magician orchestration: The
Magiciansingleton manages the lifecycle of the currently active gimmick. See Magician Orchestration Protocol below.
API reference: REvoDesign.magician | Magician README
Magician Orchestration Protocol (MGOP)¶
Magician(SingletonAbstract) is the central orchestrator for gimmicks:
- Setup:
magician.setup(name_cfg_term="ui.interact.use_external_scorer")reads the config, resolves the gimmick name, and callsinitialize()on the selectedExternalDesignerAbstractsubclass. - Usage: Access
magician.gimmick.scorer(mutant=...)for scoring ormagician.gimmick.designer(...)for sequence generation. - Cooldown: Call
magician.setup()with no arguments to clear the active gimmick. - Assistant:
MagicianAssistant(a frozen dataclass) holds the list of installed workers and providesget(name, **kwargs)to instantiate a gimmick by name.
4. Mutate Runners¶
Mutate runners wrap sidechain packing and protein modeling tools. Each is a subclass of MutateRunnerAbstract (extending ThirdPartyModuleAbstract).
MutateRunnerAbstract: Defines the contract with two required methods:run_mutate(mutant: Mutant) -> str-- perform mutations and return the PDB path.run_mutate_parallel(mutants: list[Mutant], nproc: int = 2) -> list[str]-- batch mutation in parallel.-
Optionally
reconstruct()-- rebuild sidechains on the wild-type structure. -
Runner registry:
RUNNER_REGISTRY(aPluginRegistry) auto-discovers subclasses in theREvoDesign.sidechain.mutate_runnerpackage.MutateRunnerManageris a frozen dataclass providingget(name, **kwargs)for instantiation. -
Available runners (class name → registration
name): MutateRelax_worker("Rosetta-MutateRelax") — Rosettamutate_relaxprotocol (requires Rosetta installation).DLPacker_worker("DLPacker") — DLPacker deep-learning sidechain packing.DLPackerPytorch_worker("DLPackerPytorch") — PyTorch port of DLPacker.PIPPack_worker("PIPPack") — PIPPack rotamer-based packing (configured viapippack.yaml).DiffPack_worker("DiffPack") — DiffPack diffusion-based packing.PyMOL_mutate("Dunbrack Rotamer Library") — Dunbrack rotamer library via PyMOL'scmd.get_wizard().do_pick().
API reference: REvoDesign.sidechain | Mutate Runner README
5. Design Hotspots¶
Identifying which residues to mutate is handled by two complementary PyMOL-driven modules:
PocketSearcher(REvoDesign.structure): Detects ligand/cofactor binding pockets. It uses PyMOL selections to identify:hetatm_pocket-- residues withinligand_radiusof any heteroatom.substrate_pocket-- residues around a named substrate residue (e.g., "UNK").cofactor_pocket-- residues around named cofactors.-
Outputs are saved as PyMOL selection objects and optionally written to a
.psesession file. -
SurfaceFinder(REvoDesign.structure): Computes solvent-accessible surface area (SASA) via PyMOL'sget_area()with adot_solventparameter.findSurfaceResidues()returns residue positions with exposure above a configurable cutoff (default 2.5 A^2). Used to restrict mutations to surface-exposed positions. -
Inter-chain contacts: During the design workflow, inter-chain distance constraints from the GREMLIN co-evolution analysis (see below) can further refine hotspot selection.
API reference: REvoDesign.structure
6. Profiles¶
Profiles provide external data that guides or constrains the mutagenesis search. All parsers extend ProfileParserAbstract.
-
ProfileParserAbstract: Abstract base withparse() -> pd.DataFrame, plus properties for score normalization (score_max_abs,min_score_profile,max_score_profile). -
Available parsers:
PSSM_Parser-- reads Position-Specific Scoring Matrix (PSSM) files from PSI-BLAST. Parses the 20-column amino acid probability table.CSVProfileParser-- reads CSV-format profile data (e.g., ddG per-position scores).prefer_lower = True.-
TSVProfileParser-- reads tab-separated profile data. -
ProfileManager: A factory that selects and initializes the correct parser byprofile_typename (string matched against each parser'snameattribute). -
ESM-1v: Zero-shot mutation effect predictions from the ESM-1v language model can be loaded as a profile table and integrated into the clustering workflow.
API reference: REvoDesign.common
7. MutantVisualizer¶
MutantVisualizer loads designed mutants into PyMOL sessions for interactive inspection.
- Workflow: It takes a
Mutantobject, loads the input PyMOL session, colors residues by mutation score using a configurable colormap (cmap, defaultbwr_r), and generates temporary session files for each mutant. - Features: Profile scoring data can be overlaid on the structure. Wild-type and mutant residues are shown as sticks/mesh for side-by-side comparison. The visualizer is driven by
MutateWorker/VisualizingWorkerin the phylogenetics module. - Output: Temporary
.psesessions are written to disk and loaded into the active PyMOL instance.
API reference: REvoDesign.common
8. Evaluator¶
Evaluator is the interactive decision-making engine that lets users walk through scored mutants, accept or reject them, and guide the design trajectory.
- Navigation: Relies on a
MutantTreeto track branches and current position.activate_focused()highlights the current mutant in PyMOL (mesh/sticks representation), hides other branches, and centers the view. - Decision flow:
mutant_decision(decision_to_accept: bool)records accept/reject choices into theMutantTree. Accepted mutants can seed the next design round. - Integration: Instantiated in
REvoDesignPlugin.__init__()asself.evaluator. Writes choices to a CSV log viasave_mutant_choices().
API reference: REvoDesign.evaluate (core.md includes evaluate)
9. GREMLIN (Interact)¶
GREMLIN (Generative Reuglarized Model_s of_prote_INs) provides co-evolutionary analysis to identify residue pairs that evolve together, implying structural or functional coupling.
GREMLIN_Tools(REvoDesign.phylogenetics.gremlin_tools): Loads GREMLIN output (co-evolution scores, PDB structural data). Core data class:-
CoevolvedPair-- stores a pair of positions(i, j), their amino acids, inter-chain distances (homochains_dist, supporting multi-chain/multi-state analysis), z-scores, and distance cutoffs. Methods likeis_out_of_range(),all_out_of_range, andmin_distenable filtering. -
GremlinAnalyser(REvoDesign.phylogenetics.evo_mutator): Wires co-evolved pairs into the REvoDesign workflow. Displays pair connections as PyMOL CGO (Cylinder-style) objects with state-based coloring (available / out-of-range / in-design). -
MutateWorker/REvoDesigner(REvoDesign.phylogenetics.evo_mutator): Applies evolutionary constraints to drive mutagenesis using co-evolved pair information and the Magician's scoring gimmick. Supports multi-round iterative design. -
Integration: PyTorch-based GREMLIN calculations via
gremlin_pytorch.py. The GREMLIN interact tab (Interact) is wired into the main UI alongside the cluster and evaluate workflows.
API reference: REvoDesign.phylogenetics (core.md includes phylogenetics)
10. Clusters¶
Sequence clustering reduces large mutant sets to representative variants for experimental testing. Built around a ClusterMethodAbstract base class.
-
ClusterMethodAbstract(CitableModuleAbstract, ABC): Base class for all clustering algorithms. Key attributes:name,installed,spec(aClusterMethodSpecdescribing inputs and display metadata). Theglobal_alignment()method uses Bio.PairwiseAligner with configurable substitution matrices. -
ClusterMethodManager: The registry/factory for cluster methods. Methods are discovered viabuild_plugin_registryin theREvoDesign.clusters.methodspackage. -
Available methods (in
REvoDesign.clusters.methods): AgglomerativeCluster-- hierarchical agglomerative clustering.KMeansCluster-- k-means clustering.EvoCluster-- evolution-guided clustering that incorporates PSSM, ESM-1v, and spatial proximity weights.-
LegacyCluster-- deprecated original Ward-linkage clustering based on the score matrix; retained for compatibility only. PreferAgglomerativeClusterorEvoClusterfor new work. -
ClusterRunner: The top-level orchestrator instantiated by the plugin. Reads all config values from the UI, configures the selected method, runs clustering, scores representatives (via Rosettascore_clusters), and writes output variant tables.
API reference: REvoDesign.clusters
Software & API Design Concepts¶
1. SingletonAbstract¶
SingletonAbstract (in REvoDesign.basic.abc_singleton) is the Borg-like singleton base used throughout the codebase.
- Mechanism:
__new__returns the cached_instanceif one exists.__init__callssingleton_init()only once, guarded byself.initialized. Subclasses must implementsingleton_init(). derive(name): Creates a dynamically-named subclass with its own independent_instance, enabling multiple singleton instances of the same lineage (e.g.,StoresWidget.derive("derived_name")).reset_instance(): Sets_instance = Noneso the next__new__creates a fresh instance.reset_singletons()iterates all subclasses and resets them.- Used by:
ConfigBus,Magician,SidechainSolver,CitationManager,StoresWidget.
API reference: REvoDesign.basic
2. Config Tree¶
REvoDesign uses OmegaConf/Hydra for hierarchical, YAML-based configuration management.
- Layout: YAML config files live in
src/REvoDesign/config/as templates. On first import,bootstrap/__init__.pycopies them to a user config directory determined byplatformdirs: main.yaml-- top-level UI and workflow settings.logger.yaml-- logging configuration (formatters, handlers, levels).environ.yaml-- environment variables.runtime.yaml-- runtime-only (non-persisted) settings.openmm.yaml-- OpenMM simulation parameters.-
Subdirectories:
rfdiffusion/,rosetta-node/,sidechain-solver/. -
Bootstrap sequence (
REvoDesign.bootstrap): set_REvoDesign_config_file()-- ensure user config dir exists.hydra.initialize_config_dir()-- point Hydra at the user config dir.verify_config_tree_structure()-- copy missing template files to user dir.enforce_config_key_structure()-- add new keys that exist in templates but not in user config.experiment_config()-- set up experiment output directories.-
CACHE_CONFIG_DIR-- initialize YAML cache directory. -
Access:
Configdataclass (name, path, cfg).Config.from_name("main")loads a named config.reload_config_file("main")refreshes from disk.
API reference: REvoDesign.bootstrap | Config README
3. ConfigBus¶
ConfigBus(SingletonAbstract) is the bidirectional bridge between Qt UI widgets and the OmegaConf YAML config tree. It is the central nervous system of the application.
- Headless mode: When instantiated without a UI (e.g., during tests),
ConfigBus.headless = Trueand onlyget_value/set_valuework. Widget access requires the@require_non_headlessdecorator. Widget2ConfigMapper: Maps config item names to widget IDs, then to widget objects. UsesConfig2WidgetIds(widget registry) andPushButtons(button registry).Configdataclass:Config.from_name("main")loads a named config section.cfg_groupon the bus holds all loaded configs by name.StoresWidget: A companion singleton holding server-switch references for features like the OpenMM server and the Monaco editor server. Itsreset_instance()cascades resets to all registered singleton controllers.
API reference: REvoDesign.driver
4. Logger System¶
The logging system uses Python's standard logging module, configured via logger.yaml.
- Initialization: The root logger (
ROOT_LOGGER) is initialized at import time (step 5 inREvoDesign/__init__.py).setup_logging()readslogger.yamlvialogging.config.dictConfig(). REvoDesignLogFormatter: A custom JSON formatter that outputs structured log records with ISO 8601 timestamps, making logs machine-parseable. Built-inLOG_RECORD_BUILTIN_ATTRSdefines the set of standard attributes.- Log channels: Each module creates a child logger via
ROOT_LOGGER.getChild(__name__). This produces hierarchical names likeREvoDesign.magician,REvoDesign.sidechain.sidechain_solver. - Config-driven: Formatters, handlers, levels, and filters are all specified in
logger.yaml, allowing runtime reconfiguration by editing the YAML file.
API reference: REvoDesign.logger
5. Plugin Launch Order¶
The exact import and initialization sequence matters for correct behavior. It is orchestrated in REvoDesign/__init__.py and REvoDesign.REvoDesignPlugin.make_window().
Import-time sequence (in REvoDesign/__init__.py):
- SingletonAbstract -- base singleton class (step 1).
- Bootstrap -- config file initialization (step 2).
- File extensions -- register PyMOL file format handlers (step 3).
- ConfigBus -- UI-to-config bridge (step 4). Created without UI (headless).
- Logger --
ROOT_LOGGERandsetup_logging(step 5). Must come after config so logger.yaml is available. - Version --
__version__ = "X.Y.Z"(step 6).
Runtime init sequence (in REvoDesignPlugin.make_window()):
load_runtime_ui()-- loadREvoDesign.uiviaRuntimeUiProxy.IconSetter-- set window icons.reload_configurations()-- load YAML configs into the bus.ClusterTabController-- install cluster tab.FontSetter-- set UI fonts.LanguageSwitch-- install i18n translator.MenuCollection-- bind menu actions (static + deferred config-file scanning).StoresWidget-- server-switch references.
API reference: REvoDesign.core
6. Issue System¶
REvoDesign defines a comprehensive hierarchy of custom exceptions and warnings for structured error handling.
- Exceptions (
REvoDesign.issues.exceptions): All inherit fromREvoDesignException. Key types:ConfigurationError,PluginError,DependencyError,InvalidInputError,NoResultsError,NetworkError,UninstalledPackageError,FileFormatError,InternalError,EnzymeDesignError. - Warnings (
REvoDesign.issues.warnings): All inherit fromREvoDesignWarning. Key types:DisabledFunctionWarning,NoInputWarning,ConflictWarning,BadDataWarning.ConfigureOutofDateErrorlives in exceptions. - Usage: Exceptions are raised with descriptive messages and are caught at the UI layer to show
notify_boxdialogs. Warnings use Python'swarnings.warn().
API reference: REvoDesign.issues
7. Qt Wrapper¶
All Qt imports must go through REvoDesign.Qt -- never import PyQt5 or PyQt6 directly. This compatibility layer handles differences between Qt5 and Qt6.
qt_wrapper.py: Detects the backend frompymol.Qt.PYQT_NAME. ExposesQtCore,QtGui,QtWidgets,QtNetwork,QtSvg,QtUiTools,QtWebSockets.QT_BACKENDis"PyQt5"or"PyQt6";QT_MAJORis5or6.QtCompat: Utility class providing unified access to enum values across Qt5/Qt6.install_qt6_aliases()addsQt5Compat-style access for Qt6 scoped enums.RuntimeUiProxy(ui_runtime_loader.py): Loads.uifiles at runtime viauic.loadUiType(PyQt5) orQtUiTools.QUiLoader(PyQt6). Named widgets become proxy attributes; duplicate names are recorded in_duplicate_object_names. SupportsretranslateUi()andrefresh_bindings().REvoDesignUiProtocol(inUI/types.py): Auto-generated typing contract fromREvoDesign.ui-- provides IDE autocompletion without constructing the UI.
8. Menu System¶
The menu system uses a declarative, dataclass-driven approach in REvoDesign.basic.menu_item.
MenuItem(action, func, args, kwargs): A frozen dataclass mapping a UI action name to a callable. Special cases:action="---"creates a separator.funccan be a dotted string path or a"LAMBDA:..."expression for deferred resolution.MenuCollection(ui, menu_items): Binds allMenuIteminstances to their correspondingQActionobjects at construction time. If an action doesn't exist on the UI, it can be created dynamically if amenu_sectionis provided.- Deferred registration: Dynamic actions (e.g., designer/scorer selection) are registered at config load time by
group_registries.GroupRegistryItem, which scans config files for new items.
API reference: REvoDesign.basic
9. Citation System¶
REvoDesign tracks BibTeX citations for all third-party tools and algorithms used during a session.
CitableModuleAbstract: Abstract base class with a__bibtex__dict attribute mapping citation keys to BibTeX strings (or tuples of strings). Provides:notice()-- log citation information unless silenced.cite()-- add citations to the globalCitationManagerand display notice.-
get_citable_class(func)-- resolve the citable class from a function reference. -
CitationManager(SingletonAbstract): Global singleton that collects citations from allcite()calls. Canoutput()a.bibfile,clear()the collection, anddismiss()specific modules to suppress repeated notices. -
get_citeddecorator (inREvoDesign.tools.utils): A decorator that marks a function with__bibtex__and automatically callscite()on the owning class when the function is invoked.
API reference: REvoDesign.citations
10. Plugin Registries¶
REvoDesign uses package-scoped, auto-discovering registries for extensible plugin systems.
PluginRegistry(Generic[PluginT]): A frozen dataclass that discovers all non-abstract subclasses of a base class within a given Python package. Discovery usespkgutil.iter_modulesandinspect.getmembers. Key properties:all_classes-- all discovered subclasses.implemented_map-- mapping ofname-> class.-
installed_names-- names of classes whereinstalled = True. -
build_plugin_registry(): Convenience factory for creating aPluginRegistrywith standard defaults. -
Two registries exist:
DESIGNER_REGISTRY-- inREvoDesign.magician, discoversExternalDesignerAbstractsubclasses underREvoDesign.magician.designers.-
RUNNER_REGISTRY-- inREvoDesign.sidechain, discoversMutateRunnerAbstractsubclasses underREvoDesign.sidechain.mutate_runner. -
Registration: Subclasses do not need explicit registration -- importing the package (done by
__init__.pymodule-level imports likefrom . import designers as _designers) triggerspkgutildiscovery automatically.