| import yaml |
| import json |
| import copy |
| import logging |
|
|
| from Bio import PDB |
|
|
| logger = logging.getLogger(__name__) |
|
|
|
|
| |
|
|
| def load_config(config_file): |
| """ |
| Loads file with some type of configuration. |
| Config types: |
| Descriptor config - contains descriptor settings |
| |
| Examples of all configs can be found in /configs. |
| |
| Parameters |
| ---------- |
| config_file: str or dict |
| If str is passed, config_file is interpreted as path to a file. |
| A file should be of json or yaml format to be correctly loaded. |
| If dict is passed, the function returns a deep copy of an object. |
| |
| """ |
| if isinstance(config_file, str): |
| if config_file.endswith(".yml") or config_file.endswith(".yaml"): |
| try: |
| with open(config_file, "r") as stream: |
| return yaml.safe_load(stream) |
| except BaseException as e: |
| logger.error(f"Failed to read yaml file. Please check format validity at {config_file}.\n{e}") |
| raise |
| elif config_file.endswith(".json"): |
| try: |
| with open(config_file, "r") as f: |
| return json.load(f) |
| except BaseException as e: |
| logger.error(f"Failed to read json file. Please check format validity at {config_file}.\n{e}") |
| raise |
| elif isinstance(config_file, dict): |
| return copy.deepcopy(config_file) |
| else: |
| logger.error( |
| """Invalid format! Please supply a path to .yml, .yaml, or .json file as str. |
| Alternatively, provide python dict as an argument.""" |
| ) |
| return None |
|
|
|
|
| def get_model_and_structure(pdb_file, chain_id=None): |
| """ |
| Initialize PDB structure. |
| |
| Parameters |
| ---------- |
| pdb_file: str |
| Filename of .pdb file used for calculation. |
| chain_id: str, default=None |
| Chain identifier to use. If None, tries 'A' first then falls back |
| to the first available chain. |
| |
| Returns |
| ------- |
| tuple: parser, structure, model, chain, atom_structure. |
| |
| """ |
| p = PDB.PDBParser(QUIET=True) |
| structure = p.get_structure('protein', pdb_file) |
| model = structure[0] |
|
|
| if chain_id is not None: |
| chain = model[chain_id] |
| else: |
| try: |
| chain = model['A'] |
| except KeyError: |
| chains = list(model.get_chains()) |
| if not chains: |
| raise ValueError(f"No chains found in {pdb_file}") |
| chain = chains[0] |
| logger.warning( |
| f"Chain 'A' not found in {pdb_file}. " |
| f"Using first available chain '{chain.id}' instead." |
| ) |
|
|
| atom_struct = structure.get_atoms() |
| return p, structure, model, chain, atom_struct |
|
|
|
|
| def getResidues(dssp): |
| """Get residues and their indexes in order from dssp. |
| |
| Parameters |
| ---------- |
| dssp: PDB.DSSP |
| pdb.dssp object, requires dssp module to be installed in the system. |
| |
| Returns |
| ------- |
| tuple of lists: list of residues and list of indexes. |
| |
| """ |
| residues = [] |
| numbers = [] |
| for num, val in enumerate(dssp.keys()): |
| numbers.append(num) |
| residues.append(val[1][1]) |
| return residues, numbers |
|
|
|
|
| def getNum(n, res_num): |
| """Get order number of residue based on residue id number. |
| |
| Parameters |
| ---------- |
| n: int |
| residue id number. |
| res_num: tuple of lists |
| residues and order indexes, returned by getResidues. |
| Returns |
| ------- |
| int: position number of this residue. |
| |
| """ |
| res, num = res_num |
| try: |
| idx = res.index(n) |
| return num[idx] |
| except ValueError: |
| raise ValueError(f'{n} is not in a list of residues!') |
|
|
|
|
| def getRes(n, res_num): |
| """ Get residue id number based on order number of residue. |
| |
| Parameters |
| ---------- |
| n: int |
| position index of residue. |
| res_num: tuple of lists |
| residues and order indexes, returned by getResidues. |
| Returns |
| ------- |
| int: residue id. |
| |
| """ |
| res, num = res_num |
| try: |
| idx = num.index(n) |
| return res[idx] |
| except ValueError: |
| raise ValueError(f'{n} is not in a list of numbers!') |
|
|