Source code for emdb.models.entry

from typing import TYPE_CHECKING, Optional, Dict, List, Union

from pydantic import BaseModel, PrivateAttr

from emdb.models.files import PrimaryMapFile, HalfMapFile, AdditionalMapFile, MaskFile, FigureFile, \
    ModelCifFile, EMDBMetadataXMLFile, EMDBMetadataCIFFile

if TYPE_CHECKING:
    from emdb.client import EMDB
    from emdb.models.validation import EMDBValidation
    from emdb.models.annotations import EMDBAnnotations


[docs] class EMDBEntry(BaseModel): id: str method: Optional[str] = None resolution: Optional[float] = None admin: Dict citations: Dict related_emdb_ids: List[Dict] related_pdb_ids: List[Dict] sample: Dict structure_determination_list: List[Dict] modelling: Optional[List[Dict]] = None primary_map: PrimaryMapFile metadata_files: List[Union[EMDBMetadataXMLFile, EMDBMetadataCIFFile]] = [] pdb_models: Optional[List[ModelCifFile]] = [] half_maps: Optional[List[HalfMapFile]] = [] additional_maps: Optional[List[AdditionalMapFile]] = [] masks: Optional[List[MaskFile]] = [] figure: FigureFile _client: Optional["EMDB"] = PrivateAttr(default=None)
[docs] @classmethod def from_api(cls, data: dict, client: "EMDB") -> "EMDBEntry": """ Create an EMDBEntry instance from API data. :param data: Dictionary containing EMDB entry data. :param client: An instance of EMDB client to interact with the API. :return: An instance of EMDBEntry. """ emdb_id = data.get("emdb_id") numeric_id = emdb_id[4:] try: method = data['structure_determination_list']['structure_determination'][0]['method'] except KeyError: method = None try: resolution = data['structure_determination_list']['structure_determination'][0]['image_processing'][0]['final_reconstruction']['resolution']['valueOf_'] except KeyError: resolution = None try: citations = data['crossreferences']['citation_list'] except KeyError: citations = {} try: related_emdb_ids = data['crossreferences']['emdb_list']['emdb_reference'] except KeyError: related_emdb_ids = [] try: related_pdb_ids = data['crossreferences']['pdb_list']['pdb_reference'] pdb_models = [] for model in related_pdb_ids: pdb_id = model["pdb_id"] model_file = ModelCifFile(pdb_id=pdb_id, filename=f"{pdb_id}_updated.cif") model_file._emdb_id = emdb_id pdb_models.append(model_file) except KeyError: related_pdb_ids = [] pdb_models = [] try: half_maps = data['interpretation']['half_map_list']['half_map'] except KeyError: half_maps = None try: additional_maps = data['interpretation']['additional_map_list']['additional_map'] except KeyError: additional_maps = None try: masks = data['interpretation']['segmentation_list']['segmentation'] except KeyError: masks = None try: modelling = data['interpretation']['modelling_list']['modelling'] except KeyError: modelling = None primary_map = PrimaryMapFile.from_api(data.get("map", {})) primary_map._emdb_id = emdb_id figure = FigureFile(filename=f"400_{numeric_id}.gif") figure._emdb_id = emdb_id xml_file = EMDBMetadataXMLFile(filename=f"emd-{numeric_id}-v30.xml") xml_file._emdb_id = emdb_id cif_file = EMDBMetadataCIFFile(filename=f"emd-{numeric_id}.cif.gz") cif_file._emdb_id = emdb_id metadata_files = [xml_file, cif_file] half_maps_objs = [] if half_maps: for hm in half_maps: hm_file = HalfMapFile.from_api(hm) hm_file._emdb_id = emdb_id half_maps_objs.append(hm_file) additional_maps_objs = [] if additional_maps: for am in additional_maps: am_file = AdditionalMapFile.from_api(am) am_file._emdb_id = emdb_id additional_maps_objs.append(am_file) masks_obj = [] if masks: for m in masks: mask_file = MaskFile.from_api(m) mask_file._emdb_id = emdb_id masks_obj.append(mask_file) obj = cls( id=emdb_id, method=method, resolution=resolution, admin=data.get("admin", {}), citations=citations, related_emdb_ids=related_emdb_ids, related_pdb_ids=related_pdb_ids, sample=data.get("sample", {}), structure_determination_list=data.get("structure_determination_list", {}).get("structure_determination", []), modelling=modelling, primary_map=primary_map, metadata_files=metadata_files, pdb_models=pdb_models, half_maps=half_maps_objs, additional_maps=additional_maps_objs, masks=masks_obj, figure=figure, ) obj._client = client return obj
[docs] def get_validation(self) -> Optional["EMDBValidation"]: """ Retrieve the validation data for this EMDB entry. :return: An instance of EMDBValidation if available, otherwise None. """ print("Retrieving validation data for EMDB entry:", self.id) print("Client:", self._client) if self._client: return self._client.get_validation(self.id) return None
[docs] def get_annotations(self) -> Optional["EMDBAnnotations"]: """ Retrieve annotations for this EMDB entry. :return: An instance of EMDBAnnotations if available, otherwise None. """ print("Retrieving annotations for EMDB entry:", self.id) if self._client: return self._client.get_annotations(self.id) return None
@property def deposited_files(self) -> List[Union[PrimaryMapFile, HalfMapFile, AdditionalMapFile, MaskFile, FigureFile, ModelCifFile]]: """ Retrieve all files associated with this EMDB entry. :return: A list of all file objects associated with the EMDB entry. """ files = [self.primary_map, self.figure] if self.half_maps: files.extend(self.half_maps) if self.additional_maps: files.extend(self.additional_maps) if self.masks: files.extend(self.masks) if self.pdb_models: files.extend(self.pdb_models) return files
[docs] def download_all_files(self, directory: str) -> None: """ Download all files associated with this EMDB entry to the specified directory. :param directory: The directory where files will be downloaded. """ for file in self.deposited_files: print(f"Downloading file: {file.filename}") file.download(directory)
def __str__(self): return f"<EMDBEntry id={self.id}, method={self.method}, resolution={self.resolution}>" def __repr__(self): return self.__str__()