Help with SleepECG package

Hi everybody . im working on a heart rate data with its corresponding realtime timestamps from different subjects. i was trying to use sleepecg package to stage sleep using only heart rate data ,but i got trouble using it . can anyone please help with this . does anyone nows any other solution for this problem . (note that is has to be in python ).thx for reading .

Hi @MashRiza I’ve migrated your question to a new question thread. It’s usually discouraged to tack on new questions to the end of threads that are already solved — it makes searching harder when there are multiple questions in a thread that don’t necessarily match the thread title.

Please edit the title I’ve chosen to be more specific if you can, and provide more details: I think you want to classify sleep stages using only heart rate, but what have you tried so far? Please share code and any error messages / tracebacks that you encountered. Code and errors should be copy/pasted, not screenshots, and please provide links to the data so that others can try to reproduce your same error on their local machines — debugging is much easier if we can reproduce locally!

2 Likes

Hello, @drammock. I am truly excited and grateful to see your patience in reading and crafting a response to my inquiry. Your willingness to assist is greatly appreciated. I must admit that I am new to this environment and was unaware of the conventions and rules. Thank you for offering your guidance.

I chose to engage in this particular topic and respond to the message because the user in question is one of the developers associated with sleepecg. I believed they might be able to help address my predicament. Speaking of the issue at hand, as previously mentioned, I am working with heart rate data. My objective entails employing a Python code to analyze my dataset and generate graphs depicting sleep stages (including REM, non-REM, and awake) in relation to time. This is akin to the functionality found in mobile apps that connect with smartwatches.

My approach thus far has involved attempting to utilize the sleepecg Python package. Although sleepecg offers built-in functions for working with heart rate data, I have encountered difficulties in aligning my data with the sleepecg conventions. Furthermore, I am uncertain which specific method or function within the sleepecg package would be most suitable for my requirements

Did you read the documentation? Did you take a look at the examples? If you need more specific help, please show your code and let us know what does not work (as @drammock has already mentioned).

2 Likes

“I’ve gone through the documentation, but I’m struggling to grasp how to classify sleep stages based solely on heart rate data, without involving ECG signals. I attempted some minor modifications to your provided code to see if I could make progress, but unfortunately, I didn’t achieve the results I was aiming for. Would you be able to lend a hand in this matter? Your assistance would be greatly appreciated.”

So you don’t start with ECG, but you already have the time stamps of R peaks? It would really be easier to help if you provided specific code snippets that you have tried.

@MashRiza, please provide examples of what you’ve tried, what doesn’t work, which error messages you get, and which software versions you’re using. You need to ask concrete questions and provide concrete examples of the issues you encounter. So far you’re basically only saying you tried something and it didn’t work. Nobody can provide useful help with only such unspecific information at hand.

Richard

yes thats right . i dont want to start with ECG . the problem is i dont have any specific code snipped , all i have tried so far was some random changes or tries to use sleepecg functions . sorry about that im really a noob in here . i would be very happy if guide me where to start .

I recommend reading the documentation, and especially the examples. In general, the SleepECG pipeline consists of the following steps:

  1. Read ECG data
  2. Detect R peaks
  3. Extract features from R peaks
  4. Classify features (into sleep stages)

If you don’t have ECG data, you can skip steps 1 and 2 and directly start with 3. If you don’t want to use any of the available pre-computed classifiers, you can train your own classifier to be used in step 4. I know that we need to improve our documentation and include more examples, and I’m already working on including more examples that could be relevant for users. But this will take some time, since I’m very busy with other stuff at the moment.

If you start with changing bits and pieces of available examples and function calls (that’s a good starting point!), we need to know what you tried and what went wrong (the error message). Otherwise, it basically sounds like you want us to implement the whole analysis for you (I know that’s not your intention, but if it was, it is not even clear what exactly you want to do).

2 Likes

I want to thank you once more for your patience in addressing my question. no, I’m not looking for you to implement the entire analysis for me. As I mentioned, I’m relatively new to this and needed some guidance, which you provided exceptionally well. I’m committed to following your instructions diligently and, if needed, I’ll likely reach out with more questions in the future. Thank you again for your invaluable help! .

Great! Let us know if you get stuck and need more help!

I attempted to format my data for use with the SleepECG package, and during the process, I realized that the package requires R-peak timing information for sleep classification (at least, that’s my understanding). To address this requirement, I computed the R-peaks between two sets of heart rate measurements using the following function. Subsequently, I converted the results into a NumPy array

