Source code for pestifer.objs.align

# Author: Cameron F. Abrams, <cfa22@drexel.edu>
"""
An alignment coormod: computes the rigid-body transformation that minimizes
RMSD between a selection in the pipeline system and the same (or a different)
selection in a reference coordinate file, then applies that transformation
to the pipeline system.

VMD's ``measure fit`` is used to compute the 4×4 homogeneous transformation
matrix; the reference molecule is loaded and deleted within the generated
script so it leaves no persistent state.
"""
import logging
logger = logging.getLogger(__name__)
from typing import ClassVar
from pydantic import Field, model_validator
from ..core.baseobj import BaseObj, BaseObjList


[docs] class Align(BaseObj): """ Align the pipeline system to a reference coordinate file. Parameters (from YAML ``specs``) --------------------------------- ref_pdb : str, optional Path or filename of the reference PDB file. Mutually exclusive with ``ref_sourceID``. ref_sourceID : str, optional RCSB PDB ID for the reference structure. The PDB file is downloaded to the working directory if not already present. Mutually exclusive with ``ref_pdb``. Exactly one of ``ref_pdb`` / ``ref_sourceID`` must be supplied. ref_psf : str, optional Path to the reference PSF file. When omitted the reference is loaded as a plain PDB (sufficient for coordinate fitting). mobile_sel : str, optional VMD atomselect string for the pipeline atoms used in the fit. Defaults to ``"all"``. ref_sel : str, optional VMD atomselect string for the reference atoms used in the fit. Defaults to ``mobile_sel`` when omitted. apply_to : str, optional VMD atomselect string for the pipeline atoms that are actually moved by the fitted transformation. Defaults to ``"all"``. Notes ----- Both selections passed to ``measure fit`` must contain the same number of atoms in the same order. Mismatched counts will cause a VMD error. """ _required_fields = set() _optional_fields = {'ref_pdb', 'ref_sourceID', 'ref_psf', 'mobile_sel', 'ref_sel', 'apply_to'} _mutually_exclusive = {frozenset({'ref_pdb', 'ref_sourceID'})} ref_pdb: str | None = Field(None, description="Filename of the reference PDB file.") ref_sourceID: str | None = Field(None, description="RCSB PDB ID; the file is downloaded to CWD if not already present.") ref_psf: str | None = Field(None, description="Path to the reference PSF file (optional).") mobile_sel: str = Field('all', description="VMD atomselect string for pipeline atoms used in the fit.") ref_sel: str | None = Field(None, description="VMD atomselect string for reference atoms used in the fit (defaults to mobile_sel).") apply_to: str = Field('all', description="VMD atomselect string for pipeline atoms to move after fitting.") @model_validator(mode='after') def _require_one_ref(self): if self.ref_pdb is None and self.ref_sourceID is None: raise ValueError("Align requires exactly one of 'ref_pdb' or 'ref_sourceID'.") return self @property def effective_ref_pdb(self) -> str: """Resolved filename of the reference PDB (local path or derived from ref_sourceID).""" return self.ref_pdb if self.ref_pdb is not None else f'{self.ref_sourceID}.pdb' _yaml_header: ClassVar[str] = 'align' _objcat: ClassVar[str] = 'coord'
[docs] class AlignList(BaseObjList[Align]):
[docs] def describe(self): return f'<AlignList with {len(self)} alignments>'