Models

Models

Models are a buffer between user interactions and real devices. Models should define at least some basic common properties, for example how to read a value from a sensor and how to apply a value to an actuator. Models can also take care of manipulating data, for example calculating an FFT and returning it to the user.

license:MIT, see LICENSE for more details
copyright:2020 Aquiles Carattino
class experimentor.models.models.BaseModel[source]

All models should inherit from this base model. It defines some basic methods and checks that prevent errors later at runtime.

_features

Dictionary-like object to store the properties of the model

Type:ExpDict
_actions

List-like object to store the available actions. It also stores a lock to prevent multiple actions to be triggered at the same time

Type:ExpList
_settings

Dictionary-like object where the settings are stored. This dictionary is also used to retrieve the latest known value of the setting.

Type:ExpDict
_signals

Dictionary-like object to store the signals of the model

Type:ExpDict
_subscribers

Dictionary-like object storing the subscribers to different signals arising from this model

Type:ExpDict
classmethod as_process(*args, **kwargs)[source]

Instantiate the model as a ProxyObject that will run on a separate process.

Warning

This is WORK IN PROGRESS and will remain so for the foreseeable future.

clean_up_threads()[source]

Keep only the threads that are alive.

create_context()[source]

Creates the ZMQ context. In case of wanting to use a specific context (perhaps globally defined), overwrite this method in the child classes. This method is called during the model instantiation.

create_publisher()[source]

Creates a ZMQ publisher. It will be used by signals to broadcast their information. There is a delay before returning the publisher to guarantee that it was properly initialized before actually using it.

Returns:
  • zmq.Publisher – Returns the initialized publisher
  • .. todo:: This method has a high chance of being converted to an Action in order to let it run in parallel
emit(signal_name, payload, **kwargs)[source]

Emits a signal using the publisher bound to the model. It uses the method BaseModel.get_publisher() to get the publisher to use. You can override that method in order to use a different publisher (for example, an experiment-based publisher instead of a model-based one.

Notes

If subscribers are too slow, a queue will build up on the publisher, which may lead to the model itself crashing. It is important to be sure subscribers can keep up.

Parameters:
  • signal_name (str) – The name of the signal is used as a topic for the publisher. Remember that in PyZMQ, topics are filtered on the subscriber side, therefore everything is always broadcasted broadly, which can be a bottleneck for performance in case there are many subscribers.
  • payload – It will be sent by the publisher. In case it is a numpy array, it will use a zero-copy strategy. For the rest, it will send using send_pyobj, which serializes the payload using pickle. This can be a slow process for complex objects.
  • kwargs – Optional keyword arguments to make the method future-proof. Rigth now, the only supported keyword argument is meta, which will append to the current meta_data being broadcast. For numpy arrays, metadata is a dictionary with the following keys: numpy, dtype, shape. For non-numpy objects, the only key is numpy. The submitted metadata is appended to the internal metadata, therefore be careful not to overwrite its keys unless you know what you are doing.
finalize()[source]

Finalizes the model. It only takes care of closing the publisher. Child classes should implement their own finalize methods (they get called automatically), and either close the publisher explicitly or use this method.

classmethod get_actions()[source]

Returns the list of actions stored in the model. In case this behavior needs to be extended, the method can be overwritten in any child class.

get_context()[source]

Gets the context. By default it is stored as a ‘private’ attribute of the model. Overwrite this method in child classes if there is need to extend functionality.

Returns:The context created with self.create_context()
Return type:zmq.Context
classmethod get_features()[source]

Returns the dict-like features of the model. If this behavior needs to be extended, the method can be overwritten by any child class.

get_publisher()[source]

Returns the publisher stored as a private attribute, and initialized during instantiation of the model. Consider overwriting it in order to extend functionality.

get_publisher_port()[source]

ZMQ allows to create publishers that bind to an available port without specifying which one. This flexibility means that we should check to which port the publisher was bound if we want to use it. See self.create_publisher() for more details.

Returns:The port to which the publisher is bound. A string of integers
Return type:str
get_publisher_url()[source]

Each publisher can run on a different computer. This method should return the URL in which to connect to the publisher.

Todo

Right now it only returns localhost, this MUST be improved

initialize()[source]
classmethod set_actions(actions)[source]

Method to store actions in the model. It is a convenience method that can be overwritten by child classes.

subscribers
class experimentor.models.models.ExpDict[source]
class experimentor.models.models.ExpList[source]
lock = <Lock(owner=None)>
class experimentor.models.models.ProxyObject(cls, *args, **kwargs)[source]

Creates an object that can run on a separate process. It uses pipes to exchange information in and out. This is experimental and not meant to be used in a real application. It is here as a way of documenting one of the possible directions.

Note

Right now we are using the multiprocessing pipes to exchange information, it would be useful to use the zmq options in order to have a consistent interface through the project.