import numpy as np
from sleepecg import (
    load_classifier,
    plot_hypnogram,
    stage,
    SleepRecord,
    extract_features,
    plot_hypnogram,
)
import matplotlib.pyplot as plt

data = [
    {"TimeStamp": "1690495920", "HeartRate": "82"},
    {"TimeStamp": "1690496100", "HeartRate": "62"},
    {"TimeStamp": "1690496160", "HeartRate": "73"},
    {"TimeStamp": "1690496220", "HeartRate": "72"},
    {"TimeStamp": "1690496280", "HeartRate": "76"},
    {"TimeStamp": "1690496400", "HeartRate": "70"},
    {"TimeStamp": "1690496460", "HeartRate": "118"},
    {"TimeStamp": "1690496520", "HeartRate": "84"},
    {"TimeStamp": "1690496580", "HeartRate": "94"},
    {"TimeStamp": "1690496640", "HeartRate": "102"},
]

sleep_stage_duration = 30
timestamps = [int(d["TimeStamp"]) for d in data]
heart_rates = [int(d["HeartRate"]) for d in data]


def generate_synthetic_r_peaks(timestamps, heart_rates, max_peaks=10000):
    peak_count = 0
    current_time = 0  # in unix secon, relative to start of recording
    for i in range(len(timestamps)):
        n_peaks = int((timestamps[i] - current_time) / (60.0 / heart_rates[i]))
        for j in range(n_peaks):
            if peak_count >= max_peaks:
                return
            current_time += 60.0 / heart_rates[i]
            yield current_time  # Yield the R-peak time as needed
            peak_count += 1


# Create a generator for synthetic R-peaks
synthetic_r_peak_generator = generate_synthetic_r_peaks(
    timestamps, heart_rates, max_peaks=10000
)

# Convert to numpy array
synthetic_r_peaks = np.array(list(synthetic_r_peak_generator))

# Create and populate SleepRecord
rec = SleepRecord(
    sleep_stage_duration=sleep_stage_duration, heartbeat_times=synthetic_r_peaks
)
features, stages, feature_ids = extract_features(
    [rec],
    lookback=240,
    lookforward=60,
    feature_selection=["hrv-time", "LF_norm", "HF_norm", "LF_HF_ratio"],
)
X = features[0]

clf = load_classifier("wrn-gru-mesa", "SleepECG")

# Predict stages
stages_pred = stage(clf, rec, return_mode="prob")

# Plotting
plot_hypnogram(rec, stages_pred, stages_mode=clf.stages_mode)
plt.show()

However, when I execute the code, it successfully generates the graph but appears to utilize only the initial few rows of my data. Additionally, I encounter multiple “invalid value encountered in divide” errors, all of which seem to be related to the feature_extraction.py module. error :Lib\site-packages\sleepecg\feature_extraction.py:265: RuntimeWarning: invalid value encountered in divide
CSI = SD2 / SD1
I would greatly appreciate any insights or assistance in resolving these issues. Thank you in advance for your help!

That’s correct.

I will take a look, but can you update your code so that it is self-contained? Currently, several things like timestamps, synthetic_r_peaks_list, and heart_rates are still missing (you can edit your previous post).

“Thank you very much! I’ve updated the post with the complete code and a few sample rows of my data.”

Thanks. I corrected one more minor thing, and I can now run your code. You get these warnings because your simulated RR intervals all have the same length, i.e. zero variance. You don’t see this in physiological signals, so I recommend to introduce a little variance to avoid this behavior.

Why does the graph only display a few rows of data? Is it because of the same reason (same RR intervals)? Another issue I’m encountering is the slow execution of the code, and it doesn’t terminate the process when the graph is drawn. Do you have any recommendations on how I can make it faster and more robust?

I’m not sure what you mean, but the graph contains all 10,000 data points:

Since there is no variability, predicted labels and probabilities also don’t exhibit a lot of variability. Note that the x-axis shows time in hours, whereas the input time points are in seconds. Your simulated beats range from 0 to 2 hours (the labels are not really optimized for such short sequences, which is why there are seemingly duplicate labels, but this is due to rounding).

Regarding the slow execution, it really depends on your computer as well as if you are using optimized packages. For example, it takes only a few seconds on my M2 Pro, but it might be slower if e.g. I was not using the right TensorFlow package.

When you show a plot, execution halts until you close the plot. If you run your code in an interactive interpreter, you can turn on interactive mode in Matplotlib (e.g. with %matplotlib in IPython).

1 Like