Use a logger initialized to the module name much more consistently.
[htsworkflow.git] / htsworkflow / pipelines / firecrest.py
1 """
2 Extract information about the Firecrest run
3
4 Firecrest
5   class holding the properties we found
6 firecrest
7   Firecrest factory function initalized from a directory name
8 fromxml
9   Firecrest factory function initalized from an xml dump from
10   the Firecrest object.
11 """
12
13 from datetime import date
14 from glob import glob
15 import logging
16 import os
17 import re
18 import time
19
20 from htsworkflow.pipelines.runfolder import \
21    ElementTree, \
22    VERSION_RE, \
23    EUROPEAN_STRPTIME
24
25 LOGGER = logging.getLogger(__name__)
26
27 __docformat__ = "restructuredtext en"
28
29 class Firecrest(object):
30     XML_VERSION=1
31
32     # xml tag names
33     FIRECREST = 'Firecrest'
34     SOFTWARE_VERSION = 'version'
35     START = 'FirstCycle'
36     STOP = 'LastCycle'
37     DATE = 'run_time'
38     USER = 'user'
39     MATRIX = 'matrix'
40
41     def __init__(self, xml=None):
42         self.start = None
43         self.stop = None
44         self.version = None
45         self.date = date.today()
46         self.user = None
47         self.matrix = None
48
49         if xml is not None:
50             self.set_elements(xml)
51
52     def _get_time(self):
53         return time.mktime(self.date.timetuple())
54     time = property(_get_time, doc='return run time as seconds since epoch')
55
56     def dump(self):
57         print "Starting cycle:", self.start
58         print "Ending cycle:", self.stop
59         print "Firecrest version:", self.version
60         print "Run date:", self.date
61         print "user:", self.user
62
63     def get_elements(self):
64         attribs = {'version': str(Firecrest.XML_VERSION) }
65         root = ElementTree.Element(Firecrest.FIRECREST, attrib=attribs)
66         version = ElementTree.SubElement(root, Firecrest.SOFTWARE_VERSION)
67         version.text = self.version
68         start_cycle = ElementTree.SubElement(root, Firecrest.START)
69         start_cycle.text = str(self.start)
70         stop_cycle = ElementTree.SubElement(root, Firecrest.STOP)
71         stop_cycle.text = str(self.stop)
72         run_date = ElementTree.SubElement(root, Firecrest.DATE)
73         run_date.text = str(self.time)
74         user = ElementTree.SubElement(root, Firecrest.USER)
75         user.text = self.user
76         if self.matrix is not None:
77             matrix = ElementTree.SubElement(root, Firecrest.MATRIX)
78             matrix.text = self.matrix
79         return root
80
81     def set_elements(self, tree):
82         if tree.tag != Firecrest.FIRECREST:
83             raise ValueError('Expected "Firecrest" SubElements')
84         xml_version = int(tree.attrib.get('version', 0))
85         if xml_version > Firecrest.XML_VERSION:
86             LOGGER.warn('Firecrest XML tree is a higher version than this class')
87         for element in list(tree):
88             if element.tag == Firecrest.SOFTWARE_VERSION:
89                 self.version = element.text
90             elif element.tag == Firecrest.START:
91                 self.start = int(element.text)
92             elif element.tag == Firecrest.STOP:
93                 self.stop = int(element.text)
94             elif element.tag == Firecrest.DATE:
95                 self.date = date.fromtimestamp(float(element.text))
96             elif element.tag == Firecrest.USER:
97                 self.user = element.text
98             elif element.tag == Firecrest.MATRIX:
99                 self.matrix = element.text
100             else:
101                 raise ValueError("Unrecognized tag: %s" % (element.tag,))
102
103 def firecrest(pathname):
104     """
105     Examine the directory at pathname and initalize a Firecrest object
106     """
107     f = Firecrest()
108     f.pathname = pathname
109
110     # parse firecrest directory name
111     path, name = os.path.split(pathname)
112     groups = name.split('_')
113     # grab the start/stop cycle information
114     cycle = re.match("C([0-9]+)-([0-9]+)", groups[0])
115     f.start = int(cycle.group(1))
116     f.stop = int(cycle.group(2))
117     # firecrest version
118     version = re.search(VERSION_RE, groups[1])
119     f.version = (version.group(1))
120     # datetime
121     t = time.strptime(groups[2], EUROPEAN_STRPTIME)
122     f.date = date(*t[0:3])
123     # username
124     f.user = groups[3]
125
126     bustard_pattern = os.path.join(pathname, 'Bustard*')
127     # should I parse this deeper than just stashing the
128     # contents of the matrix file?
129     matrix_pathname = os.path.join(pathname, 'Matrix', 's_matrix.txt')
130     if os.path.exists(matrix_pathname):
131         # this is for firecrest < 1.3.2
132         f.matrix = open(matrix_pathname, 'r').read()
133     elif glob(bustard_pattern) > 0:
134         f.matrix = None
135         # there are runs here. Bustard should save the matrix.
136     else:
137         return None
138
139     return f
140
141 def fromxml(tree):
142     """
143     Initialize a Firecrest object from an element tree node
144     """
145     f = Firecrest()
146     f.set_elements(tree)
147     return f