Commit f3a7b017 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron
Browse files

Merge branch 'psi-implement-trigger-modes' into psi-smx-working

parents fdb59d90 601d4102
Pipeline #81194 passed with stages
in 14 minutes and 18 seconds
......@@ -257,18 +257,34 @@ void control::impl::hw_prepare(acq_params_t const& acq_params)
using namespace sls::FrameAssembler;
// Set acquisition parameters
m_det->setTimingMode(slsDetectorDefs::AUTO_TIMING);
slsDetectorDefs::timingMode timing_mode;
switch (acq_params.acq.trigger_mode) {
case trigger_mode_enum::software:
timing_mode = slsDetectorDefs::AUTO_TIMING;
break;
case trigger_mode_enum::external:
timing_mode = slsDetectorDefs::TRIGGER_EXPOSURE;
break;
case trigger_mode_enum::gate:
timing_mode = slsDetectorDefs::TRIGGER_GATED;
break;
}
int nb_frames = acq_params.acq.nb_frames;
int frames_per_trigger = acq_params.acq.nb_frames_per_trigger;
bool trigger_all_frames = (frames_per_trigger == acq_params.acq.all_frames);
if (!trigger_all_frames && (nb_frames % frames_per_trigger != 0))
throw lima::invalid_argument("Invalid nb_frames_per_trigger: " + std::to_string(frames_per_trigger));
m_det->setTimingMode(timing_mode);
m_det->setExptime(acq_params.acq.expo_time);
auto frame_period = acq_params.acq.expo_time + acq_params.acq.latency_time;
m_det->setPeriod(frame_period);
bool trig_exp = false;
int nb_frames = acq_params.acq.nb_frames;
int cam_frames = trig_exp ? 1 : nb_frames;
int cam_triggers = trig_exp ? nb_frames : 1;
int cam_frames = trigger_all_frames ? nb_frames : frames_per_trigger;
int cam_triggers = trigger_all_frames ? 1 : nb_frames / frames_per_trigger;
m_det->setNumberOfFrames(cam_frames);
m_det->setNumberOfTriggers(cam_triggers);
m_det->setNumberOfTriggers(cam_triggers);
// Set detector parameters
set_gain_mode(acq_params.det.gain_mode);
......
......@@ -21,7 +21,7 @@ namespace lima
BOOST_DESCRIBE_ENUM(reset_level_enum, soft, hard)
BOOST_DESCRIBE_ENUM(acq_state_enum, idle, preparing, prepared, running, stopping, resetting, fault, terminate)
BOOST_DESCRIBE_ENUM(acq_mode_enum, normal, concat)
BOOST_DESCRIBE_ENUM(trigger_mode_enum, internal, software, external, external_gate)
BOOST_DESCRIBE_ENUM(trigger_mode_enum, software, external, gate)
BOOST_DESCRIBE_ENUM(shutter_mode_enum, manual, auto_frame, auto_sequence)
BOOST_DESCRIBE_ENUM(flip_enum, none, left_right, up_down)
BOOST_DESCRIBE_ENUM(auto_exposure_mode_enum, on, off)
......
......@@ -25,10 +25,9 @@ enum class acq_mode_enum : int
/// Trigger mode
enum class trigger_mode_enum : int
{
internal, //!< Internal trigger
software, //!< Software trigger
external, //!< External trigger
external_gate //!< External gate trigger
software, //!< Software trigger
external, //!< External trigger
gate //!< External gate trigger
};
/// Acquisition state
......
......@@ -40,7 +40,7 @@ namespace hw
BOOST_ANNOTATE_MEMBER(info, trigger_modes,
(desc, "trigger modes"),
(doc, "The supported trigger modes [internal, software, external, external_gate"))
(doc, "The supported trigger modes [software, external, external_gate"))
BOOST_ANNOTATE_MEMBER(info, dimensions,
(desc, "detector dimensions"),
......
......@@ -17,7 +17,8 @@ namespace lima
{
namespace hw
{
BOOST_DESCRIBE_STRUCT(acquisition_params, (), (nb_frames, expo_time, latency_time, mode))
BOOST_DESCRIBE_STRUCT(acquisition_params, (),
(nb_frames, expo_time, latency_time, trigger_mode, nb_frames_per_trigger, acq_mode))
// clang-format off
BOOST_ANNOTATE_MEMBER(acquisition_params, nb_frames,
......@@ -32,9 +33,17 @@ namespace hw
(desc, "latency time"),
(doc, "The latency time [\u03BCs]"))
BOOST_ANNOTATE_MEMBER(acquisition_params, mode,
BOOST_ANNOTATE_MEMBER(acquisition_params, trigger_mode,
(desc, "trigger mode"),
(doc, "The trigger mode [software, external, gate]"))
BOOST_ANNOTATE_MEMBER(acquisition_params, nb_frames_per_trigger,
(desc, "nb frames per trigger"),
(doc, "The number of acquired frames per trigger when [software, external]"))
BOOST_ANNOTATE_MEMBER(acquisition_params, acq_mode,
(desc, "acquisition mode"),
(doc, "The acquistion mode [normal, concat]"))
(doc, "The acquisition mode [normal, concat]"))
// clang-format on
BOOST_DESCRIBE_STRUCT(image_params, (), (binning, roi, flip))
......
......@@ -17,10 +17,14 @@ namespace hw
struct acquisition_params
{
static constexpr int all_frames = -1;
int nb_frames = 1;
std::chrono::microseconds expo_time = 1ms;
std::chrono::microseconds latency_time = 0ms;
acq_mode_enum mode = acq_mode_enum::normal;
trigger_mode_enum trigger_mode = trigger_mode_enum::software;
int nb_frames_per_trigger = all_frames;
acq_mode_enum acq_mode = acq_mode_enum::normal;
};
/// HW image capabilities of the detector
......
......@@ -240,18 +240,21 @@ class ParamBase:
item_kws = dict(kws)
item_kws['level'] += 1
def item_str(v):
def item_str(k):
v = self[k]
if any([isinstance(v, b) for b in (EnumParam, ParamArray)]):
return v.dumps(**kws)
elif isinstance(v, ParamBase):
key_suffix = '\n' if indent else ''
return key_suffix + v.dumps(**item_kws)
elif v in self.Constants.get(k, {}).values():
return [n for n, c in self.Constants[k].items() if c == v][0]
else:
return repr(v)
head = '%*s' % (head_len, '')
def item_line(k):
return '%s%-*s%s' % (head, key_len, key_str(k), item_str(self[k]))
return '%s%-*s%s' % (head, key_len, key_str(k), item_str(k))
lines = [item_line(k) for k in keys]
return prefix + sep.join(lines) + suffix
......@@ -366,7 +369,8 @@ class ParamArray(list):
return prefix + sep.join([item_str(x) for x in self]) + suffix
def get_schema_type(schema, name=None, sub_schema=None, name_prefix=''):
def get_schema_type(schema, name=None, sub_schema=None, name_prefix='',
type_filter=None):
def RefName(x):
return x['$ref'].split('/')[-1]
......@@ -392,17 +396,15 @@ def get_schema_type(schema, name=None, sub_schema=None, name_prefix=''):
def SchemaEnum(n, items):
enum_name = f'{type_name}.{cpp_2_python_name(n)}'
return EnumParam(enum_name, {e.upper(): e for e in items})
enums = {n: SchemaEnum(n, p['enum'])
for n, p in schema_items if HasEnum(p)}
enums = {n: SchemaEnum(n, p['enum']) for n, p in schema_items if HasEnum(p)}
HasType = lambda p: '$ref' in p or 'properties' in p
def SchemaType(n, p):
name = RefName(p) if '$ref' in p else n
sub_schema = p if 'properties' in p else None
prefix = f'{type_name}.'
return get_schema_type(schema, name, sub_schema, prefix)
types = {n: SchemaType(n, p)
for n, p in schema_items if HasType(p)}
return get_schema_type(schema, name, sub_schema, prefix, type_filter)
types = {n: SchemaType(n, p) for n, p in schema_items if HasType(p)}
HasArray = lambda p: 'items' in p
def ComplexItem(p):
......@@ -423,9 +425,17 @@ def get_schema_type(schema, name=None, sub_schema=None, name_prefix=''):
for n, p in schema_items
if HasArray(p) and ComplexItem(p['items'])}
type_dict = dict(Model=model, Enums=enums, Types=types, Arrays=arrays)
constants = {}
type_dict = dict(Model=model, Enums=enums, Types=types, Arrays=arrays,
Constants=constants)
for d in enums, types, arrays:
type_dict.update({cpp_2_python_name(n): t for n, t in d.items()})
if type_filter:
type_name, type_dict = type_filter(type_name, type_dict)
for c in type_dict['Constants'].values():
type_dict.update(c)
return type(type_name, (ParamBase,), type_dict)
......@@ -437,9 +447,9 @@ def is_special_type_item(item, factory):
return isinstance(item, get_type_from_factory(factory))
def get_type_data(name, schema_json):
def get_type_data(name, schema_json, type_filter=None):
schema = json.loads(schema_json)
klass = get_schema_type(schema)
klass = get_schema_type(schema, type_filter=type_filter)
return TypeData(name, schema, klass)
......@@ -562,7 +572,7 @@ class Detector:
def checkConnection(self):
try:
self.ping()
if not self.__attrs:
if not self.__attrs:
self._initAttrs()
return True
except:
......@@ -581,7 +591,7 @@ class Detector:
prop = tango_db.get_class_attribute_property(tango_class, n)
return prop[n]['schema'][0]
def GetAttrData(n):
type_data = get_type_data(n, GetSchema(n))
type_data = get_type_data(n, GetSchema(n), self._typeFilter)
json_data = json.loads(getattr(d, n))
value = type_data.klass(json_data)
return dict(type_data=type_data, value=value)
......@@ -616,6 +626,13 @@ class Detector:
desc.addDeviceAttrData(self, attr_data)
setattr(self.__class__, n, desc)
@classmethod
def _typeFilter(klass, type_name, type_dict):
if type_name.endswith('AcqParams.Acq'):
all_frames = {'ALL_FRAMES': -1}
type_dict['Constants'].update({'nb_frames_per_trigger': all_frames})
return type_name, type_dict
def ping(self):
for d in self._getDevs():
d.ping()
......
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