Source code for rnamake.chain

import exceptions


[docs]class Chain(object): """ Stored chain information from pdb file. Stores all residues in chain. Implementation is designed to be extremely lightweight. To connect residues into chains it highly adviced that you use :func:`connect_residues_into_chains` :param residues: the residues that are to be included in this chain :type residues: list of residue.Residue objects :attributes: `residues` : List of Residue objects The list of residues that belong to this chain will always be in 5' to 3' order :examples: .. code-block:: python >>> import rnamake.unittests.instances >>> c = rnamake.unittests.instances.chain() >>> c.first() <Residue('G103 chain A')> >>> c.last() <Residue('C260 chain A')> >>> len(c) 157 >>> cs = c.subchain(1, 10) >>> len(cs) 9 >>> cs.first() <Residue('A104 chain A')> >>> cs2 = c.subchain(start_res=c.residues[10], end_res=c.residues[15]) >>> len(cs2) 6 >>> c.to_pdb_str() ATOM 1 O5' G A 103 -26.469 -47.756 84.669 1.00 0.00 ATOM 2 C5' G A 103 -25.050 -47.579 84.775 1.00 0.00 ATOM 3 C4' G A 103 -24.521 -48.156 86.068 1.00 0.00 ATOM 4 O4' G A 103 -24.861 -49.568 86.118 1.00 0.00 ATOM 5 C3' G A 103 -23.009 -48.119 86.281 1.00 0.00 ATOM 6 O3' G A 103 -22.548 -46.872 86.808 1.00 0.00 ATOM 7 C1' G A 103 -23.806 -50.289 86.732 1.00 0.00 ATOM 8 C2' G A 103 -22.812 -49.259 87.269 1.00 0.00 . . . """ __slots__ = ["residues"] def __init__(self, residues=None): self.residues = residues if residues is None: self.residues = [] def __repr__(self): if len(self.residues) == 0: return "<Chain( First: None\n\t Last: None\n\t Size: 0)>" return "<Chain( First: %s\n\t Last: %s\n\t Size: %s)>" %\ (self.first(), self.last(), len(self.residues)) def __len__(self): return len(self.residues)
[docs] def first(self): """ returns residue at 5' end of chain :returns: first residue in chain :rtype: residue.Residue :examples: .. code-block:: python >>> import rnamake.unittests.instances >>> c = rnamake.unittests.instances.chain() >>> c.first() <Residue('G103 chain A')> """ if len(self.residues) == 0: raise exceptions.ChainException("cannot call first there are no " "residues in chain") return self.residues[0]
[docs] def last(self): """ returns 3' end of chain """ if len(self.residues) == 0: raise exceptions.ChainException("cannot call first there are no " "residues in chain") return self.residues[-1]
[docs] def subchain(self, start=None, end=None, start_res=None, end_res=None): """ Creates a new chain from a subsection of the residues in the current chain. :param start: start position in residues object list, default:None :param end: end position in residues object list, default:None :param start_res: The 5' residue of sub chain, default:None :param end_res: The 3' resiude of sub chain, default:None :type start: int :type end: int :return: Chain object :examples: .. code-block:: python >>> cs = c.subchain(1, 10) >>> len(cs) 9 >>> cs.first() <Residue('A104 chain A')> >>> cs2 = c.subchain(start_res=c.residues[10], end_res=c.residues[15]) >>> len(cs2) 6 """ if start_res is not None and end_res is not None: try: start = self.residues.index(start_res) end = self.residues.index(end_res) except: raise exceptions.ChainException("supplied start_res and end_res " "but they are not members of " "chain") if start > end: start, end = end, start end += 1 elif start_res is not None and end_res is None: raise exceptions.ChainException("supplied start_res but not end_res") elif start_res is not None and start is not None: raise exceptions.ChainException("cannot supply start and start_res") if start < 0: raise exceptions.ChainException("start pos cannot be less then 0") if end is None: end = len(self.residues) return Chain(self.residues[start:end])
[docs] def copy(self): """ Creates a deepcopy of the this chain object. :return: Chain object """ residues = [r.copy() for r in self.residues] return Chain(residues)
[docs] def to_str(self): """ Stringifes Chain object :return: str """ s = "" for r in self.residues: s += r.to_str() + ";" return s
[docs] def to_pdb_str(self, acount=1, return_acount=0, rnum=-1, chain_id=""): """ creates a PDB string formatted verision of this Chain object. :param acount: current atom index, default: 1 :param return_acount: final atom index after current atoms, default: 0 :param rnum: starting residue number, default: -1 :param chain_id: the chain id of the chain, i.e. "A", "B" etc :type acount: int :type return_acount: int :type rnum: int :type chain_id: str :return: str """ s = "" for r in self.residues: r_str, acount = r.to_pdb_str(acount, 1, rnum, chain_id) if rnum != -1: rnum += 1 s += r_str # TODO fix returns should only be one possibility if return_acount: return s, acount else: return s
[docs] def to_pdb(self, fname="chain.pdb", rnum=-1, chain_id=""): """ Writes a PDB string formmated verision of this Chain object to file :param fname: filename of output PDB file, default="chain.pdb" :param rnum: starting residue number, default: -1 :param chain_id: the chain id of the chain, i.e. "A", "B" etc :type fname: str :type rnum: int :type chain_id: str :return: None """ f = open(fname, "w") f.write(self.to_pdb_str(rnum=rnum, chain_id=chain_id)) f.close()
[docs]def connect_residues_into_chains(residues): """ takes all residues and puts into the correct order in chains checking for physical connection between O5' and P atoms between residues :param residues: residue objects that belong in this structure :type residues: List of Residue objects :return: List of Chain objects """ chains = [] # sort residues so check residues for connection quicker as the next on # in the array will be closest to it by number residues.sort(key=lambda x: x.num) while True: current = None # find next 5' end, all chains go from 5' to 3' for i, r in enumerate(residues): five_prime_end = 1 for j, r2 in enumerate(residues): if r.connected_to(r2) == -1: five_prime_end = 0 break if five_prime_end: current = r break if not current: break residues.remove(current) current_chain_res = [] # extend chain until 3' end while current is not None: current_chain_res.append(current) found = 0 for r in residues: if current.connected_to(r) == 1: current = r found = 1 break if found: residues.remove(current) else: # no more residues to add, make chain object chains.append(Chain(current_chain_res)) current = None return chains