Commit 5f90763e authored by Fabrice Allain's avatar Fabrice Allain
Browse files

*: added ariacns patch command

parent 5a496eea
<a name="0.0.18"></a>
## <small>0.0.18 (2018-04-24)</small>
## <small>0.0.18 (2018-04-26)</small>
* docs: Added bpt1 setup in examples ([a76abff](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/a76abff))
* docs: Added link to example archive in docs ([9ec966b](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/9ec966b))
* docs: Added MALE_ECOLI example data ([4877131](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/4877131))
* docs: updated changelog ([ceececc](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/ceececc))
* docs: updated changelog ([95d3f62](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/95d3f62))
* docs: Updated changelog (removed old tags) ([a59416d](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/a59416d))
* docs: updated examples ([794f14e](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/794f14e))
* docs: updated usage section ([d171f05](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/d171f05))
* *: Fix bug during pdf generation in analysis command; Added analysis example for bpt1 ([e159414](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/e159414))
* Added casp rr support when there is no header (pfrmatrr) ([d9d7349](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/d9d7349))
* Added coverage report in generated ci files ([476478c](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/476478c))
......@@ -60,12 +68,6 @@
* updated logo file ([774713a](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/774713a))
* Updated README.rst and installation doc ([aa67392](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/aa67392))
* Updated toctree & ariaec setup command within sphinx documentation ([3ee3140](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/3ee3140))
* docs: Added bpt1 setup in examples ([a76abff](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/a76abff))
* docs: Added link to example archive in docs ([9ec966b](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/9ec966b))
* docs: Added MALE_ECOLI example data ([4877131](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/4877131))
* docs: updated changelog ([ceececc](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/ceececc))
* docs: updated changelog ([95d3f62](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/95d3f62))
* docs: Updated changelog (removed old tags) ([a59416d](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/a59416d))
* feat: Automatic changelog ([23e095b](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/23e095b))
* fix: wrong installation order in dockerfile for husky npm module ([c83c314](https://gitlab.pasteur.fr/bis-aria/Ariaec/commit/c83c314))
......
# coding=utf-8
"""
ARIA CNS tool
"""
from __future__ import absolute_import, division, print_function
import re
import os
import time
import shutil
import logging
import subprocess
import tempfile as tmp
import argparse as argp
import pkg_resources as pkgr
from .conbox.common import CustomLogging
from .conbox.commands import CLI, ReadableDir
CNS_PATH = 'CNS_SOLVE'
LOG = logging.getLogger(__name__)
class CNSPatchCommand(CLI):
"""
CLI for cns compilation with ARIA files
"""
command_list = ('patch', )
desc_list = (
u"Compile a new CNS executable according with ARIA CNS patches", )
def __init__(self):
super(CNSPatchCommand, self).__init__(logger=CustomLogging(desc=__doc__))
def _create_argparser(self):
"""Update default CLI"""
parser = super(CNSPatchCommand, self)._create_argparser()
self.add_subparsers(parser.add_subparsers(dest="command"))
return parser
@staticmethod
def _patch_argparser(desc):
"""CNS patch arguments & options"""
parser = argp.ArgumentParser(description=desc,
add_help=False)
parser.add_argument("cns_path", metavar="CNS_SOLVE",
action=ReadableDir,
help="CNS directory path. If CNS has been installed "
"correctly, this will correspond to the "
"CNS_SOLVE environment variable")
return parser
def patch(self):
"""
CNS patch command which compile a new CNS executable
"""
# Create temporary directory where CNS source will be copied
tmp.tempdir = ''
local_tempdir = tmp.mktemp()
local_tempdir += str(int(time.time()))
local_tempdir = os.path.join(self.args.output_directory, "tmp",
local_tempdir)
# Move CNS files in the temporary directory
LOG.info("Moving CNS files in the temporary directory (%s)", local_tempdir)
shutil.copytree(self.args.cns_path, local_tempdir)
# Overwrite CNS files with ARIA cns patches
LOG.info("Patching CNS files")
for cnsrc in pkgr.resource_listdir(__name__, "cns/src"):
if not pkgr.resource_isdir(__name__, "cns/src/" + cnsrc):
shutil.copy(pkgr.resource_filename(__name__, "cns/src/" + cnsrc),
os.path.join(local_tempdir, "source"))
# Edit cns_solve_env file
cns_solve_env = os.path.join(local_tempdir, "cns_solve_env")
if os.path.exists(cns_solve_env):
with open(cns_solve_env, 'r+') as cnsolve:
content = cnsolve.read()
cnsolve.seek(0)
cnsolve.write(
re.sub(r"(CNS_SOLVE\s+')(_CNSsolve_location_)(')",
r"\1%s\3" % local_tempdir, content, flags=re.M))
# Call Make install command
cmd = "cd {cns_solve}; make install".format(cns_solve=local_tempdir)
# Get executable file using CNS_INST env var (can get it from cns_solve_env)
# Move executable to the output directory
# Delete tmp directory
def main():
"""Launch ariaec command interface"""
command = CNSPatchCommand()
command.run()
# coding=utf-8
"""
CNS patch tool
"""
from __future__ import absolute_import, division, print_function
import os
from conbox.commands import CLI
CNS_PATH = 'CNS_SOLVE'
class CNSPatchCommand(CLI):
"""
CLI for cns compilation with ARIA files
"""
command_list = ('ariacns', )
desc_list = (
u"Compile a new CNS executable according with ARIA CNS patches", )
def __init__(self):
super(CNSPatchCommand, self).__init__()
def _ariacns_argparser(self):
pass
def ariacns(self):
"""
CNS patch command which compile a new CNS executable
"""
pass
# def cns_patch():
# Check if CNS_SOLVE environment variable exists
# In this case we will compile the new executable which include ARIA cns files
#
def main():
"""Launch ariaec command interface"""
command = CNSPatchCommand()
command.run()
......@@ -8,7 +8,7 @@ import os
import logging
import argparse as argp
from . import __doc__
from . import __doc__ as conboxdoc
from abc import ABCMeta, abstractproperty
from .common import format_dict, CustomLogging
from .settings import AriaEcSettings
......@@ -88,16 +88,48 @@ class ReadableFile(argp.Action):
setattr(namespace, self.dest, os.path.abspath(os.path.expanduser(values)))
class ReadableDir(argp.Action):
"""Class used with argparse action to check if a directory exists"""
def __call__(self, parser, namespace, values, option_string=None):
prospective_dir = values
if not os.path.isdir(prospective_dir):
raise argp.ArgumentTypeError(
"readable_dir:{0} is not a valid path".format(prospective_dir))
if os.access(prospective_dir, os.R_OK):
setattr(namespace, self.dest, prospective_dir)
else:
raise argp.ArgumentTypeError(
"readable_dir:{0} is not a readable dir".format(
prospective_dir))
class CLI(object):
"""
Abstract class for command line interface
"""
# TODO: maybe to complex. Actually support only cli with subcommands...
__metaclass__ = ABCMeta
def __init__(self, logger=CustomLogging(desc=__doc__)):
self._parser = self._create_argparser()
self.args = self._parser.parse_args()
self._update_logger(logger)
def __init__(self, logger=None):
self._parser = None
self._args = None
self._logger = logger if logger else CustomLogging()
@property
def parser(self):
"""command line parser"""
if not self._parser:
self._parser = self._create_argparser()
return self._parser
@property
def args(self):
"""argparse arguments"""
if not self._args:
self._args = self.parser.parse_args()
self._update_logger(self._logger)
return self._args
@abstractproperty
def command_list(self):
......@@ -123,20 +155,18 @@ class CLI(object):
argparse.ArgumentParser
"""
parser = argp.ArgumentParser(
description=__doc__,
formatter_class=argp.ArgumentDefaultsHelpFormatter)
parser.add_argument("-o", "--output", dest="output_directory",
type=str, help="Output directory", required=True)
parser.add_argument("-o", "--output", dest="output_directory", type=str,
help="Output directory", required=True, action=ReadableDir)
parser.add_argument("--nolog", action="store_true",
default=False, help="Don't generate log files")
parser.add_argument("-d", "--debug", dest="verbose", default=False,
action='store_true',
help="Increase output verbosity")
# Create subcommands
self._create_subparsers(parser.add_subparsers(dest="command"))
return parser
def _create_subparsers(self, parser):
# TODO: should be called in child classes .....
def add_subparsers(self, parser):
"""
Generate subcommands
......@@ -153,11 +183,9 @@ class CLI(object):
# command_argparser
for index, command in enumerate(self.command_list):
# Create subparser defined in command list
# TODO: the best way to save argparsers ?
setattr(self, "_" + command + "_argparser",
argp.ArgumentParser(description=self.desc_list[index],
add_help=False))
subcommand = getattr(self, "_" + command + "_argparser")
# TODO: Is it the best way ? => More like AriaEcSettings ?
subcommand = getattr(self, "_" + command + "_argparser")(
desc=self.desc_list[index])
# TODO: Not the right way ?
parser.add_parser(command, parents=[subcommand])
......@@ -177,7 +205,8 @@ class CLI(object):
LOG.removeHandler("error_file_handler")
LOG.removeHandler("debug_file_handler")
log.set_outdir(self.args.output_directory)
log.update_msg(self.args.command)
if hasattr(self.args, "command"):
log.update_msg(self.args.command)
def run(self):
"""Call method relative to args.command"""
......@@ -197,7 +226,6 @@ class AriaEcCommands(CLI):
AriaEcCommands.desc_list: list
"""
command_list = ("setup", "bbconv", "maplot", "pdbqual", "analysis",
"tbl2xml", "pdbdist", "pdbstat", "iniconv")
desc_list = (u"Setup ARIA infrastructure with contact maps translated "
......@@ -215,8 +243,8 @@ class AriaEcCommands(CLI):
set(CONTACT_FILE_PARSERS))
default_confile = "conf/config.ini"
def __init__(self, logger=None):
super(AriaEcCommands, self).__init__(logger)
def __init__(self):
super(AriaEcCommands, self).__init__(logger=CustomLogging(desc=conboxdoc))
def _create_argparser(self):
"""
......@@ -226,9 +254,12 @@ class AriaEcCommands(CLI):
parser.add_argument("-c", "--conf", action=ReadableFile,
dest="conf_file",
default=None, help="configuration file")
# TODO: not really practical, we HAVE to call line below since every
# subcommand argparser have to be defined in the same scope
self.add_subparsers(parser.add_subparsers(dest="command"))
return parser
def _setup_argparser(self):
def _setup_argparser(self, desc=None):
"""
setup opt & args
......@@ -240,9 +271,10 @@ class AriaEcCommands(CLI):
Returns
-------
"""
parser = super(AriaEcCommands, self)._setup_argparser
parser = argp.ArgumentParser(description=desc,
add_help=False)
# Options
# Args
group = parser.add_argument_group('required arguments')
......@@ -288,7 +320,7 @@ class AriaEcCommands(CLI):
"is defined with -p option")
return parser
def _bbconv_argparser(self):
def _bbconv_argparser(self, desc=None):
"""
bbconv opt & args
......@@ -302,7 +334,8 @@ class AriaEcCommands(CLI):
"""
parser = super(AriaEcCommands, self)._bbconv_argparser
parser = argp.ArgumentParser(description=desc,
add_help=False)
# args
parser.add_argument("contactfile", help="contacts file (pconsc, plm)",
action=ReadableFile)
......@@ -317,7 +350,7 @@ class AriaEcCommands(CLI):
"type")
return parser
def _iniconv_argparser(self):
def _iniconv_argparser(self, desc=None):
"""
iniconv opt & args
......@@ -331,13 +364,14 @@ class AriaEcCommands(CLI):
"""
parser = super(AriaEcCommands, self)._iniconv_argparser
parser = argp.ArgumentParser(description=desc,
add_help=False)
# args
parser.add_argument("confiles", nargs='+',
type=str, help="config files")
return parser
def _maplot_argparser(self):
def _maplot_argparser(self, desc=None):
"""
maplot opt & args
......@@ -351,7 +385,8 @@ class AriaEcCommands(CLI):
"""
parser = super(AriaEcCommands, self)._maplot_argparser
parser = argp.ArgumentParser(description=desc,
add_help=False)
parser.add_argument("seq", action=ReadableFile,
help="sequence file [FASTA]")
parser.add_argument("sspred", action=ReadableFile,
......@@ -387,42 +422,18 @@ class AriaEcCommands(CLI):
help="Prefix name for file names")
return parser
def _pdbqual_argparser(self):
"""
Parameters
----------
desc :
(Default value = None)
Returns
-------
"""
parser = super(AriaEcCommands, self)._pdbqual_argparser
def _pdbqual_argparser(self, desc=None):
parser = argp.ArgumentParser(description=desc,
add_help=False)
parser.add_argument("infiles", nargs="+", metavar="infile",
action=ReadableFile,
help="PDB file(s) used to run quality tools with "
"aria API")
return parser
def _analysis_argparser(self):
"""
Parameters
----------
desc :
(Default value = None)
Returns
-------
"""
parser = super(AriaEcCommands, self)._analysis_argparser
def _analysis_argparser(self, desc=None):
parser = argp.ArgumentParser(description=desc,
add_help=False)
parser.add_argument("project", action=ReadableFile,
help="ARIA project file [XML]")
parser.add_argument("iteration", metavar="iteration_path",
......@@ -442,7 +453,7 @@ class AriaEcCommands(CLI):
help="Prefix name for file names")
return parser
def _tbl2xml_argparser(self):
def _tbl2xml_argparser(self, desc=None):
"""
......@@ -456,7 +467,8 @@ class AriaEcCommands(CLI):
"""
parser = super(AriaEcCommands, self)._tbl2xml_argparser
parser = argp.ArgumentParser(description=desc,
add_help=False)
parser.add_argument(
"molecule", metavar="molecule.xml", action=ReadableFile,
help="ARIA XML molecule file")
......@@ -467,7 +479,7 @@ class AriaEcCommands(CLI):
help="TBL distance restraint file(s)")
return parser
def _pdbdist_argparser(self):
def _pdbdist_argparser(self, desc=None):
"""
......@@ -481,7 +493,8 @@ class AriaEcCommands(CLI):
"""
parser = super(AriaEcCommands, self)._pdbdist_argparser
parser = argp.ArgumentParser(description=desc,
add_help=False)
# TODO: find a way to list all cullpdb file in package ressources
# Maybe move this args to the config file
......@@ -499,7 +512,7 @@ class AriaEcCommands(CLI):
help="Folder containing pdb file entries")
return parser
def _pdbstat_argparser(self):
def _pdbstat_argparser(self, desc=None):
"""
......@@ -513,7 +526,8 @@ class AriaEcCommands(CLI):
"""
parser = super(AriaEcCommands, self)._pdbstat_argparser
parser = argp.ArgumentParser(description=desc,
add_help=False)
# TODO: find a way to list all cullpdb file in package ressources
# Maybe move this args to the config file
......
......@@ -433,7 +433,7 @@ class CustomLogging(object):
# "conf/logging.json")
default_file = "conf/logging.json"
def __init__(self, level=logging.INFO, desc=__doc__):
def __init__(self, level=logging.INFO, desc=None):
"""
Parameters
......
......@@ -22,7 +22,6 @@ from .protmap import (ResMap, ResAtmMap)
LOG = logging.getLogger(__name__)
# TODO: check if Atom is still used ...
# TODO: Should use conkit in the future
Atom = collections.namedtuple("Atom", ["name", "coords"])
......
......@@ -247,7 +247,7 @@ def setup_package():
'console_scripts': [
'aria2 = aria.aria2:main',
'ariaec = aria.conbox.commands:main',
'ariacns = aria.cnspatch:main',
'ariacns = aria.ariacns:main',
],
},
# bin folder is normally for non python code that could be executed
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment