File size: 3,594 Bytes
a3f3d91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# -*- coding: utf-8 -*-

import os
from os.path import join, abspath
from subprocess import PIPE, Popen
from pkg_resources import resource_filename
from .aggrescan_3d import run as run_aggrescan_3d
from . import logger
import platform

_name = "Analysis"
if platform.system() == "Windows":
    _bin_name = "freesasa.exe"
elif platform.system() == "Darwin":
    _bin_name = "freesasa_Darwin"
else:
    _bin_name = "freesasa"


def aggregation_analysis(config, target="input.pdb", working_dir=".", agg_work_dir=""):
    """Takes Aggrescaan3D Job class config as an argument and should never change it"""
    os.chdir(working_dir)  # Just in case one of the programs handles abspaths poorly
    if config["naccess"]:
        _run_naccess(target=target, agg=agg_work_dir, naccess_dir=config["naccess"])
    else:
        _run_free_sasa(target=target, agg=agg_work_dir)
    residues = _run_aggrescan(target=target, working_dir=working_dir, config=config)
    return residues


def _run_aggrescan(target, working_dir, config):
    """
    Takes target pdb file, working directory for analysis
    and aggrescan config dict as arguments so need the two in sync
    """
    matrix_dir = resource_filename('aggrescan', join("data", "matrices", "aggrescan.mat"))
    residues = run_aggrescan_3d(target, matrix_dir, config["distance"], working_dir, naccess=config["naccess"], ph=config['ph'])
    # logger.to_file(filename=join(config["tmp_dir"], "input_output"), content=out, allow_err=False)
    return residues


def _run_free_sasa(target="folded.pdb", agg=""):
    sasa_dir = resource_filename('aggrescan', join("data", "freesasa-2.0.1", "src", _bin_name))
    sasa_cmd = [sasa_dir, "--resolution", "100", target, "--radii", "naccess", "--format", "pdb", "--format", "rsa"]
    logger.debug(module_name="freeSasa", msg="Starting freeSasa with %s" % " ".join(sasa_cmd))
    _fname = join(agg, "ASA.error")
    out, err = Popen(sasa_cmd, stdout=PIPE, stderr=PIPE).communicate()
    if err:
        logger.to_file(_fname, content=err)
        try:
            err = err.decode()
        except (UnicodeDecodeError, AttributeError):
            pass
        for line in err.split("\n"):
            if "warning" in line:
                logger.critical(module_name="freeSasa", msg="Warning detected: %s" % line)
                logger.critical(module_name="freeSasa", msg="Attempting to continue.")
            else:
                raise logger.ASAError(program_name="freeSasa", filename=_fname)
    logger.to_file(filename="sasa.out", content=out, allow_err=False)


def _run_naccess(target="folded.pdb", agg="", naccess_dir=""):
    naccess_cmd = [naccess_dir, target, "-p", "1.4", "-z", "0.05"]
    logger.debug(module_name=_name, msg="running naccess program with %s" % " ".join(naccess_cmd))
    _fname = join(agg, "ASA.error")
    try:
        out, err = Popen(naccess_cmd, stdout=PIPE, stderr=PIPE).communicate()
    except OSError:
        raise logger.AggrescanError("Couldn't start the naccess program. Naccess requires csh shell to be present on the system."
                                    " If it is present please run the program in debug mode and see if the path printed in "
                                    "Naccess command actually contains the file.", module_name="Naccess")
    if err:
        logger.to_file(filename=_fname, content=err)
        raise logger.ASAError(program_name="Naccess", filename=_fname)
    try:
        for msg in out.split("\n"):
            if msg:
                logger.debug(module_name="Naccess", msg=msg)
    except AttributeError:
        pass