GEODES / src /geodes /utils.py
miras_dev
handle chains that are not only A but X, C, 1 and etc
9536cc6
Raw
History Blame Contribute Delete
4.26 kB
import yaml
import json
import copy
import logging
from Bio import PDB
logger = logging.getLogger(__name__)
# _________________FUNCTIONS____________________________ #
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!')