PASSATA object oriented introduction

Most objects belong to one of two main categories: data objects and processing objects. Data objects hold static data used as input, output or intermediate data for the simulation (i.e. a ccd pixel frame or a phase screen). Processing objects perform calculations, and pass data objects around to communicate with each other. A few more specialized objects help in retrieving calibration data and control simulation timing.

Data objects

All simulation data is stored using data objects. The only special feature of data objects is that, in addition to holding their data, they also store the simulated time at which they were generated or updated. To do so, the routine that generates or updates the object must update the generation_time property passing the current simulation time. Every data object has a time() function that returns the last set time. Routines that use the object as input can thus judge whether the data is current, or how much time has passed since its generation. Basic objects are provided for simple scalar or array values, lists and dictionaries. Specialized data objects must derive from the base_data_obj class. Specialized objects may provide functions to manipulate their data like sum, subtraction, wavelength-based rescaling where applicable, etc.

Processing objects

All calculations is done in processing object. Each of these objects have several features:
  • Data inputs and outputs are implemented with data objects. Each processing objects defines one or more outputs, and receives object references for input data.
  • Processing is done in a procedure with the convential name trigger. This procedure has a single argument, the simulated time t, and will be called once for each increment of the simulated time.
  • Objects are configured using parameters, either from a configuration file or set in simulation code, as detailed below.
Output data is represented with a data object allocated in the processing object's _define structure. The processing object initializes the output data object as soon as it has enough information to do so, fills it with new data and timestamp in the _trigger procedure, and defines a function to return a reference to it.

Input data is not stored in the processing object. Since each input will be an output of some other object, the processing object will only receive a reference to it.

Processing of data is performed at discrete time intervals. At each time interval, the object's trigger procedure is called, with a single parameter t, which contains the currently simulated time. The object can act on the trigger, filling its data output objects, or can choose do to nothing if not enough time has passed (i.e. a processing object that produces output only once per second will do nothing until the t parameter has incremented by at least one second since the last time an output was generated). Reading of data inputs is always allowed, and their time() function can be used to check whether the data has been updated or not.

Configuration is done using parameters. Parameters are grouped into structures or dictionaries, each structure holding one or more parameters for a single object. Each parameter corresponds to a property and an entry in the configuration file. For example, an object with a parameter called "integration time" will implement a property called "integration_time" and the configuration structure will accept a definition like "integration time: 1.0". Usually the parameter will correspond to a single variable in the object __define structure.

The base object processing class implements an apply_params procedure that is automatically called after object creation. This procedure receives a structure or dictionary containing the object's parameters, and will execute a series of set_ calls to set their values.

Parameters are conventionally separated into static and runtime sets: the static set holds parameter that are rarely changed (i.e. the primary mirror diameter). The runtime set those that are likely to change at each simulation run (i.e. the source magnitude or seeing). Each set is written into its own file and can be loaded when necessary. Note that a set does not need to specify all object parameters: if a parameter is missing, the relevant set_* procedure will not be called, and the parameter will retain its previous value, or the default value if it was never set.

Setting up data transfer

USE properties instead of set/get

Once all processing objects have been created and parametrized, the data objects needed for data exchange have already been created inside the processing objects (see the definition of output data above). The remaining task is to connect each input data with the corresponding data output object.

Loop control

The loop_control object coordinates the simulation, incrementing the simulated time and calling each object trigger procedure at each increment (run method). Each processing object must be added to the loop control list (with the add method), and they will be triggered in that order. The simulation will stop when the simulated time has reached an end point, or when a stop condition is satisfied (i.e. a certain kind of data is produced or is equal to a certain value).

Calibration

Generation of calibration data can be implemented as a partial loop: to generate for example a slope offset frame, the relevant processing objects are created and connected as in a real simulation, and the loop started until the desired data has been produced. Any special configuration can be done with a runtime parameter file as in any other simulation run.

Time representation

In order to avoid rounding errors, time is represented with an integer value with 64 bits (IDL type long64). Time resolution is by default one nanosecond, and can be optionally changed when setting up the simulation. With the default resolution, the long64 type allows up to 9x10^9 seconds of simulated time (about three years). Note that all objects must agree on the time resolution, so changing the resolution after object creation is not allowed. All data and processing objects have a _time_resolution member and functions to convert from/to seconds.

Data storing

use the datastorage class

-- GuidoAgapito - 21 Aug 2018
Topic revision: r1 - 21 Aug 2018, GuidoAgapito
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding AOWiki? Send feedback