Source code for dgenies.tools

import os
import sys
import re
import inspect
from pathlib import Path
import yaml
from dgenies.lib.decorators import Singleton
from dgenies.lib import parsers


[docs]class Tool: def __init__(self, name, exec, command_line, all_vs_all, max_memory, label=None, threads=1, exec_cluster=None, threads_cluster=None, parser=None, split_before=False, help=None, order=None, options=None): """ Create a new tool :param command_line: command line to launch the tool :param all_vs_all: command line in all_vs_all mode (None if not available for the tool) :param max_memory: max memory the tool is supposed to use (ex: 40G) - for cluster submissions :param label: Name to display for user :param parser: name of the function in dgenies.lib.functions to launch after mapping to have a correct PAF out file :param split_before: True to split contigs before mapping :type split_before: bool :param help: help message to show in run form :param order: order to show in run mode :param options: list of options for the tool """ # Name self.name = name # Label if label: self.label = label else: self.label = name # Exec if exec == "default": self.exec = os.path.join(os.path.dirname(inspect.getfile(self.__class__)), "bin", self.name) else: self.exec = exec.replace("###SYSEXEC###", os.path.dirname(sys.executable)) if exec_cluster is None or exec_cluster == "default": self.exec_cluster = exec else: self.exec_cluster = exec_cluster.replace("###SYSEXEC###", os.path.dirname(sys.executable)) # Command line: if "{exe}" in command_line and "{target}" in command_line and "{query}" in command_line and "{out}" \ in command_line: self.command_line = command_line else: raise ValueError("Tools: command_line must contains at least {exe}, {target}, {query} and {out} tags") # All_vs_all: if all_vs_all is None or ("{exe}" in all_vs_all and "{target}" in all_vs_all and "{out}" in all_vs_all): self.all_vs_all = all_vs_all else: raise ValueError("Tools: all_vs_all must contains at least {exe}, {target} and {out} tags") # Max memory: if max_memory is None or isinstance(max_memory, int): self.max_memory = max_memory else: raise ValueError("Tools: max_memory must be an integer, or !!null") # Threads: if isinstance(threads, int): self.threads = threads else: raise ValueError("Tools: threads must be an integer") if threads_cluster is None or isinstance(threads_cluster, int): if threads_cluster is None: self.threads_cluster = self.threads else: self.threads_cluster = threads_cluster else: raise ValueError("Tools: threads_cluster must be an integer, or !!null") # Parser: if parser is None or hasattr(parsers, parser): self.parser = parser else: raise ValueError("Tools: parser %s is not defines in dgenies.lib.parsers!" % parser) # split_before: if isinstance(split_before, bool): self.split_before = split_before else: raise ValueError("Tools: split_before must be a boolean (True or False)") # Help: self.help = help # Order: if order is None or isinstance(order, int): if order is None: self.order = 1000 else: self.order = order # Options if options is None or isinstance(options, list): self.options = options else: raise ValueError("Tools: options must be a yaml list")
@Singleton class Tools: """ Load (from yaml file) and store available alignment tools """ def __init__(self): self.tools = {} self.load_yaml(trusted=True) def load_yaml(self, trusted=False): app_dir = os.path.dirname(inspect.getfile(self.__class__)) yaml_file = None config_file_search = [os.path.join(os.path.abspath(os.sep), "dgenies", "tools.yaml"), "/etc/dgenies/tools.yaml", "/etc/dgenies/tools.yaml.local", os.path.join(str(Path.home()), ".dgenies", "tools.yaml"), os.path.join(str(Path.home()), ".dgenies", "tools.yaml.local"), os.path.join(app_dir, '..', 'etc', 'dgenies', 'tools.yaml')] if os.name == "nt": config_file_search.insert(1, os.path.join(sys.executable, '..', "tools.yaml")) config_file_search.insert(1, os.path.join(sys.executable, '..', "tools.yaml.local")) config_file_search.append(os.path.join(app_dir, "tools-dev.yaml")) config_file_search.append(os.path.join(app_dir, "tools-dev.yaml.local")) for my_config_file in reversed(config_file_search): if os.path.exists(my_config_file): yaml_file = my_config_file break if yaml_file is None: raise FileNotFoundError("ERROR: tools.yaml not found.") with open(yaml_file, "r") as yml_f: tools_dict = yaml.load(yml_f, Loader=yaml.FullLoader if trusted else yaml.SafeLoader) tools = {} for name, props in tools_dict.items(): tools[name] = Tool(name=name, **props) self.tools.update(tools)