[CCPPETMR/SIRF] NiftiImageData template arguments (#299)

0 views
Skip to first unread message

Johannes Mayer

unread,
Feb 4, 2019, 5:28:26 AM2/4/19
to CCPPETMR/SIRF, Subscribed

@rijobro When an object of class NiftiImageData3D is constructed with a template argument not float one gets a compilation error:

#include "sirf/cReg/NiftiImageData3D.h"



int main( int argc, char *argv[] )

{	

    sirf::NiftiImageData3D< float > float_nifti;

    sirf::NiftiImageData3D< unsigned int > other_nifti;

}

In file included from /home/rich/Documents/Superbuild/Build/sources/SIRF/src/xDynamicSimulation/cDynamicSimulation/main.cpp:21:0:

/home/rich/Documents/Superbuild/Build/sources/SIRF/src/Registration/cReg/include/sirf/cReg/NiftiImageData.h: In instantiation of ‘sirf::NiftiImageData<dataType>::Iterator& sirf::NiftiImageData<dataType>::begin() [with dataType = unsigned int]’:

/home/rich/Documents/Superbuild/Build/sources/SIRF/src/xDynamicSimulation/cDynamicSimulation/main.cpp:67:1:   required from here

/home/rich/Documents/Superbuild/Build/sources/SIRF/src/Registration/cReg/include/sirf/cReg/NiftiImageData.h:445:22: error: no matching function for call to ‘sirf::NiftiImageData<unsigned int>::Iterator::Iterator(float*&)’

         _begin.reset(new Iterator(_data));


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.

Richard Brown

unread,
Feb 4, 2019, 6:33:51 AM2/4/19
to CCPPETMR/SIRF, Subscribed

Almost all of the classes in the cReg directory are templated, but explicit instantiation (I think that's the correct term) is given at the bottom of the .cpp files. E.g., for NiftiImageData3D, there is this line:
https://github.com/CCPPETMR/SIRF/blob/51d131ef1b945560e131f5585df108ba744f6c2f/src/Registration/cReg/NiftiImageData3D.cpp#L104

If you want it to compile for other datatypes, you just need to stick in another line with your desired type. What type of numbers do you need? It should be fine for double, but I can't guarantee anything for trickier types, such as complex (or even int).

Kris Thielemans

unread,
Feb 4, 2019, 6:37:12 AM2/4/19
to CCPPETMR/SIRF, Subscribed

nope. Missing a template instantation would give a linking eror. this is a compilation error.

Richard Brown

unread,
Feb 4, 2019, 6:53:15 AM2/4/19
to CCPPETMR/SIRF, Subscribed

Ok, looks like I didn't do the iterators correctly for other datatypes.

@johannesmayer This might be a very simple solution for you (if it suits your needs):
In nifti_image, data are stored as a void*. This means that whenever you want to get your data back, there are often a lot of switch statements (e.g., in the NiftyReg source code). To avoid this, I decided to always store images as floats. So, you could potentially open your unsigned int image as a float. Internally, it will convert the image to float and will be converted back to unsigned int as you are saving (or can be saved to some other datatype).

Some of the example images in data/examples/Registration aren't originally float. E.g., running:

sirf_print_nifti_info test.nii.gz test2.nii.gz standard.nii.gz mouseFixed.nii.gz mouseMoving.nii.gz 

Printing info for 5 nifti image(s):
    ...
    datatype:          16, 16, 16, 16, 16
    ...
    orig_datatype:     4, 2, 16, 4, 4
    ...

So you can see that some are 4 (NIFTI_TYPE_INT16), one is 2 (NIFTI_TYPE_UINT8) and the last is 16 (NIFTI_TYPE_FLOAT32), but they all behave as expected.

Does that make sense? In short, just use NiftiImageData3D<float> even if the input data type is not float. On reflection, it is somewhat confusing...

Johannes Mayer

unread,
Feb 4, 2019, 8:36:21 AM2/4/19
to CCPPETMR/SIRF, Subscribed

@rijobro Thanks for the suggestion. I tried, but using the constructor I need, i.e.

/// Construct from array 
NiftiImageData3D(const dataType * const data, const VoxelisedGeometricalInfo3D &geom)

, this does not work unfortunately since, then it takes the pointer to unsigned int and store it as float.
Internally this gets mixed up to something of the order e-44 instead of my integers.

Richard Brown

unread,
Feb 4, 2019, 8:55:12 AM2/4/19
to CCPPETMR/SIRF, Subscribed

Strange. If you run sirf_print_nifti_info with your image, does it print 768 (NIFTI_TYPE_UINT32) for the original datatype?

Richard Brown

unread,
Feb 4, 2019, 8:58:41 AM2/4/19
to CCPPETMR/SIRF, Subscribed

Ohhh, I see the problem. That particular constructor should probably be templated for input data type (unsigned int) and then resulting image type (float). That would solve you're problem, right?

Johannes Mayer

unread,
Feb 4, 2019, 9:01:10 AM2/4/19
to CCPPETMR/SIRF, Subscribed

Yes, if I cannot use the template argument as unsigned int then this would probably be a working workaround.

Richard Brown

unread,
Feb 4, 2019, 11:07:18 AM2/4/19
to CCPPETMR/SIRF, Subscribed

Ok, i've just pushed that to master. I've put in a ctest (for both NiftiImageData and NiftiImageData3D) in which I create an image from an unsigned int array.

https://github.com/CCPPETMR/SIRF/blob/ed219b4da022d4628df64d1f7769cd4c2c8a9e39/src/Registration/cReg/tests/test_cReg.cpp#L205-L222

Richard Brown

unread,
Feb 5, 2019, 5:08:11 AM2/5/19
to CCPPETMR/SIRF, Subscribed

Can I close this?

Kris Thielemans

unread,
Feb 23, 2019, 4:37:28 PM2/23/19
to CCPPETMR/SIRF, Subscribed

@johannesmayer could you confirm if this is fixed?

Johannes Mayer

unread,
Feb 26, 2019, 7:15:05 AM2/26/19
to CCPPETMR/SIRF, Subscribed

For me they don't compile. But I also have no idea why since I didn't dig into the code so unfortunately I cannot offer a potential solution.

However, the workaround Richard implemented is good for me and I don't need an instance of another type than float.

Kris Thielemans

unread,
Feb 26, 2019, 4:46:20 PM2/26/19
to CCPPETMR/SIRF, Subscribed

Thanks! I've postponed till later

Richard Brown

unread,
Mar 4, 2019, 4:58:18 AM3/4/19
to CCPPETMR/SIRF, Subscribed

Would you be able to clarify what didn't compile? Thanks

Johannes Mayer

unread,
Mar 4, 2019, 5:22:56 AM3/4/19
to CCPPETMR/SIRF, Subscribed

The same thing as I posted in the initial message of this thread. I thought you changed that there is a constructor to fill a NiftiImage<float> from a unsigned int*.
This works for me, but as far as I understood didn't fix the problem with the Iterators?

Richard Brown

unread,
Mar 4, 2019, 12:45:04 PM3/4/19
to CCPPETMR/SIRF, Subscribed

Ah yeah, ok. I don't plan on doing this any time soon though.

Kris Thielemans

unread,
Aug 30, 2019, 10:22:02 AM8/30/19
to CCPPETMR/SIRF, Subscribed

is this one still necessary? If so, should be rescheduled to 2.2?

Reply all
Reply to author
Forward
0 new messages