mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-01-16 17:58:05 +01:00
generalized set_using_dict
This commit is contained in:
@@ -1267,9 +1267,11 @@ class Detector(CppDetectorApi):
|
||||
|
||||
@settingspath.setter
|
||||
def settingspath(self, path):
|
||||
self.setSettingsPath(path)
|
||||
path = ut.make_string_path(path)
|
||||
ut.set_using_dict(self.setSettingsPath, path)
|
||||
|
||||
@property
|
||||
@element
|
||||
def status(self):
|
||||
"""Gets detector status. Enum: runStatus
|
||||
Note
|
||||
@@ -1279,9 +1281,10 @@ class Detector(CppDetectorApi):
|
||||
>>> d.status
|
||||
runStatus.IDLE
|
||||
"""
|
||||
return element_if_equal(self.getDetectorStatus())
|
||||
return self.getDetectorStatus()
|
||||
|
||||
@property
|
||||
@element
|
||||
def rx_status(self):
|
||||
"""Gets receiver listener status. Enum: runStatus
|
||||
Note
|
||||
@@ -1290,21 +1293,23 @@ class Detector(CppDetectorApi):
|
||||
>>> d.rx_status
|
||||
runStatus.IDLE
|
||||
"""
|
||||
return element_if_equal(self.getReceiverStatus())
|
||||
return self.getReceiverStatus()
|
||||
|
||||
@property
|
||||
@element
|
||||
def rx_udpsocksize(self):
|
||||
"""UDP socket buffer size in receiver. Tune rmem_default and rmem_max accordingly."""
|
||||
return element_if_equal(self.getRxUDPSocketBufferSize())
|
||||
return self.getRxUDPSocketBufferSize()
|
||||
|
||||
@rx_udpsocksize.setter
|
||||
def rx_udpsocksize(self, buffer_size):
|
||||
self.setRxUDPSocketBufferSize(buffer_size)
|
||||
ut.set_using_dict(self.setRxUDPSocketBufferSize, buffer_size)
|
||||
|
||||
@property
|
||||
@element
|
||||
def rx_realudpsocksize(self):
|
||||
"""Gets actual udp socket buffer size. Double the size of rx_udpsocksize due to kernel bookkeeping."""
|
||||
return element_if_equal(self.getRxRealUDPSocketBufferSize())
|
||||
return self.getRxRealUDPSocketBufferSize()
|
||||
|
||||
@property
|
||||
def trimbits(self):
|
||||
@@ -1324,7 +1329,7 @@ class Detector(CppDetectorApi):
|
||||
@trimbits.setter
|
||||
def trimbits(self, fname):
|
||||
fname = ut.make_string_path(fname)
|
||||
self.loadTrimbits(fname)
|
||||
ut.set_using_dict(self.loadTrimbits, fname)
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -1336,26 +1341,27 @@ class Detector(CppDetectorApi):
|
||||
|
||||
@trimval.setter
|
||||
def trimval(self, value):
|
||||
self.setAllTrimbits(value)
|
||||
ut.set_using_dict(self.setAllTrimbits, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def lock(self):
|
||||
"""Lock detector to one client IP, 1 locks, 0 unlocks. Default is unlocked."""
|
||||
return element_if_equal(self.getDetectorLock())
|
||||
return self.getDetectorLock()
|
||||
|
||||
@lock.setter
|
||||
def lock(self, value):
|
||||
self.setDetectorLock(value)
|
||||
ut.set_using_dict(self.setDetectorLock, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def rx_lock(self):
|
||||
"""Lock receiver to one client IP, 1 locks, 0 unlocks. Default is unlocked."""
|
||||
return element_if_equal(self.getRxLock())
|
||||
return self.getRxLock()
|
||||
|
||||
@rx_lock.setter
|
||||
def rx_lock(self, value):
|
||||
self.setRxLock(value)
|
||||
|
||||
ut.set_using_dict(self.setRxLock, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
@@ -1379,9 +1385,10 @@ class Detector(CppDetectorApi):
|
||||
ut.set_using_dict(self.setRxZmqStartingFrame, value)
|
||||
|
||||
@property
|
||||
@element
|
||||
def lastclient(self):
|
||||
"""Get Client IP Address that last communicated with the detector."""
|
||||
return element_if_equal(self.getLastClientIP())
|
||||
return self.getLastClientIP()
|
||||
|
||||
@property
|
||||
def reg(self):
|
||||
@@ -1501,13 +1508,14 @@ class Detector(CppDetectorApi):
|
||||
return self.getMeasurementTime()
|
||||
|
||||
@property
|
||||
@element
|
||||
def led(self):
|
||||
"""[Ctb] Switches on/off all LEDs. Default is enabled. """
|
||||
return element_if_equal(self.getLEDEnable())
|
||||
return self.getLEDEnable()
|
||||
|
||||
@led.setter
|
||||
def led(self, value):
|
||||
self.setLEDEnable(value)
|
||||
ut.set_using_dict(self.setLEDEnable, value)
|
||||
|
||||
def acquire(self):
|
||||
"""
|
||||
@@ -1592,6 +1600,7 @@ class Detector(CppDetectorApi):
|
||||
self.setRateCorrection(tau)
|
||||
|
||||
@property
|
||||
@element
|
||||
def speed(self):
|
||||
"""
|
||||
[Eiger][Jungfrau] Readout speed of chip. Enum: speedLevel
|
||||
@@ -1605,7 +1614,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
@speed.setter
|
||||
def speed(self, value):
|
||||
self.setSpeed(value)
|
||||
ut.set_using_dict(self.setSpeed, value)
|
||||
|
||||
@property
|
||||
def rx_jsonpara(self):
|
||||
@@ -1653,11 +1662,7 @@ class Detector(CppDetectorApi):
|
||||
ut.set_using_dict(self.setAdditionalJsonHeader, args)
|
||||
|
||||
@property
|
||||
def rx_frameindex(self):
|
||||
"""Current frame index received in receiver during acquisition"""
|
||||
return self.getRxCurrentFrameIndex()
|
||||
|
||||
@property
|
||||
@element
|
||||
def threshold(self):
|
||||
"""[Eiger] Threshold in eV
|
||||
Note
|
||||
@@ -1665,13 +1670,14 @@ class Detector(CppDetectorApi):
|
||||
To change settings as well or set threshold without trimbits, use setThresholdEnergy.
|
||||
:setter: It loads trim files from settingspath.
|
||||
"""
|
||||
return element_if_equal(self.getThresholdEnergy())
|
||||
return self.getThresholdEnergy()
|
||||
|
||||
@threshold.setter
|
||||
def threshold(self, eV):
|
||||
self.setThresholdEnergy(eV)
|
||||
ut.set_using_dict(self.setThresholdEnergy, eV)
|
||||
|
||||
@property
|
||||
@element
|
||||
def timing(self):
|
||||
"""
|
||||
Set Timing Mode of detector. Enum: timingMode
|
||||
@@ -1682,13 +1688,14 @@ class Detector(CppDetectorApi):
|
||||
[Mythen3] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, TRIGGER_GATED \n
|
||||
[Eiger] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, BURST_TRIGGER
|
||||
"""
|
||||
return element_if_equal(self.getTimingMode())
|
||||
return self.getTimingMode()
|
||||
|
||||
@timing.setter
|
||||
def timing(self, mode):
|
||||
self.setTimingMode(mode)
|
||||
ut.set_using_dict(self.setTimingMode, mode)
|
||||
|
||||
@property
|
||||
@element
|
||||
def trimen(self):
|
||||
"""
|
||||
[Eiger] List of trim energies, where corresponding default trim files exist in corresponding trim folders.
|
||||
@@ -1700,13 +1707,14 @@ class Detector(CppDetectorApi):
|
||||
>>> d.trimen
|
||||
[4500, 5400, 6400]
|
||||
"""
|
||||
return element_if_equal(self.getTrimEnergies())
|
||||
return self.getTrimEnergies()
|
||||
|
||||
@trimen.setter
|
||||
def trimen(self, energies):
|
||||
self.setTrimEnergies(energies)
|
||||
ut.set_using_dict(self.setTrimEnergies, energies)
|
||||
|
||||
@property
|
||||
@element
|
||||
def vthreshold(self):
|
||||
"""
|
||||
[Eiger][Mythen3] Detector threshold voltage for single photon counters in dac units.
|
||||
@@ -1715,13 +1723,19 @@ class Detector(CppDetectorApi):
|
||||
[Eiger] Sets vcmp_ll, vcmp_lr, vcmp_rl, vcmp_rr and vcp to the same value. \n
|
||||
[Mythen3] Sets vth1, vth2 and vth3 to the same value.
|
||||
"""
|
||||
return element_if_equal(self.getDAC(dacIndex.VTHRESHOLD, False))
|
||||
return self.getDAC(dacIndex.VTHRESHOLD)
|
||||
|
||||
@vthreshold.setter
|
||||
def vthreshold(self, value):
|
||||
self.setDAC(dacIndex.VTHRESHOLD, value, False)
|
||||
if isinstance(value, dict):
|
||||
args = ({k:(dacIndex.VTHRESHOLD,v) for k,v in value.items()},)
|
||||
else:
|
||||
args = (dacIndex.VTHRESHOLD, value)
|
||||
ut.set_using_dict(self.setDAC, *args)
|
||||
|
||||
|
||||
@property
|
||||
@element
|
||||
def type(self):
|
||||
""" Returns detector type. Enum: detectorType
|
||||
Note
|
||||
@@ -1729,7 +1743,7 @@ class Detector(CppDetectorApi):
|
||||
:setter: Not implemented
|
||||
Values: EIGER, JUNGFRAU, GOTTHARD, MOENCH, MYTHEN3, GOTTHARD2, CHIPTESTBOARD
|
||||
"""
|
||||
return element_if_equal(self.getDetectorType())
|
||||
return self.getDetectorType()
|
||||
|
||||
@property
|
||||
def rx_frameindex(self):
|
||||
|
||||
@@ -3,9 +3,8 @@ 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 _slsdet #C++ lib
|
||||
import functools
|
||||
import datetime as dt
|
||||
import pathlib
|
||||
@@ -14,18 +13,21 @@ from pathlib import Path
|
||||
|
||||
Geometry = namedtuple('Geometry', ['x', 'y'])
|
||||
|
||||
|
||||
def is_iterable(item):
|
||||
try:
|
||||
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]
|
||||
return [i for i in range(mask.bit_length()) if (mask >> i) & 1]
|
||||
|
||||
|
||||
def list_to_bitmask(values):
|
||||
"""
|
||||
@@ -33,17 +35,19 @@ def list_to_bitmask(values):
|
||||
where the list indicates
|
||||
"""
|
||||
mask = int(0)
|
||||
values = list(set(values)) #Remove duplicates
|
||||
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)
|
||||
return Geometry(x=value.x, y=value.y)
|
||||
else:
|
||||
raise ValueError("Can only convert slsdet.xy")
|
||||
|
||||
|
||||
def all_equal(mylist):
|
||||
"""If all elements are equal return true otherwise false"""
|
||||
return all(x == mylist[0] for x in mylist)
|
||||
@@ -53,7 +57,7 @@ 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
|
||||
@@ -62,6 +66,7 @@ def element_if_equal(mylist):
|
||||
else:
|
||||
return mylist
|
||||
|
||||
|
||||
def reduce_time(mylist):
|
||||
res = element_if_equal(element_if_equal(mylist))
|
||||
if isinstance(res, dt.timedelta):
|
||||
@@ -71,6 +76,7 @@ def reduce_time(mylist):
|
||||
else:
|
||||
return [r.total_seconds() for r in res]
|
||||
|
||||
|
||||
def element(func):
|
||||
"""
|
||||
Wrapper to return either list or element
|
||||
@@ -78,6 +84,7 @@ def element(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
return element_if_equal(func(self, *args, **kwargs))
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
@@ -90,14 +97,16 @@ def eiger_register_to_time(register):
|
||||
"""
|
||||
clocks = register >> 3
|
||||
exponent = register & 0b111
|
||||
return clocks*10**exponent / 100e6
|
||||
return clocks * 10**exponent / 100e6
|
||||
|
||||
|
||||
def make_timedelta(t):
|
||||
if isinstance(t, dt.timedelta):
|
||||
return t
|
||||
return t
|
||||
else:
|
||||
return dt.timedelta(seconds=t)
|
||||
|
||||
|
||||
def _make_string_path(path):
|
||||
"""
|
||||
Accepts either a pathlib.Path or a string, expands ~ to user and convert
|
||||
@@ -110,26 +119,28 @@ def _make_string_path(path):
|
||||
else:
|
||||
raise ValueError("Cannot convert argument to posix path")
|
||||
|
||||
|
||||
def make_string_path(path):
|
||||
if isinstance(path, dict):
|
||||
return {key:_make_string_path(value) for key,value in path.items()}
|
||||
else:
|
||||
return _make_string_path(path)
|
||||
return _make(path, _make_string_path)
|
||||
|
||||
|
||||
def make_ip(arg):
|
||||
return _make(arg, _slsdet.IpAddr)
|
||||
|
||||
|
||||
def make_mac(arg):
|
||||
return _make(arg, _slsdet.MacAddr)
|
||||
|
||||
|
||||
def make_path(arg):
|
||||
return _make(arg, Path)
|
||||
|
||||
|
||||
|
||||
def _make(arg, transform):
|
||||
"""Helper function for make_mac and make_ip special cases for
|
||||
dict, list and tuple. Otherwise just calls transform"""
|
||||
if isinstance(arg, dict):
|
||||
return {key:transform(value) for key,value in arg.items()}
|
||||
return {key: transform(value) for key, value in arg.items()}
|
||||
elif isinstance(arg, list):
|
||||
return [transform(a) for a in arg]
|
||||
elif isinstance(arg, tuple):
|
||||
@@ -137,15 +148,21 @@ def _make(arg, transform):
|
||||
else:
|
||||
return transform(arg)
|
||||
|
||||
def set_using_dict(func, args):
|
||||
if isinstance(args, dict) and all(isinstance(k, int) for k in args.keys()):
|
||||
for key, value in args.items():
|
||||
|
||||
def set_using_dict(func, *args):
|
||||
|
||||
if len(args) == 1 and isinstance(args[0], dict) and all(
|
||||
isinstance(k, int) for k in args[0].keys()):
|
||||
for key, value in args[0].items():
|
||||
if not isinstance(value, tuple):
|
||||
value = (value,)
|
||||
try:
|
||||
func(value, [key])
|
||||
func(*value, [key])
|
||||
except TypeError:
|
||||
func(value, key)
|
||||
func(*value, key)
|
||||
else:
|
||||
func(args)
|
||||
func(*args)
|
||||
|
||||
|
||||
def set_time_using_dict(func, args):
|
||||
if isinstance(args, dict) and all(isinstance(k, int) for k in args.keys()):
|
||||
@@ -155,11 +172,13 @@ def set_time_using_dict(func, args):
|
||||
func(value, [key])
|
||||
else:
|
||||
if isinstance(args, int):
|
||||
args = float(args)
|
||||
args = float(args)
|
||||
func(args)
|
||||
|
||||
|
||||
def lhex(iterable):
|
||||
return [hex(item) for item in iterable]
|
||||
|
||||
|
||||
def lpath(iterable):
|
||||
return [Path(item) for item in iterable]
|
||||
Reference in New Issue
Block a user