| """
|
| 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
|
|
|
| binding_status: Optional[str] = None
|
| chain_composition: Optional[str] = None
|
|
|
| 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
|
|
|
| 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]
|
|
|