tools.py 4.75 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
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):
Floreal Cabanettes's avatar
Floreal Cabanettes committed
105
        yaml_file = None
106
107
108
109
110
111
        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":
Floreal Cabanettes's avatar
Floreal Cabanettes committed
112
113
            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"))
114

Floreal Cabanettes's avatar
Floreal Cabanettes committed
115
116
117
118
119
        app_dir = os.path.dirname(inspect.getfile(self.__class__))
        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):
120
            if os.path.exists(my_config_file):
Floreal Cabanettes's avatar
Floreal Cabanettes committed
121
122
123
                yaml_file = my_config_file
                break
        if yaml_file is None:
124
125
            raise FileNotFoundError("ERROR: tools.yaml not found.")

Floreal Cabanettes's avatar
Floreal Cabanettes committed
126
127
128
129
130
131
        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)
            self.tools.update(tools)