Skip to content

Slice timing#1175

Merged
Lestropie merged 13 commits intodevfrom
slice_timing
Nov 15, 2017
Merged

Slice timing#1175
Lestropie merged 13 commits intodevfrom
slice_timing

Conversation

@Lestropie
Copy link
Member

Second of three PRs targeted particularly at dwipreproc (wanted to merge #1159 before this one). Some verbose commit messages in there that contain a decent amount of information; but the crux is:

  • Capture slice encoding direction and slice timing from DICOM, and store them in BIDS-compatible header fields.

  • In dwipreproc, make sure that if the slice encoding axis is known, it's the third axis. eddy doesn't have a command-line option to set this; ideally dwipreproc should permute axes in order to support this, but that could have weird side-effects, e.g. when eddy's text file outputs are interpreted (which is the third of the three PRs). If --mporder is provided to eddy, either grab the text file that the user provides via --slspec=, or construct such a file based on the slice timing information present in the image header (which I expect to be the most common usage).

  • In mrdegibbs, if the slice encoding axis is known, compare it to the default / user-defined within-slice axes selected, and report / modify as appropriate (as requested in Store slice axes in header for subsequent mrdegibbs #1173).

The time of acquisition of individual slices may come from one of three sources:
- If the image is stored in mosaic format, the Siemens CCSA field 'MosaicRefAcqTimes' will be used.
- If the Siemens CSA field 'TimeAfterStart' is present, it will be used for all frames in the first volume to determine the slice timing.
- Otherwise, the DICOM field 'AcquisitionTime' will be used to determine the slice timing.
Note that the last of these three additionally requires rarsing of the DICOM time format; therefore, all standard date and time fields in DICOM will now be explicitly converted and displayed as such.
Relates to #1169.
If the user specifies --mporder within -eddy_options, this will be handled in one of two ways:
- If the user has also specified --slspec within -eddy_options, then dwipreproc will find that file, copy it into the temporary directory, and modify the contents of -eddy_options to reflect the location of that file.
If --slspec is not specified within -eddy_options, then dwipreproc will look for 'SliceTiming' within the input DWI header key-value entries. If this is found, then an appropriate slspec file is generated based on the slice timings, and this is provided to eddy.
Closes #1169.
- When importing from DICOM, fill field 'SliceEncodingDirection', which is defined as part of BIDS.
- Whenever MRtrix3 performs a permutation of image axes (whether implicit or explicit), additionally adjust this field, just as is performed for DW and PE schemes.
- If attempting to run dwipreproc with slice-to-volume correction in eddy, ensure that if the slice encoding direction is specified, it corresponds to the third axis (which is what eddy will assume). Permutation of axes as part of dwipreproc may be addressed at a later date.
- dwipreproc: If slice encoding direction is negative, then the information contained in SliceTiming needs to be reversed.
- mrdegibbs: If SliceEncodingDirection is defined in the image header, use that information as appropriate: If the user has not manually specified the within-slice axes, make use of this header information, issuing a terminal message as appropriate; if user provides -axes option, compare to header information and issue warning if they are not consistent.
- Better handling of slice encoding direction in backend. This parameter is in fact permitted to indicate a negative direction (as can be done with PhaseEncodingDirection), and hence axis flips need to be taken into account.
Closes #1173.
Lestropie and others added 6 commits October 24, 2017 14:07
Combining changes related to -se_epi option, and those for compatibility with -eddy_options "--mporder", resulted in a couple of little mistakes.
If the number of slices in an axis of the image is odd, and topup is being used, then dwipreproc will duplicate the final slice along that axis, in order to prevent a fatal crash in topup.
However, if slice-to-volume correction is being used, and there are an odd number of slices, then this padding will result in a mismatch between the number of slices in the image data and the number of entries in the slice timing data.
These changes compensate for this by correspondingly altering the slice timing information, and delaying writing that information to file until after image padding has taken place.
- Don't attempt to erase header key-value entries that will never be there due to NIfTI conversion; will just produce unwarranted warnings.
- Disable pylint testing the number of lines in the file (dwipreproc is now close to 1000 lines).
@Lestropie
Copy link
Member Author

Okay, I think I've done everything I want to with this branch. I had a brief look at permuting image axes if the slice encoding direction is not k or k-, but this was going to be quite difficult, since axis permutation may also affect phase encoding direction if one is not careful, and order of axis permutation relative to other functions may cause issues. So I'm giving up on that for now; if someone has a non-axial DWI acquisition, they can deal with the data manually (they'll at least get a meaningful error message from dwipreproc).

Unlikely to attract much critique here, so would prefer to merge and have it more thoroughly tested in dev.

One possible point of contention would be the creation of core/axes.h and core/axes.cpp, for dealing with encoding of axis & direction as [ i, i-, j, j-, k, k- ]; previously this only applied to phase encoding, so lived in /core/phase_encoding.*, but is now also used for slice encoding; and although the nomenclature has origins from NIfTI (apparently), the functionality doesn't only apply to NIfTI. So it's hard to find a place for.

Other thing is core/file/dicom/mapper.cpp: I think that certain lines should refer to frame properties rather than image properties (changed in 3c474c6 and 335038b), but when I did a manual merge in #1159 I accidentally reverted. This PR should restore the earlier fixes; @jdtournier might want to double-check.

@Lestropie Lestropie merged commit c685841 into dev Nov 15, 2017
@Lestropie Lestropie deleted the slice_timing branch November 15, 2017 05:00
Lestropie added a commit that referenced this pull request Mar 12, 2020
- Revert slice timing write to image header to use comma delimiter rather than space; this is necessary as parsing of header entries for JSON export is done via MR::parse_floats(), which only considers commas and colons. This was done correctly in 4870c12 / #1175, but erroneously changed to space in 518b053 / #1937.
- When reading slice times from Siemens CSA header, do not perform conversion from ms to s using floating-point multiplication. Instead, convert (0.1ms) to integer, then to string, and then insert the decimal point manually. This prevents the creation of erroneously long text strings in the slice timing header field due to limited floating-point precision.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant