SlideShare a Scribd company logo
DIVERSE USES OF PYTHON AT DIAMOND

                          M. G. Abbott, T. M. Cobb, I. J. Gillingham, M. T. Heron,
                                 Diamond Light Source, Oxfordshire, UK

Abstract                                                      (all extra channel access ”control” fields). All the extra
                                                              values are returned as fields of the returned value, for
   Diamond Control Systems Group has used Python for a
                                                              example:
range of control system applications. These include scripts
to support use of the application build environment, client   signal = caget(’SR21C-DI-DCCT-01:SIGNAL’,
GUIs and integrated with EPICS as EPICS Channel Access            format=FORMAT_TIME)
servers and concentrators. This paper will present these      print signal.name, signal, signal.timestamp
applications and summarise our experience.
                                                              Note that the value returned by caget() is, in effect, a
                                                              double with extra fields: Python allows builtin types to be
                 INTRODUCTION                                 subclassed in this way.
  Distributed control systems at Diamond extensively use         Finally camonitor() raises the most difficult issues:
Python scripting for clients and some applications. Three     callbacks delivering new data from channel access can
examples of this are presented here.                          occur at any time. There are three possible solutions:
                                                              allow callbacks to occur completely asynchronously (using
                                                              threads), allow callbacks to occur only when polled
 PYTHON CHANNEL ACCESS BINDINGS
                                                              explicitly, or allow callbacks to automatically occur when
   Bindings for EPICS channel access have been imple-         convenient. In this library we use the last approach.
mented in Python using the ctypes library, which allows          Python support for threads has the disadvantage of
Python to directly call all of the C functions required to    threads that updates can occur at any time, for example
implement full EPICS client functionality. Channel access     when a data structure being updated is in an inconsistent
is provided through three functions: caput, caget and         state, without the compensating advantage of being able to
camonitor.                                                    use multiple processor cores. The decision was made to
                                                              use Python’s support for coroutines provided through the
caput(pvs, values, repeat_value=False,                        Greenlet library [2]. This is very low level, so it was also
    timeout=5, wait=False, throw=True)                        necessary to write a simple coroutine scheduler on top of
caget(pvs, timeout=5, datatype=None,                          the greenlet library.
    format=FORMAT_RAW, count=0, throw=True)                      In the end, the channel access library (catools) has
camonitor(pvs, callback, events=DBE_VALUE,                    turned into the primary application of a coroutine threading
    datatype=None, format=FORMAT_RAW,                         library (cothread). Most users don’t need to be aware
    count=0, all_updates=False,                               of the existence of coroutines, but they are there in the
    notify_disconnect=False)                                  background. The most basic functions provided by the
                                                              coroutine library are Spawn (starts a new coroutine or
   The caput() function is the simplest to describe: this
                                                              “cothread”) and Wait (suspends the calling cothread until
writes a single value to a single PV. Python values are
                                                              a specified event occurs). The main complication of
automatically converted into channel access (DBR) format:
                                                              this approach has been integration with other libraries, in
all channel access datatypes are supported.
                                                              particular the Qt library—currently this is implemented
   The caget() function is a bit more tricky. Support
                                                              through polling on a timer by a dedicated cothread.
for reading multiple PVs at once is helpful, as then the
library can wait for all values in parallel (the cothread
framework described below makes this particularly easy         CONTROL SYSTEM USER INTERFACE
and efficient). Conversion of channel access values to            A graphical user interface has been implemented at
Python values is reasonably straightforward—values are        Diamond, based on the Qt interface [3] with Python (PyQt
one of string, integer or floating point. If channel access    [4]) and the channel access bindings described above.
delivers an array of values then Numeric Python [1] is used   Figure 1 shows an example of this applied to a photon beam
to represent the resulting array. The call to caget() can     front-end. Qt/Python has the following advantages over the
specify the desired data format (using either Python data     Extensible Display Manager (EDM [5]).
types or channel access enum names).
   The most interesting functionality arises if timestamps,     • Object Oriented Design allows for easy inheritance
