tools.py 4.58 KB
Newer Older
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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


class Tool:

    def __init__(self, name, exec, command_line, all_vs_all, max_memory, threads=1, exec_cluster=None, threads_cluster=None,
                 parser=None, split_before=False, help=None, order=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 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
        """
        # Name
        self.name = name

        # Exec
        if exec == "default":
            self.exec = os.path.join(os.path.dirname(inspect.getfile(self.__class__)), "bin", self.name)
        else:
            self.exec = exec
        if exec_cluster is None or exec_cluster == "default":
            self.exec_cluster = exec
        else:
            self.exec_cluster = exec_cluster

        # 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




@Singleton
class Tools:

    def __init__(self):
        self.tools = {}
        self.load_yaml()

    def load_yaml(self):
        config_file = []
        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.local")]

        if os.name == "nt":
            config_file.insert(1, os.path.join(sys.executable, '..', "tools.yaml"))
            config_file.insert(1, os.path.join(sys.executable, '..', "tools.yaml.local"))

        for my_config_file in config_file_search:
            if os.path.exists(my_config_file):
                config_file.append(my_config_file)
        if len(config_file) == 0:
            raise FileNotFoundError("ERROR: tools.yaml not found.")

        for yaml_file in config_file:
            with open(yaml_file, "r") as yml_f:
                tools_dict = yaml.load(yml_f)
                tools = {}
                for name, props in tools_dict.items():
                    tools[name] = Tool(name=name, **props)
                print(tools)
                self.tools.update(tools)