Commit 93f271a9 authored by Matias Guijarro's avatar Matias Guijarro Committed by Sebastien Petitdemange

scanning/scan.py: special case for motor groups

motor groups have no name, hence each channel (motor in group)
is attached to its parent node to make it look like it
corresponds to its own dataset using the motor name.
parent bf3f3bf9
......@@ -17,6 +17,7 @@ from treelib import Tree
from bliss.common.event import dispatcher
from bliss.common.cleanup import capture_exceptions
from bliss.common.greenlet_utils import KillMask
from bliss.common import motor_group
from .channel import AcquisitionChannelList, AcquisitionChannel
from .channel import duplicate_channel, attach_channels
......@@ -204,6 +205,14 @@ class ChainIterationPreset(object):
pass
def set_channel_device_name(acq_device, *channels):
for channel in channels:
if isinstance(acq_device.device, motor_group._Group):
channel._device_name = "axis"
else:
channel._device_name = acq_device.name
class AcquisitionMaster(object):
HARDWARE, SOFTWARE = list(range(2))
......@@ -274,8 +283,8 @@ class AcquisitionMaster(object):
self.__stats_dict = stats_dict
with profile(stats_dict, self.name, "prepare"):
if not self.__prepared:
for channel in self.channels:
channel._device_name = self.name
set_channel_device_name(self, *self.channels)
for connect, _ in self.__duplicated_channels.values():
connect()
self.__prepared = True
......@@ -488,8 +497,7 @@ class AcquisitionDevice(object):
def _prepare(self, stats_dict):
with profile(stats_dict, self.name, "prepare"):
for channel in self.channels:
channel._device_name = self.name
set_channel_device_name(self, *self.channels)
if not self._check_reading_task():
raise RuntimeError("%s: Last reading task is not finished." % self.name)
......
......@@ -35,6 +35,7 @@ from bliss.data.node import (
)
from bliss.data.scan import get_data
from bliss.common.session import get_current as _current_session
from bliss.common import motor_group
from .chain import AcquisitionDevice, AcquisitionMaster
from .writer.null import Writer as NullWriter
from .scan_math import peak, cen, com
......@@ -669,6 +670,17 @@ class Scan(object):
if signal == "end":
self.__trigger_data_watch_callback(signal, sender, sync=True)
def _prepare_channels(self, channels, parent_node):
for channel in channels:
self.nodes[channel] = _get_or_create_node(
channel.name,
channel.data_node_type,
parent_node,
shape=channel.shape,
dtype=channel.dtype,
)
connect(channel, "new_data", self._channel_event)
def prepare(self, scan_info, devices_tree):
parent_node = self.node
prev_level = 1
......@@ -681,19 +693,19 @@ class Scan(object):
if prev_level != level:
prev_level = level
parent_node = self.nodes[dev_node.bpointer]
if isinstance(dev, (AcquisitionDevice, AcquisitionMaster)):
data_container_node = _create_node(dev.name, parent=parent_node)
self.nodes[dev] = data_container_node
for channel in dev.channels:
self.nodes[channel] = _get_or_create_node(
channel.name,
channel.data_node_type,
data_container_node,
shape=channel.shape,
dtype=channel.dtype,
)
connect(channel, "new_data", self._channel_event)
if isinstance(dev.device, motor_group._Group):
# special case for motor group: motor groups have no name,
# each channel (motor in group) corresponds to its own dataset
# and is attached to the parent node
self.nodes[dev] = parent_node
self._prepare_channels(dev.channels, parent_node)
else:
data_container_node = _create_node(dev.name, parent=parent_node)
self.nodes[dev] = data_container_node
self._prepare_channels(dev.channels, data_container_node)
for signal in ("start", "end"):
connect(dev, signal, self._device_event)
......
......@@ -40,13 +40,10 @@ ascan_dump = """{ascan}
NX_class: NXinstrument
{ascan}/measurement
NX_class: NXcollection
{ascan}/measurement/{group_name}
{ascan}/measurement/{group_name}/{group_name}:roby
{ascan}/measurement/{group_name}/timer
{ascan}/measurement/timer
{ascan}/measurement/timer/diode:diode
{ascan}/measurement/timer/simu1:spectrum_det0
{ascan}/measurement/timer/timer:elapsed_time
{ascan}/measurement/axis:roby
{ascan}/measurement/diode:diode
{ascan}/measurement/simu1:spectrum_det0
{ascan}/measurement/timer:elapsed_time
{ascan}/start_time
{ascan}/title
"""
......@@ -115,24 +112,16 @@ def test_hdf5_file_items(beacon, session):
continue
else:
in_scan = l == s.node.name or l.startswith(s.node.name + "/")
if in_scan:
if l.startswith(s.node.name + "/measurement/group_"):
group_name = l.replace(s.node.name + "/measurement/", "").split("/")[0]
else:
if not in_scan:
continue
if "positioner" in l:
in_positioner = True
continue
else:
in_positioner = False
assert l == ref_ascan_dump[i].format(ascan=s.node.name, group_name=group_name)
i += 1
f = h5py.File(s.writer.filename)
assert (
f[f[s.node.name]["measurement"][group_name]["timer"].value]
== f[s.node.name]["measurement"]["timer"]
)
assert l == ref_ascan_dump[i].format(ascan=s.node.name)
i += 1
def test_hdf5_values(beacon, session):
......@@ -142,5 +131,5 @@ def test_hdf5_values(beacon, session):
scan_file = s.writer.filename
data = s.get_data()["diode"]
f = h5py.File(scan_file)
dataset = f[s.node.name]["measurement"]["timer"]["diode:diode"]
dataset = f[s.node.name]["measurement"]["diode:diode"]
assert list(dataset) == list(data)
......@@ -334,3 +334,20 @@ def test_save_images(session, beacon, lima_simulator, scan_tmpdir):
assert not os.path.isfile(os.path.join(images_path, image_filename % 0))
finally:
scan_saving.base_path = saved_base_path
def test_motor_group(beacon):
diode = beacon.get("diode")
roby = beacon.get("roby")
robz = beacon.get("robz")
scan = scans.a2scan(roby, 0, 1, robz, 0, 1, 5, 0.1, diode)
items = dict((child.name, child) for child in scan.node.children())
assert items["roby"].parent.db_name == scan.node.db_name
assert items["robz"].parent.db_name == scan.node.db_name
assert items["timer"].parent.db_name == scan.node.db_name
timer_channels = list(items["timer"].children())
timer_channel_names = set([chan.name.split(":")[-1] for chan in timer_channels])
assert "elapsed_time" in timer_channel_names
assert "diode" in timer_channel_names
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment