Hello,
I'm new to AFNI and coding in general and I'm trying to figure out how to use physio_calc.py to get regressors from my psychophys data (respiratory and cardiac), that I can then add to my afni_proc.py code with the ricor block.
I unlocked my physio DICOM files using this code: MB/readCMRRPhysio.py at master · CMRR-C2P/MB · GitHub
And it gives me a log file for my RESP and one for my PULS data. I just had to modify them slightly to remove the extra headers to just have the acquisition time on the left and the corresponding RESP/PULS value on the right.
I then put it into my physio_calc.py code here:
physio_calc.py -freq 400 -card_file PULS_OBRun3_8345_clean.txt -resp_file RESP_OBRun3_8345_clean.txt -dset_epi Run3_8345.nii -dset_tr 1 -do_interact -do_fix_nan -do_fix_null -do_fix_outliers -out_dir physio_result -prefix subj8345
And the program would quit because it says the RESP and PULS files are shorter than the EPI file.
Could anyone help me out?
Hi-
It will help to know both your AFNI version, as well as to have a copy+paste of the text output of physio_calc.py.
physio_calc.py is aiming to take physio time series as inputs, and to create FMRI regressors as a primary output. If the input physio data do not cover the full duration of the FMRI time series, the program will complain. That might be the complaint you have, let's see.
If the physio data are just really too short, that will be a problem. It is also possible that there is a mistake in the inputs about physio sampling rate and/or EPI TR, and those can be checked. Since you are using -dset_epi ..
to load in the EPI to the program already, you should be able to leave -dset_tr ..
out of your option list---the former option should lead to the latter information being obtained automatically from the input EPI header. I guess those values agree, as that should be checked in the program, but it will make your option list simpler, at least.
You might want to doublecheck the value of the sampling rate for the physio data---the program uses that (as well as the length of each physio file) to determine the total time coverage of the physio data.
--pt
Hi,
This is the output I get:
jadeshelp% physio_calc.py -freq 297.092 -resp_file RESP_OBRun3_8345_clean.txt -card_file PULS_OBRun3_8345_clean.txt -dset_epi Run3_8345.nii -do_interact -do_fix_nan -do_fix_null -do_fix_outliers -out_dir physio_result -prefix subj8345
++ No start time provided; will assume it is 0.0.
++ Good: No items found in bad nan list
++ Good: No items found in bad null list
++ Good: No items found in bad nan list
++ Good: No items found in bad null list
++ Add any outliers to the bad list, N = 0
++ Add any outliers to the bad list, N = 0
++ (card) Start time physio : 0.000000
++ (card) End times of physio and MRI:
physio end time : 257.519556
final MRI slice time : 367.000000
** -- Final duration problem (card) --
** ERROR: card physio data too short for MRI data
++ (resp) Start time physio : 0.000000
++ (resp) End times of physio and MRI:
physio end time : 63.505581
final MRI slice time : 367.000000
** -- Final duration problem (resp) --
** ERROR: resp physio data too short for MRI data
My afni version seems to be: AFNI_25.1.03
I'm not totally sure how to find the sample rate of my psychophys measures. If they are taking one sample per slice, is there a way to calculate the sample rate from that?
Thank you!
Howdy-
Great, thanks, that does clarify what is happening. This is the most relevant part of the output:
physio end time : 257.519556
final MRI slice time : 367.000000
So, the physio data is about 110s too short for that FMRI data.
How did you get this number to put in for the physio data:
-freq 297.092
? When you converted your physio data from DICOMs, did you get an accompanying JSON of information with that, perhaps, that might include the sampling freq?
--pt
Hi,
The frequency I put was the frequency of the scanner, because I wasn't sure what else I was supposed to put there.
No I didn't, the output I got was a log file for the respiratory data, a long file for the cardiac data, and a log file that was general acquisition info that contained stuff like this:
UUID = 226399dd-6655-4575-8053-ac8618748dfc
ScanDate = 20250331_141955
LogVersion = EJA_1
LogDataType = ACQUISITION_INFO
NumSlices = 66
NumVolumes = 393
NumEchoes = 1
VOLUME SLICE ACQ_START_TICS ACQ_FINISH_TICS ECHO
0 0 20783221 20783230 0
0 22 20783221 20783230 0
0 44 20783221 20783230 0
0 9 20783239 20783248 0
0 31 20783239 20783248 0
0 53 20783239 20783248 0
Am I supposed to find the sampling frequency from this file? Or is there another program I can use to convert physiological DICOMs into tsv.gz and json files? I've been struggling to find one.
Thank you!
Howdy-
I have been chatting with folks here about any particular program to convert physio time series and get more meta/header data out. There wasn't an obvious choice, unfortunately.
One suggestion was to go back to the source of the scan, and chat with the folks at that scanner. They should (hopefully) have log files or information about what rate(s) of sampling are use.
An important thing to also check is about the relative starts of the physio data acquisition and the FMRI data acquisition. Are you sure that both sets of numbers are starting from the same time=0? Sometimes physio collection is started first, and so there is an offset between the FMRI and physio collection (which might be recorded as "start time" difference somewhere). In your case, if the physio were started before the FMRI here, then that would make the duration mismatch even worse, unfortunately...
I will note that it seems a bit odd that the cardio and resp data appear to have very different lengths. That might suggest that the resp (which is far shorter) was interrupted or otherwise not fully collected, or that perhaps it came from a different acquisition during the scan session (something much shorter, like an anatomical or localizer)? That is also something to check up on separately.
Sorry to not have any easy solutions for this, but being sure about the data origins and parameters will be useful in any case.
--pt