Introduction



Creative Commons License Sardana-Training by ALBA Synchrotron is licensed under the Creative Commons Attribution 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

Sardana VM (sardana-icalepcs2019.ova)

  • VM is a Debian Buster

    • it contains all Sardana Suite dependencies installed with the official Debian packages
    • some other tools which may be installed from PyPI
  • Run the VM

    • Import sardana-icalepcs2019.ova with VirtualBox (VirtualBox -> File -> Import Appliance)
    • Start the VM
    • Log in with user vagrant & password vagrant
  • If you want to recreate this VM, or just view it in details, please check the Vagrantfile

Sardana VM - last minute fixes

  • Either use the OVA from the USB or from here
  • Or try to fix it (requires Internet access):
    • Copy h5py and taurus_pyqtgraph from /root/.local/... to ~/.local/...:
      cd ~/sardana-training/
      git pull
      sudo ~/sardana-training/users/copy_modules
      python3 -c "import h5py"
      python3 -c "import taurus"
    • Install gevent and blender (optionally emacs and okular):
      sudo apt-get install -y python3-gevent blender
      sudo apt-get install -y emacs okular

We will follow the Sardana training materials (users)

Installation and configuration of Sardana system from scratch



Creative Commons License Sardana-Training by ALBA Synchrotron is licensed under the Creative Commons Attribution 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

Installation and configuration of Sardana system from scratch

  • How to install Sardana Suite?
    • Sardana and Taurus releases
    • Review dependencies
  • Create the workshop enviroment
    • Install Taurus and Sardana
    • Create and run Sardana server
    • Create profile and run Spock CLI
    • Create simulated environment and quick demo

Releases and latest code

Official releases

Taurus and Sardana aim to produce at least 2 official releases per year (in January and July) in PyPI. Additional installable files (.wheel, .msi, .deb, etc.) may also be released on GitHub.

The official releases are also pushed and tagged on the master branch of the official repositories.

Latest code

The latest code can be found in the develop branch of the repositories.

For more details and information on how to contribute, see the CONTRIBUTING.md files (taurus / sardana)

How to install Sardana Suite

Taurus

