Next: Data Object Attributes Up: Some Functions and Methods Previous: Utilities for Handling Cartesian Contents

## Joining Time Series Data

A utility to join several time series objects onto a single timeline is provided in qdos, and a simple utility call to access it is provided which also ensures the metadata and ttimelines are set correctly for the joined objects.

      #include qdutil.h;

       QuMultiJoin( QdObjectSeq_var        ToJoin_obj_seq,
                    QdTimeSeq_var          tt_target,
                    QdObjectSeq_var        Joined_obj_seq,
                    vector<KVDataBase_var> options,
                    int                    triage_cnt = -1);

  If we have N qdos time series objects to join the arguments would be:

  `ToJoin_obj_seq` is a sequence of N QdRScalarSeq_var and/or QdRMatrixSeq_var objects (multijoin can accept data series of different type and dimensionality), and holds the N input data series that are to be joined onto a new timeline.

  `tt_target` is a single QdTimeSeq_var holding the new set of timetags that the all time series are to be joined onto.

  `Joined_obj_seq` is a QdObjectSeq_var pointer that will return a sequence of length N holding the output data series - on return each entry will be a data series of the corresponding type and dimensionality as the input series at the same index. This sequence does not need to be populated before calling QuMultiJoin(), but if it does contain objects, they must match the dimensionality of the corresponding input objects, and these objects will be overwritten.

  `options` is a vector of N KVDataBase_var objects holding the join options selected independently for each input object. See example for how to set these options. They cover the `join algorithm` ( LINEAR, BOXCAR, and NEAREST_NEIGHBOUR ), `gap_value` (the width in seconds to be used as the maximum input time tag separation above which the data is deemed to have a gap), `gap_handler` ( the action to be taken if a gap is detected in the corresponding data series. REMOVE_GAP, ZERO_FILL_GAP, FILL_GAP (with fillval), LINEAR_INTERP_GAP or NEAREST_NEIGHBOUR_GAP). This object also holds the new name to be used for the output object.

  Note that `join_method`, `gap_value`, and `gap_handler` must all be set for each of the input data series, and need not be the same for each series.

  `triage_cnt` determines how many of the input series must contain data at any time tag in order for that point to be included in the output sequences. Hence if any input series has gap_handler set to remove gaps, then `triage_cnt` is set to the number of input data series, in all other cases it is set to zero.

  Note also that multijoin will work with any dependent variable, not just time, but the utility QuMultiJoin is specific to time series joining.

       #include "Qdos.h"
       #include "qdutil.h"
       // join 4 data series onto time tags (5th arg in PlugIn list)
       int nSeq = 4;
       int triage_cnt = 0;
       QdObjectSeq_var ToJoin_obj_seq;
       QdObjectSeq_var Joined_obj_seq;
       vector<KVDataBase_var> options;

       QdTimeSeq_var qdtt = get_timetags((*arglist)[4]); // safe against null obj

       if ( qdtt.is_nil() )
       {
          QplugAppendTextDisplay ("invalid target time tags\n");
          return QPLUG_FAILURE;
       }
       for ( int i=0; i<nSeq; i++)
       {
          QdObject_var obj = (*arglist)[i];

          // set options for object

          KVDataBase_var obj_options;

      	// fill value
      	QdRScalar_var    fillval_ptr;
      	if ( obj->xref_exists( "FILLVAL" ) )
      	{
      		QdObject_var fill_xref = obj->get_xref( "FILLVAL" );
      		fillval_ptr            = QdRScalar_var::narrow( fill_xref );
      	}
      	if ( fillval_ptr.is_nil() )
      	{
      		fillval_ptr = new QdRScalar( ( double ) 0.1e-30 );
      	}
      	obj_options->set( FILL_VALUE, fillval_ptr );

      	// gap tolerance in seconds
      	QdTime_var gap_ptr = new QdTime( Seconds( 6 ) );
      	obj_options->set( GAP_TOLERANCE, gap_ptr );

      	// boxcar width in seconds
      	QdTime_var boxcar_ptr = new QdTime( Seconds(60 ) );
      	obj_options->set( BOXCAR_WIDTH, boxcar_ptr );

      	// interpolation method
      	QdString_var interp_ptr = new QdString( LINEAR );
      	obj_options->set( INTERP_METHOD, interp_ptr );

      	// gap handling option
      	QdString_var gap_opt_ptr = new QdString( ZERO_FILL_GAP,  );
      	obj_options->set( GAP_METHOD, gap_opt_ptr );

      	QdString_var new_obj_name = new QdString( getSlotText(i) + "_joined");
      	obj_options->set( NEW_NAME, new_obj_name );

          ToJoin_obj_seq->push_back( obj );
          options.push_back( obj_options );

       }

       // Do actual join
       try
       {
          QuMultiJoin( ToJoin_obj_seq, qdtt, Joined_obj_seq, options );
       }
       catch( Exception &e )
       {
          QplugAppendTextDisplay (e.msg().c_str());
          return QPLUG_FAILURE;
       }

       for(int i=0;i<nSeq;i++)
       {
         // return each object to qsas
         call_list->push_back((QdObject_var) Joined_obj_seq[i]);
       }

  Note that using the QuMultiJoin() utility it is no longer necessary to attatch the target time tags or input sequence Xrefs to the output objects as this is done by the utility.

Next: Data Object Attributes Up: Some Functions and Methods Previous: Utilities for Handling Cartesian Contents