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 Not Accepting 7T .resp, .ext and .puls Files? #283

Open EmilyJD777 opened 1 month ago

EmilyJD777 commented 1 month ago

Hi there,

I've got raw PMU fomatted data for Siemens 7T fMRI (as .ext. .puls and .resp files). I can't seem to get PhysIO to read the formatting, which looks like this: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5003 ECG Freq Per: 0 0 PULS Freq Per: 65 911 RESP Freq Per: 10 5980 EXT Freq Per: 0 0 EXT2 Freq Per: 0 0 ECG Min Max Avg StdDiff: 110 545 276 123 PULS Min Max Avg StdDiff: 547 2823 909 15 RESP Min Max Avg StdDiff: 3380 11720 5859 776 EXT Min Max Avg StdDiff: 1660 30005 6694 4698 EXT2 Min Max Avg StdDiff: 0 0 0 0 NrTrig NrMP NrArr AcqWin: 0 0 0 0 LogStartMDHTime: 9405947 LogStopMDHTime: 14579527 LogStartMPCUTime: 37313200 LogStopMPCUTime: 42486697 6003

Is this is known issue in PhysIO or have I missed something? Any help you might have would be greatly appreciated. Thanks again!

mrikasper commented 1 month ago

Dear Emily,

Thank you for trying out the PhysIO Toolbox!

This looks like the standard Siemens VB / IdeaCmdTool log format, and you could start from that example to adapt your script or matlab job. Would you be able to export your job file as a .m and paste it here. Or provide some error message output when you try to run it?

Thank you and

All the best, Lars

EmilyJD777 commented 1 month ago

Hi Lars,

Thanks for your quick response! Here is a copy of the base script I am trying to get functional: ` logDir = 'Z:\derivatives\brainstem_funk\BIDS_DAY2\sub-001\physio'; % /baseDir/physio/s01/run01 cd (logDir); PULS = dir('.puls'); RESP = dir('.resp'); EXT = dir('*.ext');

% 2. Define physio model structure physio = tapas_physio_new();

% 3. Define input files physio.save_dir = 'Z:\derivatives\brainstem_funk\BIDS_DAY2\sub-001\physio'; % enter directory to save physIO output physio.log_files.cardiac = 'sub-001_allruns.puls'; % .puls file physio.log_files.respiration = 'sub-001_allruns.resp'; % .resp file physio.log_files.scan_timing = 'sub-001_allruns.ext'; % Log file physio.log_files.vendor = 'Siemens_Tics'; % Vendor physio.log_files.relative_start_acquisition = 0; % only used for Philips physio.log_files.align_scan = 'last'; % sync log and EPI files from the last scan

% 4. Define scan timing parameters physio.scan_timing.sqpar.Nslices = 52; % number of slices in EPI volume physio.scan_timing.sqpar.TR = 1; % TR in secs physio.scan_timing.sqpar.Ndummies = 0; % Real dummy are not recorded physio.scan_timing.sqpar.Nscans = 426; % number of time points/scans/volumes physio.scan_timing.sqpar.onset_slice = 51; % slice of interest (choose middle slice if unsure?) physio.scan_timing.sync.method = 'scan_timing_log'; % using info file

% 5. Define cardiac data parameters physio.preproc.cardiac.modality = 'PPU'; % cardiac data acquired with PPU physio.preproc.cardiac.initial_cpulse_select.auto_matched.min = -0.4; physio.preproc.cardiac.initial_cpulse_select.auto_matched.file = 'initial_cpulse_kRpeakfile.mat'; physio.preproc.cardiac.posthoc_cpulse_select.off = struct([]);

% 6. Define generic physio model parameters physio.model.orthogonalise = 'none'; physio.model.output_multiple_regressors = 'multiple_regressors.txt'; %% regressor output filename`

Here is the error I am getting: `Error using regexp The 'STRING' input must be either a char row vector, a cell array of char row vectors, or a string array.

Error in tapas_physio_read_columnar_textfiles (line 107) haveFoundColumnHeader = any(regexp(upper(strLine), strColumnHeader));

Error in tapas_physio_read_physlogfiles_siemens_tics (line 109) C = tapas_physio_read_columnar_textfiles(log_files.respiration, 'RESP');

Error in tapas_physio_read_physlogfiles (line 92) tapas_physio_read_physlogfiles_siemens_tics(log_files, cardiac_modality, verbose);

Error in tapas_physio_main_create_regressors (line 121) verbose] = tapas_physio_read_physlogfiles(...

Error in physIO_example_script_TEST (line 82) tapas_physio_main_create_regressors(physio);`

