Skip to content

Conversation

@Lestropie
Copy link
Member

Oversight in #3011. Believe that at some point I changed the function from checking for a non-identity transform to checking for an identity transform, and one of the operators didn't get changed.

This should affect any NIfTI export. My best guess right now regarding how this could have survived my barrage of tests is that the metadata checks had no issue in terms of concordance with the image data, but the image data themselves were not conforming to the axis strides that were being requested, and the metadata tests in github.com/Lestropie/DWI_metadata were not doing any check for that and the CI tests in MRtrix3 don't have adequate coverage.

@Lestropie Lestropie self-assigned this Sep 3, 2025
Lestropie added a commit that referenced this pull request Sep 3, 2025
- Increment version number in CMakeLists.txt to reflect #3101 doing a merge with tag 3.0.5.
- Various code features overlooked during writing of 1ebdb39.
- Change MR::Axes::permutations_type to be a class rather than typedef in order to define a default uninitialised value, and also make it uint8 rather than size_t given it only has to stores the values 0, 1, 2, and an invalid flag.
- Fix check for shuffle being the identity matrix as per #3169.
@Lestropie
Copy link
Member Author

Should look into whether the effect here can be demonstrated.
Eg. Take a 3D image from the test data suite, do an mrconvert with all 24 possible spatial strides, and check that the generated output image conforms to the request.
This bug should manifest in 3.0.5, but not in 3.0.4 or with this change.

@Lestropie
Copy link
Member Author

As best I can tell, the bug should be inconsequential from a data perspective.
No permutation can satisfy the equation [ == 0 , == 1 , != 2], so .is_identity() returns False always.
However in all instances of use of this function:
https://github.com/MRtrix3/mrtrix3/blob/3.0.5/core/file/nifti_utils.cpp#L603
https://github.com/MRtrix3/mrtrix3/blob/3.0.5/core/header.cpp#L645
https://github.com/MRtrix3/mrtrix3/blob/3.0.5/core/metadata/phase_encoding.cpp#L227
https://github.com/MRtrix3/mrtrix3/blob/3.0.5/core/metadata/phase_encoding.cpp#L238
https://github.com/MRtrix3/mrtrix3/blob/3.0.5/core/metadata/phase_encoding.cpp#L266
https://github.com/MRtrix3/mrtrix3/blob/3.0.5/core/metadata/slice_encoding.cpp#L36
https://github.com/MRtrix3/mrtrix3/blob/3.0.5/core/metadata/slice_encoding.cpp#L81
, the function is only used to skip calculations that will result in a no-op for an identity transform.
As such, while the erroneous software may issue misleading terminal messages at INFO level that reorientation is taking place when it in fact isn't, I don't think any further issues should manifest.

Python snippet used to make sure that NIfTI writes were not detrimentally affected:
#!/usr/bin/env python3

import os
import subprocess
import sys

PATHS = {
    "3.0.4": "/home/unimelb.edu.au/robertes/src/3.0.4/bin",
    "3.0.5": "/home/unimelb.edu.au/robertes/src/3.0.5/bin",
    "bugfix": "/home/unimelb.edu.au/robertes/src/master/bin"
}

STRIDES = [
    "+1,+2,+3",
    "+1,+2,-3",
    "+1,-2,+3",
    "+1,-2,-3",
    "-1,+2,+3",
    "-1,+2,-3",
    "-1,-2,+3",
    "-1,-2,-3",

    "+1,+3,+2",
    "+1,+3,-2",
    "+1,-3,+2",
    "+1,-3,-2",
    "-1,+3,+2",
    "-1,+3,-2",
    "-1,-3,+2",
    "-1,-3,-2",

    "+2,+1,+3",
    "+2,+1,-3",
    "+2,-1,+3",
    "+2,-1,-3",
    "-2,+1,+3",
    "-2,+1,-3",
    "-2,-1,+3",
    "-2,-1,-3",

    "+2,+3,+1",
    "+2,+3,-1",
    "+2,-3,+1",
    "+2,-3,-1",
    "-2,+3,+1",
    "-2,+3,-1",
    "-2,-3,+1",
    "-2,-3,-1",

    "+3,+2,+1",
    "+3,+2,-1",
    "+3,-2,+1",
    "+3,-2,-1",
    "-3,+2,+1",
    "-3,+2,-1",
    "-3,-2,+1",
    "-3,-2,-1",

    "+3,+1,+2",
    "+3,+1,-2",
    "+3,-1,+2",
    "+3,-1,-2",
    "-3,+1,+2",
    "-3,+1,-2",
    "-3,-1,+2",
    "-3,-1,-2",
]

for version, binpath in PATHS.items():
    errors = []
    os.makedirs(version)
    for intended_strides in STRIDES:
        image_path = os.path.join(version, intended_strides.replace('+', 'p').replace('-', 'm') + '.nii')
        subprocess.run([os.path.join(binpath, 'mrconvert'),
                        'in.mif',
                        image_path,
                        '-strides', intended_strides,
                        '-quiet'])
        # Make sure that *upon reorientation at image load*
        #   the strides reported by mrinfo match what they should be
        actual_strides = subprocess.run([os.path.join(binpath, 'mrinfo'),
                                         image_path,
                                         '-strides',
                                         '-config', 'RealignTransform', 'true'],
                                        capture_output=True).stdout.decode().strip()
        if [int(item) for item in actual_strides.split(' ')] != [int(item) for item in intended_strides.split(',')]:
            errors.append((intended_strides, actual_strides))
    if errors:
        sys.stderr.write(f'{len(errors)} errors for version {version}:\n')
        for error in errors:
            sys.stderr.write(f'    {error[0]} != {error[1]}\n')
    else:
        sys.stderr.write(f'No errors for version {version}\n')

@Lestropie Lestropie requested a review from a team September 3, 2025 10:34
@Lestropie Lestropie removed the critical label Sep 3, 2025
@Lestropie Lestropie enabled auto-merge September 3, 2025 10:34
@Lestropie
Copy link
Member Author

Error came specifically from 79c4ba4.

@Lestropie Lestropie mentioned this pull request Sep 4, 2025
@Lestropie Lestropie added this pull request to the merge queue Sep 10, 2025
Merged via the queue into master with commit 863441d Sep 10, 2025
5 checks passed
@Lestropie Lestropie deleted the fix_axis_shuffle_identity_check branch September 10, 2025 08:37
@jdtournier jdtournier mentioned this pull request Oct 20, 2025
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 this pull request may close these issues.

3 participants