(don't execute the following commands)

  • Debian Packages
    apt-get install python-taurus
  • PyPI and pip
    # pip install taurus
    pip3 install taurus
  • For developers:
    git clone https://github.com/taurus-org/taurus.git
    # pip install -e ./taurus
    pip3 install -e ./taurus

Taurus dependencies

  • python 2.7 | >=3.5
  • numpy >=1.1
  • pint
  • taurus-epics
    • pyepics
  • taurus-h5file
    • h5py
  • taurus-tango
    • PyTango
  • taurus-pyqtgraph
    • pyqtgraph
  • taurus-qt
    • pyqt4 | pyqt5 | pyside1 | pyside2
    • lxml
    • guiqwt
    • ply
  • taurus-qt-editor
    • spyder >=3
  • Others:
    • pymca

How to install Sardana Suite

Sardana

(don't execute the following commands)

  • Debian Packages
    apt-get install python-sardana
  • PyPI and pip
    pip install sardana
  • For developers:
    git clone https://github.com/sardana-org/sardana.git
    pip3 install -e ./sardana

Sardana dependencies

  • python 3 (last official release still on python >= 2.6 and < 3)
  • lxml
  • PyTango >= 9.2.5 (last stable release >= 7.2.6)
    • itango
  • Taurus >= 4.5.4 (last stable release >= 3.6)
  • Others:
    • hkl
    • h5py

Create the workshop enviroment

Install Sardana Suite

  • Taurus installation
    pip3 install --user git+https://github.com/taurus-org/taurus.git@icalepcs2019
  • Sardana installation
    pip3 install --user git+https://github.com/sardana-org/sardana.git@icalepcs2019

Run and populate Sardana

  • The goal:

sardana

  • Instantiate the Sardana Tango Device Server:
    Sardana demo1 --log-level=debug

sardana_empty

Spock

  • CLI based on IPython
  • Single point of control - allows to execute macros and control elements
  • Allows to work with multiple profiles i.e. connecting to different doors
  • Run spock:
    spock
  • Populate sar_demo environment (in Spock):
    sar_demo

Macros and quick demo

  • Sardana macro catalog

    lsdef
    lsa
  • motion example:

    umv mot01 20
  • acquisition example:

    uct 2 ct01
  • scan example:

    ascan?
    ascan mot01 0 10 10 0.1

TAURUS GUI CREATION FROM SCRATCH



Creative Commons License Sardana-Training by ALBA Synchrotron is licensed under the Creative Commons Attribution 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

Prerequisites

Start TangoTest device server

  • open a new konsole and run:
    /usr/lib/tango/TangoTest test

Assumes sar_demo environment running

TAURUS GUI CREATION

Create a Taurus GUI from scratch containing Sardana elements

TAURUS GUI CREATION FROM SCRATCH

  • Create a new GUI with taurus newgui

    taurus newgui
  • Follow the wizard of taurus newgui

    • Choose the project directory (e.g: /home/vagrant/demogui)
    • Choose GUI name (e.g: demogui)
    • Add synoptic (optional): /home/vagrant/sardana-training/users/res/demoBL.jdw
    • Enable Sardana communication (optional) select: MacroServer - MacroServer/demo1/1 and Door - Door/demo1/1
    • Generate panels from Sardana Pool (optional): choose yes
    • We will skip some steps: custom logo, extra panels, Monitor list

TAURUS GUI INSTALLATION AND LAUNCH

  • Install the freshly created Taurus GUI:

    pip3 install --user /home/vagrant/demogui
  • Congratulations! You can already run your freshly created GUI:

    demogui
    • Enable JSONRecorder pop-up.

TAURUS GUI FEATURES

Playing with demogui: Adding panels, loading perspectives, etc.

TAURUS GUI FEATURES - first customizations

  • Maximize the GUI and unlock the view': View -> Lock View
  • Check the panels that have been automatically created:
    • Manual
    • Sardana macros panels (Experiment Config, Macros, Sequences, MacroDescription, DoorOutput, DoorDebug, DoorResult)
    • Synoptic (demoBL)
    • Sardana Instrument panels (/monitor, /slit, /mirror)
  • Reorder the panels for "macro execution" work:
    • close (hide) all panels except the macros related panels
    • reorder the panels so in a way that is appropriate to launch and monitor macros (e.g. tabbing on together on one side Macros+Sequencer+Expconf and on the other side MacroDescription above and all Door* panels tabbed below)

TAURUS GUI FEATURES - explore and execute macros

  • Go to the ExperimentConfiguration panel, first switch to the "Simple View" (from the context menu) and then enable plotting ct1 and ct2
    • (Use Plot : Spectrum, PlotAxes: <mov> and don't forget to Apply)
    • (More features of this widget to be explained in a later session)
  • Go to the Macros panel
    • select ascan macro (note that the description appears in the MacroDescription Panel)
    • fill the parameters (the same as in the scan run in Spock)
      • Note that the existing moveables are offered for the first parameter
      • Note that the command is shown in the yellow line
    • Run the macro ascan
      • Note the led indicating that the door changed to running state
      • Note that a Trend Panel appears (it may be hidden in a tab)
      • Put it in a visible place and re-run the macro to show the online plot & the door output simultaneously
      • Note that the macro was stored in the history and that it can be marked as "favourite"
      • Re-run the scan and try to stop, pause and resume it
  • Save a perspective called macros

TAURUS GUI FEATURES - interact with instruments using synoptic (I)

  • Reorder the widgets for "interaction with instruments":
    • Go to Panels -> hide all panels
    • Click on the "demoBL" button in the toolbar to show the synoptic panel
    • Click on the "mirror" instrument in the synoptic (the area below "DCM"). This should show the "/mirror" panel
    • move the "mirror" panel above the synoptic
    • Click on the slits in the synoptics (labelled "diagnostics" in the synoptic). This should show the "/slits" panel. Move it to a tab together with "/mirror"
    • Click on the monitor in the synoptics (labelled "FSM4" in the synoptic). This should show the "/monitor" panel. Move it to a tab together with "/mirror" and "/slits"
    • Show the 2-ways communication between panels and synoptics:
      • Click on the active areas of the synoptics and show that the corresponding panels are shown
      • Select the panels and see that the synoptic highlights the corresponding area

TAURUS GUI FEATURES - interact with instruments using synoptic (II)

  • Move the mot01 and gap01 motors in the "/slit" panel using the motor widget
    • note the changing state of physical and pseduo motors
    • show absolute and relative mode of move
    • stop button and attributes dialogue (context menu -> Tango Attributes)
  • Save a perspective called instruments
  • Switch back and forth perspectives macros and instruments

TAURUS GUI FEATURES - add and modify custom panels (I)

  • Open the "/slit" panel. Note that it cannot be modified by the user, because it is auto-created based on sardana config
  • Create a friendlier slits panel:
    • Use New Panel button
    • Select TaurusForm and use name "myslit" and click "Finish"
    • Drag and drop "gap01" and "offset01" from "/slit" to "myslit"
    • Hide buttons of "myslit" panel (Uncheck "Show buttons" in the context menu)
    • Set compact mode in "myslit" panel (In the context menu)
    • Associate the synoptic to the new panel:
      • Go to Tools Menu --> "Manage instrument-panel associations" -> Associate Instrument /slit with panel myslit --> OK
    • Close (hide) the "/slits" panel and place the "myslit" panel in its place
    • check that now the synoptic is 2-way associated with the myslit panel

TAURUS GUI FEATURES - add and modify custom panels (II)

  • Hide all panels
  • Create a Tango DB tree panel:
    • Use New Panel button
      • Select TaurusDBTreeWidget and use name db
      • Click on "Advanced Settings" and set tango://buster.localdomain:10000 as model and click on finish
  • Create a Plot panel:
    • Use New Panel button
      • Select TaurusPlot and use name plot and click on finish
  • Create a Form panel:
    • Use New Panel button
      • Select TaurusForm and use name form and click on finish
  • Make sure that the "db" and "form" and "plot" panels are all simultaneously visible
  • Add a new element to the "form" form panel:
    • Navigate in the db panel to sys/tg_test/1/ampli, and drag and drop it into "form".
    • Navigate in the db panel to sys/tg_test/1/boolean_scalar, and drag and drop it into "form"
    • Navigate in the db panel to sys/tg_test/1/wave, and drag and drop it into "plot"

TAURUS GUI FEATURES - add and modify custom panels (III)

  • Further customize "form"
    • self drag&drop ampli to create a duplicated display of "ampli"
    • right-click label of "ampli" -> Change write Widget -> TaurusWheelEdit
    • right click label of "ampli" and select Change label to "voltage" Note that this is a change at the widget level
    • right-click label of "voltage" and select "Configurations->All" and set unit to "millivolts" and exit config dialog.
      Note that this is a change at the Tango Attribute level!
      Don't worry about the error message. It warns about change of the attribute's value from dimensionles to millivolts.
    • Note the units support:
      • both "ampli" and "voltage" now display "mV"
      • if you use the line edit of "voltage" to write 1V, the value will change to 1000 mV in both "ampli" and "voltage"

Macros: scans, data acquisition and storage



Creative Commons License Sardana-Training by ALBA Synchrotron is licensed under the Creative Commons Attribution 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

Contents

  • MacroServer overview
  • MeasurementGroup overview
  • Generic Scan Framework
  • Recorders

MacroServer overview

  • Is a controlled environment to run procedures, called macros, sequentially or simultaneously (using multiple entry-points called Doors)
  • Provides a standard catalogue of procedures.
  • Macros syntax is inspired on the SPEC control system syntax
  • Allows to plug in new/custom procedures written as Python functions or classes
  • Connects to device Pool(s) and allows to act on their elements from within macros

MeasurementGroup overview

  • MeasurementGroup is a high level element whose role is to:
    • coordinate a complex measurement process
    • provide a simplified interface to it
  • Run uct macro (in Spock):
    uct
  • Open expconf (in Spock):
    expconf
  • Disable some channels in the expconf e.g. ct02 and ct04 (Enabled column -> False) and run ct macro (in Spock):
    ct
  • Briefly review other configuration parameters
  • Add 1D channel oned01 in expconf (Add channel + button), apply changes and run ct macro
  • Create new measurement group using the defmeas macro and run ct afterwards (in Spock):
    defmeas mntgrp02 ct01 twod01
    ct
    • Note the external changes pop-up.
  • Change active measurement group in expconf and run ct macro

Generic Scan Framework (GSF)

Deomnstration of different scanning and synchronization modes

Demonstration of different scanning and synchronization modes - preparation

  • Precise software synchronized continuous scans require intensive monitoring loops. Increase the frequency of position checks (in Spock) and restart the Sardana server:
    Pool_demo1_1.put_property({"MotionLoop_StatesPerPosition":"1"})
  • Start taurustrend with high frequency of polling:
    taurus tpg trend mot01/position "eval:int(bool({ct01/state}))"
    • Configure Forced read period of 10 ms
    • Configure fill area of the state curve and move it to y2 axis in Plot configuration

Demonstration of different scanning and synchronization modes - demo

  • Demonstrate step scan in Spock:
    ascan mot01 0 10 10 1
  • Demonstrate continuous scan with no latency time in Spock:
    ascanct mot01 0 10 10 1
  • Demonstrate continuous scan with 100 ms latency time (in spock):
    ascanct mot01 0 10 10 1 0.1
  • Configure hardware synchronization for ct01 in expconf (Synchronizer column -> tg01) and execute the scan without latency time:
    ascanct mot01 0 10 10 1
    • Note about cooexistence of software and hardware synchronization modes in the same scan
    • Note the continuous moving state of the ct01

Generic Scan Framework (GSF)

  • Scanning modes: step, continuous and time
  • Provides the catalogue of turn-key scan macros e.g., ascan, dscan, a2scanc, ascanct, mesh, timescan, etc.
  • Provides the base classes for developing custom scans e.g., GScan, SScan, CScan, etc.
  • Custom scans are developed by instantiating the base class and developing a custom generator
  • Scans are highly configurable with the environment variables e.g. ActiveMntGrp, ScanFile, ApplyInterpolation
  • Scans macros support hooks e.g. pre-scan, post-acq

Recorders - demo

Demonstrate recorder selection based on the file extension

  • Start expconf (in Spock):
    expconf
  • In expconf Storage tab set scan file to test.h5 and directory to /tmp (equivalent in Spock with senv ScanFile test.h5 and senv ScanDir /tmp)
  • Execute a scan (in Spock):
    ascan mot01 0 2 2 0.1
  • Access to the data with silx:
    silx view
  • Close the silx

How to write macros



Creative Commons License Sardana-Training by ALBA Synchrotron is licensed under the Creative Commons Attribution 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

Macro function vs. macro class

Function

  • For programmers with background on a functional language (e.g. Fortran, Matlab, SPEC)
  • Sequencial procedures to run an experiment

Class

  • For proammers with background on object-oriented languages (e.g. Java, C++, C#)
  • Overriding an existing macros (e.g. inherit from mv macro and extend its funcionality)
  • Some advanced features require use of classes e.g. define hook places or mandatory environment variables

Macro plugins discovery

  • Sardana built-in macros are importable from sardana.macroserver.macros
  • The plugin discovery system is based on directory scanning and python module inspection
  • Custom macros should be installed in one of the MacroPath directories:
    • Create macros directory:
      mkdir /home/vagrant/macros
    • Configure MacroPath (in Spock):
      _MACRO_SERVER.put_property({"MacroPath":["/home/vagrant/macros", "/home/vagrant/.local/lib/python3.7/site-packages/sardana/macroserver/macros/examples"]})
    • Restart the Sardana server
  • The path order is important! Macros in the higher position paths will take precedence over the lower position paths.

Macro development tools

  • edmac <macro_name> [<module_name>]
  • relmac, relmaclib, addmaclib, rellib
  • www, post_mortem
  • debug on|off

Hello world

  • Create hello_world macro (in Spock):
    edmac hello_world mymacros
    • Implement a function decorated with macro decorator that can be found in sardana.macroserver.macro
    • Use self.output() to print something...
    • Exit from editor and apply changes on the server [y]
  • Run hello_world macro (in Spock):
    hello_world
In [2]:
from sardana.macroserver.macro import Macro, macro, Type

@macro()
def hello_world(self):
    """Macro hello_world"""
    self.output("Running hello_world...")

MACRO FEATURES

Logging in macros

  • Macros may log messages to various destinations
    • Spock or other clients
    • Macro logging/reporting feature
    • MacroServer log files
  • Different log levels are possible e.g. output, error, debug

Logging in macros - demo

  • Edit hello_world macro and add a self.info("How are you?")
    edmac hello_world
    • Note about change of the color in Spock
  • wa (table view)
  • umv mot01 100 (update block view)

Macro parameters

  • Benefits
    • The parameters validation prevents runtime errors
    • Spock offers autocompletion facilities
    • Autogenerated documentation

Macro parameters

  • Parameters are defined either as arguments of the macro decorator for the macro function or as param_def class member for the macro class
  • A parameter is characterized by: name, type, default value and description
  • Parameter values arrives as positional arguments to the macro function or to the run method of the macro class

Macro parameters - demo

  • Open ~/macros/mymacros.py module with an external editor e.g.
    kwrite ~/macros/mymacros.py
  • Develop a new macro: move
  • Add two macro parameters according to the Adding macro parameters documentation
    • moveable of type Moveable
    • position (to move) of type Float
  • Move the motor to the position according to the Moveable API (moveable.move(position))
  • Apply the new code on the server using the relmaclib macro (in Spock)
    relmaclib mymacros
  • Show the macro help (in Spock):
    move?
  • Continue developing your macro to print the motor position (moveable.getPosition())
  • Apply the new code on the server using the relmac macro macro (in Spock)
  • Run move macro (in Spock):
    move mot01 10
In [ ]:
@macro([["moveable", Type.Moveable, None, "moveable to move"],
        ["position", Type.Float, None, "absolute position"]])
def move(self, moveable, position):
    """This macro moves a moveable to the specified position"""
    moveable.move(position)
    self.output("{} is now at {}".format(moveable.getName(), moveable.getPosition()))

Macro parameters - repeat parameters

  • Allows to pass as parameter value a list of repetitions of the repeat parameter member(s)
  • Repeat parameters allow to:
    • restrict the minimum and/or maximum number of repetitions
    • nest repeat parameters inside of another repeat parameters
    • define multiple repeat parameters in the same macro

Macro parameters - repeat parameters - demo

  • prdef pt4
  • pt4 mot01 mot02

Macro results

  • Allows to pass the macro result to the clients (string representation) and to the wrapper macro
  • Results are defined as the result_def class member of the macro class
  • A result is characterized by: name, type, default value and description - exactly the same as macro parameter
  • Multiple results are possible

Macro results - demo

  • prdef twice
  • twice 2

Macro data

  • Allows to pass the macro data to the clients (serialized with pickle) and to the wrapper macro
  • Data format is totally opened

Macro data - demo

  • Execute macro twice: twice 3
  • Access macro data in Spock with: macrodata
  • Execute scan: ascan mot01 0 10 2 0.1
  • Access macro data with in Spock with: macrodata

Sequencing and nesting macros

  • Programmatically
    • Macros can call other macros, and these other macros can call another macros, and so on...
    • The easiest way to program execution of a macro from wihin another macro is to use the macro context: edmac hello_world and add self.lsm()

Sequencing and nesting macros

  • Graphically using sequencer:
    • Open demogui and show Sequencer panel
    • Add macros to the sequence e.g. lsm, wa and ascan and fill their parameters
    • Start the sequence execution, stop it, pause it, etc..
    • Save the sequence to a file and open it back
    • Don't close sequencer

Hooks

  • Python code that will be executed at given points of the macro
  • Can be a Python callable or a macro
  • Hooks can be attached to the hook places that defines macros
  • Macro must inherit from Hookable class to allow hook places
  • Hook places are defined and handled by the macro in the code
  • Exists three possibilities to attach hooks to the macros:
    • configuring general hooks - using the lsgh, defgh, udefgh.
    • programatically - using the Hookable class API (it requires defining a wrapper macro)
    • graphically - using the sequencer widget

Hooks - sequencer

  • Edit the sequence using the arrow buttons and nest the wa macro in the ascan
  • Set its hook place to pre-acq from the context menu

Hooks - programatically

  • Demonstrate programatic usage of hook (in Spock, line by line):
    prdef loop
    loop 0 10 1
    prdef captain_hook
    captain_hook 0 10 1

General Hooks - demo

  • Demonstrate usage of Geneal Hooks (in Spock, liny by line):
    lsgh
    defgh "wm mot01" pre-acq
    ct
    udefgh "wm mot01"
    ct

Interactive macros

  • Macros can ask for user input
  • Macro must be declared as interactive e.g. imacro decorator or interactive class member set to True
  • The user input request may be characterized with: type, default value, title, unit, label, range, ...
  • Spock may handle user input request either in the CLI or GUI mode - see SPOCK_INPUT_HANDLER in the sardana.sardanacustomsettings

Interactive macros - demo

  • Demonstrate interactive macros (in Spock, line by line):
    prdef ask_number_of_points
    ask_number_of_points

Ploting in macros

  • Macro send request to plot to the client e.g. spock
  • Uses matplotlib.pyplot framework API e.g. pyplot.plot

Ploting in macros - demo

  • Demonstrate plotting in macros (in Spock, line by line):
    prdef random_image
    random_image

Interrupting macro execution

  • Macros can be stopped, aborted or paused
  • As soon as the user requested the macro interruption the macro will get interrupted on the next call of checkPoint (or pausePoint) or any of the macro API method (Macro class methods decorated with mAPI)
  • Long sleeps should be interleaved with check points
  • Macro may define on_stop, on_abort and on_pause method that will be called on the corresponding interruption
  • Macro reserved object, for example requested with the getMotion method (getMotor will not reserve the motor object!), are stopped/aborted on the corresponding interruption (before calling the on_stop/on_abort method)

Reporting macro progress

  • Macros may report their progress while are executed
  • The progress is usually expressed in percentage 0 - 100 %
  • The progress update is done using the yield statement within the run method

Macro environment

  • Key-value store accessible from macros and clients
  • Stored persistently
  • API: getEnv and setEnv or simply senv macro
  • Different levels: Global, Door, Macro
  • Example (in Spokc, line by line):
    senv ActiveMntGrp mntgrp01
    ct

MACROBUTTON

A GUI button to execute a single macro

MACROBUTTON: A GUI button to execute a single macro

  • macrobutton is a Widget button allowing execution of a single macro
  • It can be integraged in Qt GUIs
  • It allows:
    • Running macro: by clicking once
    • Interrupting a macro: by clicking again
      • It is possible to abort the macro
      • It is possible to continue with the execution
    • To see the macro progress

MACROBUTTON: A GUI button to execute a single macro -> DEMO

Execute the macrobutton code, which in this case executes the 'lsm' macro

  • macrobutton executing an lsm macro:

    python3 ~/sardana-training/res/macrobutton/macrobutton_lsm.py
  • macrobutton executing an ascan macro:

    python3 ~/sardana-training/res/macrobutton/macrobutton_scan.py

MACROBUTTON: BL13-Xaloc ALBA Beamline Use Case

BL13-Xaloc Beamline uses Macrobuttons in a TaurusGUI for focusing the sample image and for looking for the best diffraction position on the sample

BL13-Xaloc GUI with Macrobuttons

Motion controllers



Creative Commons License Sardana-Training by ALBA Synchrotron is licensed under the Creative Commons Attribution 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

Contents

  • Writing controller - general
  • Writing motor controller - Blender blades
  • Pseudomotor basics - Slit controller

Before writing a new controller

  • Before writing a new controller check in the catalogue if someone already wrote a similar one
  • If not, it does not harm to ask on one of the communication channels e.g. mailing list, github issue, etc.

Controller plugins discovery

  • Sardana built-in controllers are importable from sardana.pool.poolcontrollers
  • The plugin discovery system is based on directory scanning and python module inspection
  • Custom controllers should be installed in one of the PoolPath directories:
    • Create /controllers directory:
      mkdir ~/controllers
    • In spock configure PoolPath:
      Pool_demo1_1.put_property({"PoolPath":["/home/vagrant/controllers"]})
    • Restart the Sardana server
  • The path order is important! Controllers in the higher position paths will take precedence over the lower position paths.

Blender Blades Motor Controller

  • Open the code with your favourite editor e.g.:
    kwrite ~/sardana-training/controllers/templates/BlenderBladesMotorCtrl.py

Blender Blades Motor Controller

  • Install Blender Slits system:
    pip3 install --user ~/sardana-training/blender-slits
  • Start the blnder simulation:
    blender-slits-server
  • Blender Blades system (NOT PART OF SARDANA):
    • Communication protocol is explained in: ~/sardana-training/blender-slits/README.md
    • Directions are in the hardware coordinate system
    • Positions are not calibrated in the local coordinate system - beam axis is not the zero!

Writing constructor

  • Constructor
    • Called on: controllers creation, pool startup and controller's code reload
    • Accepts arguments: instance (name of the controller instance) and properties (dictionary with the controller properties)
    • If an exception is raised when constructing the controller, the controller automatically gets into the Fault state and its status describes the exception that occured
  • Define controller properties: host and port
  • Instantiate BlenderBlades in the constructor

Instantiate controller

  • Deploy controller:
    ln -s ~/sardana-training/controllers/templates/BlenderBladesMotorCtrl.py ~/controllers
  • Load it in the system (in Spock):
    addctrllib BlenderBladesMotorCtrl
  • Check if the controller library was corectly loaded (in Spock):
    lsctrllib
  • Create an instance of the controller (in Spock):
    defctrl BlenderBladesMotorController bleblactrl
  • Ask for controllers state (in Spock):
    bleblactrl.state()

Implement StateOne

  • Get axis state (State sequence)
    • Applies only to the to physical elements
    • Called on: state request, during operations e.g. motion, acquisition
    • Returns: state and optionally status, if no status is returned, it will be composed by Sardana from the state (in case of motor also returns limit switches)
    • If an exception is raised when reading the state, the axis automatically gets into the Fault state and the status contains the exception details.

Implement StateOne

  • Implement AXIS_NAMES class member for quick lookup to motor identifiers
  • Implement AXIS_ID and VALUE class members for refering to the corresponing part of the answer
  • Implement method by quering ?state <axis id>

Implement ReadOne

  • Implement method by quering ?pos <axis id>

Instantiate top motor

  • Reload controller code (in Spock):
    relctrlcls BlenderBladesMotorController
  • Create motor instance (in Spock):
    defelem top bleblactrl 1
  • Ask for motor state (in Spock):
    top.state()
  • Ask for motor position (in Spock):
    top.position
    or
    wm top

Implement StartOne

  • Implement method by commanding <axis id> <pos>

Move top motor

  • Reload controller code (in Spock):
    relctrlcls BlenderBladesMotorController
  • Ask motor to move (in Spock):
    umvr top 10

Implement AbortOne

  • Implement method by commanding abort

Move and abort top motor

  • Reload controller code (in Spock):
    relctrlcls BlenderBladesMotorController
  • Ask motor to move (in Spock):
    umvr top 50
  • Issue Ctrl+C in Spock

Implement standard axis attributes

  • Implement GetAxisPar method
    • Implement velocity by querying ?vel <axis id>
    • Implement acceleration by querying ?acc <axis id>
    • Implement deceleration by querying ?dec <axis id>
    • Hardcode base_rate to 0
    • Hardcode steps_per_unit to 1

Read standard axis attributes

  • Read attributes (in Spock):
    • Read velocity:
      top.velocity
    • Read acceleration time:
      top.acceleration
    • Read deceleration time:
      top.deceleration

Implement standard axis attributes

  • Implement SetAxisPar method
    • Implement velocity by commanding vel <axis id> <value>
    • Implement acceleration by commanding acc <axis id> <value>
    • Implement deceleration by commanding dec <axis id> <value>
    • Raise exception when base_rate is set
    • Raise exception when steps_per_unit is set

Write standard axis attributes

  • Change velocity attribute (in Spock):
    • Write new velocity:
      top.velocity = 1
    • Make some moves e.g.
      umvr top 5

Align slits

  • Define the rest of the motors (in Spock, line by line):
    defm bottom bleblactrl 2
    defm left bleblactrl 3
    defm right bleblactrl 4
  • Ask for motor positions (in Spock):
    wm top bottom left right
  • Determine direction with relative move and adjust sign (in Spock, line by line):
    bottom.sign = -1
    left.sign = -1
  • Fully close slits and change offset by using the set_user_pos macro (in Spock, line by line):
    set_user_pos top 0
    set_user_pos bottom 0
    set_user_pos left 0
    set_user_pos right 0
  • Open and close gap by moving physical motors (in Spock, line by line)
    mv top 5 bottom 5 left 5 right 5
    mv top 0 bottom 0 left 0 right 0

Pseudomotor basics - Slit

  • Slit controller - Sardana's standard slit controller
  • Physical axes = motors that will be moved
  • Pseudo axes = virtual axes consisting of physical axes
  • pseudo_motor_roles and motor_roles class members defines number of pseudo and physical axes used by the controller
  • Instantiate vertical slits controller (in Spock):
    defctrl Slit vertctrl sl2t=top sl2b=bottom Gap=gapvert Offset=offsetvert
  • Instantiate horizontal slits controller:
    defctrl Slit horctrl sl2t=right sl2b=left Gap=gaphor Offset=offsethor

Inside Slit controller

  • CalcPhysical method, for calculating physical axes positions based on pseudo axes position
    • Calculate half_gap
    • top = offset + half_gap
    • Bottom would be offset - half_gap if directions were common
    • Since the directions are opposit bottom = half_gap - offset
  • CalcPseudo method, for calculating pseudo axes positions based on physical ones
    • gap = bottom + top
    • offset = top - half_gap

Play with the slits

  • Open the gaps: mv gapvert 10 gaphor 10
  • Make a scan of offset: dscan offsetvert -10 10 10 0.1

Data acquisition controllers



Creative Commons License Sardana-Training by ALBA Synchrotron is licensed under the Creative Commons Attribution 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

Contents

  • Writing counter/timer controller - Network Trafic Counter
  • Playing with Blender Detector - 2D experimental channel controller

Network Traffic Counter

How to write a counter/timer controller

Network Traffic Counter

  • Open the code in your favourite editor e.g.:
    kwrite ~/sardana-training/controllers/templates/NetworkTrafficCTCtrl.py

Network Traffic Counter

  • Network traffic counter counts bytes that pass via a network interface (both ways)
  • Demo:
    • Directly from the system:
      cat /proc/net/dev | grep eth0
    • Using python function:
      cd ~/sardana-training/controllers
      python3 -c "from NetworkTrafficCTCtrl import read_network_counts; print(read_network_counts('eth0'))"

Writing constructor

  • Constructor
    • Called on: controllers creation, pool startup and controller's code reload
    • Accepts arguments: instance (name of the controller instance) and properties (dictionary with the controller properties)
    • If an exception is raised when constructing the controller, the controller automatically gets into the Fault state and its status describes the exception that occured
  • Define controller property interface

Writing constructor

  • Counter will work on the following principle:
    • Load of the timer will store the integration time in the cache
    • Start of the counting will latch the current number of bytes
    • Start of the counting will define the end acquisition time (current time + integration time)
  • In the constructor we need to instantiate the necessary variables:
    • acq_time = 1
    • acq_end_time = time.time()
    • start_counts = 0

Instantiate controller

  • Deploy controller:
    ln -s ~/sardana-training/controllers/templates/NetworkTrafficCTCtrl.py ~/controllers
  • Load it in the system (in Spock):
    addctrllib NetworkTrafficCTCtrl
  • Create an instance of the controller:
    defctrl NetworkTrafficCounterTimerController netctrl interface eth0
  • Ask for controllers state:
    netctrl.state()

Implement StateOne

  • Assume state is On
  • Only if current time is less then the acq_end_time return Moving state
  • IMPORTANT: due to sardana-org/sardana#621 return an empty status ""

Implement LoadOne

  • receives either integration time or monitor counts (negative number) as arguments *
  • is called only on the controller's timer or monitor

  • store the integration time in the cache acq_time

* An advanced API is available for continuous acquisitions e.g. continuous scans

Implement ReadOne

  • returns a single counter value
  • is called multiple times during the acquisition operation

  • latch network bytes

  • return a difference between the current network bytes and start_counts

* An advanced API is available for continuous acquisitions e.g. continuous scans

Instantiate net counter

  • Reload controller code (in Spock):
    relctrlcls NetworkTrafficCounterTimerController
  • Create motor instance (in Spock):
    defelem net netctrl 1
  • Ask for motor state (in Spock):
    net.state()

Implement StartOne

  • receives intergation timer or monitor count as argument
  • latch the current bytes to start_counts and calcultate the end acquisition time in acq_end_time

Demonstrate single acquisition with net counter

  • Reload controller code (in Spock):
    relctrlcls NetworkTrafficCounterTimerController
  • Count (in Spock) -> zero counts!:
    uct 1 net
  • While long counting (in Spock):
    uct net 10
    get sardana CHANGELOG with the wget tool:
    wget https://github.com/sardana-org/sardana/blob/develop/CHANGELOG.md

Blender Detector

Play with the 2D experimental channel on example of Blender Detector

Instantiate controller and experimental channels

  • Deploy controller:
    ln -s ~/sardana-training/controllers/Blender2DCtrl.py ~/controllers
  • Load it in the system (in Spock):
    addctrllib Blender2DCtrl
  • Create an instance of the controller (in Spock):
    defctrl Blender2DController ble2dctrl
  • Ask for controllers state (in Spock):
    ble2dctrl.state()
  • Create an instance of the 2D experimental channel (in Spock):
    defelem ble2d ble2dctrl
  • Ask for channels state (in Spock):
    ble2d.state()

Acquire with the detector - data transfer

  • Configure timer (in Spock, line by line):
    ble2d.timer = "__self"
    ct 1 ble2d
  • Show image (value attribute):
    taurus form ble2d
  • In expconf (started from Spock):
    • define measurement group with the ble2d channel
    • configure storage to HDF5 file (Storage tab -> File name(s) & Path):
  • Move slits to a well known position (in Spock):
    mv gapvert 10 gaphor 10 offsetvert 0 offsethor 0
  • Slightly open left blade (in Spock):
    mv left 50
  • Scan the vertical offset (in Spock):
    dscan offsetvert -10 10 10 0.1
  • Show images with silx (remember to close silx afterwards):
    silx view

Acquire with the detector - data references transfer

  • In expconf configure data referencing:
    • Ref Enabled -> True
    • Ref Pattern -> h5file:///tmp/ble2d_img{image_nb:03d}.h5
  • Repeat the last scan (in Spock):
    dscan offsetvert -10 10 10 0.1
  • Show images via VDS with silx (remember to close silx afterwards):
    silx view
    • Note the usage of HDF5 VDS - image data are not stored in the Sardana file.

What else?

Questions?

Propose topics for dicsussion?

If not we have planty of other features that we could briefly introduce...

ZeroD channels - software sampling

  • Read scalar values but without controller acqusition capability
  • Read loop adds value to the buffer
  • Apply custom transformation to the gathered values

Pseudo counters - transformation of counter values

  • Perform calculations on counter values
  • Provide results as another measurement channel

Configuration tools

  • Full-fledged solution is not ready yet
  • Few different options:
    • dsconfig and sardana-dsconfig from MAX IV
    • Ansible plugin for configuring Tango database
    • FODS (flat ODS) spreadsheets

Eval scheme

  • Evaluate any Python expression and use its value as Taurus data source
  • Example: taurus form eval:123.4*{tango:sys/tg_test/1/double_scalar}

Advanced motion features

  • Possibility to fine tune moveables behaviour
  • Backlash:
    • Over travel and go back
    • Stop at given position always from one direction
  • Limit protection:
    • In addition to hardware limit switches
    • Software limits, that are checked before starting motion
  • Position calibration:
    • Used to change the reference frame for axis movement
    • Sign - allows to change the apparent movement direction in software
    • Offset - change software position values
  • Drift correction:
    • Correct positioning inaccuracy of the hardware
    • Prevent accumulation of positioning errors
    • For detailed description check the documentation

Synchronization

  • Synchronization types
    • Software - best-effort software synchronizer
    • Hardware - make use of dedicated synchronization hardware
  • Synchronization modes
    • Trigger - start measurement for given time on single trigger event
    • Gate - measure for how long the gate signal is active
    • Start - run whole measurement sequence on single start event
  • Synchronization domains
    • Time - synchronize measurements based on given time and duration
    • Position - synchronize measurements with moveable position
  • Equidistant or non-equidistant

Units support

  • pint module
  • Support for managing and displaying units of values

QtSpock

  • Simple way to embed Spock console inside Qt application
  • Implemented as Qt widget

Diffractometer control

  • Integrated controllers and macros for different types of diffractometers
  • Support for HKL calculations
  • Pseudomotor based interface
  • Dedicated set of macros (e.g. hklscan)
  • More details in the documentation

Integration with EPICS

  • Taurus ca or epics scheme gives direct access to EPICS system
  • EPICS controller built with pyepics