Package: nearest-advocate
Nearest-AdvocateA time delay estimation method for event-based time-series.This repository contains the source code, demonstration data, unit tests, benchmarks as well as research experiments for the Nearest Advocate Algorithm.Github-Repository:https://github.com/iot-salzburg/nearest-advocatePip-Package:https://pypi.org/project/nearest-advocate/.Scope of the packageThis package focuses on the time delay estimation between two event-based time-series that are relatively shifted by an unknown time offset. An event-based time-series is given by a set of timestamps of certain events.
If you want to guarantee synchronous measurements in advance or estimate the time delay of continuous measurements sampled at a constant rate, you might want to use other methods.
However, in some use cases, performing an event detection and then estimating the relative time delay has advantages.
The Nearest Advocate method provides aprecise time delay estimation in event-based time-seriesthat isrobust against imprecise timestamps, a high fraction of missing events, and clock drift.QuickstartInstall the package with:pipinstallnearest_advocateOpen Python and import and use it for time delay estimation of event-based time-series:importnumpyasnpimportnearest_advocateCreate a reference array whose inter-event intervals are sampled from a normal distribution. The signal array is a clone of the reference´, shifted bynp.piand added Gaussian noise. The event's timestamps of both arrays must be sorted.arr_ref=np.sort(np.cumsum(np.random.normal(loc=1,scale=0.25,size=1000)))arr_sig=np.sort(arr_ref+np.pi+np.random.normal(loc=0,scale=0.1,size=1000))The functionnearest_advocate.nearest_advocatereturns a two-columned array with all investigated time-shifts and their mean distances, i.e., the measure of the synchronicity between both arrays (lower is better).time_shifts=nearest_advocate.nearest_advocate(arr_ref=arr_ref,arr_sig=arr_sig,td_min=-60,td_max=60,sps=20)time_shift,min_mean_dist=time_shifts[np.argmin(time_shifts[:,1])]print(f"Found an optimum at{time_shift:.4f}s with a minimal mean distance of{min_mean_dist:.6f}s")#> Found an optimum at 3.15s with a minimal mean distance of 0.079508sThe time delay estimation is 3.15 seconds which is pretty close to the true one.
Create a plot of the resulting characteristic curve of Nearest Advocate, the global minimum of the curve is used as time delay estimation.importmatplotlib.pyplotaspltplt.plot(time_shifts[:,0],time_shifts[:,1],color="steelblue",label="Mean distance")plt.vlines(x=time_shift,ymin=min_mean_dist,ymax=np.mean(time_shifts[:,1]),color="firebrick",label=f"Shift ={time_shift:.2f}s")plt.xlim(time_shift-4,time_shift+4)plt.xlabel("Time delay (s)")plt.ylabel("Mean distance (s)")plt.legend(loc="lower right")plt.show()FunctionalitySymmetric Nearest AdvocateTo apply the Nearest Advocate algorithm symmetrically, just pass the flagsymmetric=Truein the method:time_shifts=nearest_advocate.nearest_advocate(arr_ref=arr_ref,arr_sig=arr_sig,td_min=-60,td_max=60,sps=20,symmetric=True)time_shift,min_mean_dist=time_shifts[np.argmin(time_shifts[:,1])]print(f"Found an optimum at{time_shift:.4f}s with a minimal mean distance of{min_mean_dist:.6f}s")#> Found an optimum at 3.15s with a minimal mean distance of 0.079508sClock-drift correctionUsing the NAd in sliding windows, it is possible to estimate the linear or non-linear trend of the relatve clock drift between two clocks. To do so, both event time-series should be very long in terms of their number of elements.
A Jupyter notebook is provided to adapt this functionality to other applicationsexperiments/application_nonlinear_correction.ipynb.Example of a linear clock-drift correction:Example of a subsequent nonlinear clock-drift correction:Time Delay Estimation based on Different ObservationsThis algorithm is so robust against data quality issues, that it is even possible to estimate the time-delay between two event-based measurements of different observations. Inexperiments/application_different_observations.ipynbit is demonstrated how to apply the NAd for breathing and step events from the same participant, that uses the fact that both frequencies are slightly interdependent.FunctionalityApplied methods for windowed Nearest Advocate, linear and nonlinear clock-drift correction and advanced plotting is provided inexperiments/nearest_advocate_windowedwith sample Jupyter notebooks of how to use them in the parent directory.Building from sourceSetupcd/go/to/path
gitclonehttps://github.com/iot-salzburg/nearest-advocatecdnearest-advocate
pipinstall-rrequirements.txtFor reproducibility, the experiments were run in Python 3.9 inside a container environment using the Docker orchestration software with the imagecschranz/gpu-jupyterand tagv1.4\_cuda-11.0\_ubuntu-20.04, available on Dockerhub.Build the Cython-version of the algorithm with:cdsrc
pythonsetup.pybuild_ext--inplaceRun the testsCurrently, the Cython-version is under development and will be available soon.Run the test scripts:pythontests/test_algorithm.py#> Testing numba-version:          ok#> Testing Cython-version:         ok#> Testing Python-version:         okpythontests/test_performances.py#> ################# Test and compare shifts ###################> Numba:          0.01329827 s,    detected time shift: 3.15 s,    minimal mean distance: 0.084238 s#> Cython:         0.01338649 s,    detected time shift: 3.15 s,    minimal mean distance: 0.084238 s#> Python:         3.06915808 s,    detected time shift: 3.15 s,    minimal mean distance: 0.084238 s#>#> ########## Compare versions for multiple lengths ############> Method      10       100       1000     10000     100000#> Numba:   0.000157  0.000786  0.013276  0.138520  1.402027Reproduce the research experimentsIn the directorynearest_advocate/experiments, multiple Jupyter Notebooks contain experiments based on data in thedatadirectory.CitationWhen using in academic works please cite:Christoph Schranz and Sebastian Mayr. 2022. Ein neuer Algorithmus zur Zeitsynchronisierung von Ereignis- basierten Zeitreihendaten als Alternative zur Kreuzkorrelation. (9 2022). https://doi.org/10.5281/ZENODO.7370958