File: core_tutorial.rst

package info (click to toggle)
taurus 5.2.3-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 100,792 kB
  • sloc: python: 51,356; sh: 67; makefile: 12
file content (256 lines) | stat: -rw-r--r-- 9,066 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256

.. currentmodule:: taurus.core

.. _taurus-core-tutorial:

=====================
taurus core tutorial
=====================

The core has been designed to provide a model-based abstraction to the various
sources of data and/or control objects supported via the Taurus schemes (we use
the term "model" to refer to the model component in an MVC driven architecture).

A scheme is a plugin for Taurus that provides the glue between Taurus and a
given source of data and/or of objects that can be controlled. For example,
schemes exist for various control system libraries (such as
Tango_, or EPICS_) as well as for processing data (e.g. the
:mod:`taurus.core.evaluation` scheme).

Each scheme implements at least a Factory (derived from
:class:`taurus.core.TaurusFactory`) which provides Taurus model objects ,
for a given model name.

.. _model-concept:

Model concept
-------------

All Taurus Elements (Devices, Attributes, etc) are model objects with an
associated unique name. The model name is an URI (as defined in RFC3986_).

In practice, the URIs have the following form (for a complete and rigorous
description refer to RFC3986_):

[<scheme>:][<authority>][<path>][?<query>][#<fragment>]

Notes:

- The <authority>, if present, starts by '//'
- The <path>, if present, starts by '/' (except for relative URIs)

A model object (also referred to occasionally as Taurus Element) is an instance
of a class derived from one of :class:`taurus.core.TaurusAuthority`,
:class:`taurus.core.TaurusDevice`, :class:`taurus.core.TaurusAttribute`.


Examples of model names
-----------------------

Different schemes may choose different conventions to name the models that they
provide.

The following are some examples for the :mod:`taurus.core.tango` scheme:

The full Taurus model name for a Tango device `sys/tg_test/1` registered in
a Tango Database running on `machine:10000` is:

``tango://machine:10000/sys/tg_test/1``

Now, if we assume that:

  - ``tango`` is set as the default scheme and that
  - ``machine:10000`` is set as the default TANGO_HOST
  - and that ``tgtest1`` is set as an alias of ``sys/tg_test/1``

then the same Tango device could be accessed as:

``tgtest1``

In the case of Tango attributes, here are some equivalent examples given the
above assumptions:

``tango://machine:10000/sys/tg_test/1/double_scalar``,

``sys/tg_test/1/double_scalar``,

``tango:tgtest1/double_scalar``,

``tgtest1/double_scalar``

See :mod:`taurus.core.tango` for a more exhaustive description and more
examples related to Tango.

The following are some examples for the :mod:`taurus.core.evaluation` scheme:

An evaluation attribute that generates an array of dimensionless random
values when read:

``eval:rand(256)``

An evaluation attribute that applies a multiplication factor to an existing
tango attribute (and which is updated every time that the tango attribute
changes):

``eval:123.4*{tango:sys/tg_test/1/double_scalar}``

Or one that adds noise to a tango image attribute:

``eval:img={tango:sys/tg_test/1/short_image_ro};img+10*rand(*img.shape)``

And, by using custom evaluators, one can easily access virtually anything
available from a python module. For example, using the datetime module
to get today's date as a Taurus attribute:

``eval:@datetime.*/date.today().isoformat()``

See :mod:`taurus.core.evaluation` for a more exhaustive description and some
tricks with the Evaluation scheme and the custom evaluators.

Now an example for the :mod:`taurus.core.epics` scheme. The model name for the
EPICS process variable (PV) "my:example.RBV" is:

``epics:my:example.RBV``

Note that you can create your own schemes and add them to taurus (e.g., a
scheme to access your own home-brew control system). Some schemes that are in
our TO-DO list are:

- A scheme to access datasets in HDF5 files as Taurus attributes
- A scheme to access ranges of cells in a spreadsheet file as Taurus attributes
- A scheme to access column/row data in ASCII files as Taurus attributes
- A scheme to access data from mySQL databases as Taurus attributes
- A scheme to access Tango-archived data as Taurus attributes

model access
------------

Taurus users are encouraged to write code that is "scheme-agnostic",
that is, that it neither assumes the availability of certain schemes nor uses
any scheme-specific feature. For this, Taurus provides several high-level
scheme-agnostic helpers to obtain the Taurus Element associated to a given
model name:

- :func:`taurus.Authority`
- :func:`taurus.Device`
- :func:`taurus.Attribute`
- :func:`taurus.Object`

The first three helpers require you to know which type of Element (i.e.,
Attribute, Device or Authority) is represented by the model name. If you do not know that
beforehand, you can use :meth:`taurus.Object` which will automatically find the
type and provide you with the corresponding model object (but of course this is
slightly less efficient than using one of the first three helpers).

These helpers will automatically find out which scheme corresponds to the given
model and will delegate the creation of the model object to the corresponding
scheme-specific Factory. Therefore, the returned model object will be of a
specialized subclass of the corresponding Taurus generic Element and it
will expose the scheme-agnostic API plus optionally some scheme-specific
methods (e.g., :class:`taurus.core.tango.TangoDevice` objects provide all the
API of a :class:`taurus.core.TaurusDevice` but they also provide all the methods
from a :class:`PyTango.DeviceProxy`)

For example, obtaining the device model object for a TangoTest Device
can be done as follows::

    import taurus
    testDev = taurus.Device('sys/tg_test/1')

or, using :meth:`taurus.Object`::

    import taurus
    testDev = taurus.Object('sys/tg_test/1')

Also for example, obtaining the Taurus Attribute model corresponding to the
EPICS Process Variable called "my:example.RBV" is just::

    import taurus
    testDev = taurus.Attribute('epics:my:example.RBV')

Taurus also provides other helpers to access lower level objects for dealing
with models:

- :func:`taurus.Factory`
- :func:`taurus.Manager`

And also some useful methods to validate names, find out the element type(s)
for a given name and other related tasks:

- :func:`taurus.isValidName`
- :func:`taurus.getValidTypesForName`
- :func:`taurus.getSchemeFromName`


Advantages of accessing Tango via Taurus over PyTango
-----------------------------------------------------

If you are familiar with PyTango_ you may be asking yourself what is the real
advantage of using taurus instead of PyTango_ directly for accessing Tango
objects. There are actually many benefits from using taurus. Here is a list of
the most important ones.

*integration with other schemes*
    Taurus is not just Tango. For example, you can treat a Tango Attribute just
    as you would treat an EPICS attribute, and use them both in the same
    application.

*model unicity:*
    you may request the same model many times without performance hit, since
    taurus will give you the same object::

        >>> import taurus
        >>> sim1 = taurus.Device('sys/tg_test/1')
        >>> sim2 = taurus.Device('sys/tg_test/1')
        >>> print sim1 == sim2
        True

    Whereas in PyTango_ the same code always results in the construction of new
    DeviceProxy objects::

        >>> import PyTango
        >>> sim1 = PyTango.DeviceProxy('sys/tg_test/1')
        >>> sim2 = PyTango.DeviceProxy('sys/tg_test/1')
        >>> print sim1 == sim2
        False

*model intelligence:*
    taurus is clever enough to know that, for example, 'sys/tg_test/1'
    represents the same model as 'tango:SYS/Tg_TEST/1' so::

        >>> import taurus
        >>> sim1 = taurus.Device('sys/tg_test/1')
        >>> sim2 = taurus.Device('tango:SYS/Tg_TEST/1')
        >>> print sim1 == sim2
        True

*tango event abstraction:*
    taurus cleverly hides the complexities and restrictions of the tango event
    system. With taurus you can:

      - subscribe to the same event multiple times
      - handle tango events from any thread

    Some optimizations are also done to ensure that the tango event thread is
    not blocked by the user event handle code.

*tango subscription states:*
    In the following flow diagram you can see how the SubscriptionState changes:

    .. mermaid::
        :align: center
        :caption: SubscriptionState flow diagram

        flowchart TD
            n2["Unsubscribed"] --> n3["Subscribing"]
            n3 --> D{"subscribe_event\n(stateless=False)"}
            D -- "Success:\npush_event() callback" --> n4["Subscribed"]
            D -- "Exception:\nsubscribe_event(stateless=True)" --> n5["PendingSubscribe"]
            n5 -- "Tango Events Enabled:\npush_event()" --> n4
            n4 -- "Tango Events Disabled:\nEVENT_TO_POLLING_EXCEPTIONS\n(like API_PollObjNotFound)" --> n5


.. _Tango: http://www.tango-controls.org/
.. _PyTango: http://packages.python.org/PyTango/
.. _EPICS: http://www.aps.anl.gov/epics/
.. _RFC3986: https://tools.ietf.org/html/rfc3986