Conversation
- Write boolean values as "true" and "false" rather than "1" and "0". - For string data (whether single- or multi-line), remove double-quotes from the start and end of the string if appropriate. - When loading a JSON, base the realignment of orientation-based data on what was applied to the corresponding image during the Header::realign_transform() function; previously the function Axes::get_permutation_to_make_axial() was being re-run on the image header to which these realignments had already been applied. - Additionally issue INFO-level messages if orientation-based information is present in the JSON but the data are not being realigned. - Fix erroneous flipping or non-flipping of slice and phase encoding directions during JSON import. - When writing a JSON file, decide whether or not to apply realignment of orientation-based information based on whether or not the corresponding output image is one of the NIfTI formats.
Conflicts: core/file/json_utils.cpp
Necessary following changes in afa27c7 in order for both numeric and string-based array data to be imported as desired.
Utilise so that whe saving alongside an output image, the predicted realignment is applied to key-value entries, whereas for mrinfo no such realignment is performed.
- Rename Header::do_not_realign_transform() to Header::do_realign_transform(), since we don' like no double negatives. - Add config file entry "RealignTransform" to affect this parameter for all MRtrix3 commands. - When exporting JSON outside of mrinfo, use the extension of the output image path to determine whether or not the output image is a NIfTI, and hence whether the same orientation transformations need to be applied to orientation information within the JSON file. Previous attempt e940c22 did not work, as Header::name() is loaded based on an input image but not updated based on the name of an output image. - Introduce BIDS field "IntendedFor" into JSON files, and issue a warning on load if this does not appear to match the image for which the JSON is being loaded. - Various fixes to phase and slice encoding direction handling based on extensive testing.
|
Well that was not fun in the slightest. I have 12 DICOM series, each acquired with a unique slice & phase encoding direction.
So that is at least working. Want to do some more manual checks on a different day before merging anything though. Have to be super careful with external metadata because of the internal RAS realignment. For instance, if you run Also note that with the addition of config file entry " |
|
Also, the JSON import doesn't currently overwrite existing entries, and it probably should. |
|
😶 sounds horrendous... Thanks for taking care of this. 🙏 |
Fix updates of phase encoding and slice encoding directions based on the MRtrix3 internal header realignment to RAS.
This functionality can now be used in any MRtrix3 command by specifying "-config RealignTransform false".
|
Okay. So. What I did is manually draw fiducials on my 12 images with different phase & slice encoding directions, do conversion to NII / MIF & JSON with & without internal header realignment, convert back to MIF with & without header realignment, and verify correspondence between header data and fiducials in |
Extracted changes from #1735 in order to apply to dev. In dwifslpreproc, perform a robust parsing of slice timing information from the image header. During DICOM import, separate slice timings by space rather than comma; although the results of JSON export should be the same following #1771 / #1843, use of space delimiter for vector data is more consistent with other multi-dimensional data handling in image headers.
In trying to resolve the various issues with JSON handling (#1735, #1738, #1771), it looks like there was quite a bit wrong with the relevant code. Given the breadth and magnitude of issues, I'd like to try to get JSON handling working as well as possible on
dev(essentially expanding #1738), and then once we're happy with the behaviour here, determine what does or does not require immediate rectification onmaster.The complexity of the problem is as follows.
Input orientation information could be either:
Stored in the image header, in which case such data may be reoriented in the header key-value data during the
Header::realign_transform()function (depending on-norealignorHeader::do_not_realign_transform);Imported via
-json_import, which occurs afterHeader::realign_transform()has already been completed.Output orientation could be either:
Stored in the header along with the image data;
Exported to JSON to live alongside a non-NIfTI image;
Exported to JSON to live alongside a NIfTI image.
So what I think may be two ongoing issues in parallel are:
JSON::read()was callingAxes::get_permutation_to_make_axial(), but doing so on an image header that has already had such permutation applied. So this change stores the permutations & flips applied to aHeaderas class member variables for later reference byJSON::read().On JSON export, realignment of header key-value information based on a predicted transformation of the corresponding output image data I think needs to be predicated on whether or not that output image is or is not a NIfTI format. The current function does so based on
Header::do_not_realign_transformor a manual boolean input parameter. Unfortunately I couldn't find a very clean way of detecting the image format, so it's currently a string comparison againstHeader::format().There's also the issue here of how
mrinfoshould work, as opposed tomrconvert, since the former doesn't actually have an output image...In additon to these:
It seems that for JSON import the flipping of phase and slice encoding directions was erroneous, due to the minus signs being in the wrong place... I think @bjeurissen reported something akin to this at some point? Or was it @dchristiaens?
I think that changing from comma-separated to space-separated slice timing on
masterin Fixes to slice timing handling #1735 may have been a band-aid placed at the wrong location... Other vector data in.mifheaders are stored as comma-separated. So it might have fixed the export of such data onmaster, but using the wrong approach.Strings imported from JSON retain double quotation marks around them, whereas e.g. DICOM converted data don't contain such.
So there's a fair bit in this changeset, and it also includes a cherry-pick from #1735, as the intention is to get JSON working "as best as possible".
Printing some test data results here; could potentially incorporate something into CI, but it won't be trivial. These are mainly for the format of the slice timing vector; the issue of phase and slice encoding directions is probably going to require further interrogation.
Test JSON file:
cat testing/binaries/data/dwi.json{ "EchoTime": 0.028, "FlipAngle": 90, "MultibandAccelerationFactor": 1, "PhaseEncodingDirection": "j-", "RepetitionTime": 3.93, "SliceEncodingDirection": "k", "SliceTiming": [ 1.96500003, 0.0, 2.03250003, 0.0675000027, 2.09750009, 0.132499993, 2.1624999, 0.197500005, 2.22749996 ], "TotalReadoutTime": 0.0447, "comments": [ "ORIENTATION TEST (2016_10_05) [MR] ep2d_se AXIAL A-P", "study: BRI_PROTOCOLS VE11A Post 08-03-2016 SB.2002.060RS EPI - ROB - 20 [ ORIGINAL PRIMARY M ND NORM ]", "DOB: 01/01/1975", "DOS: 06/10/2016 14:09:38" ] }mastermrinfo output: Slice timing as separate entries, quotation marks around comments
mrconvert dwi.mif -clear_property dw_scheme -clear_property comments - | mrconvert - -json_import dwi.json - | mrinfo -JSON export: Key-values are all strings (#1738 was to `dev`), slice timing is list of lists, "comments" not split
mrconvert dwi.mif -clear_property dw_scheme -clear_property comments - | mrconvert - -json_import dwi.json - | mrinfo - -json_keyval test.json; cat test.json{ "EchoTime": "0.0280000009", "FlipAngle": "90", "MultibandAccelerationFactor": "1", "PhaseEncodingDirection": "j-", "RepetitionTime": "3.93000007", "SliceEncodingDirection": "k", "SliceTiming": [ [ 1.96500003 ], [ 0.0 ], [ 2.03250003 ], [ 0.0675000027 ], [ 2.09750009 ], [ 0.132499993 ], [ 2.1624999 ], [ 0.197500005 ], [ 2.22749996 ] ], "TotalReadoutTime": "0.0447000004", "command_history": "/home/rob/src/master/bin/mrconvert \"dwi.mif\" \"-clear_property\" \"dw_scheme\" \"-clear_property\" \"comments\" \"-\" (version=3.0_RC3_latest-66-g323bc8ac)\n/home/rob/src/master/bin/mrconvert \"-\" \"-json_import\" \"dwi.json\" \"-\" (version=3.0_RC3_latest-66-g323bc8ac)", "comments": "\"ORIENTATION TEST (2016_10_05) [MR] ep2d_se AXIAL A-P\"\n\"study: BRI_PROTOCOLS VE11A Post 08-03-2016 SB.2002.060RS EPI - ROB - 20 [ ORIGINAL PRIMARY M ND NORM ]\"\n\"DOB: 01/01/1975\"\n\"DOS: 06/10/2016 14:09:38\"", "mrtrix_version": "3.0_RC3_latest-66-g323bc8ac" }devmrinfo output: Slice timing is separate entries, comments have quotation marks
mrconvert dwi.mif -clear_property dw_scheme -clear_property comments - | mrconvert - -json_import dwi.json - | mrinfo -JSON export: comments have quotation marks
mrconvert dwi.mif -clear_property dw_scheme -clear_property comments - | mrconvert - -json_import dwi.json - | mrinfo - -json_keyval test.json; cat test.json{ "EchoTime": 0.0280000009, "FlipAngle": 90, "MultibandAccelerationFactor": 1, "PhaseEncodingDirection": "j-", "RepetitionTime": 3.93000007, "SliceEncodingDirection": "k", "SliceTiming": [ 1.96500003, 0.0, 2.03250003, 0.0675000027, 2.09750009, 0.132499993, 2.1624999, 0.197500005, 2.22749996 ], "TotalReadoutTime": 0.0447000004, "command_history": [ "mrconvert dwi.mif -clear_property dw_scheme -clear_property comments - (version=3.0_RC4-33-g0bd38e16-dirty)", "mrconvert - -json_import dwi.json - (version=3.0_RC4-33-g0bd38e16-dirty)" ], "comments": [ "\"ORIENTATION TEST (2016_10_05) [MR] ep2d_se AXIAL A-P\"", "\"study: BRI_PROTOCOLS VE11A Post 08-03-2016 SB.2002.060RS EPI - ROB - 20 [ ORIGINAL PRIMARY M ND NORM ]\"", "\"DOB: 01/01/1975\"", "\"DOS: 06/10/2016 14:09:38\"" ], "mrtrix_version": "3.0_RC4-33-g0bd38e16-dirty" }PR code
mrinfo output:
mrconvert dwi.mif -clear_property dw_scheme -clear_property comments - | mrconvert - -json_import dwi.json - | mrinfo -JSON export:
mrconvert dwi.mif -clear_property dw_scheme -clear_property comments - | mrconvert - -json_import dwi.json - | mrinfo - -json_keyval test.json; cat test.json{ "EchoTime": 0.0280000009, "FlipAngle": 90, "MultibandAccelerationFactor": 1, "PhaseEncodingDirection": "j-", "RepetitionTime": 3.93000007, "SliceEncodingDirection": "k", "SliceTiming": [ 1.96500003, 0.0, 2.03250003, 0.0675000027, 2.09750009, 0.132499993, 2.1624999, 0.197500005, 2.22749996 ], "TotalReadoutTime": 0.0447000004, "command_history": [ "mrconvert dwi.mif -clear_property dw_scheme -clear_property comments - (version=3.0_RC4-37-g14f760e1-dirty)", "mrconvert - -json_import dwi.json - (version=3.0_RC4-37-g14f760e1-dirty)" ], "comments": [ "ORIENTATION TEST (2016_10_05) [MR] ep2d_se AXIAL A-P", "study: BRI_PROTOCOLS VE11A Post 08-03-2016 SB.2002.060RS EPI - ROB - 20 [ ORIGINAL PRIMARY M ND NORM ]", "DOB: 01/01/1975", "DOS: 06/10/2016 14:09:38" ], "mrtrix_version": "3.0_RC4-37-g14f760e1-dirty" }