Welcome to LithoGraphX’s documentation!

Screen shot of LithoGraphX

LithoGraphX is a software to visualize, process and analyse 3D images and meshes. This documentation is organized into a reference manual describing the user interface in details and a collection of tutorials describing how to perform usual tasks.

The main website of LithoGraphX is: http://www.lithographx.com

LithoGraphX is a fork of the MorphoGraphX project.

Getting help:

  1. Read this documentation
  2. If you have problems, want help or have suggestions, use the
    LithoGraphX bitbucket issue tracker.
  3. You can also contact me by email at pierre@barbierdereuille.net

Hint

If you have never used LithoGraphX, I recommend you start by reading the definitions and the description of the main interface. Then, you should probably read tutorials close to what you want to do.

Installation

Hardware Requirements and Recommendations

Volumetric rendering and 3D image processing are very demanding tasks both for the CPU and the GPU. For this reason, it is highly recommended to opt for high-end desktop computer. Also, both because LithoGraphX uses CUDA and because their video drivers tend to be more stable we highly recommend using NVidia GPUs.

Minimum configuration

Desktop Computer
  • CPU: Intel Core i7 with 8GB to 16GB of RAM (depending on the size of your images)
  • GPU: any NVidia or AMD GPU less than 5 years old.
Laptop Computer
  • CPU: Intel Core i7 with 8GB to 16GB of RAM (depending on the size of your images)
  • GPU: high-end NVidia GPU of Intel HD Graphics 4600 or more recent with the latest video drivers (tested with drivers Build 10.18.15.4248). We do not recommend AMD GPUs due to serious issues with their video drivers for laptops.

Install from binaries

windows_logo Microsoft Windows

Quick Setup
  1. Install LithoGraphX for Windows: http://updates.lithographx.com (the default version requires an NVidia graphics cards, otherwise download the NOCUDA version)
  2. Install Anaconda Python 2.7 64 bits: https://www.continuum.io/downloads
Full Setup

If you don’t want to install Anaconda or would rather know the full list of Python modules used in LithoGraphX, please read on.

