translationalneuromodeling / tapas

TAPAS - Translational Algorithms for Psychiatry-Advancing Science
https://translationalneuromodeling.github.io/tapas/
GNU General Public License v3.0
219 stars 90 forks source link

PhysIO: strange heart rate (30-40 bpm) #284

Open yanapanikratova opened 1 month ago

yanapanikratova commented 1 month ago

Dear Lars,

Thank you very much for wonderful PhysIO!

I'm trying this toolbox for the first time and have carefully read the documentation. Processing of my data seems to go well, however, the estimated heart rate looks suspicious (it is in the range of 30-40 bpm). At the same time, the heart rate estimated online during scanning (displayed via Philips system) was normal. Could you please clarify why this might happen?

I'm working with PPU Wi-Fi data (Philips 3T Ingenia, a sampling rate of 496 Hz). TR = 2 s, 34 slices, 225 volumes, and 0 dummies.

A Philips logfile: ScanPsaLog20241014143359.log

Parameters from the SPM batch: matlabbatch{1}.spm.tools.physio.save_dir = {'G:\example\physio_out'}; matlabbatch{1}.spm.tools.physio.log_files.vendor = 'Philips'; matlabbatch{1}.spm.tools.physio.log_files.cardiac = {'G:\example\scanphyslog\ScanPsaLog20241014143359.log'}; matlabbatch{1}.spm.tools.physio.log_files.respiration = {'G:\example\scanphyslog\ScanPsaLog20241014143359.log'}; matlabbatch{1}.spm.tools.physio.log_files.scan_timing = {''}; matlabbatch{1}.spm.tools.physio.log_files.sampling_interval = 0.00201612903225806; matlabbatch{1}.spm.tools.physio.log_files.relative_start_acquisition = 0; matlabbatch{1}.spm.tools.physio.log_files.align_scan = 'last'; matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.Nslices = 34; matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.NslicesPerBeat = []; matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.TR = 2; matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.Ndummies = 0; matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.Nscans = 225; matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.onset_slice = 17; matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.time_slice_to_slice = []; matlabbatch{1}.spm.tools.physio.scan_timing.sqpar.Nprep = []; matlabbatch{1}.spm.tools.physio.scan_timing.sync.nominal = struct([]); matlabbatch{1}.spm.tools.physio.preproc.cardiac.modality = 'PPU_Wifi'; matlabbatch{1}.spm.tools.physio.preproc.cardiac.filter.no = struct([]); matlabbatch{1}.spm.tools.physio.preproc.cardiac.initial_cpulse_select.auto_matched.min = 0.4; matlabbatch{1}.spm.tools.physio.preproc.cardiac.initial_cpulse_select.auto_matched.file = 'initial_cpulse_kRpeakfile.mat'; matlabbatch{1}.spm.tools.physio.preproc.cardiac.initial_cpulse_select.auto_matched.max_heart_rate_bpm = 90; matlabbatch{1}.spm.tools.physio.preproc.cardiac.posthoc_cpulse_select.off = struct([]); matlabbatch{1}.spm.tools.physio.preproc.respiratory.filter.passband = [0.01 2]; matlabbatch{1}.spm.tools.physio.preproc.respiratory.despike = false; matlabbatch{1}.spm.tools.physio.model.output_multiple_regressors = 'multiple_regressors.txt'; matlabbatch{1}.spm.tools.physio.model.output_physio = 'physio.mat'; matlabbatch{1}.spm.tools.physio.model.orthogonalise = 'none'; matlabbatch{1}.spm.tools.physio.model.censor_unreliable_recording_intervals = false; matlabbatch{1}.spm.tools.physio.model.retroicor.yes.order.c = 3; matlabbatch{1}.spm.tools.physio.model.retroicor.yes.order.r = 4; matlabbatch{1}.spm.tools.physio.model.retroicor.yes.order.cr = 1; matlabbatch{1}.spm.tools.physio.model.rvt.yes.method = 'hilbert'; matlabbatch{1}.spm.tools.physio.model.rvt.yes.delays = 0; matlabbatch{1}.spm.tools.physio.model.hrv.yes.delays = 0; matlabbatch{1}.spm.tools.physio.model.noise_rois.no = struct([]); matlabbatch{1}.spm.tools.physio.model.movement.no = struct([]); matlabbatch{1}.spm.tools.physio.model.other.no = struct([]); matlabbatch{1}.spm.tools.physio.verbose.level = 2; matlabbatch{1}.spm.tools.physio.verbose.fig_output_file = 'figure_output.jpg'; matlabbatch{1}.spm.tools.physio.verbose.use_tabs = false;