status or control values are requested. This is done by           for adding new classes of widgets and the potential
specifying the format of the required data as one of RAW          to modify the behaviour of existing ones, without the
(data only), TIME (timestamps with status fields) or CTRL          need to modify or rebuild the base libraries.
Figure 1: Example screenshot of Qt/Python application


  • Good processing of large XML datasets, which we
    have found to be a powerful approach to application
    configuration.
  • Scalable Vector Graphics rendering, is the basis for
    much of our implementation of the Qt/Python user
    interface. This permits easy manipulation of widgets,
    such as changing element fill colour, shape and
    position as required at run-time, through the standard
    Document Object Model.                                           Figure 2: EPICS Qt Widget Class Diagram
  • Dynamic scalability (zooming) allows the size of
    the user interface to be changed at will, which can
    significantly improve desktop real-estate, especially      inherit full clipboard copy functionality (XDND protocol),
    when multiple application windows are displayed.          tooltips and context menus.
  • Ability at runtime, to customise a single, common
    application architecture, in order to support multiple
    systems, which are similar, but not necessarily
    identical (e.g. Diamond’s Front Ends).                             PYTHON IN SIMULATIONS
  • The visualisation of complex three-dimensional scan
    plots and beamline geometry is being realised through        EPICS based photon beamlines at Diamond are increas-
    Python graphical interfaces, using OpenGL.                ingly using Asyn [6] as an interface layer between Device
                                                              and Driver Support (figure 3 left). This abstraction allows
Implementation                                                the low level driver to be replaced with a simulation
                                                              without modifying the upper levels of the structure. These
   The class diagram in figure 2 highlights the design         simulations support early testing, not only of high level
pattern adopted to facilitate the implemention of widgets     applications including EDM panels, but also core modules
with specific characteristics. Only three widget classes are   such as Asyn and Stream Device [7].
shown as examples in this diagram.
   The EPICS Channel Access (CA) interface is via
the catools library described above. An example im-              Client Tools        Client Tools        Client Tools
plementation (from Diamond’s Front Ends interface) is
abstracted in the EpicsSVGGraphic class. The applica-           EPICS Database     EPICS Database      EPICS Database
tion framework implements the modern Qt scene/view
                                                                Record Support      Record Support     Record Support
framework. The view layout is specified by subclassing
QtGui.QGraphicsView, instantiating all widgets in the           Device Support      Device Support     Device Support
constructor, defining their positions and setting their PV
identifiers.                                                        Asyn Port          Asyn Port           Asyn Port
   When EpicsSVGGraphic is instantiated, it subscribes to
updates of the given EPICS PV, by supplying its callback        Driver Support      Driver Support        Simulated
                                                                                                            Driver
function to the CA interface. Update processing, specific
                                                                                                           Support
to a graphical widget, is realised simply by overriding          Real Device       Simulated Device
the base-class callback. For instance, a valve widget will
change the fill-colour of the graphical element, depending     Figure 3: Asyn device structure and the two most desirable
on the new valve status.                                      levels of simulation
   All widgets derived from EpicsSVGGraphic, also
The Problem                                                    class my_asyn(pyDrv):
                                                                   # supported list of asyn commands
  The most realistic and useful simulation is written at the       commands = ["A","B","C","D"]
lowest possible level. However, driver support is typically        # internal dictionary of values
written in C, making simulations at that level quite time          vals = {"A":1,"B":"BE","C":3.4,"D":[1,2]}
consuming.                                                         def write(self,command,signal,value):
                                                                       # write <value> to internal dict
Our Solutions                                                          self.vals[command] = value
   The first solution is to use the existing Driver Support         def read(self,command,signal):
but connect it to a Simulated Device (figure 3 middle).                 # return value from internal dict
Serial devices are simulated in this way, by creating a                return self.vals[command]
virtual serial port at the system level and connecting a                    Figure 5: Simple pyDrv example
drvAsynSerialPort to it. The second solution is to replace
the Driver Support with a simulation (figure 3 right). This
                                                               from a startup script creating both kinds of port. The file
is likely to be used for a complex device like a camera or
                                                               my.py imported in the first line contains the code in Figures
