MuSProt / backend /app /protein /models.py
WinslowFan's picture
Add chain_composition + binding status; refresh DB, docs, Fidelity plot
2d33606
Raw
History Blame Contribute Delete
5.66 kB
"""
Data models for the protein visualization API.
"""
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
class CrystalGrow(BaseModel):
"""Crystal growth conditions."""
pH: Optional[float] = None
pH_structured: Optional[float] = None
pH_from_details: Optional[float] = None
temp: Optional[float] = None
pdbx_details: Optional[str] = None
class EntryInfo(BaseModel):
"""Entry-level information."""
rcsb_id: Optional[str] = None
title: Optional[str] = None
initial_release_date: Optional[str] = None
exptl_method: Optional[str] = None
resolution_combined: Optional[List[float]] = None
crystal_grow: Optional[CrystalGrow] = None
class PolymerEntity(BaseModel):
"""Polymer entity (sequence-level) information."""
rcsb_id: Optional[str] = None
entity_id: Optional[str] = None
sequence_length: Optional[int] = None
seq_can: Optional[str] = None
reference_sequences: Optional[List[Dict[str, str]]] = None
class PolymerEntityInstance(BaseModel):
"""Polymer entity instance (chain-level) information."""
rcsb_id: Optional[str] = None
asym_id: Optional[str] = None
auth_asym_id: Optional[str] = None
binding_affinity: Optional[Any] = None
class NonpolymerEntity(BaseModel):
"""Nonpolymer entity (ligand/binder) information."""
rcsb_id: Optional[str] = None
name: Optional[str] = None
formula_weight: Optional[float] = None
smiles: Optional[str] = None
inchi: Optional[str] = None
class ChainMetadata(BaseModel):
"""Complete chain metadata from RCSB."""
pdb_id: str
chain_id: str
entry: EntryInfo
polymer_entity: Optional[PolymerEntity] = None
polymer_entity_instance: Optional[PolymerEntityInstance] = None
nonpolymer_entities: Optional[List[NonpolymerEntity]] = None
binding_status: Optional[str] = None
chain_composition: Optional[str] = None
cath_id: Optional[str] = None
cath_superfamily: Optional[str] = None
state_id: Optional[str] = None
class FilterParams(BaseModel):
"""Request model for filtering protein data."""
chain_ids: Optional[List[str]] = Field(default=None, description="List of chain IDs to filter")
pdb_id: Optional[str] = Field(default=None, description="PDB ID for single chain search")
auth_asym_id: Optional[str] = Field(default=None, description="Chain ID for single chain search")
rmsd_min: Optional[float] = Field(default=None, ge=0, description="Minimum RMSD value")
rmsd_max: Optional[float] = Field(default=None, ge=0, description="Maximum RMSD value")
tm_score_min: Optional[float] = Field(default=None, ge=0, le=1, description="Minimum TM-score")
tm_score_max: Optional[float] = Field(default=None, ge=0, le=1, description="Maximum TM-score")
length_min: Optional[int] = Field(default=None, ge=0, description="Minimum sequence length")
length_max: Optional[int] = Field(default=None, ge=0, description="Maximum sequence length")
include_duplicates: Optional[bool] = Field(default=None, description="Include duplicate structures")
cluster_id: Optional[str] = Field(default=None, description="Structural similarity cluster ID")
limit: Optional[int] = Field(default=1000, ge=1, le=10000, description="Maximum results to return")
class FilterOptions(BaseModel):
"""Available filter options and ranges."""
chain_ids: List[str] = Field(description="Available chain IDs")
rmsd_range: Dict[str, float] = Field(description="Min and max RMSD values")
tm_score_range: Dict[str, float] = Field(description="Min and max TM-score values")
length_range: Dict[str, int] = Field(description="Min and max sequence lengths")
clusters: List[str] = Field(description="Available similarity clusters")
total_records: int = Field(description="Total number of records")
class DataRecord(BaseModel):
"""Single protein comparison record."""
pdb_id_a: str
auth_asym_id_a: str
pdb_id_b: str
auth_asym_id_b: str
tm_score: float
rmsd: float
structure_sim: Optional[float] = None
sequence_identity: Optional[float] = None
length_a: Optional[int] = None
length_b: Optional[int] = None
aligned_length: Optional[int] = None
status: Optional[str] = None
cluster_id: Optional[str] = None
exptl_method: Optional[str] = None
temp: Optional[float] = None
pH: Optional[float] = None
# Matched-chain (B) annotations from the node table
binding_status: Optional[str] = None
chain_composition: Optional[str] = None
# Energy score deltas fetched directly from the edge table
delta_rosetta: Optional[float] = None
delta_foldx: Optional[float] = None
delta_evoef2: Optional[float] = None
delta_rw: Optional[float] = None
delta_rw_plus: Optional[float] = None
# Alternative state similarity fields from edge table
state_id_b: Optional[str] = None
state_fidelity: Optional[str] = None
avg_sim: Optional[str] = None
observation_fidelity: Optional[str] = None
class DataResponse(BaseModel):
"""Response model for filtered data."""
data: List[DataRecord]
total: int
filtered: int
class SummaryStats(BaseModel):
"""Aggregate statistics for the dataset."""
total_records: int
unique_chains: int
avg_rmsd: float
avg_tm_score: float
avg_sequence_length: float
rmsd_distribution: Dict[str, int]
tm_score_distribution: Dict[str, int]
length_distribution: Dict[str, int]