Source code for PANDORA.Database.Database

import PANDORA
import pickle
from PANDORA.PMHC import PMHC
from PANDORA.Database import Database_functions
import os

[docs]class Database: def __init__(self): self.MHCI_data = {} self.MHCII_data = {} self.ref_MHCI_sequences = {} self.__IDs_list_MHCI = [] self.__IDs_list_MHCII = []
[docs] def download_data(self, data_dir = PANDORA.PANDORA_data, download = True): """download_data(self, data_dir = PANDORA.PANDORA_data, download = True) Download all MHC structures and get a two lists that contains all MHCI and MHCII IDs respectively""" if download: print('Downloading structures ...') Database_functions.download_unzip_imgt_structures(data_dir = data_dir, del_inn_files=True, del_kabat_files=True) self.__IDs_list_MHCI = Database_functions.download_ids_imgt('MH1', data_dir = data_dir, out_tsv='all_MHI_IDs.tsv') self.__IDs_list_MHCII = Database_functions.download_ids_imgt('MH2', data_dir = data_dir, out_tsv='all_MHII_IDs.tsv')
def __clean_MHCI_file(self, pdb_id, data_dir): """ Clean all MHCI structures""" return Database_functions.parse_pMHCI_pdb(pdb_id, indir = data_dir + '/PDBs/IMGT_retrieved/IMGT3DFlatFiles', outdir = data_dir + '/PDBs/pMHCI', bad_dir = data_dir + '/PDBs/Bad/pMHCI') def __clean_MHCII_file(self, pdb_id, data_dir): """ Clean all MHCII structures. Returns a list of bad PDBs""" return Database_functions.parse_pMHCII_pdb(pdb_id, indir = data_dir + '/PDBs/IMGT_retrieved/IMGT3DFlatFiles', outdir = data_dir + '/PDBs/pMHCII', bad_dir = data_dir + '/PDBs/Bad/pMHCII')
[docs] def update_ref_sequences(self): """Downloads and parse HLA and other MHC sequences to compile reference fastas. Returns a dictionary that can be used to select the desired reference sequence""" self.ref_MHCI_sequences = Database_functions.generate_mhcseq_database()
[docs] def construct_database(self, save, data_dir = PANDORA.PANDORA_data, MHCI=True, MHCII=True, download=True, update_ref_sequences=True): '''construct_database(self, save, data_dir = PANDORA.PANDORA_data, MHCI=True, MHCII=True, download=True, update_ref_sequences=True) Construct the database. Download, clean and add all structures Args: save (str/bool): Filename of database, can be False if you don't want to save the database data_dir (str): Path of data directory. Defaults to PANDORA.PANDORA_data. MHCI (bool): Parse data for MHCI. Defaults to True. MHCII (bool): Parse data for MHCII. Defaults to True. download (bool): If True, download the structures data from IMGT. Defaults to True. update_ref_sequences (bool): If True, downloads and parse reference sequence strcutres. Defaults to True Returns: Database object ''' # Download the data self.download_data(download = download, data_dir = data_dir) # Construct the MHCI database if MHCI: # Parse all MHCI files for id in self.__IDs_list_MHCI: try: templ = self.__clean_MHCI_file(pdb_id = id, data_dir = data_dir) if templ != None: self.MHCI_data[id] = templ except: pass # Construct the MHCII database if MHCII: # Parse all MHCII files for id in self.__IDs_list_MHCII: try: templ = self.__clean_MHCII_file(pdb_id = id, data_dir = data_dir) if templ != None: self.MHCII_data[id] = templ except: print('something went wrong parsing %s' %id) if save: self.save(save) #Download and parse HLA and MHC sequences reference data if update_ref_sequences: self.update_ref_sequences() print('Database correctly generated')
[docs] def add_structure(self, id, allele_type, peptide = '', MHC_class = 'I', chain_seq = [], anchors = [], pdb_path = False, pdb = False): ''' Add a single structure to the database Args: id: (str) PDB identifier allele_type: (lst) list of MHC alleles (or allele) peptide: (str) peptide sequence MHC_class: (str) either 'I' or 'II' denoting MHC class I and MHC class II respectively chain_seq: (lst) list of chain sequence(s) for the M and N (Alpha and Beta) chain respectively anchors: (lst) list of integers specifying which residue(s) of the peptide should be fixed as an anchor during the modelling. MHC class I typically has 2 anchors, while MHC class II typically has 4. pdb_path: (str) path to pdb file pdb: (Bio.PDB) Biopython PBD object ''' if not id: if not pdb_path or not pdb: raise ValueError('Structure id or path of .pdb files was not given. Enter value for id and pdb_path') # Add to MHCI data if MHC_class == 'I': self.MHCI_data[id] = PMHC.Template(id, allele_type, peptide, MHC_class, chain_seq, anchors, pdb_path, pdb) # Add to MHCII data if MHC_class == 'II': self.MHCII_data[id] = PMHC.Template(id, allele_type, peptide, MHC_class, chain_seq, anchors, pdb_path, pdb)
[docs] def remove_structure(self, id =''): ''' Removes a structure (by id) from the database Args: id: (str) PDB ID ''' # Remove structure from database self.MHCI_data.pop(id, None) self.MHCII_data.pop(id, None)
[docs] def repath(self, new_folder_path, save): """ Necessary if the absolut path to the templates structures is different from the one used while generating the database. It changes the template.pdb_path for each template object in the database and returns the modified database. Args: new_folder_path (str): New path to the 'PDBs' directory contaning template structures. save (str/bool): If False, doesn't save the modified database. If str, saves the modified database to the specified file path.' Returns: None. Example: >>> MyDatabase.repath('/home/Users/MyUserName/PANDORA/PDBs/', './MyHome_Database.pkl') """ if type(new_folder_path) != str: raise Exception('Non-string argument detected. Please provide a valid path as argument.') if self.MHCI_data != {}: for id in self.MHCI_data: from_pMHCI_path = os.path.join(*os.path.normpath(self.MHCI_data[id].pdb_path).split('/')[-2:]) self.MHCI_data[id].pdb_path = os.path.join(new_folder_path, from_pMHCI_path) if self.MHCII_data != {}: for id in self.MHCII_data: from_pMHCII_path = os.path.join(*os.path.normpath(self.MHCII_data[id].pdb_path).split('/')[-2:]) self.MHCII_data[id].pdb_path = os.path.join(new_folder_path, from_pMHCII_path) if save: self.save(save)
[docs] def save(self, fn = 'db.pkl'): """Save the database as a pickle file :param fn: (str) pathname of file """ with open(fn, "wb") as pkl_file: pickle.dump(self, pkl_file)
[docs]def load(file_name): """Loads a pre-generated database Args: file_name (str): Dabase file name/path. Returns: Database.Database: Database object. Example: >>> db = Database.load('MyDatabase.pkl') """ with open(file_name, 'rb') as inpkl: db = pickle.load(inpkl) return db