scaler card. Both solutions can be accomplished in Python.
                                                               4 and 5, the databases connect to port a and port b.

Creating a Simulated Device                                    Python("from my import my_serial,my_asyn")
                                                               # start a virtual serial port
   The Python class serial_device wraps either a TCP
                                                               Python("a = my_serial()")
server or a Linux pseudo serial port, deals with I/O and
                                                               Python("a.start_serial(’env_a’)")
terminators, and provides scheduling functionality. The
                                                               # name of port stored in environment var
programmer is required to code a reply method suitable for
                                                               drvAsynSerialPortConfig(’port_a’,’$env_a’)
the device. Figure 4 is the code for a device that has one
                                                               Python("b = my_asyn(’port_b’)")
internal value. It can be read by sending “?” and written by
sending anything else. The accompanying database uses                 Figure 6: Excerpt from st.cmd startup script
Stream Device to strip off the terminator and parse the
response.
                                                                                 CONCLUSIONS
class my_serial(serial_device):
    # set a terminator and internal val                          Python has provided a flexible and powerful frame-
    Terminator = "rn"; val = 1                               work for building EPICS components, including clients
    def reply(self, command):                                  (described here) and even servers (IOCs, not described).
        # return reply to <command>                            The Python language and libraries have allowed very
        if command=="?":                                       powerful frameworks to be developed and rapidly used
            return self.val                                    at Diamond—this paper only hints at the range of
        else:                                                  applications.
            self.val=command                                     The language supports flexible rapid prototyping and
            return "OK"                                        has provided to be a valuable integration tool. The main
                                                               drawback of the large scale application of Python is that it
           Figure 4: Simple serial sim example                 can run a lot slower than corresponding C code—but this
                                                               has been a problem less frequently than might be expected.
Creating Simulated Driver Support
                                                                                  REFERENCES
   The Python class pyDrv registers itself as an Asyn
                                                               [1] Numeric Python, http://numpy.scipy.org
port with a variety of interfaces, provides scheduling and
callback functionality and handles type conversion to and      [2] Lightweight in-process concurrent programming, http://
from Python native types. The programmer is required               pypi.python.org/pypi/greenlet
to code suitable write and read methods. Figure 5 is           [3] Trolltech, http://trolltech.com/
the code for a simple example that keeps an internal           [4] Riverbank       Computing,         http://www.
dictionary object of values, and allows access to these            riverbankcomputing.com/static/Docs/PyQt4/
via a series of commands. The accompanying database                html/classes.html
has records of many types with INP or OUT links like           [5] EDM, http://ics-web.sns.ornl.gov/edm/
“@Asyn($(PORT) 0)C”.
                                                               [6] Asyn,    http://www.aps.anl.gov/epics/modules/
   Instances of these classes need to be created in                soft/asyn/
the EPICS IOC. The “Python” command provided by
                                                               [7] Stream Device 2, http://epics.web.psi.ch/software/
pyDrv ensures the interpreter is running and executes the
                                                                   streamdevice/
argument as a Python command. Figure 6 shows an excerpt

More Related Content

PDF
Mkl mic lab_0
PDF
2010 nephee 01_smart_grid과제진행및이슈사항_20100630_kimduho
PPT
DUSK - Develop at Userland Install into Kernel
PPT
Order Independent Transparency
PPT
FIR filter on GPU
PPSX
Oit And Indirect Illumination Using Dx11 Linked Lists
PDF
Chap5 - ADSP 21K Manual
PPT
IS-ENES COMP Superscalar tutorial
Mkl mic lab_0
2010 nephee 01_smart_grid과제진행및이슈사항_20100630_kimduho
DUSK - Develop at Userland Install into Kernel
Order Independent Transparency
FIR filter on GPU
Oit And Indirect Illumination Using Dx11 Linked Lists
Chap5 - ADSP 21K Manual
IS-ENES COMP Superscalar tutorial

What's hot (19)

