Source code for swamp.wrappers.mapalign

import os
import conkit.io
import numpy as np
from pyjob import cexec
from swamp.wrappers.wrapper import Wrapper
from swamp.wrappers.gesamt import Gesamt
from swamp.parsers import MapAlignParser


[docs]class MapAlign(Wrapper): """Wrapper around map_align :param str workdir: working directory :param str map_a: file name of the map A to be used in the alignment :param str pdb_a: file name of the pdb A to be used for benchmarking of the alignment :param str format_a: contact prediction file format of map A (default 'mapalign') :param str map_b: file name of the map B to be used in the alignment :param str pdb_b: file name of the pdb B to be used for benchmarking of the alignment :param str format_b: contact prediction file format of map B (default 'mapalign') :param int gap_o: gap opening penalty (default -1) :param float gap_e: gap extension penalty (default -0.01) :param int sep_cut: separation cutoff to compute contacts (default 0) :param `~swamp.logger.swamplogger.SwampLogger` logger: logging interface for the wrapper (default None) :ivar bool error: if True an error has occurred along the process :ivar str con_sco: the contact score obtained after alignment of the input maps :ivar str gap_sco: the gap score obtained in the alignment :ivar str total_sco: the gap score obtained after alignment of the input maps :ivar int alignment_length: the length of the alignment obtained between the two input maps :ivar float qscore: qscore as reported by :py:obj:`~swamp.wrappers.gesamt.Gesamt` :ivar float rmsd: the obtained rmsd as reported by :py:obj:`~swamp.wrappers.gesamt.Gesamt` :ivar float seq_id: seq identity between the input structures obtained with :py:obj:`~swamp.wrappers.gesamt.Gesamt` :ivar int n_align: number of aligned residues with :py:obj:`~swamp.wrappers.gesamt.Gesamt` :example: >>> from swamp.wrappers import MapAlign >>> mapalign = MapAlign('<workdir>', '<map_a>', '<map_b>') >>> mapalign.run() """ def __init__(self, workdir, map_a, map_b, format_a='mapalign', format_b='mapalign', gap_o=-1, gap_e=-0.01, sep_cut=0, pdb_a=None, pdb_b=None, logger=None): super(MapAlign, self).__init__(workdir=workdir, logger=logger) self.alignment = None self.con_sco = None self.gap_sco = None self.total_sco = None self.alignment_length = None self.sep_cut = sep_cut self.gap_e = gap_e self.gap_o = gap_o self.qscore = np.nan self.rmsd = np.nan self.seq_id = np.nan self.n_align = np.nan self.pdb_a = pdb_a self.format_a = format_a self.format_b = format_b self.map_a = map_a self.map_b = map_b self.pdb_b = pdb_b # ------------------ Some properties ------------------ @property def wrapper_name(self): """The name of this `~swamp.wrapper.wrapper.Wrapper` child class (aleigen)""" return "map_align" @property def cmd(self): """Command to be executed in the shell""" return [self.source] + self.keywords @property def input_a(self): """File name of the map file A to use in the alignment""" if self.format_a != self._reference_mapformat: return os.path.join(self.workdir, "{}.{}").format(self.map_a_id, self._reference_mapformat) else: return self.map_a @property def input_b(self): """File name of the map file B to use in the alignment""" if self.format_b != self._reference_mapformat: return os.path.join(self.workdir, "{}.{}").format(self.map_b_id, self._reference_mapformat) else: return self.map_b @property def keywords(self): """Keywords passed through the command line to map_align""" return ['-a', self.input_a, '-b', self.input_b, "-sep_cut", str(self.sep_cut), "-gap_e", str(self.gap_e), "-gap_o", str(self.gap_o), '-silent'] @property def summary_results(self): """A list with the figures of merit obtained""" return [self.map_a, self.map_b, self.con_sco, self.gap_sco, self.total_sco, self.alignment_length, self.qscore, self.rmsd, self.seq_id, self.n_align] @property def map_a_id(self): """Basename of :py:attr:`~swamp.wrappers.mapaling.MapAlign.map_a` file without extension""" return os.path.splitext(os.path.basename(self.map_a))[0] @property def map_b_id(self): """Basename of :py:attr:`~swamp.wrappers.mapaling.MapAlign.map_b` file without extension""" return os.path.splitext(os.path.basename(self.map_b))[0] @property def _reference_mapformat(self): """The reference contact map format to be used with the aligner""" return 'mapalign' # ------------------ Some general methods ------------------ def _check_alignment_input(self): """Check that :py:attr:`~swamp.wrappers.mapaling.MapAlign.map_a` and \ :py:attr:`~swamp.wrappers.mapaling.MapAlign.map_b` have the \ :py:attr:`~swamp.wrappers.mapaling.MapAlign._reference_mapformat` and if not convert them using `conkit.io`""" if self.format_a != self._reference_mapformat: self.make_workdir() self.logger.debug((self.map_a, self.format_a, self.input_a, self._reference_mapformat)) self._filthy_files.append(self.input_a) conkit.io.convert(self.map_a, self.format_a, self.input_a, self._reference_mapformat) if self.format_b != self._reference_mapformat: self.make_workdir() self.logger.debug((self.map_b, self.format_b, self.input_b, self._reference_mapformat)) self._filthy_files.append(self.input_b) conkit.io.convert(self.map_b, self.format_b, self.input_b, self._reference_mapformat)
[docs] def get_scores(self, logfile=None): """Method to extract the figures of merit out the stdout :param str logfile: Not in use """ parser = MapAlignParser(logger=self.logger, stdout=self.logcontents) parser.parse() if parser.error: self.error = True self.logger.warning('Previous errors while parsing map_align output detected!') else: self.alignment, self.con_sco, self.gap_sco, self.total_sco, self.alignment_length = parser.summary
[docs] def benchmark(self): """Use :py:obj:`~swamp.wrappers.gesamt.Gesamt` to perform a structural alignment between the input structures \ for benchmarking purposes""" gesamt = Gesamt.get_optimum_alignment((self.pdb_a, self.pdb_b))[0] if gesamt.error: self.rmsd = np.nan self.seq_id = np.nan self.qscore = np.nan self.n_align = np.nan else: self.rmsd = gesamt.rmsd self.seq_id = gesamt.seq_id self.qscore = gesamt.qscore self.n_align = gesamt.n_align
def _run(self): """Run the :py:attr:`~swamp.wrappers.mapalign.MapAlign.cmd` and store the stdout :raises EnvironmentError: if :py:attr:`~swamp.wrappers.wrapper.Wrapper.source` is not found in the system """ self._check_alignment_input() self.logger.debug(" ".join(self.cmd)) self.logcontents = cexec(self.cmd, permit_nonzero=True) if self.logcontents == b'': self.error = True self.logger.error("No output found for the contact map alignment!") return self.logger.debug(self.logcontents) self.get_scores() if self.pdb_a is not None and self.pdb_b is not None: self.benchmark() self._cleanup_files()