Hi,
Sorry about the cryptic error messages, those come from the boost python bindings.
I don't understand the documentation; I thought that I could use the simplest form of this:
histx_list.putScalarArray('histx')
You need to actually provide python list of strings as the argument of the function.
twissx_dict = pvaccess.Channel('WFE:MEBT_PHYS_ALSC:TwissX').getIntrospectionDict()
Is this what I should be using, or is a simple Channel() sufficient?
getIntrospectionDict() is used for retrieving structure of a PvObject. If you want to get a dictionary out of the structure you retrieve from the server, you should be able to do something like this:
c = pvaccess.Channel('WFE:MEBT_PHYS_ALSC:histX')
d = dict(c.get())
Included below is a simple example of a server that simulates your IOC and client code that hopefully will help with both questions. The client code shows two ways you can do a channel put you need.
(demo) sveseli@bluegill3> cat string_list_server.py
import pvaccess as pva
import time
s = pva.PvaServer()
pv = pva.PvObject({'intarray' : [pva.INT], 'strarray' : [pva.STRING]})
s.addRecord('mypv', pv)
s.start()
time.sleep(100)
(demo) sveseli@bluegill3> cat string_list_client.py
import pvaccess as pva
c = pva.Channel('mypv')
pv = c.get()
print(f'Original:\n{pv}')
# Update using modified retrieved PvObject
pv['strarray'] = ['histx_list','histx','INT']
c.put(pv)
print(f'First put:\n{c.get()}')
# Update given field using string list
c.putScalarArray(['histx_list2','histx2','INT2'], 'strarray')
print(f'Second put:\n{c.get()}')
# Conversion to dictionary
print(f'Converted to dict:\n{dict(c.get())}')
(demo) sveseli@bluegill3> python string_list_server.py &
[1] 300044
(demo) sveseli@bluegill3> pvget mypv
mypv structure
int[] intarray []
string[] strarray []
(demo) sveseli@bluegill3> python string_list_client.py
Original:
structure
int[] intarray []
string[] strarray []
First put:
structure
int[] intarray []
string[] strarray [histx_list, histx, INT]
Second put:
structure
int[] intarray []
string[] strarray [histx_list2, histx2, INT2]
Converted to dict:
{'intarray': array([], dtype=int32), 'strarray': ['histx_list2', 'histx2', 'INT2']}
(demo) sveseli@bluegill3> pvget mypv
mypv structure
int[] intarray []
string[] strarray [histx_list2, histx2, INT2]
(demo) sveseli@bluegill3>
Please let me know if you have more issues.
Thanks,
Sinisa
--
Siniša Veseli
Scientific Software Engineering & Data Management
Advanced Photon Source
Argonne National Laboratory
sveseli at anl.gov
(630)252-9182
From: Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of Pierrick M Hanlet via Tech-talk <tech-talk at aps.anl.gov>
Sent: Monday, May 5, 2025 10:12 PM
To: tech-talk at aps.anl.gov <tech-talk at aps.anl.gov>
Subject: pvaPy syntax
I have an IOC which serves the PVs to which I want to read and write. I run pvaPy in
a python program which is a digital twin (DT). For scalars, I'm successful in reading
from and writing to the PVs from my IOC. I'm having trouble, presumably syntax, with
lists and dictionaries.
For my lists, I'm doing:
In accelParams.py, I have a function beam_params() in which:
histx_list = []
histx_list = pvaccess.Channel('WFE:MEBT_PHYS_ALSC:histX')
...
return((...,histx_list,...))
In my DT:
from accelParams import beam_params
...,histx_list,...=beam_params()
...
fill list name histx
...
histx_list.putScalarArray('histx_list','histx','INT') <<<===== this is line 988
I don't understand the documentation; I thought that I could use the simplest form of this:
histx_list.putScalarArray('histx')
I don't understand the error messages either; they always appear to ask for one more argument
than I provide:
===================================================================================================
Error in main: Python argument types in
Channel.putScalarArray(Channel, str, str, str)
did not match C++ signature:
putScalarArray(Channel {lvalue}, boost::python::list valueList)
putScalarArray(Channel {lvalue}, boost::python::list valueList, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > requestDescriptor)
Traceback (most recent call last):
File "/home/epics/Simulations/DigitalTwin/MEBT_DT/MEBT_DT_04MAY_2025_v1.py", line 1035, in <module>
main()
File "/home/epics/Simulations/DigitalTwin/MEBT_DT/MEBT_DT_04MAY_2025_v1.py", line 988, in main
histx_list.putScalarArray('histx_list','histx','INT')
Boost.Python.ArgumentError: Python argument types in
Channel.putScalarArray(Channel, str, str, str)
did not match C++ signature:
putScalarArray(Channel {lvalue}, boost::python::list valueList)
putScalarArray(Channel {lvalue}, boost::python::list valueList, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > requestDescriptor)
===================================================================================================
The second question is with regards to connecting a dictionary with a scalar array. In beam_params(),
I have:
twissx_dict = {}
twissx_dict = pvaccess.Channel('WFE:MEBT_PHYS_ALSC:TwissX').getIntrospectionDict()
Is this what I should be using, or is a simple Channel() sufficient?
Many thanks,
Pierrick
--
Pierrick Hanlet
Fermi National Accelerator
Accelerator Front End Controls
+1-630-840-5555 -- lab
+1-312-687-4980 -- mobile
"Whether you think you can or think you can't, you're right" -- Henry Ford
|