Is Siemens_Tics the proper input for physio.log_files.vendor? Or is this error related to something else? It's looks like formatting to me.

mrikasper commented 1 month ago

Dear Emily,

The format you have is not Siemens_Tics, but Siemens. You will have to change this in the physio.log_files.vendor field.

Have a look at the example data for PhysIO: After typing tapas_init() in the TAPAS main folder, download the example data via tapas_download_example_data() and check the tapas/examples/<your_version>/PhysIO/Siemens_VB/PPU3T_Sync_First folder for the matlab script .m file.

The SPM job code version of the example comes with the code, if you use SPM anyway.

Also, I would recommend using the DICOM file of your first or last volume in the fMRI run as input for physio.log_files.scan_timing. On most scanners, the .ext file does not contain any triggers, but only 0s.

I hope that helps.

All the best, Lars

EmilyJD777 commented 1 month ago

Sorry, I'm a bit new. Unfortunately, I don't have access to the dicoms for this particular data set, but there does appear to be triggers in the .ext file (at least I think so). There are a lot of zeroes but a sequence every so often ' 1 1 5000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'. Does this signify a trigger? Are the fMRI DICOM files necessary to run PhysIO?

When modifying it to 'Siemens' I get this following error: Index exceeds the number of array elements. Index must not exceed 0.

Error in tapas_physio_read_physlogfiles_siemens (line 104) tStartScanDicom = dicomHeader{1}.AcquisitionTime;

