OpenGATE / Gate

Official public repository of Gate
http://www.opengatecollaboration.org
GNU Lesser General Public License v3.0
232 stars 262 forks source link

Exporting mhd loses reference position #359

Open BishopWolf opened 3 years ago

BishopWolf commented 3 years ago

When Gate exports a n mhd image like a dose actor it loses completely the reference position. The solution I perform is to manually copy the reference lines in the reference mhd to the dose actor image.

Example: The dose actor is attached to a SPECT image with this header

ObjectType = Image
NDims = 3
BinaryData = True
BinaryDataByteOrderMSB = False
CompressedData = False
TransformMatrix = 1 0 0 0 1 0 0 0 1
Offset = -280.54680000000008 -280.54679999999996 964.30169999999987
CenterOfRotation = 0 0 0
AnatomicalOrientation = RAI
ElementSpacing = 4.4180599999999997 4.4180599999999997 4.4180000000000028
DimSize = 128 128 90
ElementType = MET_DOUBLE
ElementDataFile = ACTM.raw

The Dose actor is then exported with this header

ObjectType = Image
NDims = 3
BinaryData = True
BinaryDataByteOrderMSB = False
CompressedData = False
TransformMatrix = 1 0 0 0 1 0 0 0 1
Offset = -280.547 -280.547 964.302
CenterOfRotation = 0 0 0
ElementSpacing = 4.41806 4.41806 4.418
DimSize = 128 128 90
AnatomicalOrientation = ???
ElementType = MET_FLOAT
ElementDataFile = doseMonteCarlo1HR-Dose.raw

As you can see now Anatomical orientation is missing, this causes a lot of problems in automatic processing. Imagine to process 1000 patients ans 5 images per patient, you need to copy the anatomical orientation each time.

The request is to take the orientation of the volume the dose actor is attached to.

djboersma commented 3 years ago

The implementation of GateImageMHD relies on ITK code in source/external/itk-mhd, specifically the "MetaImage" class. The method called M_SetupReadFields seems to define which fields should be read from the input MHD file, and the anatomical orientation is not included. For writing output, the anatomical orientation is included (it's included in M_SetupWriteFields), and seems to get a default value if it is somehow not defined yet. I am guessing that this causes the anatomical orientation to get lost.

(For comparison: the MetaImage::M_SetupReadFields overrides the virtual MetaObject::M_SetupReadFields, which seems to define all possible fields including anatomical orientation, while meta image only includes a subset, not including anatomical orientation.)

Since this is external code, we'd be reluctant to edit ourselves. The code is copied from the ITK library, some pretty old version (@dsarrut do you remember from which one?). However, I checked a relatively new ITK release (5.0.1), and it looks like this method has not changed at all (modulo the syntax cleanups to make the code grow up from C++03 to C++1x).

I am surprised that the anatomical orientation is in MetaImage's default list of fields to write, but not in its list of fields to read. Maybe there is an insightful reason for that? Or would this really be a strange long-living bug in ITK?

If it's a bug and/or if we are convinced that the above mentioned but so far unknown "insightful reason" does not apply to our use case, then I think that there is a way to fix it without hacking the MetaImage code. It's not very pretty though. We could introduce a new image class, which derives from MetaImage and overrides the (virtual) M_SetupReadFields method, to make sure that the "AnatomicalOrientation" field will be read, in addition to the fields that are already setup for MetaImage to read.

dsarrut commented 3 years ago

Yes, I agree, the copied itk code should probably not be edited. Deriving MetaImage is probably the way to go. I am also a bit annoyed by the rounding issue (look at the spacing or the offset). Alex, please, if you plan to work on that topic, could you also have a look on this rounding issue ?

djboersma commented 3 years ago

The rounding actually happens in our own code, in line 106-108 of GateMHDImage.icc.