PDF
More mpi4py
PPTX
CloudMC: A cloud computing map-reduce implementation for radiotherapy. RUBEN ...
PDF
TCF Helios Update - EclipseCon 2010
PDF
High Speed Decoding of Non-Binary Irregular LDPC Codes Using GPUs (Paper)
PDF
Hadoop Internals (2.3.0 or later)
PDF
OpenGL NVIDIA Command-List: Approaching Zero Driver Overhead
PDF
Open cl programming using python syntax
PDF
I/O (imput/output) [JAVA]
PPT
Os7 2
PPTX
FrameGraph: Extensible Rendering Architecture in Frostbite
PPT
ADMS'13 High-Performance Holistic XML Twig Filtering Using GPUs
PDF
customization of a deep learning accelerator, based on NVDLA
PDF
2020 icldla-updated
PPTX
Core .NET Framework 4.0 Enhancements
PDF
L kernel-logging-apis-pdf
PPTX
vkFX: Effect(ive) approach for Vulkan API
PPT
OpenGL ES based UI Development on TI Platforms
PPTX
Scope Stack Allocation
PDF
Introduction to MapReduce using Disco
More mpi4py
CloudMC: A cloud computing map-reduce implementation for radiotherapy. RUBEN ...
TCF Helios Update - EclipseCon 2010
High Speed Decoding of Non-Binary Irregular LDPC Codes Using GPUs (Paper)
Hadoop Internals (2.3.0 or later)
OpenGL NVIDIA Command-List: Approaching Zero Driver Overhead
Open cl programming using python syntax
I/O (imput/output) [JAVA]
Os7 2
FrameGraph: Extensible Rendering Architecture in Frostbite
ADMS'13 High-Performance Holistic XML Twig Filtering Using GPUs
customization of a deep learning accelerator, based on NVDLA
2020 icldla-updated
Core .NET Framework 4.0 Enhancements
L kernel-logging-apis-pdf
vkFX: Effect(ive) approach for Vulkan API
OpenGL ES based UI Development on TI Platforms
Scope Stack Allocation
Introduction to MapReduce using Disco
Ad

Viewers also liked (20)

PDF
電子書籍と図書館 120619Ver.3
PPTX
TLF Reunion 2011
PPT
Lecture910
PPT
Lecture3
PPT
Ded algorithm
DOC
Pm104 standard
PPTX
Texas Leadership Forum Ppt 2008
PPTX
From Ink to Pixel and Beyond...
PPTX
Homelessness and Housing – Moving from Policy to Action - Frank Murtagh
PDF
Raporti Mbi Shqiperine ... Raport Su Albania
PPT
Lecture911
PPT
Tobch lecture
PPT
Chap04alg
PDF
データ集 トマ・ピケティ『21 世紀の資本』
DOCX
Lissajous pattern
PPTX
Berenschot presentatie Metaalunie Noord NL Samenwerken & aanbesteden
PPT
Lecture916
PDF
Worldcup2010 gs report
PDF
PPTX
Nings To Knols Upload
電子書籍と図書館 120619Ver.3
TLF Reunion 2011
Lecture910
Lecture3
Ded algorithm
Pm104 standard
Texas Leadership Forum Ppt 2008
From Ink to Pixel and Beyond...
Homelessness and Housing – Moving from Policy to Action - Frank Murtagh
Raporti Mbi Shqiperine ... Raport Su Albania
Lecture911
Tobch lecture
Chap04alg
データ集 トマ・ピケティ『21 世紀の資本』
Lissajous pattern
Berenschot presentatie Metaalunie Noord NL Samenwerken & aanbesteden
Lecture916
Worldcup2010 gs report
Nings To Knols Upload
Ad

Similar to Python (20)

