36c2c78e7b2b0aac0613217ec2171f84a3c727ba
[htsworkflow.git] / htsworkflow / submission / results.py
1 """Help collect and process results for submission
2 """
3 from collections import MutableMapping
4 import os
5 import logging
6
7 from collections import namedtuple
8
9 LOGGER = logging.getLogger(__name__)
10
11 class ResultMap(MutableMapping):
12     """Store list of results
13     """
14     def __init__(self):
15         self.results_order = []
16         self.results = {}
17
18     def __iter__(self):
19         for item in self.results_order:
20             yield item
21
22     def __len__(self):
23         l = len(self.results)
24         assert l == len(self.results_order)
25         return l
26
27     def __setitem__(self, key, value):
28         self.results_order.append(key)
29         self.results[key] = value
30
31     def __getitem__(self, key):
32         return self.results[key]
33
34     def __delitem__(self, key):
35         del self.results[key]
36         i = self.results_order.index(key)
37         del self.results_order[i]
38
39     def add_results_from_file(self, filename):
40         pathname = os.path.abspath(filename)
41         basepath, name = os.path.split(pathname)
42         results = read_result_list(filename)
43         for lib_id, lib_path in results:
44             if not os.path.isabs(lib_path):
45                 lib_path = os.path.join(basepath, lib_path)
46             self[lib_id] = lib_path
47
48     def make_tree_from(self, source_path, destpath = None):
49         """Create a tree using data files from source path.
50         """
51         if destpath is None:
52             destpath = os.getcwd()
53
54         LOGGER.debug("Source_path: %s", source_path)
55         LOGGER.debug("Dest_path: %s", destpath)
56         for lib_id in self.results_order:
57             lib_path = self.results[lib_id]
58             LOGGER.debug("lib_path: %s", lib_path)
59             if os.path.isabs(lib_path):
60                 lib_path = os.path.relpath(lib_path, destpath)
61
62             LOGGER.debug('lib_path: %s', lib_path)
63             lib_destination = os.path.join(destpath, lib_path)
64             if not os.path.exists(lib_destination):
65                 LOGGER.info("Making dir {0}".format(lib_destination))
66                 os.mkdir(lib_destination)
67
68             source_rel_dir = os.path.join(source_path, lib_path)
69             source_lib_dir = os.path.abspath(source_rel_dir)
70             LOGGER.debug("source_lib_dir: %s", source_lib_dir)
71
72             for filename in os.listdir(source_lib_dir):
73                 source_pathname = os.path.join(source_lib_dir, filename)
74                 target_pathname = os.path.join(lib_destination, filename)
75                 if not os.path.exists(source_pathname):
76                     raise IOError(
77                         "{0} does not exist".format(source_pathname))
78                 if not os.path.exists(target_pathname):
79                     os.symlink(source_pathname, target_pathname)
80                     LOGGER.info(
81                         'LINK {0} to {1}'.format(source_pathname,
82                                                  target_pathname))
83
84 def read_result_list(filename):
85     """
86     Read a file that maps library id to result directory.
87     Does not support spaces in filenames.
88
89     For example:
90       10000 result/foo/bar
91     """
92     stream = open(filename, 'r')
93     results = parse_result_list(stream)
94     stream.close()
95     return results
96
97
98 def parse_result_list(stream):
99     results = []
100     for line in stream:
101         line = line.rstrip()
102         if not line.startswith('#') and len(line) > 0:
103             library_id, result_dir = line.split()
104             results.append((library_id, result_dir))
105     return results