PhysIO output figures: figure_output_01 figure_output_02 figure_output_03 figure_output_04 figure_output_05 figure_output_06 figure_output_07 figure_output_08 figure_output_09

P.S. I have noticed that the x-axis in nearly all figures above includes 1000 s, but I don't understand why (2s TR x 225 volumes = 450 s). Is it normal?

Also, I have found a thread https://github.com/translationalneuromodeling/tapas/issues/207 where Marni has ScanPsa (not SCANPHYSLOG) files and no gradient data -- the same as in my case. Is my case therefore a problem of synchronization?

Additionally, I have tried to adjust log_files.relative_start_acquisition = 26 (this is the difference between time stamps in ScanPsaLog and DICOM) but this did not change anything.

I would be very grateful for your help and apologize if there are some obvious mistakes.

Yana

mrikasper commented 1 month ago

Dear Yana,

Thank you very much for your detailed description and taking the time to read the PhysIO documentation.

  1. It looks indeed as if your logfile does not have any gradient time stamps and you have to resort to nominal/manual timing synchronization. I am not sure that the clock of the system that logs the SCANPHYSLOG time is the same as the one that writes the DICOM headers, but if so, what you did with setting the relative_start_acquisition seems reasonable (maybe double-check the sign)
  2. Regarding the low heart rates, can you horizontally zoom into the Diagnostic Raw Data Figure to a window of about 20 or 30 seconds, so that we can look at the peak detection a bit better?

All the best, Lars

yanapanikratova commented 1 month ago

Dear Lars,

Thank you so much for the quick reply and taking the time to consider my case!

  1. It looks indeed as if your logfile does not have any gradient time stamps and you have to resort to nominal/manual timing synchronization. I am not sure that the clock of the system that logs the SCANPHYSLOG time is the same as the one that writes the DICOM headers, but if so, what you did with setting the relative_start_acquisition seems reasonable (maybe double-check the sign)

The time stamp in DICOM is 14:34:25, and in ScanPsaLog it is 2:33:59 PM. Therefore 26 seconds (with plus sign) seem reasonable. However, I'm also not sure in the equality of the clocks in logging systems. Additionally, when I count the number of rows in ScanPsaLog, there are 243 901 rows with data; 243 901 x 0.0020161 (sampling interval) = 491.73 s; 491.73 - 456 s (fMRI scan time displayed via console 07:36) = 35.73 s. This number is somehow different from 26 s... Do you know an additional way to check this?

  1. Regarding the low heart rates, can you horizontally zoom into the Diagnostic Raw Data Figure to a window of about 20 or 30 seconds, so that we can look at the peak detection a bit better?

Please see the screenshots, I hope I did what you asked for right: 1 2 3

Grateful for your help, Yana

mrikasper commented 1 month ago

Dear Yana,

  1. For the zooming, can you please also include the red curves and detected peaks (red stems) into the zoom?

Thank you! Lars

yanapanikratova commented 1 month ago

Dear Lars,

I'm sorry for the misunderstanding. Please find the images below 1 2 3

mrikasper commented 1 month ago

Dear Yana,

The detected peaks look really odd. I am contemplating whether this could be an old bug that I thought I fixed for the new PhysIO versions. Can you type tapas_physio_version to let me know which release of PhysIO you are using, please?

Also, can you please zoom in a bit further into the plots, e.g., showing tiem 600 to 620s with a y-range of -1 to +1.

Thank you for your help!

All the best, Lars

yanapanikratova commented 1 month ago

Dear Lars,

I have recently downloded PhysIO, the version is R2022a-v8.1.0.

A screenshot: 1

Please let me know if you need other kinds of graphs or information, I'll be happy to provide them.

Many thanks for your help, Yana