Skip to main content

Synchronize multiple signals from different sources.

Project description

Jointly: Signal Synchronizer

The Syncing Process

To sync two sources with each other, they need a simultaneously recorded signal with a characteristic signature at two timepoints in common. This could be the magnitude of the accelerometer for example, if multiple devices are shaken together.

Selecting common segments

The script can detect prominent shakes automatically with the ShakeExtractor. This is done by detecting the peaks above a certain threshold. They are then merged to sequences, if two peaks are not farther apart than a specified distance in milliseconds. Sequences with less than min_length peaks are filtered out. Sequences, that do not start or end in a window of seconds from start and end of the signal respectivley, are filtered in a second step. From these filtered sequences the sequence with the highest weight (mean + median of sequence) is selected for the corresponding segment.

Calculation of the timeshift

To compensate the differences in the system time of different sources, the timeshift to synchronize the selected segments with each other is calculated. For the automatic computation of the timeshift between two signals the cross-correlation for each segment with the reference signal is calculated. The signals are shifted so that the correlation between the selected segments is maximized.

Adjusting the frequency

Due to clock drift, which denotes the issue that a clock is not running at the exact same frequency as a specified reference clock, signals that can be in sync at one timepoint desynchronize gradually over time. To compensate this effect a stretching factor is calculated, which brings the difference between the timeshifts for the synchronization based on the first and second segment respectively to zero. After stretching the signal, the timeshift to align the signals has to be calculated again.

Usage

Syncing data

The data has to be provided in pandas DataFrame with a DateTimeIndex.

import jointly

sources = {
    'Faros': {
        'data': faros.data,
        'ref_column': 'acc_mag',
    },
    'Empatica': {
        'data': empatica.data,
        'ref_column': 'acc_mag',
    },
    'Everion': {
        'data': everion.data,
        'ref_column': 'acc_mag',
    }
}
ref_source_name = 'Empatica'

extractor = jointly.ShakeExtractor()
synchronizer = jointly.Synchronizer(sources, ref_source_name, extractor)
synced_data = synchronizer.get_synced_data()

Saving data

To define the tables, which should be saved, create a dictionary. Every key at root level defines the name of the corresponding file. The dictionary at the second level defines a list of columns, which should be saved in this file, for each source. The save_data() method will also automatically save all data from all sources in a file named TOTAL.csv. This can be deactivated by adding the argument save_total_table = False.

tables = {
    'ACC': {
        'Faros': ['Accelerometer_X', 'Accelerometer_Y', 'Accelerometer_Z'],
        'Empatica': ['acc_x', 'acc_y', 'acc_z'],
        'Everion': ['accx_data', 'accy_data', 'accz_data'],
    },
    'PPG': {
        'Empatica': ['bvp'],
        'Everion': ['blood_pulse_wave', 'led2_data', 'led3_data'],
    },
    'EDA': {
        'Empatica': ['eda'],
        'Everion': ['gsr_electrode'],
    },
    'ECG': {
        'Faros': ['ECG'],
    },
    'TEMP': {
        'Empatica': ['temp'],
        'Everion': ['temperature_object'],
    },
    'HR': {
        'Empatica': ['hr'],
        'Everion': ['heart_rate', 'heart_rate_quality'],
    },   
    'IBI': {
        'Faros': ['HRV'],
        'Empatica': ['ibi'],
        'Everion': ['inter_pulse_interval', 'inter_pulse_interval_deviation'],
    }
}

synchronizer.save_data(sync_dir_path, tables=tables)

Logging

To activate logging simply add the following lines to your code:

from jointly.log import logger
logger.setLevel(10)

This will give you insight into the shake detection, calculation of the timeshifts and stretching factor, and output plots of the segements.

Writing you own segment extractor

Work in progress

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

Jointly-0.1.tar.gz (10.4 kB view hashes)

Uploaded Source

Built Distribution

Jointly-0.1-py3-none-any.whl (11.6 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page