MarcusVollmer / HRV

Methods for analyzing Heart Rate Variability
http://marcusvollmer.github.io/HRV/
MIT License
83 stars 37 forks source link

Mac compatibility for acq2mat and event markers #22

Open LinnDot opened 1 year ago

LinnDot commented 1 year ago

Hej!

I want to automise my HRV analyses and have a Mac (OS Monterey 12.6) with Matlab R 2022a. I recorded data with BioPac AcqKnowledge.

I have two questions:

  1. When I tried to convert my files in Matlab, I got errors, but I also read that Jimmy Shen's code seems to be for Windows users? Does anyone have experience with using this toolbox and specifically the part of converting Ace to Mat files with Mac?

  2. I read on the BioPac documentation that when using Matlab, the event labels from the .acq file (stimulus events based on digital markers for example) would not be converted into Matlab, is that the case and if yes, is there a workaround?

Unfortunately, I am rather new to both HRV analyses and Matlab..

Thanks for any tips or help! :-)

Best Linn

MarcusVollmer commented 1 year ago

Hi Linn,

I cannot run Matlab on a MacBook currently, but I will give it a try with a sample acq file soon. Nevertheless I believe that it's no a problem of the operating system. The code of J Shen has platform compatibility as the load_acq.m does only contain Matlab standard functions, see https://www.mathworks.com/matlabcentral/fileexchange/14562-load-biopac-acq-acqknowledge-for-pc-data.

  1. Can you give more details about the error? It should give the line of load_acq were the process stops with some details what cannot be evaluated.
  2. Markers can be read with the function by a modification of Antonio Molins. Can you tell which AcqKnowledge version you are using? The function to load ACQ is rather old and may require a small update to load newer file versions.

Best, Marcus

LinnDot commented 1 year ago

Hej Marcus,

Thank you for your e-mail and offering your support! Very appreciated!

Considering the initial error I got, I had a coleague writing me a new script for transferring the HRV data from .acq to .mat which worked fine in the end. I uploaded the script I used and one example data set (T1_subject2.mat) here in case you would like to have a closer look: https://drive.google.com/drive/folders/1YSSTZe4HyrK2fZGUD6z9lD0cv8txK4yF?usp=sharing

However when trying to import the data after opening the GUI of your toolbox, I get a new error:

  1. Here is a screenshot of the error message I get currently when trying to import the data set: [A screenshot of a computer Description automatically generated] I am not proficient in Matlab but I guess the error concerning “zeros – array exceeding maximum possible variable size” refers to the dataset being too large?

  2. We recorded the data with AcqKnowledge 5.0

Thanks again and best regards from Lund, Linn

MarcusVollmer commented 1 year ago

Dear Linn,

I imported your data into Matlab and I have the feeling that the acq file was not converted to mat correctly. According to the header Channels 4 to Channel 11 should contain signals on voltage scale. Plotting these signals such as plot(acq_data.data(:,4)) will not show an ECG. It's rather a mixture of 14 different signals. Plotting every 14th value, will indeed show some ECG channel: plot(acq_data.data(5:14:end,4)) Please try to export the signals in a different file format. According to the documentation of AcqKnowledge5 you should be able to export signals as PhysioNet WFDB, wav, txt or EDF. I recommend to export the ECGs as EDF, that can be easily imported in HRVTool.

Best, Marcus

LinnDot commented 1 year ago

Dear Marcus,

thank you for looking deeper into my file! I tried to export one file from .acq to an EDF and it was indeed imported into your tool box, thank you! 😊 Now I try to find my way through the interface and make sense of all the functions and buttons. 😉 Happy you provided even tutorials here http://marcusvollmer.github.io/HRV/

One more question since I have read that event importing to matlab from acq can be quite tricky: Do you have any further recommendation about how to best attach the event labels to the data in this format (EDF)? I want to run a spectral analysis on certain parts of the data which are timewise marked by event labels (marking up to 320 trials in different conditions).

Thank you again!

Best regards Linn

MarcusVollmer commented 1 year ago

