Main Page | Features | Central Services | csv-Files | Types | Transfer | Access | API-C | API-.NET | API-Java | Examples | Downloads
page generated on 21.12.2024 - 04:45
TINE Data Array Types

If a registered property returns an array it is often extremely useful to know systematically what kind of array is being returned. TINE offers several different categories of array types to properly specify a property's behavior.

Under the most primitive of circumstances an 'array' of something can just be a 'collection', and any special behavior or meaning is systematcally unknown. Such property behavior is generally 'frowned upon' as only the developer himself knows 'what is going on'!

A common category of arrays is the case where an array of numbers represents a 'trace' (also known as a waveform or spectrum), whereby the values returned in the array generally have a well defined maximum and minimum and units (vertical scale) as well as a well defined range and units (horizontal scale). This might represent a bunch profile, a scope trace, a tune spectrum, or other things of this ilk.

Another common category of arrays is the case where an array of number represents a 'vector' of elements each with the same setting and units. This is known in TINE as a 'Multi-Channel Array'. Here the values in the array all have a well defined maximum and minimum and units (vertical scale). However as each element of the array represents a specific 'device' or location (i.e. instance), if such an array were plotted, it is best represented as a histogram where the horizontal axis is merely a running count of the devices. Such an array might be an Orbit (an array of beam position monitor positions), or an array of vacuum pressures, temperature sensors, or other things of this variety.

The behvior expected from Multi-Channel Array Properties is as follows. The most efficient way to acquire all values is of course to ask for them in the call to the property. Occasionally, a caller might only want the value of a specific device. For example a vacuum property might be "Pressure" which a caller can use either to acquire all pumps or a single selected pump (or a section). The caller will in any case ask for property "Pressure" and provide a device name (the location of a pump). If the call requests only 1 value then the value for the pressure at that location will be returned. If the call requests more than one value (for example ALL of them), then an array of pressures beginning at the device location specified will be returned. An example in C of how to produce this behavior with a minimum code is shown below (taken from the sine generator example)

