mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-20 02:40:03 +02:00
293 lines
8.4 KiB
Python
Executable File
293 lines
8.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Wed Dec 6 11:51:18 2017
|
|
|
|
@author: l_frojdh
|
|
"""
|
|
|
|
from .detector import Detector
|
|
from .temperature import Temperature, DetectorTemperature
|
|
from .dacs import DetectorDacs
|
|
import _slsdet
|
|
dacIndex = _slsdet.slsDetectorDefs.dacIndex
|
|
from .detector_property import DetectorProperty
|
|
|
|
class EigerVcmp:
|
|
"""
|
|
Convenience class to be able to loop over vcmp for Eiger
|
|
|
|
.. todo::
|
|
|
|
Support single assignment and perhaps unify with Dac class
|
|
|
|
"""
|
|
|
|
def __init__(self, detector):
|
|
_dacs = [ dacIndex.VCMP_LL,
|
|
dacIndex.VCMP_LR,
|
|
dacIndex.VCMP_RL,
|
|
dacIndex.VCMP_RR]
|
|
self.set = []
|
|
self.get = []
|
|
for i in range(detector.size()):
|
|
if i % 2 == 0:
|
|
dacs = _dacs
|
|
else:
|
|
dacs = _dacs[::-1]
|
|
for d in dacs:
|
|
self.set.append(lambda x, d=d, i=i : detector.setDAC(d, x, False, [i]))
|
|
self.get.append(lambda d=d, i=i : detector.getDAC(d, False, [i])[0])
|
|
|
|
def __getitem__(self, key):
|
|
if key == slice(None, None, None):
|
|
return [_d() for _d in self.get]
|
|
return self.get[key]()
|
|
|
|
def __setitem__(self, i, value):
|
|
self.set[i](value)
|
|
|
|
def __repr__(self):
|
|
return 'vcmp: '+ str(self[:])
|
|
|
|
|
|
class EigerDacs(DetectorDacs):
|
|
"""
|
|
Eiger specific dacs
|
|
"""
|
|
_dacs = [('vsvp', dacIndex.VSVP,0, 4000, 0),
|
|
('vtrim', dacIndex.VTRIM,0, 4000, 2500),
|
|
('vrpreamp', dacIndex.VRPREAMP,0, 4000, 3300),
|
|
('vrshaper', dacIndex.VRSHAPER,0, 4000, 1400),
|
|
('vsvn', dacIndex.VSVN,0, 4000, 4000),
|
|
('vtgstv', dacIndex.VTGSTV,0, 4000, 2556),
|
|
('vcmp_ll', dacIndex.VCMP_LL,0, 4000, 1500),
|
|
('vcmp_lr', dacIndex.VCMP_LR,0, 4000, 1500),
|
|
('vcal', dacIndex.VCAL,0, 4000, 4000),
|
|
('vcmp_rl', dacIndex.VCMP_RL,0, 4000, 1500),
|
|
('rxb_rb', dacIndex.RXB_RB,0, 4000, 1100),
|
|
('rxb_lb', dacIndex.RXB_LB,0, 4000, 1100),
|
|
('vcmp_rr', dacIndex.VCMP_RR,0, 4000, 1500),
|
|
('vcp', dacIndex.VCP,0, 4000, 200),
|
|
('vcn', dacIndex.VCN,0, 4000, 2000),
|
|
('vishaper', dacIndex.VISHAPER,0, 4000, 1550),
|
|
('iodelay', dacIndex.IO_DELAY,0, 4000, 660)]
|
|
_dacnames = [_d[0] for _d in _dacs]
|
|
|
|
|
|
from .detector import freeze
|
|
|
|
@freeze
|
|
class Eiger(Detector):
|
|
"""
|
|
Subclassing Detector to set up correct dacs and detector specific
|
|
functions.
|
|
"""
|
|
_detector_dynamic_range = [4, 8, 16, 32]
|
|
|
|
|
|
_settings = ['standard', 'highgain', 'lowgain', 'veryhighgain', 'verylowgain']
|
|
"""available settings for Eiger, note almost always standard"""
|
|
|
|
def __init__(self, id=0):
|
|
super().__init__(id)
|
|
self._frozen = False
|
|
self._dacs = EigerDacs(self)
|
|
self._vcmp = EigerVcmp(self)
|
|
|
|
# Eiger specific adcs
|
|
self._temp = DetectorTemperature()
|
|
self._temp.fpga = Temperature('temp_fpga', dacIndex.TEMPERATURE_FPGA, self)
|
|
self._temp.fpgaext = Temperature('temp_fpgaext', dacIndex.TEMPERATURE_FPGAEXT, self)
|
|
self._temp.t10ge = Temperature('temp_10ge', dacIndex.TEMPERATURE_10GE, self)
|
|
self._temp.dcdc = Temperature('temp_dcdc', dacIndex.TEMPERATURE_DCDC, self)
|
|
self._temp.sodl = Temperature('temp_sodl', dacIndex.TEMPERATURE_SODL, self)
|
|
self._temp.sodr = Temperature('temp_sodl', dacIndex.TEMPERATURE_SODR, self)
|
|
self._temp.temp_fpgafl = Temperature('temp_fpgafl', dacIndex.TEMPERATURE_FPGA2, self)
|
|
self._temp.temp_fpgafr = Temperature('temp_fpgafr', dacIndex.TEMPERATURE_FPGA3, self)
|
|
|
|
|
|
|
|
@property
|
|
def dacs(self):
|
|
"""
|
|
|
|
An instance of DetectorDacs used for accessing the dacs of a single
|
|
or multi detector.
|
|
|
|
Examples
|
|
---------
|
|
|
|
::
|
|
|
|
d = Eiger()
|
|
|
|
#Set all vrf to 1500
|
|
d.dacs.vrf = 1500
|
|
|
|
#Check vrf
|
|
d.dacs.vrf
|
|
>> vrf : 1500, 1500
|
|
|
|
#Set a single vtr
|
|
d.dacs.vtr[0] = 1800
|
|
|
|
#Set vrf with multiple values
|
|
d.dacs.vrf = [3500,3700]
|
|
d.dacs.vrf
|
|
>> vrf : 3500, 3700
|
|
|
|
#read into a variable
|
|
var = d.dacs.vrf[:]
|
|
|
|
#set multiple with multiple values, mostly used for large systems
|
|
d.dacs.vcall[0,1] = [3500,3600]
|
|
d.dacs.vcall
|
|
>> vcall : 3500, 3600
|
|
|
|
d.dacs
|
|
>>
|
|
========== DACS =========
|
|
vsvp : 0, 0
|
|
vtr : 4000, 4000
|
|
vrf : 1900, 1900
|
|
vrs : 1400, 1400
|
|
vsvn : 4000, 4000
|
|
vtgstv : 2556, 2556
|
|
vcmp_ll : 1500, 1500
|
|
vcmp_lr : 1500, 1500
|
|
vcall : 4000, 4000
|
|
vcmp_rl : 1500, 1500
|
|
rxb_rb : 1100, 1100
|
|
rxb_lb : 1100, 1100
|
|
vcmp_rr : 1500, 1500
|
|
vcp : 1500, 1500
|
|
vcn : 2000, 2000
|
|
vis : 1550, 1550
|
|
iodelay : 660, 660
|
|
|
|
"""
|
|
return self._dacs
|
|
|
|
|
|
@property
|
|
def vcmp(self):
|
|
"""
|
|
Convenience function to get and set the individual vcmp of chips
|
|
Used mainly in the calibration code.
|
|
|
|
Examples
|
|
---------
|
|
|
|
::
|
|
|
|
#Reading
|
|
d.vcmp[:]
|
|
>> [500, 500, 500, 500, 500, 500, 500, 500]
|
|
|
|
#Setting
|
|
d.vcmp = [500, 500, 500, 500, 500, 500, 500, 500]
|
|
|
|
|
|
"""
|
|
|
|
return self._vcmp
|
|
|
|
@vcmp.setter
|
|
def vcmp(self, values):
|
|
if len(values) == len(self._vcmp.set):
|
|
for i, v in enumerate(values):
|
|
self._vcmp.set[i](v)
|
|
else:
|
|
raise ValueError('vcmp only compatible with setting all')
|
|
|
|
# @property
|
|
# def rx_udpport(self):
|
|
# """
|
|
# UDP port for the receiver. Each module has two ports referred to
|
|
# as rx_udpport and rx_udpport2 in the command line interface
|
|
# here they are grouped for each detector
|
|
|
|
# ::
|
|
|
|
# [0:rx_udpport, 0:rx_udpport2, 1:rx_udpport ...]
|
|
|
|
# Examples
|
|
# -----------
|
|
|
|
# ::
|
|
|
|
# d.rx_udpport
|
|
# >> [50010, 50011, 50004, 50005]
|
|
|
|
# d.rx_udpport = [50010, 50011, 50012, 50013]
|
|
|
|
# """
|
|
# p0 = self._api.getReceiverUDPPort()
|
|
# p1 = self._api.getReceiverUDPPort2()
|
|
# return [int(val) for pair in zip(p0, p1) for val in pair]
|
|
|
|
# @rx_udpport.setter
|
|
# def rx_udpport(self, ports):
|
|
# """Requires iterating over elements two and two for setting ports"""
|
|
# a = iter(ports)
|
|
# for i, p in enumerate(zip(a, a)):
|
|
# self._api.setReceiverUDPPort(p[0], i)
|
|
# self._api.setReceiverUDPPort2(p[1], i)
|
|
|
|
@property
|
|
def rx_zmqport(self):
|
|
"""
|
|
Return the receiver zmq ports. Note that Eiger has two ports per receiver!
|
|
This functions therefore differ from the base class.
|
|
|
|
::
|
|
|
|
e.rx_zmqport
|
|
>> [30001, 30002, 30003, 30004]
|
|
|
|
|
|
"""
|
|
ports = self.getRxZmqPort()
|
|
return [p + i for p in ports for i in range(2)]
|
|
|
|
|
|
# @rx_zmqport.setter
|
|
# def rx_zmqport(self, port):
|
|
# if isinstance(port, Iterable):
|
|
# for i, p in enumerate(port):
|
|
# self._api.setReceiverStreamingPort(p, i)
|
|
# else:
|
|
# self._api.setReceiverStreamingPort(port, -1)
|
|
|
|
@property
|
|
def temp(self):
|
|
"""
|
|
An instance of DetectorAdcs used to read the temperature
|
|
of different components
|
|
|
|
Examples
|
|
-----------
|
|
|
|
::
|
|
|
|
detector.temp
|
|
>>
|
|
temp_fpga : 36.90°C, 45.60°C
|
|
temp_fpgaext : 31.50°C, 32.50°C
|
|
temp_10ge : 0.00°C, 0.00°C
|
|
temp_dcdc : 36.00°C, 36.00°C
|
|
temp_sodl : 33.00°C, 34.50°C
|
|
temp_sodr : 33.50°C, 34.00°C
|
|
temp_fpgafl : 33.81°C, 30.93°C
|
|
temp_fpgafr : 27.88°C, 29.15°C
|
|
|
|
a = detector.temp.fpga[:]
|
|
a
|
|
>> [36.568, 45.542]
|
|
|
|
|
|
"""
|
|
return self._temp
|
|
|