Initial port to python3
[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 import \
21    ElementTree, \
22    VERSION_RE, \
23    EUROPEAN_STRPTIME
24
25 LOGGER = logging.getLogger(__name__)
26
27 class Firecrest(object):
28     """Gather information about older firecrest runs
29     """
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         """Initialize a Firecrest object
43         
44         consider using factory :function:firecrest
45         
46         :param xml: xml serialzation element to initialze from [optional]
47         """
48         self.start = None
49         self.stop = None
50         self.version = None
51         self.date = date.today()
52         self.user = None
53         self.matrix = None
54
55         if xml is not None:
56             self.set_elements(xml)
57
58     def _get_software(self):
59         return "Firecrest"
60     software = property(_get_software)
61
62     def _get_time(self):
63         return time.mktime(self.date.timetuple())
64     time = property(_get_time, doc='return run time as seconds since epoch')
65
66     def dump(self):
67         """Report debugginf information
68         """
69         print("Starting cycle:", self.start)
70         print("Ending cycle:", self.stop)
71         print("Firecrest version:", self.version)
72         print("Run date:", self.date)
73         print("user:", self.user)
74
75     def get_elements(self):
76         """Return XML serialization structure.
77         """
78         attribs = {'version': str(Firecrest.XML_VERSION) }
79         root = ElementTree.Element(Firecrest.FIRECREST, attrib=attribs)
80         version = ElementTree.SubElement(root, Firecrest.SOFTWARE_VERSION)
81         version.text = self.version
82         start_cycle = ElementTree.SubElement(root, Firecrest.START)
83         start_cycle.text = str(self.start)
84         stop_cycle = ElementTree.SubElement(root, Firecrest.STOP)
85         stop_cycle.text = str(self.stop)
86         run_date = ElementTree.SubElement(root, Firecrest.DATE)
87         run_date.text = str(self.time)
88         user = ElementTree.SubElement(root, Firecrest.USER)
89         user.text = self.user
90         if self.matrix is not None:
91             matrix = ElementTree.SubElement(root, Firecrest.MATRIX)
92             matrix.text = self.matrix
93         return root
94
95     def set_elements(self, tree):
96         if tree.tag != Firecrest.FIRECREST:
97             raise ValueError('Expected "Firecrest" SubElements')
98         xml_version = int(tree.attrib.get('version', 0))
99         if xml_version > Firecrest.XML_VERSION:
100             LOGGER.warn('Firecrest XML tree is a higher version than this class')
101         for element in list(tree):
102             if element.tag == Firecrest.SOFTWARE_VERSION:
103                 self.version = element.text
104             elif element.tag == Firecrest.START:
105                 self.start = int(element.text)
106             elif element.tag == Firecrest.STOP:
107                 self.stop = int(element.text)
108             elif element.tag == Firecrest.DATE:
109                 self.date = date.fromtimestamp(float(element.text))
110             elif element.tag == Firecrest.USER:
111                 self.user = element.text
112             elif element.tag == Firecrest.MATRIX:
113                 self.matrix = element.text
114             else:
115                 raise ValueError("Unrecognized tag: %s" % (element.tag,))
116
117 def firecrest(pathname):
118     """
119     Examine the directory at pathname and initalize a Firecrest object
120     """
121     f = Firecrest()
122     f.pathname = pathname
123
124     # parse firecrest directory name
125     path, name = os.path.split(pathname)
126     groups = name.split('_')
127     # grab the start/stop cycle information
128     cycle = re.match("C([0-9]+)-([0-9]+)", groups[0])
129     f.start = int(cycle.group(1))
130     f.stop = int(cycle.group(2))
131     # firecrest version
132     version = re.search(VERSION_RE, groups[1])
133     f.version = (version.group(1))
134     # datetime
135     t = time.strptime(groups[2], EUROPEAN_STRPTIME)
136     f.date = date(*t[0:3])
137     # username
138     f.user = groups[3]
139
140     bustard_pattern = os.path.join(pathname, 'Bustard*')
141     # should I parse this deeper than just stashing the
142     # contents of the matrix file?
143     matrix_pathname = os.path.join(pathname, 'Matrix', 's_matrix.txt')
144     if os.path.exists(matrix_pathname):
145         # this is for firecrest < 1.3.2
146         f.matrix = open(matrix_pathname, 'r').read()
147     elif glob(bustard_pattern) > 0:
148         f.matrix = None
149         # there are runs here. Bustard should save the matrix.
150     else:
151         return None
152
153     return f
154
155 def fromxml(tree):
156     """
157     Initialize a Firecrest object from an element tree node
158     """
159     f = Firecrest()
160     f.set_elements(tree)
161     return f