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