-
-
Notifications
You must be signed in to change notification settings - Fork 441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dev - Symbolic dynamics HRV parameters added #1057
base: dev
Are you sure you want to change the base?
Conversation
Thanks for opening this pull request! We'll make sure it's perfect before merging 🤗 |
@Tam-Pham kind bump |
@Tam-Pham bump x2 |
@mrosol thanks a lot for that very interesting paper (and sorry for the delay in reviewing it 😩) |
@DominiqueMakowski I thought to separate it from the code clarity perspective, not to extend the file with nonlinear parameters too much, but it might go over there as well. Do you want me to move it from |
60c3734
to
ef4d7f0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @mrosol
I'm so so so sorry for the late review. It has been a few hectic months for me.
Thank you for your contribution to the package. Symbolic dynamic metrics are indeed interesting and novel parameters for the ANS activities.
I agree that they could be placed under the non-linear domain as similar to other metrics there, they are capturing the dynamics in the signal that are distinct from the traditional statistical or frequency-based metrics. However, I'm not sure how to incorporate them into the existing function.
@mrosol I have added just 2 comments - 1 of them would need @DominiqueMakowski inputs with the naming convention. Other than that, the code looks great :) Thanks so much
neurokit2/hrv/hrv_symdyn.py
Outdated
A dictionary with keys corresponding to the symbolic dynamics families ('0V', '1V', '2LV', '2UV') | ||
and values representing the normalized counts of words belonging to each family. | ||
""" | ||
families = {'0V': 0, '1V': 0, '2LV': 0, '2UV': 0} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest making a few revisions to improve the efficiency of this function:
- using
np.unique()
instead oflen(set(word))
to avoid processing one word at a time in a loop
words = np.array(words) # Ensure input is a NumPy array
unique_counts = np.apply_along_axis(lambda w: len(np.unique(w)), 1, words)
- accumulate raw count using
np.sum()
without looping
families = {
'0V': np.sum(unique_counts == 1),
'1V': np.sum(unique_counts == 2),
'2LV': np.sum((unique_counts == 3) & ((words[:, 1] > words[:, 0]) & (words[:, 2] > words[:, 1]) |
(words[:, 1] < words[:, 0]) & (words[:, 2] < words[:, 1]))),
'2UV': np.sum((unique_counts == 3) & ~((words[:, 1] > words[:, 0]) & (words[:, 2] > words[:, 1]) |
(words[:, 1] < words[:, 0]) & (words[:, 2] < words[:, 1]))),
}
- calculate
len(words)
just once
total_words = len(words)
for key in families:
families[key] /= total_words
neurokit2/hrv/hrv_symdyn.py
Outdated
* **SymDynSigma0.05_1V**: Indicates the percentage of sequences with one variation, derived using the σ method. | ||
* **SymDynSigma0.05_2LV**: Reflects the percentage of sequences with two like variations, as quantized by the σ method. | ||
* **SymDynSigma0.05_2UV**: Shows the percentage of sequences with two unlike variations, according to the σ method. | ||
* **SymDynEqualPorba4_0V**: Represents the percentage of sequences with zero variation, derived using the Equal-Probability method with quantization level 4, ensuring each level has the same number of points. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be "Proba" instead of "Porba"?
Anyway, in terms of naming output variables, we don't have an existing naming convention with the method inside the variable names (@DominiqueMakowski correct me if I'm wrong). Would SymDyn_EqualProb4_1V
instead of SymDynEqualProb4_1V
be clearer?
Description
This PR aims at adding calculation of symbolic dynamics HRV parameters [1-5]
[1] Cysarz, D., Edelhäuser, F., Javorka, M., Montano, N., and Porta, A. (2018). On the relevance of symbolizing heart rate variability by means of a percentile-based coarse graining approach. Physiol. Meas. 39:105010. doi: 10.1088/1361-6579/aae302
[2] Cysarz, D., Porta, A., Montano, N., Leeuwen, P. V., Kurths, J., and Wessel, N. (2013). Quantifying heart rate dynamics using different approaches of symbolic dynamics. Eur. Phys. J. Spec. Top. 222, 487–500. doi: 10.1140/epjst/e2013-01854-7
[3] Wessel, N., Malberg, H., Bauernschmitt, R., and Kurths, J. (2007). Nonlinear methods of cardiovascular physics and their clinical applicability. Int. J. Bifurc. Chaos 17, 3325–3371. doi: 10.1142/s0218127407019093
[4] Porta, A., Tobaldini, E., Guzzetti, S., Furlan, R., Montano, N., and Gnecchi-Ruscone, T. (2007). Assessment of cardiac autonomic modulation during graded head-up tilt by symbolic analysis of heart rate variability. Am. J. Physiol. Heart Circ. Physiol. 293, H702–H708. doi: 10.1152/ajpheart.00006.2007
[5] Gąsior, J. S., Rosoł, M., Młyńczak, M., Flatt, A. A., Hoffmann, B., Baranowski, R., Werner, B. (2022). Reliability of Symbolic Analysis of Heart Rate Variability and Its Changes During Sympathetic Stimulation in Elite Modern Pentathlon Athletes: A Pilot Study. Front. Physiol. 13, doi: 10.3389/fphys.2022.829887
Proposed Changes
I added
neurokit2/hrv/hrv_symdyn.py
and changed the following filesneurokit2/hrv/hrv.py
,neurokit2/hrv/__init__.py
,tests/tests_hrv.py
,docs/functions/hrv.rst
Checklist
Here are some things to check before creating the PR. If you encounter any issues, do let us know :)