Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  <20092010  2011  2012  2013  2014  2015  2016  2017  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  <20092010  2011  2012  2013  2014  2015  2016  2017 
<== Date ==> <== Thread ==>

Subject: RE: EPICS Python client application survey
From: <michael.abbott@diamond.ac.uk>
To: <anj@aps.anl.gov>
Cc: tech-talk@aps.anl.gov
Date: Fri, 2 Oct 2009 18:16:19 +0100
From: Andrew Johnson [mailto:anj@aps.anl.gov] 
> On Friday 02 October 2009 07:22:16 Michael Abbot wrote:
> > From: Andrew Johnson [mailto:anj@aps.anl.gov]
> > > As I said, there are already applications that use waveform
> > > records configured as an array of CHARs to store long strings
> > > (file path-names for example) and standard MEDM and EDM text
> > > widgets to display and edit them (the widgets do have to be
> > > configured properly though).  The $ modifier extends this technique
> > > to the IOC's existing string field types.
> >
> > Ahh.  I wasn't aware of this, but a colleague (Ulrik) pointed me to an
> > example on one of our beamline IOCs.  I've revisited my cothread.catools
> > API and I think I have a better solution:
> >
> > 1. caget and camonitor take an extra flag as_string which defaults to
> > False; if as_string is true and if (and ONLY if) the data returned is an
> > array of CHAR then the result is converted to a string.  Seems to work, but
> > I'm going to have to watch my step with malformed strings...
> 
> In the Perl API I give the user the ability to specify what 
> type to use for a get_callback() or monitor subscription.  
> If they specify DBF_CHAR for a channel containing more than
> one element, they'll get the result converted to a string.  
> If they don't want a string, they have to ask for it as DBF_LONG, 
> which is the only integer data type the API supports.

I think cothread.catools is similar, but maybe a little more flexible.  The user can specify the datatype in really rather a huge variety of formats, or else they get the default channel type.  Python only supports one integer data type, int, but that's not the same for arrays which can be just about any support machine type (at least with numpy), so it's quite natural for me to return an array of CHAR.

I wonder whether it would be better to add a special code to my supported datatypes rather than having a separate flag, which really has no meaning unless the datatype is CHAR.  Hmm...

> Good point about the malformed strings, it would be wise to 
> stick a zero in the last cell of the incoming data before 
> calling strlen() on the result. In the majority of cases it's
> not going to be necessary, but if you allow the user to 
> specify how many elements to fetch and the string is 
> longer than the request it could save you from a including 
> trash in the string, or in the worst case from a segfault.

Yes, it turns out to be easy to put trash in the string!  The ctypes way of converting a raw buffer of known length to a string is a little odd (string_at is a ctypes method):

	s = string_at(string_at(raw_buffer, length))

where the inner string_at computes a fixed length string (probably with nulls in it) and the outer one stops at the first null.  

> > 2. caput takes an extra flag str_as_array (wish I could 
> > think of a nicer, briefer, name) which defaults to False.  
> > If true and if a string is passed
> > to caput then it is converted to an array of CHAR.
> 
> Why not make that flag into an optional data type name 
> instead; if not supplied you would default to whatever 
> you were doing before, but as well as controlling whether 
> strings get sent as a DBF_STRING or DBF_CHAR, this could 
> also allow the user to tell your API "please convert my data 
> to this type before sending it."

Very tempted to do this for caget, but for caput I don't currently offer the caller control over the conversion -- instead, I convert the data to whatever format fits, so for scalars I only do caputs in LONG, DOUBLE or STRING (waveforms get the lot, except for ENUM).  Hmmm.... very tempting to add a datatype specifier, actually, not sure if it'd be useful though?

Huh: did you know that if you do 
	caget('STRING-PV-ENDING-IN.$', datatype=str)
you get an array of strings, each string containing the decimal representation of each character in the PV?  Very entertaining!

> The Perl API doesn't actually do that, although I could add 
> some put_as() and put_callback_as() methods if I wanted to 
> allow it.  I look at the number of elements of both the 
> channel and the supplied data to work out what to do when 
> the channel's native type is DBF_CHAR; for a long string it's 
> putting a single item to an array of DBF_CHAR.  This approach
> does make it harder (but not completely impossible) for an 
> application to send a single integer value to a multi-element
> DBF_CHAR array, although I don't believe that's a particularly 
> common thing to want to do.

Speaking of length ... think I'd better put my question on length in a separate message, actually.

-- 
This e-mail and any attachments may contain confidential, copyright and or privileged material, and are for the use of the intended addressee only. If you are not the intended addressee or an authorised recipient of the addressee please notify us of receipt by returning the e-mail and do not use, copy, retain, distribute or disclose the information in or attached to the e-mail.
Any opinions expressed within this e-mail are those of the individual and not necessarily of Diamond Light Source Ltd. 
Diamond Light Source Ltd. cannot guarantee that this e-mail or any attachments are free from viruses and we cannot accept liability for any damage which you may sustain as a result of software viruses which may be transmitted in or with the message.
Diamond Light Source Limited (company no. 4375679). Registered in England and Wales with its registered office at Diamond House, Harwell Science and Innovation Campus, Didcot, Oxfordshire, OX11 0DE, United Kingdom
 





Replies:
Re: EPICS Python client application survey Andrew Johnson
References:
Re: EPICS Python client application survey Andrew Johnson

Navigate by Date:
Prev: Re: EPICS Python client application survey Andrew Johnson
Next: Channel access and ca_element_count michael.abbott
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  <20092010  2011  2012  2013  2014  2015  2016  2017 
Navigate by Thread:
Prev: Re: EPICS Python client application survey Andrew Johnson
Next: Re: EPICS Python client application survey Andrew Johnson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  <20092010  2011  2012  2013  2014  2015  2016  2017 
ANJ, 31 Jan 2014 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·