Find all available modules from GroupIO

Is it possible to use any installed/available modules from Group IO without specifying particular Modules: IOTIFF, etc? Something like:

find_package(ITK COMPONENTS ITKExternalModule ITKGroupIO ...)

Right now I am using:

find_package(ITK COMPONENTS IsotropicWavelets ITKIOImageBase ITKIOTIFF ITKIOPNG ITKIOJPEG REQUIRED)

But it feels like my application shouldn’t care what IO modules the user has selected.

What do you use/recommend here? Thanks

1 Like

The list of packages are important in the case of static libraries - the more formats you list, the bigger your compiled executable will be.

1 Like

Good question, @phcerdan.

What is needed is not necessarily the Group IO modules – what is needed are all modules that provide itk::ImageIOBase classes for population of the factory. Some modules in Group IO provide transform and mesh IO. And, there other modules that provide ImageIOBase classes that are not in Group IO.

So, what we needed is a new parameter for the itk_module macro that declares what factory classes a module provides. These values can be stored in lib/cmake/ITK-4.XX/Modules/ModuleName.cmake, and loaded and parsed by ITKConfig.cmake when find_package(ITK is called.

1 Like

While having improved information specified in the itk_module, for internal and external management of the IO factories, would be an overall good thing, there are some conventions that can be currently be utilized. Currently, all IO modules names contain “IO”, so I have using the following in SimpleITK, which may work for your case too:

2 Likes

Thanks for the feedback! @matt.mccormick that would super helpful for external projects indeed. I’ll go for parsing ITK_MODULES_ENABLED for now, as @blowekamp suggested. Thanks!

For completeness, this is what I have used based on @blowekamp suggestion.

I had to find_package twice to import ITK_MODULES_ENABLED

find_package(ITK CONFIG REQUIRED)
set(use_itk_modules IsotropicWavelets )
foreach( mod IN LISTS ITK_MODULES_ENABLED)
  if( ${mod} MATCHES "IO")
    list(APPEND use_itk_modules ${mod})
  endif()
endforeach()
find_package(ITK COMPONENTS ${use_itk_modules} REQUIRED)
#include_directories(${ITK_INCLUDE_DIRS}) # Not needed
include(${ITK_USE_FILE})

Another option would be to do:

# First pass to get the list of IOs available
find_package(ITK CONFIG REQUIRED)
include(${ITK_USE_FILE})

# Create list of avaialble image formats
foreach(ImageFormat ${LIST_OF_IMAGEIO_FORMATS})
  if (NOT ${ImageFormat}_image_module_name )
     list(APPEND IOList ITKIO${ImageFormat})
  endif()
endforeach()
find_package(ITK COMPONENTS IsotropicWavelets ${IOList} REQUIRED )
include(${ITK_USE_FILE})

I haven’t tried it, but I think it should work.

I thought LIST_OF_IMAGEIO_FORMATS and LIST_OF_TransformIO_FORMATS were “private” cmake variables, and not part of the public interface for of UseITK.cmake?

1 Like

Thanks for the follow-up, @phcerdan.

Minor tweak possible here – include_directories is called already by include(${ITK_USE_FILE}), so it can be removed. This will help reduce the length of the command line calls.

1 Like

Thanks @matt.mccormick , I commented it out.

Do you know if this approach is still valid in ITK-5.0?
I cannot read 3D tiff files with the suggested workaround --it reads a 3D image, but only the first slice-- but if a hard code the ITKIOTIFF component it works.
I am not getting a read error, it is just that the image of size 64x64x16 reads as 64x64x1.

A much better approach is available in ITK 4.13 and newer.

find_package(ITK REQUIRED COMPONENTS ITKImageIO)

Here ITKImageIO will bring in all modules that have Image IO’s, whether they are in the IO group or otherwise (like remote modules).

1 Like

Oh yeah, thanks!

For completeness, I tested it and it doesn’t work. For version < 4.13 I am sticking with what I was using.
Since 4.13, ITKImageIO is awesome :slight_smile:
Thanks!

2 Likes

@matt.mccormick and @phcerdan I am wondering how we can realize which components should be added in the cmakelist. For example, once I included the #include <itkMeshFileWriter.h> , I was getting the undefined reference errors as follows:

CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0xc0): undefined reference to `itk::BYUMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0xc8): undefined reference to `itk::BYUMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0xd0): undefined reference to `itk::FreeSurferAsciiMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0xd8): undefined reference to `itk::FreeSurferAsciiMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0xe0): undefined reference to `itk::FreeSurferBinaryMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0xe8): undefined reference to `itk::FreeSurferBinaryMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0xf0): undefined reference to `itk::GiftiMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0xf8): undefined reference to `itk::GiftiMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0x100): undefined reference to `itk::OBJMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0x108): undefined reference to `itk::OBJMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0x110): undefined reference to `itk::OFFMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0x118): undefined reference to `itk::OFFMeshIOFactoryRegister__Private()'
CMakeFiles/3-WritePLY.dir/main.cpp.o:(.data+0x120): undefined reference to `itk::VTKPolyDataMeshIOFactoryRegister__Private()'

I just commented the include line and then could run the code. But how we can know that which component should we include in the fine_package in the cmake file whenever we are including any specific header file?

Is there any reference that we can get help from?

Hey @Sara_Caffe, please do not revamp existing threads for completely new questions. Just open a new one.

ITK has a helper script WhatModulesITK.py for finding what modules you need based on the #include's you have in your projects.

See this thread for more info about modules.

For usage, see documentation in the python script, for example:
Single file:

 /path/src-ITK-master/Utilities/Maintenance/WhatModulesITK.py /path/ITK/src-ITK-master /path/myproject/foo.cpp)

List of files:

 /path/src-ITK-master/Utilities/Maintenance/WhatModulesITK.py /path/ITK/src-ITK-master $(find /path/myproject/ -type f)
3 Likes

Thank you Sir, This is really helpful. Sorry for asking the question here

appreciate it.