The title says it all. I want a docker image of slicer with elastix extension preinstalled. My current Dockerfile is the following:
# start from base with centos & qt5
FROM slicer/buildenv-qt5-centos7:latest
WORKDIR /usr/src
# get basics for the gui
RUN yum install Xvfb Xorg mesa-dri-drivers libGLEW -y
# get slicer nighly version
RUN git clone -b master https://github.com/Slicer/Slicer.git
# create slicer-build and environment
RUN mkdir /usr/src/Slicer-build && \
cd /usr/src/Slicer-build && \
# build slicer
cmake \
-DCMAKE_BUILD_TYPE:STRING=Release \
-DQt5_DIR:PATH=${Qt5_DIR} \
-DSlicer_USE_SimpleITK:BOOL=OFF \
-DSlicer_USE_QtTesting:BOOL=OFF \
/usr/src/Slicer && \
# build dependencies
make -j 32
# create environment variables
ENV PATH="${PATH}:/usr/src/Slicer-build/python-install/bin"
ENV PYTHONPATH="${PYTHONPATH}:/usr/src/Slicer-build/python-install/bin/PythonSlicer"
ENV SLICER=/usr/src/Slicer
# Create ExtensionsIndex
RUN git clone git://github.com/Slicer/ExtensionsIndex.git && \
mkdir ExtensionsIndex-build && cd ExtensionsIndex-build && \
cmake -DSlicer_DIR:PATH=/usr/src/Slicer-build/Slicer-build -DSlicer_EXTENSION_DESCRIPTION_DIR:PATH=../ExtensionsIndex \
-DCMAKE_BUILD_TYPE:STRING=Release ${SLICER}/Extensions/CMake && \
make -j 32
# Install Elastix
RUN PythonSlicer -c "import sys;print(sys.path)"
RUN PythonSlicer -m pip install --upgrade pip
RUN PythonSlicer -m pip install 2to3 lmfit
RUN 2to3 -w /usr/src/Slicer-build/python-install/lib/python3.6/site-packages/uncertainties
# start running container
CMD bash
But this raises an 18GB image!! All extensions are built!! The worst is: no extension is installed! They are all built and able to be installed, but not actually installed.
When I try to use it, it says slicer has no module app.
I have tried building an image from slicer-base, but it is also unsuccessful. The Dockerfile is:
# start from base with slicer-base
FROM slicer/slicer-base
WORKDIR /usr/src/Slicer
# get basics for the gui
RUN yum install Xvfb Xorg mesa-dri-drivers libGLEW -y
# create slicer package
RUN ../Slicer-build/BuildSlicer.sh && \
package=$(head -n1 /usr/src/Slicer-build/Slicer-build/PACKAGE_FILE.txt) && \
echo "package [${package}]" && \
mkdir -p /Slicer-package && \
mv ${package} /Slicer-package/
# create environment variables
ENV PATH="${PATH}:/Slicer-package/"
ENV PYTHONPATH="${PYTHONPATH}:/usr/src/Slicer-build/python-install/bin/PythonSlicer"
ENV SLICER=/usr/src/Slicer
# Install Elastix
RUN PythonSlicer -c "import sys;print(sys.path)"
RUN PythonSlicer -m pip install --upgrade pip
RUN PythonSlicer -m pip install 2to3 lmfit
RUN 2to3 -w /usr/src/Slicer-build/python-install/lib/python3.6/site-packages/uncertainties
RUN (echo "import slicer" ; echo "emm = slicer.app.extensionsManagerModel()"; echo "md = emm.retrieveExtensionMetadataByName('SlicerElastix')"; echo "emm.dow$
RUN PythonSlicer InstallElastix.py
# start running container
CMD bash
This fails in the BuildSlicer.sh
Step 4/14 : RUN ../Slicer-build/BuildSlicer.sh && package=$(head -n1 /usr/src/Slicer-build/Slicer-build/PACKAGE_FILE.txt) && echo "package [${package}]" && mkdir -p /Slicer-package && mv ${package} /Slicer-package/
---> Running in 8bb2e3f6bf82
+ set -o pipefail
+ set -o
allexport off
braceexpand on
emacs off
errexit on
errtrace off
functrace off
hashall on
histexpand off
history off
ignoreeof off
interactive-comments on
keyword off
monitor off
noclobber off
noexec off
noglob off
nolog off
notify off
nounset off
onecmd off
physical off
pipefail on
posix off
privileged off
verbose off
vi off
xtrace on
+ cd /usr/src/Slicer-build
+ /usr/bin/cmake -E make_directory /usr/src/Slicer
+ /usr/bin/cmake -E make_directory /usr/src/Slicer-build/Slicer-build
+ /usr/bin/cmake -E make_directory /usr/src/Slicer-build/Slicer-prefix
+ /usr/bin/cmake -E make_directory /usr/src/Slicer-build/Slicer-prefix/tmp
+ /usr/bin/cmake -E make_directory /usr/src/Slicer-build/Slicer-prefix/src/Slicer-stamp
+ /usr/bin/cmake -E make_directory /usr/src/Slicer-build/Slicer-prefix/src
+ /usr/bin/cmake -E touch /usr/src/Slicer-build/Slicer-prefix/src/Slicer-stamp/Slicer-mkdir
+ cd /usr/src/Slicer-build/Slicer-prefix/src
+ /usr/bin/cmake -E echo_append
+ /usr/bin/cmake -E touch /usr/src/Slicer-build/Slicer-prefix/src/Slicer-stamp/Slicer-download
+ cd /usr/src/Slicer
+ /usr/bin/cmake -E echo_append
+ /usr/bin/cmake -E touch /usr/src/Slicer-build/Slicer-prefix/src/Slicer-stamp/Slicer-update
+ cd /usr/src/Slicer-build
+ /usr/bin/cmake -E echo_append
+ /usr/bin/cmake -E touch /usr/src/Slicer-build/Slicer-prefix/src/Slicer-stamp/Slicer-patch
+ cd /usr/src/Slicer-build/Slicer-build
+ /usr/bin/cmake -C/usr/src/Slicer-build/Slicer-prefix/tmp/Slicer-cache-Release.cmake -GNinja /usr/src/Slicer
loading initial cache file /usr/src/Slicer-build/Slicer-prefix/tmp/Slicer-cache-Release.cmake
CMake Error: The source directory "/usr/src/Slicer" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.
+ exit 1
The command '/bin/sh -c ../Slicer-build/BuildSlicer.sh && package=$(head -n1 /usr/src/Slicer-build/Slicer-build/PACKAGE_FILE.txt) && echo "package [${package}]" && mkdir -p /Slicer-package && mv ${package} /Slicer-package/' returned a non-zero code: 1
Please remember this is a docker container, I can’t start slicer there. Also the slicer-base image is supposed to have a prebuilt image of Slicer, I just need to add the elastix extension by default. I can trigger the instalation in Slicer by:
but in the docker environment this fails with the error:
Traceback (most recent call last):
File "installElastix.py", line 2, in <module>
emm = slicer.app.extensionsManagerModel()
AttributeError: module 'slicer' has no attribute 'app'
vtkDebugLeaks has found no leaks.
E15TY:~ alexvergaragil$ docker run -it slicer/buildenv /bin/bash
Unable to find image 'slicer/buildenv:latest' locally
docker: Error response from daemon: pull access denied for slicer/buildenv, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
See 'docker run --help'.
I have tried this approach and in the test it will fail with
CMake Error at CMakeLists.txt:17 (find_package):
By not providing "FindSlicer.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Slicer", but
CMake did not find one.
Could not find a package configuration file provided by "Slicer" with any
of the following names:
SlicerConfig.cmake
slicer-config.cmake
Add the installation prefix of "Slicer" to CMAKE_PREFIX_PATH or set
"Slicer_DIR" to a directory containing one of the above files. If "Slicer"
provides a separate development package or SDK, be sure it has been
installed.
The CMakeList.txt in my extension is:
cmake_minimum_required(VERSION 3.5)
project(Dosimetry4D)
#-----------------------------------------------------------------------------
# Extension meta-information
set(EXTENSION_HOMEPAGE "http://gitlab.com/opendose/opendose4d")
set(EXTENSION_CATEGORY "Dosimetry")
set(EXTENSION_CONTRIBUTORS "Alex Vergara Gil (INSERM) and Janick Rueegger (KSA)")
set(EXTENSION_DESCRIPTION "This extension contains the entire dosimetry workflow for a multipoint study")
set(EXTENSION_ICONURL "https://opendose.org/themes/default/images/opendose_favicon.png")
set(EXTENSION_SCREENSHOTURLS "http://www.example.com/Slicer/Extensions/Dosimetry/Screenshots/1.png")
set(EXTENSION_DEPENDS SlicerElastix) # Specified as a space separated string, a list or 'NA' if any
#-----------------------------------------------------------------------------
# Extension dependencies
find_package(Slicer REQUIRED)
include(${Slicer_USE_FILE})
#-----------------------------------------------------------------------------
# Extension modules
add_subdirectory(Dosimetry4D)
## NEXT_MODULE
#-----------------------------------------------------------------------------
include(${Slicer_EXTENSION_GENERATE_CONFIG})
include(${Slicer_EXTENSION_CPACK})
#-----------------------------------------------------------------------------
option(ENABLE_TESTS "Enable tests" OFF)
if (${ENABLE_TESTS})
enable_testing()
endif()
but my extension is just a python module, Is there a way to avoid the find_package(Slicer REQUIRED) line??
I have done that, but that path does not contain any cmake file in the nightly build. You can use docker run -it unnmdnwb3/slicer3d-nightly:0.8.0 /bin/bash to test this approach. It contains a slicer-base image with a preinstalled slicer-nightly. the Slicer_DIR is /usr/src/Slicer
I see. An install tree is not sufficient for build&test. As a workaround, you could create a script that runs Pytjon selftests manually. You can find the full command-line of each test on CDash.
Actually I only require the slicerMacroBuildScriptedModule macro definition to run the tests. This file does not depend on any slicer header, but is the one who builds the python module.
Are the command lines like this one?
It would be nice to properly build and test your extension. It would increase the test coverage (it would test building) and you never know when you’ll need to add a loadable or CLI module to your extension.
I can perform normal test without elastix, but that will truncate half the functionality of my extension. Is it possible to have a build sequence that leaves me with a built Slicer+Elastix by default?
I have tried to run manually the tests and this happens
$ /usr/src/Slicer/bin/PythonSlicer -c "import slicer.testing; slicer.testing.runUnitTest(['$CI_BUILDS_DIR/dosimetry4d-build/Dosimetry4D/Logic', '$CI_BUILDS_DIR/opendose/opendose4d/Dosimetry4D/Logic'], 'Dosimetry4DTest')"
Dosimetry4DTest (unittest.loader._FailedTest) ... ERROR
======================================================================
ERROR: Dosimetry4DTest (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: Dosimetry4DTest
Traceback (most recent call last):
File "/usr/src/Slicer/lib/Python/lib/python3.6/unittest/loader.py", line 153, in loadTestsFromName
module = __import__(module_name)
File "/builds/dosimetry4d-build/Dosimetry4D/Logic/Dosimetry4DTest.py", line 3, in <module>
from slicer.ScriptedLoadableModule import ScriptedLoadableModuleTest
File "/usr/src/Slicer/bin/Python/slicer/ScriptedLoadableModule.py", line 4, in <module>
import qt, ctk, slicer
File "/usr/src/Slicer/bin/Python/qt/__init__.py", line 19, in <module>
from PythonQt.private import QObject
ModuleNotFoundError: No module named 'PythonQt'
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/src/Slicer/bin/Python/slicer/testing.py", line 26, in runUnitTest
exitFailure()
File "/usr/src/Slicer/bin/Python/slicer/testing.py", line 11, in exitFailure
raise Exception(message)
Exception
No module named 'logic'
-------------------------------------------
path: ['/builds/dosimetry4d-build/Dosimetry4D/Logic', '/builds/opendose/opendose4d/Dosimetry4D/Logic']
testname: Dosimetry4DTest
-------------------------------------------
vtkDebugLeaks has found no leaks.
I think preinstalled slicer leads to even more errors than building it
I have succeeded to make a Full Test using BrainsFit, not optimal but good enough solution. The Full Test in graphical mode (Reload and test) will use elastix if it is installed.
The module is complete, I am just waiting for testers answers. Next steps will be:
Write the article (shall be presented in ECMP2020 or EANM2020)
Open the source (as soon as the abstract is accepted)
integrating in Slicer as scripted module (I will need your help in this point). The module shall be accesible by the time the article is published.