Error in tapas_physio_read_physlogfiles (line 87) tapas_physio_read_physlogfiles_siemens(log_files, cardiac_modality, verbose, ...

Error in tapas_physio_main_create_regressors (line 121) verbose] = tapas_physio_read_physlogfiles(...

Error in physIO_example_script_TEST (line 82) tapas_physio_main_create_regressors(physio);

Is this related to the lack of DICOM files?

Apologies if the questions are obvious, but I'm new to this and just trying to figure it all out. Thanks again so much for your help here.

mrikasper commented 1 month ago

Dear Emily,

You can just put physio.scan_timing.sync.method = 'nominal' to see whether it runs through at all.

If you don't have a DICOM file, maybe you got a .json sidecar file instead with your fMRI run (same name as the .nii file, but with .json file extension)? The information is in there as well, and I have a development version of the PhysIO code that could work with that one.

All the best, Lars

EmilyJD777 commented 1 month ago

Thanks again for this info! This has been really helpful. I have another question couple questions for you if that's okay.

  1. What is the best way to calculate log_files.relative_start_acquisition if I know my physiological data was started before the scan began and do not have access to dicom files? I have, say an acquisition time of 10:43:49.480000 and start and stop times in the physio logs for: LogStartMDHTime: 10282865 LogStopMDHTime: 10756050 LogStartMPCUTime: 38491580 LogStopMPCUTime: 38964792

Why is there a discrepancy between LogStopMPCUTime - LogStartMPCUTime and LogStopMDHTime - LogStartMDHTime? Which should I use? If I have 189 volumes, will it correctly align the start time with how many volumes?

  1. Some of our earlier participants only have one long .res, .puls and .ext file for all runs combined. Is it still possible to parse these out somehow?

Again, thank you so much for your time!

mrikasper commented 1 month ago

Dear Emily,

  1. You don't have to parse out the relative_start_acquisition (just leave it at 0), if you provide a scan_timing_log file, e.g., the .json sidecar and the AcquisitionTime variable therein.. The parsing and synchronization is exactly what PhysIO will do for you in the initial read-in steps. The intricacies of the LogStart/Stop and MDH/MPCU Time variables have been scrutinized multiple times, for example here in our Wiki. I don't think there is a satisfactory answer.
  2. Yes, it's possible. Again, if you have the actual .json sidecar file (or AcquisitionTime variable) for the actual run you want to compute the physiological noise regressors for, PhysIO will sync the timing for you automatically. I would recommend to use physio.log_files.align_scan = 'first';, if you base it on the AcquisitionTime from the .json sidecar file.

All the best, Lars

EmilyJD777 commented 1 month ago

I've tried having the log_files.scan_timing as my .ext file path with the triggers in it (which would be optimal) and I've also tried the log_files.scan_timing as my .json file path. I've also tried both scan_timing.sync.method = 'nominal'; and scan_timing.sync.method = 'scan_timing_log';

I've tried each combination of these parameters and no matter what, I am getting the following error:

tapas_physio_main_create_regressors(physio)
Warning: Z:\derivatives\brainstem_funk\physio\YA\Day2\001\001.ext: Not a DICOM file. 
In spm_dicom_header (line 54)
In spm_dicom_headers (line 27)
In tapas_physio_read_physlogfiles_siemens (line 103)
In tapas_physio_read_physlogfiles (line 87)
In tapas_physio_main_create_regressors (line 137) 
Index exceeds the number of array elements. Index must not exceed 0.
Error in tapas_physio_read_physlogfiles_siemens (line 114)
        dc = dicomHeader{1};
Error in tapas_physio_read_physlogfiles (line 87)
            tapas_physio_read_physlogfiles_siemens(log_files, cardiac_modality, verbose, ...
Error in tapas_physio_main_create_regressors (line 137)
                verbose] = tapas_physio_read_physlogfiles(... 
>> 

It seems as though it keeps looking for a DICOM file. Is there any way around using the DICOMS?

**Edited for length.

EmilyJD777 commented 1 month ago

Really hoping to find a solution to this! Thanks again!

mrikasper commented 1 month ago

Dear Emily,

  1. scan_timing.sync.method = 'nominal' should work without specifying a log_files.scan_timing_log file. Can you try to leave the file empty, i.e., physio.log_files.scan_timing = '';
  2. Are you able to share the .json file you tried to use? It might be that you are running into an issue I fixed in a development branch of PhysIO and haven't released yet.

Thank you and

All the best, Lars

EmilyJD777 commented 1 month ago

When I run it with physio.log_files.scan_timing = ''; and scan_timing.sync.method = 'nominal', it does run and outputs figures, but then runs into an error saying:

Error using tapas_physio_main_create_regressors Please specify an onset slice.

I've attached a .json file here. sub-001_task-cloudy_acq-ep2d19mm_run-01_echo-1_bold.json

EmilyJD777 commented 3 weeks ago

Just wanted to follow up on this as it is still an issue. Thanks again!

mrikasper commented 3 weeks ago

Dear Emily,

For the 'nominal' scan timing setting, did you specify the onset slice like in your example above, i.e.,

physio.scan_timing.sqpar.onset_slice = 51;

?

It's really odd why that part is not working, but I will only have time next week to look closely into this.

All the best, Lars

EmilyJD777 commented 2 weeks ago

I did. I have even managed to get access to the dicoms so that I could make use of the data and the last dicom isn't working either. I'd rather use the trigger files if possible, but if there were any way to get this up and rolling, it would be so very appreciated.

mrikasper commented 4 days ago

Dear Emily,

I am really at a loss here, this should work. Would you be able to send me the example logfile that belongs to the json file you sent as well the matlabbatch or m-file script that you are trying to run?

You can send it via email if you don't want to post it here (see below).

Thank you!

All the best, Lars

-- Lars Kasper, PhD (he/him) @.***

MR Physicist Toronto Neuroimaging Facility (ToNI), Department of Psychology, University of Toronto

325 Huron St, Toronto, ON M5S 3J7 phone: +1 416-978-7613 (office) / +1 416-946-0356 (scanner)


From: EmilyJD777 @.> Sent: Monday, October 28, 2024 5:17:56 PM To: translationalneuromodeling/tapas @.> Cc: Lars Kasper @.>; Assign @.> Subject: Re: [translationalneuromodeling/tapas] PhysIO Not Accepting 7T .resp, .ext and .puls Files? (Issue #283)

I did. I have even managed to get access to the dicoms so that I could make use of the data and the last dicom isn't working either. I'd rather use the trigger files if possible, but if there were any way to get this up and rolling, it would be so very appreciated.

— Reply to this email directly, view it on GitHubhttps://github.com/translationalneuromodeling/tapas/issues/283#issuecomment-2442648375, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ADFUIX7J2ZO7S7MPILOZJ3TZ52SYJAVCNFSM6AAAAABPSTFML6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINBSGY2DQMZXGU. You are receiving this because you were assigned.Message ID: @.***>

EmilyJD777 commented 4 days ago

Could you DM me your email address? I tried emailing through github but the file size of the .m is too large.

mrikasper commented 4 days ago

Hi Emily,

You can use my email at the top of the PhysIO README.

Thank you for sending the data!

All the best, Lars