Dear Linn,

I'm happy for you that it works well with EDF. You can try to export the event labels as a separate file. When writing an analysis script you can load loop the parts to extract the information you need. To extract certain HRV parameters you can use the functions available from the Matlab class HRV.m. Please have a look into the sample script HRV_sample_batchjob.m and loop over the parts of each recording.

Best, Marcus

LinnDot commented 1 year ago

Thank you! I exported the event label file as an excel and try now to somehow fit it to my edf file. Therefore I guess I would have to load my edf file into matlab. I found this part in the sample.batchjob code you recommended:

% Import waveform (ECG) - use an appropriate import function sig_waveform = loadwaveform; Ann = [];

So far I failed to use an appropriate import function apparently for my edf file to load into matlab so I could use it for further analyses. I downloaded as well the signal processing toolbox which has an EDF reader. Unfortunately I am not very skilled in Matlab as one can tell.

Do you have a recommendation how to load my ECG waveform into matlab so I could attach the event labels and do the HRV analyses you offer in your functions?

Best regards Linn

MarcusVollmer commented 1 year ago

Hi Linn,

you can use read_edf of my toolbox to import the data from edf files:

[record, signals, start_date, header, header2] = read_edf(fname);

record does contain all waveforms stored in the edf. signals does contain the description of waveforms. Please notice the start_date that might be useful for you to identify the starting frames of your event labels.

Best, Marcus

LinnDot commented 1 year ago

Thank you very much, I will give this a try! Start_date seems very useful, though atm I try first to figure out how to merge my event labels to the edf file in matlab so I can select the meaningful parts in my data for the analysis. 😊

LinnDot commented 1 year ago

Dear Marcus,

I have another question. I managed to extract the respective onset times for the event labels of interest (from my different experimental conditions) from Acqknowledge into xlsx and into Matlab.l I created vectors with one column showing my labels, one column with the respective onset time in seconds. Now I am a little clueless how to continue…

How could I potentially loop over as you suggested over certain parts of interest in my ecg data using your batchjob.m script so that with the help of my time&label vector only parts of my edf file get extracted? I guess I first use your read_edf function to load the waveform into matlab and then, for example for detecting of heart beats in the times of interest, should I change something in this part of the script so it could access the times indicated in my vector?

% Heart beat detection seg = ceil(length(sig_waveform)/(300Fs)); if seg>2 for i=0:seg sig_waveform_tmp = sig_waveform(max(300Fsi-10Fs,1):min(300Fs(i+1),length(sig_waveform))); if sum(isnan(sig_waveform_tmp)) ~= length(sig_waveform_tmp) Ann_tmp = singleqrs(sig_waveform_tmp,Fs,'downsampling',d_fs,'Beat_min',Beat_min,'Beat_max',Beat_max,'wl_tma',wl_tma,'wl_we',wl_we); Ann = [Ann; Ann_tmp+max(300Fsi-10Fs,1)]; end end Ann = Ann(Ann>0 & Ann<=length(sig_waveform)); Ann = unique(sort(Ann)); Ann(diff(Ann)<.05Fs)=[]; else Ann = singleqrs(sig_waveform,Fs,'downsampling',d_fs,'Beat_min',Beat_min,'Beat_max',Beat_max,'wl_tma',wl_tma,'wl_we',wl_we); end Ann = Ann/Fs;

Thank you! 😊

Best regards Linn

MarcusVollmer commented 1 year ago

Dear Linn,

The code you sent is a loop to generate beat annotations of the entire recording. The locations of each beat are stored in the vector Ann and is in seconds. You should now proceed using another loop over your time frames running from event onset to event offset each. Annotations that fall into the time frame can be identified using a selection based on logical conditions:

CurrentAnn = Ann(Ann>=onset[i] & Ann<=offset[i]);
CurrentRR = diff(CurrentAnn);

This may be included in your loop (over i time frames) to get the annotations that are available in each period. You can then use HRV methods applied to the respective RR intervals.

Best, Marcus