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