[hkl] It is important to move the diffractometer during a trajectory calculation.
[hkl.git] / Documentation / hkl.org.in
blob368a032fdd31fb1b7d36a0b3653b529a5d06ec66
1 #+TITLE: Welcome to hkl's @VERSION@ documentation!
2 #+AUTHOR: Picca Frédéric-Emmanuel
3 #+EMAIL: picca at synchrotron dash soleil dot fr
4 #+LANGUAGE: en
5 #+STYLE: <style>table.center {margin-left:auto; margin- right:auto;}</style>
7 #+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
8 #+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
10 #+HTML_HEAD: <script src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
11 #+HTML_HEAD: <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
12 #+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
13 #+HTML_HEAD: <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
15 * Introduction
16   The purpose of the library is to factorize single crystal
17   diffraction angles computation for different kind of diffractometer
18   geometries. It is used at the SOLEIL, Desy and Alba synchrotron with
19   the Tango control system to pilot diffractometers.
20 ** Features
21    - mode computation (aka PseudoAxis)
22    - item for different diffractometer geometries.
23    - UB matrix computation.
24      - busing & Levy with 2 reflections
25      - simplex computation with more than 2 reflections using the GSL
26        library.
27      - Eulerians angles to pre-orientate your sample.
28    - Crystal lattice refinement
29      - with more than 2 reflections you can select which parameter must
30        be fitted.
31    - Pseudoaxes
32      - psi, eulerians, q, ...
33 ** Conventions
34    In all this document the next convention will be used to describe
35    the diffractometers geometries.
36    - right handed convention for all the angles.
37    - direct space orthogonal base.
38    - description of the diffractometer geometries is done with all
39      axes values set to zero.
40 ** Diffraction
41 *** the crystal
43     A periodic crystal is the association of a pattern and a lattice. The
44     pattern is located at each points of the lattice node. Positions of
45     those nodes are given by:
47     \[
48     R_{uvw}=u\cdot\vec{a}+v\cdot\vec{b}+w\cdot\vec{c}
49     \]
51     $\vec{a}$, $\vec{b}$, $\vec{c}$ are the former vector of a base of the
52     space. =u=, =v=, =w= are integers. The pattern contain atoms
53     associated to each lattice node. the purpose of diffraction is to study
54     the interaction of this crystal (pattern+lattice) with X-rays.
56     #+CAPTION: Crystal direct lattice.
57     [[./figures/crystal.png]]
59     this lattice is defined by $\vec{a}$, $\vec{b}$, $\vec{c}$ vectors, and
60     the angles $\alpha$, $\beta$, $\gamma$. In general cases this lattice is
61     not orthonormal.
63     Nevertheless to compute the interaction of this real space lattice and
64     the X-Rays, it is convenient to define another lattice called reciprocal
65     lattice defined like this:
67     \begin{eqnarray*}
68     \vec{a}^{\star} & = & \tau\frac{\vec{b}\wedge\vec{c}}{\vec{a}\cdot(\vec{b}\wedge\vec{c})}\\
69     \vec{b}^{\star} & = & \tau\frac{\vec{c}\wedge\vec{a}}{\vec{b}\cdot(\vec{c}\wedge\vec{a})}\\
70     \vec{c}^{\star} & = & \tau\frac{\vec{a}\wedge\vec{b}}{\vec{c}\cdot(\vec{a}\wedge\vec{b})}
71     \end{eqnarray*}
73     $\tau=2\pi$ or $\tau=1$ depending on the conventions.
75     It is then possible to define theses orthogonal properties:
77     \begin{eqnarray*}
78     \vec{a}^{\star}\cdot\vec{a}=\tau & \vec{b}^{\star}\cdot\vec{a}=0    & \vec{c}^{\star}\cdot\vec{a}=0\\
79     \vec{a}^{\star}\cdot\vec{b}=0    & \vec{b}^{\star}\cdot\vec{b}=\tau & \vec{c}^{\star}\cdot\vec{b}=0\\
80     \vec{a}^{\star}\cdot\vec{c}=0    & \vec{b}^{\star}\cdot\vec{c}=0    & \vec{c}^{\star}\cdot\vec{c}=\tau
81     \end{eqnarray*}
83     This reciprocal space lattice allow to write in a simpler form the
84     interaction between the crystal and the X-Rays. We often only know about
85     $\vec{a}$, $\vec{b}$, $\vec{c}$ vectors and the angles $\alpha$,
86     $\beta$, $\gamma$. Using the previous equations reciprocal, we can
87     compute the reciprocal lattice this way:
90     \begin{eqnarray*}
91     a^{\star} & = & \frac{\sin\alpha}{aD}\\
92     b^{\star} & = & \frac{\sin\beta}{bD}\\
93     c^{\star} & = & \frac{\sin\gamma}{cD}
94     \end{eqnarray*}
96     where
98     \[
99     D=\sqrt{1-\cos^{2}\alpha-\cos^{2}\beta-\cos^{2}\gamma+2\cos\alpha\cos\beta\cos\gamma}
100     \]
102     To compute the angles between the reciprocal space vectors, it is once
103     again possible to use the previous equations reciprocal to obtain the
104     sines and cosines of the angles $\alpha^\star$, $\beta^\star$ and
105     $\gamma^\star$:
107     \begin{eqnarray*}
108     \cos\alpha^{\star}=\frac{\cos\beta\cos\gamma-\cos\alpha}{\sin\beta\sin\gamma} & \, & \sin\alpha^{\star}=\frac{D}{\sin\beta\sin\gamma} \\
109     \cos\beta^{\star}=\frac{\cos\gamma\cos\alpha-\cos\beta}{\sin\gamma\sin\alpha} & \, & \sin\beta^{\star}=\frac{D}{\sin\gamma\sin\alpha}\\
110     \cos\gamma^{\star}=\frac{\cos\alpha\cos\beta-\cos\gamma}{\sin\alpha\sin\beta} & \, & \sin\gamma^{\star}=\frac{D}{\sin\alpha\sin\beta}
111     \end{eqnarray*}
113     the volume of the lattice can be compute this way:
115     \[
116     V = abcD
117     \]
119     or
121     \[
122     V = \vec{a} \dot (\vec{b} \wedge \vec{c}) = \vec{b} \dot (\vec{c} \wedge \vec{a}) = \vec{c} \dot (\vec{a} \wedge \vec{b})
123     \]
125 *** Diffraction
127     Let the incoming X-rays beam whose wave vector is $\vec{k_{i}}$,
128     $|k_{i}|=\tau/\lambda$ where $\lambda$ is the wavelength of the signal.
129     The $\vec{k_{d}}$ vector wavelength of the diffracted beam. There is
130     diffusion if the diffusion vector $\vec{q}$ can be expressed as follows:
132     \[
133     \vec{q}=\vec{k_{d}}-\vec{k_{i}}=h.\vec{a}^{*}+k.\vec{b}^{*}+l.\vec{c}^{*}
134     \]
136     where $(h,k,l)\in\mathbb{N}^{3}$ and $(h,k,l)\neq(0,0,0)$. Theses
137     indices $(h,k,l)$ are named Miller indices.
139     Another way of looking at things has been given by Bragg and that famous
140     relationship:
142     \[
143     n\lambda=2d\sin\theta
144     \]
146     where $d$ is the inter-plan distance and $n \in \mathbb{N}$.
148     The diffusion occurs for an unique $\theta$ angle. Then we got
149     $\vec{q}$ perpendicular to the diffraction plan.
151     The Ewald construction allow to represent this diffraction in the
152     reciprocal space.
154 *** Quaternions
155 **** Properties
157      The quaternions will be used to describe the diffractometers geometries.
158      Theses quaternions can represent 3D rotations. There is different way to
159      describe then like complex numbers.
161      \[
162      q=a+bi+cj+dk
163      \]
165      or
167      \[
168      q=[a,\vec{v}]
169      \]
171      To compute the quaternion's norm, we can proceed like for complex
172      numbers
174      \[
175      \|q\|=\sqrt{a²+b²+c²+d²}
176      \]
178      Its conjugate is :
180      \[
181      q^{*}=[a,-\vec{u}]=a-bi-cj-dk
182      \]
184 **** Operations
186      The difference with the complex number algebra is about
187      non-commutativity.
189      \[
190      qp \neq pq
191      \]
193      \[
194      \begin{bmatrix}
195      ~ & 1 & i  & j  & k \cr
196      1 & 1 & i  & j  & k \cr
197      i & i & -1 & k  & -j \cr
198      j & j & -k & -1 & i \cr
199      k & k & j  & -i & -1
200      \end{bmatrix}
201      \]
203      The product of two quaternions can be express by the Grassman product
204      Grassman product. So for two quaternions $p$ and $q$:
206      \begin{align*}
207      q &= a+\vec{u} = a+bi+cj+dk\\
208      p &= t+\vec{v} = t+xi+yj+zk
209      \end{align*}
211      we got
213      \[
214      pq = at - \vec{u} \cdot \vec{v} + a \vec{v} + t \vec{u} + \vec{v} \times \vec{u}
215      \]
217      or equivalent
219      \[
220      pq = (at - bx - cy - dz) + (bt + ax + cz - dy) i + (ct + ay + dx - bz) j + (dt + az + by - cx) k
221      \]
223 **** 3D rotations
225      L'ensemble des quaternions unitaires (leur norme est égale à 1) est le
226      groupe qui représente les rotations dans l'espace 3D. Si on a un vecteur
227      unitaire $\vec{u}$ et un angle de rotation $\theta$ alors le quaternion
228      $[\cos\frac{\theta}{2},\sin\frac{\theta}{2}\vec{u]}$ représente la
229      rotation de $\theta$ autour de l'axe $\vec{u}$ dans le sens
230      trigonométrique. Nous allons donc utiliser ces quaternions unitaires
231      pour représenter les mouvements du diffractomètre.
233      Alors que dans le plan 2D une simple multiplication entre un nombre
234      complex et le nombre $e^{i\theta}$ permet de calculer simplement la
235      rotation d'angle $\theta$ autour de l'origine, dans l'espace 3D
236      l'expression équivalente est:
238      \[
239      z'=qzq^{-1}
240      \]
242      où $q$ est le quaternion de norme 1 représentant la rotation dans
243      l'espace et $z$ le quaternion représentant le vecteur qui subit la
244      rotation (sa partie réelle est nulle).
246      Dans le cas des quaternions de norme 1, il est très facile de calculer
247      $q^{-1}$. En effet l'inverse d'une rotation d'angle $\theta$ est la
248      rotation d'angle $-\theta$. On a donc directement:
250      \[
251      q^{-1}=[\cos\frac{-\theta}{2},\sin\frac{-\theta}{2}\vec{u}]=[\cos\frac{\theta}{2},-\sin\frac{\theta}{2}\vec{u}]=q^{*}
252      \]
254      Le passage aux matrices de rotation se fait par la formule suivante
255      $q\rightarrow M$.
257      \[
258      \begin{bmatrix}
259      a{{}^2}+b{{}^2}-c{{}^2}-d{{}^2} & 2bc-2ad & 2ac+2bd\\
260      2ad+2bc & a{{}^2}-b{{}^2}+c{{}^2}-d{{}^2} & 2cd-2ab\\
261      2bd-2ac & 2ab+2cd & a{{}^2}-b{{}^2}-c{{}^2}+d{{}^2}
262      \end{bmatrix}
263      \]
265      La composition de rotation se fait simplement en multipliant les
266      quaternions entre eux. Si l'on à $q$
268 ** Modes de fonctionnement
269 ** Equations fondamentales
271    Le problème que nous devons résoudre est de calculer pour une famille de
272    plan $(h,k,l)$ donné, les angles de rotation du diffractomètre qui
273    permettent de le mettre en condition de diffraction. Il faut donc
274    exprimer les relations mathématiques qui lient les différents angles
275    entre eux lorsque la condition de Bragg est vérifiée. L'équation
276    fondamentale est la suivante:
278    \begin{align*}
279    \left(\prod_{i}S_{i}\right)\cdot U\cdot B\cdot\vec{h} & =\left(\prod_{j}D_{j}-I\right)\cdot\vec{k_{i}}\\
280    R\cdot U\cdot B\cdot\vec{h} & =\vec{Q}
281    \end{align*}
283    ou $\vec{h}$ est le vecteur $(h,k,l)$, $\vec{k_{i}}$ est le vecteur
284    incident, $S_{i}$ les matrices de rotations des mouvements liés à
285    l'échantillon, $D_{j}$ les matrices de rotation des mouvements liés au
286    détecteur, $I$ la matrice identité, $U$ la matrice d'orientation du
287    cristal par rapport au repère de l'axe sur lequel ce dernier est monté
288    et $B$ la matrice de passage d'un repère non orthonormé ( celui du
289    crystal réciproque) à un repère orthonormé.
291 *** Calcule de B
293     Si l'on connaît les paramètres cristallins du cristal étudié, il est
294     très simple de calculer $B$:
296     \[
297     B=
298     \begin{bmatrix}
299     a^{\star} & b^{\star}\cos\gamma^{\star} & c^{\star}\cos\beta^{\star}\\
300     0 & b^{\star}\sin\gamma^{\star} & -c^{\star}\sin\beta^{\star}\cos\alpha\\
301     0 & 0 & 1/c
302     \end{bmatrix}
303     \]
305 *** Calcule de U
307     Il existe plusieurs façons de calculer $U$. Busing et Levy en a proposé
308     plusieurs. Nous allons présenter celle qui nécessite la mesure de
309     seulement deux réflections ainsi que la connaissance des paramètres
310     cristallins. Cette façon de calculer la matrice d'orientation $U$, peut
311     être généralisée à n'importe quel diffractomètre pour peu que la
312     description des axes de rotation permette d'obtenir la matrice de
313     rotation de la machine $R$ et le vecteur de diffusion $\vec{Q}$.
315     Il est également possible de calculer $U$ sans la connaîssance des
316     paramètres cristallins. il faut alors faire un affinement des
317     paramètres. Cela revient à minimiser une fonction. Nous allons utiliser
318     la méthode du simplex pour trouver ce minimum et donc ajuster l'ensemble
319     des paramètres cristallins ainsi que la matrice d'orientation.
321 *** Algorithme de Busing Levy
323     L'idée est de se placer dans le repère de l'axe sur lequel est monté
324     l'échantillon. On mesure deux réflections $(\vec{h}_{1},\vec{h}_{2})$
325     ainsi que leurs angles associés. Cela nous permet de calculer $R$ et
326     $\vec{Q}$ pour chacune de ces reflections. nous avons alors ce système:
328     \begin{eqnarray*}
329     U\cdot B\cdot\vec{h}_{1} & = & \tilde{R}_{1}\cdot\vec{Q}_{1}\\
330     U\cdot B\cdot\vec{h}_{2} & = & \tilde{R}_{2}\cdot\vec{Q}_{2}
331     \end{eqnarray*}
333     De façon à calculer facilement $U$, il est intéressant de définir deux
334     trièdres orthonormé $T_{\vec{h}}$ et $T_{\vec{Q}}$ à partir des vecteurs
335     $(B\vec{h}_{1},B\vec{h}_{2})$ et
336     $(\tilde{R}_{1}\vec{Q}_{1},\tilde{R}_{2}\vec{Q}_{2})$. On a alors très
337     simplement:
339     \[
340     U \cdot T_{\vec{h}} = T_{\vec{Q}}
341     \]
343     Et donc
345     \[
346     U = T_{\vec{Q}} \cdot \tilde{T}_{\vec{h}}
347     \]
349 *** Affinement par la méthode du simplex
351     Dans ce cas nous ne connaissons pas la matrice $B$, il faut donc mesurer
352     plus que deux réflections pour ajuster les 9 paramètres. Six paramètres
353     pour le crystal et trois pour la matrice d'orientation $U$. Les trois
354     paramètres qui permennt de representer $U$ sont en fait les angles
355     d'euler. il faut donc être en mesure de passer d'une représentation
356     eulérien à cette matrice :math::U et réciproquement.
358     \[
359     U = X \cdot Y \cdot Z
360     \]
362     où $X$ est la matrice rotation suivant l'axe Ox et le premier angle
363     d'Euler, $Y$ la matrice de rotation suivant l'axe Oy et le deuxième
364     angle d'Euler et $Z$ la matrice du troisième angle d'Euler pour l'axe
365     Oz.
367     #+ATTR_HTML: class="center"
368     | $X$        | $Y$        | $Z$        |
369     | <10>       | <10>       | <10>       |
370     | $\begin{bmatrix} 1 & 0 & 0\\ 0 & A & -B\\ 0 & B & A \end{bmatrix}$ | $\begin{bmatrix}C & 0 & D\\0 & 1 & 0\\-D & 0 & C\end{bmatrix}$ | $\begin{bmatrix}E & -F & 0\\F & E & 0\\0 & 0 & 1\end{bmatrix}$ |
372     et donc:
374     \[
375     U=
376     \begin{bmatrix}
377     CE & -CF & D\\
378     BDE+AF & -BDF+AE & -BC\\
379     -ADE+BF & ADF+BE & AC
380     \end{bmatrix}
381     \]
383     Il est donc facile de passer des angles d'Euler à la matrice
384     d'orientation.
386     Il faut maintenant faire la transformation inverse de la matrice $U$
387     vers les angles d'euler.
389 * PseudoAxes
390   This section describe the calculations done by the library for the
391   different kind of pseudo axes.
392 ** General process
393 *** First Solution
394     The hkl library use the gsl library in order to find the first
395     valid solution.
396 *** Multiplication of the solutions.
397     Once we have got the first solution different strategies are
398     applyed in order to generate more solutions.
399 **** Geometry Multiplication
400      For kappa diffractometers, once you have one solution it is
401      possible to générate another one using a property of this
402      geometry. (Left arm and right arm).
403 *** Restrains of the Solutions
404     We apply then some constrains to reduce these solutions to only a
405     bunch of acceptable ones. Usualy we take the axis range into
406     account.
407 ** Eulerians to Kappa angles
409    1st solution
411    \begin{eqnarray*}
412    \kappa_\omega & = & \omega - p + \frac{\pi}{2} \\
413    \kappa & = & 2 \arcsin\left(\frac{\sin\frac{\chi}{2}}{\sin\alpha}\right) \\
414    \kappa_\phi & = &  \phi - p - \frac{\pi}{2}
415    \end{eqnarray*}
417    or 2nd one
419    \begin{eqnarray*}
420    \kappa_\omega & = & \omega - p - \frac{\pi}{2} \\
421    \kappa & = & -2 \arcsin\left(\frac{\sin\frac{\chi}{2}}{\sin\alpha}\right) \\
422    \kappa_\phi & = &  \phi - p + \frac{\pi}{2}
423    \end{eqnarray*}
425    where
427    \[
428    p = \arcsin\left(\frac{\tan\frac{\chi}{2}}{\tan\alpha}\right)
429    \]
431    and $\alpha$ is the angle of the kappa axis with the $\vec{y}$ axis.
433 ** Kappa to Eulerians angles
435    1st solution
437    \begin{eqnarray*}
438    \omega & = & \kappa_\omega + p - \frac{\pi}{2} \\
439    \chi   & = & 2 \arcsin\left(\sin\frac{\kappa}{2} \sin\alpha\right) \\
440    \phi   & = & \kappa_\phi + p + \frac{\pi}{2}
441    \end{eqnarray*}
443    or 2nd one
445    \begin{eqnarray*}
446    \omega & = & \kappa_\omega + p + \frac{\pi}{2} \\
447    \chi   & = & -2 \arcsin\left(\sin\frac{\kappa}{2} \sin\alpha\right) \\
448    \phi   & = & \kappa_\phi + p - \frac{\pi}{2}
449    \end{eqnarray*}
451    where
453    \[
454    p = \arctan\left(\tan\frac{\kappa}{2} \cos\alpha\right)
455    \]
457    #+CAPTION: $\omega = 0$, $\chi = 0$, $\phi = 0$, 1st solution
458    [[./figures/e2k_1.png]]
460    #+CAPTION: $\omega = 0$, $\chi = 0$, $\phi = 0$, 2nd solution
461    [[./figures/e2k_2.png]]
463    #+CAPTION: $\omega = 0$, $\chi = 90$, $\phi = 0$, 1st solution
464    [[./figures/e2k_3.png]]
466    #+CAPTION: $\omega = 0$, $\chi = 90$, $\phi = 0$, 2nd solution
467    [[./figures/e2k_4.png]]
469 ** Qper and Qpar
470    [[./figures/qper_qpar.png]]
472    this pseudo axis engine compute the perpendicular
473    ($\left|\left|\vec{Q_\text{per}}\right|\right|$) and parallel
474    ($\left|\left|\vec{Q_\text{par}}\right|\right|$) contribution of
475    $\vec{Q}$ relatively to the surface of the sample defined by the
476    $\vec{n}$ vector.
478    \begin{eqnarray*}
479    \vec{q} & = & \vec{k_\text{f}} - \vec{k_\text{i}} \\
480    \vec{q} & = & \vec{q_\text{per}} + \vec{q_\text{par}} \\
481    \vec{q_\text{per}} & = & \frac{\vec{q} \cdot \vec{n}}{\left|\left|\vec{n}\right|\right|} \frac{\vec{n}}{\left|\left|\vec{n}\right|\right|}
482    \end{eqnarray*}
483 * Diffractometers
484   #+BEGIN_QUOTE
485   *warning*
487   This section is automatically generating by introspecting the hkl library.
488   #+END_QUOTE
490 #+BEGIN_SRC python :exports results :results value raw
491   from gi.repository import Hkl
493   def bold(l):
494       return ["\"*" + _ + "*\"" for _ in l]
496   def level(indent=1, s=None):
497       return "  "*indent + s
499   diffractometers = Hkl.factories().iterkeys()
501   output = ''
502   for diffractometer in sorted(diffractometers):
503       factory = Hkl.factories()[diffractometer]
504       output += "** " + diffractometer + "\n\n"
505       detector = Hkl.Detector.factory_new(Hkl.DetectorType(0))
506       sample = Hkl.Sample.new("toto")
507       geometry = factory.create_new_geometry()
508       engines = factory.create_new_engine_list()
509       engines.init(geometry, detector, sample)
511       output += "*** Axes: \n"
512       for axis in geometry.axis_names_get():
513           axis_v = geometry.axis_get(axis).axis_v_get().data
514           output += level(2, "+ \"*" + axis + "*\": rotation around the *" + repr(axis_v) + "* axis\n")
516       output += "*** Engines: \n"
517       for engine in engines.engines_get():
518           output += "**** \"*" + engine.name_get() + "*\":\n\n"
519           output += level(3, "* pseudo axes:\n")
520           for pseudo in engine.pseudo_axis_names_get():
521               p = engine.pseudo_axis_get(pseudo)
522               description = p.description_get()
523               output += level(4, "* \"*" + pseudo + "*\" : " + description + '\n\n')
524           output += "\n"
525           for mode in engine.modes_names_get():
526               output += level(3, "+ mode: \"*" + mode + "*\"\n")
527               engine.current_mode_set(mode)
528               axes_r = engine.axis_names_get(Hkl.EngineAxisNamesGet.READ)
529               axes_w = engine.axis_names_get(Hkl.EngineAxisNamesGet.WRITE)
530               output += level(4, "+ axes (read) : " + ", ".join(bold(axes_r)) + "\n")
531               output += level(4, "+ axes (write): " + ", ".join(bold(axes_w)) + "\n")
532               parameters = engine.parameters_names_get()
533               output += level(4, "+ parameters: ")
534               if parameters:
535                   output += "\n"
536                   for parameter in parameters:
537                       p = engine.parameter_get(parameter)
538                       description = p.description_get()
539                       value = p.value_get(Hkl.UnitEnum.USER)
540                       output += level(5, "+ *" + parameter + "* [" + str(value) + "]: " + description + "\n")
541               else:
542                   output += "No parameter\n"
544   return output
545 #+END_SRC
546 * Developpement
547 ** Getting hkl
549    To get hkl, you can download the last stable version from sourceforge or
550    if you want the latest development version use
551    [[http://git.or.cz/][git]] or
552    [[http://code.google.com/p/msysgit/downloads/list][msysgit]] on windows
553    system and do:
555    #+BEGIN_SRC sh
556 git clone git://repo.or.cz/hkl.git
557    #+END_SRC
559    or:
561    #+BEGIN_SRC sh
562     git clone http://repo.or.cz/r/hkl.git (slower)
563    #+END_SRC
565    then checkout the next branch like this:
567    #+BEGIN_SRC sh
568     cd hkl
569     git checkout -b next origin/next
570    #+END_SRC
572 ** Building hkl
574    To build hkl you need [[http://www.python.org][Python 2.3+]] the
575    [[http://www.gnu.org/software/gsl/][GNU Scientific Library 1.12]] and
576    [[https://developer.gnome.org/glib/][GLib-2.0 >= 2.3.4]]:
578    #+BEGIN_SRC sh
579     ./configure --disable-gui
580     make
581     sudo make install
582    #+END_SRC
584    you can also build a GUI interfaces which use
585    [[http://www.gtk.org][gtk]]:
587    #+BEGIN_SRC sh
588     ./configure
589     make
590     sudo make install
591    #+END_SRC
593    optionnaly you can build an experimental /libhkl3d/ library (no public
594    API for now) which is used by the GUI to display and compute
595    diffractometer collisions (only the /K6C/ model). To build it you need
596    also [[https://projects.gnome.org/gtkglext/][gtkglext]] and
597    [[http://bulletphysics.org/wordpress/][bullet 2.82]]:
599    #+BEGIN_SRC sh
600     ./configure --enable-hkl3d
601     make
602     sudo make install
603    #+END_SRC
605    if you want to work on the documentation you need the extra
607    - [[http://www.gtk.org/gtk-doc/][gtk-doc]] for the api
608    - [[http://sphinx.pocoo.org/][sphinx]] for the html and latex doc.
609    - [[http://asymptote.sourceforge.net/][asymptote]] for the figures
610    - [[http://www.gnu.org/software/emacs/][emacs]] the well known editor
611    - [[https://github.com/emacsmirror/htmlize][htmlize]] used to highlight the source code
612    - [[http://orgmode.org][org-mode]] litteral programming
614    On Debian/Ubuntu you just need to install
616    #+BEGIN_SRC sh
617     sudo apt-get install emacs dvipng emacs-goodies-el org-mode
618    #+END_SRC
620    #+BEGIN_SRC sh
621     ./configure --enable-gtk-doc
622     make
623     make html
624 #+END_SRC
626    nevertheless if you do not want to build the documentation you can do:
628    #+BEGIN_SRC sh
629    ./configure --disable-hkl-doc
630    #+END_SRC
632 ** Hacking hkl
633 *** Bug reporting
635     You can find the bug tracker here
636     [[https://bugs.debian.org/cgi-bin/pkgreport.cgi?repeatmerged=no&src=hkl][libhkl]]
638 -  Debian/Ubuntu:
640    #+BEGIN_SRC sh
641        reportbug hkl
642    #+END_SRC
644 -  Other OS
646    You just need to send an [[mailto:submit@bugs.debian.org?subject=%20My%20problem%20with%20hkl...&body=Package:%20hkl%0AVersion:%20@VERSION@%0A%0AI%20found%20this%20problem%20in%20hkl][email]]
648 *** Providing patches
650     you can send your patch to [[mailto:picca@synchrotron-soleil.fr][Picca Frédéric-Emmanuel]] using =git=
652     Here a minimalist example of the workflow to prepare and send
653     patches for integration into the hkl library. Suppose you wan to
654     add a new feature, you need first to create a new branch from the
655     =next= one:
657     #+BEGIN_SRC sh
658     git checkout -b my-next next
659     #+END_SRC
661     hack, hack:
663     #+BEGIN_SRC sh
664     git commit -a
665     #+END_SRC
667     more hacks:
669     #+BEGIN_SRC sh
670     git commit -a
671     #+END_SRC
673     now that your new feature is ready, you can send by email your
674     work using =git format-patch= for review:
676     #+BEGIN_SRC sh
677     git format-patch origin/next
678     #+END_SRC
680     which will generate a bunch of ~0001\_xxx~, ~0002\_xxx~,
681     ... patches
683     Then you can configure =git send-email= in order to send the
684     patches for review.
686     #+BEGIN_SRC sh
687     git config sendemail.to "picca@synchrotron-soleil.fr"
688     #+END_SRC
690     and send then with this command:
692     #+BEGIN_SRC sh
693     git send-email 0001-xxx.patch, 0002-xxx.patch, ...
694     #+END_SRC
696     If it does not work you can use your usually email software and
697     send these generated patches to the [[mailto:picca@synchrotron-soleil.fr][author]].
699 ** Howto's
700 *** Add a diffractometer
701     To add a new diffractometer, you just need to copy the
702     ~hkl/hkl-engine-template.c~ into
703     ~hkl/hkl-engine-INSTITUT-BEAMLINE-INSTRUMENT.c~ where you replace
704     the upper case with the appropriate values.
706     The template file is compiled during the build process to ensure
707     that it is always valid.
709     Then you just need to follow the instruction found in the
710     template. If you need some precision about the process, do not
711     hesitate to contact the main author.
713     do not forgot also to add this new file into ~hkl/Makefile.am~
714     with other diffractometers in the hkl_c_sources variable (please
715     keep the alphabetic order).
716 *** Work on the documentation
717     The documentation system is written with [[http://orgmode.org/][org-mode]], and the [[http://orgmode.org/worg/org-contrib/babel/][babel]]
718     extension which allow to introspect the library and generate part
719     of the doc using the hkl library. Python code is executed during
720     the build process to generate the Diffractometer section of the
721     documentation. To work on the doc and test the embedded python
722     code it is necessary to setup a few environment variables and
723     start emacs with the right LD_LIBRARY_PATH. In order to simplify
724     the process a make target was written. You just need to type:
725     #+BEGIN_SRC sh
726       cd Documentation
727       make doc-edit
728     #+END_SRC
729     and start to contribute.
731     If you do not have emacs, you can nevertheless contribute by
732     editing the ~Documentation/hkl.org.in~ file which is text only.
734     The most expected contributions are for now:
735     * english correctness
736     * a nicer css
737 * Bindings
739   The hkl library use the gobject-introspection to provide automatic
740   binding for a few languages.
742 ** Python
744    You can test the binding directly from the source directory with
745    these commandes if ipython is installed.
747     #+BEGIN_SRC sh
748       cd tests/bindings
749       make ipython
750     #+END_SRC
752    then you have the Hkl module preloaded into the ipython environment.
754    hkl computation:
756    has you can see there is 4 available solutions.
758    let's compute an hkl trajectory and select the first solution.
760    if we look at the 3 other solutions we can see that there is a problem
761    of continuity at the begining of the trajectory.
763    hey what's happend with theses solutions ! let's look closely to real
764    numbers. the last column is the distance to the diffractometer current
765    position. This distance is for now express like this:
767    $\sum_{axes} \left|\text{current position} - \text{target position}\right|$
769    #+BEGIN_EXAMPLE
770     [0.0, 119.99999999999999, 0.0, -90.0, 0.0, 59.99999999999999] 0.0
771     [0.0, -119.99999999999999, 0.0, -90.0, 0.0, -59.99999999999999] 6.28318530718
772     [0.0, -60.00000000000005, 0.0, 90.0, 0.0, 59.99999999999999] 6.28318530718
773     [0.0, 60.00000000000001, 0.0, 90.0, 0.0, -59.99999999999999] 6.28318530718
775     [0.0, 117.7665607657826, 7.456826294401656, -92.39856410531434, 0.0, 60.33024982425957] 0.216753826612
776     [0.0, -57.436310940366894, -7.456826294401656, 92.39856418853617, 0.0, 60.33024982425957] 6.41621345188
777     [0.0, 62.2334392342174, -7.456826294401656, 92.39856410531434, 0.0, -60.33024982425957] 6.42197739723
778     [0.0, -122.5636890596331, 7.456826294401656, -92.3985641885362, 0.0, -60.33024982425957] 6.50570308205
780     [0.0, 115.89125602137928, 14.781064139466098, -94.7660423112577, 0.0, 61.314597086440706] 0.219062698235
781     [0.0, -125.42334103772737, 14.781064139466098, -94.7660427050904, 0.0, -61.314597086440706] 6.53671995288
782     [0.0, -54.57665896227262, -14.781064139466098, 94.76604270509038, 0.0, 61.314597086440706] 6.67989976726
783     [0.0, 64.10874397862072, -14.781064139466098, 94.7660423112577, 0.0, -61.314597086440706] 6.71437170098
785     [0.0, 114.39338605351007, 21.85448296702796, -97.074145033719, 0.0, 62.93506298693471] 0.218163667981
786     [0.0, -128.54167683157993, 21.85448296702796, -97.07414574435087, 0.0, -62.93506298693471] 6.59846359365
787     [0.0, -51.45832316842005, -21.85448296702796, 97.07414574435087, 0.0, 62.93506298693471] 6.93673746356
788     [0.0, 65.60661394648993, -21.85448296702796, 97.074145033719, 0.0, -62.93506298693471] 7.03385205725
790     [0.0, 113.28316795475283, 28.583837575232764, -99.29953499008337, 0.0, 65.16540747008955] 0.21459359225
791     [0.0, -131.88223933078322, 28.583837575232764, -99.29953638594702, 0.0, -65.16540747008955] 6.69038531388
792     [0.0, -48.11776066921677, -28.583837575232764, 99.29953638594702, 0.0, 65.16540747008955] 7.18296350386
793     [0.0, 66.71683204524717, -28.583837575232764, 99.29953499008337, 0.0, -65.16540747008955] 7.37556986959
795     [0.0, 112.56286877075006, 34.90573305321372, -101.42496979586187, 0.0, 67.97568017857415] 0.209053830457
796     [0.0, -135.4128111996365, 34.90573305321372, -101.42497263302461, 0.0, -67.97568017857415] 6.81174779784
797     [0.0, -44.58718880036348, -34.90573305321372, 101.4249726330246, 0.0, 67.97568017857415] 7.41581162393
798     [0.0, 67.43713122924994, -34.90573305321372, 101.42496979586187, 0.0, -67.97568017857415] 7.7353201851
800     [0.0, 112.2291126083182, 40.78594007247402, -103.43941832567457, 0.0, 71.33706722449408] 0.202280147961
801     [0.0, -139.10795451001587, 40.78594007247402, -103.43942357602316, 0.0, -71.33706722449408] 6.96173845391
802     [0.0, -40.89204548998411, -40.78594007247402, 103.43942357602312, 0.0, 71.33706722449408] 7.63358787543
803     [0.0, 67.7708873916818, -40.78594007247402, 103.43941832567457, 0.0, -71.33706722449408] 8.10986069093
805     [0.0, 112.27578927291766, 46.214916130901734, -105.33741042812996, 0.0, 75.22640762217479] 0.196576175748
806     [0.0, -142.95061850160724, 46.214916130901734, -105.3374188005596, 0.0, -75.22640762217479] 7.13962155618
807     [0.0, -37.04938149839278, -46.214916130901734, 105.33741880055959, 0.0, 75.22640762217479] 7.83557762281
808     [0.0, 67.72421072708234, -46.214916130901734, 105.33741042812996, 0.0, -75.22640762217479] 8.49706672677
810     [0.0, 112.697137434232, 51.201667684695856, -107.11797492933192, 0.0, 79.63023536264535] 0.202327153157
811     [0.0, -146.9330984641471, 51.201667684695856, -107.11798610058318, 0.0, -79.63023536264535] 7.34491897177
812     [0.0, -33.0669015358529, -51.201667684695856, 107.11798610058317, 0.0, 79.63023536264535] 8.02185610877
813     [0.0, 67.30286256576798, -51.201667684695856, 107.11797492933192, 0.0, -79.63023536264535] 8.89597005568
815     [0.0, 113.49085964586432, 55.76762791023837, -108.78347437395287, 0.0, 84.54867879242364] 0.208455586312
816     [0.0, -151.05782007465257, 55.76762791023837, -108.78348605483542, 0.0, -84.54867879242364] 7.57761473366
817     [0.0, -28.942179925347414, -55.76762791023837, 108.78348605483538, 0.0, 84.54867879242364] 8.19307323084
818     [0.0, 66.50914035413568, -55.76762791023837, 108.78347437395287, 0.0, -84.54867879242364] 9.30675279514
820     [0.0, 114.6614608037443, 59.941489465646214, -110.3385360479293, 0.0, 90.00000081324956] 0.215562935229
821     [0.0, -155.33854118146962, 59.941489465646214, -110.33854432979601, 0.0, -89.99999918675044] 7.83839602383
822     [0.0, -24.661458818530395, -59.941489465646214, 110.33854432979601, 0.0, 90.00000081324956] 8.3502621071
823     [0.0, 65.3385391962557, -59.941489465646214, 110.3385360479293, 0.0, -89.99999918675044] 9.7307712883
824    #+END_EXAMPLE
826    as you can see for the first point of the trajectory, the 2nd, 3rd and
827    4th solutions have identical distances to the current position of the
828    diffractometer so they are un-ordered:
830    #+BEGIN_EXAMPLE
831     [0.0, 119.99999999999999, 0.0, -90.0, 0.0, 59.99999999999999] 0.0
832     [0.0, -119.99999999999999, 0.0, -90.0, 0.0, -59.99999999999999] 6.28318530718
833     [0.0, -60.00000000000005, 0.0, 90.0, 0.0, 59.99999999999999] 6.28318530718
834     [0.0, 60.00000000000001, 0.0, 90.0, 0.0, -59.99999999999999] 6.28318530718
835    #+END_EXAMPLE
837    then the problem arise with the second and third solution. you can see a
838    sort of reorganisation of the solution. 2 -> 3, 3 -> 4 and 4 -> 2 then
839    the order will stick unchanged until the end of the trajectory. this is
840    because the distance is computed relatively to the current position of
841    the diffractometer.:
843    #+BEGIN_EXAMPLE
844     [0.0, 117.7665607657826, 7.456826294401656, -92.39856410531434, 0.0, 60.33024982425957] 0.216753826612
845     [0.0, -57.436310940366894, -7.456826294401656, 92.39856418853617, 0.0, 60.33024982425957] 6.41621345188
846     [0.0, 62.2334392342174, -7.456826294401656, 92.39856410531434, 0.0, -60.33024982425957] 6.42197739723
847     [0.0, -122.5636890596331, 7.456826294401656, -92.3985641885362, 0.0, -60.33024982425957] 6.50570308205
849     [0.0, 115.89125602137928, 14.781064139466098, -94.7660423112577, 0.0, 61.314597086440706] 0.219062698235
850     [0.0, -125.42334103772737, 14.781064139466098, -94.7660427050904, 0.0, -61.314597086440706] 6.53671995288
851     [0.0, -54.57665896227262, -14.781064139466098, 94.76604270509038, 0.0, 61.314597086440706] 6.67989976726
852     [0.0, 64.10874397862072, -14.781064139466098, 94.7660423112577, 0.0, -61.314597086440706] 6.71437170098
853    #+END_EXAMPLE
855    #+BEGIN_QUOTE
856    *warning*
858    when you compute a trajectory, start from a valid position (the
859    starting point must be the real first point of your trajectory) then
860    use only the closest solution for the next points of the trajectory.
861    (first solution of the geometries list)
862    #+END_QUOTE
863 * Releases
864 ** @VERSION@
865 *** DONE Fix for multiarch (headers) <2016-05-04 mer.>
866     The =ccan_config.h= generated file is arch specific. It is then
867     necessary to install this file under /usr/include/<triplet> on
868     Debian like systems. This way it will be possible to co-installa
869     32/64 bit version of hkl, or to do cross-compilation (arm on
870     x86_64, etc...)
871 ** 5.0.0.2080 <2016-04-27 mer.>
872 *** DONE =HklEngine= <2016-01-20 mer.>
873     emergence_fixed for the SOLEIL SIX MED 2+2 geometry.
874 *** DONE =HklVector= <2016-02-09 mar.>
875     The hkl_vector_init method is now public.
876 *** DONE =HklParameter= <2016-02-25 Thu>
877     at the end of the computation all solutions are filtered in order
878     to check that they are valid (min < value < range). BUT for a
879     rotation axis this check was instead (min < value % 2pi < max).
880 *** DONE =HklGeometry= <2016-04-20 mer.>
881     Add hkl_geometry_[sample/detector]_rotation_get method. It is now
882     possible to get the sample or the detector rotation expressed as a
883     =HklQuaternion=.
884 #+BEGIN_SRC python :export code
885   qr = geometry.sample_rotation_get(sample)
886   qd = geometry.detector_rotation_get(detector)
887 #+END_SRC
888 *** DONE =HklQuaternion= <2016-04-20 mer.>
889     Add hkl_quaternion_to_matrix in order to convert a =HklQuaternion=
890     into a =HklMatrix=. Then you just need to convert this HklMatrix
891     into a numpy array when used from the python binding
892 #+BEGIN_SRC python :export code
893   def hkl_matrix_to_numpy(m):
894       M = empty((3, 3))
895       for i in range(3):
896           for j in range(3):
897               M[i, j] = m.get(i, j)
898       return M
901   M = hkl_matrix_to_numpy(q.to_matrix())
902 #+END_SRC
903 *** DONE Soleil Sirius Turret <2016-04-26 mar.>
904     Add the =basepitch= axis which rotate around $\vec{y}$ in mrad.
905 ** 4.99.99.1955 <2015-07-15 mer.>
906    Add the ccan_config.h public header. This header is generated with
907    the ccan configurator program.
908 ** 4.99.99.1950 <2015-07-07 mar.>
909    Fix an FTBFS observed on the sparc arch
910 ** 4.99.99.1949 <2015-07-03 ven.>
911 *** DONE =HklInterval= <2015-07-03 ven.>
912     =hkl_interval_cmp= was wrong. Now the comparison is done between
913     =HKL_EPSILON= and the distance between minimum and maximum. This
914     problem was triggered first on ppc64el architecture.
915 *** DONE PATH_MAX <2015-07-03 ven.>
916     Replace getcwd called by get_current_dir_path instead in order to
917     avoid PATH_MAX which is not available on hurd.
918 ** 4.99.99.1946 <2015-06-30 mar.>
919 *** DONE =HklEngine=
920 **** "emergence" <2015-06-22 lun.>
921      Add a new emergence engine which contain only one pseudo axis.
922      + =emergence= the outgoing beam emergence from the sample's surface.
923      + =azimuth= the sample's surface azimuth.
924 ** 4.99.99.1940 <2015-05-04 lun.>
925 *** DONE =HklLattice= add an =hkl_lattice_volume_get=
926 #+BEGIN_SRC c
927   volume = hkl_lattice_volume_get(lattice);
928 #+END_SRC
929 *** DONE =HklEngine=
930 **** "nrj, sample, ...  dependencies" <2015-03-24 mar.>
931      Add the =hkl_engine_dependencies_get= method which return if the
932      =HklEngine= depends of the axes, the energy, or the sample. the
933      possible values are stored in the =HklEngineDependencies= enum.
935 #+BEGIN_SRC c
936   dependencies = hkl_engine_dependencies_get(engine);
937   if (dependencies & HKL_ENGINE_DEPENDENCIES_ENERGY) {
938           ...
939   }
940   if (dependencies & HKL_ENGINE_DEPENDENCIES_SAMPLE) {
941           ...
942   }
943   ...
944 #+END_SRC
945 **** "tth2" <2015-04-03 ven>
946      Add a new hkl engine which contain two pseudo axes.
947      + =tth=  two times the diffraction angle $\theta$
948      + =alpha= the azimuth of q in the zOy plan.
949 **** "incidence" <2015-04-21 mar.>
950      Add a new incidence engine which contain only one pseudo axis.
951      + =incidence= the incoming beam incidence on the sample surface.
952      + =azimuth= the sample surface azimuth.
953 **** =hkl_engine_parameter_set= <2015-05-04 lun.>
954      Fix a bug and expose the method in the binding.
955 **** general
956      - use #define AXIS "axis_name" in all the code to set the axes
957        names at only one place. <2015-04-23 jeu.>
958 *** DONE =HklLattice= expose in the binding the _x_get/set methods <2015-03-24 mar.>
959     Now you can use hkl_lattice_x_get where x=a, b, c, alpha, beta,
960     gamma in the bindings.
961 #+BEGIN_SRC python :export code
962   a = lattice.a_get()
963   lattice.a_set(a)
964 #+END_SRC
965 *** DONE =HklSampleReflection= expose the flag_get/set and geometry_get/set method <2015-03-24 mar.>
966     It is now possible to change the geometry stored in a reflection
967     via the bindings.
968 #+BEGIN_SRC python :export code
969   flag = reflection.flag_get()
970   reflection.flag_set(flag)
972   geometry = reflection.geometry_get()
973   geometry.axes_values_set([omega, chi, phi, ...])
974   reflection.geometry_set(geometry)
975 #+END_SRC
976 * Todo
977 ** hkl
978 *** TODO [#A] =HklEngine= *q/q2*
979     Fix all these engines... This engine takes into account only the
980     *gamma* and *delta* axes.  so diffractometers with 3 axes for the
981     detector are wrong.  It would be nice to take into account all the
982     detector holder AND the position of the detecteor on the
983     diffractometer arms (for now the detector is always on the last
984     axis).
985 *** TODO [#A] HklSource
986     Create a parameter for the wavelength. This is just internally for
987     the futur trajectory system, so no need to change the signature of
988     hkl_geometry_vawelength get/set
989 *** TODO [#A] SOLEIL SIRIUS KAPPA
990     Investigation of a problem saw on Sirius Kappa geometry. The idea
991     is to compute a trajectory from $[0, 0, 1]$ to $[0, 0, 6]$ on a
992     $GaAs$ sample.
994     #+BEGIN_SRC sh
995       Geometry SOLEIL SIRIUS KAPPA (Source 1.4586370000000007e-9 m) (fromList [-0.5193202,40.795148838481424,134.08834052117254,-55.57809067120416,-2.23369e-2,14.824478553649875]) (Just [Parameter "mu" (-0.5193202) (Range (-180.0) 180.0),Parameter "komega" 40.795148838481424 (Range (-180.0) 180.0),Parameter "kappa" 134.08834052117254 (Range (-180.0) 180.0),Parameter "kphi" (-55.57809067120416) (Range (-180.0) 180.0),Parameter "delta" (-2.23369e-2) (Range (-180.0) 180.0),Parameter "gamma" 14.824478553649875 (Range (-180.0) 180.0)])
996       [Engine "hkl" [Parameter "h" 2.1481674408578524e-8 (Range (-1.0) 1.0),Parameter "k" 6.392014061803081e-8 (Range (-1.0) 1.0),Parameter "l" 1.0000000132413767 (Range (-1.0) 1.0)] (Mode "bissector_vertical" []),Engine "eulerians" [Parameter "omega" 7.412239314132745 (Range (-180.0) 180.0),Parameter "chi" 89.72020738176312 (Range (-180.0) 180.0),Parameter "phi" 91.03899980444716 (Range (-180.0) 180.0)] (Mode "eulerians" [Parameter "solutions" 1.0 (Range 0.0 1.0)]),Engine "psi" [Parameter "psi" 154.5513657893786 (Range (-180.0) 180.0)] (Mode "psi_vertical_soleil_sirius_kappa" [Parameter "h2" 1.0 (Range (-1.0) 1.0),Parameter "k2" 1.0 (Range (-1.0) 1.0),Parameter "l2" 1.0 (Range (-1.0) 1.0)]),Engine "q2" [Parameter "q" 1.1114190632688228 (Range 0.0 1.0),Parameter "alpha" 89.91560430137815 (Range (-180.0) 180.0)] (Mode "q2" []),Engine "qper_qpar" [Parameter "qper" 1.1114162413072137 (Range (-1.0) 1.0),Parameter "qpar" 2.5045470426602284e-3 (Range (-1.0) 1.0)] (Mode "qper_qpar" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "tth2" [Parameter "tth" 14.824495004588014 (Range (-180.0) 180.0),Parameter "alpha" 89.91560430137815 (Range (-180.0) 180.0)] (Mode "tth2" []),Engine "incidence" [Parameter "incidence" 7.414401593159588 (Range (-180.0) 180.0),Parameter "azimuth" 89.78541978058817 (Range (-180.0) 180.0)] (Mode "incidence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "emergence" [Parameter "emergence" 7.410055570443473 (Range (-180.0) 180.0),Parameter "azimuth" 89.78541978058817 (Range (-180.0) 180.0)] (Mode "emergence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)])]
997       Geometry SOLEIL SIRIUS KAPPA (Source 1.4586370000000007e-9 m) (fromList [-0.5193202,47.97247473743512,134.654265266118,124.92415016158583,-2.23369e-2,29.904632884360968]) (Just [Parameter "mu" (-0.5193202) (Range (-180.0) 180.0),Parameter "komega" 47.97247473743512 (Range (-180.0) 180.0),Parameter "kappa" 134.654265266118 (Range (-180.0) 180.0),Parameter "kphi" 124.92415016158583 (Range (-180.0) 180.0),Parameter "delta" (-2.23369e-2) (Range (-180.0) 180.0),Parameter "gamma" 29.904632884360968 (Range (-180.0) 180.0)])
998       [Engine "hkl" [Parameter "h" (-1.3839931497468412e-9) (Range (-1.0) 1.0),Parameter "k" (-4.913404854447784e-10) (Range (-1.0) 1.0),Parameter "l" 2.000000003360829 (Range (-1.0) 1.0)] (Mode "bissector_vertical" []),Engine "eulerians" [Parameter "omega" 14.95231642186499 (Range (-180.0) 180.0),Parameter "chi" 89.9575990161042 (Range (-180.0) 180.0),Parameter "phi" 271.9039918460157 (Range (-180.0) 180.0)] (Mode "eulerians" [Parameter "solutions" 1.0 (Range 0.0 1.0)]),Engine "psi" [Parameter "psi" (-26.325999847139332) (Range (-180.0) 180.0)] (Mode "psi_vertical_soleil_sirius_kappa" [Parameter "h2" 1.0 (Range (-1.0) 1.0),Parameter "k2" 1.0 (Range (-1.0) 1.0),Parameter "l2" 1.0 (Range (-1.0) 1.0)]),Engine "q2" [Parameter "q" 2.2228381008394895 (Range 0.0 1.0),Parameter "alpha" 89.96116221471468 (Range (-180.0) 180.0)] (Mode "q2" []),Engine "qper_qpar" [Parameter "qper" 2.222832456913507 (Range (-1.0) 1.0),Parameter "qpar" (-5.009095284686147e-3) (Range (-1.0) 1.0)] (Mode "qper_qpar" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "tth2" [Parameter "tth" 29.90464045486422 (Range (-180.0) 180.0),Parameter "alpha" 89.96116221471468 (Range (-180.0) 180.0)] (Mode "tth2" []),Engine "incidence" [Parameter "incidence" 14.952081490954424 (Range (-180.0) 180.0),Parameter "azimuth" 90.09480115642252 (Range (-180.0) 180.0)] (Mode "incidence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "emergence" [Parameter "emergence" 14.952481262345229 (Range (-180.0) 180.0),Parameter "azimuth" 90.09480115642252 (Range (-180.0) 180.0)] (Mode "emergence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)])]
999       Geometry SOLEIL SIRIUS KAPPA (Source 1.4586370000000007e-9 m) (fromList [-0.5193202,56.25907471532187,133.92128004831832,-55.45556970293517,-2.23369e-2,45.53873596992208]) (Just [Parameter "mu" (-0.5193202) (Range (-180.0) 180.0),Parameter "komega" 56.25907471532187 (Range (-180.0) 180.0),Parameter "kappa" 133.92128004831832 (Range (-180.0) 180.0),Parameter "kphi" (-55.45556970293517) (Range (-180.0) 180.0),Parameter "delta" (-2.23369e-2) (Range (-180.0) 180.0),Parameter "gamma" 45.53873596992208 (Range (-180.0) 180.0)])
1000       [Engine "hkl" [Parameter "h" 8.37724528421826e-9 (Range (-1.0) 1.0),Parameter "k" 2.018612859089285e-8 (Range (-1.0) 1.0),Parameter "l" 2.999999983141756 (Range (-1.0) 1.0)] (Mode "bissector_vertical" []),Engine "eulerians" [Parameter "omega" 22.76936798418434 (Range (-180.0) 180.0),Parameter "chi" 89.64969149765572 (Range (-180.0) 180.0),Parameter "phi" 91.0547235659273 (Range (-180.0) 180.0)] (Mode "eulerians" [Parameter "solutions" 1.0 (Range 0.0 1.0)]),Engine "psi" [Parameter "psi" 154.50191592522592 (Range (-180.0) 180.0)] (Mode "psi_vertical_soleil_sirius_kappa" [Parameter "h2" 1.0 (Range (-1.0) 1.0),Parameter "k2" 1.0 (Range (-1.0) 1.0),Parameter "l2" 1.0 (Range (-1.0) 1.0)]),Engine "q2" [Parameter "q" 3.334257126919726 (Range 0.0 1.0),Parameter "alpha" 89.97807925598289 (Range (-180.0) 180.0)] (Mode "q2" []),Engine "qper_qpar" [Parameter "qper" 3.334248661038927 (Range (-1.0) 1.0),Parameter "qpar" 7.513639271725189e-3 (Range (-1.0) 1.0)] (Mode "qper_qpar" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "tth2" [Parameter "tth" 45.53874024285007 (Range (-180.0) 180.0),Parameter "alpha" 89.97807925598289 (Range (-180.0) 180.0)] (Mode "tth2" []),Engine "incidence" [Parameter "incidence" 22.771374111123095 (Range (-180.0) 180.0),Parameter "azimuth" 89.8380685773065 (Range (-180.0) 180.0)] (Mode "incidence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "emergence" [Parameter "emergence" 22.767244039797937 (Range (-180.0) 180.0),Parameter "azimuth" 89.8380685773065 (Range (-180.0) 180.0)] (Mode "emergence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)])]
1001       Geometry SOLEIL SIRIUS KAPPA (Source 1.4586370000000007e-9 m) (fromList [-0.5193202,64.64191214924969,133.78682078017752,-55.41938838621407,-2.23369e-2,62.132688461209455]) (Just [Parameter "mu" (-0.5193202) (Range (-180.0) 180.0),Parameter "komega" 64.64191214924969 (Range (-180.0) 180.0),Parameter "kappa" 133.78682078017752 (Range (-180.0) 180.0),Parameter "kphi" (-55.41938838621407) (Range (-180.0) 180.0),Parameter "delta" (-2.23369e-2) (Range (-180.0) 180.0),Parameter "gamma" 62.132688461209455 (Range (-180.0) 180.0)])
1002       [Engine "hkl" [Parameter "h" 9.177457430250849e-9 (Range (-1.0) 1.0),Parameter "k" 2.5693823994163015e-8 (Range (-1.0) 1.0),Parameter "l" 3.9999999929703476 (Range (-1.0) 1.0)] (Mode "bissector_vertical" []),Engine "eulerians" [Parameter "omega" 31.06634423136446 (Range (-180.0) 180.0),Parameter "chi" 89.5927920859556 (Range (-180.0) 180.0),Parameter "phi" 91.00504369590071 (Range (-180.0) 180.0)] (Mode "eulerians" [Parameter "solutions" 1.0 (Range 0.0 1.0)]),Engine "psi" [Parameter "psi" 154.51996903181714 (Range (-180.0) 180.0)] (Mode "psi_vertical_soleil_sirius_kappa" [Parameter "h2" 1.0 (Range (-1.0) 1.0),Parameter "k2" 1.0 (Range (-1.0) 1.0),Parameter "l2" 1.0 (Range (-1.0) 1.0)]),Engine "q2" [Parameter "q" 4.44567618639551 (Range 0.0 1.0),Parameter "alpha" 89.9881895320358 (Range (-180.0) 180.0)] (Mode "q2" []),Engine "qper_qpar" [Parameter "qper" 4.445664898550648 (Range (-1.0) 1.0),Parameter "qpar" 1.0018187400499787e-2 (Range (-1.0) 1.0)] (Mode "qper_qpar" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "tth2" [Parameter "tth" 62.13269076337942 (Range (-180.0) 180.0),Parameter "alpha" 89.9881895320358 (Range (-180.0) 180.0)] (Mode "tth2" []),Engine "incidence" [Parameter "incidence" 31.068363501362125 (Range (-180.0) 180.0),Parameter "azimuth" 89.83747231179481 (Range (-180.0) 180.0)] (Mode "incidence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "emergence" [Parameter "emergence" 31.064152026450454 (Range (-180.0) 180.0),Parameter "azimuth" 89.83747231179481 (Range (-180.0) 180.0)] (Mode "emergence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)])]
1003       Geometry SOLEIL SIRIUS KAPPA (Source 1.4586370000000007e-9 m) (fromList [-0.5193202,73.83399863752925,133.64586701159254,-55.35712475482595,-2.23369e-2,80.33702663350934]) (Just [Parameter "mu" (-0.5193202) (Range (-180.0) 180.0),Parameter "komega" 73.83399863752925 (Range (-180.0) 180.0),Parameter "kappa" 133.64586701159254 (Range (-180.0) 180.0),Parameter "kphi" (-55.35712475482595) (Range (-180.0) 180.0),Parameter "delta" (-2.23369e-2) (Range (-180.0) 180.0),Parameter "gamma" 80.33702663350934 (Range (-180.0) 180.0)])
1004       [Engine "hkl" [Parameter "h" 2.7577312257761425e-9 (Range (-1.0) 1.0),Parameter "k" 7.650403950118726e-9 (Range (-1.0) 1.0),Parameter "l" 4.999999999622215 (Range (-1.0) 1.0)] (Mode "bissector_vertical" []),Engine "eulerians" [Parameter "omega" 40.168513316578995 (Range (-180.0) 180.0),Parameter "chi" 89.53300638651663 (Range (-180.0) 180.0),Parameter "phi" 90.9773899242238 (Range (-180.0) 180.0)] (Mode "eulerians" [Parameter "solutions" 1.0 (Range 0.0 1.0)]),Engine "psi" [Parameter "psi" 154.50326819560394 (Range (-180.0) 180.0)] (Mode "psi_vertical_soleil_sirius_kappa" [Parameter "h2" 1.0 (Range (-1.0) 1.0),Parameter "k2" 1.0 (Range (-1.0) 1.0),Parameter "l2" 1.0 (Range (-1.0) 1.0)]),Engine "q2" [Parameter "q" 5.557095242340622 (Range 0.0 1.0),Parameter "alpha" 89.99619673890915 (Range (-180.0) 180.0)] (Mode "q2" []),Engine "qper_qpar" [Parameter "qper" 5.557081132533362 (Range (-1.0) 1.0),Parameter "qpar" 1.2522734784728349e-2 (Range (-1.0) 1.0)] (Mode "qper_qpar" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "tth2" [Parameter "tth" 80.33702737486469 (Range (-180.0) 180.0),Parameter "alpha" 89.99619673890915 (Range (-180.0) 180.0)] (Mode "tth2" []),Engine "incidence" [Parameter "incidence" 40.17045932119529 (Range (-180.0) 180.0),Parameter "azimuth" 89.82724901343079 (Range (-180.0) 180.0)] (Mode "incidence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "emergence" [Parameter "emergence" 40.16632251480728 (Range (-180.0) 180.0),Parameter "azimuth" 89.82724901343079 (Range (-180.0) 180.0)] (Mode "emergence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)])]
1005       Geometry SOLEIL SIRIUS KAPPA (Source 1.4586370000000007e-9 m) (fromList [-0.5193202,84.086619565407,134.11156620489382,125.37371040144704,-2.23369e-2,101.43713587367031]) (Just [Parameter "mu" (-0.5193202) (Range (-180.0) 180.0),Parameter "komega" 84.086619565407 (Range (-180.0) 180.0),Parameter "kappa" 134.11156620489382 (Range (-180.0) 180.0),Parameter "kphi" 125.37371040144704 (Range (-180.0) 180.0),Parameter "delta" (-2.23369e-2) (Range (-180.0) 180.0),Parameter "gamma" 101.43713587367031 (Range (-180.0) 180.0)])
1006       [Engine "hkl" [Parameter "h" 8.392762843275724e-10 (Range (-1.0) 1.0),Parameter "k" 2.459154264227675e-9 (Range (-1.0) 1.0),Parameter "l" 6.0000000015375905 (Range (-1.0) 1.0)] (Mode "bissector_vertical" []),Engine "eulerians" [Parameter "omega" 50.718567936651276 (Range (-180.0) 180.0),Parameter "chi" 89.72999512595882 (Range (-180.0) 180.0),Parameter "phi" 272.0056587726913 (Range (-180.0) 180.0)] (Mode "eulerians" [Parameter "solutions" 1.0 (Range 0.0 1.0)]),Engine "psi" [Parameter "psi" (-26.58708882570157) (Range (-180.0) 180.0)] (Mode "psi_vertical_soleil_sirius_kappa" [Parameter "h2" 1.0 (Range (-1.0) 1.0),Parameter "k2" 1.0 (Range (-1.0) 1.0),Parameter "l2" 1.0 (Range (-1.0) 1.0)]),Engine "q2" [Parameter "q" 6.668514293021504 (Range 0.0 1.0),Parameter "alpha" 90.00451897705055 (Range (-180.0) 180.0)] (Mode "q2" []),Engine "qper_qpar" [Parameter "qper" 6.6684973612522915 (Range (-1.0) 1.0),Parameter "qpar" (-1.5027281967821613e-2) (Range (-1.0) 1.0)] (Mode "qper_qpar" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "tth2" [Parameter "tth" 101.43713499280318 (Range (-180.0) 180.0),Parameter "alpha" 90.00451897705055 (Range (-180.0) 180.0)] (Mode "tth2" []),Engine "incidence" [Parameter "incidence" 50.71877816056822 (Range (-180.0) 180.0),Parameter "azimuth" 90.20844936572345 (Range (-180.0) 180.0)] (Mode "incidence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)]),Engine "emergence" [Parameter "emergence" 50.71800112341318 (Range (-180.0) 180.0),Parameter "azimuth" 90.20844936572345 (Range (-180.0) 180.0)] (Mode "emergence" [Parameter "x" 0.0 (Range (-1.0) 1.0),Parameter "y" 1.0 (Range (-1.0) 1.0),Parameter "z" 0.0 (Range (-1.0) 1.0)])
1007     #+END_SRC
1009     As we can see the phi and kphi motor switch from time to time to
1010     another solution which is at around 180° of the other solutions.
1012    #+CAPTION: plot the [0,0,1] -> [0,0,6] trajectory from two different starting point and different step size
1013     [[./figures/sirius-s.svg]]
1015    #+CAPTION: plot the [0,0,1] -> [0,0,6] trajectory from two different starting point and different step size
1016     [[./figures/sirius-m.svg]]
1018 *** TODO [0/2] PetraIII
1019 **** TODO computation problem
1020      Dear Teresa,
1022      Using the prruptest.txt ubmatrix I see that the value of psi is
1023      offset by 45 degrees. I expect it to be 0 degrees when azimuth
1024      reference vector is 0 0 1 that is along the beam. See below
1025      thereturned numbers. This might have to do with the definition of
1026      the beam axis in the controller.  Otherwise now when I change
1027      reference vector by 90 degrees the computed value is changed by
1028      90 degrees. That is a progress. Can you contact Frederic and ask
1029      him about this ?
1031      Best regards,
1033      Sonia
1035      See below
1036      p09/door/haspp09.01 [9]: setaz 1 0 0
1038      p09/door/haspp09.01 [10]: wh
1040      Engine: hkl
1042      Mode: psi_constant_vertical
1044      H K L =    0.00000   3.00605  -0.00000
1045      Ref   =    1.00000   0.00000   0.00000
1046      Azimuth (Psi - calculated) =  -45.00005
1047      Azimuth (Psi - set) =  0.00000
1048      Wavelength =  2.07957
1050      Delta       Theta          Chi         Phi         Mu       Gamma
1051      45.77575    22.88783     90.00000   182.85400    0.00000    -0.00000
1053      p09/door/haspp09.01 [11]: setaz 0 0 1
1055      p09/door/haspp09.01 [12]: wh
1057      Engine: hkl
1059      Mode: psi_constant_vertical
1061      H K L =    0.00000   3.00605  -0.00000
1062      Ref   =    0.00000   0.00000   1.00000
1063      Azimuth (Psi - calculated) =  -135.00005
1064      Azimuth (Psi - set) =  0.00000
1065      Wavelength =  2.07957
1067      Delta       Theta          Chi         Phi         Mu       Gamma
1068      45.77575    22.88783     90.00000   182.85400    0.00000    -0.00000
1070      where:
1072      Azimuth (Psi - calculated) is the value of the pseudomotor psi.
1073      Azimuth (Psi - set) is the value set in the parameter psi of the current mode.
1075    Hi Frederic,
1077    This is the UB matrix:
1079    Best regards,
1081    Sonia
1083    Created at 2015-01-21 12:35
1085    Crystal    prruptest
1087    Wavelength 2.07957463938
1089    A 8.03656 B 8.03656 C 8.03656
1090    Alpha 90.0 Beta 90.0 Gamma 90.0
1092    R0 0 0.0 1.0 0.0 0 1 0.0 14.8979 90.0 182.854 0.0 29.7959
1093    R1 1 1.0 0.0 1.0 0 1 0.0 14.8979 0.0 182.854 0.0 29.7959
1095    Mode psi_constant_vertical
1097    PsiRef 0.0 0.0 1.0
1099    U00 -0.580 U01 0.000 U02 0.525
1100    U10 0.000 U11 0.782 U12 -0.000
1101    U20 -0.525 U21 -0.000 U22 -0.580
1103    Ux 179.999952315 Uy 42.14605 Uz -179.999932647
1105    SaveDirectory /home/p09user/crystals/
1107 **** TODO another question
1108      J'ai un probleme avec la position que le controlleur calcule avec la
1109      matrice UB que nous t'avons envoye.
1110      See sequence of emails echanges avec Teresa.
1112      >>>> I am at 0 3.00605 0 with phi -182 and psi calculated is -135
1113      >>>> When I freeze psi at -135  and type ca 0 3.00605 0 the controller
1114      >> should return to me the positions at which I am. But no he tells me
1115      that I
1116      >> have to go to 178 degrees in  phi that is turning by 360 degrees.
1118      Est-ce un probleme avec la trajectoire selectionnee ?
1119      Est-ce qu'il est possible de definir des cut-points comme dans spec avec
1120      ta librairie ?
1121 *** TODO [2/4] HklParameter
1122     - [X] method to use min/max to check for the validity
1123     - [X] add a method to get the axis_v and quaternion of the HklAxis
1124       this method will return NULL if this is not relevant.
1125       hkl_parameter_axis_v_get and hkl_parameter_quaternion_get
1126     - [ ] degenerated an axis is degenerated if its position have no
1127       effect on the HklPseudoAxis calculus. Add a degenerated member
1128       to the axis. that way it would be possible to check a posteriori
1129       for this degenerescencence.
1130     - [ ] Add a description for each parameters.
1131 *** TODO This will help for the documentation and the gui.
1132 *** TODO HklGeometryList different method to help select a solution.
1133     this select solution can depend on the geometry
1134     for example the kappa axis must be in one side of the plane.
1135 *** TODO add a fit on the Hklaxis offsets.
1136 *** TODO API to put a detector and a sample on the Geometry.
1137 *** TODO HklSample
1138 **** TODO [#B] unit test: hkl_sample_affine.
1139      Check this:
1140      lattice=1.540000;1.540000;1.540000;90.000000;90.000000;90.000000;0;0;0;0;0;0
1141      uxuyuz=0.000000;0.000000;0.000000
1142      reflection=1.540000;0.159010;1.256718;0.796660;1;0.000000;0.000000;0.000000;0.000000;0.000000
1143      reflection=1.540000;0.206208;0.342357;-0.080346;1;0.000000;0.000000;0.000000;0.000000;0.000000
1144      reflection=1.540000;0.206208;0.342357;-0.080346;1;0.000000;0.000000;0.000000;0.000000;0.000000
1146      A,  B, C, Alpha,  Beta, Gamma, Ux, Uy, Uy:
1147      17764892.133, 5793679.092, 15733785.198,  179.997,  179.999,452408725.23,  -575727594.04,  -1913661011.01 (affine) 1rst finetness
1149      all the reflections are non collinear the affine method should
1150      warn the user about this.
1151 *** TODO HklEngine "zone"
1152 *** TODO HklEngine "custom"
1153     for now this pseudoaxis let you select the axis you
1154     want to use for the computation.
1155 *** TODO HklEngine "q/q2" add a "reflectivity" mode
1156     This mode should have the surface as parameters and the incident
1157     angle is equal to the emergence angle.
1158 *** TODO create a macro to help compare two real the right way
1159     fabs(a-b) < epsilon * max(1, abs(a), abs(b))
1160 *** TODO add an hkl_sample_set_lattice_unit()
1161 *** TODO SOLEIL SIXS
1162 **** DONE find the right solutions.                                   :zaxis:
1163      The cosinus and sinus properties are not enough to find the solution expected by the users.
1164      The idea is to use the Ewalds construction to generate a valid solution from the first one
1165      obtain numerically. The basic idea is to rotate the hkl vector around the last axis of the
1166      sample holder until it intersect again the Ewalds sphere. Then we just need to fit the
1167      detector position. This way the solution can be entirely generic (not geometry specific).
1168      Nevertheless it is necessary to propose this only for the hkl pseudo axes. I will add this
1169      special feature in the Mode. So it will be possible to add thoses special cases easily.
1170 **** TODO Add the DEP diffractometer geometry
1171      This diffractometer is a Newport one based on the kappa 6 circles ones.
1172      But instead of a kappa head, they use an Hexapod head.
1173      This head can be put horizontally or vertically.
1174 *** TODO generalisation of the z-axis hkl solver
1175     first we need the degenerated member of the Axis. thaht way it could be possible
1176     to find the last non degenerated axis for the detector fit.
1177 *** TODO investigate the prigo geometry.
1178 *** TODO augeas/elektra for the plugin configure part.
1179 *** TODO logging
1180 **** TODO [1/2] add in a few methods.
1181      + [X] hkl_pseudo_axes_values_set
1182      + [ ] hkl_sample_affine
1183 **** TODO gir logging
1184      It would be nice to generate the library logging using the .gir
1185      information. So instead of writing the logging code for each
1186      method, it would be better to have a generic method for this
1187      purpose.
1188 **** TODO parsable logging information.
1189      A parsable logging format would help to setup some re-play unit
1190      test. This way it could help during the developpement process
1191      (modification of the hkl internals) to be confident that
1192      computation are ok.
1193 *** TODO performances
1194     + Investigate [[http://liboil.freedesktop.org/wiki/][liboil]] to speed calculation (in HklVector, HklMatrix
1195       and HklQuaternion)
1196     + Avoid to call =hkl_engine_prepare_internal= at each computation.
1198 ** documentation
1199 *** TODO [1/6] rewrite documentation in org-mode
1200     - [-] embedding code into the org file
1201       - [-] [1/4] python
1202         - [X] auto generation of the diffractometer descriptions
1203         - [ ] trajectories explanations
1204         - [ ] trajectories tests.
1205         - [ ] unit tests output ?
1206       - [ ] asymptote
1207     - [X] need to check if templates could be generated using the hkl
1208       python binding for all diffractometer geometries.
1209     - [ ] need to add a description for the diffractometer, the mode, the parameters.
1210     - [ ] need a nice css for the generated doc.
1211     - [ ] check if org-info.js could be usefull
1212     - [ ] add documentation explaining the sector-cuts a la hkl
1213 ** [0/3] gui
1214    - [ ] change the color of fitparameter cells if they differ from
1215      the current sample values
1216    - [ ] check if a [[https://github.com/jonathanslenders/python-prompt-toolkit/tree/master/examples/tutorial][REPL]] could be integrated to provide an autocad
1217       like interface.
1218    - [ ] add tooltips using hkl_parameter_description_get for the
1219      pseudo axes and the mode parameters.
1220 ** hkl3d
1221 *** TODO add a method to find the 3D models in the right directories.
1223 ** packaging
1224 *** TODO add a .spec file for rpm generation.