PDF
Jq2416671672
PDF
turecko-150426_pse_01
PDF
OpenSAF Symposium_Python Bindings_9.21.11
PDF
A NETWORK-BASED DAC OPTIMIZATION PROTOTYPE SOFTWARE 2 (1).pdf
DOCX
ESL report
PDF
OpenCL programming using Python syntax
PPTX
What Have We Lost - A look at some historical techniques
PDF
05 defense
PDF
Open source building blocks for the Internet of Things - Jfokus 2013
PDF
Ju2416921695
PDF
A guide to common automation terms
PDF
Hack Like It's 2013 (The Workshop)
PDF
Build Apps
PDF
Twisted
PDF
Black hat dc-09-laurie-satellite-hacking
PDF
Adam Laurie - $atellite Hacking for Fun & Pr0fit!
PDF
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
PDF
Connecting hardware up to ColdFusion
PPTX
Profiling Multicore Systems to Maximize Core Utilization
PDF
HARDWARE/SOFTWARE CO-DESIGN OF A 2D GRAPHICS SYSTEM ON FPGA
Jq2416671672
turecko-150426_pse_01
OpenSAF Symposium_Python Bindings_9.21.11
A NETWORK-BASED DAC OPTIMIZATION PROTOTYPE SOFTWARE 2 (1).pdf
ESL report
OpenCL programming using Python syntax
What Have We Lost - A look at some historical techniques
05 defense
Open source building blocks for the Internet of Things - Jfokus 2013
Ju2416921695
A guide to common automation terms
Hack Like It's 2013 (The Workshop)
Build Apps
Twisted
Black hat dc-09-laurie-satellite-hacking
Adam Laurie - $atellite Hacking for Fun & Pr0fit!
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
Connecting hardware up to ColdFusion
Profiling Multicore Systems to Maximize Core Utilization
HARDWARE/SOFTWARE CO-DESIGN OF A 2D GRAPHICS SYSTEM ON FPGA

Recently uploaded (20)

PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Encapsulation theory and applications.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Empathic Computing: Creating Shared Understanding
PDF
Electronic commerce courselecture one. Pdf
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
KodekX | Application Modernization Development
PPT
Teaching material agriculture food technology
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
sap open course for s4hana steps from ECC to s4
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
Spectral efficient network and resource selection model in 5G networks
Encapsulation theory and applications.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
Empathic Computing: Creating Shared Understanding
Electronic commerce courselecture one. Pdf
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Diabetes mellitus diagnosis method based random forest with bat algorithm
“AI and Expert System Decision Support & Business Intelligence Systems”
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Review of recent advances in non-invasive hemoglobin estimation
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
KodekX | Application Modernization Development
Teaching material agriculture food technology
Mobile App Security Testing_ A Comprehensive Guide.pdf
Chapter 3 Spatial Domain Image Processing.pdf
sap open course for s4hana steps from ECC to s4

