synchronize time base for multiple waves

A recent experiment was run where two datasets were obtained from two different instruments.  The instruments ran independently and saved the measured data to separate files.  I now would like to plot the output of one dataset versus the values from the second.  Since both datasets were one different "clocks" and sampling rates, does anyone have a routine to place both datasets under the same time scale.  This would allow me to plot the measured values against each other rather than only versus time.


If each data set has regular sampling frequency, you can set the wave scaling for the start and time between each point.  Then you can graph the data sets as normal and the scaling will adjust their positions as appropriate.

If the sampling is less regular and you have the time at each data point, then plot the xy pair as appropriate.

If you need to get values for the same time interval from each data set, then I would create a base wave with the time points of interest and interpolate the values from each data set.


I would like to point out a possible fundamental problem with regard to the two separate instruments. If each reports times derived from its own clock (or sampling base), their clock frequencies may not agree, even if the nominal frequencies are the same. Depending on the sampling rates and your desired accuracy, this could be a problem. In a past data acquisition experiment using Igor Pro, I had to synchronize two PCI cards with a common external clock.

I constantly have to deal with this very problem - time is the worst invention IMHO - my strategy is to create a regular reference time base and expand all the errant data onto that time base.

For example say in your example you have insturent 1 sampling at nominally 1hz but drifting around that value, instrument 2 samples at 5 hz probably also drifting around a bit. Decide what data rate you eventually want your data at - say try 1 hz. You can average data on an uneven time base using this peice of (inefficient) code. Beware a free wave is returned , you could modify it to use a pass-by-refference or however you like:

// average a wave which may be on an uneven timebase
Function/WAVE AvgDateTime(Wave dataWv, Wave timeWv, double secs)

    [double beginPnt, double endPnt] = WaveMinAndMax(timeWv)
    int n = round((endPnt - beginPnt) / secs),i,j,k
    Make /O /N=(n) /FREE outWv = NaN
        FindValue /Z /S=(i) /V=(beginPnt + (i+1 * secs)) /T=(secs / 2) timeWV
        k = V_value
        WaveStats /Q /M=1 /R=[j,k] dataWv
        outWv[i] = V_avg
        j = V_value
    while (i < n)  
    return outWv

I probably wouldn't bother averaging your 1hz data, but if there is also no harm in it.

You can then expand the data onto an even time base by first getting the data limits:

// get the limits of waves passed as a list
Function [double minVar,double maxVar] findLimits(String wavList)

    int num = ItemsInList(wavList),i
    Make /O /D /FREE /N=(2 * num) limits
    for (i = 0;i<num;i++)
        Wave wav = $StringFromList(i,wavList)
        WaveStats /Q /M=1 wav // there may be NaN values
        limits[2*i,2*i+1] = {V_min,V_max}
    [minVar,maxVar] = WaveMinandMax(limits) // get the limits
    return [minVar,maxVar]

Make the even time base, I'm assuminmg the instrument time data is already in Igor time:

// get the extent of the time variables - you could manually set your own limits
[double minVar, doublemaxVar] = findLimits("insrument_1_time;instrument_2_time;")

// make a regular time wave
Make /D /N=(1 + maxVar - minVar) timewave = x+minVar

Expand out the data onto the regular time wave:

delta would be 0.5 in the case of 1hz data
t1 is the instrument time wave
t2 is the reference regular time wave
w1 is the data to be expanded 

Again a free wave is returned, but you could modify that

// Performs an expansion but doesn't round t1 and t2 to even fractional seconds. Finds nearest time in t2 within the supplied delta.
// Especially useful for data at faster than 1Hz that isn't on an even time base.
// 20200303 added ability to expand 2D waves, assumes dim0 is the one being expanded
Function/WAVE expand2nearest(t1, w1, t2, delta)
    wave t1, w1, t2
    variable delta
    variable x1, x2, n1, n2 , diff1, diff2
    n1 = numpnts(t1)    //length of timewave1
    n2 = numpnts(t2)    //length of timewave2
    Make /N=(n2,DimSize(w1,1)) /FREE w2=NaN
        diff1 = abs(t2[x2] - t1[x1])
        if (x1+1<n1)
            diff2 = abs(t2[x2] - t1[x1+1])  // only test this if not on last row of t1, else it will be index out of range error.
        if ((diff1 <=  diff2) * (diff1 <= delta) * (numtype(w1[x1]) == 0))    //if this difference is smaller than the next difference, and difference is less than delta, and isn't NaN.
            if (x1 == n1)   // That was the last point for w1, so break. We're done.
            if (x1+1 < n1)
                if ((abs(t1[x1] - t2[x2])) < (abs(t1[x1+1] - t2[x2])))  //only increment x2 if the NEXT point in t1 is farther from t2 than the current point in t1
            else        // can't test if next row would be closer because this is last row of w1. Just test if within delta.
                if (abs(t1[x1] - t2[x2]) > delta)
            if ( t2[x2] < t1[x1] )
    while((x2 < n2 )&&(x1< n1))
    return w2


In reply to by cpr

Thank you for the code, it will be helpful with the full experiment as I will have multiple waves to apply the routine to.  The interpolation routine worked but required redundant effort.  Running a procedure multiple times is more straightforward.