Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STC ignoring SliceEncodingDirection #1345

Closed
fliem opened this issue Oct 25, 2018 · 8 comments · Fixed by #1350
Closed

STC ignoring SliceEncodingDirection #1345

fliem opened this issue Oct 25, 2018 · 8 comments · Fixed by #1350
Labels
Milestone

Comments

@fliem
Copy link
Contributor

fliem commented Oct 25, 2018

Hi.

It seems that stc is not taking SliceEncodingDirection into account.

I was under the impression that this parameter should alter how SliceTiming is handled.
If my nifti orientation is LPS and the slices where acquired in z direction in descending order (from superior to inferior), SliceEncodingDirection should be 'k-' and SliceTiming something like [0, .05, .1 (...)] correct?
Thanks.

@effigies effigies added the bug label Oct 25, 2018
@effigies
Copy link
Member

That looks correct. Thanks for the heads up. Any interest in submitting a patch?

@fliem
Copy link
Contributor Author

fliem commented Oct 25, 2018

I can work on that.

  • SliceEncodingDirection would also make non-axial acquisitions possible (although that's probably rare). Is it desired to enable data that has not been recorded in z direction?
  • I'm not familiar with AFNI's TShift. How should the timing information that goes into it look like? Does it assume superio-to-inferior, or does it lookup nifti orientation (I can look that up myself, but if there are experts here, I'd be interested...)

@effigies
Copy link
Member

I'll start by saying that we have been assuming the k orientation; as a consequence, at least one of the SDC algorithms will fail if the PhaseEncodingDirection is k[-]. But I do agree we should handle these cases correctly.

By my reading, TShift will use the header only if no slice timing pattern is supplied. Because we supply a pattern, it is treated as if it's in the z+ direction.

  -tpattern ttt = use 'ttt' as the slice time pattern, rather
                  than the pattern in the input dataset header;
                  'ttt' can have any of the values that would
                  go in the 'tpattern' input to to3d, described below:

   alt+z = altplus   = alternating in the plus direction
   alt+z2            = alternating, starting at slice #1 instead of #0
   alt-z = altminus  = alternating in the minus direction
   alt-z2            = alternating, starting at slice #nz-2 instead of #nz-1
   seq+z = seqplus   = sequential in the plus direction
   seq-z = seqminus  = sequential in the minus direction
   @filename         = read temporal offsets from 'filename'

  For example if nz = 5 and TR = 1000, then the inter-slice
  time is taken to be dt = TR/nz = 200.  In this case, the
  slices are offset in time by the following amounts:

             S L I C E   N U M B E R
   tpattern    0   1   2   3   4   Comment
   --------- --- --- --- --- ---   -------------------------------
   altplus     0 600 200 800 400   Alternating in the +z direction
   alt+z2    400   0 600 200 800   Alternating, but starting at #1
   altminus  400 800 200 600   0   Alternating in the -z direction
   alt-z2    800 200 600   0 400   Alternating, starting at #nz-2 
   seqplus     0 200 400 600 800   Sequential  in the +z direction
   seqminus  800 600 400 200   0   Sequential  in the -z direction

  If @filename is used for tpattern, then nz ASCII-formatted numbers
  are read from the file.  These indicate the time offsets for each
  slice. For example, if 'filename' contains
     0 600 200 800 400
  then this is equivalent to 'altplus' in the above example.
  (nz = number of slices in the input dataset)

It's not obvious from the docs whether z+ is assumed to be the positive direction along the I-S axis, or the increasing indices along the k data axis of the data block, or whether there's any effect of the slicedim attribute in the NIFTI header. This could be tested fairly easily, though I'll try to summon @afni-rickr to see if he happens to know (or know who might know).

In any event, I see no options for including a manually specified slice-encoding dimension, so I'm going to guess that they always assume that it's either k or S+ (this is why I don't like the XYZ convention, btw).

I would recommend making the changes in nipype:

https://github.com/nipy/nipype/blob/39675df33fadf4459e46b0dcdb78425b853dd22d/nipype/interfaces/afni/preprocess.py#L2725-L2729

You could add a slice_direction option with values (i|j|k)[-] to the input spec, and if there's a -, subtract the array from the TR.

If we want to go all out, once we figure out how to interpret z+, we could either reorder the data block or munge the affine to get the correct behavior out of TShift, and then restore the correct order/affine post-run. But that might make more sense as a fMRIPrep subclass of nipype's TShift for now.

@afni-rickr
Copy link

Hi @effigies, Yes, 3dTshift will get the slice timing pattern from the dataset, if it is there. And timing passed from the command line overrides the header contents.

And yes, the positive z direction for timing is based on positive indexing of the z direction on disk, not I-S, and not dependent on the sign of the coordinates. For verification, one can use 3dinfo -VERB to show the slice timing and orientation info, or something like 3dinfo -slice_timing -orient to get that info more specifically. The NIFTI_SLICE_* values were defined translating directly to the AFNI codes that you report.

I have never seen data where the slice-encoding dimension is not k, and am not sure how the software would behave. Does this mean datasets are being reoriented in scanner space for some reason? Is that the basis for this thread?

Thanks.

@effigies
Copy link
Member

Hi @afni-rickr. Than So we'll always be passing a file indicating slice timing, so the only extent to which 3dTshift reading the header is relevant is for the slice_dim field, which could be other than 3. If it's going to always assume 3, that's fine. (It does mean that if for some reason we get data where the SliceEncodingDirection is 'i', or 'j', then we'll need to roll the data matrix to ensure that 3dTshift works as expected, but that might be simpler than assuming that 3dTshift would handle it smoothly, anyway.

I have never seen data where the slice-encoding dimension is not k, and am not sure how the software would behave.

I haven't either.

Does this mean datasets are being reoriented in scanner space for some reason? Is that the basis for this thread?

I suppose it's possible. Or supposing I collected ILA, and my slice-encoding direction is still k, but then when standardizing my data, I reoriented to LPS, now I would need to indicate that my slice-encoding direction is j-.

Not to say this is a good idea, but to the extent that this information can be represented, I would like to be able to handle it correctly, and knowing how much the underlying tool adjusts its behavior to NIfTI headers as opposed to just working on the data block is necessary.

@afni-rickr
Copy link

Hi @effigies. For what it is worth, if one resamples data in AFNI, we generally wipe out the slice timing, believing it is misleading at best. So a subsequent 3dTshift would simply duplicate the input (with modest whining).

@mattcieslak
Copy link

I have a bunch of multiband EPIs that were collected with coronal slices. Happy to share an example if it would be helpful

@effigies
Copy link
Member

effigies commented Nov 1, 2018

@mattcieslak An example image would surely be helpful, though right now working with just an individual BOLD series is hard, as the anatomical portions of the pipeline are non-optional.

If you're open to sharing a non-trivial amount of data, would it be possible to share the dataset on OpenNeuro? That would make it simpler for anybody to pick it up, work on the problem, and be sure they can run through the whole pipeline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants