Erik Frojdh 6c753f3b50 veto
2020-05-28 08:48:11 +02:00

96 lines
2.4 KiB
Python
Executable File

"""
Utility functions that are useful for testing and troubleshooting
but not directly used in controlling the detector
"""
from collections import namedtuple
import _slsdet #C++ lib
import functools
import datetime as dt
Geometry = namedtuple('Geometry', ['x', 'y'])
def is_iterable(item):
try:
iter(item)
except TypeError:
return False
return True
def get_set_bits(mask):
"""
Return a list of the set bits in a python integer
"""
return [i for i in range(mask.bit_length()) if (mask>>i)&1]
def list_to_bitmask(values):
"""
Convert a list of integers to a bitmask with set bits
where the list indicates
"""
mask = int(0)
values = list(set(values)) #Remove duplicates
for v in values:
mask += 1 << v
return mask
def to_geo(value):
if isinstance(value, _slsdet.xy):
return Geometry(x = value.x, y = value.y)
else:
raise ValueError("Can only convert sls_detector.xy")
def all_equal(mylist):
"""If all elements are equal return true otherwise false"""
return all(x == mylist[0] for x in mylist)
def element_if_equal(mylist):
"""If all elements are equal return only one element"""
if not is_iterable(mylist):
return mylist
if all_equal(mylist):
if len(mylist) == 0:
return None
else:
return mylist[0]
else:
return mylist
def reduce_time(mylist):
res = element_if_equal(element_if_equal(mylist))
if isinstance(res, dt.timedelta):
return res.total_seconds()
elif isinstance(res[0], list):
return [[item.total_seconds() for item in subl] for subl in res]
else:
return [r.total_seconds() for r in res]
def element(func):
"""
Wrapper to return either list or element
"""
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
return element_if_equal(func(self, *args, **kwargs))
return wrapper
def eiger_register_to_time(register):
"""
Decode register value and return time in s. Values are stored in
a 32bit register with bits 2->0 containing the exponent and bits
31->3 containing the significand (int value)
"""
clocks = register >> 3
exponent = register & 0b111
return clocks*10**exponent / 100e6
def make_timedelta(t):
if isinstance(t, dt.timedelta):
return t
else:
return dt.timedelta(seconds=t)