neuropsychology / NeuroKit

NeuroKit2: The Python Toolbox for Neurophysiological Signal Processing
https://neuropsychology.github.io/NeuroKit
MIT License
1.58k stars 420 forks source link

ECG simulation method based on deepfake-ecg #467

Closed DominiqueMakowski closed 2 years ago

DominiqueMakowski commented 3 years ago

Can add this as a method for ECG simulation: https://github.com/vlbthambawita/deepfake-ecg

We'd need to check for the installation of that package (and if not tell to run pip install deepfake-ecg) and then run

import deepfakeecg

#deepfakeecg.generate("number of ECG to generate", "Path to generate", "start file ids from this number", "device to run") 

deepfakeecg.generate(5, ".", start_id=0, run_device="cpu") # Generate 5 ECGs to the current folder starting from id=0

If no possibility to directly load the data (i.e., if it can only save a file on the disk), we can save the file, load it and then delete it.

zen-juen commented 3 years ago

We can probably do something like this

def _ecg_simulate_deepfake(n_heartbeats=5):

    # Try loading deepfakeecg
    try:
        import deepfakeecg
    except ImportError:
        raise ImportError(
            "NeuroKit error: _ecg_simulate_deepfake(): the 'deepfakeecg' module is required ",
            "for this function to run. ",
            "Please install it first (`pip install deepfakeecg`).",
        )

    # Generate n_heartbeats ECGs to the current folder starting from id=0
    deepfakeecg.generate(n_heartbeats, ".", start_id=0, run_device="cpu") 

    current_path = os.getcwd()

    data_list = []
    for i in range(n_heartbeats):
        file_name = str(i) + '.asc'
        file = os.path.join(current_path, file_name)
        data = np.loadtxt(file, skiprows=0)
        ecg = np.concatenate(data)
        data_list.append(ecg)

        # remove files
        os.remove(file)

    return data_list

with data_list being something like

Out[13]: 
[array([ -61.,  169.,  -62., ...,  -11., -113.,  -37.]),
 array([-162.,  113.,   -9., ...,  -15.,  -86.,  -35.]),
 array([ -63.,  -32.,  -24., ...,  -74., -150., -125.]),
 array([-144.,   19.,   30., ...,  175.,  181.,  164.]),
 array([ -39., -137.,   79., ...,   -5.,  -77.,  -63.])]

Based on the deepfakeecg source code, the only variable parameter is the number of signals (specified as n_heartbeats here) that you can generate. I'm not sure what's the best way of incorporating it into our ecg module so that it is consistent with the rest of the other internal methods while also making full use of the package's capacity. In this example here I store 5 ecg signals (one array being one signal) in data_list - from this, we can either randomly choose one signal to return as the final simulated output or we can also scrap the n_heartbeats argument entirely and just default to returning one signal.

DominiqueMakowski commented 3 years ago

so each "signal" is one QRS complex? In that case I suppose we can assemble them to make a continuous signal with multiple beats?

zen-juen commented 3 years ago

Nope one signal is the full signal itself

pd.Series(data_list[0]).plot()

Figure_1

alexxony commented 3 years ago

There are some missing values Due to bluetooth disconnection.

Can this make complement for missing value area?

I thinks it is beneficial for R peaks detection

zen-juen commented 3 years ago

Hi @alexxony I don't get quite what you mean here, do you mean with this specific implementation of simulating ecg using deepfake?

stale[bot] commented 2 years ago

This issue has been automatically marked as inactive because it has not had recent activity. It will eventually be closed if no further activity occurs.

stale[bot] commented 2 years ago

This issue has been inactive for a long time. We're closing it (but feel free to reopen it if need be).