Commit 47047256 authored by Linus Pithan's avatar Linus Pithan
Browse files

really stuck

parent 2d1a771a
......@@ -10,7 +10,8 @@ import os
from .properties import LimaProperties, LimaProperty
from .bpm import Bpm
from .roi import Roi, RoiCounters
#from .roi import Roi, RoiCounters
from .new_roi import Roi, RoiCounters
from .image import ImageCounter
from .bgsub import BgSub
from bliss.common.utils import common_prefix, autocomplete_property
......
# -*- coding: utf-8 -*-
#
# This file is part of the bliss project
#
# Copyright (c) 2016 Beamline Control Unit, ESRF
# Distributed under the GNU LGPLv3. See LICENSE for more info.
import weakref
import numpy
from bliss.config import settings
from bliss.common.measurement import IntegratingCounter, BaseCounter, namespace, Counter
from bliss.scanning.chain import AcquisitionDevice, AcquisitionChannel
class Roi(object):
def __init__(self, x, y, width, height, name=None):
self.x = x
self.y = y
self.width = width
self.height = height
self.name = name
@property
def p0(self):
return (self.x, self.y)
@property
def p1(self):
return (self.x + self.width, self.y + self.height)
def is_valid(self):
return self.x >= 0 and self.y >= 0 and self.width >= 0 and self.height >= 0
def __repr__(self):
return "<%s,%s> <%s x %s>" % (self.x, self.y, self.width, self.height)
def __eq__(self, other):
return self.p0 == other.p0 and self.p1 == other.p1 and self.name == other.name
@classmethod
def frompoints(cls, p0, p1, name=None):
return cls.fromcoords(p0[0], p0[1], p1[0], p1[1], name=name)
@classmethod
def fromcoords(cls, x0, y0, x1, y1, name=None):
xmin = min(x0, x1)
ymin = min(y0, y1)
xmax = max(x0, x1)
ymax = max(y0, y1)
return cls(xmin, ymin, xmax - xmin, ymax - ymin, name=name)
class RoiStatCounter(Counter):
def __init__(self, roi_name, roi_obj, grouped_read_handler, **kwargs):
self.roi_name = roi_name
self.roi_obj = roi_obj
self.controller_ref = weakref.ref(kwargs.pop("controller"))
self._master_controller_ref = weakref.ref(kwargs.pop("master_controller"))
self.grouped_read_handler=grouped_read_handler
# ROISTATS = ["id","frame", "sum","avg","std","min", "max"]
# def factory(func):
# return map(lambda s : func(roi_name + "_" + s), ROISTATS)
@property
def controller(self):
return self.controller_ref()
@property
def name(self):
return self.roi_name
@property
def dtype(self):
return numpy.float
@property
def shape(self):
return ()
def create_acquisition_device(self, scan_pars):
return LimaAcqDevice(self.controller,self.master_controller, **scan_pars)
@property
def counters(self):
pass
# ~ class SingleRoiStatCounter(BaseCounter):
# ~ def __init__(self, roi_name, roi_counters_controller):
# ~ self._roi_counters_controller = weakref.ref(roi_counters_controller)
# ~ self.roi_name = roi_name
# ~ # ROISTATS = ["id","frame", "sum","avg","std","min", "max"]
# ~ # def factory(func):
# ~ return map(lambda s : func(roi_name + "_" + s), ROISTATS)
# ~ @property
# ~ def controller(self):
# ~ return self._roi_counters_controller()
# ~ @property
# ~ def name(self):
# ~ if self._chan_nb:
# ~ return "channel_{}".format(self._chan_nb)
# ~ else: # channel 0 == delay
# ~ return "delay"
# ~ @property
# ~ def dtype(self):
# ~ return numpy.float
# ~ @property
# ~ def shape(self):
# ~ return ()
class LimaAcqDevice(AcquisitionDevice):
def __init__(self, controller, master_controller, count_time=1, mode=None, counters=(), **kwargs):
prepare_once = kwargs.get("prepare_once", True)
start_once = kwargs.get("start_once", False)
AcquisitionDevice.__init__(
self,
controller,
controller.name,
npoints=kwargs.get("npoints", 1),
prepare_once=prepare_once,
start_once=start_once,
)
self._count_time = count_time
# self._mode = mode
self.counters = list()
self.add_counters(counters)
# self._event = gevent.event.Event()
self._controller=controller
self._master_controller=master_controller
def add_counter(self, roi_counter):
self.counters.append(roi_counter)
## self.channels.extend( self, lambda something map ...
self.channels.append(AcquisitionChannel(self, roi_counter.name + "_sum", roi_counter.dtype, roi_counter.shape))
self.channels.append(AcquisitionChannel(self, roi_counter.name + "_avg", roi_counter.dtype, roi_counter.shape))
self.channels.append(AcquisitionChannel(self, roi_counter.name + "_std", roi_counter.dtype, roi_counter.shape))
self.channels.append(AcquisitionChannel(self, roi_counter.name + "_min", roi_counter.dtype, roi_counter.shape))
self.channels.append(AcquisitionChannel(self, roi_counter.name + "_max", roi_counter.dtype, roi_counter.shape))
def add_counters(self, roi_counters):
for rc in roi_counters:
add_counter(rc)
def prepare(self):
pass
def start(self):
pass
def stop(self):
pass
def trigger(self):
pass
def reading(self):
print ("BLAAA")
class RoiCounterGroupReadHandler(IntegratingCounter.GroupedReadHandler):
def prepare(self, *counters):
self.controller.upload_rois()
def get_values(self, from_index, *counters):
import rlcompleter
import pdb
pdb.Pdb.complete = rlcompleter.Completer(locals()).complete
pdb.set_trace()
roi_counter_size = len(RoiStat)
raw_data = self.controller._proxy.readCounters(from_index)
if not raw_data.size:
return len(counters) * (numpy.array(()),)
raw_data.shape = (raw_data.size) // roi_counter_size, roi_counter_size
result = dict([int(counter), []] for counter in counters)
for roi_counter in raw_data:
roi_id = int(roi_counter[0])
for stat in range(roi_counter_size):
full_id = RoiStatCounter.roi_stat_id(roi_id, stat)
counter_data = result.get(full_id)
if counter_data is not None:
counter_data.append(roi_counter[stat])
return list(map(numpy.array, result.values()))
class RoiCounters(object):
"""Lima ROI counters
Example usage:
# add/replace a roi
mpx.roi_counters['r1'] = Roi(10, 10, 100, 200)
# add/replace multiple rois
mpx.roi_counters['r2', 'r3'] = Roi(20, 20, 300, 400), Roi(20, 20, 300, 400)
# get roi info
r2 = mpx.roi_counters['r2']
# get multiple roi info
r2, r1 = mpx.roi_counters['r2', 'r1']
# remove roi
del mpx.roi_counters['r1']
# clear all rois
mpx.roi_counters.clear()
# list roi names:
mpx.roi_counters.keys()
# loop rois
for roi_name, roi in mpx.roi_counters.items():
pass
"""
def __init__(self, name, proxy, acquisition_proxy):
self._proxy = proxy
self._acquisition_proxy = acquisition_proxy
self.name = "roi_counters"
full_name = "%s:%s" % (name, self.name)
self._current_config = settings.SimpleSetting(
full_name, default_value="default"
)
settings_name = "%s:%s" % (full_name, self._current_config.get())
self._save_rois = settings.HashObjSetting(settings_name)
# ~ self._roi_ids = {}
self._grouped_read_handler = RoiCounterGroupReadHandler(self)
# ~ def _set_roi(self, name, roi_values):
# ~ if isinstance(roi_values, Roi):
# ~ roi = roi_values
# ~ elif len(roi_values) == 4:
# ~ roi = Roi(*roi_values, name=name)
# ~ else:
# ~ raise TypeError(
# ~ "Lima.RoiCounters: roi accepts roi (class)"
# ~ " or (x,y,width,height) values"
# ~ )
# ~ roi.name = name
# ~ roi_id = self._proxy.addNames((name,))[0]
# ~ self._proxy.Start()
# ~ self._proxy.setRois((roi_id, roi.x, roi.y, roi.width, roi.height))
# ~ self._set_roi_settings(roi_id, roi)
# ~ def _set_roi_settings(self, roi_id, roi):
# ~ self._save_rois[roi.name] = roi
# ~ self._roi_ids[roi.name] = roi_id
# ~ def _clear_rois_settings(self):
# ~ self._save_rois.clear()
# ~ self._roi_ids.clear()
# ~ def _remove_rois(self, names):
# ~ for name in names:
# ~ del self._save_rois[name]
# ~ if name in self._roi_ids:
# ~ del self._roi_ids[name]
# ~ self._proxy.removeRois(names)
# ~ def set(self, name, roi_values):
# ~ """alias to: <lima obj>.roi_counters[name] = roi_values"""
# ~ self[name] = roi_values
# ~ def get_rois(self):
# ~ """alias to values()"""
# ~ return list(self.values())
# ~ def remove(self, name):
# ~ """alias to: del <lima obj>.roi_counters[name]"""
# ~ del self[name]
def get_saved_config_names(self):
return list(settings.scan(match="%s:*" % self.name))
@property
def config_name(self):
return self._current_config.get()
@config_name.setter
def config_name(self, name):
self._current_config.set(name)
self._save_rois = settings.HashObjSetting("%s:%s" % (self.name, name))
# ~ def upload_rois(self):
# ~ self._proxy.clearAllRois()
# ~ roi_list = [roi for roi in self.get_rois() if roi.is_valid()]
# ~ roi_id_list = self._proxy.addNames([x.name for x in roi_list])
# ~ rois_values = list()
# ~ for roi_id, roi in zip(roi_id_list, roi_list):
# ~ rois_values.extend((roi_id, roi.x, roi.y, roi.width, roi.height))
# ~ self._roi_ids[roi.name] = roi_id
# ~ if rois_values:
# ~ self._proxy.Start()
# ~ self._proxy.setRois(rois_values)
# ~ def load_rois(self):
# ~ """
# ~ Load current ROI counters from Lima and store them in settings
# ~ """
# ~ self._clear_rois_settings()
# ~ roi_names = self._proxy.getNames()
# ~ rois = self._proxy.getRois(roi_names)
# ~ for i, name in enumerate(roi_names):
# ~ roi_id = rois[i * 5]
# ~ idx = i * 5 + 1
# ~ x, y, w, h = rois[idx : idx + 4]
# ~ roi = Roi(x, y, w, h, name=name)
# ~ self._set_roi_settings(roi_id, roi)
# dict like API
# ~ def get(self, name, default=None):
# ~ return self._save_rois.get(name, default=default)
def __getitem__(self, names):
if isinstance(names, str):
return self._save_rois[names]
else:
return [self[name] for name in names]
# ~ def __setitem__(self, names, rois):
# ~ if isinstance(names, str):
# ~ self._set_roi(names, rois)
# ~ else:
# ~ for name, value in zip(names, rois):
# ~ self[name] = value
# ~ def __delitem__(self, names):
# ~ if isinstance(names, str):
# ~ names = (names,)
# ~ self._remove_rois(names)
# ~ def __contains__(self, name):
# ~ return name in self._save_rois
# ~ def __len__(self):
# ~ return len(self._save_rois)
# ~ def clear(self):
# ~ self._clear_rois_settings()
# ~ self._proxy.clearAllRois()
def keys(self):
return self._save_rois.keys()
def values(self):
return self._save_rois.values()
def items(self):
return self._save_rois.items()
# ~ def has_key(self, name):
# ~ return name in self._save_rois
# ~ def update(self, rois):
# ~ for name, roi in rois.items():
# ~ self[name] = roi
# ~ def pop(self, name, *args):
# ~ if name in self._roi_ids:
# ~ del self._roi_ids[name]
# ~ result = self._save_rois.pop(name, *args)
# ~ self._proxy.removeRois([name])
# ~ return result
# Counter access
# ~ def get_single_roi_counters(self, name):
# ~ if self._save_rois.get(name) is None:
# ~ raise AttributeError("Unknown ROI counter {!r}".format(name))
# ~ return SingleRoiCounters(
# ~ name,
# ~ controller=self,
# ~ master_controller=self._acquisition_proxy,
# ~ grouped_read_handler=self._grouped_read_handler,
# ~ )
# ~ def iter_single_roi_counters(self):
# ~ for roi in self.get_rois():
# ~ yield self.get_single_roi_counters(roi.name)
@property
def counters(self):
cnt_dict=dict()
for roi_name, roi_obj in self.items():
cnt_dict[roi_name] = RoiStatCounter(roi_name,roi_obj, self._grouped_read_handler, controller=self, master_controller=self._acquisition_proxy )
return namespace(cnt_dict)
# ~ return [
# ~ counter
# ~ for counters in self.iter_single_roi_counters()
# ~ for counter in counters
# ~ ]
# ~ def __getattr__(self, name):
# ~ return self.get_single_roi_counters(name)
# Representation
def __repr__(self):
name = self.name.rsplit(":", 1)[-1]
lines = ["[{0}]\n".format(self.config_name)]
rois = [self[name] for name in sorted(self.keys())]
if rois:
header = "Name", "ROI (<X, Y> <W x H>)"
x = max((len(str(roi.x)) for roi in rois))
y = max((len(str(roi.y)) for roi in rois))
w = max((len(str(roi.width)) for roi in rois))
h = max((len(str(roi.height)) for roi in rois))
roi_template = (
"<{{0.x: >{0}}}, {{0.y: >{1}}}> "
"<{{0.width: >{2}}} x {{0.height: >{3}}}>".format(x, y, w, h)
)
name_len = max(max((len(roi.name) for roi in rois)), len(header[0]))
roi_len = (
x + y + w + h + 10
) # 10 is surrounding characters (<,>,x and spaces)
template = "{{0: >{0}}} {{1: >{1}}}".format(name_len, roi_len)
lines += [
template.format(*header),
template.format(name_len * "-", roi_len * "-"),
]
lines += [
template.format(roi.name, roi_template.format((roi))) for roi in rois
]
else:
lines.append("*** no ROIs defined ***")
return "\n".join(lines)
Supports Markdown
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