Properties

Properties

Every model in Experimentor has a set of properties that define their state. A camera has, for example, an exposure time, a DAQ card has a delay between data points, and an Experiment holds global parameters, such as the number of repetitions a measurement should take.

In many situations, the parameters are stored as a dictionary, mainly because they are easy to retrieve from a file on the hard drive and to access from within the class. We want to keep that same approach, but adding extra features.

Features of Properties

Each parameter stored on a property will have three values: new_value, value, old_value, which represent the value which will be set, the value that is currently set and the value that was there before. In this way it is possible to just update on the device those values that need updating, it is also possible to revert back to the previously known value.

Each value will also be marked with a flag to_update in case the value was changed, but not yet transmitted to the device. This allows us to collect all the values we need, for example looping through a user interface, reading a config file, and applying only those needed whenever desired.

The Properties have also another smart feature, achieved through linking. Linking means building a relationship between the parameters stored within the class and the methods that need to be executed in order to get or set those values. In the linking procedure, we can set only getter methods for read-only properties, or both methods. A general apply function then allows to use the known methods to set the values that need to be updated to the device.

Future Roadmap

We can consider forcing methods to always act on properties defined as new/known/old in order to use that information as a form of cache and validation strategy.

license:MIT, see LICENSE for more details
copyright:2021 Aquiles Carattino
class experimentor.models.properties.Properties(parent: experimentor.models.models.BaseModel, **kwargs)[source]

Class to store the properties of models. It keeps track of changes in order to monitor whether a specific value needs to be updated. It also allows to keep track of what method should be triggered for each update.

all()[source]

Returns a dictionary with all the known values.

Returns:properties – All the known values
Return type:dict
apply(property, force=False)[source]

Applies the new value to the property. This is provided that the property is marked as to_update, or forced to be updated.

Parameters:
  • property (str) – The string identifying the property
  • force (bool (default: False)) – If set to true it will update the propery on the device, regardless of whether it is marked as to_update or not.
apply_all()[source]

Applies all changes marked as ‘to_update’, using the links to methods generated with :meth:~link

Links the properties defined as ModelProp in the models using their setters and getters.

fetch(prop)[source]

Fetches the desired property from the device, provided that a link is available.

fetch_all()[source]

Fetches all the properties for which a link has been established and updates the value. This method does not alter the to_update flag, new_value, nor old_value.

classmethod from_dict(parent, data)[source]

Create a Properties object from a dictionary, including the linking information for methods. The data has to be passed in the following form: {property: [value, getter, setter]}, where getter and setter are the methods used by :meth:~link.

Parameters:
  • parent – class to which the properties are attached
  • data (dict) – Information on the values, getter and setter for each property
get_property(prop)[source]

Get the information of a given property, including the new value, value, old value and if it is marked as to be updated.

Returns:prop – The requested property as a dictionary
Return type:dict

Link properties to methods for update and retrieve them.

Parameters:linking (dict) –

Dictionary in where information is stored as parameter=>[getter, setter], for example:

linking = {'exposure_time': [self.get_exposure, self.set_exposure]}

In this case, exposure_time is the property stored, while get_exposure is the method that will be called for getting the latest value, and set_exposure will be called to set the value. In case set_exposure returns something different from None, no extra call to get_exposure will be made.

to_update()[source]

Returns a dictionary containing all the properties marked to be updated.

Returns:props – all the properties that still need to be updated
Return type:dict

Unlinks the properties and the methods. This is just to prevent overwriting linkings under the hood and forcing the user to actively unlink before linking again.

Parameters:unlink_list (list) – List containing the names of the properties to be unlinked.
update(values: dict)[source]

Updates the values in the same way the update method of a dictionary works. It, however, stores the values as a new value, it does not alter the values stored. For updating the proper values use self.upgrade().

After updating the values, use self.apply_all() to send the new values to the device.

upgrade(values, force=False)[source]

This method actually overwrites the values stored in the properties. This method should be used only when the real values generated by a device are known. It will change the new values to None, it will set the value to value, and it will set the to_update flag to false.

Parameters:
  • values (dict) – Dictionary in the form {property: new_value}
  • force (bool) – If force is set to True, it will create the missing properties instead of raising an exception.