Skip to content

Commit

Permalink
Made stats plugin write its own XML attribute file
Browse files Browse the repository at this point in the history
  • Loading branch information
coretl committed Mar 15, 2017
1 parent 5c9c392 commit 2e2afea
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
6 changes: 6 additions & 0 deletions malcolm/includes/ADCore/ndarray_parts.yaml
Expand Up @@ -27,3 +27,9 @@
description: Current unique id number for frame
rbv: $(prefix):UniqueId_RBV
widget: textupdate

- parts.ca.CACharArrayPart:
name: attributesFile
description: Filename for NDAttributes
pv: $(prefix):NDAttributesFile
widget: textinput
29 changes: 27 additions & 2 deletions malcolm/parts/ADCore/statspluginpart.py
@@ -1,3 +1,9 @@
import os
from xml.etree import cElementTree as ET

from malcolm.compat import et_to_string
from malcolm.core import REQUIRED, method_takes
from malcolm.core.vmetas import StringMeta
from malcolm.parts.builtin.childpart import ChildPart
from malcolm.controllers.runnablecontroller import RunnableController
from malcolm.parts.ADCore.hdfwriterpart import CalculatedNDAttributeDatasetInfo
Expand All @@ -9,8 +15,27 @@ class StatsPluginPart(ChildPart):
def report_info(self, _):
return [CalculatedNDAttributeDatasetInfo(name="sum", attr="StatsTotal")]

def _make_attributes_xml(self):
# Make a root element with an NXEntry
root_el = ET.Element("Attributes")
ET.SubElement(
root_el, "Attribute", addr="0", datatype="DOUBLE", type="PARAM",
description="Sum of the array", name="StatsTotal", source="TOTAL",
)
xml = et_to_string(root_el)
return xml

@RunnableController.Configure
def configure(self, task, completed_steps, steps_to_do, part_info):
task.put_many(self.child, dict(
@method_takes(
"filePath", StringMeta("File path to write data to"), REQUIRED)
def configure(self, task, completed_steps, steps_to_do, part_info, params):
file_dir, filename = params.filePath.rsplit(os.sep, 1)
fs = task.put_many_async(self.child, dict(
enableCallbacks=True,
computeStatistics=True))
xml = self._make_attributes_xml()
attributes_filename = os.path.join(
file_dir, "%s-attributes.xml" % self.params.mri)
open(attributes_filename, "w").write(xml)
fs += task.put_async(self.child["attributesFile"], attributes_filename)
task.wait_all(fs)
24 changes: 22 additions & 2 deletions tests/test_parts/test_ADCore/test_statspluginpart.py
Expand Up @@ -21,18 +21,38 @@ def getitem(name):
self.child.__getitem__.side_effect = getitem

self.params = MagicMock()
self.params.mri = "BLOCK-STAT"
self.process.get_block.return_value = self.child
self.o = StatsPluginPart(self.process, self.params)

def test_report_info(self):
infos = self.o.report_info(ANY)
self.assertEqual(len(infos), 1)
self.assertEqual(infos[0].name, "sum")
self.assertEqual(infos[0].attr, "StatsTotal")

def test_configure(self):
task = MagicMock()
completed_steps = ANY
steps_to_do = ANY
part_info = ANY
self.o.configure(task, completed_steps, steps_to_do, part_info)
task.put_many.assert_called_once_with(self.child, dict(
params = MagicMock()
params.filePath = "/tmp/anything.h5"
infos = self.o.configure(
task, completed_steps, steps_to_do, part_info, params)
self.assertIsNone(infos)
task.put_many_async.assert_called_once_with(self.child, dict(
enableCallbacks=True,
computeStatistics=True))
expected_filename = "/tmp/BLOCK-STAT-attributes.xml"
task.put_async.assert_called_once_with(
self.child["attributesFile"], expected_filename)
expected_xml = """<?xml version="1.0" ?>
<Attributes>
<Attribute addr="0" datatype="DOUBLE" description="Sum of the array" name="StatsTotal" source="TOTAL" type="PARAM" />
</Attributes>"""
actual_xml = open(expected_filename).read().replace(">", ">\n")
self.assertEqual(actual_xml.splitlines(), expected_xml.splitlines())

if __name__ == "__main__":
unittest.main(verbosity=2)

0 comments on commit 2e2afea

Please sign in to comment.