HI_Interpolate

HI_Interpolate — queries history data for interpolation.

Syntax

#include <cogent.h>
ST_STATUS HI_Interpolate(IP_hTASK  historian,
 char*  retbuf,
 int  buflen,
 char*  histname,
 char*  interpolator,
 double  start,
 double  duration,
 int  nxargs,
 char**  xargs,
 int*  bufferid);

Arguments

historian

The task pointer to the Cascade Historian program.

retbuf

An optional buffer containing an error message.

buflen

The length in bytes of retbuf. If retbuf is non-NULL, this must be a valid non-zero length. If retbuf is NULL, this parameter is ignored.

histname

The name of a history.

interpolator

The name of the interpolator to use, as described below.

start

The start of the time range of interest for query. If this value is 0, it defaults to the time of the first data value available for the history.

duration

The amount of time, in seconds, over which to perform the interpolation. If this value is 0, it defaults to the length of time between that specified by start and the time of the last data value available for the history.

nxargs

The number of extra arguments to the interpolator.

xargs

The array of extra arguments to the interpolator, as strings.

bufferid

A query ID number for the interpolation. This is a return argument.

Returns

ST_OK on success. Otherwise ST_ERROR, and the retbuf will contain a NULL-terminated character string with an error message. If the return value is ST_OK, the retbuf may not contain useful information.

Description

This function performs a query on history data, placing the result in a buffer for subsequent transfer. It generates a unique, sequentially numbered ID 'handle' for each query that is made, so clients can access the resulting buffer. The IDs have no meaning outside the Cascade Historian, and are only valid after a query and until the buffer is freed with the bufferIdDestroy command, the HIBufferIDDestroy Cogent C API function, or the hist_buffer_id_destroy dynamic library function, as appropriate.

This is the first of four steps (which can be done as commands, dynamic libary functions, or API functions) required to make an interpolation:

  1. A call to interpolate, hist_interpolate, or HI_Interpolate performs a query on history data, placing the result in a buffer for subsequent transfer.
  2. A call to bufferIdLength, hist_buffer_id_length, or HI_BufferIDLength gets the length of the interpolation buffer.
  3. A call to bufferIdData, bufferIdDataAscii, hist_buffer_id_read, or HI_BufferIDRead brings in the data from the interpolation buffer.
  4. A call to bufferIdDestroy, hist_buffer_id_destroy, or HI_BufferIDDestroy destroys the interpolation buffer. This should always be done to free up memory.

This task has been divided into four steps for convenience and performance. A buffer, once created, remains available to be read as required, potentially by multiple users, until it is no longer needed and can be destroyed. The buffers can also be very large, exceeding typical IPC message sizes, and requiring a relatively long time to transfer. That problem can be addressed by transferring the data in predictably-sized portions, allowing other processing to be done in between. The multi-step process defined above provides the flexibility needed for just such tailoring to the user's requirements. To run all four steps with one function call, see HI_InterpolateData in the Cogent C API manual or the hist_interpolate_data dynamic library function.

The following choices are available for the interpolator argument:

[Note]

The NoInterpolator function is currently the only one that requires no additional parameters, making it possible to not supply start or duration. For the other interpolator functions, setting start or duration to 0 forces the default values.

    NoInterpolator simply returns all data that falls within the specified time range. No other processing is performed. When calling the HI_Interpolate function, this interpolator requires no extra arguments (nxargs = 0, xargs = NULL).

    PeriodicInterpolator generates data as Y vs. time on an even time interval. The first extra argument is a double-precision float indicating the time interval in seconds. The second (optional) extra argument is a double-precision float indicating the maximum gap time: if provided and the time between two data samples exceeds this threshold, then data cannot be interpolated between the points. This suppresses generating interpolated data during 'gaps' in the data.

    RelativeInterpolator generates Y vs. X at all known values of X. The first extra argument is a string indicating the history name for X. The history argument provided to interpolate command (or the histname argument provided to HI_Interpolate function) is used as the Y history.

    FixedRelativeInterpolator generates Y vs. X on an even time interval. The first extra argument is a string indicating the history name for X. The second extra argument is a double specifying the time interval. The history argument provided to interpolate command (or the histname argument provided to HI_Interpolate function) is used as the Y history.

This function corresponds to the Cascade Historian interpolate command and the hist_interpolate dynamic library function.

Example

The following example is the code for the HI_InterpolateData function. It demonstrates how HI_Interpolate is used with HI_BufferIDLength, HI_BufferIDRead, and HI_BufferIDDestroy.

ST_STATUS HI_InterpolateData (IP_hTASK historian, char* histname,
                              char* interpolator,
                              double start, double duration,
                              int nxargs, char** xargs,
                              HI_stVALUE** values, int *nvalues)
{
  static char           retbuf[256];
  ST_STATUS             status;
  int                   n, bufid;
  HI_stVALUE            *hvalues;

  status = HI_Interpolate (historian, retbuf, sizeof(retbuf),
                           histname, interpolator, start, duration,
                           nxargs, xargs, &bufid);
  if (status == ST_OK)
    {
      status = HI_BufferIDLength (historian, NULL, 0, bufid, &n);
      if (status == ST_OK)
        {
          hvalues = (HI_stVALUE*) ME_ZMalloc (n * sizeof(HI_stVALUE));
          if (hvalues)
            {
              status = HI_BufferIDRead (historian, NULL, 0,
                                        bufid, 0, n, hvalues);
              if (status == ST_OK)
                {
                  *values = hvalues;
                  *nvalues = n;
                }
              else
                {
                  ME_Free (hvalues);
                  *values = NULL;
                }
            }
        }
      HI_BufferIDDestroy (historian, NULL, 0, bufid);
    }
  return (status);