Skip to content

Fix conform.py losing tr value during conversion#714

Merged
m-reuter merged 1 commit into
Deep-MI:devfrom
OtabekRintaro:fix/tr-change-after-conform
Jun 20, 2025
Merged

Fix conform.py losing tr value during conversion#714
m-reuter merged 1 commit into
Deep-MI:devfrom
OtabekRintaro:fix/tr-change-after-conform

Conversation

@OtabekRintaro
Copy link
Copy Markdown
Contributor

Previously, when conform.py had nifti file as input, it wouldn't copy the tr information into conformed output image.
Reason: MGHheader and niftiheader formats store this information differently.

Sadly, I didn't find a precise definition in documentation of Nifti's specification website.
I have scraped some partial definitions from different sources, here they are:

Nifti Specification FAQ
https://nifti.nimh.nih.gov/nifti-1/documentation/faq.html
Q20. How is the timing of acquisition encoded in the NIfTI-1 header?
...
slice_duration * dim[slice_dim] can be less than pixdim[4] with a clustered acquisition method, for example.

so there is a correlation between slice_duration (timing of acquisition) encoding and pixdim[4]

Nifti Specification
https://nifti.nimh.nih.gov/nifti-1/documentation/Analyze_usage.pdf
This file which shows how different FMRI software packages use header values which contains the line that pixdim[4] = TR.

Documentation by NITRC
https://www.nitrc.org/docman/view.php/26/64/nifti1.h
The codes below can be used in xyzt_units to indicate the units of pixdim.
As noted earlier, dimensions 1,2,3 are for x,y,z; dimension 4 is for
time (t).

  • If dim[4]=1 or dim[0] < 4, there is no time axis.
  • A single time series (no space) would be specified with
  • dim[0] = 4 (for scalar data) or dim[0] = 5 (for vector data)
  • dim[1] = dim[2] = dim[3] = 1
  • dim[4] = number of time points
  • pixdim[4] = time step

One of the chapters in course about fMRI data analysis from Berkley
https://bic-berkeley.github.io/psych-214-fall-2016/tr_and_headers.html

You can get the voxel (plus TR) dimensions with the get_zooms method of the header object:

func_img = nib.load('ds114_sub009_t2r1.nii')
header = func_img.header
header.get_zooms()
(4.0, 4.0, 4.0000162, 2.5)
In this case, the image spatial voxel sizes are (4 by 4 by 4) millimeters, and the TR is 2.5 seconds.

We can see, that the TR is specified in seconds, when mgz files store the value in ms, so we need to convert seconds into milliseconds.

Also, by reading documentations, I have realized that conform.py does well while converting from nii.gz/nii to mgz but it still loses tr value due to it not having a 'tr' value and nib.save doesn't do the copy by itself. Basically, when nib.save converts mgh header to nii.gz header then it doesn't copy the tr into pixdim[4]. I will see if there is a fix for that as well.

*Opened new PR due to branch management

@m-reuter
Copy link
Copy Markdown
Member

Thanks, may be also related to #587

@m-reuter m-reuter merged commit bddbd0d into Deep-MI:dev Jun 20, 2025
2 of 3 checks passed
@OtabekRintaro OtabekRintaro deleted the fix/tr-change-after-conform branch October 9, 2025 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants