6 from . import hooke as hooke
7 from . import libhookecurve as lhc
8 from . import libhooke as lh
10 class Playlist(object):
11 def __init__(self, drivers):
15 self.drivers = drivers
17 self.genericsDict = {}
18 self.hiddenAttributes = ['curve', 'driver', 'name', 'plots']
20 self.name = 'Untitled'
25 def add_curve(self, path, attributes={}):
26 curve = lhc.HookeCurve(path)
27 for key,value in attribures.items():
28 setattr(curve, key, value)
29 curve.identify(self.drivers)
30 curve.plots = curve.driver.default_plots()
31 self.curves.append(curve)
33 self.count = len(self.curves)
36 def close_curve(self, index):
37 if index >= 0 and index < self.count:
38 self.curves.remove(index)
40 def filter_curves(self, keeper_fn=labmda curve:True):
41 playlist = copy.deepcopy(self)
42 for curve in reversed(playlist.curves):
43 if not keeper_fn(curve):
44 playlist.curves.remove(curve)
45 try: # attempt to maintain the same active curve
46 playlist.index = playlist.curves.index(self.get_active_curve())
49 playlist._saved = False
50 playlist.count = len(playlist.curves)
53 def get_active_curve(self):
54 return self.curves[self.index]
56 #TODO: do we need this?
57 def get_active_plot(self):
58 return self.curves[self.index].plots[0]
60 def get_status_string(self):
62 return '%s (%s/%s)' % (self.name, self.index + 1, self.count)
63 return 'The file %s does not contain any valid force curve data.' \
79 self.name = os.path.basename(path)
80 playlist = lh.delete_empty_lines_from_xmlfile(path)
81 self.xml = xml.dom.minidom.parse(path)
83 self._removeWhitespaceNodes()
85 generics_list = self.xml.getElementsByTagName('generics')
86 curve_list = self.xml.getElementsByTagName('curve')
87 self._loadGenerics(generics_list)
88 self._loadCurves(curve_list)
91 def _removeWhitespaceNodes(self, root_node=None):
94 for node in root_node.childNodes:
95 if node.nodeType == node.TEXT_NODE and node.data.strip() == '':
96 root_node.removeChild(node) # drop this whitespace node
98 _removeWhitespaceNodes(root_node=node) # recurse down a level
100 def _loadGenerics(self, generics_list, clear=True):
102 self.genericsDict = {}
104 generics_list = self.xml.getElementsByTagName('generics')
105 for generics in generics_list:
106 for attribute in generics.attributes.keys():
107 self.genericsDict[attribute] = generics_list[0].getAttribute(attribute)
108 if self.genericsDict.has_key('pointer'):
109 index = int(self.genericsDict['pointer'])
110 if index >= 0 and index < len(self.curves):
115 def _loadCurves(self, curve_list, clear=True):
118 #populate playlist with curves
119 for curve in curve_list:
120 #rebuild a data structure from the xml attributes
121 curve_path = lh.get_file_path(element.getAttribute('path'))
122 #extract attributes for the single curve
123 attributes = dict([(k,curve.getAttribute(k))
124 for k in curve.attributes.keys()])
125 attributes.pop('path')
126 curve = self.add_curve(os.path.join(path, curve_path), attributes)
127 if curve is not None:
128 for plot in curve.plots:
129 curve.add_data('raw', plot.vectors[0][0], plot.vectors[0][1], color=plot.colors[0], style='plot')
130 curve.add_data('raw', plot.vectors[1][0], plot.vectors[1][1], color=plot.colors[1], style='plot')
134 if self.index > self.count - 1:
140 self.index = self.count - 1
143 if self.has_curves():
148 def save(self, path):
150 saves the playlist in a XML file.
153 output_file = file(path, 'w')
156 print 'Cannot save playlist: %s' % e
158 self.xml.writexml(output_file, indent='\n')
164 Creates an initial playlist from a list of files.
165 A playlist is an XML document with the following syntax:
166 <?xml version="1.0" encoding="utf-8"?>
168 <generics pointer="0"/>
169 <curve path="/my/file/path/"/ attribute="value" ...>
172 Relative paths are interpreted relative to the location of the
175 #create the output playlist, a simple XML document
176 implementation = xml.dom.minidom.getDOMImplementation()
177 #create the document DOM object and the root element
178 self.xml = implementation.createDocument(None, 'playlist', None)
179 root = self.xml.documentElement
181 #save generics variables
182 playlist_generics = self.xml.createElement('generics')
183 root.appendChild(playlist_generics)
184 self.genericsDict['pointer'] = self.index
185 for key in self.genericsDict.keys():
186 self.xml.createAttribute(key)
187 playlist_generics.setAttribute(key, str(self.genericsDict[key]))
189 #save curves and their attributes
190 for item in self.curves:
191 playlist_curve = self.xml.createElement('curve')
192 root.appendChild(playlist_curve)
193 for key in item.__dict__:
194 if not (key in self.hiddenAttributes):
195 self.xml.createAttribute(key)
196 playlist_curve.setAttribute(key, str(item.__dict__[key]))