#(c) 2013-2014 by Authors #This file is a part of Ragout program. #Released under the BSD license (see LICENSE file) """ This module runs progressiveCactus """ import os import sys import shutil import subprocess import multiprocessing import logging from .synteny_backend import SyntenyBackend, BackendException from .hal import HalBackend from ragout.shared import config CACTUS_EXEC = "bin/runProgressiveCactus.sh" CACTUS_WORKDIR = "cactus-workdir" try: CACTUS_INSTALL = os.environ["CACTUS_INSTALL"] except: CACTUS_INSTALL = "" logger = logging.getLogger() class CactusBackend(SyntenyBackend): def __init__(self): SyntenyBackend.__init__(self) def run_backend(self, recipe, output_dir, overwrite): logger.warning("cactus backend support is deprecated and will be " "removed in future releases. Use hal instead.") return _make_permutations(recipe, output_dir, overwrite, self.threads) if os.path.isfile(os.path.join(CACTUS_INSTALL, CACTUS_EXEC)): SyntenyBackend.register_backend("cactus", CactusBackend()) def _make_permutations(recipe, output_dir, overwrite, threads): """ Runs Cactus, then outputs preprocessesed results into output_dir """ work_dir = os.path.join(output_dir, CACTUS_WORKDIR) files = {} if overwrite and os.path.isdir(work_dir): shutil.rmtree(work_dir) hal_backend = HalBackend() if os.path.isdir(work_dir): #using existing results logger.warning("Using existing Cactus results from previous run") logger.warning("Use --overwrite to force alignment") hal_file = os.path.join(work_dir, "alignment.hal") if not os.path.isfile(hal_file): raise BackendException("Exitsing results are incompatible " "with input recipe") recipe["hal"] = hal_file else: #running cactus for genome, params in recipe["genomes"].items(): if "fasta" not in params: raise BackendException("FASTA file for {0} is not " "specified".format(genome)) os.mkdir(work_dir) config_path = _make_cactus_config(recipe, work_dir) hal_file = _run_cactus(config_path, recipe["target"], work_dir, threads) recipe["hal"] = hal_file #now run another backend return hal_backend.run_backend(recipe, output_dir, overwrite) def _make_cactus_config(recipe, directory): """ Creates cactus "seq" file """ CONF_NAME = "cactus.cfg" file = open(os.path.join(directory, CONF_NAME), "w") file.write(recipe["tree"] + "\n") for genome, params in recipe["genomes"].items(): if genome != recipe["target"]: file.write("*") file.write("{0} {1}\n".format(genome, os.path.abspath(params["fasta"]))) return file.name def _run_cactus(config_path, ref_genome, out_dir, threads): """ Runs Progressive Cactus """ CACTUS_OUT = "alignment.hal" logger.info("Running progressiveCactus...") work_dir = os.path.abspath(out_dir) out_hal = os.path.join(work_dir, CACTUS_OUT) config_file = os.path.abspath(config_path) prev_dir = os.getcwd() threads_param = "--maxThreads=" + str(threads) os.chdir(CACTUS_INSTALL) devnull = open(os.devnull, "w") cmdline = [CACTUS_EXEC, config_file, work_dir, out_hal, threads_param] try: subprocess.check_call(cmdline, stdout=devnull) except subprocess.CalledProcessError: raise BackendException() return out_hal