# synchronize time base for multiple waves

wieliczkad

Wed, 10/06/2021 - 09:25 am

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.

Hi,

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.

Andy

October 6, 2021 at 09:46 am - Permalink

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

nominalfrequencies 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.October 6, 2021 at 10:10 am - Permalink

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

expandall 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

do

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

i++

while (i < n)

return outWv

End

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

You can then

expandthe 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}

endfor

[minVar,maxVar] = WaveMinandMax(limits) // get the limits

return [minVar,maxVar]

End

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

[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

do

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.

else

diff2=diff1

endif

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.

w2[x2][]=w1[x1][q]

x1+=1

if (x1 == n1) // That was the last point for w1, so break. We're done.

break

endif

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

x2+=1

endif

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)

x2+=1

endif

endif

else

if ( t2[x2] < t1[x1] )

x2+=1

else

x1+=1

endif

endif

while((x2 < n2 )&&(x1< n1))

return w2

end

October 6, 2021 at 12:36 pm - Permalink

In reply to Hi, If each data set has… by hegedus

Andy:

Thank you for the input. I used your idea for interpolation and created new datasets at the same time intervals. This produced the two waves required to plot one wave versus the other.

October 6, 2021 at 01:51 pm - Permalink

In reply to I constantly have to deal… 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.

October 6, 2021 at 01:55 pm - Permalink