Abo
The abo
subpackage provides modules with various ways and classes for higher level synchronous
readout from the
DOOCS control system. The contents of this subpackage is presented below:
import doocspie
help(doocspie.abo)
Help on package doocspie.abo in doocspie:
NAME
doocspie.abo - Modules for higher level synchronous readout from DOOCS.
PACKAGE CONTENTS
synchronizer
train_abo
train_event
FILE
/home/cbehrens/Home/Repositories/gitlab/doocspie/doocspie/abo/__init__.py
In the following, we show how to use instances of TrainAbo
to
synchronously acquire instances of TrainEvent
,
which contains all the relevant data of interest. The synchronization backend, which is
provided by the
Synchronizer
,
is described as well. The latter can also be used independently.
TrainAbo
The simplest and most convenient way to synchronously retrieve data can be realized
with the TrainAbo
class of the
train_abo
module, and its entire documentation is presented here:
help(doocspie.abo.train_abo.TrainAbo)
Help on class TrainAbo in module doocspie.abo.train_abo:
class TrainAbo(builtins.object)
| TrainAbo(properties=None, train_events=None, timeout_seconds=10, buffer_size=32, allow_zero_events=False)
|
| TrainAbo class for higher level synchronous readout from DOOCS.
|
| This class provides the train abo for higher level synchronous readout from DOOCS.
|
| Methods defined here:
|
| __init__(self, properties=None, train_events=None, timeout_seconds=10, buffer_size=32, allow_zero_events=False)
| Constructor of the train abo class.
|
| This constructor initializes the instance with optional parameters (see 'Args' below).
|
| Args:
| properties (tuple or dict, optional): The optional properties to get train events with readouts for.
| train_events (int, optional): The optional number of train events to synchronously readout.
| timeout_seconds (int): The optional timeout seconds for unsuccessful readout.
| buffer_size (int): The optional number of buffers to be used for storing previous readouts.
| allow_zero_events (bool, optional): The optional state for allow zero train events.
|
| __iter__(self)
| Special method to provide a train abo iterator.
|
| __next__(self)
| Special method to provide the next train event for the train abo iterator.
|
| __str__(self)
| Special method to return a properly formatted string representation of the train abo.
|
| add(self, address, label=None, offset=None, timestamp_event=None, meta_event=None, start=None, elements=None)
| Add address with optional parameters to the properties for synchronous readout.
|
| Args:
| address (str): The DOOCS address to add to the properties for synchronous readout.
| label (str, optional): Optional label for DOOCS address as a means for alternative property access.
| offset (int, optional): Optional offset to be applied on event numbers for synchronization.
| timestamp_event (bool, optional): Optional state to determine using the timestamp as an alternative event.
| meta_event (str, optional): Optional Meta property to replace the default event with.
| start (int, optional): Optional start position for reading out array-like types.
| elements (int, optional): Optional number of elements to read out for array-like types.
|
| Returns:
| None
|
| Raises:
| DoocspieException: Doocspie related exception for address duplication.
|
| reset(self)
| Reset the train abo in order to use it again.
|
| Returns:
| None
|
| start_loop(self, function)
| Start the loop the train abo and execute the given function once there is a new train event.
|
| Args:
| function (function): The function to execute for a new train event.
|
| Returns:
| None
|
| stop_loop(self)
| Stop the loop of the train abo and its execution of the supplied function.
|
| Returns:
| None
|
| update(self)
| Update the newly added properties for synchronous readout.
|
| Returns:
| None
|
| ----------------------------------------------------------------------
| Readonly properties defined here:
|
| actual_properties
| tuple: The properties that can actually be readout and returned via TrainEvent's 'get'.
|
| train_event
| int: The number of the current train event in the train abo.
|
| train_events
| int: The number of total train events in the train abo.
|
| unusable_properties
| tuple: The properties that cannot be used for synchronized readout in the train abo.
|
| usable_properties
| tuple: The properties that can be used for synchronized readout in the train abo.
|
| zero_event_properties
| tuple: The properties that have an event number of 'zero'.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
The TrainAbo
class can simply be imported directly from
the doocspie.abo
subpackage as shown in the code example
below. Here, we instantiate an empty instance and print out its content.
from doocspie.abo import TrainAbo
train_abo = TrainAbo()
print(train_abo)
TrainAbo(train_events=None, train_event=0, actual_properties=())
The printout above reveals the important attributes of the TrainAbo
instance, namely the number of total
train_events
to return (None
corresponds to unlimited events), the current train_event
number and the
properties that are actually be recorded, called actual_properties
. No properties were added to the
TrainAbo
instance for recording yet, but this will be carried out in the following:
train_abo.add("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER", label="foo")
train_abo.add("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER", offset=0)
print(train_abo)
train_abo.update()
print(train_abo)
train_abo.add("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/SPECTRUM", start=10, elements=20)
print(train_abo)
TrainAbo(train_events=None, train_event=0, actual_properties=())
TrainAbo(train_events=None, train_event=0, actual_properties=('TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', 'foo', 'TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER'))
TrainAbo(train_events=None, train_event=0, actual_properties=('TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', 'foo', 'TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER'))
While adding DOOCS properties for synchronous readout via the add
method,
the two optional parameters label
and
offset
can be supplied among others. The label
parameter provides an alternative, more
convenient way to access
the data, and the offset
parameter can be applied for synchronization when unintentional offsets in the event
number exist. The parameters start
and elements
additionally allow to read out only
chunks of the entire array
data for array-like DOOCS types, e.g. SPECTRUM
, when supported by the server. The TrainAbo
does internal
feasibility checks on the added properties, hence the update
method must be called in order to see effects on the
added properties (see example above). However, this update
method is also being called implicitly when data is being
recorded, hence it can usually be omitted. The following code lines demonstrate how
to actually get data from the
TrainAbo
instance, making use of its iterator protocol:
train_event = next(train_abo)
print(train_event)
TrainEvent(id=3524121, properties=('TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', 'foo', 'TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER'))
The acquired data provided by TrainAbo
is aggregated in an instance of the TrainEvent
,
having an id
that
represents the event
number of all simultaneously recorded DOOCS
properties and the actually recorded properties
themselves. In the example above, the two previously added DOOCS properties,
accessible either via their addresses or
supplied labels, are included in the TrainEvent
instance. The TrainEvent
class is described more carefully in a
separated section below.
An alternative way to add properties to the TrainAbo
is
by supplying the DOOCS addresses with the optional
label
,
offset
,
start
,
elements
,
timestamp_event
and/or meta_event
key-value pairs during
instantiation, which is demonstrated in the following code example. Here, the three
update
invocation mentioned
above is not required. The properties (attributes) usable_properties
, unusable_properties
and
actual_properties
are also being introduced, which
are convenient for debugging purposes. A few options are also
being used in an example at the end of this section.
addresses = {"TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER": {"label": "float",
"offset": 1},
"TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/SPECTRUM": {"start": 100,
"elements": 200},
"TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER": {"label": "integer"}}
train_abo = TrainAbo(addresses)
print("usable properties:", train_abo.usable_properties)
print("unusable properties:", train_abo.unusable_properties)
print("actual properties:", train_abo.actual_properties)
usable properties: (Usable(address='TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', label='float', offset=1, timestamp_event=None, meta_event=None, start=None, elements=None), Usable(address='TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER', label='integer', offset=None, timestamp_event=None, meta_event=None, start=None, elements=None))
unusable properties: (Unusable(address='TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/SPECTRUM', label=None, reason='zero event number'),)
actual properties: ('TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', 'float', 'TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER', 'integer')
The DOOCS properties in the TrainAbo
are fundamentally being split into usable_properties
and
unusable_properties
, where the latter cannot be
used for synchronized readout for a number of reasons. The actual
reason is also given in the corresponding property output, and in the previous
example, it is due to zero event numbers
(e.g. typical for actuators or slowly changing values in general). In some
situations, one might want to record
‘zero events’ anyway, and this can be realized by the optional allow_zero_events
parameter. Those DOOCS
properties
are then still listed in unusable_properties
, but they also appear in actual_properties
, which determines the
properties that get actually recorded in a TrainEvent
. This is presented in the two following
examples:
addresses = ("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER",
"TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT")
train_abo = TrainAbo(addresses, allow_zero_events=True)
print("usable properties:", train_abo.usable_properties)
print("unusable properties:", train_abo.unusable_properties)
print("actual properties:", train_abo.actual_properties)
usable properties: (Usable(address='TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', label=None, offset=None, timestamp_event=None, meta_event=None, start=None, elements=None),)
unusable properties: (Unusable(address='TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT', label=None, reason='zero event number'),)
actual properties: ('TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', 'TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT')
train_event = next(train_abo)
print(train_event)
TrainEvent(id=3524131, properties=('TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', 'TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT'))
The TrainAbo
class implements the iterator protocol and
thus allows convenient iteration in a simple for
loop as
is demonstrated in the following. The TrainAbo
instance being used has been instantiated
without a certain number of
train_events
, hence a break
condition is being applied in order to prevent unlimited iteration. The subsequent
example then presents how to provide a train_events
parameter to limit the iteration, and
the attributes
train_event(s)
are introduced.
for index, train_event in enumerate(train_abo):
if index == 3:
break
print("train event:", train_event.id)
train event: 3524132
train event: 3524133
train event: 3524134
addresses = ("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER",
"TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER")
train_abo = TrainAbo(addresses, train_events=3)
print("train event / train events:", train_abo.train_event, "of", train_abo.train_events, "\n")
for train_event in train_abo:
print("train event:", train_event.id)
train event / train events: 0 of 3
train event: 3524140
train event: 3524141
train event: 3524142
Once all train_events
have been generated, the TrainAbo
instance is exhausted as is shown here:
print("train event / train events:", train_abo.train_event, "of", train_abo.train_events, "\n")
for train_event in train_abo:
print("train event:", train_event.id) # not being executed
try:
next(train_abo)
except StopIteration as err:
print(err)
train event / train events: 3 of 3
all train events have been generated
In order to use it again, one can either create a new instance or apply the reset
method like that:
train_abo.reset() # reset in order to use it again
print("train event / train events:", train_abo.train_event, "of", train_abo.train_events, "\n")
for train_event in train_abo:
print("train event:", train_event.id)
train event / train events: 0 of 3
train event: 3524143
train event: 3524144
train event: 3524145
Besides iterators, the TrainAbo
supports callback functions that get provided with TrainEvent
instances. In the
following example, we re-use the previous TrainAbo
instance by resetting it, and define a
callback function that
gets executed in a loop by passing it to the start_loop
method. The callback function can be
named anything, and its
one parameter (name ist also arbitrary) will be an instance of TrainEvent
. The callback function’s name without
parentheses must be supplied.
train_abo.reset()
def callback(train_event):
print("train event:", train_event.id)
train_abo.start_loop(callback)
train event: 3524146
train event: 3524147
train event: 3524148
In case the TrainAbo
is being instantiated without a certain
number of train_events
, the loop that is executing
the callback function can be stopped via the stop_loop
methods as is shown here:
addresses = ("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER",
"TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER")
train_abo = TrainAbo(addresses)
counter = 0
def callback(train_event):
global counter
counter += 1
print("train event:", train_event.id)
if counter == 3:
train_abo.stop_loop()
train_abo.start_loop(callback)
train event: 3524153
train event: 3524154
train event: 3524155
Finally, we demonstrate both the iterator and callback function approach of the TrainAbo
class for synchronized
readout in a typical use case, respectively. We instantiate a TrainAbo
instance with fifty train_events
and two
DOOCS addresses for charge monitors (toroids), which are supposed to be correlated
to a very high degree. We then
collect the charge of the first bunch of each charge monitor (using the [0]
indexing) in a list
and eventually
plot them against each other.
import matplotlib.pyplot as plt
train_abo = TrainAbo(train_events=50)
train_abo.add("FLASH.DIAG/TOROID/1FL0UBC2/CHARGE.TD", label="charge 1")
train_abo.add("FLASH.DIAG/TOROID/2FL0DBC2/CHARGE.TD", label="charge 2")
charge_1 = list()
charge_2 = list()
for train_event in train_abo:
charge_1.append(train_event.get("charge 1").data[0])
charge_2.append(train_event.get("charge 2").data[0])
plt.plot(charge_1, charge_2, "o")
plt.xlabel("Charge 1 (nC)")
plt.ylabel("Charge 2 (nC)");
Here, we simply re-use the previous TrainAbo
instance by resetting it and clearing the
lists:
train_abo.reset()
charge_1.clear()
charge_2.clear()
def correlate_charge(train_event):
charge_1.append(train_event.get("charge 1").data[0])
charge_2.append(train_event.get("charge 2").data[0])
train_abo.start_loop(correlate_charge)
plt.plot(charge_1, charge_2, "o")
plt.xlabel("Charge 1 (nC)")
plt.ylabel("Charge 2 (nC)");
The two parameters timeout_seconds
and buffer_size
most likely do not have to be touched ever, because they
affect the internals of the synchronization backend and are adjusted properly.
In the following two code blocks, we demonstrate how configure the TrainAbo
with the both options start
and
elements
in order to read out only a limited range of data from a SPECTRUM
type. First we plot the entire array,
showing the bunch charge as a function of time separation, i.e. the charge along the
three electron beamlines at FLASH.
Then we use a TrainAbo
instance and read out only a certain
number of elements starting at a certain position and
plot the result.
readout = doocspie.get("FLASH_SIM.DIAG/TOROID/3GUN/CHARGE.TD")
plt.plot(doocspie.util.get_time_axis(readout), readout.data)
plt.xlabel("Time (\u03bcs)")
plt.ylabel("Charge (nC)");
addresses = {"FLASH_SIM.DIAG/TOROID/3GUN/CHARGE.TD": {"label": "charge",
"start": 875,
"elements": 200}}
train_abo = TrainAbo(addresses)
train_event = next(train_abo)
readout = train_event.get("charge")
plt.plot(doocspie.util.get_time_axis(readout), readout.data)
plt.xlabel("Time (\u03bcs)")
plt.ylabel("Charge (nC)");
The latter plot effectively presents the bunch charge along the FLASH2 electron beamline.
If the DOOCS properties of a particular server do not provide an appropriate event
number, i.e. it is either 0 or
static, the direct timestamp
attribute or a property from the meta
attribute can serve as an alternative event
number for the TrainAbo
instance. As similar to the start
and elements
options utilized in the previous code
example, the alternative events can be applied via the boolean timestamp_event
or the meta_event
string, either
in the configuration dict
or by using the add
method with the timestamp_event
and the meta_event
parameter. Possible values for these two parameters (options) are shown in
documentation about the get
method of
doocspie.io
.
TrainEvent
The previous section already dealt with instances of TrainEvent
,
and here we will cover it in a more detailed
manner. Its documentation, including the most relevant method get
, is
given below:
help(doocspie.abo.train_abo.TrainEvent)
Help on class TrainEvent in module doocspie.abo.train_event:
class TrainEvent(builtins.object)
| TrainEvent(readouts, properties)
|
| TrainEvent class for higher level synchronous readout from DOOCS.
|
| This class provides the train event for higher level synchronous readout from DOOCS.
|
| Methods defined here:
|
| __init__(self, readouts, properties)
| Constructor of the train event class.
|
| This constructor initializes the instance using the readouts and its related properties.
|
| Args:
| readouts (dict): The readouts for the related properties.
| properties (tuple): The properties related to the readouts.
|
| __str__(self)
| Special method to return a properly formatted string representation of the train event.
|
| get(self, property)
| Get the readout from the train event for the given property.
|
| Args:
| property (str): The property for the readout to get from the train event.
|
| Returns:
| Readout: An instance of the readout object for the requested property.
|
| Raises:
| DoocspieException: Doocspie related exception for non-existing property requested.
|
| ----------------------------------------------------------------------
| Readonly properties defined here:
|
| id
| int: The id of the current train event.
|
| properties
| tuple: The properties that can be returned via 'get'.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
As already carried out multiple times in the earlier section, we create a TrainAbo
instance and add two DOOCS
properties including a label, one during instantiation and the other by means of the
add
method. We do this simply
as a reminder of how adding properties can be realized. Once the TrainAbo
instance is set up, we call next
to
get a TrainEvent
instance, which gets printed:
addresses = {"TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER": {"label": "float"}}
train_abo = TrainAbo(addresses)
train_abo.add("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER", label="integer")
train_event = next(train_abo)
print(train_event)
TrainEvent(id=3524281, properties=('TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER', 'float', 'TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER', 'integer'))
The TrainEvent
instance contains the recorded DOOCS
properties, i.e. the address and optionally the corresponding
label, in its properties
attribute, and those are presented in the following:
for _property in train_event.properties:
print("property:", _property)
property: TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER
property: float
property: TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER
property: integer
The actual data that is recorded synchronously can be retrieved via the get
method,
which returns a Readout
instance (the standard way of representing data in doocspie), as is
demonstrated below:
print("TrainEvent's 'get' method returns a 'Readout':",
all(isinstance(train_event.get(_property), doocspie.doocspie.io.Readout)
for _property in train_event.properties))
TrainEvent's 'get' method returns a 'Readout': True
The id
attribute of the TrainEvent
instance represents the event number that all synchronously recorded DOOCS
properties share simultaneously. This is shown in the following code example by
comparing the id
with the event
of Readout
that is returned via get
for
each property:
print(" train event:", train_event.id)
for _property in train_event.properties:
print("property event:", train_event.get(_property).event)
train event: 3524281
property event: 3524281
property event: 3524281
property event: 3524281
property event: 3524281
Finally, we present the DoocspieException
message for not existing properties in the TrainEvent
:
try:
train_event.get("not existing")
except doocspie.DoocspieException as exc:
print("exception message:", exc.message)
exception message: readout for 'not existing' does not exist
Synchronizer
The synchronization backend of the TrainAbo
above is provided by the Synchronizer
class. This class provides an
interface that is very similar to the TrainAbo
and is presented below:
help(doocspie.abo.train_abo.Synchronizer)
Help on class Synchronizer in module doocspie.abo.synchronizer:
class Synchronizer(builtins.object)
| Synchronizer(properties=None, timeout_seconds=10, buffer_size=32, allow_zero_events=False)
|
| Synchronizer class for higher level synchronous readout from DOOCS.
|
| This class provides the synchronizer for higher level synchronous readout from DOOCS.
|
| Methods defined here:
|
| __init__(self, properties=None, timeout_seconds=10, buffer_size=32, allow_zero_events=False)
| Constructor of the synchronizer class.
|
| This constructor initializes the instance with optional parameters (see 'Args' below).
|
| Args:
| properties (tuple or dict, optional): The optional properties to get train events with readouts for.
| timeout_seconds (int): The optional timeout seconds for unsuccessful readout.
| buffer_size (int): The optional number of buffers to be used for storing previous readouts.
| allow_zero_events (bool, optional): The optional state for allow zero train events.
|
| __str__(self)
| Special method to return a properly formatted string representation of the synchronizer.
|
| add(self, address, label=None, offset=None, timestamp_event=None, meta_event=None, start=None, elements=None)
| Add address with optional parameters to the properties for synchronous readout.
|
| Args:
| address (str): The DOOCS address to add to the properties for synchronous readout.
| label (str, optional): Optional label for DOOCS address as a means for alternative property access.
| offset (int, optional): Optional offset to be applied on event numbers for synchronization.
| timestamp_event (bool, optional): Optional state to determine using the timestamp as an alternative event.
| meta_event (str, optional): Optional Meta property to replace the default event with.
| start (int, optional): Optional start position for reading out array-like types.
| elements (int, optional): Optional number of elements to read out for array-like types.
|
| Returns:
| None
|
| Raises:
| DoocspieException: Doocspie related exception for address duplication.
|
| get(self)
| Get the synchronous readouts mapped by its address or label for the particular properties.
|
| Returns:
| dict: The address (key) and readout (value) for the particular properties.
|
| Raises:
| DoocspieException: Doocspie related exception for synchronization timeout or no usable properties.
|
| get_event_matched_readouts(self)
| Get the event matched readouts mapped by its address or label for the particular properties.
|
| Returns:
| dict: The address (key) and readout (value) for the particular properties.
|
| get_label_of(self, source)
| Get the optional label of the given source.
|
| Args:
| source (str): The source to get the label for.
|
| Returns:
| str: The optional label of the given source.
|
| update(self)
| Update the newly added properties for synchronous readout.
|
| Returns:
| None
|
| ----------------------------------------------------------------------
| Readonly properties defined here:
|
| actual_properties
| tuple: The properties that can actually be readout.
|
| timeout_seconds
| int: The timeout seconds for unsuccessful readout.
|
| unusable_properties
| tuple: The properties that cannot be used for synchronized readout in the train abo.
|
| usable_properties
| tuple: The properties that can be used for synchronized readout in the train abo.
|
| zero_event_properties
| tuple: The properties that have an event number of 'zero'.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
In the earlier sections above, the features of the TrainAbo
have been demonstrated already. We further highlight the
capabilities of the synchronized readout by instantiating a Synchronizer
with a list
of
all charge and beam
position monitors at FLASH in the following code example:
from doocspie.abo import Synchronizer
addresses = [location + "/CHARGE.TD" for location in doocspie.ls("FLASH.DIAG/TOROID/*")]
addresses.extend([location + "/X.ALL" for location in doocspie.ls("FLASH.DIAG/BPM/*")])
synchronizer = Synchronizer(addresses)
print(synchronizer)
Synchronizer(timeout_seconds=10, buffer_size=32, allow_zero_events=False, actual_properties=('FLASH.DIAG/TOROID/1FL0UBC2/CHARGE.TD', 'FLASH.DIAG/TOROID/2FL0DBC2/CHARGE.TD', 'FLASH.DIAG/TOROID/3GUN/CHARGE.TD', 'FLASH.DIAG/TOROID/2FL0UBC1/CHARGE.TD', 'FLASH.DIAG/TOROID/8FL0DBC1/CHARGE.TD', 'FLASH.DIAG/TOROID/18ACC7/CHARGE.TD', 'FLASH.DIAG/TOROID/4TCOL/CHARGE.TD', 'FLASH.DIAG/TOROID/1ORS/CHARGE.TD', 'FLASH.DIAG/TOROID/4FL2EXTR/CHARGE.TD', 'FLASH.DIAG/TOROID/18FL2EXTR/CHARGE.TD', 'FLASH.DIAG/TOROID/1FL2SEED4/CHARGE.TD', 'FLASH.DIAG/TOROID/5FLFEXTR/CHARGE.TD', 'FLASH.DIAG/TOROID/7FLFMAFF/CHARGE.TD', 'FLASH.DIAG/TOROID/7FL2XTDS/CHARGE.TD', 'FLASH.DIAG/TOROID/7FL2DUMP/CHARGE.TD', 'FLASH.DIAG/TOROID/7FLFDUMP/CHARGE.TD', 'FLASH.DIAG/TOROID/2SDUMP/CHARGE.TD', 'FLASH.DIAG/TOROID/11SMATCH/CHARGE.TD', 'FLASH.DIAG/TOROID/12EXP/CHARGE.TD', 'FLASH.DIAG/TOROID/9DUMP/CHARGE.TD', 'FLASH.DIAG/BPM/1GUN/X.ALL', 'FLASH.DIAG/BPM/3GUN/X.ALL', 'FLASH.DIAG/BPM/2FL0UBC1/X.ALL', 'FLASH.DIAG/BPM/9ACC1/X.ALL', 'FLASH.DIAG/BPM/5FL0LAHE/X.ALL', 'FLASH.DIAG/BPM/1FL0DBC1/X.ALL', 'FLASH.DIAG/BPM/3FL0DBC1/X.ALL', 'FLASH.DIAG/BPM/5FL0DBC1/X.ALL', 'FLASH.DIAG/BPM/7FL0DBC1/X.ALL', 'FLASH.DIAG/BPM/10ACC2/X.ALL', 'FLASH.DIAG/BPM/10ACC3/X.ALL', 'FLASH.DIAG/BPM/2FL0UBC2/X.ALL', 'FLASH.DIAG/BPM/2FL0CBC2/X.ALL', 'FLASH.DIAG/BPM/3FL0CBC2/X.ALL', 'FLASH.DIAG/BPM/1FL0DBC2/X.ALL', 'FLASH.DIAG/BPM/3FL0DBC2/X.ALL', 'FLASH.DIAG/BPM/5FL0DBC2/X.ALL', 'FLASH.DIAG/BPM/9ACC4/X.ALL', 'FLASH.DIAG/BPM/9ACC5/X.ALL', 'FLASH.DIAG/BPM/9ACC6/X.ALL', 'FLASH.DIAG/BPM/11ACC7/X.ALL', 'FLASH.DIAG/BPM/8TCOL/X.ALL', 'FLASH.DIAG/BPM/3ECOL/X.ALL', 'FLASH.DIAG/BPM/5ECOL/X.ALL', 'FLASH.DIAG/BPM/2ORS/X.ALL', 'FLASH.DIAG/BPM/4ORS/X.ALL', 'FLASH.DIAG/BPM/7ORS/X.ALL', 'FLASH.DIAG/BPM/9ORS/X.ALL', 'FLASH.DIAG/BPM/12ORS/X.ALL', 'FLASH.DIAG/BPM/1SFUND2/X.ALL', 'FLASH.DIAG/BPM/1SFUND3/X.ALL', 'FLASH.DIAG/BPM/1SFUND4/X.ALL', 'FLASH.DIAG/BPM/1SFELC/X.ALL', 'FLASH.DIAG/BPM/1SMATCH/X.ALL', 'FLASH.DIAG/BPM/6SMATCH/X.ALL', 'FLASH.DIAG/BPM/13SMATCH/X.ALL', 'FLASH.DIAG/BPM/14SMATCH/X.ALL', 'FLASH.DIAG/BPM/5UND1/X.ALL', 'FLASH.DIAG/BPM/5UND2/X.ALL', 'FLASH.DIAG/BPM/5UND3/X.ALL', 'FLASH.DIAG/BPM/5UND4/X.ALL', 'FLASH.DIAG/BPM/5UND5/X.ALL', 'FLASH.DIAG/BPM/5UND6/X.ALL', 'FLASH.DIAG/BPM/3EXP/X.ALL', 'FLASH.DIAG/BPM/9EXP/X.ALL', 'FLASH.DIAG/BPM/9DUMP/X.ALL', 'FLASH.DIAG/BPM/10DUMP/X.ALL', 'FLASH.DIAG/BPM/13DUMP/X.ALL', 'FLASH.DIAG/BPM/15ACC7/X.ALL', 'FLASH.DIAG/BPM/19ACC7/X.ALL', 'FLASH.DIAG/BPM/1TCOL/X.ALL', 'FLASH.DIAG/BPM/6TCOL/X.ALL', 'FLASH.DIAG/BPM/4FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/5FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/8FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/11FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/13FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/15FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/18FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/21FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/22FL2EXTR/X.ALL', 'FLASH.DIAG/BPM/1FL2BC/X.ALL', 'FLASH.DIAG/BPM/6FL2BC/X.ALL', 'FLASH.DIAG/BPM/3FL2SEED3/X.ALL', 'FLASH.DIAG/BPM/3FL2SEED4/X.ALL', 'FLASH.DIAG/BPM/3FL2SEED5/X.ALL', 'FLASH.DIAG/BPM/3FL2SEED6/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE2/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE3/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE4/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE5/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE7/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE8/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE9/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE10/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE11/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE12/X.ALL', 'FLASH.DIAG/BPM/3FL2SASE13/X.ALL', 'FLASH.DIAG/BPM/3FL2BURN/X.ALL', 'FLASH.DIAG/BPM/3FL2XTDS/X.ALL', 'FLASH.DIAG/BPM/9FL2XTDS/X.ALL', 'FLASH.DIAG/BPM/5FL2DUMP/X.ALL', 'FLASH.DIAG/BPM/6FL2DUMP/X.ALL', 'FLASH.DIAG/BPM/10FL2DUMP/X.ALL'))
In contrast to the TrainAbo
,
the Synchronizer
provides a parameterless get
method that returns a Python
dict
with
all simultaneously recorded property addresses and Readout
instances. The current number of recorded
readout items and the readout’s dictionary itself is printed here:
readouts = synchronizer.get()
print("number of readouts:", len(readouts))
print("readout dictionary:", readouts)
number of readouts: 104
readout dictionary: {'FLASH.DIAG/TOROID/1FL0UBC2/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f207f0>, 'FLASH.DIAG/TOROID/2FL0DBC2/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f203a0>, 'FLASH.DIAG/TOROID/3GUN/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21030>, 'FLASH.DIAG/TOROID/2FL0UBC1/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22530>, 'FLASH.DIAG/TOROID/8FL0DBC1/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f20e50>, 'FLASH.DIAG/TOROID/18ACC7/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21150>, 'FLASH.DIAG/TOROID/4TCOL/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f204f0>, 'FLASH.DIAG/TOROID/1ORS/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21750>, 'FLASH.DIAG/TOROID/4FL2EXTR/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21360>, 'FLASH.DIAG/TOROID/18FL2EXTR/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f205b0>, 'FLASH.DIAG/TOROID/1FL2SEED4/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22380>, 'FLASH.DIAG/TOROID/5FLFEXTR/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f213f0>, 'FLASH.DIAG/TOROID/7FLFMAFF/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21b70>, 'FLASH.DIAG/TOROID/7FL2XTDS/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21e40>, 'FLASH.DIAG/TOROID/7FL2DUMP/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21f90>, 'FLASH.DIAG/TOROID/7FLFDUMP/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21a50>, 'FLASH.DIAG/TOROID/2SDUMP/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22050>, 'FLASH.DIAG/TOROID/11SMATCH/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21d80>, 'FLASH.DIAG/TOROID/12EXP/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21cc0>, 'FLASH.DIAG/TOROID/9DUMP/CHARGE.TD': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21870>, 'FLASH.DIAG/BPM/1GUN/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f226e0>, 'FLASH.DIAG/BPM/3GUN/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f228f0>, 'FLASH.DIAG/BPM/2FL0UBC1/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f225f0>, 'FLASH.DIAG/BPM/9ACC1/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22cb0>, 'FLASH.DIAG/BPM/5FL0LAHE/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f223e0>, 'FLASH.DIAG/BPM/1FL0DBC1/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22b00>, 'FLASH.DIAG/BPM/3FL0DBC1/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f222f0>, 'FLASH.DIAG/BPM/5FL0DBC1/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f21ae0>, 'FLASH.DIAG/BPM/7FL0DBC1/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f229b0>, 'FLASH.DIAG/BPM/10ACC2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22320>, 'FLASH.DIAG/BPM/10ACC3/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f230d0>, 'FLASH.DIAG/BPM/2FL0UBC2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f23070>, 'FLASH.DIAG/BPM/2FL0CBC2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22f80>, 'FLASH.DIAG/BPM/3FL0CBC2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f237c0>, 'FLASH.DIAG/BPM/1FL0DBC2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22fb0>, 'FLASH.DIAG/BPM/3FL0DBC2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f23610>, 'FLASH.DIAG/BPM/5FL0DBC2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22ec0>, 'FLASH.DIAG/BPM/9ACC4/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f23460>, 'FLASH.DIAG/BPM/9ACC5/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22dd0>, 'FLASH.DIAG/BPM/9ACC6/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3a4074c0>, 'FLASH.DIAG/BPM/11ACC7/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3a407f70>, 'FLASH.DIAG/BPM/8TCOL/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3a406f50>, 'FLASH.DIAG/BPM/3ECOL/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3a407250>, 'FLASH.DIAG/BPM/5ECOL/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3a406e60>, 'FLASH.DIAG/BPM/2ORS/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3a405e70>, 'FLASH.DIAG/BPM/4ORS/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3a405ea0>, 'FLASH.DIAG/BPM/7ORS/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3a4061d0>, 'FLASH.DIAG/BPM/9ORS/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302fc40>, 'FLASH.DIAG/BPM/12ORS/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302ed70>, 'FLASH.DIAG/BPM/1SFUND2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302ce50>, 'FLASH.DIAG/BPM/1SFUND3/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302cdf0>, 'FLASH.DIAG/BPM/1SFUND4/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302dc30>, 'FLASH.DIAG/BPM/1SFELC/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302fdf0>, 'FLASH.DIAG/BPM/1SMATCH/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f460>, 'FLASH.DIAG/BPM/6SMATCH/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302e1a0>, 'FLASH.DIAG/BPM/13SMATCH/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302da80>, 'FLASH.DIAG/BPM/14SMATCH/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f7f0>, 'FLASH.DIAG/BPM/5UND1/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302cfa0>, 'FLASH.DIAG/BPM/5UND2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302ef50>, 'FLASH.DIAG/BPM/5UND3/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f2b0>, 'FLASH.DIAG/BPM/5UND4/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302e770>, 'FLASH.DIAG/BPM/5UND5/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302ccd0>, 'FLASH.DIAG/BPM/5UND6/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302cf10>, 'FLASH.DIAG/BPM/3EXP/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302cd00>, 'FLASH.DIAG/BPM/9EXP/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d0c0>, 'FLASH.DIAG/BPM/9DUMP/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302dc90>, 'FLASH.DIAG/BPM/10DUMP/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d5d0>, 'FLASH.DIAG/BPM/13DUMP/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d510>, 'FLASH.DIAG/BPM/15ACC7/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f490>, 'FLASH.DIAG/BPM/19ACC7/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302e680>, 'FLASH.DIAG/BPM/1TCOL/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f7c0>, 'FLASH.DIAG/BPM/6TCOL/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302fe20>, 'FLASH.DIAG/BPM/4FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f070>, 'FLASH.DIAG/BPM/5FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d210>, 'FLASH.DIAG/BPM/8FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d3c0>, 'FLASH.DIAG/BPM/11FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d990>, 'FLASH.DIAG/BPM/13FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f9d0>, 'FLASH.DIAG/BPM/15FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302e410>, 'FLASH.DIAG/BPM/18FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d5a0>, 'FLASH.DIAG/BPM/21FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302cee0>, 'FLASH.DIAG/BPM/22FL2EXTR/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f430>, 'FLASH.DIAG/BPM/1FL2BC/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f310>, 'FLASH.DIAG/BPM/6FL2BC/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d360>, 'FLASH.DIAG/BPM/3FL2SEED3/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302e3e0>, 'FLASH.DIAG/BPM/3FL2SEED4/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d870>, 'FLASH.DIAG/BPM/3FL2SEED5/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d840>, 'FLASH.DIAG/BPM/3FL2SEED6/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d180>, 'FLASH.DIAG/BPM/3FL2SASE2/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d0f0>, 'FLASH.DIAG/BPM/3FL2SASE3/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302d330>, 'FLASH.DIAG/BPM/3FL2SASE4/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302eb00>, 'FLASH.DIAG/BPM/3FL2SASE5/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f23c40>, 'FLASH.DIAG/BPM/3FL2SASE7/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f231f0>, 'FLASH.DIAG/BPM/3FL2SASE8/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f23040>, 'FLASH.DIAG/BPM/3FL2SASE9/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302de70>, 'FLASH.DIAG/BPM/3FL2SASE10/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f200d0>, 'FLASH.DIAG/BPM/3FL2SASE11/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f1c0>, 'FLASH.DIAG/BPM/3FL2SASE12/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f4f0>, 'FLASH.DIAG/BPM/3FL2SASE13/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302f100>, 'FLASH.DIAG/BPM/3FL2BURN/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302dea0>, 'FLASH.DIAG/BPM/3FL2XTDS/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f3302eaa0>, 'FLASH.DIAG/BPM/9FL2XTDS/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f20580>, 'FLASH.DIAG/BPM/5FL2DUMP/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f20be0>, 'FLASH.DIAG/BPM/6FL2DUMP/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f20490>, 'FLASH.DIAG/BPM/10FL2DUMP/X.ALL': <doocspie.doocspie.readout.Readout object at 0x7f3f32f22740>}
All the returned readouts correspond to the same unique event as is shown in the following:
unique_events = {readout.event for readout in readouts.values()} # using set comprehension
print("number of unique events:", len(unique_events))
number of unique events: 1
A Synchronizer
instance always returns readouts once
there is a new event, just like the TrainAbo
. For the
current number of properties, five subsequent event numbers are printed here:
for _ in range(5):
readouts = synchronizer.get()
print("event of property:",
list(readouts.values())[0].event) # all properties have the same event
event of property: 1966138771
event of property: 1966138772
event of property: 1966138773
event of property: 1966138774
event of property: 1966138775
If there are no usable properties for synchronization, a particular DoocspieException
will be raised:
synchronizer = Synchronizer() # trivially no usable properties for synchronization
try:
synchronizer.get()
except doocspie.DoocspieException as exc:
print("exception message:", exc.message)
exception message: no usable properties found
Duplicated property addresses and/or labels get caught before any readout can be returned:
synchronizer.add("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER")
synchronizer.add("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER.BUFFER", label="integer")
try:
synchronizer.add("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER")
except doocspie.DoocspieException as exc:
print("exception message:", exc.message)
try:
synchronizer.add("TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/INTEGER", label="integer")
synchronizer.update() # duplicated labels get checked after updating
except doocspie.DoocspieException as exc:
print("exception message:", exc.message)
exception message: address 'TEST.DOOCS/UNIT_TEST_SUPPORT/PY_DOOCS/FLOAT.BUFFER' already exists
exception message: label 'integer' already exists
The Synchronizer
can be configured exactly the same as the TrainAbo
, i.e. via list
/tuples
,
dict
or
by means of the add
method. It also accepts the label
,
offset
,
start
,
elements
,
timestamp_event
and meta_event
options, and we refer to the TrainAbo
section for examples.