# Composite Transform error

**URL:** https://discourse.itk.org/t/composite-transform-error/6108
**Category:** Beginner Questions
**Tags:** simpleitk
**Created:** [July 28, 2023, 3:39pm UTC](https://discourse.itk.org/t/composite-transform-error/6108 "2023-07-28T15:39:57Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![CrownMella](https://discourse.itk.org/user_avatar/discourse.itk.org/crownmella/32/3612_2.png) [@CrownMella](https://discourse.itk.org/u/CrownMella)
#### Post date: [July 28, 2023, 3:39pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/1 "2023-07-28T15:39:57Z")

</div>

Hello,

I have two transforms: affine and displacementfield. When I apply them affine then df, it works well. I would like to create a composite transform. I read that they are in reverse order with the back being applied first.

My code is as follows:  
ct = sitk.CompositeTransform(df\_transform)  
ct.AddTransform(aff\_transform)  
sitk.WriteTransform(ct, ‘ct\_transform.h5’)

However, I get an error:  
RuntimeError: Exception thrown in SimpleITK WriteTransform: [D:\a\1\sitk-build\ITK\Modules\IO\TransformHDF5\src\itkHDF5TransformIO.cxx:389](file:///D:/a/1/sitk-build/ITK/Modules/IO/TransformHDF5/src/itkHDF5TransformIO.cxx:389): ITK ERROR: HDF5TransformIOTemplate(00000194FBD310D0): Composite Transform can only be 1st transform in a file

What does this mean?

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [July 28, 2023, 5:08pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/2 "2023-07-28T17:08:11Z")

</div>

Hello @CrownMella,

This means that there is already a transform stored in that file (likely your code is more complex than what you provided). The composite transform has to be the first transform in the file.  
The following code works as expected:

```auto
import SimpleITK as sitk
import numpy as np

# Create affine and deformation field transformations
dim = 3
aff_transform = sitk.AffineTransform(dim)
df_transform = sitk.DisplacementFieldTransform(dim)
field_size = [10]*dim
field_origin = [-1.0]*dim
field_spacing = [0.8]*dim
field_direction = list(np.identity(dim).ravel())

df_transform.SetFixedParameters(
    field_size + field_origin + field_spacing + field_direction
)
df_transform.SetParameters(np.random.random(len(df_transform.GetParameters())))

# Compose the two transformations and write to file
ct = sitk.CompositeTransform(df_transform)
ct.AddTransform(aff_transform)
sitk.WriteTransform(ct, "ct_transform.h5")

```

---

<div class="post-metadata">

### Author: ![CrownMella](https://discourse.itk.org/user_avatar/discourse.itk.org/crownmella/32/3612_2.png) [@CrownMella](https://discourse.itk.org/u/CrownMella)
#### Post date: [July 28, 2023, 6:01pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/3 "2023-07-28T18:01:03Z")

</div>

Hi ziv,

Interestingly enough, if I flip the two i.e.  
ct = sitk.CompositeTransform(aff\_transform)  
ct.AddTransform(df\_transform)  
it works. I’ve tried restarting python, changing the variable name, but it still keeps showing the error.

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [July 28, 2023, 6:27pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/4 "2023-07-28T18:27:47Z")

</div>

Hello @CrownMella,

Are you working with the code snippet I provided or your original code? Does the code snippet I provided work? If yes, then there is something else going on with your original code.

Make sure that the type of `df_transform` is not a `CompositeTransform` (you end up with a nested `CompositeTransform` which isn’t supported).

---

<div class="post-metadata">

### Author: ![CrownMella](https://discourse.itk.org/user_avatar/discourse.itk.org/crownmella/32/3612_2.png) [@CrownMella](https://discourse.itk.org/u/CrownMella)
#### Post date: [July 28, 2023, 6:50pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/5 "2023-07-28T18:50:27Z")

</div>

Hi Ziv,

Your code works. In my code, the registration returns sitk.DisplacementFieldTransform(initial\_displacement\_field) where the initial\_displacement\_field comes from TransformToDisplacementField(initial\_transform) where the initial transform is itk.CenteredTransformInitializer(f,m,sitk.AffineTransform(3), sitk.CenteredTransformInitializerFilter.GEOMETRY)

so no I don’t see any compositetransforms here unless any of those words actually mean composite.

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [July 28, 2023, 7:24pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/6 "2023-07-28T19:24:42Z")

</div>

Hello @CrownMella,

Theoretically you are correct, doesn’t sound like you should get a `CompositeTransform` from that set of steps, but that is a description of the code, not the code itself. Now we know that the transforms are obtained from registration.

My suspicion, the registration using the deformation field isn’t done in-place, and the returned transformation type from the registration is a `Transform`. If this is the case, you can do the registration in-place or downcast the transform using its `Downcast()` method.

To see the details of a transform simply print it:

```auto
print(df_transform)

```

---

<div class="post-metadata">

### Author: ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)
#### Post date: [July 28, 2023, 7:58pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/7 "2023-07-28T19:58:52Z")

</div>

> [@zivy](#):
>
> Theoretically you are correct, doesn’t sound like you should get a `CompositeTransform` from that set of steps, but that is a description of the code, not the code itself. Now we know that the transforms are obtained from registration.

The results of `ImageRegistrationMethods::Execute` can be a `CompositeTransform`. The RegistrationMethods can be configure to modify the displacement field, with the `SetInitialTransform(tx, inPlace=True)`.

Additionally nested Composite transforms can be remote with `CompositeTransform::FlattenTransform()` method.

---

<div class="post-metadata">

### Author: ![CrownMella](https://discourse.itk.org/user_avatar/discourse.itk.org/crownmella/32/3612_2.png) [@CrownMella](https://discourse.itk.org/u/CrownMella)
#### Post date: [July 28, 2023, 7:59pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/8 "2023-07-28T19:59:15Z")

</div>

Hi Ziv,

What do you mean by done in-place? Also below is the output from print. Looks to be a displacementfieldtransform. The only thing different from the df\_transform you made is the reference count (though idk what this even means)

```auto
print(dd_transform)
itk::simple::DisplacementFieldTransform
 DisplacementFieldTransform (000002470113D0E0)
   RTTI typeinfo: class itk::DisplacementFieldTransform<double,3>
   Reference Count: 1
   Modified Time: 124240
   Debug: Off
   Object Name: 
   Observers: 
     none
   DisplacementField: 
     Image (0000024701157910)
       RTTI typeinfo: class itk::Image<class itk::Vector<double,3>,3>
       Reference Count: 3
       Modified Time: 124236
       Debug: Off
       Object Name: 
       Observers: 
         none
       Source: (none)
       Source output name: (none)
       Release Data: Off
       Data Released: False
       Global Release Data: Off
       PipelineMTime: 0
       UpdateMTime: 0
       RealTimeStamp: 0 seconds 
       LargestPossibleRegion: 
         Dimension: 3
         Index: [0, 0, 0]
         Size: [300, 200, 600]
       BufferedRegion: 
         Dimension: 3
         Index: [0, 0, 0]
         Size: [300, 200, 600]
       RequestedRegion: 
         Dimension: 3
         Index: [0, 0, 0]
         Size: [300, 200, 600]
       Spacing: [1, 1, 1]
       Origin: [0, 0, 0]
       Direction: 
1 0 0
0 1 0
0 0 1

       IndexToPointMatrix: 
1 0 0
0 1 0
0 0 1

       PointToIndexMatrix: 
1 0 0
0 1 0
0 0 1

       Inverse Direction: 
1 0 0
0 1 0
0 0 1

       PixelContainer: 
         ImportImageContainer (0000024700E27F60)
           RTTI typeinfo: class itk::ImportImageContainer<unsigned __int64,class itk::Vector<double,3> >
           Reference Count: 1
           Modified Time: 124233
           Debug: Off
           Object Name: 
           Observers: 
             none
           Pointer: 00000247B37C6040
           Container manages memory: true
           Size: 36000000
           Capacity: 36000000
   InverseDisplacementField: (null)
   Interpolator: 
     VectorLinearInterpolateImageFunction (0000024747BF2670)
       RTTI typeinfo: class itk::VectorLinearInterpolateImageFunction<class itk::Image<class itk::Vector<double,3>,3>,double>
       Reference Count: 1
       Modified Time: 124229
       Debug: Off
       Object Name: 
       Observers: 
         none
       InputImage: 0000024701157910
       StartIndex: [0, 0, 0]
       EndIndex: [299, 199, 599]
       StartContinuousIndex: [-0.5, -0.5, -0.5]
       EndContinuousIndex: [299.5, 199.5, 599.5]
   InverseInterpolator: 
     VectorLinearInterpolateImageFunction (0000024747BF2430)
       RTTI typeinfo: class itk::VectorLinearInterpolateImageFunction<class itk::Image<class itk::Vector<double,3>,3>,double>
       Reference Count: 1
       Modified Time: 124230
       Debug: Off
       Object Name: 
       Observers: 
         none
       InputImage: 0000000000000000
       StartIndex: [0, 0, 0]
       EndIndex: [0, 0, 0]
       StartContinuousIndex: [0, 0, 0]
       EndContinuousIndex: [0, 0, 0]
   DisplacementFieldSetTime: 124240
   m_IdentityJacobian: [1, 0, 0]
[0, 1, 0]
[0, 0, 1]

    CoordinateTolerance: 1e-06
    DirectionTolerance: 1e-06

```

---

<div class="post-metadata">

### Author: ![CrownMella](https://discourse.itk.org/user_avatar/discourse.itk.org/crownmella/32/3612_2.png) [@CrownMella](https://discourse.itk.org/u/CrownMella)
#### Post date: [July 28, 2023, 8:24pm UTC](https://discourse.itk.org/t/composite-transform-error/6108/9 "2023-07-28T20:24:33Z")

</div>

Hi Bradley, Hi Ziv,

Flattening the transform worked! Thanks to you both. I guess the result of the execute really was a composite transform. Although, I am still confused as to why the order would matter if the compositetransform does not support nesting ie why composite(df), addtransform(aff) didnt work but composite(af),addtransform(df) worked (though the resulting image was not nice)
