\[% Math \newcommand{\diff}{\operatorname{d}\!} \newcommand{\setR}{\mathbb{R}} \newcommand{\setN}{\mathbb{N}} \newcommand{\esp}[1]{\mathbb{E}\left[#1\right]} \newcommand{\Space}{$\phantom{grrr}$} \newcommand{\argmin}[1]{\underset{#1}{\operatorname{argmin}} \; } \newcommand{\Argmin}[1]{\underset{#1}{\operatorname{Argmin}} \; } \newcommand{\argmax}[1]{\underset{#1}{\operatorname{argmax}} \; } \let\oldvec\vec \renewcommand{\vec}{\boldsymbol} %boldsymbol or mathbf ? \newcommand{\tv}[1]{\operatorname{TV}\left( #1 \right)} \newcommand{\prox}[2]{\operatorname{prox}_{#1}{\left(#2\right)}} \newcommand{\proj}[2]{\operatorname{Proj}_{#1}{\left(#2\right)}} \newcommand{\sign}[1]{\operatorname{sign}\left( #1 \right)} \newcommand{\braket}[2]{\left\langle #1 \, , \, #2 \right\rangle} \renewcommand{\div}{\operatorname{div}} \newcommand{\id}{\operatorname{Id}} \newcommand{\norm}[1]{\left\| #1 \right\|} \newcommand{\lag}[1]{\mathcal{L}\left( #1 \right)} \newcommand{\mmax}[2]{\max_{#1}\left\{ #2 \right\}} \newcommand{\mmin}[2]{\min_{#1}\left\{ #2 \right\}} \newcommand{\conv}{\ast} \newcommand{\ft}[1]{\mathcal{F}\left( #1 \right)} \newcommand{\ift}[1]{\mathcal{F}^{-1}\left( #1 \right)} \newcommand{\pmat}[1]{\begin{pmatrix} #1 \end{pmatrix}} \newcommand{\E}[1]{\cdot 10^{#1}} %notation scientifique. Utiliser "e", "E", ou "10^" ? \newcommand{\amin}[2]{\underset{#1}{\operatorname{argmin}} \; \left\{ #2 \right\} }\]

Building a dictionary

This tutorial explains how to generate a dictionary required by PyHST2 when using the Dictionary-based reconstruction method. A typical use case is when you have a high quality reconstructed slice of a sample, and you want to perform low-dose scans on similar samples afterwards. The dictionary will capture the essential features of the high-quality slice, and will be used to reconstruct other volumes.

Installing ksvd

You first need to install ksvd, a Python script which generates a patches file from a slice/volume. In this tutorial, the directory /home/myself/software/ksvd is used as an example.

First download and compile ksvd :

mkdir software/ksvd
cd software/ksvd
export KSVD_DIR=$(pwd)
git clone http://gitlab.esrf.fr/mirone/ksvd
cd ksvd
python setup.py install --prefix=$KSVD_DIR

Then, set the environment variables. This has to be done each time you want to run ksvd.

export PATH=$PATH:$KSVD_DIR/bin
export PYTHONPATH=$PYTHONPATH:$KSVD_DIR/lib/python2.7/site-packages/

Running ksvd

Do not forget to set the environment variables :

export PATH=$PATH:/home/myself/software/ksvd/bin
export PYTHONPATH=$PYTHONPATH:/home/myself/software/ksvd/lib/python2.7/site-packages/
The syntax is ksvd input_file.yaml. You need :
  • An input file

  • A slice or volume from which the patches will be built

Input file format for a slice

ksvd uses an input file format in the .yaml format. Suppose you have a (good quality) slice (in EDF or vol format) myslice.edf from which you want to build the dictionary patches. A basic input file will be :

patchwidth: 8
NPURSUIT:    4
n_comps:   200
nitersksvd:  5
files:
 - !ImageFile
    START_X: 0
    END_X: 100000
    START_Y: 0
    END_Y: 100000
    VAL_MIN: -1.0e+30   # no constraints
    VAL_MAX: +1.0e+30   # no constraints
    FILE_TYPE: edf
    FILE:  myslice.edf
    DERIVATIVES: 0
    N_PATCHES: 40000

This example produces a dictionary of 200 \(8 \times 8\) patches.

You can build the patches from a region of interest with the parameters START_X, END_X, START_Y, END_Y. If the entire slice is used, you can set these parameters to a huge value.

You can also discard values outsides of the range [VAL_MIN, VAL_MAX].

Input file format for a volume

The input file for a vomume is slightly different. A example of file building patches on the volume myvol.vol is the following :

patchwidth: 8
NPURSUIT:    4
n_comps:   200
nitersksvd:  5

files:
 - !VolumeFile
    START_X: 600
    END_X: 1428
    START_Y: 600
    END_Y: 1333
    START_Z: 31
    END_Z: 51
    VDIMX: 2048
    VDIMY: 2048
    VDIMZ: 81
    VAL_MIN: 0.1
    VAL_MAX: 0.29
    FILE_TYPE: vol
    FILE:  myvolume.vol
    DERIVATIVES: 0
    N_PATCHES: 40000

In this example, 200 \(8 \times 8\) patches are generated from the region of interest \([600, 1428] \times [600, 1333]\). The slices 31 to 51 are used in the volume. The parameters VDIMX, VDIMY, VDIMZ specify the total dimensions of the volume.

Input file format for vectorial patches

The Dictionary-based reconstruction can exploit the 3D correlation within the volume (instead of the 2D correlation in a slice). To do so, the patches need to be three-dimensional (hence they have to be learned on a volume).

The following example generates 300 patches of size \(8 \times 8 \times 3\). This means that in the reconstruction, the slice will be reconstructed by groups of 3. Here, the provided volume has 7 slices, which is enough for this example.

patchwidth: 8
NPURSUIT:    4
n_comps:   300
nitersksvd:  5
patch_eight: 3

files:
 - !VolumeFile
    START_X: 0
    END_X: 1163
    START_Y: 879
    END_Y: 1333
    START_Z: 0
    END_Z: 6
    VDIMX: 2048
    VDIMY: 2048
    VDIMZ: 7
    VAL_MIN: -1000.0
    VAL_MAX: 1000.0
    FILE_TYPE: vol
    FILE:  myvol.vol
    DERIVATIVES: 0
    N_PATCHES: 40000

Input file for differential phase contrast

PyHST2 has a reconstruction mode for differential phase contrast (eg. analyzer-based phase contrast). In this case, each line of the sinogram is multiplied by \(\cos(\theta)\) and \(\sin(\theta)\), which gives two sinograms, and eventually two slices. The slice corresponding to the \(\cos (\theta)\) component will be reconstructed with a set of patches, while the slice corresponding to the component \(\sin (\theta)\) will be resconstructed with another set of patches.

Thus, the dictionary contains patches with two components. To build this kind of patches, the option to set is

DERIVATIVES: 1

Visualizing the patches

You can also visualize the patches. In the directory where your patches file is located, just type

ksvd

(without arguments), and then provide the name of the patches file when prompted.

A common error

If you do not have the version 5 of PyMca, you will get the following error :

Traceback (most recent call last):
  File "/home/myself/software/ksvd/bin/ksvd", line 3, in <module>
    import ksvd.ksvd
  File "/home/myself/software/ksvd/lib/python2.7/site-packages/ksvd/ksvd.py", line 7, in <module>
    from PyMca5.PyMcaIO import EdfFile
ImportError: No module named PyMca5.PyMcaIO

You need to modify the lines 7-8 of the file /home/myself/software/ksvd/lib/python2.7/site-packages/ksvd/ksvd.py. The lines

from PyMca5.PyMcaIO import EdfFile
#from PyMca import EdfFile

should be

#from PyMca5.PyMcaIO import EdfFile
from PyMca import EdfFile