Convert FreeSurfer Transform to ANTs H5 Transform (with proper header)

Hi,

I am looking into replacing an ANTs registration step with FreeSurfer SynthMorph for a processing pipeline. FreeSurfer uses RAS orientation while ANTs/ITK uses LPS.

I can successfully get my RAS xfm to LPS with FreeSurfer’s mri_warp_convert -g moving.nii.gz --inras warp.mgz --outlps warp.h5, but that resultant .H5 file does not have the expected ANTs H5 header, which leads me to the following error when the registration is applied later with antsApplyTransform:

	Description: ITK ERROR: TransformFileReaderTemplate(0x55565df6abb0): Could not create Transform IO object for reading file /home/smeisler/projects/fmriprep_ants/single_subject_bids/derivatives/synthmorph_test/sub-NDARINV1Y40DZT8/ses-baselineYear1Arm1/anat/sub-NDARINV1Y40DZT8_ses-baselineYear1Arm1_rec-normalized_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5
	  Tried to create one of the following:
	    HDF5TransformIOTemplate
	    HDF5TransformIOTemplate
	    MINCTransformIOTemplate
	    MINCTransformIOTemplate
	    MatlabTransformIOTemplate
	    MatlabTransformIOTemplate
	    TxtTransformIOTemplate
	    TxtTransformIOTemplate
	  You probably failed to set a file suffix, or
	    set the suffix to an unsupported type.

Unfortunately, I need to keep the xfm to be an .h5 file, or at least I would like to (otherwise I’ll have to tinker with more of the pipeline than I had anticipated).

So the main question is: Is there a utility that can add ANTs header information to a transform file such that antsApplyRegistration will behave better?

Thanks,
Steven

As an update, I have tried the following to manually convert,

   def convert_nifti_to_ants_h5_deformation(self, nifti_file, h5_file):
        # Load the NIfTI file
        img = nib.load(nifti_file)
        data = img.get_fdata()

        # Ensure the data is in float32 format for compatibility
        if data.dtype != np.float32:
            data = data.astype(np.float32)

        # Create the HDF5 file with ANTs specific structure
        with h5py.File(h5_file, 'w') as f:
            # Create the Transform group
            xform_group = f.create_group('/TransformGroup/0')
            
            # Write out the transformation parameters
            xform_group.create_dataset('TransformParameters', data=data.flatten(order='C'))
            
            # Write additional attributes and datasets expected by ANTs
            xform_group.attrs['TransformType'] = 'DisplacementFieldTransform'
            xform_group.attrs['TransformDisplacementField'] = 'DisplacementField'
            xform_group.attrs['TransformFixedParameters'] = img.affine.flatten().tolist()
            
            f.attrs['ITKTransformType'] = 'DisplacementFieldTransform_double_3_3'
            f.attrs['ITKVersion'] = '4.11.0'
            f.attrs['HDFVersion'] = '1.8.15'

and now ANTs returns the following errors when I go to apply the registration:

Stderr:
	HDF5-DIAG: Error detected in HDF5 (1.14.3) thread 1:
	  #000: H5D.c line 403 in H5Dopen2(): unable to synchronously open dataset
	    major: Dataset
	    minor: Can't open object
	  #001: H5D.c line 364 in H5D__open_api_common(): unable to open dataset
	    major: Dataset
	    minor: Can't open object
	  #002: H5VLcallback.c line 1980 in H5VL_dataset_open(): dataset open failed
	    major: Virtual Object Layer
	    minor: Can't open object
	  #003: H5VLcallback.c line 1947 in H5VL__dataset_open(): dataset open failed
	    major: Virtual Object Layer
	    minor: Can't open object
	  #004: H5VLnative_dataset.c line 331 in H5VL__native_dataset_open(): unable to open dataset
	    major: Dataset
	    minor: Can't open object
	  #005: H5Dint.c line 1418 in H5D__open_name(): not found
	    major: Dataset
	    minor: Object not found
	  #006: H5Gloc.c line 421 in H5G_loc_find(): can't find object
	    major: Symbol table
	    minor: Object not found
	  #007: H5Gtraverse.c line 816 in H5G_traverse(): internal path traversal failed
	    major: Symbol table
	    minor: Object not found
	  #008: H5Gtraverse.c line 596 in H5G__traverse_real(): traversal operator failed
	    major: Symbol table
	    minor: Callback failed
	  #009: H5Gloc.c line 381 in H5G__loc_find_cb(): object 'TransformType' doesn't exist
	    major: Symbol table
	    minor: Object not found
	Transform reader for /home/smeisler/projects/fmriprep_ants/single_subject_bids/derivatives/synthmorph_test/sub-NDARINV1Y40DZT8/ses-baselineYear1Arm1/anat/sub-NDARINV1Y40DZT8_ses-baselineYear1Arm1_rec-normalized_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5 caught an ITK exception:

	itk::ExceptionObject (0x560251e0ed50)
	Location: "unknown" 
	File: /home/conda/feedstock_root/build_artifacts/libitk_1717078286681/work/Modules/IO/TransformHDF5/src/itkHDF5TransformIO.cxx
	Line: 365
	Description: ITK ERROR: HDF5TransformIOTemplate(0x560251d81890): H5Dopen2 failed

Is this manual setting a good direction to go down or are there more automated tools for this?

Thanks,
Steven

Another update, working with the ITK support group seems to have provided a good solution: Convert .nii.gz warp to .h5 (with proper header) - #4 by smeisler - Beginner Questions - ITK