int sineqm(char *devName,char *devProperty,DTYPE *dout, DTYPE *din,short access)
{
int devnr,prpid,i,cc;
float mcarray[NUM_DEVICES], fval;
SineInfo *sinf;
devnr = GetDeviceNumber(SINEQM_TAG,devName);
if (devnr < 0 || devnr >= NUM_DEVICES) return illegal_equipment_number;
prpid = GetPropertyId(SINEQM_TAG,devProperty);
switch (prpid)
{
case PRP_SINE:
if (access&CA_WRITE) return illegal_read_write;
if ((cc=PutValuesFromFloat(dout,sinbuf[devnr],NUM_VALUES)) != 0) return cc;
sineInfoTable[devnr].numberCalls++;
return 0;
case PRP_AMPLITUDE:
if (din->dArrayLength > 0)
{ /* input data => require write access */
if (!(access & CA_WRITE)) return illegal_read_write;
if ((cc=GetValuesAsFloat(din,&fval,1)) != 0) return cc;
if (fval < 1 || fval > 1000) return out_of_range;
sineInfoTable[devnr].amplitude = fval;
}
if (dout->dArrayLength > 0)
{ /* prepare multichannel array */
for (i=0; i<NUM_DEVICES; i++)
mcarray[i] = sineInfoTable[i].amplitude;
if ((cc=PutValuesFromFloatEx(dout,mcarray,NUM_DEVICES,devnr)) != 0) return cc;
}
return 0;
case PRP_FREQUENCY:
if (din->dArrayLength > 0)
{ /* input data => require write access */
if (!(access & CA_WRITE)) return illegal_read_write;
if ((cc=GetValuesAsFloat(din,&fval,1)) != 0) return cc;
if (fval < 1 || fval > 100) return out_of_range;
sineInfoTable[devnr].frequency = fval;
}
if (dout->dArrayLength > 0)
{ /* prepare multichannel array */
for (i=0; i<NUM_DEVICES; i++)
mcarray[i] = sineInfoTable[i].frequency;
if ((cc=PutValuesFromFloatEx(dout,mcarray,NUM_DEVICES,devnr)) != 0) return cc;
}
return 0;
// omitted code ...
}

The propery "Sine" is a trace style property, whereas the properties "Amplitude" and "Frequency" are multi-channel array properties. Helper routines such as PutValuesFromFloatEx() are ideally suited for manipulating multi-channel arrays, as they take an offset parameter (given by the 'starting' device number) and will 'wrap' the end of the array if the caller requests all values but 'starts in the middle'.

In the case of a java server, a similar approach is shown in the example below.

private int callFrequency(String devName, TDataType dout, TDataType din, TAccess devAccess)
{
int cc = 0;
SineDevice theDevice;
if (devAccess.isWrite())
{ // CLIENT WANTS TO SET FREQUENCY (allow single-channel write)
double[] input = new double[1];
if (din.getArrayLength() != 1) return TErrorList.dimension_error;
theDevice = (SineDevice) myDeviceSet.getDevice(devName);
if (theDevice == null) return TErrorList.illegal_equipment_number;
if ((cc=din.getData(input)) != 0) return cc;
theDevice.setFrequency(input[0]);
}
if (devAccess.isRead())
{ // CLIENT WANTS TO READ (allow multi-channel read)
int nret = dout.getArrayLength(); // what was asked for
int ndv = myDeviceSet.getNumberOfDevices(); // what I've got
int dv = myDeviceSet.getDeviceNumber(devName); // the starting device
if (dv < 0 || dv >= ndv) return TErrorList.illegal_equipment_number;
double[] output = new double[ndv];
for (int i=0; i<ndv; i++)
{
theDevice = (SineDevice) myDeviceSet.getDevice(i);
output[i] = theDevice.getFrequency();
}
cc = dout.putData(output,nret,dv);
}
return cc;
}

Servers which make use of the 'buffered server' layer, such as LabView servers, do not need to supply any special logic as such array behavior is handled automatically within the buffered server.

Further array specifications might include noting that the array is a doubly dimensioned array, in which case a 'row size' needs to be specified, or noting that the array is an array of boolean types (the contents should be interpretted as either TRUE or FALSE).

Of course, in order for various TINE systematics to take effect the array type of a property needs to be registered with the property. If properties are registered via the API registration call RegisterPropertyInformation() (C library), the array type is directly provided as an argument to the registration call. In java, use the constructor for TExportProperty() which takes a TPropertyDescription object. The TPropertyDescription object can hold the array type, row size, and number of rows information.

When registering a property through configuration files, the data type parser can also be told of the array type, e.g. declaring the data format to be, for instance, "float.CHANNEL" rather than simply "float". (Or "float.DOUBLE.32" for a double array with row length = 32).

Alternatively, the array type can be supplied along with the property description. A property's description is first parsed for range, units, and array type information before assigning the given description to the property. For example the property description

"[0:1000 V][-10:100 msec]transient voltage"

would assign the properties minimum and maximum settings (y-axis) to '0' and '1000' and the units (y-axis) to 'V'. In this case the parser sees an additional set of range and units which are assigned to the x-axis. This information by itself is enough to specify the property as being of array type AT_TRACE. The final description assigned to the property is "transient voltage".

Below is a list of the available data array type codes

A TINE query for extended property information returns amoung other information a code specifying the type of data array returned. If the property in question does not return an array, then 'AT_SCALAR' is returned if data are returned at all. 'AT_UNKNOWN' is returned in the case of 'trigger' properties which do not involve data transfer at all (in which case the property's data size is 0).

The codes below are bit-wise unique and can appear in combination.

List of data array type flags

  • AT_UNKNOWN
    • The array type is either unspecified or the property is question does not involve a transfer of data.
  • AT_SCALAR
    • The property does not return an array but instead a single value.
  • AT_SINGLE
    • The property returns a single dimensioned array (i.e. a vector).
  • AT_DOUBLE
    • The property returns a double dimensioned array (a matrix).
  • AT_BOOLEAN
    • The property returns a boolean value (TRUE or FALSE), or it's value should be interpreted in a boolean way, i.e. displayed as "TRUE" or "FALSE".
  • AT_CHANNEL
    • The property returns an array and the array reprsents a multi-channel array, where the array elements represent the associated property values of corresponding device modules. Typically the property is overloaded to return the group of devices beginning with and specified by the device name used in the call and to fill in the requested array up to the length specified. Hence the entire group can be obtained, or a single device, or a subset of the array property so registered. Such arrays are best displayed as a historgram.
  • AT_SPECTRUM (alias AT_TRACE, AT_WAVEFORM)
    • The property returns an array the the array represents a trace or waveform. Such arrays are best displayed as a line trace. The horizontal display information concerning the range and units can likewise be obtained with a call for extended property query information.
  • AT_STRUCTURED (alias AT_COLLECTION)
    • The property returns an array whose elements represent non-plottable information unrelated to a common set of engineering units. For instance an array of long integers where the first gives an number, the second a timestamp, the third a target value, and so on.
  • AT_UNSTRUCTURED (alias AT_BLOB, AT_IMAGE)
    • The property returns an array whose elements are unstructured and are to be manipulated (and understood) by the caller. For instance an image is usually sent and a unstructured byte-blob which needs to be decompressed by the client, before being displayed.
  • AT_JPEG
    • The property returns an array whose elements are to be intpreted as a byte blob representing a JPEG image.
  • AT_MPEG
    • The property returns an array whose elements are to be intpreted as a byte blob representing a MPEG image.
  • AT_BMP
    • The property returns an array whose elements are to be intpreted as a byte blob representing a bitmap image.
  • AT_GIF
    • The property returns an array whose elements are to be intpreted as a byte blob representing a GIF image.
  • AT_WAV
    • The property returns an array whose elements are to be intpreted as a byte blob representing a WAV audio stream.
  • AT_MP3
    • The property returns an array whose elements are to be intpreted as a byte blob representing a MP3 audio stream.
GetDeviceNumber
TINE_EXPORT int GetDeviceNumber(char *eqm, char *devname)
Gives the registered device number for the specified device name.
Definition: srvdbase.c:5339
illegal_read_write
@ illegal_read_write
Definition: errors.h:161
TErrorList
TErrorList
Definition: errors.h:74
DTYPE
Defines a TINE data object.
Definition: tinetype.h:997
out_of_range
@ out_of_range
Definition: errors.h:119
illegal_equipment_number
@ illegal_equipment_number
Definition: errors.h:115
PutValuesFromFloatEx
TINE_EXPORT int PutValuesFromFloatEx(DTYPE *d, float *fval, int num, int offset)
Submits outgoing data from an array of floats.
Definition: toolkit.c:836
GetValuesAsFloat
TINE_EXPORT int GetValuesAsFloat(DTYPE *d, float *fval, int num)
Retrieves incoming data as an array of floats.
Definition: toolkit.c:716
GetPropertyId
TINE_EXPORT int GetPropertyId(char *eqm, char *prpName)
Gives the associated property identifier for the given property name.
Definition: srvdbase.c:5371
DTYPE::dArrayLength
UINT32 dArrayLength
Definition: tinetype.h:999

Impressum   |   Imprint   |   Datenschutzerklaerung   |   Data Privacy Policy   |   Declaration of Accessibility   |   Erklaerung zur Barrierefreiheit
Generated for TINE API by  doxygen 1.5.8