First, to run LithoGraphX, you will also need to install the 64 bits version of Python 2.7 for Windows. There are many sources from which you can download Python for windows. We recommend using Anaconda (https://www.continuum.io/downloads), as it will include by default a large number of libraries for scientific computing and machine learning. However, you can also download the official python binaries from there: Python 2.7.11 64 bits.

If you install the official python binaries, you may need to install Numpy, SciPy and scikit-learn (all of which are provided by Anaconda) as they are used by some macros. First, install Numpy and Scipy by downloading the corresponding wheel files from this website: http://www.lfd.uci.edu/~gohlke/pythonlibs/. Once the files downloaded, you can use pip to install them. For example, at the time this is written, you will download the files numpy-1.10.4+mkl-cp27-cp27m-win_amd64.whl for numpy, scipy-0.17.0-cp27-none-win_amd64.whl for scipy and pandas-0.17.1-cp27-none-win_amd64.whl for pandas. To install them, open a command prompt and type:

pip install numpy-1.10.4+mkl-cp27-cp27m-win_amd64.whl scipy-0.17.0-cp27-none-win_amd64.whl pandas-0.17.1-cp27-none-win_amd64.whl

pip can also be used to download and install scikit-learn:

pip install scikit-learn

You will find all binary installers in the LithoGraphX update site: http://updates.lithographx.com. LithoGraphX for windows is currently compiled in two version:

  • a version requiring CUDA, this is the default version.
  • a version that doesn’t use CUDA, named -NOCUDA.

Download the version you want (probably the latest) and execute it to install LithoGraphX.

Note

Since the version 1.1.1, LithoGraphX for Windows will check if a new version exist, and will offer to update your installation. Automatic checking for a new version can be tweaked/deactivated from the settings dialog box.

Hint

If you have issues, check the FAQ on installation.

ubuntu_logo Linux - Ubuntu

The simplest way to install LithoGraphX and to keep it up to date is to use the launchpad PPA. To use it you have two options:

  1. From the Ubuntu Software Center, select the menu Edit->Software Sources. In the Other software tab, click the Add... button and enter ppa:pierre-barbierdereuille/ppa in the APT line. For more details look at the answer of this question:

    http://askubuntu.com/questions/4983/what-are-ppas-and-how-do-i-use-them

    The PPA offers 4 packages. The two main ones are lithographx and lithographx-nocuda. As the name suggests, lithographx-nocuda simply doesn’t use CUDA. These two packages contain the latest tested version of LithoGraphX. The two other packages are lithographx-daily and lithographx-nocuda-daily. As their name suggests, these two packages are compiled daily with whatever the latest version of the source code is. As such, they are not recommended for non-developers.

  2. You can use the command line and type from a terminal:

    $ sudo add-apt-repository ppa:pierre-barbierdereuille/ppa
    $ sudo apt-get update
    $ sudo apt-get install lithographx
    

Hint

If you have issues, check the FAQ on installation.

Important

After installing LithoGraphX on Linux, you need to configure the Alt key.

linux_logo Linux - other

If you don’t use an Ubuntu-derived distribution but still a debian-derived one, you can obtain the source package and build it yourself:

  1. Enable source downloading for the PPA:

    $ sudo add-apt-repository -s ppa:pierre-barbierdereuille/ppa
    
  2. Create a folder where you are going to build the package. From this folder, type:

    $ apt-get source -b lithographx
    

    If you have problems building, or want to adjust the dependencies for your system, you can also first get the source code:

    $ apt-get source lithographx
    

    Make the necessary adjustments to the package, and build it. For the version 1.1.0, you can build the package with:

    $ cd lithographx-1.1.0
    $ dpkg-buildpackage -us -uc -nc
    

    The debian package will be created in the folder containing lithographx-1.1.0.

For non-debian based systems, you will need to install from source. If you need help doing so, do not hesitate to contact us.

Important

After installing LithoGraphX on Linux, you need to configure the Alt key.

Install from source

First, you need to retrieve the source code, which is hosted by BitBucket: https://bitbucket.org/PierreBdR/lithographx

Then, you need to follow the instructions for your operating system.

Requirements

To compile LithoGraphX you will need the following programs installed (more recent versions should work too):

To run some of the macros, you will need:

To generate the documentation, you will need:

linux_logo Installation on Linux

If using Ubuntu, or probably any debian-derived system, you will find a list of packages to install in the file called ubuntu-packages.txt at the root of the source tree.

In the list of dependencies, the packages nvidia-cuda-toolkit may be replaced with any package from NVidia (e.g. cuda-7-0), or simply by libthrust-dev if you want to compile without CUDA.

For other distribution, you will need to find equivalent packages.

Configuration

Create a folder in which the application will be built. Then, using cmake-gui, select the source and build directories. Make sure CMAKE_BUILD_TYPE is set to Release, and select the modules you want to build by checking the variables starting with BUILD_. When configuring, more options may appear (in red), in this case, just configure again, until you have no error and no red line. When that is done, click the Generate button.

Compilation

Open a shell in the build folder and simply use make. To speed up compilation, you can choose to use parallel compilation with the -j options. For examplem to use 8 compilation processes in parallel, type: make -j8.

windows_logo Installation on Windows

Configuring your development environment for Windows is a complex task. We are using gcc for the compilation (to be able to use the GNU Scientific Library), but at the same time, python and CUDA require the use of Visual Studio (at least by default). For that reason, windows has its own page:

Installing LithoGraphX from Source on Microsoft Windows

There are two ways of compiling for Windows: the recommended way using MinGW64 or using Visual Studio.

Compilation with MinGW64 – The Easy Way

The easier way to compile with MinGW64 is to install it via MSys2: http://sourceforge.net/projects/msys2/

Here is a step by step method to install all the libraries you need for LithoGraphX.

  1. (Cuda version only) Install Visual Studio 2013, for example the community edition which is available for free on http://www.visualstudio.com. From this version, you only need the C++ component.

  2. (Cuda version only) Install the CUDA drivers. Note: These must be installed after Visual Studio, so CUDA find it and install all the necessary components.

  3. Install MSys2 using the graphical installer

  4. Open the MSys2 Win64 shell using the shortcut installed in the start menu.

  5. Upgrade MSys2 using pacman, the package manager of MSys2:

    $ pacman -Su
    
  6. Install the packages we need for LithoGraphX:

    $ pacman -S mingw-w64-x86_64-libtiff mingw-w64-x86_64-qt5 mingw-w64-x86_64-python2-pyqt5 mingw-w64-x86_64-eigen3 mingw-w64-x86_64-cmake doxygen
    
  7. (Optional). Install VTK:

    $ pacman -S mingw-w64-x86_64-vtk mingw-w64-x86_64-opencv
    

    We also need to install OpenCV as it is a dependence of VTK. However, as far as the version 20150512 of MSys2 is concerned, OpenCV is not installed automatically with VTK.

  8. (Optional). Install ITK. Sadly, the version of ITK that comes with MSys2 doesn’t include the auto-seeded morphological watershed, central in so many protocols of LithoGraphX. So we need to compile it ourselve:

    1. Download ITK from http://www.itk.org

    2. Prepare your directory structure. For simplicity, I will assume everything linked to ITK will be in the same folder. This folder will contain three sub-folder:

      ITK_Source

      Contains the source code of ITK

      ITK_Build

      Will contain the build files of ITK

      ITK

      Will contain the installed version of ITK

    3. Make sure the three directories exist, and ITK_Source contains the source code.

    4. Launch a MSys2 Win64 shell, using the shortcut in the start menu.

    5. Go to the ITK folder. Careful: MSys2 has an odd syntax. For example, if your folder is C:\Users\Me\ITK, then you need to type:

      $ cd /C/Users/Me/ITK
      
    6. Configure ITK:

      $ cd ITK_Build
      $ cmake -G "MinGW Makefiles" -DCMAKE_CXX_FLAGS="-std=c++11" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DModule_ITKReview=ON -DCMAKE_INSTALL_PREFIX=../ITK ../ITK_Source
      
    7. Then, compile and install ITK:

      $ make -j4 install
      
  9. (Optional). Install the GNU Scientific Library:

    $ pacman -S -s mingw-w64-x86_64-gsl
    
  10. (NoCuda version only) Download and extract the thrust library https://thrust.github.io. As this library only contains header files, there is nothing to compile. Simply mark down where it is installed.

  11. (Cuda version only) Create batch scripts to have both MinGW64 and Visual Studio compilers available. For the default installation of Visual Studio and MinGW64, the script should contain:

    call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64
    @echo Visual Studio installed in current shell
    @set MINGW64=C:\msys64\mingw64
    @set PATH=%MINGW64%\bin;%PATH%
    @echo MINGW64 installed in current shell
    

    You might also want to create a shortcut to start the shell. Right-click somewhere (for example the desktop) and select New->Shortcut. In the dialog box that appear, for location type:

    %comspec% /k ""C:\Path\to\script.bat""
    

    For the following, use the shortcut to open a terminal, and go to the LithoGraphX source tree:

    $ cd C:\Users\Me\LithoGraphX
    
  12. (NoCuda version only). Open an msys Win64 shell from the start menu, and go to the LithoGraphX source tree:

    $ cd /C/Users/Me/LithoGraphX
    
  13. Create a Build folder in the LithoGraphX source tree:

    $ mkdir Build
    $ cd Build
    
  14. Configure LithoGraphX:

    $ cmake-gui ..
    
    1. (Cuda version) Select MinGW Makefiles

    2. (NoCuda version) Select MSys Makefiles

    3. On the right of the search box, check the boxes Grouped and Advanced.

    4. Press the Configure button and check for errors until there are none left. Typically, you will need to inform the following variables:

      PYTHON_EXECUTABLE

      CMake will find the program python.exe, but really you want python2.exe in the same folder

      PYTHON_LIBRARY

      If you already have python installed, CMake may find it instead of the python for MinGW64. If you left the default installation folder of MSys2, the correct path for the library is C:/msys64/mingw64/lib/libpython2.7.dll.a

      SIP_EXECUTABLE

      This is the path to the sip.exe program. It should be at C:/msys64/mingw64/bin/sip.exe.

      SIP_PYQT5_CORE_PATH

      This is the path to the Core module of PyQt5. This should be C:/msys64/mingw64/share/sip/Py2-Qt5/QtCore

      SIP_PYQT5_PATH

      This is the path to all the modules of PyQt5. This should be: C:/msys64/mingw64/share/sip/Py2-Qt5

      THRUST_BACKEND_CUDA / THRUST_BACKEND_OMP

      Check one or the other depending on whether you want to compile with CUDA or not. If not, you can delete the whole CUDA group.

      CMAKE_BUILD_TYPE

      Set this one to Release to compile with all the optimizations.

      CMAKE_INSTALL_PREFIX

      If you don’t want to install LithoGraphX into the Program Files folder, change the value. Note that to install in Program Files, you need to set the proper permissions, unless you use the installer.

      BUILD_ITK

      If you have build ITK, check this box. The last build of ITK should be found automatically.

      BUILD_VTK

      If you have installed VTK, check this box. Again, CMake should find where it is automatically.

    5. When you are done configuring, press the Generate button. If there is no error, you are done with configuring LithoGraphX.

  15. Now, you need to compile LithoGraphX. If you use the MSys command line, you need to type:

    $ make -j8
    

    Otherwise, you need to type:

    $ mingw32-make
    
  16. Once compiled, you can either directly install LithoGraphX, or create a package you can re-distribute. We recommend the creation of a package. For this, from the command line, type:

    $ cpack -G NSIS64
    
Compilation with MinGW64 – The Hard Way

This is another way to get MinGW64 with all the libraries. It avoids compiling MinGW64 and Qt, but almost all the other dependencies are compiled.

Because CUDA requires Visual C++ under windows, and because we are using MinGW64 for the rest of the compilation, you have to be careful when installing your development environment. Here, I will describe how to install it for CUDA 7.0:

  1. Install Visual Studio 2013, for example the community edition which is available for free on http://www.visualstudio.com. From this version, you only need the C++ component.

  2. Install the CUDA drivers. Note: These must be installed after Visual Studio, so CUDA find it and install all the necessary components.

  3. Install python. We highly recommend using Anaconda. Once installed, you will need to install the libpython conda package.

  4. Download the source code of SIP and PyQt5 from http://www.riverbankcomputing.com

  5. Download the version of Qt5 corresponding to the version of PyQt5 you downloaded from http://sourceforge.net/projects/qt64ng Note: This version of Qt5 also contains python 2.7. However, to make it work you need to go into mingw64\opt\bin and copy the file libpython2.7.dll to mingw64\libs\python27.dll (the folder doesn’t exist)

  6. Download MSys from the MinGW64 website here: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/

  7. To make your life simpler, create two scripts that will add the path to MinGW64 to your PATH environment variable: one for the command shell, and one for UNIX shell. Assuming you installed MinGW64 in C:\MinGW64, the first script should be called mingw64.bat and have for content:

    @set MINGW64=C:\MinGW64
    @set PATH=%MINGW64%\bin;%MINGW64%\opt\bin;%MINGW64%\opt\libs;%PATH%
    

    The second script should be called mingw64.sh and have for content:

    export PATH=/c/MinGW64/bin:$PATH
    

    This way, when you open a terminal, if this is a windows command, you can type:

    $ call mingw64.bat
    

    and have MinGW64 available, or for MSys shell:

    $ source mingw64.sh
    
  8. Compilation of SIP
    1. Start a windows command and setup your environment variables for MinGW64:

      $ call mingw64.bat
      
    2. Configure sip:

      $ python configure.py -p win32-g++
      
    3. Compile and install:

      $ mingw32-make
      $ mingw32-make install
      
    4. Copy the file sip.exe in %MINGW64%\opt to %MINGW64%\opt\bin

# Compilation of PyQt5
  1. Start a windows command and setup your environment variables for MinGW64 (you can re-use the one open for SIP)

  2. Configure PyQt5:

    $ python configure.py --spec=win32-g++
    
  3. Compile and install:

    $ mingw32-make
    $ mingw32-make install
    
  4. Copy the files in %MINGW64%\opt to %MINGW64%\opt\bin

  1. Download the source code of libtiff5 from the GNUWin32 project: http://gnuwin32.sourceforge.net/packages/tiff.htm

    1. Launch the MSys shell
    2. Setup the environment variables for MinGW64
    3. Create a build directory and change to it (optional)
    4. Run the configure script, specifying a prefix
    5. Compile and install
  2. (Optional). Download and compile ITK at: http://www.itk.org

    1. Prepare your directory structure. For simplicity, I will assume everything linked to ITK will be in the same folder. This folder will contain three sub-folder:

      ITK_Source

      Contains the source code of ITK

      ITK_Build

      Will contain the build files of ITK

      ITK

      Will contain the installed version of ITK

    2. Make sure the three directories exist, and ITK_Source contains the source code.

    3. Launch a windows command and setup your environment variables for MinGW64

    4. From the main directory, configure ITK:

      $ cd ITK_Build
      $ cmake -G "MinGW Makefiles" -DCMAKE_CXX_FLAGS="-std=c++11" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DModule_ITKReview=ON -DCMAKE_INSTALL_PREFIX=..\ITK ..\ITK_Source
      
    5. Then, compile and install ITK:

      $ mingw32-make install
      
  3. (Optional). Download and compile VTK at: http://www.vtk.org

    1. Prepare your directory structure. For simplicity, I will assume everything linked to VTK will be in the same folder. This folder will contain three sub-folder:

      VTK_Source

      Contains the source code of VTK

      VTK_Build

      Will contain the build files of VTK

      VTK

      Will contain the installed version of VTK

    2. Create a build directory, for example call VTK_build

    3. Launch a windows command and setup your environment variables for MinGW64

    4. From the main directory, configure VTK:

      $ cd VTK_Build
      $ cmake -G "MinGW Makefiles" -DCMAKE_CXX_FLAGS="-std=c++11" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=..\VTK ..\VTK_Source
      
    5. Then, compile and install VTK:

      $ mingw32-make install
      
  4. (Optional, for extra modules only) Download the GNU scientific library from their website.

    1. Prepare your directory structure. For simplicity, I will assume everything linked to the GSL will be in the same folder. This folder will contain two sub-folder:

      GSL_Source

      Contains the source code of the GSL

      GSL

      Will contain the installed version of the GSL

    2. Launch the MSys shell

    3. Setup the environment variables for MinGW64

    4. Create a build directory and change to it (optional)

    5. Run the configure script, specifying a prefix:

      $ cd GSL_Source
      $ configure --prefix=../GSL
      
    6. Compile and install:

      $ make && make install
      
  5. Configure LithoGraphX for compilation

    1. Create a build directory

    2. Start a x64 Native Tools Command Prompt from the Visual Studio tools.

    3. Setup the MinGW64 environment variables:

      $ call mingw64.bat
      
    4. Change the current folder to the build directory you created

    5. Run cmake-gui, specifying the path to the source. For example, if you created your build folder as a sub-folder in the source tree:

      $ cmake-gui ..
      
    6. Select the MinGW Makefiles generator

    7. Check the Grouped check box to simplify the interface. This will put together all the options starting with the same work.

    8. Press the Configure button and check errors until there are none left. Typically you will need to inform the following variables have (in order in which they will appear):

      CUDA_CL_VERSION

      You need to set this to your version of Visual Studio, so here 2013.

      TIFF_INCLUDE_DIR

      This should be the include of the installation folder for libtiff.

      TIFF_LIBRARY

      This should be the file libtiff.a in the lib folder of the installation of libtiff.

      Eigen_SIGNATURE

      You need to select the file signature_of_eigen3_matrix_library in the Eigen folder.

      SIP_EXECUTABLE

      If this is not found by default, this is because you didn’t install sip in the default python location. It should be in the same folder as the python you used to compile it. If this is the case, you should activate the advanced options and make sure you select the python interpreter SIP is compiled for.

      SIP_INCLUDE_PATH

      This is the include folder, wherever the sip executable is

      SIP_PYQT5_PATH

      This should be the sip\PyQt5 folder, still where the sip executable is.

      PYTHON_LIBRARY

      To access this variable, you need to show the advance options. By default, this will look for python27.lib. If you use Anaconda, you need to install libpython and select the file libpython27.a instead.

      BUILD_EXTRA_INCLUDES

      If you didn’t install CImg in a standard path, chances are, you will need to add its path in this variable, for example if it is not found. This shouldn’t be a problem if you copy CImg.h in the src folder of LithoGraphX.

      CMAKE_BUILD_TYPE

      Set this to Release for maximal performance.

      CMAKE_INSTALL_PREFIX

      Choose the folder where LithoGraphX will be installed. If this is in Program Files, make sure the folder already exists and you can write in it, as normal programs cannot create a folder there.

      BUILD_ITK

      If you have built ITK, check this box

      BUILD_VTK

      If you have built VTK, check this box

  6. Without closing the command line, start the compilation:

    $ mingw32-make
    
  7. Then, install:

    $ mingw32-make install
    

You can contact the development team to get a zip file with all the versions we are using currently.

Compilation with Visual Studio 2013

Note the following process should also work with other versions of Visual Studio. However, I haven’t tested it, so it is not granted.

  1. Install Visual Studio 2013, for example the community edition which is available for free on http://www.visualstudio.com. From this version, you only need the C++ component.

  2. Install the CUDA drivers. Note: These must be installed after Visual Studio, so CUDA find it and install all the necessary components.

  3. Download the source code of SIP and PyQt5 from http://www.riverbankcomputing.com

  4. Download the version of Qt5 corresponding to the version of PyQt5 you downloaded.

  5. Download Python 2.7 or 3.4. If you are an academic, I recommend using the Anaconda distribution.

  6. Compilation of SIP
    1. Start a x64 Native Tools Command Prompt from the Visual Studio tools.

    2. Configure sip. At this time, only Visual Studio 2010 is supported, but it seems to work for Visual Studio 2013 too:

      $ python configure.py -p win32-msvc2010
      
    3. Compile and install:

      $ nmake
      $ nmake install
      
  7. Compilation of PyQt5
    1. Start the same command prompt used for SIP (you can re-use the one open for SIP)

    2. Configure PyQt5:

      $ python configure.py --spec=win32-msvc2013
      
    3. Compile and install:

      $ nmake
      $ nmake install
      
  8. Download the source code of libtiff5 from the GNUWin32 project: http://gnuwin32.sourceforge.net/packages/tiff.htm

    1. Launch the x64 Native Tools Command Prompt

    2. Compile:

      $ nmake /f Makefile.vc
      
    3. The programs may fail to compile, but the library should be fine. It will be in the libtiff folder.

  9. Download CImg from http://cimg.sourceforge.net/. Just uncompress it somewhere: this is only a header file, so there is no compilation necessary. Also, copy the header file of CImg in the src folder of LithoGraphX.

  10. (Optional). Download and compile ITK at: http://www.itk.org

    1. Prepare your directory structure. For simplicity, I will assume everything linked to ITK will be in the same folder. This folder will contain three sub-folder:

      ITK_Source

      Contains the source code of ITK

      ITK_Build

      Will contain the build files of ITK

      ITK

      Will contain the installed version of ITK

    2. Make sure the three directories exist, and ITK_Source contains the source code.

    3. Launch a VS2013 x64 Native Tools Command Prompt

    4. From the main directory, configure ITK:

      $ cd ITK_Build
      $ cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=ON -DModule_ITKReview=ON -DCMAKE_INSTALL_PREFIX=..\ITK ..\ITK_Source
      
    5. Then, compile and install ITK:

      $ nmake install
      
  11. (Optional). Download and compile VTK at: http://www.vtk.org

    1. Prepare your directory structure. For simplicity, I will assume everything linked to VTK will be in the same folder. This folder will contain three sub-folder:

      VTK_Source

      Contains the source code of VTK

      VTK_Build

      Will contain the build files of VTK

      VTK

      Will contain the installed version of VTK

    2. Create a build directory, for example call VTK_build

    3. Launch a VS2013 x64 Native Tools Command Prompt

    4. From the main directory, configure VTK:

      $ cd VTK_Build
      $ cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=..\VTK ..\VTK_Source
      
    5. Then, compile and install VTK:

      $ nmake install
      
  12. Create a build folder, either in or outside of the LithoGraphX folder

  13. Run cmake, and select correct the source code and build binary folders

    1. You can use either the Visual Studio 2013 Win64 or the NMake Makefiles generator.

    2. Check the Grouped check box to simplify the interface. This will put together all the options starting with the same work.

    3. Press the Configure button and check errors until there are none left. Typically you will need to inform the following variables have (in order in which they will appear):

      CUDA_CL_VERSION

      You need to set this to your version of Visual Studio, so here 2013.

      CUDA_HOST_COMPILER

      You need to put here the path to the cl program. To get this, from the command line you have opened earlier, type:

      $ where cl
      

      And copy the path writen.

      TIFF_INCLUDE_DIR

      This should be the libtiff sub-folder where you compiled libtiff in a previous step

      TIFF_LIBRARY

      This should be the file libtiff.lib in the same folder as for TIFF_INCLUDE_DIR

      Eigen_SIGNATURE

      You need to select the file signature_of_eigen3_matrix_library in the Eigen folder.

      SIP_EXECUTABLE

      If this is not found by default, this is because you didn’t install sip in the default python location. It should be in the same folder as the python you used to compile it. If this is the case, you should activate the advanced options and make sure you select the python interpreter SIP is compiled for.

      SIP_INCLUDE_PATH

      This is the include folder, wherever the sip executable is

      SIP_PYQT5_PATH

      This should be the sip\PyQt5 folder, still where the sip executable is.

      BUILD_EXTRA_INCLUDES

      If you didn’t install CImg in a standard path, chances are, you will need to add its path in this variable, for example if it is not found. This shouldn’t be a problem if you copy CImg.h in the src folder of LithoGraphX.

      CMAKE_INSTALL_PREFIX

      Choose the folder where LithoGraphX will be installed. If this is in Program Files, make sure the folder already exists and you can write in it, as normal programs cannot create a folder there.

    4. Press the Generate button

  14. If you used the NMake Makefile generator, open a x64 Native Tools Command Prompt, and compile LithoGraphX:

    $ nmake install
    

    Otherwise, open the file ALL_BUILD.vcxproj, select the Release compilation (the default is Debug), click on the INSTALL solution and compile with the Build INSTALL solution entry from the Build menu. Note: The entry will only be available if the INSTALL solution is the one currently selected on the left pane.

Configuring the Operating System

Configuring the Alt key under Linux

Most window manager are configured to use the Alt key in combination with the mouse to move or resize windows. On the other hand, LithoGraphX uses the Alt key to interact with the mesh and the stack. So to use LithoGraphX, the window manager needs to be configured to use another key, such as the Super or Meta key (i.e. the window key on your keyboard). Here is how to do it on some common window manager:

gnome3_img Gnome 3
TODO
cinnamon_img Cinnamon
In the system settings, find the Windows settings. There, change the mouse modifier key from Alt to Super.
kde_img KDE
In the system settings, open the Window behaviour settings. Then, on the Window Actions tab, change the modifier key to Meta.
XFCE_img XFCE 4
In the Settings, select Window Manager Tweaks. From there, in the Accessibility tab, change the Key used to grab and move windows from Alt to Super.

Principles and user Interface

LithoGraphX is an open source platform for the visualization and processing of 3D image data. It can visualise and manipulate 3D image stacks and triangulated curved surfaces (2½D). Surfaces can be extracted from 3D images and both can interact in various ways.

Before introducing the user interface there are a few useful definitions that come over and over in LithoGraphX.

Definitions

Stack
A stack is really a biological sample. Each stack has a unique size, location and resolution. It contains 2 images (stores) and a mesh. The two stores of a stack are the main and the work store. The main store is where the data is loaded by default. When the data is processed, the result is always put in the work store, using the main store as a checkpoint. They can also be used to load two different channels of a same image.
Store
A store is a 16 bits, single channel, 3D image. Each store has its own rendering properties (color, opacity, brightness), but they share location, resolution and size. The voxel values can be interpreter either as signal intensity or labels.
Mesh
A mesh is a triangulated surface. A mesh can be loaded from a file, or extracted from a 3D image. It is worth noting the surface doesn’t have to be continuous and can therefore represent many distinct objects.
Process——-
All non-interactive operations in LithoGraphX are performed by processes. They are grouped into three categories: Stack, Mesh and Global. Stack and processes cannot modify meshes, Mesh processes cannot modify Stack or Stores and Global processes can modify anything. Processes can be used in Python scripts or macros to automate complex pipelines. Processes are refered as Type.Name. For example, the process Stack.Save is a stack process used to save the current stack.
Active Stack
At any point in time, a single store is marked as active. The active store is the one processed by default. If a process works on meshes, the active mesh is the one associated with the active store. Before launching a process, you should always check which is the active store: it is indicated on the bottom right of the main window.

User Interface

User Interface

Figure 1: User Interface

The main window (Figure 1) of LithoGraphX is organised around a central interaction area, black when you stack the application. This is also where you want to drop files to load them in their default place.

The volume and mesh toolbars offer tools to interact with either the volume or the mesh. This tools are always activated by pressing the Alt key and clicking on the interaction area. You will find a complete description of the tools in Interaction toolbars.

Interaction area

This is the most important area of LithoGraphX. This is where your objects are displayed and where you can interact with them. The commands used for this area are available either by pressing the H key when hovering above the interaction area, or by selecting “Mouse and Keyboard” in the help menu.

Interaction box

Interaction box

Figure 2: Interaction box

The object selected in the interaction box (Figure 2) can be moved around by presing the control key and using the same mouse movement as for moving the camera.

Global toolbar

Global toolbar

Figure 3: Global toolbar

See Figure 3.

Current label
The most important function of the global toolbar is to visualize and reset the current label. The left-most button (transparent in the image above), indicate which is the current label. You can see its color on the tool and the tooltip will give you its exact number. Cliking on it will reset the label to 0 (e.g. no label selected).
swap_stack_img Swap surfaces
This tool is used when co-segmenting meshes and is described in the appropriate protocol.
snapshot_img Save screenshot
As the name suggest, this tool brings the screenshot interface to capture the interaction area in an image.
record_video_img Record video
This allows to take a screenshot every time the image changes. This can be handy to record a movie.
palette_img Color palette
This tool opens a dialog box used to change the colors used in the interaction area: background, mesh lines, text, …
label_color_img Edit labels
This tool opens a dialog box used to change the number of colors used when representing labeled stacks or meshes. It also allows to change which colors are used for which label.
anchor_img Reset view
This is a panic button when you loose your objects. It will reset the view, including the positions of the stacks, the clipping planes and the cutting surfaces you may have moved.
edit_project Edit project file
This tool opens a simple text editor from which you can edit the project file directly. This is for advanced users only!

Interaction toolbars

Interaction toolbars

Figure 4: Interaction toolbars

To use the tools of the intefaction toolbar (Figure 4), you need to press the Alt key while clicking (see Configuring the Alt key under Linux).

The volume tool bar
pipette_img Pick volume label
Set the current label to the one the user click on.
scissors_pick_img Delete volume label
Pick a label on a 3D stack and erase it (e.g. replace it with zeros). It is done using the Stack.Fill Label process, setting the new label to 0.
wand_img Pixel edit
This tool allows you to change pixels values on the work store of a stack. What the pixels are changed to is decided on the Stack Editing.
fill_label_img Fill volume label
Pick a label and replace it with the current label. This is using the process Stack.Fill Label, setting the new label to the active one.
The mesh tool bar
pipette_img Pick label
Set the current label to
mesh_select_img Mesh select
Select vertexes on the active mesh or the cutting surface. The selection is one by drawing a rectangle: every vertex within the rectangle will be selected. To use it, the points of the mesh or cutting surface must be visible. By default, at every click, the selection is replaced. To avoid this, press Shift while clicking.
mesh_label_select_img Mesh label select
Pick a label and select all the vertexes having this label.
mesh_connected_select_img Select connected area
Extend the current selection to all vertexes connected to it.
mesh_new_seed_img Add new seed
At each click on the mesh, this tool selects a new seed and label the triangle (e.g. all three vertexes) with it. The seed will be used while the mouse move until the button is released.
mesh_add_current_img Add current seed
Set the label of the triangles you click on to the current label.
mesh_grab_seed_img Grab seed
When co-segmenting surfaces, this grab the seed from the other surface and apply it to the triangles being clicked on.
fill_label_img Fill label
Replace the label clicked on by the current one.
mesh_deleted_picked_img Delete picked label
Delete all vertexes having the label clicked. The deletion only happen when the mouse button is released, giving the opportunity to select more than one label by moving the mouse, keeping the left button pressed.
mesh_erase_selection_img Erase selection
Erase the label of all the selected vertexes.
mesh_fill_selection_img Fill selection
Set the label of all selected vertexes to the current one.
mesh_delete_selection_img Delete selection
Delete selected vertexes

Tab Area

Main tab
Main tab

Figure 5: Main tab

The main tab (see Figure 5) controls what is displayed and how.

The stack tab select the current stack: you can check this looking at the bottom right corner of the window.

The main and work store areas are identical:

  • the main check box controls their visibility
  • the Transfer-function icon button is used to control the transfer function
  • the 16 bits check box controls whether the image is displayed using the full 16 bits or only 8 bits. If rendering is too slow, you can try to un-check it.
  • the labels check box indicate whether the image is interpreter as signal intensity or labels.
  • the opacity and brightness sliders are rather self-explanatory

The display of the mesh is part in two: the surface and the mesh itself.

The surface area controls the surface representation of the mesh:

  • the top Transfer-function icon button controls the transfer function for the mesh’s signal
  • the bottom Transfer-function icon button controls the transfer function for the heat
  • the view combo box controls what is displayed on the surface: signal, label, heat or parent label.
  • the bottom three radio buttons control whether the surface displays its own information (Surface), the texture attached to it (tex) or the part of the 3D image intersecting the surface (Img).

The mesh area control the display of the wireframe representation of the mesh:

  • The view combo box allows to select what part of the mesh is visible. Options are: selected, all, cells and border. Cells show the border of cells and border the border of the mesh (in case it is an open surface).
  • It is possible to display the lines or the points of the mesh. Note that to select the mesh, it is necessary to display its points.
  • The Map check box show the labels of each cells as text above the image itself.
  • At last the Information icon button gives information about the whole stack and mesh: size, resolution, number of vertices, range of the signal, what has been computed, …

The scaling and position area controls global properties of the stack:

  • The stack has two position matrices: normal and transformed. The Transform check box control which one is displayed / modified. Processes should always change the transformed position.
  • The BBox check box control whether the bounding box of the image is displayed.
  • The Scale check box control whether the display size of the stack and mesh is the original one, or the one scaled by the sliders.
  • The three sliders control the scaling of the whole stack (including the mesh) along the local X, Y and Z axis. If the tied check box is ticked, the three sliders are forced to the same value.
View tab
View tab

Figure 6: View tab

The view tab (see Figure 6) is split in 3 sections: image quality, stack editing and clipping planes.

Image Quality

The view tab is split into 4 boxes. The image quality box controls global rendering properties. Beside the common brightness and contrast, you can set the number of slices used to render 3D images: the more slices, the better the rendering, but also the slower. To get a feel for what it does, do not hesitate to descrease it to the minimum (on the left). The last parameter is the sampling. When the view moves, instead of rendering the full view, LithoGraphX degrades the image by rendering only a fraction of the pixels. This allows for a precise rendering when the image is still while keeping a fluid movement. If you change this slider, check the result by moving the view.

Note

Most sliders can be reset to their default position by double-clicking on them!

Stack Editing

The second box is the stack editing box. First, you will notice it is grayes: it will become available when the current store is the work store of a stack (otherwise, you cannot use the Pixel Edit tool anyway). The main control here is the slider, which decides how large the editing pencil is. The size is in screen coordinate, so how much of the object you are editing will also depend on the level of zoom. The default behavior of the pixel edit tool is to erase voxels (e.g. set them to 0). You can choose instead to fill the voxels with other values. Depending on the store (e.g. whether it contains labels or intensity), you will be able to set the value used to fill the stack, or choose to create a new seed at every click.

Clipping Planes

LithoGraphX provides 3 pairs of clipping planes. Each pair are maintained parallel to allow for easy slicing of the objects. To use the clipping planes, first show the grid, checking the grid check box. Select the clipping plane in the Interaction box and move it wherever you need before checking the Enabled box. It is usually easier to move it in place before enabling it.

Process tab
Process tab

Figure 7: Process tab

LithoGraphX has three kinds of Processes: Stack, Mesh and Global. The three first tabs each list one of the categories.

Within these tabs (see Figure 7), processes are organised in folders, which can be open and closed by clicking on the triangle on their left. When a process is selected, its parameters appear in the bottom part of the tab. Be aware that some processes will also provide a dialog box to help you with the parameters. Although the parameters written there will always be taken into account.

The last tab contains tasks. Tasks are ordered collections of processes, usually organized to make protocols easier to follow. Tasks can group processes of all types. They can be saved and loaded from files.

Tips for Data Collection

Data collection for use in 3D image processing softwares can be a little different than for other uses. In most cases, people optimize data collection so that individual slices look good to the human eye. This is not always the best for 3D data analysis and visualization. The following are some tips to help get the most out of the images:

  • 16 bits images. If possible collect 16 bits per channel, instead of 8 bits. Although the pictures may look no different, the 16 bits images will have higher dynamic range, and it will be easier to extract features in darker areas of the image. If the microscope only supports 12 bits, that will still be better than 8 bits.
  • More slices, less averaging. A common technique used to improve the image quality on confocal microscope is frame or line averaging. In this mode, the microscope takes each line/frame many times (typicalle 2 or 4 times), and creates an image by averaging each pass. Although this improves the image quality, it also increase the acquisition time, leading to problems such as: bleaching, tissue damage, movement during acquisition, … and to avoid these, a common technique is to reduce the number of slices taken. When acquiring data for 3D image processing software such as LithoGraphX, it is recommended to favour increasing the number of slices rather than averaging. The noise will be reduced later using neighboring slices.
  • Dynamic range. When acquiring images, it is best to maximize their dynamic range: that is the difference between the brightness and the darkest pixel. To help you optimize this, most microscope’s software have a mode in which the saturated and black pixels are marked. When in that mode, first set the offset down until you see a lot of black pixels, and then increase it slowly to reduce their number until only a few are left. Then, increase the gain until many pixels are saturated, and decrease it slowly until only a few pixes are saturated. If you are interested in the geometry of cells, it is a good idea to saturate the cell walls slightly more: that will avoid issues with drops in signal and the exact shape will still be found at the middle of the saturated areas.
  • Start and end slices shouldn’t contain any sign of your sample. It is tempting to start the acquisition when the sample is just visible, and stop just before it disappear. This is a bad idea: the reconstruction algorithms need the extra information that “there is no more tissue here” (or at least, not of interest) to reconstruct their geometry properly. So make sure you start a few micron before your sample, and stop a few micros after.
  • Use Fiji to get TIFF files. Most microscope formats are proprietary. The Loci Bioformat group has reverse engineered the formats of the most popular microscopes and made plugins for ImageJ. We recommend Fiji, which is a distribution of ImageJ that contains these, along with many other useful plugins. Even if your microscope generates TIFF images, you might want to open them with the Bioformat plugins to extract the thickness of the slices. LithoGraphX only recognise ImageJ generated TIFF and OME TIFF for this.
  • If voxel sizes are wrong. The TIFF format has no standard way to specify the voxel size in Z. ImageJ defines its own attributes for this, and the OME tif format another one. LithoGraphX recognises both formats. But some manufacturers provide their own TIFF file, with a different specification of the slice thickness. In this case, LithoGraphX will be unable to read it. You will need to use the Stack process Change Voxel Size in the Canvas folder and specify the z resolution.

Tutorials

You will find here a series of tutorial to accomplish various tasks. Each tutorial is given with a sample dataset and a LithoGraphX task to get you started.

The datasets used in these tutorials can be found there: http://www.lithographx.com/data-gallery

Loading and visualizing data

16-cell embryo of Arabidopsis thaliana

Figure 8: 16-cells embryo of Arabidopsis thaliana. Image: Saiko Yoshida, Weijer’s lab.

For this tutorial, download this dataset, which we used while working on [Yoshida2014].

Loading the data

There are four ways to load data in LithoGraphX.

  1. The simplest is to open the data directly with LithoGraphX. If you installed it correctly, data files native to LithoGraphX are associated with it. If you right-click on such a file you should have en entry to open it with LithoGraphX. Once launched, the data is simply loaded in the Stack 1, on the Main store for stacks.
  2. Once LithoGraphX is open, to load more data or replace existing data, the next simplest way is to use drag&drop. If you drop the file on the interaction area, it will be loaded in the currently active stack. For 3D images, you can also drop them on the main and store boxes in the main tab to load it at a particular location.
  3. You can use the menu to load either a LithoGraphX project, a stack or a mesh file. There are different menus for the various targets.
  4. You can directly use the loading processes: they are in the System folders of the Stack, Mesh and Global process tabs.

Try the various means to load the files 160112_4.tif, 160112_4.mgxm and at last the project file 160112_4.lgxp.

Tuning the visualization

For this part, load only the TIFF file 160112_4.tif.

Opacity and basic transfer function
original image just loaded

Figure 9: Initial view of the dataset.

When loading this dataset, you will see a very opaque object filling in almost the whole image. This is an embryo of Arabidopsis thaliana within its ovule, and we need to change the visual properties to start to see it.

But first, click the Transfer-function icon button to see the transfer function (see Figure 10).

transfer function of the dark object

Figure 10: Transfer function of the object: note how only the low values are used.

We can see that the signal is entirely on the left of the spectrum! This is because the image is a 12 bits image. The number on the top-left indicate the value under the mouse cursor: a 12 bits image has a maximum possible value of 4095, while a 16 bits image can have values up to 65535. For further processing, we will want to expand the range of values. This will allow us to work with the representation with more ease, and will ensure fewer variations in the parameters of the data processing.

Process [Stack]Filters/Autoscale Stack

The process Stack.Autoscale Stack in the Filters folder, will do just that: rescale the stack to use the whole range of possible values. This process has no parameter and will simply modify the current store. You will notice a change in colour from green to cyan: this is because the result has been saved in the work store of the stack 1, and this store is by default cyan. We can look now at the transfer function of the work store (see Figure 11).

Scaled transfer function

Figure 11: Scaled transfer function.

Now, we can see the stack uses the whole spectrum of values, which will be important later.

But to see the embryo, you need to decrease the opacity of the store (see Figure 12).

Embryo

Figure 12: We need to adjust the opacity to reveal the embryo.

Surface and Mesh

Now, load the mesh, check the Blend check box and adjust the opacity.

Embryo mesh

Figure 13: Mesh covering the cells in the Embryo.

To look at the signal, we need first to create some. For example, compute the Gaussian curvature on each point:

Process [Stack]Signal/Project Mesh Curvature
Parameter Value
Type Gaussian
Neighborhood (μm) 2
Autoscale Yes

Then, click on the upper Transfer-function icon button to change the transfer function of the signal (this is the second such button in the surface box). In the dialogue box, select the “French flag” transfer function (see Figure 14).

Embryo curvature

Figure 14: Curvature of the mesh.

Another property of the mesh is the heat. While the signal is per point, the heat is per label. THe main way to create a heat map is to use the process:

Process [Mesh]Heat Map/Heat Map

When you launch the process, a fairly large dialogue box appear. Other tutorials will explain in more details what it is for. For now, simply change the heat map type fo “Volume” and make sure the visualization is “Geometry” (see Figure 15).

Heat map dialogue box

Figure 15: Dialog box of the Heatmap process.

After validation, the surface visualization automatically changed to “Heat” and displays the result (see Figure 16).

Heat map result

Figure 16: Head map of the cell volumes.

To change the transfer function, you can use the lower Transfer-function icon button.

Changing the colours

The main colours can be changed using the palette-button button (see Figure 17).

Colors Editor

Figure 17: Colors Editor

For example, to re-create the image at the top of this page, change the background to white, and the legend and scale bar to black by double-clicking on the colour and use the dialogue box to choose the colour. To use if fully, you might also want to change the editing pixels and clipping planes colour to something darker.

Rendering speed

If rendering is slow, there are a number of settings in the View tab that can be helpful in the view quality box:

  • Slices: changes the number of slices used to render the volume. The more the slower but also the better the quality. You can try to push it fully on the left to see how artefacts look like.
  • Screen sampling: to speed up rendering while keeping a good image quality, LithoGraphX can reduce the image quality only when moving. This parameters sets the sub-sampling done while moving.
Transfer function

TODO

Inside the object
Clipping Planes
Cutting Surface
Processes
[Yoshida2014]Yoshida, S., Barbier de Reuille, P., Lane, B., Bassel, G. W., Prusinkiewicz, P., Smith, R. S. and Weijers, D. Genetic Control of Plant Development by Overriding a Geometric Division Rule Developmental Cell, 2014, 29, 75-87

Data Visualization (2)

Shoot apical meristem of A. thaliana

Figure 18: Shoot apical meristem of A. thaliana, cell walls stained with PI and with DR5::YFP fluorescent marker. Image: Agata Burian

Introduction

The purpose of this exercise is to introduce the interface of LithoGraphX, learn to segment cells in 3D and work with the heat map.

Note that you will find a lot of useful information in the Help menu, including a user manual, a documentation of all the existing processes, and the mouse and keyboard interactions.

LithoGraphX has a fixed number of objects that exist at any given time. They are organized in two Stacks, each stack containing two images and a mesh. The stack defines the size, resolution and position of the images it contains. The two images are called the Main and Work store: the main store is where the data is loaded by default, while the work store is where the result of any processing will be put. Only one store can be active at any given time. Which is active depends on the visibility of the stores and which stack tab is currently active. It is however, indicated on the right of the status bar, at the bottom of the main window.

Hint

In the beginning, always check which store is active before launching processes.

Each stack also contains a triangular mesh. To each vertex of the mesh is attached a signal and a label. The label however, is interpreter by triangle: if at least two vertices of a triangle have the same label, the whole triangle is given this label. In case of tie, the triangle is considered un-labelled. At last, to each label a heat may be associated. A mesh can be seen either as a continuous surface, displaying the signal, label or label’s heat, or as a wireframe mesh, or both at the same time.

In LithoGraphX, loading, saving, processing, analysing is done through Processes (in fact, most menu items are simply shortcuts to processes). There are three kind of processes: Stack, Mesh and Global. Stack processes can only modify the stacks and stores, the Mesh processes can only modify the meshes and Global processes can modify anything.

Loading a stack

Once LithoGraphX is started, the simplest way to open a new image stack is to drag&drop the file (tif) onto the drawing area. You can also use the Stack menu to open a file to a particular store.

Loading a second channel

To load a second channel, you can either use the menus, or again drag&drop a file. However, instead of dropping onto the drawing area, you can drop the file onto the Work store area (see Main tab).

Clipping planes

Clipping planes

You should now have a nice image the SAM, But you cannot easily see inside! To help with this, LithoGraphX has few tools. The first one is three pairs of clipping planes (see Figure~ref{fig:clipping}). To work with the clipping planes, they must be enabled in the View tab. Each pair of clipping plane has its own tab, from which the user can enable it, show a grid to see its position when not enabled, and set the distance between the two planes. To move the planes, it must be selected in the main tab in the Control-Key Interaction box. As the name suggest, the clipping planes are then moved by pressing the Control key and use the mouse in the same way as for moving the camera.

Try using the clipping planes to see where the DR5::YFP signal is with respect to the cell layers.

Cutting Surfaces

Cutting surfaces

Another way to see the insides of a volume is to use cutting surfaces. Like the clipping planes, the cutting surface need to be enabled in the View tab, at the bottom. The cutting surface can take one of three forms: a single plane, three orthogonal planes, or a Bézier surface. When enabled, the part of the visible volumes that intersect the chosen surface will be drawn, ignoring their brightness and opacity settings. Instead, the brightness and opacity of the surface is usedfootnote{To see a volume only on the cutting surface, push its opacity slider all the way to the left, making it completely transparent.}.

As for the clipping plane, you can move the cutting surface is it is selected in the Control-key interaction box.

At last, for the Bézier surface, if you show the grid and make sure points are shown, you can select and move them using the mesh selection tool.

Segmenting Cells in 3D

Shoot apical meristem of A. thaliana, segmented in 3D

Figure 21: Shoot apical meristem of A. thaliana, segmented in 3D

In this section, we are going to see how we can extract the 3D shape of cells in images of the shoot apical meristem of Arabidopsis thaliana, and see how we can use an extra channel with the segmentation. To start, download this dataset, provided by Dr. Agata Burian.

Loading the data

For this tutorial, you can start either by loading the file Arabido_DR5-YFP_pi.tif or Arabido_DR5-YFP_pi_cleaned.tif.

Cleaning the data

If you have loaded Arabido_DR5-YFP_pi.tif, you will see in addition to the shoot apical meristem a few lateral organs, including those partially removed to acquire the image. To extract only what we want to see, we need to clean the image.

  1. Copy the stack to the work store. At the same time, we will autoscale the stack’s intensity. This is an important step as it makes to rest of the process much easier.

    Process [Stack]Filters/Autoscale Stack
  2. Select the pixel edit tool. In the View tab make sure Fill checkbox in the Stack Editing area is not checked. Then, pressing the Alt key, you should see a circle above the drawing area. This circle marks the cylinder that will get erased. Click to erase.

  3. When you are happy with your cleaning, save the stack!

Note

If the area to erase is too large, nothing will change until you release the mouse button.

Hint

You can also do the cleaning on the segmented stack. In this case, another useful tool is the fill volume tool. Ensure no label is currently selected by clicking on the current label button. Then click on the labels you want to erase.

3D Cells Segmentation

  1. Make sure the stack is in the Main store.

  2. Blur the stack

    Process [Stack]Filters/Gaussian Blur Stack
    Parameter Value
    X Sigma (μm) 0.3
    Y Sigma (μm) 0.3
    Z Sigma (μm) 0.3
  3. Optionnally, use the Sieve filter. It can be quite slow, but it really improves the segmentation.

    Process [Stack]Morphology/SieveFilter
    Parameter Value
    Type Median
    Size (μm²/μm³) 4
  4. Segment the stack:

    Process [Stack]ITK/Segmentation/ITK Watershed Auto Seeded
    Parameter Value
    Level 1500
  5. Remove external cells:

    Process [Stack]Segmentation/Erase at Border
    Parameter Value
    Distance (μm) 0
    X Yes
    Y Yes
    Z Yes
  6. Extract the cell shapes:

    Process [Mesh]Creation/Marching Cubes 3D
    Parameter Value
    Cube Size (μm) 1
    Smooth Passes 3

Hint

Use the clipping planes to scan through the volume and make sure the segmentation worked correctly in the depth of the tissue.

3D Signal Quantification

Signal quantification on 3D mesh

Figure 22: Signal quantification on 3D mesh

  1. Load the YFP channel in the work store of the stack 1. To do that, the simplest is to drag&drop the file onto the work store area.

  2. Launch the Heat map mesh process:

    Process [Mesh]Heat Map/Heat Map
  3. In the dialog box, select the Volume heat map type and the Total signal visualization and make sure Signal average is not ticked.

The result is, per cell, the total amount of signal present in the YFP channel.

Note

This is not sufficient for a proper signal quantification. This is only qualitative. For a proper quantification of the signal you need a reference channel.

Segmenting Cells in 3D (advanced)

For this first tutorial, we are going to look step by step into the 3D segmentation of the cells of the embryo of Arabidopsis.

First, download the dataset from BitBucket here: dataset.

Loading the dataset

  1. Launch LithoGraphX
  2. Drag & drop the file 160112_4.tif into the interaction area of LithoGraphX
  3. Adjust the opacity as we have seen in the previous tutorial.

You should see the embryo like in Figure 23.

Loaded stack with embryo

Figure 23: Loaded stack with the embryo

Extracting the embryo

As you can see, in addition to the embryo, we have a lot of extra tissues. There are a number of tools we can use to remove most of it. We will first use the clipping planes and then the pixel editing tool.

Trimming with clipping planes
Placing the clipping plane

Figure 24: Place the clipping planes to include just the embryo itself.

  1. Go to the View tab

  2. Show the grid of the first clipping plane.

  3. Make sure Clip 1 is selected in the Interaction box.

  4. Ajusting the thickness of the slice, and moving the clipping plane with the control-key pressed, place the clipping planes to include the embryo (see Figure 24)

  5. Enable the clipping planes

  6. Clip the image itself:

    Process [Stack]Mesh Interaction/Clip Stack
  7. Adjust the transfer function of the work stack: click on the Transfer-function icon button of the work store and click on the auto-adjust button. At last, adjust the opacity.

  8. Disable the Clip 1 from the View tab.

Using the Pixel Editing tool
Cleaned stack

Figure 25: Cleaned stack

  1. Select the pixel editing tool

  2. Ensure the active stack is the Work Stack 1

  3. In the View tab, make sure the Fill check-box in the Stack Editing box is not checked.

  4. Remove pixels by pressing the Alt key and clicking. All visible pixels within the drawn circle will be erased! After a few minutes of erasing, you should get something like Figure 25.

  5. When you are done, copy the result to the main store.

    Process [Stack]Multi-stack/Copy Main to Work Stack
Troubleshooting
  • When using the pixel edit, depending on the view angle (e.g. the number of voxels that would need editing), the edition may be done only when you release the mouse button.

  • If you make a mistake, there is no undo! Unless you copy the stack back to the main store, where you will be able to access it again.

    Process [Stack]Multi-stack/Copy Main to Work Stack
  • Don’t panick if you find it hard to move around. This is normal at the beginning, but you will get used to it. A commonly forgotten useful shortcut allows to turn the object in the plane of view with Left+Middle mouse click (look at the Mouse and Keyboard help).

Segmentation

Now we have a nice, isolated image. We are ready for the segmentation part.

  1. To make it easier and more reproducable, we need to scale the values to use the whole range. Run the process Stack.Autoscale Stack from the Filters folder. If you changed the transfer function, you might need to re-adjust it.

  2. The image is too noisy to be segmented as is. You need to blur the image:

    Process [Stack]Filters/Gaussian Blur Stack
    Parameter Value
    X Sigma (μm) 0.3
    Y Sigma (μm) 0.3
    Z Sigma (μm) 0.3
  3. We will now segment the stack. The Level parameter is the most important one: it tells the algorithm the level of background noise to consider. Remember the values range from 0 to 65535, so 1500 is quite small. But if you didn’t autoscale the stack before, it may become very large compare to the actual maximum intensity!

    Process [Stack]ITK/Segmentation/ITK Watershed Auto Seeded
    Parameter Value
    Level 1500
  4. Use the Fill picked label tool fill_label_img to erase the outside cell: make sure no label is selected, and Alt-click on the outside cell to delete it. There might be some other small cells to erase.

At that stage, the segmentation is mostly good, but some cells are too large. We could of course edit by hand the initial stack to improve, but we are going to use another means, more in line with what LithoGraphX is good with: interaction between mesh and stack.

Segmenting cells in 2D

Shoot apical meristem of A. thaliana, with microtubules

Figure 26: Shoot apical meristem of A. thaliana, with microtubules

In this section, we are going to see how we can extract the 2D shape of cells in images of the shoot apical meristem of Arabidopsis thaliana, and see how we can use a marker of cortical microtubule to compute their orientation based on the method published in [Boudaoud2014]. To start, download this dataset, provided by Dr. Agata Burian.

To segment the cells in 2D, we need to proceed in two phases:

  1. Extract the surface of the meristem
  2. Segment the cells on that surface

Extracting the surface of the meristem

See figure 27 A-D.

  1. Blur the stack slightly:

    Process [Stack]Filters/Gaussian Blur Stack
    Parameter Value
    X Sigma (μm) 0.5
    Y Sigma (μm) 0.5
    Z Sigma (μm) 0.5
  2. Extract the surface, using all the default arguments:

    Process [Stack]Morphology/Edge Detect
  3. Erase the bumps due to dead cells by hand, using the Pixel Edit tool

  4. Extract a coarse surface:

    Process [Mesh]Creation/Marching Cubes Surface
    Parameter Value
    Cube size (μm) 3
  5. Select the bottom and sides with the selection tool: make sure the Mesh check-box is ticked and View is on Selected. Then, orienting properly the meristem, press the Alt key and click and drag a rectangle to select the vertices to remove. You can extend the selection by pressing the Shift key while clicking. For a demonstration of what needs to be done, look at this video.

  6. We now need to refine the surface. For this, we will alternate smoothing and refining the mesh. Check the terminal for the number of vertices after subdivision. You really should ends with around 250‘000 vertices.

    Process [Mesh]Structure/Smooth Mesh
    Parameter Value
    Passes 3
    Process [Mesh]Structure/Subdivide

Youtube video: http://www.youtube.com/watch?v=ZbTaYITkObg

2D segmentation of the meristem

Figure 27: 2D Segmentation of the meristem

Segment the cells

See figure 27 E-F.

  1. First, make sure the PI channel, which should be the Main Stack 1 is the active stack. In the Main tab, the Stack 1 tab should be the selected tab, the Main store should be selected and the Work store not.

  2. Then, project the signal onto the surface. You can play with the mim and max distances to see what happens when they change.

    Process [Mesh]Signal/Project Signal
    Parameter Value
    Min Dist (μm) 1
    Max Dist (μm) 4
  3. Now, we are going to segment the cells visible in the signal.

    Process [Mesh]Segmentation/Auto-Segmentation
    Parameter Value
    Update Yes
    Normalize No
    Blur Cell Radius (μm) 1
    Auto-Seed Radius (μm) 2
    Border Distance (μm) 1
    Combine Threshold 1
  4. After a while, you will see outline of segmented cells. In the Main tab, select Labels as representation for the surface. And using the 2D bucket, erase the cells above the areas where the staining didn’t work.

Micro-tubule orientations

Extracting the orientation of the microtubules

Figure 28: Extraction of the microtubules orientation.

  1. Load the MBD stack: just drag and drop the file on the LithoGraphX window.

  2. Project the new signal onto the surface. Select a range from -1 µm to 1 µm. You can try different values and see which provide the best contrast.

  3. Compute the fibril orientations:

    Process [Mesh]Cell Axis/Fibril Orientation/Compute Fibril Orientations
  4. You can also adjust the way the orientation is displayed:

    Process [Mesh]Cell Axis/Fibril Orientation/Display Fibril Orientation
[Boudaoud2014]Boudaoud, A.; Burian, A.; Borowska-Wykręt, D.; Uyttewaal, M.; Wrzalik, R.; Kwiatkowska, D. and Hamant, O. FibrilTool, an ImageJ plug-in to quantify fibrillar structures in raw microscopy images. Nature Protocols, 2014, 9, 457-463

Segmenting cells from a 2D image and automated cell classification

Cross-section of a hypocotyl of A. thaliana at 14 days

Figure 29: Cross-section of a hypocotyl of A. thaliana at 14 days

In this section, we are going to see how we can extract the 2D shape of cells from a 2D image of the cross-section of a hypocotyl of Arabidopsis thaliana, and see how we can train a cell classifier to automatically label cell types. This tutorial is based on [BarbierDeReuille.Ragni.InPress]. To start, download this dataset, provided by Dr. Laura Ragni.

Pre-processing

Although the image is of very good quality, the cells contain a lot of small “objects” that may cause problem when segmenting. In this sense, an object is a contiguous group of pixels whose intensities are all strictly greater and strictly smaller than their neighbors. For the pre-processing, we will remove them:

  1. Load the image Col_14d_63x_bl1_4sti_s1.ome.tiff

  2. Change the transfer function to Scale Gray and auto-adjust its range.

  3. Re-scale the stack’s intensities to maximize its dynamic range:

    Process [Stack]Filters/Apply Transfer Function
  4. Filter the stack using two gaussian blurs with a very small radius (about the half voxel size):

    Process [Stack]Filters/Gaussian blur
    Parameter Value
    X Sigma (μm) 0.1
    Y Sigma (μm) 0.1
    Z Sigma (μm) 0
  5. Remove all the small objects from the image. This process will remove any object (see above for the definition) whose area (for a 2D image) or volume (for a 3D image) is smaller than some threshold. Note that the shape of the object is irrelevant. As the smaller cells are about 3-4 μm², set the size to 2 μm²:

    Process [Stack]Morphology/Sieve Filter
    Parameter Value
    Size (μm²) 2
  6. Save this stack as it might be useful later.

Segmentation of the vascular tissues

Segmentation of the vascular tissues

Figure 30: Segmentation of the vascular tissues

  1. Use the Segment Section process in the Segmentation folder. This process will blur the cells slightly and use the auto-seeded watershed for the segmentation itself. The auto-seeded watershed requires the cell walls to be bright and the background to be dark, which is the opposite of our images here. The last option of the process is to invert the image before segmentation. Otherwise, use the default options.

    Process [Stack]Segmentation/Segment Section
    Parameter Value
    BlurX 0.3
    BlurY 0.3
    Invert Yes
  2. We now need to remove all the segmented parts outside our region of interest. In the image, the vascular tissue is contained in a disc of radius 80 μm:

    Process [Stack]Segmentation/Remove Labels in Shape
    Parameter Value
    Shape Sphere
    Center 0 0 0
    Size 80
  3. Create a cell mesh from the segmentation with a fairly fine description of the cell:

    Process [Mesh]Cell Mesh/Cell Mesh from 2D Image
    Parameter Value
    Edge Length (μm) 1
  4. To inspect the segmentation, it is simpler to show the outline of the cells. For this, in the main tab, un-check the Surface check box and check the Mesh check box. For the mesh, select to view the cells (in the view combo box) and hide the points.

Correcting the segmentation

With the cell outline visible, you can check the correspondance between the segmentation and the image. Segmentation errors can be broadly classified in three categories:

  1. Over-segmentation is when a single biological cell has been identified as many cells by the segmentation..
  2. Under-segmentation is when some biological cells have been identified as a single cell by the segmentation.
  3. Mis-segmentation is any error that doesn’t fall into either previous category.
Over-segmentation
Example of over-segmented cell.

Figure 31: Example of over-segmented cell.

Over-segmentations are the easiest error to correct.

  1. Show the segmented stack (which should be in the work stack)
  2. Using the 3D pipette, select the label of part of the cell
  3. Using the 3D bucket, replace all the other labels in the biological cell by the one selected.
  4. Re-create the cell mesh
Under-segmentation
Example of under-segmented cell.

Figure 32: Example of under-segmented cell.

Under segmentation is a bit more difficult as it requires local re-segmentation.

  1. Erase the under-segmented cell.

  2. Select the magic want and, in the view tab, in the Stack Editing section, select Fill and New Seed.

  3. Place seeds at the center of each biological cells.

  4. In the menu Labels & Selection, select New Seed

  5. Using the 3D bucket, flood-fill the outside of the tissue. To flood fill an area, you need to press Shift and Alt while clicking with the left button of the mouse.

  6. Swap the main and work stack:

    Process [Stack]Multi-stack/Swap Main and Work Stacks
  7. Invert the main stack:

    Process [Stack]Filters/Invert
  8. Swap the stacks back in place

  9. Re-segment the image:

    Process [Stack]ITK/Segmentation/ITK Watershed
  10. Delete the outside cell with the 3D bucket tool.

  11. Re-create the cell mesh

  12. Optionally you can re-invert the image by repeating steps 6 to 8.

Mis-segmentation

Correcting mis-segmentation is very similar to correcting under-segmentation. The only difference is that all mis-segmented cells should be deleted. Also, mis-segmentation is often due to issues with wall staining. If this is the case, place the seeds close to the cell wall to prevent the re-segmentation from “bleeding”“.

Automated cell classification

An automated classifier will try to identify cells from a set of adapted features. LithoGraphX offer a process computing a whole series of features adapted to cells segmented from 2D images. As often, cells will be identified by a numeric identifier, which you need to choose for each cell type. In this protocol, here are the identifiers we chose:

Cell types identifier
Cell Type Identifier
Xylem vessel 3
Phloem bundles 4
Cambium 5
Xylem parenchyma 6
Phloem parenchyma 7

Creating the classifier is done in three steps:

  1. Label some cells by hand
  2. Compute the features
  3. Train the classifier

It will be important that all files linked to a given image share a common prefix.

Labelling of the cells
Example of input labelled cells.

Figure 33: Example labelled cells.

Cells are labelled using the “parents” feature. Except that, instead of giving to a cell the id of its parent, we are going to give it its cell type identifier.

  1. Show the surface, selecting the Parents
  2. To see more easily, check the Blend check box and decrease the opacity by moving the slider.
  3. In the menu Labels & Selection select Change current label and enter one cell type identifier.
  4. Using the 2D bucket, Alt-Left click on some of the cells of that identify
  5. Save the mesh file.
  6. Repeats steps 3 and 4 for each cell type, marking each time some of the cells and trying to mark as many of all the cell types.
Features computation
Dialog box to compute cells features.

Figure 34: Dialog box to compute cells features.

The orange background indicates the feature file exists already and will be over-written.
  1. Start the process creating the classifier features:

    Process [Global]Cell Classifier/Generate Classifier Features
  2. If you have been editing all your files in the same folder, the base folder should be correct, otherwise, select the folder containing all your datasets. If you created separate folders for different datasets, check the recursive check box.

  3. You may want to update the Main file pattern to reflect your convention. The base name is contained within the curly bracket and used as prefix for the other files. As you can see in the example, the mesh here also has a suffix.

  4. Inspect the file list to make sure all the files will be properly processed as you want. Then press the OK button to start the process.

Training the classifier
Creation of the cell classifier.

Figure 35: Creation of the cell classifier.

After having computed the features on all your samples you can train the classifier.

  1. Start the process creating the classifier itself:

    Process [Global]Cell Classifier/Generate Cell Classifier
  2. The input area works like the previous dialog box. You will notice the process allows you to use only a range of cell types. This can be useful if you are not sure about detecting some cell types.

  3. We currently offer two algorithms: Support Vector Machine (SVM) and Random Forest. Previous tests showed that SVM work better for this particular problem, but you can select more than one algorithm.

  4. After running the algorithm, you should examine the summary generated. You should in particular look at the confusions matrix and report at the top the file:

Machine Learning Summary
========================
Selected classifier:  Support Vector Machine

Testing using set with 9 elements
---------------------------------

Confusion matrix:
Predicted  3  4  5  6  7  Sum
Real                         
3          2  0  0  0  0    2
4          0  1  0  0  1    2
5          0  0  0  0  0    0
6          0  0  1  0  0    1
7          0  0  0  0  4    4
Sum        2  1  1  0  5    9

Classification report:
             precision    recall  f1-score   support

          3       1.00      1.00      1.00         2
          4       1.00      0.50      0.67         2
          5       0.00      0.00      0.00         0
          6       0.00      0.00      0.00         1
          7       0.80      1.00      0.89         4

avg / total       0.80      0.78      0.77         9


Score:  77.7777777778 %

Algorithms Details
==================

Support Vector Machine
----------------------

Best score with k-fold: 0.858823529412
Parameters:
class_weight : balanced
C : 31.04345899553238
gamma : 0.0514347955741465
Using the classifier
Using of the cell classifier.

Figure 36: Using of the cell classifier.

After creation, we want to use the cell classifier:

  1. Start the process to use the classifier:

    Process [Global]Cell Classifier/Use Cell Classifier
  2. Choose the name of the classifier file you generated in the previous step

  3. Fill in the input and output part as usual

  4. In the output, the default is to write a CSV file containing two columns: the cell labels and the estimated cell type. You can optionally generate a file containing all the features and add a column with the estimated cell type. This file can conveniently be used for further filtering/analyses using R, Python, …

  5. You can visualize the result by loading a mesh and changing the parents, using the files generated in the previous step (e.g. by default the ones ending up with -celltypes.csv)

    Process [Mesh]Lineage Tracking/Load Parents
Result of the cell classifier.

Figure 37: Result of the cell classifier.

[BarbierDeReuille.Ragni.InPress]Barbier de Reuille P, Ragni L. in press. Vascular morphodynamics during secondary growth. In: de Lucas M, Etchells JP, eds. Xylem: methods and protocols Springer.

Computing a growth map

TODO

Python Macros and Scripts

LithoGraphX can be scripted in python in two ways: scripts and macros.

In both cases, you can call any process with the syntax:

Type.Name(parameter1, parameter2, ...)

For example, to call the Average stack process, with a radius of 1 and 3 steps, you will type:

Stack.Average(1, 1, 1, 3)

The parameters are in the order in which they are presented, top to bottom. To make things easier, every time you run a process, the exact Python call is written in the file LithoGraphX.py in the current folder. The current folder is the one of the file marked in the title bar of the application.

In case of an error, three exceptions may be launched:

UserCancelException

If the user canceled the process, this exception will be thrown.

ProcessError

If an error occurs while the process runs, this exception is raised, and the attached string has the error message in it.

NoSuchProcess

Exception thrown if the process doesn’t exist.

Python Scripts

Python script are the simpler ones to make. Just write a script that will be executed using the Global process Execute Python in the Python folder.

Python Macros

Macros are more like processes. They are python modules, placed in the user or system macro folder. They appear at the same place as any other process. Also, while in scripts, the names Stack, Mesh and Global are always defined, in macros they need to be imported from the lgxPy module.

To be a valid macro, the module need to define a function run:

def run(p1=default1, p2=default2, p3=default3, ...):
    ...

Remember that the parameter received are always strings, even if defaults are specified otherwise.

The number, name and default values of the parameters will be automatically extracted and presented in the user interface of LithoGraphX.

You can also define an initialize function, which need to take the same number of parameters as the run function, plus one. The extra parameter, placed at the end of the list, is the parent window, used to create dialog boxes. The function needs to return the list of parameters to pass to the run function:

def initialize(p1, p2, p3, ..., parent):
    ...
    return (p1, p2, p3, ...)

At last, we noticed that the initialize and run typically have to perform the same argument parsing. To help with that, you can define a function that will be called automatically before either run or initialize to parse the arguments:

def parseParms(p1, p2, p3, ...):
    return (p1, p2, p3, ...)

The number of returned argument must be the same as the number of parameter, but they will typically be of the correct type.

Other variables that the module can defines are:

processName

Name of the process, instead of the name of the module. If not specified, the default is the name of the module (e.g. the name of the file without the .py).

processType

Must be one of Stack, Mesh or Global. If not Global, only processes of the same type can be called. If not specify, the default is Global.

processFolder

Folder in which the process will be seen. If not specified, the default is Python.

parmsDescs

Dictionnary giving, for each named parameter, a description. It will appear in the online parameter help.

parmsChoice

Dictionnary giving, for each named parameter, a list of choices to display as drop-down list.

processIcon

String with the path to the icon of the process. The path can be relative to the module path.

Module lgxPy

This module defines how to interact with LithoGraphX itself: various classes, other processes, …

Accessing Processes

The module defines three objects of class ProcessMaker:

lgxPy.Stack

Object of type ProcessMaker for the stack processes

lgxPy.Mesh

Object of type ProcessMaker for the mesh processes

lgxPy.Global

Object of type ProcessMaker for the global processes

class lgxPy.ProcessMaker

This class represent a list of processes of a given type.

__getattr__(name)

Retrieve a process. If it doesn’t exist, this throws a NoSuchProcess exception.

Parameters:name – Name of the process.
Returns:An object of type ProcessRunner.
__str__()
Returns:the type of process this object will make.
__dir__()
Returns:The list of all processes of this type.
class lgxPy.ProcessRunner

This class represent a process.

__call__(...)

Call the process with the given arguments.

Returns:

Always true.

Raises:
  • UserCancelException – Thrown if the user pressed the Cancel button on a progress bar.
  • ProcessError – If the process (or a sub-process) returns false, this exception is raised instead.
  • StdException – If the process raises a standard exception, this will be translated into this exception.
lastParms

List of parameters last used for this process, or the default parameters if the process has never been used.

defaultParms

List of default parameters, as defined by the implementation of the process.

nbParms

Number of parameters for this process.

folder

Folder this process is stored in.

__str__()
Returns:The name of this process as Type.Name.
Exceptions
exception lgxPy.UserCancelException

Exception launched when the user press the Cancel button

exception lgxPy.ProcessError

If a process fails (i.e. returns false), this is translated into this exception.

exception lgxPy.BadProcessType

If the user is trying to access a process of the wrong type.

exception lgxPy.NoSuchProcess

If trying to access a process that doesn’t exist.

exception lgxPy.StdException

If an exception deriving std::exception is caught, it is translated into this exception (except for the ones defined above).

Utilities
class lgxPy.Point3u

A 3D point with unsigned integers.

x

Get/set the first dimension.

y

Get/set the second dimension.

z

Get/set the third dimension.

class lgxPy.Point3f

A 3D point with floating point values.

x

Get/set the first dimension.

y

Get/set the second dimension.

z

Get/set the third dimension.

class lgxPy.ImageInfo

Class used to parse an image and get information such as number of slices, channels, timepoints, …

filename

Name of the file containing the image.

size

Number of pixels in each dimension, given as a Point3u.

step

Size a of single voxel, given as a Point3f.

origin

Position of the origin of the stack (e.g. the front, lower, left corner), given as a Point3f.

nb_channels

Number of channels in the file.

nb_timepoints

Number of time points in the image.

labels

Whether the image is a labeled image or not.

Note:This is only valid for files saved by LithoGraphX, otherwise this is always false.

Parameter Handling

LithoGraphX provides three options to manage parameters, which you can choose by setting the parmsHandling module variable:

smart
This is the default. In this mode, parameters will be converted to the Python object closest to the C++ object. In practice, any argument provided directly by the user will be a string, but if another process provide a number, it will be a number. Any other type will still be a QVariant.
string only
In this mode, all arguments are always converted to string.
qvariant
In this mode, your Python process received the QVariant directly, like in C++.
Example Macro

Here is a simple example macro, calling a number of times the blur process:

# This first line is for modules to work with Python 2 or 3
from __future__ import print_function, division
# This is to access the Stack processes
from lgxPy import Stack
# This is to provide a user interface: note that for windows, LithoGraphX
# provides its own version of PyQt5
from PyQt5 import QtWidgets

processType = "Stack"
processName = "Repeat Blur"
processFolder = "Filters"
parmsChoice = dict(repeat=[1, 2, 3, 4, 5, 6, 7, 8, 9])
processIcon = ":/images/Blur.png" # we are re-using icons in the Qt resources
parmsDescs = dict(printed="Number of repetition of the blur")

def initialize(X, Y, Z, repeat, parent):
    repeat, ok = QtWidgets.QInputDialog.getInt(parent, "Number of repeats", "N = ", int(repeat), 0, 10)
    if not ok:
        return False
    return X, Y, Z, repeat

def run(X=.3, Y=.3, Z=.3, repeat=1):
    for i in range(int(repeat)):
        Stack.Gaussian_Blur_Stack(X, Y, Z)

Simply copy and paste this example in a file with a py extension and copy it to the user macro folder. The simplest way to access this folder is from the Macros menu in LithoGraphX. After that, select the Reload Macros entry in the same menu.

Hint

As LithoGraphX may be compiled with Python 2.7 or Pythong 3.4 or later, I recommend you use the __future__ module.

Frequently Asked Questions

Installation

I have a Windows laptop with an NVidia discrete card, but the main windows doesn’t show

You should have a terminal window opening. Check the start of the terminal, you should have something like this:

Welcome to LithoGraphX!

Thrust host evaluation: OpenMP

LithoGraphX version: 1.1.0 revision:
   created in thread: 0x14969344
Cuda driver version: 7.0
Cuda runtime version: 7.0

Cuda capable device found, device 0: GeForce GTX 960M
                 Compute capability: 5.0
                       Total memory: 2047 Mb
                    MultiProcessors: 5
     Res.threads per MultiProcessor: 2048
               Max resident threads: 10240
                         Cuda cores: 960
                         Clock rate: 1.176 GHz

The version of the Cuda driver and runtime may be different, but you should have a valid version. If not, you probably need to install the NVidia drivers for your card, as often default video drivers are not compatible with Cuda. You will find the latest NVidia drivers here: http://www.nvidia.com/Download/index.aspx

I have a Windows laptop with an AMD discrete card, but the main windows doesn’t show

You need to check if the discrete card has been triggered. For example, if you see something like:

OpenGL:
 - Version : 4.2.0 - Build 10.18.10.3540
 - Renderer: Intel(R) HD Graphics 4600
 - Vendor  : Intel

Then it’s your onboard Intel card that is selected. And as of today (July 2015), no Intel card is capable of running LithoGraphX. You need to tell the drivers of your graphics card to use the discrete card.

I have a Linux laptop with an NVidia card and LithoGraphX doesn’t start

Modern laptops with NVidia cards usually have a primary, low-consumption card. To use your NVidia card, you need to have either bumblebee or nvidia-prime installed (depending on how recent your Linux distribution is). If you installed nvidia-prime, make sure the nvidia card is selected. In a shell the command:

$ prime-select query

should return nvidia. If not, type:

$ sudo prime-select nvidia

If you installed bumblebee, you should have a program called optirun or primusrun (or both). LithoGraphX should detect automatically which one needs to be used. To make sure your installation is working run the following command in a shell:

$ primusrun glxinfo | grep -i nvidia
$ optirun glxinfo | grep -i nvidia

You should at least see:

server glx vendor string: NVIDIA Corporation
client glx vendor string: NVIDIA Corporation

If not, you need to fix your installation. You can try to contact us for help (http://www.lithographx.com/contact-credits).

Referencing and citations

How to cite this software?

Please, cite this paper:

Barbier de Reuille, P., Routier-Kierzkowska, A.-L., Kierzkowski, D., Bassel, G.W., Schüpbach, T., Tauriello, G., Bajpai, N., Strauss, S., Weber, A., Kiss, A., Burian, A., Hofhuis, H., Sapala, A., Lipowczan, M., Heimlicher M.B., Robinson, S., Bayer, E.M., Basler, K., Koumoutsakos, P., Roeder, A.H.K., Aegerter-Wilmsen, T., Nakayama, N., Tsiantis, M., Hay, A., Kwiatkowska, D., Xenarios, I., Kuhlemeier, C. & Smith, R.S. (2015) MorphoGraphX: A platform for quantifying morphogenesis in 4D. eLife 4:e05864 http://dx.doi.org/10.7554/eLife.05864

Also, we would appreciate if you put a link to the LithoGraphX website http://lithographx.com in the publication, or even better, from your own website.

Writing and Distributing Extensions

Processes, Macros, Plugins and Packages

The extension mechanism of LithoGraphX relies on these four notions:

Processes
A process implements an algorithm and is what users will see in the end. Within LithoGraphX, each process is an object that can be configured with some user interaction and execute the processing without any interaction.
Plugins
A Plugin is a single file registering one or more processes for use in LithoGraphX. Plugins can be enabled or disabled and if more than one plugin declares the same process, only the first one will be used. Plugins are typically written in C++.
Macros
A macro is a particular plugin that uses a macro language instead of a compiled one. These are different from standard plugins in that they rely on a Macro language being being defined to make the interface with the C++.
Packages
Packages are a distributable set of plugins and macros. Packages can contain the sources or binaries. Source packages need to be compiled, while binary packages are restricted to a given version of LithoGraphX and OS.

Writing a C++ Process

From C++, a process is a single class inheriting one of three classes: StackProcess, MeshProcess or GlobalProcess. Which class the process inherits from will decide where in the GUI it will appear and what other processes it can call. In short, if inheriting from StackProcess or MeshProcess only processes of the same type can be called, while inheriting from GlobalProcess allows a process to call any other process.

A process’s class should follow the following pattern, in which Some must be replaced by Stack, Mesh or Global

class ProcessName : public SomeProcess {
public:
  ProcessName(const SomeProcess& process)
    : Process(process)
    , SomeProcess(process)
  {
  }

  // The two following methods are mandatory

  bool operator()(const ParmList& parms) override {
    // Implementation of the process
  }
  QString name() const override {
    return "[Process Name]";
  }

  // All other methods are optional

  bool initialize(ParmList& parms, QWidget* parent) override {
    // Provide user interface to adjust the list of parameters
    // Note: the number of parameters cannot change!
  }

  QString description() const override {
    return "[Process Description]";
  }
  QString folder() const override {
    return "[Folder in which the process is stored]";
  }
  QStringList parmNames() const override {
    return QStringList() << "Parm1"
                         << "Parm2"
                         << ...;
  }
  QStringList parmDescs() const override {
    return QStringList() << "Description Parm1"
                         << "Description Parm2"
                         << ...;
  }
  ParmList parmDefaults() const override {
    return ParmList() << value1
                      << value2
                      << ...;
  }
  ParmChoiceMap parmChoice() const override {
    ParmChoiceMap map;
    map[ParmNum1] = QStringList() << "Value 1"
                                  << "Value 2"
                                  << ...;
    map[ParmNum2] = QStringList() << "Value 1"
                                  << "Value 2"
                                  << ...;
    // ...
    return map;
  }
  QIcon icon() const override {
    return QIcon(":/path/to/resource");
  }
}

When writing the process, the first task is to parse the parameters. Then, it is customary to provide another operator() method for direct call from C++ with the parameters already parsed.

Process Execution

Processes are executed in a separate thread, from which you cannot run any GUI-related events. This means you must never try to provide a user interface from within a process main method. If you want a user interface, it must be implemented in the Process::initialize(...) method.

During the process execution, there are two ways to show the user the progress of the algorithm:

  1. Use the lgx::Progress class
  2. Use the lgx::process::Process::updateState() method. This will pause the process while LithoGraphX updates the view, showing the current state. Be careful for the mesh to be in a proper state when you call this function. Also, all changed states will be reset after that.

Parameter Parsing

The ParmList type is an alias for a QList or QVariant. When using types, remember that the user must be able to type values as a string. QVariant are quite good at converting from string to various values, except for boolean values. So if you need boolean values, You should use the parmToBool function, which will convert the strings “yes”, “y”, “true”, “t”, “on” or “1” as true and any other value as false.

Calling other processes

There are two ways to call other processes, depending on the availability of the C++ definition or not. The more general method consist in using the runProcess method of the Process class. The signation of the function is:

bool Process::runProcess(const QString &processType, const QString &processName, const ParmList &parms)

Launch a process by name

Note that any exception launched by the process will be filtered and converted into an error message and the process returning false.

If the C++ implementation is available (through a library for exemple), then it is possible to directly instanciate the process, which allows to call the internal operator() method. Say you want to use the SieveFilter, you can write (see include/SieveFilter/SieveFilter.hpp in the system processes folder for details):

SieveFilter filter(*this);
filter(input, output, "Median", 100.f, false);

Modifying the State

When a process modifies the state (e.g. image, mesh, transformation, …), it needs to inform the system. For performance reasons, it would be impractical to either track all changes or to re-analyse all the data structures when coming back from a process. This section will explain first how images and meshes are represented and then how to inform the system about what has been changed.

Images: Layout and Utilities
Image type and memory layout
C++ implementation
Mesh Data Structure

Meshes are implemented using a Graph Rotation System (citation) via the class VVGraph.

Graph Rotation Systems
C++ Implementation
Triangles and Cells
Image Modifications

Images are modified through the lgx::Store objects. If the image is modified, you can call one of two functions:

void lgx::Store::changed()

Call this function for large-scale changed in the image, requiring the whole image to be updated.

void lgx::Store::changed(const BoundingBox3i &bbox)

Call this function for localised changes. The bounding box should include all the voxel changed.

Other aspects of image rendering (size, transfer function, …) are small and simple enough for their modifications to be tracked automatically.

Meshes Modifications

There are five different functions to mark what changed in a mesh:

void lgx::Mesh::updateTriangles()

Call this function if triangles properties have change, which means label or heat map.

void lgx::Mesh::updateLines()

Call this function if the “lines” change. This means mostly cell or mesh edges.

void lgx::Mesh::updatePositions()

Call this function if the position of the vertices have changed.

void lgx::Mesh::updateSelection()

Call this function if the selection has changed.

void lgx::Mesh::updateAll()

Call this function if you would have called all the others or if you added/removed vertices.

Useful Utilities

Here are a few features you might want to look at in the developer documentation:

  • File src/Dir.hpp for path manipulations you really need to use functions here to manage paths, in particular to save paths in files.
  • File src/Geometry.hpp and class templates lgx::util::Vector and lgx::util::Matrix for geometry
  • Class lgx::util::CSVStream to parse CSV files
  • Class lgx::util::PlyFile to parse PLY files (e.g. mesh files)
  • To run a process over a whole collection use the functions in src/Algorithms.hpp.
  • Use the class lgx::Progress to provide a progress bar, possibly with a mean for the user to cancel the process.
  • Use the class lgx::Image5D and associated functions to load/save images.

The Packaging System

Packages are simply folders, possibly compressed. There are two kind of packages:

  1. Source packages needs to be compiled but are independent from the operating system.
  2. Binary packages can be directly used but are usually dependent on an exact version of LithoGraphX and operating system.

Preparing a Binary Package

A binary package is simpler to prepare and is useful to distribute macros that don’t need compilation. The structure is important, the top-level should contain a file called description.ini and up to three folders, looking like this:

description.ini
macros/
processes/
    include/
        PackageName/
lib/

The description.ini file should be following this template:

[Package]
Name = [Package name]
Version = major.minor.patch
Description = "Description of the package"
Dependencies = ...
OS = [OS]

The “Dependencies” and “OS” description are optional. If they are not there, it means there is no constraints.

The other folders should contains specific files:

macros
This is were the macro needs to be put. This is also where any Python package you need should be placed.
lib
This is were support libraries should be placed.
packages
This is were compiled plug-ins need to be placed. In the include folder, the header files for the support libraries should be placed.

There shouldn’t be any files outside these folder or the installation will fail.

Preparing a Source Package

Unlike a binary package, the structure of a source package is a lot more free. The only constraint is the presence of two files at the root of the package:

description.ini
CMakeLists.txt

The description.ini file has the same structure as for the binary package. CMakeLists.txt should describe how to compile and install a binary package using CPack with a ZIP generator. Although you are free to implement this as you want, it is recommended to include the LithoGraphX CMake package:

LithoGraphX CMake package

First, the module defined the following variables:

LithoGraphX_FOUND
Whether LithoGraphX was found or not
LithoGraphX_VERSION
Version of the installed LithoGraphX
LithoGRaphX_PROCESS_VERSION
Version of the process subsystem
LithoGraphX_PROGRAM
Path to the LithoGraphX program
LithoGraphX_lgxPack
Path to the lgxPack program
LithoGraphX_LIBRARIES
List of libraries to link to LithoGraphX
LithoGraphX_OS
Name of the operating system LithoGraphX has been compiled for
LithoGraphX_BIN_DIR
Folder containing the LithoGraphX program
LithoGraphX_USER_PROCESS_DIR
Folder containing user-installed plugins
LithoGraphX_PROCESS_DIR
Folder containing system-installed plugins
LithoGraphX_USER_MACRO_DIR
Folder containing user-installed macros
LithoGraphX_MACRO_DIR
Folder containing system-installed macros
LithoGraphX_INCLUDE_DIR
Main LithoGraphX include directory
LithoGraphX_USER_LIB_DIR
Folder containing user-installed libraries
LithoGraphX_LIB_DIR
Folder containing system-installed libraries
LithoGraphX_USER_PACKAGES_DIR
Folder containing the definition of user packages
LithoGraphX_PACKAGES_DIR
Folder containing the definition of system packages

Each plug-ins containing support libraries define a component you can include when importing the package. For example, if you want to call directly the process defined in the SieveFilter package, you can use:

find_package(LithoGraphX REQUIRED COMPONENTS SieveFilter)

Then, for each requested module, the following variables will be defined:

LithoGraphX_${Module}_FOUND
Whether the module has been found or not
LithoGraphX_${Module}_VERSION
Version of the module
LithoGraphX_${Module}_LIBRARIES
Libraries to link against
LithoGraphX_${Module}_INCLUDE_DIRS
Folders containing the include files
LithoGraphX_${Module}_LIB_DIR
Folder containing the libraries
LithoGraphX_${Module}_LOCATION
Location of the file ${module}.cmake
LithoGraphX_${Module}_INSTALL_TYPE
user, system or builtin depending on how the module was installed. If ‘builtin’, the INCLUDE_DIRS, LIB_DIR and LOCATION are not defined.

Also, for each module, a target LithoGraphX::${Module} is created to use in TARGET_LINK_LIBRARIES() which will set all dependent libraries, include directories, …

This module also creates the following macro:

INIT_LGX_PACKAGE()

This function analyses the description.ini and creates the following variables and call the PROJECT function with the package name as argument:

LithoGraphX_PACKAGE_NAME
Name of the package
${LithoGraphX_PACKAGE_NAME}_VERSION
Version of the package, which MUST be in the form MAJOR.MINOR.PATCH
${LithoGraphX_PACKAGE_NAME}_DESCRIPTION
Description of the package
${LithoGraphX_PACKAGE_NAME}_DEPENDENCIES
Dependencies of the package

You can also set these variables by hand and call PROJECT() yourself.

LGX_PACKAGE()

This function creates the files needed by the package and setup CPack variables. Two files may be created:

  1. description.ini is always created using the variables created by INIT_LGX_PACKAGE()

  2. ${LithoGraphX_PACKAGE_NAME}.cmake is created if the package

    exports at least one library and contains the definition to link against it. It uses as a model the file Package.cmake found either in the current folder or in the cmake directory of LithoGraphX. The following variables can be used to influence the generated cmake module:

    LithoGraphX_${package}_EXTRA_INCLUDE_DIRS

    List of directories containing useful include dirs (probably from dependencies)

    LithoGraphX_${package}_EXTRA_LIBS

    List of libraries to link against, in addition to the ones defined in the package.

    ${package}_HAS_LIBS

    This is set automatically by LGX_ADD_LIBRARY, but if set to false, no CMake module will be generated. You can use this to prevent users from linking to your module.

LGX_FIND_PACKAGE(...)
Calls FIND_PACKAGE(...) but record the call to repeat it in the module.
LGX_ADD_PLUGIN(target source1 [source2 ...])
Add a plugin, compiled from source. It will be installed at the proper place.
LGX_ADD_MACRO(macro1 [macro2 ...] [STRIP_DIR dir])
Add a set of macros to the macro folder. If STRIP_DIR is specified, all files should be in the given folder, which will not be created in the macro folder.
LGX_ADD_LIBRARY(target [SHARED|STATIC] [MAIN] source1 [source2 ...] [PUBLIC_HEADER header1 [header2 ...]])
Add a library linked to LithoGraphX and installed in the library folder. If no library is marked as MAIN, the last specified one will be the main one.
LGX_DESCRIPTION(field output_var required)
Read the given field from the description.ini file in the local folder and store the result in output_var. If required is TRUE and the field is not present or empty, this raises an error.

Note: All paths must use forward slash, indenpendent from the system, so a windows path may look like: "C:/Program Files/LithoGraphX/bin".

A typical CMake file would follow the following template:

find_package(LithoGraphX REQUIRED)
init_lgx_package()

lgx_add_plugin(${LithoGraphX_PACKAGE_NAME} source1.cpp source2.cpp ...)

lgx_package()

Or, if a support library is compiled:

find_package(LithoGraphX REQUIRED)
init_lgx_package()

lgx_add_library(${LithoGraphX_PACKAGE_NAME}_lib SHARED
    source1.cpp source2.cpp ...
    PUBLIC_HEADER header1.gpp header2.hpp ...)

lgx_add_plugin(${LithoGraphX_PACKAGE_NAME} source_impl.cpp)
target_link_library(${LithoGraphX_PACKAGE_NAME} ${LithoGraphX_PACKAGE_NAME}_util)

lgx_package()

What’s new?

Version 1.2.1

Highlights

  • New Image loading/saving interface to load/save full 5D images (no display yet though)
  • Direct interfacing to Image Magick to load images, allowing finer control and faster image loading.

Details

  • Corrected the auto-update dialog box (Pull Request 21)
  • Corrected installation message of Image Magick (Pull Request 21)
  • Corrected handling of spaces in path to Python (windows only) (Pull Request 22)
  • Restored cutting surfaces, as v. 1.2.0 has a typo in the shaders. (Pull Request 23)
  • Completly new Image5D object for loading/saving images. This means processes can now load and process full 5D images (Pull Request 24)
  • Auto-seeded mesh segmentation now clear the old segmentation (Pull Request 25)
  • Corrected handling of the Delete and Backspace keys in the main GUI (Pull Request 25)
  • Python macros can now be documented using the module’s documentation (Pull Request 25)
  • New python module plyfile in lgxUtils package to load PLY files (e.g. meshes) (Pull Request 25)
  • Information::out and Information::err are now thread-safe (Pull Request 26)
  • Correction of 3D picking (it was shifted by half a voxel) (Pull Request 27)
  • Corrected use of Image Magick to prevent gamma correction when loading (Pull Request 27)
  • lgx::util::apply_kernel_it can now accept a kernel by rvalue reference too.
  • When installing directly a source package, a copy of the source is kept for future re-compilation, but is currently not used (Pull Request 28)
  • If a plugin fails to load, LithoGraphX will try again to load it at the next launch (Pull Request 28).
  • Started the documentation of the plugins and packaging system (Pull Request 29).
  • Added samples plugins to installation (Pull Request 29)
  • Added notes to not use named arguments in sip as it wasn’t available for Qt 5.2 (Pull Request 30)
  • Improved checking of package dependencies, added option to force (un-)installation (Pull request 31).
  • Optimized image sequence loading using Image Magick’s capability to load many files at once (Pull Request 32).

Version 1.2.0

Highlights

  • New Packaging system to distribute processes
  • New Plugin system with interface to manager them
  • Improved cell classification processes
  • Optimization if ITK algorithms for 2D images
  • New incremental auto-seeded watershed

Details

  • Corrected reading RGB TIFFs and OME-TIFFs generated by the Zeiss software (Pull Request 1).
  • Watershed can now be used on partially segmented stacks (Pull Request 2).
  • Transfer function is now copied with the meta data of a store (Pull Request 3).
  • Swap / Copy stacks handles small differences (e.g. less than noise) in step and origin correctly (Pull Request 3).
  • Corrected cutting surfaces (Pull request 4).
  • Improved Segment Section process: when inverting the image, it is reverted before exiting the process (Pull Request 5).
  • Documented Shader class, also minor improvements of this class (Pull Request 5).
  • Correction PC analysis: PCs are now ordered properly (Pull request 6)
  • Split Ubuntu packages into dev, doc and bin and added versioning of shared object files (Pull Request 7).
  • Now all ITK algorithms are instanciated explicitely for 2D images if one of the dimension is 1, it’s faster and works more often (some 3D algorithms require a real 3D image) (Pull Request 8).
  • Corrected the use of copyMetaData in ITK algorithms (Pull Request 8).
  • Correctly compiles with newer version of ITK and CUDA (Pull Request 9).
  • Improvements in cell classifier UI: the GUI has been fully revised and what was “suffixes” can now be Python’s formatting expressions (Pull Request 10).
  • Cell classifiers can now use project files to read the transformation before generating the features (Pull Request 10).
  • The CSV reader now also understands if the CSV uses semi-colons instead of comas (looking at you Microsoft Excel) and it works if there is only one columns (Pull Request 11).
  • The windows version now finds the correct version of Python (Pull Request 12).
  • ITK segmentation now sets the labels flag properly (Pull Request 13).
  • New section about hardware specification in the documentation (Pull Request 14).
  • Corrected computation of the incline angle for 2d cell features to be in the range from -pi/2 to pi/2 (Pull Request 15).
  • The cell classifier has been moved to Global processes to allow use of cells from stacks or meshes and change the transformation (Pull Request 16).
  • Added packaging system and plugin management (Pull Request 18 and Pull Request 19).
  • For windows, added a building environment (Pull Request 18).
  • Added new tutorial on “flat” cells segmentation (Pull Request 18).
  • Corrected problem with drawing when selecting cells (Pull Request 18).
  • Corrected rendering of Pixel Edit’s circle (Pull Request 19).
  • Added dialog box to use laptop or desktop configuration the first time LithoGraphX is launched (Pull Request 19).
  • Updated tutorials with new presentation of used processes (Pull Request 19).
  • Thrust can now compile in CPU mode, in which case CLang can be used (Pull Request 19).
  • Under windows, the installer register LithoGraphX to the local installation of cmake (Pull Request 19).
  • All tools now have keyboard shortcuts (Pull Request 19).
  • Under windows, the installer now offers to also install Image Magick (Pull Request 19).
  • Add new “What’s new?” section in the documentation (Pull Request 20).
  • When a new version of LithoGraphX appears, the About box appears before the interface (Pull Request 20).

Contributors and Licensing

LithoGraphX is licensed under the GPL v3. It is a fork of MorphoGraphX version 1.0 rev. 1256.

Contributors

  • Dr. Barbier de Reuille, Pierre (lead developer)
  • Dr. Robinson, Sarah
  • Dr. Burian, Agata
  • Dr. Summers, Holly
  • Dr. Yoshida, Saiko

Past Contributors

People listed have contributed to MorphoGraphX in significant ways, and in this way also contributed to LithoGraphX:

  • Dr. Weber, Alain
  • Schuepbach, Thierry
  • Toriello, Gerardo
  • Dr. Strauss, Soeren
  • Dr. Nakayama, Naomi
  • Dr. Richard Smith’s team

Funding Support

  • Google Inc.
  • SystemsX.ch
  • Swiss National Science Foundation
  • University of Bern, Switzerland

Indices and tables