Scans and acq. chain refactoring
Minutes of the meeting with: @papillon, @berruyer, @pguillou, @cyril.guilloud, @pancino, @matias.guijarro ; excused: @sebastien.petitdemange
Problems
- many repeated code for different continuous scans for different beamlines
- missing rules for writing counter controllers
- to clarify what is an Acquisition Master, an Acquisition Device, an Acquisiton Channel
- the default chain mechanisms are not generic enough
- Acquisition Chain today
- acquisition master => wraps a device which has the ability to trigger slaves
- can emit data = has Acquisition Channels
- acquisition device => wraps a device which can only acquire data
- has Acquisition Channels
- problem: since masters can emit data, it is possible to turn masters into "powerful" slaves, and special cases can arise, which makes it complicated to write generic code
- acquisition master => wraps a device which has the ability to trigger slaves
Proposal
A toolbox is needed to avoid many different implementations of the same thing
- it reduces errors and silly mistakes
- it guarantees coherency and ensure better maintainability
- the final goal is to be able to build continuous scans or default scans with the same reusable bits
- the default chain for default scans being just a specialization of applying the generic toolbox
Proposed changes to Acquisition Chain
- acquisition master should not emit data (= no acquisition channels)
- let's introduce a new
AcquisitionSlave
object- clearly shows a dependency on a particular master type
- will contain the acq. channels
- keep
AcquisitionDevice
for the generic case, when no specific Acq. Master is needed- ".add_external_channel" should be removed ; the feature has to be kept
- a way to alias data channels, like "musst1:encoder1" to be called "roby:position"
- valid for the whole chain
- proposal: name translation after data is emitted, before it is sent to redis
scan.aliases["musst1:encoder"] = "roby:position"
- ".add_external_channel" should be removed ; the feature has to be kept
Software timer example
|-- SoftwareTimerMaster
|- TimeAcquisitionSlave => epoch, elapsed_time acq. channels
Q: why not adding index
channel, for the current point number ?
Lima example
|-- LimaAcquisitionMaster
|- LimaImageAcquisitionSlave => image(s) channel(s)
|- LimaROICounterAcquisitionSlave => multiple Acq. Channels
|- LimaBPMAcquisitionSlave => multiple Acq. Channels
The slave objects can only be placed under a corresponding master object of same "type"
There can be several slaves under a master, triggered by the master "at the same time"
Keithley example
|-- KeithleyAcquisitionDevice
The device objects have to be placed under a parent master
This uses the generic mechanism in the acquisition chain to perform the acquisition
MUSST example
|-- MusstAcquisitonMaster => loads a program
|- MusstAcquisitionSlave => acq. channels correspond to what the program saves
|-- MusstTimerAcquistionMaster => works like a software timer master
|- MusstIntegratingAcquisitionSlave
|-- MusstSamplingAcquisitionDevice => has acq. channels to read latest values
P201 example
|-- P201AcquisitionMaster => works like a software timer master
|- P201IntegratingAcquisitionSlave => acq. channels correspond to the defined hw channels
EMh (ALBA electrometer) example
|-- EMhHardwareAcquisitionMaster
|- EMhAcquisitionSlave
|-- EMhSamplingAcquisitionDevice => multiple acq. channels for optimized reading
Steps to be able to build a chain from Measurement Group
Measurement group:
* pco
* keithley_diode
Corresponding counters:
* pco image (ImageCounter)
* pco roi1 (IntegratingCounter)
* pco roi2 (IntegratingCounter)
* keithley_diode (SamplingCounter)
Introspection, to get:
{ pco_controller:
{ 'master_class': LimaAcquisitionMaster,
'slaves': [{ "class": LimaROICounterAcquisitionSlave, "counters": ["roi1", "roi2"] }]
},
keithley_controller:
{ 'master_class': None,
'slaves': [{ "class": KeithleyAcquisitionDevice, "counters": ["keithley_diode"] }]
},
}
-
Functions to go through the introspection dictionary, to create acq. masters, slaves and devices
-
Functions to add to a scan chain
Example of chain to be built at the end, using the toolbox:
|-LimaAcquisitionMaster
|- LimaImageAcquisitionSlave
|- LmaROICountersAcquisitionSlave
|-SoftwareTimerAcquisitionMaster
|- KeithleyAcquisitionDevice