EPICS Home

Experimental Physics and Industrial Control System


 
2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Data Interface Classes
From: Marty Kraimer <[email protected]>
To: [email protected]
Date: Fri, 09 Sep 2005 10:51:59 -0500
The following are  some thoughts about Kay's  wiki document.

Executive Summary:

1) I agree that what Kay presents is easier to understand than raw dataAccess.
2) I think a distinction sould be made between primative and compound types.
3) The Property Catalog for accessing IOC databases should not hold the data but use interfaces defined by database access to read/write data.

Before commenting about Kay's wiki I first want to mention something about the "CS Office Data Access Feature Requests" prepared by Gasper Tkacik (cosylab) for the EPICS Office effort being lead by Matthais.

It is interesting that the proposal use the terminology "CS Office Data Access Layer". Although part of the name is "Data Access", this proposal is a layer that will interface to EPICS (V3 and V4), TINE, TANGO, ACD, and DOOOCS and is not the same as dataAccess.

The document proposes to support the following:

Basic Types: integral, floating, string, enumeration,  and bit-pattern
Compound Types: arrays and maps.
Tuples: See discussion in paper. Not clear it wsill be supported. Comes from TINE Infrastructure types: alarm codes, completion codes, time stamps, etc. Again see discussion.

I will guess that Tuples and Infrastructure types would be implemented via The Basic and Compound types. The document does not mention how various sizes of intergal and float will be supported.

I also want to mention how types for fields in database records are defined in "V4 Design: dbdInterfaces"
   enum BasicType {
       basicTypeBoolean,  // DbfBoolean
       basicTypeOctet,    // DbfOctet
       basicTypeInt16,    // DbfInt16
       basicTypeInt32,    // DbfInt32
       basicTypeInt64,    // DbfInt64
       basicTypeFloat32,  // DbfFloat32
       basicTypeFloat64,  // DbfFloat64
       basicTypeString,   // DbfString
       basicTypeArray,    // DbfArray
       basicTypeStruct,   // DbfStruct
   }

   enum DbfType {
       dbfTypeBasic,       // DbfBoolean,...,DbfStruct
       dbfTypeMenu,        // DbfMenu
       dbfTypeEnum,        // DbfEnum
       dbfTypeLink,        // DbfLink
       dbfTypeDevice,      // DbfDevice
       dbfTypeMDArray,     // DbfMDArray
       dbfTypeTimeStamp    // DbfTimeStamp
   }

It also says that
1) Channel Access will access data only as BasicType data.
2) Types basicTypeBoolean, ...,  basicTypeFloat64 are considered primitive.

The base interface for accessing a Dbf field is

interface Dbf{
       boolean isPrimitive(); // BasicTypeBoolean,...,BasicTypeFloat64
       boolean isBasic();
       BasicType getBasicType();
       RecordInstance getRecord(); // getb descriptor of record containing this field
       int16 getIndex(); // index of field within record
   }


Primitive types are all accessed via an interface that extends Dbf and adds just two methods: get and put
Other types are accessed via interfaces that add additional methods.

"V4 Data Interface"  proposes the following:

enum EpicsDataCharacter
{
   Octet,     // Raw bits,known to a server/client pair, but no one else
   Bool,
   Integer,   // Discrete, available with 16, 32, 64 bits
   Real,      // Floating-point, available with 32 and 64 bits
   String,    // UTF-8
   Enum,      // >=0 Integer with state names
   Structure,
   TimeStamp  // For efficiency?
};


And then adds

class EpicsDataDescriptor
{
public:
   virtual EpicsDataCharacter getType() = 0;
   virtual int  getNumDims() = 0;      // Scalar, vector: 1, matrix: >1
   virtual int  getSize(int dim) = 0;  // Scalar: 1
   virtual int  getBitsize() = 0;      // bits of integer or real. 0 for rest?
   virtual bool isSigned() = 0;        // Integer might be unsigned?
};

and also

class EpicsDataReader : public EpicsDataDescriptor
{
public:
   // Get data as type XX as best as possible.
   // Example: getDouble returns true for
   //          Bool (d=0.0, 1.0), Integer, Real, Enum.
   virtual bool getReal64(real64_t &r) = 0;
   virtual bool getDouble(double &d) = 0;
   virtual bool getInt(int &d) = 0;
   // String
   virtual bool getString(char *buf, int buf_len) = 0;
   virtual int  getStringLength() = 0;
   virtual bool getCstring(const char *&c_ptr) = 0;
   /// many more, at least one for each supported type.

   // A structure is accessed via a (sub-)catalog.
   // See below for PropertyCatalog.
   virtual class EpicsPropertyCatalog *getStructure() = 0;
// Get array element. getDouble(x) == getArrayDouble(0, x)
   virtual bool getArrayDouble(int element, double &d) = 0;
   virtual bool getMatrixDouble(int dim, int element, double &d) = 0;
   virtual class EpicsPropertyCatalog *getArrayStructure(int element) = 0;
   /// For arrays, it could include per-element access
   /// as well as accessors that copy sub-arrays into client buffers.
};

and also EpicsProperty and  EpicsPropertyCatalog


All three proposals have a lot of similarity but also major differences.

A major difference is the answer to the following question.
"Should there be a major distinction between primitive and compound types"

The cosylab and the dbdInterface proposals say yes.
The Data Interface proposal says maybe but the existing definitions say no.

Let me give an argument that making a major distinction is a better way.
Let me just look at the methods of EpicsDataDescriptor.

getType - This is generic, i.e. applys to all EpicsDataCharacter types
getNumDims and getSize - Together these are generic ( both 1 means scaler)
getBitsize - Only has meaning for Integer and Real
isSigned - Only has meaning for Integer



EpicsDataReader has methods for getting any EpicsDataCharacter data. Many of the methods will have very strange semantics if applied to particular types. Also it will need many methods. Arrays will be a particularly big problem. These problems are mentioned in the document

// The alternative would be individual reader interfaces


This could be done something like:

interface EpicsDataDescriptor {
   EpicsDataCharacter getType();
   int getNumDims(); // Scalar, vector: 1, matrix: >1
   int getSize(int dim); // Scalar: 1
}
interface EpicsIntegerDescriptor extends EpicsDataDescriptor {
   int getBitsize();
   bool isSigned();
}

Something similar could be done for EpicsDataReader

Now to change topics.

The "V4 Data Interface" shows an implementation of

class TestRecord : public EpicsPropertyCatalogBase


This is an example of automatically generated code that implements a property catalog that provides access to an IOC record. Instead of the generated code holding the data it should just use the Dbf interfaces described in "V4 Design: dbdInterfaces".

Marty



Replies:
Re: Data Interface Classes Kay-Uwe Kasemir

Navigate by Date:
Prev: V4 Record Access and Record Support Marty Kraimer
Next: RE: Video Conferencing Dayle Kotturi
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: V4 Record Access and Record Support Marty Kraimer
Next: Re: Data Interface Classes Kay-Uwe Kasemir
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024