Python

  • 1. DIVERSE USES OF PYTHON AT DIAMOND M. G. Abbott, T. M. Cobb, I. J. Gillingham, M. T. Heron, Diamond Light Source, Oxfordshire, UK Abstract (all extra channel access ”control” fields). All the extra values are returned as fields of the returned value, for Diamond Control Systems Group has used Python for a example: range of control system applications. These include scripts to support use of the application build environment, client signal = caget(’SR21C-DI-DCCT-01:SIGNAL’, GUIs and integrated with EPICS as EPICS Channel Access format=FORMAT_TIME) servers and concentrators. This paper will present these print signal.name, signal, signal.timestamp applications and summarise our experience. Note that the value returned by caget() is, in effect, a double with extra fields: Python allows builtin types to be INTRODUCTION subclassed in this way. Distributed control systems at Diamond extensively use Finally camonitor() raises the most difficult issues: Python scripting for clients and some applications. Three callbacks delivering new data from channel access can examples of this are presented here. occur at any time. There are three possible solutions: allow callbacks to occur completely asynchronously (using threads), allow callbacks to occur only when polled PYTHON CHANNEL ACCESS BINDINGS explicitly, or allow callbacks to automatically occur when Bindings for EPICS channel access have been imple- convenient. In this library we use the last approach. mented in Python using the ctypes library, which allows Python support for threads has the disadvantage of Python to directly call all of the C functions required to threads that updates can occur at any time, for example implement full EPICS client functionality. Channel access when a data structure being updated is in an inconsistent is provided through three functions: caput, caget and state, without the compensating advantage of being able to camonitor. use multiple processor cores. The decision was made to use Python’s support for coroutines provided through the caput(pvs, values, repeat_value=False, Greenlet library [2]. This is very low level, so it was also timeout=5, wait=False, throw=True) necessary to write a simple coroutine scheduler on top of caget(pvs, timeout=5, datatype=None, the greenlet library. format=FORMAT_RAW, count=0, throw=True) In the end, the channel access library (catools) has camonitor(pvs, callback, events=DBE_VALUE, turned into the primary application of a coroutine threading datatype=None, format=FORMAT_RAW, library (cothread). Most users don’t need to be aware count=0, all_updates=False, of the existence of coroutines, but they are there in the notify_disconnect=False) background. The most basic functions provided by the coroutine library are Spawn (starts a new coroutine or The caput() function is the simplest to describe: this “cothread”) and Wait (suspends the calling cothread until writes a single value to a single PV. Python values are a specified event occurs). The main complication of automatically converted into channel access (DBR) format: this approach has been integration with other libraries, in all channel access datatypes are supported. particular the Qt library—currently this is implemented The caget() function is a bit more tricky. Support through polling on a timer by a dedicated cothread. for reading multiple PVs at once is helpful, as then the library can wait for all values in parallel (the cothread framework described below makes this particularly easy CONTROL SYSTEM USER INTERFACE and efficient). Conversion of channel access values to A graphical user interface has been implemented at Python values is reasonably straightforward—values are Diamond, based on the Qt interface [3] with Python (PyQt one of string, integer or floating point. If channel access [4]) and the channel access bindings described above. delivers an array of values then Numeric Python [1] is used Figure 1 shows an example of this applied to a photon beam to represent the resulting array. The call to caget() can front-end. Qt/Python has the following advantages over the specify the desired data format (using either Python data Extensible Display Manager (EDM [5]). types or channel access enum names). The most interesting functionality arises if timestamps, • Object Oriented Design allows for easy inheritance status or control values are requested. This is done by for adding new classes of widgets and the potential specifying the format of the required data as one of RAW to modify the behaviour of existing ones, without the (data only), TIME (timestamps with status fields) or CTRL need to modify or rebuild the base libraries.
  • 2. Figure 1: Example screenshot of Qt/Python application • Good processing of large XML datasets, which we have found to be a powerful approach to application configuration. • Scalable Vector Graphics rendering, is the basis for much of our implementation of the Qt/Python user interface. This permits easy manipulation of widgets, such as changing element fill colour, shape and position as required at run-time, through the standard Document Object Model. Figure 2: EPICS Qt Widget Class Diagram • Dynamic scalability (zooming) allows the size of the user interface to be changed at will, which can significantly improve desktop real-estate, especially inherit full clipboard copy functionality (XDND protocol), when multiple application windows are displayed. tooltips and context menus. • Ability at runtime, to customise a single, common application architecture, in order to support multiple systems, which are similar, but not necessarily identical (e.g. Diamond’s Front Ends). PYTHON IN SIMULATIONS • The visualisation of complex three-dimensional scan plots and beamline geometry is being realised through EPICS based photon beamlines at Diamond are increas- Python graphical interfaces, using OpenGL. ingly using Asyn [6] as an interface layer between Device and Driver Support (figure 3 left). This abstraction allows Implementation the low level driver to be replaced with a simulation without modifying the upper levels of the structure. These The class diagram in figure 2 highlights the design simulations support early testing, not only of high level pattern adopted to facilitate the implemention of widgets applications including EDM panels, but also core modules with specific characteristics. Only three widget classes are such as Asyn and Stream Device [7]. shown as examples in this diagram. The EPICS Channel Access (CA) interface is via the catools library described above. An example im- Client Tools Client Tools Client Tools plementation (from Diamond’s Front Ends interface) is abstracted in the EpicsSVGGraphic class. The applica- EPICS Database EPICS Database EPICS Database tion framework implements the modern Qt scene/view Record Support Record Support Record Support framework. The view layout is specified by subclassing QtGui.QGraphicsView, instantiating all widgets in the Device Support Device Support Device Support constructor, defining their positions and setting their PV identifiers. Asyn Port Asyn Port Asyn Port When EpicsSVGGraphic is instantiated, it subscribes to updates of the given EPICS PV, by supplying its callback Driver Support Driver Support Simulated Driver function to the CA interface. Update processing, specific Support to a graphical widget, is realised simply by overriding Real Device Simulated Device the base-class callback. For instance, a valve widget will change the fill-colour of the graphical element, depending Figure 3: Asyn device structure and the two most desirable on the new valve status. levels of simulation All widgets derived from EpicsSVGGraphic, also
  • 3. The Problem class my_asyn(pyDrv): # supported list of asyn commands The most realistic and useful simulation is written at the commands = ["A","B","C","D"] lowest possible level. However, driver support is typically # internal dictionary of values written in C, making simulations at that level quite time vals = {"A":1,"B":"BE","C":3.4,"D":[1,2]} consuming. def write(self,command,signal,value): # write <value> to internal dict Our Solutions self.vals[command] = value The first solution is to use the existing Driver Support def read(self,command,signal): but connect it to a Simulated Device (figure 3 middle). # return value from internal dict Serial devices are simulated in this way, by creating a return self.vals[command] virtual serial port at the system level and connecting a Figure 5: Simple pyDrv example drvAsynSerialPort to it. The second solution is to replace the Driver Support with a simulation (figure 3 right). This from a startup script creating both kinds of port. The file is likely to be used for a complex device like a camera or my.py imported in the first line contains the code in Figures scaler card. Both solutions can be accomplished in Python. 4 and 5, the databases connect to port a and port b. Creating a Simulated Device Python("from my import my_serial,my_asyn") # start a virtual serial port The Python class serial_device wraps either a TCP Python("a = my_serial()") server or a Linux pseudo serial port, deals with I/O and Python("a.start_serial(’env_a’)") terminators, and provides scheduling functionality. The # name of port stored in environment var programmer is required to code a reply method suitable for drvAsynSerialPortConfig(’port_a’,’$env_a’) the device. Figure 4 is the code for a device that has one Python("b = my_asyn(’port_b’)") internal value. It can be read by sending “?” and written by sending anything else. The accompanying database uses Figure 6: Excerpt from st.cmd startup script Stream Device to strip off the terminator and parse the response. CONCLUSIONS class my_serial(serial_device): # set a terminator and internal val Python has provided a flexible and powerful frame- Terminator = "rn"; val = 1 work for building EPICS components, including clients def reply(self, command): (described here) and even servers (IOCs, not described). # return reply to <command> The Python language and libraries have allowed very if command=="?": powerful frameworks to be developed and rapidly used return self.val at Diamond—this paper only hints at the range of else: applications. self.val=command The language supports flexible rapid prototyping and return "OK" has provided to be a valuable integration tool. The main drawback of the large scale application of Python is that it Figure 4: Simple serial sim example can run a lot slower than corresponding C code—but this has been a problem less frequently than might be expected. Creating Simulated Driver Support REFERENCES The Python class pyDrv registers itself as an Asyn [1] Numeric Python, http://numpy.scipy.org port with a variety of interfaces, provides scheduling and callback functionality and handles type conversion to and [2] Lightweight in-process concurrent programming, http:// from Python native types. The programmer is required pypi.python.org/pypi/greenlet to code suitable write and read methods. Figure 5 is [3] Trolltech, http://trolltech.com/ the code for a simple example that keeps an internal [4] Riverbank Computing, http://www. dictionary object of values, and allows access to these riverbankcomputing.com/static/Docs/PyQt4/ via a series of commands. The accompanying database html/classes.html has records of many types with INP or OUT links like [5] EDM, http://ics-web.sns.ornl.gov/edm/ “@Asyn($(PORT) 0)C”. [6] Asyn, http://www.aps.anl.gov/epics/modules/ Instances of these classes need to be created in soft/asyn/ the EPICS IOC. The “Python” command provided by [7] Stream Device 2, http://epics.web.psi.ch/software/ pyDrv ensures the interpreter is running and executes the streamdevice/ argument as a Python command. Figure 6 shows an excerpt