Commit e16f4398 authored by Sebastien Petitdemange's avatar Sebastien Petitdemange Committed by Vincent Michel

pep8

parent 1caf9975
import os, errno
import os
import errno
import h5py
from bliss.scanning.chain import AcquisitionDevice,AcquisitionMaster
from bliss.scanning.chain import AcquisitionDevice, AcquisitionMaster
class FileOrganizer(object):
def __init__(self,root_path,
def __init__(self, root_path,
windows_path_mapping=None,
detector_temporay_path=None,**keys):
detector_temporay_path=None, **keys):
""" A default way to organize file structure
windows_path_mapping -- transform unix path to windows
......@@ -16,36 +18,41 @@ class FileOrganizer(object):
self._root_path = root_path
self._windows_path_mapping = windows_path_mapping or dict()
self._detector_temporay_path = detector_temporay_path or dict()
class Hdf5Organizer(FileOrganizer):
def __init__(self,root_path,**keys):
FileOrganizer.__init__(self,root_path,**keys)
def __init__(self, root_path, **keys):
FileOrganizer.__init__(self, root_path, **keys)
self.file = None
def _acq_device_event(self, event_dict=None, signal=None, sender=None):
print 'received', signal, 'from', sender, ":", event_dict
def prepare(self,scan_recorder,scan_info,devices_tree):
path_suffix = scan_recorder.node.db_name().replace(':',os.path.sep)
full_path = os.path.join(self._root_path,path_suffix)
def prepare(self, scan_recorder, scan_info, devices_tree):
path_suffix = scan_recorder.node.db_name().replace(':', os.path.sep)
full_path = os.path.join(self._root_path, path_suffix)
try:
os.makedirs(full_path)
except OSError as exc: # Python >2.5
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else: raise
else:
raise
self.file = h5py.File(os.path.join(full_path,'data.h5'))
scan_entry = h5py.Group(self.file,scan_recorder.name,create=True)
self.file = h5py.File(os.path.join(full_path, 'data.h5'))
scan_entry = h5py.Group(self.file, scan_recorder.name, create=True)
scan_entry.attrs['NX_class'] = 'NXentry'
measurement = h5py.Group(scan_entry,'measurement',create=True)
measurement = h5py.Group(scan_entry, 'measurement', create=True)
master_id = 0
for dev,node in scan_recorder.nodes.iteritems():
if isinstance(dev,AcquisitionMaster):
master_entry = h5py.Group(measurement,'master%d' % master_id,create=True)
for dev, node in scan_recorder.nodes.iteritems():
if isinstance(dev, AcquisitionMaster):
master_entry = h5py.Group(
measurement, 'master%d' % master_id, create=True)
master_id += 1
for slave in dev.slaves:
if isinstance(slave,AcquisitionDevice):
for signal in ('start', 'end', 'new_ref','new_data'):
dispatcher.connect(self._acq_device_event, signal,dev)
if isinstance(slave, AcquisitionDevice):
for signal in ('start', 'end', 'new_ref', 'new_data'):
dispatcher.connect(
self._acq_device_event, signal, dev)
......@@ -11,26 +11,27 @@ import itertools
import functools
try:
from collections import OrderedDict
from collections import OrderedDict
except ImportError: # python2.6 compatibility
from ordereddict import OrderedDict
from ordereddict import OrderedDict
class WrappedMethod(object):
def __init__(self, control, method_name):
self.method_name = method_name
self.control = control
def __init__(self, control, method_name):
self.method_name = method_name
self.control = control
def __call__(self, this, *args, **kwargs):
return getattr(self.control, self.method_name)(*args, **kwargs)
def __call__(self, this, *args, **kwargs):
return getattr(self.control, self.method_name)(*args, **kwargs)
def wrap_methods(from_object, target_object):
for name in dir(from_object):
if inspect.ismethod(getattr(from_object, name)):
if hasattr(target_object, name) and inspect.ismethod(getattr(target_object, name)):
continue
setattr(target_object, name, types.MethodType(WrappedMethod(from_object, name), target_object, target_object.__class__))
for name in dir(from_object):
if inspect.ismethod(getattr(from_object, name)):
if hasattr(target_object, name) and inspect.ismethod(getattr(target_object, name)):
continue
setattr(target_object, name, types.MethodType(WrappedMethod(
from_object, name), target_object, target_object.__class__))
def add_conversion_function(obj, method_name, function):
......@@ -40,7 +41,7 @@ def add_conversion_function(obj, method_name, function):
def new_method(*args, **kwargs):
values = meth(*args, **kwargs)
return function(values)
setattr(obj, method_name, new_method)
setattr(obj, method_name, new_method)
else:
raise ValueError("conversion function must be callable")
else:
......@@ -48,25 +49,29 @@ def add_conversion_function(obj, method_name, function):
def add_property(inst, name, method):
cls = type(inst)
if not hasattr(cls, '__perinstance'):
cls = type(cls.__name__, (cls,), {})
cls.__perinstance = True
inst.__class__ = cls
setattr(cls, name, property(method))
cls = type(inst)
if not hasattr(cls, '__perinstance'):
cls = type(cls.__name__, (cls,), {})
cls.__perinstance = True
inst.__class__ = cls
setattr(cls, name, property(method))
def grouped(iterable, n):
"s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..."
return itertools.izip(*[iter(iterable)]*n)
return itertools.izip(*[iter(iterable)] * n)
def all_equal(iterable):
g = itertools.groupby(iterable)
return next(g, True) and not next(g, False)
"""
functions to add custom attributes and commands to an object.
"""
def add_object_method(obj, method, pre_call, name=None, args=[], types_info=(None, None)):
if name is None:
......@@ -98,27 +103,31 @@ def object_method(method=None, name=None, args=[], types_info=(None, None), filt
# Returns a method where _object_method_ attribute is filled with a
# dict of elements to characterize it.
method._object_method_ = dict(name=name, args=args, types_info=types_info, filter=filter)
method._object_method_ = dict(
name=name, args=args, types_info=types_info, filter=filter)
return method
def object_method_type(method=None, name=None, args=[], types_info=(None, None), type=None):
f = lambda x: isinstance(x, type)
def f(x): return isinstance(x, type)
return object_method(method=method, name=name, args=args, types_info=types_info, filter=f)
def add_object_attribute(obj, name=None, fget=None, fset=None, args=[], type_info=None, filter=None):
obj._add_custom_attribute(name, fget, fset, type_info)
"""
decorators for set/get methods to access to custom attributes
"""
def object_attribute_type_get(get_method=None, name=None, args=[], type_info=None, type=None):
f = lambda x: isinstance(x, type)
def f(x): return isinstance(x, type)
return object_attribute_get(get_method=get_method, name=name, args=args, type_info=type_info, filter=f)
def object_attribute_get(get_method=None, name=None, args=[], type_info=None, filter=None):
if get_method is None:
return functools.partial(object_attribute_get, name=name, args=args,
......@@ -128,21 +137,24 @@ def object_attribute_get(get_method=None, name=None, args=[], type_info=None, fi
name = get_method.func_name
attr_name = name
if attr_name.startswith("get_"):
attr_name = attr_name[4:] # removes leading "get_"
attr_name = attr_name[4:] # removes leading "get_"
get_method._object_method_ = dict(name=name, args=args, types_info=("None", type_info), filter=filter)
get_method._object_method_ = dict(
name=name, args=args, types_info=("None", type_info), filter=filter)
if not hasattr(get_method, "_object_attribute_"):
get_method._object_attribute_ = dict()
get_method._object_attribute_.update(name=attr_name, fget=get_method, args=args, type_info=type_info, filter=filter)
get_method._object_attribute_.update(
name=attr_name, fget=get_method, args=args, type_info=type_info, filter=filter)
return get_method
def object_attribute_type_set(set_method=None, name=None, args=[], type_info=None, type=None):
f = lambda x: isinstance(x, type)
def f(x): return isinstance(x, type)
return object_attribute_set(set_method=set_method, name=name, args=args, type_info=type_info, filter=f)
def object_attribute_set(set_method=None, name=None, args=[], type_info=None, filter=None):
if set_method is None:
return functools.partial(object_attribute_set, name=name, args=args,
......@@ -152,13 +164,15 @@ def object_attribute_set(set_method=None, name=None, args=[], type_info=None, fi
name = set_method.func_name
attr_name = name
if attr_name.startswith("set_"):
attr_name = attr_name[4:] # removes leading "set_"
attr_name = attr_name[4:] # removes leading "set_"
set_method._object_method_ = dict(name=name, args=args, types_info=(type_info, "None"), filter=filter)
set_method._object_method_ = dict(
name=name, args=args, types_info=(type_info, "None"), filter=filter)
if not hasattr(set_method, "_object_attribute_"):
set_method._object_attribute_ = dict()
set_method._object_attribute_.update(name=attr_name, fset=set_method, args=args, type_info=type_info, filter=filter)
set_method._object_attribute_.update(
name=attr_name, fset=set_method, args=args, type_info=type_info, filter=filter)
return set_method
......@@ -174,7 +188,7 @@ def set_custom_members(src_obj, target_obj, pre_call=None):
attribute_info = dict(member._object_attribute_)
filter = attribute_info.pop('filter', None)
if filter is None or filter(target_obj):
add_object_attribute(target_obj, **member._object_attribute_)
add_object_attribute(target_obj, **member._object_attribute_)
# For each method of <src_obj>: try to add it as a
# custom method or as methods to set/get custom
......@@ -237,7 +251,8 @@ def with_custom_members(klass):
access_mode = 'r' if fget else ''
access_mode += 'w' if fset else ''
if fget is None and fset is None:
raise RuntimeError("impossible case: must have fget or fset...")
raise RuntimeError(
"impossible case: must have fget or fset...")
custom_attrs[name] = type_info, access_mode
klass._get_custom_methods = _get_custom_methods
......@@ -250,7 +265,6 @@ def with_custom_members(klass):
return klass
class Null(object):
__slots__ = []
......
......@@ -11,33 +11,39 @@ from bliss import setup_globals
import weakref
import pickle
class InvalidValue(Null):
def __str__(self):
raise ValueError
def __repr__(self):
return '#ERR'
def get_cache():
return client.get_cache(db=0)
def boolify(s,**keys):
def boolify(s, **keys):
if s == 'True' or s == 'true':
return True
return True
if s == 'False' or s == 'false':
return False
return False
raise ValueError('Not Boolean Value!')
def auto_conversion(var):
'''guesses the str representation of the variables type'''
if var is None:
return None
for caster in (boolify,int, float):
for caster in (boolify, int, float):
try:
return caster(var)
except (ValueError,TypeError):
except (ValueError, TypeError):
pass
return var
def pickle_loads(var):
if var is None:
return None
......@@ -46,24 +52,26 @@ def pickle_loads(var):
except Exception:
return InvalidValue()
def ttl_func(cnx,name,value = -1):
def ttl_func(cnx, name, value=-1):
if value is None:
return cnx.persist(name)
elif value is -1:
return cnx.ttl(name)
else:
return cnx.expire(name,value)
return cnx.expire(name, value)
def read_decorator(func):
def _read(self,*args,**keys):
value = func(self,*args,**keys)
def _read(self, *args, **keys):
value = func(self, *args, **keys)
if self._read_type_conversion:
if isinstance(value,list):
if isinstance(value, list):
value = [self._read_type_conversion(x) for x in value]
elif isinstance(value,dict):
for k,v in value.iteritems():
elif isinstance(value, dict):
for k, v in value.iteritems():
value[k] = self._read_type_conversion(v)
if hasattr(self,'default_values') and isinstance(self.default_values,dict):
if hasattr(self, 'default_values') and isinstance(self.default_values, dict):
tmp = dict(self._default_values)
tmp.update(value)
value = tmp
......@@ -71,60 +79,65 @@ def read_decorator(func):
if value is not None:
value = self._read_type_conversion(value)
if value is None:
if hasattr(self,'_default_value'):
if hasattr(self, '_default_value'):
value = self._default_value
elif(hasattr(self,'_default_values') and
hasattr(self._default_values,'get')):
elif(hasattr(self, '_default_values') and
hasattr(self._default_values, 'get')):
value = self._default_values.get(args[0])
return value
return _read
def write_decorator_dict(func):
def _write(self,values,**keys):
def _write(self, values, **keys):
if self._write_type_conversion:
if not isinstance(values,dict) and values is not None:
if not isinstance(values, dict) and values is not None:
raise TypeError('can only be dict')
if values is not None:
for k,v in values.iteritems():
for k, v in values.iteritems():
values[k] = self._write_type_conversion(v)
return func(self,values,**keys)
return func(self, values, **keys)
return _write
def write_decorator_multiple(func):
def _write(self,values,**keys):
def _write(self, values, **keys):
if self._write_type_conversion:
if not isinstance(values,(list,tuple)) and values is not None:
if not isinstance(values, (list, tuple)) and values is not None:
raise TypeError('can only be tuple or list')
if values is not None:
values = [self._write_type_conversion(x) for x in values]
return func(self,values,**keys)
return func(self, values, **keys)
return _write
def write_decorator(func):
def _write(self,value,**keys):
def _write(self, value, **keys):
if self._write_type_conversion and value is not None:
value = self._write_type_conversion(value)
return func(self,value,**keys)
return func(self, value, **keys)
return _write
def scan(match='*',count=1000,connection=None):
def scan(match='*', count=1000, connection=None):
if connection is None:
connection = get_cache()
cursor = 0
while 1:
cursor,values = connection.scan(cursor=cursor,
match=match,count=count)
cursor, values = connection.scan(cursor=cursor,
match=match, count=count)
for val in values:
yield val
if int(cursor) == 0:
break
class SimpleSetting(object):
def __init__(self,name,connection = None,
read_type_conversion = auto_conversion,
write_type_conversion = None,
default_value = None):
def __init__(self, name, connection=None,
read_type_conversion=auto_conversion,
write_type_conversion=None,
default_value=None):
if connection is None:
connection = get_cache()
self._cnx = weakref.ref(connection)
......@@ -140,71 +153,72 @@ class SimpleSetting(object):
return value
@write_decorator
def set(self,value):
def set(self, value):
cnx = self._cnx()
cnx.set(self._name,value)
cnx.set(self._name, value)
def ttl(self, value=-1):
return ttl_func(self._cnx(), self._name, value)
def ttl(self,value = -1):
return ttl_func(self._cnx(),self._name,value)
def clear(self):
cnx = self._cnx()
cnx.delete(self._name)
def __add__(self,other):
def __add__(self, other):
value = self.get()
if isinstance(other,SimpleSetting):
if isinstance(other, SimpleSetting):
other = other.get()
return value + other
def __iadd__(self,other):
def __iadd__(self, other):
cnx = self._cnx()
if cnx is not None:
if isinstance(other,int):
if isinstance(other, int):
if other == 1:
cnx.incr(self._name)
else:
cnx.incrby(self._name,other)
elif isinstance(other,float):
cnx.incrbyfloat(self._name,other)
cnx.incrby(self._name, other)
elif isinstance(other, float):
cnx.incrbyfloat(self._name, other)
else:
cnx.append(self._name,other)
cnx.append(self._name, other)
return self
def __isub__(self,other):
if isinstance(other,basestring):
raise TypeError("unsupported operand type(s) for -=: %s" % type(other).__name__)
def __isub__(self, other):
if isinstance(other, basestring):
raise TypeError("unsupported operand type(s) for -=: %s" %
type(other).__name__)
return self.__iadd__(-other)
def __getitem__(self,ran):
def __getitem__(self, ran):
cnx = self._cnx()
if cnx is not None:
step = None
if isinstance(ran,slice):
i,j = ran.start,ran.stop
if isinstance(ran, slice):
i, j = ran.start, ran.stop
step = ran.step
elif isinstance(ran,int):
elif isinstance(ran, int):
i = j = ran
else:
raise TypeError('indices must be integers')
value = cnx.getrange(self._name,i,j)
value = cnx.getrange(self._name, i, j)
if step is not None:
value = value[0:-1:step]
return value
def __repr__(self):
cnx = self._cnx()
value = cnx.get(self._name)
return '<SimpleSetting name=%s value=%s>' % (self._name,value)
return '<SimpleSetting name=%s value=%s>' % (self._name, value)
class SimpleSettingProp(object):
def __init__(self,name,connection = None,
read_type_conversion = auto_conversion,
write_type_conversion = None,
default_value = None,
use_object_name = True):
def __init__(self, name, connection=None,
read_type_conversion=auto_conversion,
write_type_conversion=None,
default_value=None,
use_object_name=True):
self._name = name
self._cnx = connection or get_cache()
self._read_type_conversion = read_type_conversion
......@@ -212,18 +226,19 @@ class SimpleSettingProp(object):
self._default_value = default_value
self._use_object_name = use_object_name
def __get__(self,obj,type = None):
def __get__(self, obj, type=None):
if self._use_object_name:
name = obj.name + ':' + self._name
else:
name = self._name
return SimpleSetting(name,self._cnx,
return SimpleSetting(name, self._cnx,
self._read_type_conversion,
self._write_type_conversion,
self._default_value)
def __set__(self,obj,value):
if isinstance(value,SimpleSetting): return
def __set__(self, obj, value):
if isinstance(value, SimpleSetting):
return
if self._use_object_name:
name = obj.name + ':' + self._name
......@@ -235,67 +250,69 @@ class SimpleSettingProp(object):
else:
if self._write_type_conversion:
value = self._write_type_conversion(value)
self._cnx.set(name,value)
self._cnx.set(name, value)
class QueueSetting(object):
def __init__(self,name,connection = None,
read_type_conversion = auto_conversion,
write_type_conversion = None):
if connection is None: connection = get_cache()
def __init__(self, name, connection=None,
read_type_conversion=auto_conversion,
write_type_conversion=None):
if connection is None:
connection = get_cache()
self._cnx = weakref.ref(connection)
self._name = name
self._read_type_conversion = read_type_conversion
self._write_type_conversion = write_type_conversion
@read_decorator
def get(self,first=0,last=-1):
def get(self, first=0, last=-1):
cnx = self._cnx()
if first == last:
l = cnx.lindex(self._name,first)
l = cnx.lindex(self._name, first)
else:
if last != -1:
last -= 1
l = cnx.lrange(self._name,first,last)
l = cnx.lrange(self._name, first, last)
return l
@write_decorator
def append(self,value):
def append(self, value):
cnx = self._cnx()
return cnx.rpush(self._name,value)
return cnx.rpush(self._name, value)
def clear(self):
cnx = self._cnx()
cnx.delete(self._name)
@write_decorator
def prepend(self,value):
def prepend(self, value):
cnx = self._cnx()
return cnx.lpush(self._name,value)
return cnx.lpush(self._name, value)
@write_decorator_multiple
def extend(self,values):