[doc] better TODO for the documentation
[hkl.git] / Documentation / hkl.org.in
blob05bed8cf48d1ab77eacf8eced9b7e8d39e4cf282
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 #+OPTIONS: tex:dvipng
7 * Introduction
8   The purpose of the library is to factorise single crystal
9   diffraction angles computation for different kind of diffractometer
10   geometries. It is used at the SOLEIL, Desy and Alba synchrotron with
11   the Tango control system to pilot diffractometers.
12 ** Features
13    - mode computation (aka PseudoAxis)
14    - item for different diffractometer geometries.
15    - UB matrix computation.
16      - busing & Levy with 2 reflections
17      - simplex computation with more than 2 reflections using the GSL
18        library.
19      - Eulerians angles to pre-orientate your sample.
20    - Crystal lattice affinement
21      - with more than 2 reflections you can select which parameter must
22        be fitted.
23    - Pseudoaxes
24      - psi, eulerians, q, ...
25 ** Conventions
26    In all this document the next convention will be used to describe
27    the diffractometers geometries.
28    - right handed convention for all the angles.
29    - direct space orthogonal base.
30    - description of the diffractometer geometries is done with all
31      axes values set to zero.
32 ** Diffraction
33 *** the crystal
35     A periodic crystal is the association of a pattern and a lattice. The
36     pattern is located at each points of the lattice node. Positions of
37     those nodes are given by:
39     \begin{displaymath}
40     R_{uvw}=u\cdot\vec{a}+v\cdot\vec{b}+w\cdot\vec{c}
41     \end{displaymath}
43     $\vec{a}$, $\vec{b}$, $\vec{c}$ are the former vector of a base of the
44     space. =u=, =v=, =w= are integrers. The pattern contain atomes
45     associated to each lattice node. the purpose of diffraction is to study
46     the interaction of this crystal (pattern+lattice) with X-rays.
48     #+CAPTION: Crystal direct lattice.
49     [[./figures/crystal.png]]
51     this lattice is defined by $\vec{a}$, $\vec{b}$, $\vec{c}$ vectors, and
52     the angles $\alpha$, $\beta$, $\gamma$. In general cases this lattice is
53     not othonormal.
55     Nevertheless to compute the interaction of this real space lattice and
56     the X-Rays, it is convenient to define another lattice called reciprocal
57     lattice defined like this:
59     \begin{eqnarray*}
60     \vec{a}^{\star} & = & \tau\frac{\vec{b}\wedge\vec{c}}{\vec{a}\cdot(\vec{b}\wedge\vec{c})}\\
61     \vec{b}^{\star} & = & \tau\frac{\vec{c}\wedge\vec{a}}{\vec{b}\cdot(\vec{c}\wedge\vec{a})}\\
62     \vec{c}^{\star} & = & \tau\frac{\vec{a}\wedge\vec{b}}{\vec{c}\cdot(\vec{a}\wedge\vec{b})}
63     \end{eqnarray*}
65     $\tau=2\pi$ or $\tau=1$ depending on the conventions.
67     It is then possible to define thoses orthogonal properties:
69     \begin{eqnarray*}
70     \vec{a}^{\star}\cdot\vec{a}=\tau & \vec{b}^{\star}\cdot\vec{a}=0    & \vec{c}^{\star}\cdot\vec{a}=0\\
71     \vec{a}^{\star}\cdot\vec{b}=0    & \vec{b}^{\star}\cdot\vec{b}=\tau & \vec{c}^{\star}\cdot\vec{b}=0\\
72     \vec{a}^{\star}\cdot\vec{c}=0    & \vec{b}^{\star}\cdot\vec{c}=0    & \vec{c}^{\star}\cdot\vec{c}=\tau
73     \end{eqnarray*}
75     This reciprocal space lattice allow to write in a simpler form the
76     interaction between the crystal and the X-Rays. We often only know about
77     $\vec{a}$, $\vec{b}$, $\vec{c}$ vectors and the angles $\alpha$,
78     $\beta$, $\gamma$. Using the previous equations reciprocal, we can
79     compute the reciprocal lattice this way:
82     \begin{eqnarray*}
83     a^{\star} & = & \frac{\sin\alpha}{aD}\\
84     b^{\star} & = & \frac{\sin\beta}{bD}\\
85     c^{\star} & = & \frac{\sin\gamma}{cD}
86     \end{eqnarray*}
88     where
90     \begin{displaymath}
91     D=\sqrt{1-\cos^{2}\alpha-\cos^{2}\beta-\cos^{2}\gamma+2\cos\alpha\cos\beta\cos\gamma}
92     \end{displaymath}
94     To compute the angles between the reciprocal space vectors, it is once
95     again possible to use the previous equations reciprocal to obtain the
96     sinus and cosinus of the angles $\alpha^\star$, $\beta^\star$ et
97     $\gamma^\star$:
99     \begin{eqnarray*}
100     \cos\alpha^{\star}=\frac{\cos\beta\cos\gamma-\cos\alpha}{\sin\beta\sin\gamma} & \, & \sin\alpha^{\star}=\frac{D}{\sin\beta\sin\gamma} \\
101     \cos\beta^{\star}=\frac{\cos\gamma\cos\alpha-\cos\beta}{\sin\gamma\sin\alpha} & \, & \sin\beta^{\star}=\frac{D}{\sin\gamma\sin\alpha}\\
102     \cos\gamma^{\star}=\frac{\cos\alpha\cos\beta-\cos\gamma}{\sin\alpha\sin\beta} & \, & \sin\gamma^{\star}=\frac{D}{\sin\alpha\sin\beta}
103     \end{eqnarray*}
105 *** Diffraction
107     Let the incomming X-rays beam whose wave vector is $\vec{k_{i}}$,
108     $|k_{i}|=\tau/\lambda$ where $\lambda$ is the wavelength of the signal.
109     The $\vec{k_{d}}$ vector wavelength of the diffracted beam. There is
110     diffusion if the diffusion vector $\vec{q}$ can be expressed as follows:
112     \begin{displaymath}
113     \vec{q}=\vec{k_{d}}-\vec{k_{i}}=h.\vec{a}^{*}+k.\vec{b}^{*}+l.\vec{c}^{*}
114     \end{displaymath}
116     where $(h,k,l)\in\mathbb{N}^{3}$ and $(h,k,l)\neq(0,0,0)$. Thoses
117     indices $(h,k,l)$ are named Miller indices.
119     Another way of looking at things has been given by Bragg and that famous
120     relationship:
122     \begin{displaymath}
123     n\lambda=2d\sin\theta
124     \end{displaymath}
126     where $d$ is the inter-plan distance and $n \in \mathbb{N}$.
128     The diffusion accure for a unique $\theta$ angle. Then we got $\vec{q}$
129     perpendicular to the diffraction plan.
131     The Ewald construction allow to represent this diffraction in the
132     reciprocal space.
134 *** Quaternions
135 **** Properties
137      The quaternions will be used to discribe the diffractometers geometries.
138      Thoses quaternions can represent 3D rotations. There is different way to
139      describe then like complex numbers.
141      \begin{displaymath}
142      q=a+bi+cj+dk
143      \end{displaymath}
145      or
147      \begin{displaymath}
148      q=[a,\vec{v}]
149      \end{displaymath}
151      To compute the quaternion's norm, we can proceed like for complex
152      numbers
154      \begin{displaymath}
155      \lvert q \rvert = \sqrt{a{{}^2}+b{{}^2}+c{{}^2}+d{{}^2}}
156      \end{displaymath}
158      Its conjugate is :
160      \begin{displaymath}
161      q^{*}=[a,-\vec{u}]=a-bi-cj-dk
162      \end{displaymath}
164 **** Operations
166      The difference with the complexnumber algebre is about
167      non-commutativity.
169      \begin{displaymath}
170      qp \neq pq
171      \end{displaymath}
173      \begin{displaymath}
174      \bordermatrix{
175      ~ & 1 & i  & j  & k \cr
176      1 & 1 & i  & j  & k \cr
177      i & i & -1 & k  & -j \cr
178      j & j & -k & -1 & i \cr
179      k & k & j  & -i & -1
180      }
181      \end{displaymath}
183      The product of two quaternions can be express by the Grassman product
184      Grassman product. So for two quaternions $p$ and $q$:
186      \begin{align*}
187      q &= a+\vec{u} = a+bi+cj+dk\\
188      p &= t+\vec{v} = t+xi+yj+zk
189      \end{align*}
191      we got
193      \begin{displaymath}
194      pq = at - \vec{u} \cdot \vec{v} + a \vec{v} + t \vec{u} + \vec{v} \times \vec{u}
195      \end{displaymath}
197      or equivalent
199      \begin{displaymath}
200      pq = (at - bx - cy - dz) + (bt + ax + cz - dy) i + (ct + ay + dx - bz) j + (dt + az + by - cx) k
201      \end{displaymath}
203 **** 3D rotations
205      L'ensemble des quaternions unitaires (leur norme est égale à 1) est le
206      groupe qui représente les rotations dans l'espace 3D. Si on a un vecteur
207      unitaire $\vec{u}$ et un angle de rotation $\theta$ alors le quaternion
208      $[\cos\frac{\theta}{2},\sin\frac{\theta}{2}\vec{u]}$ représente la
209      rotation de $\theta$ autour de l'axe $\vec{u}$ dans le sens
210      trigonométrique. Nous allons donc utiliser ces quaternions unitaires
211      pour représenter les mouvements du diffractomètre.
213      Alors que dans le plan 2D une simple multiplication entre un nombre
214      complex et le nombre $e^{i\theta}$ permet de calculer simplement la
215      rotation d'angle $\theta$ autour de l'origine, dans l'espace 3D
216      l'expression équivalente est:
218      \begin{displaymath}
219      z'=qzq^{-1}
220      \end{displaymath}
222      où $q$ est le quaternion de norme 1 représentant la rotation dans
223      l'espace et $z$ le quaternion représentant le vecteur qui subit la
224      rotation (sa partie réelle est nulle).
226      Dans le cas des quaternions de norme 1, il est très facile de calculer
227      $q^{-1}$. En effet l'inverse d'une rotation d'angle $\theta$ est la
228      rotation d'angle $-\theta$. On a donc directement:
230      \begin{displaymath}
231      q^{-1}=[\cos\frac{-\theta}{2},\sin\frac{-\theta}{2}\vec{u}]=[\cos\frac{\theta}{2},-\sin\frac{\theta}{2}\vec{u}]=q^{*}
232      \end{displaymath}
234      Le passage aux matrices de rotation se fait par la formule suivante
235      $q\rightarrow M$.
237      \begin{displaymath}
238      \begin{bmatrix}
239      a{{}^2}+b{{}^2}-c{{}^2}-d{{}^2} & 2bc-2ad & 2ac+2bd\\
240      2ad+2bc & a{{}^2}-b{{}^2}+c{{}^2}-d{{}^2} & 2cd-2ab\\
241      2bd-2ac & 2ab+2cd & a{{}^2}-b{{}^2}-c{{}^2}+d{{}^2}
242      \end{bmatrix}
243      \end{displaymath}
245      La composition de rotation se fait simplement en multipliant les
246      quaternions entre eux. Si l'on à $q$
248 ** Modes de fonctionnement
249 ** Equations fondamentales
251    Le problème que nous devons résoudre est de calculer pour une famille de
252    plan $(h,k,l)$ donné, les angles de rotation du diffractomètre qui
253    permettent de le mettre en condition de diffraction. Il faut donc
254    exprimer les relations mathématiques qui lient les différents angles
255    entre eux lorsque la condition de Bragg est vérifiée. L'équation
256    fondamentale est la suivante:
258    \begin{align*}
259    \left(\prod_{i}S_{i}\right)\cdot U\cdot B\cdot\vec{h} & =\left(\prod_{j}D_{j}-I\right)\cdot\vec{k_{i}}\\
260    R\cdot U\cdot B\cdot\vec{h} & =\vec{Q}
261    \end{align*}
263    ou $\vec{h}$ est le vecteur $(h,k,l)$, $\vec{k_{i}}$ est le vecteur
264    incident, $S_{i}$ les matrices de rotations des mouvements liés à
265    l'échantillon, $D_{j}$ les matrices de rotation des mouvements liés au
266    détecteur, $I$ la matrice identité, $U$ la matrice d'orientation du
267    cristal par rapport au repère de l'axe sur lequel ce dernier est monté
268    et $B$ la matrice de passage d'un repère non orthonormé ( celui du
269    crystal réciproque) à un repère orthonormé.
271 *** Calcule de B
273     Si l'on connaît les paramètres cristallins du cristal étudié, il est
274     très simple de calculer $B$:
276     \begin{displaymath}
277     B=
278     \begin{bmatrix}
279     a^{\star} & b^{\star}\cos\gamma^{\star} & c^{\star}\cos\beta^{\star}\\
280     0 & b^{\star}\sin\gamma^{\star} & -c^{\star}\sin\beta^{\star}\cos\alpha\\
281     0 & 0 & 1/c
282     \end{bmatrix}
283     \end{displaymath}
285 *** Calcule de U
287     Il existe plusieurs façons de calculer $U$. Busing et Levy en a proposé
288     plusieurs. Nous allons présenter celle qui nécessite la mesure de
289     seulement deux réflections ainsi que la connaissance des paramètres
290     cristallins. Cette façon de calculer la matrice d'orientation $U$, peut
291     être généralisée à n'importe quel diffractomètre pour peu que la
292     description des axes de rotation permette d'obtenir la matrice de
293     rotation de la machine $R$ et le vecteur de diffusion $\vec{Q}$.
295     Il est également possible de calculer $U$ sans la connaîssance des
296     paramètres cristallins. il faut alors faire un affinement des
297     paramètres. Cela revient à minimiser une fonction. Nous allons utiliser
298     la méthode du simplex pour trouver ce minimum et donc ajuster l'ensemble
299     des paramètres cristallins ainsi que la matrice d'orientation.
301 *** Algorithme de Busing Levy
303     L'idée est de se placer dans le repère de l'axe sur lequel est monté
304     l'échantillon. On mesure deux réflections $(\vec{h}_{1},\vec{h}_{2})$
305     ainsi que leurs angles associés. Cela nous permet de calculer $R$ et
306     $\vec{Q}$ pour chacune de ces reflections. nous avons alors ce système:
308     \begin{eqnarray*}
309     U\cdot B\cdot\vec{h}_{1} & = & \tilde{R}_{1}\cdot\vec{Q}_{1}\\
310     U\cdot B\cdot\vec{h}_{2} & = & \tilde{R}_{2}\cdot\vec{Q}_{2}
311     \end{eqnarray*}
313     De façon à calculer facilement $U$, il est intéressant de définir deux
314     trièdres orthonormé $T_{\vec{h}}$ et $T_{\vec{Q}}$ à partir des vecteurs
315     $(B\vec{h}_{1},B\vec{h}_{2})$ et
316     $(\tilde{R}_{1}\vec{Q}_{1},\tilde{R}_{2}\vec{Q}_{2})$. On a alors très
317     simplement:
319     \begin{displaymath}
320     U \cdot T_{\vec{h}} = T_{\vec{Q}}
321     \end{displaymath}
323     Et donc
325     \begin{displaymath}
326     U = T_{\vec{Q}} \cdot \tilde{T}_{\vec{h}}
327     \end{displaymath}
329 *** Affinement par la méthode du simplex
331     Dans ce cas nous ne connaissons pas la matrice $B$, il faut donc mesurer
332     plus que deux réflections pour ajuster les 9 paramètres. Six paramètres
333     pour le crystal et trois pour la matrice d'orientation $U$. Les trois
334     paramètres qui permennt de representer $U$ sont en fait les angles
335     d'euler. il faut donc être en mesure de passer d'une représentation
336     eulérien à cette matrice :math::U et réciproquement.
338     \begin{displaymath}
339     U = X \cdot Y \cdot Z
340     \end{displaymath}
342     où $X$ est la matrice rotation suivant l'axe Ox et le premier angle
343     d'Euler, $Y$ la matrice de rotation suivant l'axe Oy et le deuxième
344     angle d'Euler et $Z$ la matrice du troisième angle d'Euler pour l'axe
345     Oz.
347     \begin{tabular}{ccc}
348     $X$ & $Y$ & $Z$\tabularnewline
349     $\begin{bmatrix}
350     1 & 0 & 0\\
351     0 & A & -B\\
352     0 & B & A
353     \end{bmatrix}$
354     &
355     $\begin{bmatrix}
356     C & 0 & D\\
357     0 & 1 & 0\\
358     -D & 0 & C
359     \end{bmatrix}$
360     &
361     $\begin{bmatrix}
362     E & -F & 0\\
363     F & E & 0\\
364     0 & 0 & 1
365     \end{bmatrix}$
366     \end{tabular}
368     et donc:
370     \begin{displaymath}
371     U=
372     \begin{bmatrix}
373     CE & -CF & D\\
374     BDE+AF & -BDF+AE & -BC\\
375     -ADE+BF & ADF+BE & AC
376     \end{bmatrix}
377     \end{displaymath}
379     Il est donc facile de passer des angles d'Euler à la matrice
380     d'orientation.
382     Il faut maintenant faire la transformation inverse de la matrice $U$
383     vers les angles d'euler.
385 * PseudoAxes
386   This section describe the calculations done by the library for the
387   different kind of pseudo axes.
388 ** Eulerians to Kappa angles
390    1st solution
392    \begin{eqnarray*}
393    \kappa_\omega & = & \omega - p + \frac{\pi}{2} \\
394    \kappa & = & 2 \arcsin\left(\frac{\sin\frac{\chi}{2}}{\sin\alpha}\right) \\
395    \kappa_\phi & = &  \phi - p - \frac{\pi}{2}
396    \end{eqnarray*}
398    or 2nd one
400    \begin{eqnarray*}
401    \kappa_\omega & = & \omega - p - \frac{\pi}{2} \\
402    \kappa & = & -2 \arcsin\left(\frac{\sin\frac{\chi}{2}}{\sin\alpha}\right) \\
403    \kappa_\phi & = &  \phi - p + \frac{\pi}{2}
404    \end{eqnarray*}
406    where
408    \begin{displaymath}
409    p = \arcsin\left(\frac{\tan\frac{\chi}{2}}{\tan\alpha}\right)
410    \end{displaymath}
412    and $\alpha$ is the angle of the kappa axis with the $\vec{y}$ axis.
414 ** Kappa to Eulerians angles
416    1st solution
418    \begin{eqnarray*}
419    \omega & = & \kappa_\omega + p - \frac{\pi}{2} \\
420    \chi   & = & 2 \arcsin\left(\sin\frac{\kappa}{2} \sin\alpha\right) \\
421    \phi   & = & \kappa_\phi + p + \frac{\pi}{2}
422    \end{eqnarray*}
424    or 2nd one
426    \begin{eqnarray*}
427    \omega & = & \kappa_\omega + p + \frac{\pi}{2} \\
428    \chi   & = & -2 \arcsin\left(\sin\frac{\kappa}{2} \sin\alpha\right) \\
429    \phi   & = & \kappa_\phi + p - \frac{\pi}{2}
430    \end{eqnarray*}
432    where
434    \begin{displaymath}
435    p = \arctan\left(\tan\frac{\kappa}{2} \cos\alpha\right)
436    \end{displaymath}
438    #+CAPTION: $\omega = 0$, $\chi = 0$, $\phi = 0$, 1st solution
439    [[./figures/e2k_1.png]]
441    #+CAPTION: $\omega = 0$, $\chi = 0$, $\phi = 0$, 2nd solution
442    [[./figures/e2k_2.png]]
444    #+CAPTION: $\omega = 0$, $\chi = 90$, $\phi = 0$, 1st solution
445    [[./figures/e2k_3.png]]
447    #+CAPTION: $\omega = 0$, $\chi = 90$, $\phi = 0$, 2nd solution
448    [[./figures/e2k_4.png]]
450 ** Qper and Qpar
451    [[
452    ./figures/qper_qpar.png]]
454    this pseudo axis engine compute the perpendicular
455    ($\left|\left|\vec{Q_\text{per}}\right|\right|$) and parallel
456    ($\left|\left|\vec{Q_\text{par}}\right|\right|$) contribution of
457    $\vec{Q}$ relatively to the surface of the sample defined by the
458    $\vec{n}$ vector.
460    \begin{eqnarray*}
461    \vec{q} & = & \vec{k_\text{f}} - \vec{k_\text{i}} \\
462    \vec{q} & = & \vec{q_\text{per}} + \vec{q_\text{par}} \\
463    \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|}
464    \end{eqnarray*}
465 * Diffractometers
466   #+BEGIN_QUOTE
467   *warning*
469   This section is automatically generating by introspecting the hkl library.
470   #+END_QUOTE
472 #+BEGIN_SRC python :exports results :results value raw
473   from gi.repository import Hkl
475   def bold(l):
476       return ["\"*" + _ + "*\"" for _ in l]
478   diffractometers = Hkl.factories().iterkeys()
480   output = ''
481   for diffractometer in sorted(diffractometers):
482       factory = Hkl.factories()[diffractometer]
483       output += "** " + diffractometer + "\n"
484       detector = Hkl.Detector.factory_new(Hkl.DetectorType(0))
485       sample = Hkl.Sample.new("toto")
486       geometry = factory.create_new_geometry()
487       engines = factory.create_new_engine_list()
488       engines.init(geometry, detector, sample)
490       output += "*** Axes: \n"
491       for axis in geometry.axes_names_get():
492           axis_v = geometry.axis_get(axis).axis_v_get().data
493           output += "    + \"*" + axis + "*\": rotation around the *" + repr(axis_v) + "* axis\n"
495       output += "*** Engines: \n"
496       for engine in engines.engines_get():
497           output += "    * \"*" + engine.name_get() + "*\":"
498           for pseudo in engine.pseudo_axes_names_get():
499               output += " \"*" + pseudo + "*\""
500           output += "\n"
501           for mode in engine.modes_names_get():
502               output += " "*6 + "+ mode: \"*" + mode + "*\"\n"
503               engine.current_mode_set(mode)
504               axes_r = engine.axes_names_get(Hkl.EngineAxesNamesGet.READ)
505               axes_w = engine.axes_names_get(Hkl.EngineAxesNamesGet.WRITE)
506               parameters = engine.parameters_names_get() or ["No parameter"]
507               output += " "*8 + "+ axes (read) : " + ", ".join(bold(axes_r)) + "\n"
508               output += " "*8 + "+ axes (write): " + ", ".join(bold(axes_w)) + "\n"
509               output += " "*8 + "+ parameters: " + ", ".join(bold(parameters)) + "\n"
511   return output
512 #+END_SRC
513 * Developpement
514 ** Getting hkl
516    To get hkl, you can download the last stable version from sourceforge or
517    if you want the latest development version use
518    [[http://git.or.cz/][git]] or
519    [[http://code.google.com/p/msysgit/downloads/list][msysgit]] on windows
520    system and do:
522    #+BEGIN_SRC sh
523 git clone git://repo.or.cz/hkl.git
524    #+END_SRC
526    or:
528    #+BEGIN_SRC sh
529     git clone http://repo.or.cz/r/hkl.git (slower)
530    #+END_SRC
532    then checkout the next branch like this:
534    #+BEGIN_SRC sh
535     cd hkl
536     git checkout -b next origin/next
537    #+END_SRC
539 ** Building hkl
541    To build hkl you need [[http://www.python.org][Python 2.3+]] the
542    [[http://www.gnu.org/software/gsl/][GNU Scientific Library 1.12]] and
543    [[https://developer.gnome.org/glib/][GLib-2.0 >= 2.3.4]]:
545    #+BEGIN_SRC sh
546     ./configure --disable-gui
547     make
548     sudo make install
549    #+END_SRC
551    you can also build a GUI interfaces which use
552    [[http://www.gtk.org][gtk]]:
554    #+BEGIN_SRC sh
555     ./configure
556     make
557     sudo make install
558    #+END_SRC
560    optionnaly you can build an experimental /libhkl3d/ library (no public
561    API for now) which is used by the GUI to display and compute
562    diffractometer collisions (only the /K6C/ model). To build it you need
563    also [[https://projects.gnome.org/gtkglext/][gtkglext]] and
564    [[http://bulletphysics.org/wordpress/][bullet 2.82]]:
566    #+BEGIN_SRC sh
567     ./configure --enable-hkl3d
568     make
569     sudo make install
570    #+END_SRC
572    if you want to work on the documentation you need the extra
574 - [[http://www.gtk.org/gtk-doc/][gtk-doc]] for the api
575 - [[http://sphinx.pocoo.org/][sphinx]] for the html and latex doc.
576 - [[http://asymptote.sourceforge.net/][asymptote]] for the figures
577 - [[http://www.gnu.org/software/emacs/][emacs]] the well known editor
578 - [[https://github.com/emacsmirror/htmlize][htmlize]] used to highlight the source code
579 - [[http://orgmode.org][org-mode]] litteral programming
580 - [[http://savannah.nongnu.org/projects/dvipng/][dvipng]] convert latex equation into pictures
582 On Debian/Ubuntu you just need to install
584 #+BEGIN_SRC sh
585   sudo apt-get install emacs dvipng emacs-goodies-el org-mode
586 #+END_SRC
588 #+BEGIN_SRC sh
589     ./configure --enable-gtk-doc
590     make
591     make html
592 #+END_SRC
594 ** Hacking hkl
596 *** Bug reporting
598     You can find the bug tracker here
599     [[https://bugs.debian.org/cgi-bin/pkgreport.cgi?repeatmerged=no&src=hkl][libhkl]]
601 -  Debian/Ubuntu:
603    #+BEGIN_SRC sh
604        reportbug hkl
605    #+END_SRC
607 -  Other OS
609    You just need to send an email:
611    #+BEGIN_EXAMPLE
612        To: submit@bugs.debian.org
613        From: xxx@yyy.zzz
614        Subject: My problem with hkl...
616        Package: hkl
617        Version: |version|
619        I found this problem in hkl...
620    #+END_EXAMPLE
622 *** Providing patchs
624     you can send your patch to [[picca@synchrotron-soleil.fr][Picca
625     Frédéric-Emmanuel]] using =git=
627     Here a minimalist exemple of the workflow to prepare and send a patch
628     for hkl. Suppose you wan to add a new feature to hkl create first a new
629     branch from the next one:
631     #+BEGIN_SRC sh
632     git checkout -b my-next next
633     #+END_SRC
635     hack, hack:
637     #+BEGIN_SRC sh
638     git commit -a
639     #+END_SRC
641     more hacks:
643     #+BEGIN_SRC sh
644     git commit -a
645     #+END_SRC
647     now that your new feature is ready for a review, you can send by email
648     your work using git format-patch:
650     #+BEGIN_SRC sh
651     git format-patch origin/next
652     #+END_SRC
654     and send generated files 0001\_xxx, 0002\_xxx, ... to the author.
656 ** Howto add a diffractometer
658    To add a new diffractometer, you just need to copy the
659    hkl/hkl-engine-template.c into
660    hkl/hkl-engine-INSTITUT-BEAMLINE-INSTRUMENT.c where you replace the
661    upper case with the appropriate values.
663    The template file is compiled during the build process to ensure that it
664    is always valid.
666    Then you just need to follow the instruction found in the template. If
667    you need some precision about the process, do not hesitate to contact
668    the main author.
670    do not forgot also to add this new file into hkl/Makefile.am with other
671    diffractometers in the hkl\_c\_sources variable (please keep the
672    alphabetic order).
673 * Bindings
675   The hkl library use the gobject-introspection to provide automatic
676   binding for a few languages.
678 ** Python
680    hkl computation:
682    has you can see there is 4 available solutions.
684    let's compute an hkl trajectory and select the first solution.
686    if we look at the 3 other solutions we can see that there is a problem
687    of continuity at the begining of the trajectory.
689    hey what's happend with theses solutions ! let's look closely to real
690    numbers. the last column is the distance to the diffractometer current
691    position. This distance is for now express like this:
693    $\sum_{axes} \left|\text{current position} - \text{target position}\right|$
695    #+BEGIN_EXAMPLE
696     [0.0, 119.99999999999999, 0.0, -90.0, 0.0, 59.99999999999999] 0.0
697     [0.0, -119.99999999999999, 0.0, -90.0, 0.0, -59.99999999999999] 6.28318530718
698     [0.0, -60.00000000000005, 0.0, 90.0, 0.0, 59.99999999999999] 6.28318530718
699     [0.0, 60.00000000000001, 0.0, 90.0, 0.0, -59.99999999999999] 6.28318530718
701     [0.0, 117.7665607657826, 7.456826294401656, -92.39856410531434, 0.0, 60.33024982425957] 0.216753826612
702     [0.0, -57.436310940366894, -7.456826294401656, 92.39856418853617, 0.0, 60.33024982425957] 6.41621345188
703     [0.0, 62.2334392342174, -7.456826294401656, 92.39856410531434, 0.0, -60.33024982425957] 6.42197739723
704     [0.0, -122.5636890596331, 7.456826294401656, -92.3985641885362, 0.0, -60.33024982425957] 6.50570308205
706     [0.0, 115.89125602137928, 14.781064139466098, -94.7660423112577, 0.0, 61.314597086440706] 0.219062698235
707     [0.0, -125.42334103772737, 14.781064139466098, -94.7660427050904, 0.0, -61.314597086440706] 6.53671995288
708     [0.0, -54.57665896227262, -14.781064139466098, 94.76604270509038, 0.0, 61.314597086440706] 6.67989976726
709     [0.0, 64.10874397862072, -14.781064139466098, 94.7660423112577, 0.0, -61.314597086440706] 6.71437170098
711     [0.0, 114.39338605351007, 21.85448296702796, -97.074145033719, 0.0, 62.93506298693471] 0.218163667981
712     [0.0, -128.54167683157993, 21.85448296702796, -97.07414574435087, 0.0, -62.93506298693471] 6.59846359365
713     [0.0, -51.45832316842005, -21.85448296702796, 97.07414574435087, 0.0, 62.93506298693471] 6.93673746356
714     [0.0, 65.60661394648993, -21.85448296702796, 97.074145033719, 0.0, -62.93506298693471] 7.03385205725
716     [0.0, 113.28316795475283, 28.583837575232764, -99.29953499008337, 0.0, 65.16540747008955] 0.21459359225
717     [0.0, -131.88223933078322, 28.583837575232764, -99.29953638594702, 0.0, -65.16540747008955] 6.69038531388
718     [0.0, -48.11776066921677, -28.583837575232764, 99.29953638594702, 0.0, 65.16540747008955] 7.18296350386
719     [0.0, 66.71683204524717, -28.583837575232764, 99.29953499008337, 0.0, -65.16540747008955] 7.37556986959
721     [0.0, 112.56286877075006, 34.90573305321372, -101.42496979586187, 0.0, 67.97568017857415] 0.209053830457
722     [0.0, -135.4128111996365, 34.90573305321372, -101.42497263302461, 0.0, -67.97568017857415] 6.81174779784
723     [0.0, -44.58718880036348, -34.90573305321372, 101.4249726330246, 0.0, 67.97568017857415] 7.41581162393
724     [0.0, 67.43713122924994, -34.90573305321372, 101.42496979586187, 0.0, -67.97568017857415] 7.7353201851
726     [0.0, 112.2291126083182, 40.78594007247402, -103.43941832567457, 0.0, 71.33706722449408] 0.202280147961
727     [0.0, -139.10795451001587, 40.78594007247402, -103.43942357602316, 0.0, -71.33706722449408] 6.96173845391
728     [0.0, -40.89204548998411, -40.78594007247402, 103.43942357602312, 0.0, 71.33706722449408] 7.63358787543
729     [0.0, 67.7708873916818, -40.78594007247402, 103.43941832567457, 0.0, -71.33706722449408] 8.10986069093
731     [0.0, 112.27578927291766, 46.214916130901734, -105.33741042812996, 0.0, 75.22640762217479] 0.196576175748
732     [0.0, -142.95061850160724, 46.214916130901734, -105.3374188005596, 0.0, -75.22640762217479] 7.13962155618
733     [0.0, -37.04938149839278, -46.214916130901734, 105.33741880055959, 0.0, 75.22640762217479] 7.83557762281
734     [0.0, 67.72421072708234, -46.214916130901734, 105.33741042812996, 0.0, -75.22640762217479] 8.49706672677
736     [0.0, 112.697137434232, 51.201667684695856, -107.11797492933192, 0.0, 79.63023536264535] 0.202327153157
737     [0.0, -146.9330984641471, 51.201667684695856, -107.11798610058318, 0.0, -79.63023536264535] 7.34491897177
738     [0.0, -33.0669015358529, -51.201667684695856, 107.11798610058317, 0.0, 79.63023536264535] 8.02185610877
739     [0.0, 67.30286256576798, -51.201667684695856, 107.11797492933192, 0.0, -79.63023536264535] 8.89597005568
741     [0.0, 113.49085964586432, 55.76762791023837, -108.78347437395287, 0.0, 84.54867879242364] 0.208455586312
742     [0.0, -151.05782007465257, 55.76762791023837, -108.78348605483542, 0.0, -84.54867879242364] 7.57761473366
743     [0.0, -28.942179925347414, -55.76762791023837, 108.78348605483538, 0.0, 84.54867879242364] 8.19307323084
744     [0.0, 66.50914035413568, -55.76762791023837, 108.78347437395287, 0.0, -84.54867879242364] 9.30675279514
746     [0.0, 114.6614608037443, 59.941489465646214, -110.3385360479293, 0.0, 90.00000081324956] 0.215562935229
747     [0.0, -155.33854118146962, 59.941489465646214, -110.33854432979601, 0.0, -89.99999918675044] 7.83839602383
748     [0.0, -24.661458818530395, -59.941489465646214, 110.33854432979601, 0.0, 90.00000081324956] 8.3502621071
749     [0.0, 65.3385391962557, -59.941489465646214, 110.3385360479293, 0.0, -89.99999918675044] 9.7307712883
750    #+END_EXAMPLE
752    as you can see for the first point of the trajectory, the 2nd, 3rd and
753    4th solutions have identical distances to the current position of the
754    diffractometer so they are un-ordered:
756    #+BEGIN_EXAMPLE
757     [0.0, 119.99999999999999, 0.0, -90.0, 0.0, 59.99999999999999] 0.0
758     [0.0, -119.99999999999999, 0.0, -90.0, 0.0, -59.99999999999999] 6.28318530718
759     [0.0, -60.00000000000005, 0.0, 90.0, 0.0, 59.99999999999999] 6.28318530718
760     [0.0, 60.00000000000001, 0.0, 90.0, 0.0, -59.99999999999999] 6.28318530718
761    #+END_EXAMPLE
763    then the problem arise with the second and third solution. you can see a
764    sort of reorganisation of the solution. 2 -> 3, 3 -> 4 and 4 -> 2 then
765    the order will stick unchanged until the end of the trajectory. this is
766    because the distance is computed relatively to the current position of
767    the diffractometer.:
769    #+BEGIN_EXAMPLE
770     [0.0, 117.7665607657826, 7.456826294401656, -92.39856410531434, 0.0, 60.33024982425957] 0.216753826612
771     [0.0, -57.436310940366894, -7.456826294401656, 92.39856418853617, 0.0, 60.33024982425957] 6.41621345188
772     [0.0, 62.2334392342174, -7.456826294401656, 92.39856410531434, 0.0, -60.33024982425957] 6.42197739723
773     [0.0, -122.5636890596331, 7.456826294401656, -92.3985641885362, 0.0, -60.33024982425957] 6.50570308205
775     [0.0, 115.89125602137928, 14.781064139466098, -94.7660423112577, 0.0, 61.314597086440706] 0.219062698235
776     [0.0, -125.42334103772737, 14.781064139466098, -94.7660427050904, 0.0, -61.314597086440706] 6.53671995288
777     [0.0, -54.57665896227262, -14.781064139466098, 94.76604270509038, 0.0, 61.314597086440706] 6.67989976726
778     [0.0, 64.10874397862072, -14.781064139466098, 94.7660423112577, 0.0, -61.314597086440706] 6.71437170098
779    #+END_EXAMPLE
781    #+BEGIN_QUOTE
782    *warning*
784    when you compute a trajectory, start from a valid position (the
785    starting point must be the real first point of your trajectory) then
786    use only the closest solution for the next points of the trajectory.
787    (first solution of the geometries list)
788    #+END_QUOTE
789 * Todo
790 ** hkl
791 *** TODO [2/4] HklParameter
792     - [X] method to use min/max to check for the validity
793     - [X] add a method to get the axis_v and quaternion of the HklAxis
794       this method will return NULL if this is not relevant.
795       hkl_parameter_axis_v_get and hkl_parameter_quaternion_get
796     - [ ] degenerated an axis is degenerated if its position have no
797       effect on the HklPseudoAxis calculus. Add a degenerated member
798       to the axis. that way it would be possible to check a posteriori
799       for this degenerescencence.
800     - [ ] Add a description for each parameters.
801       This will help for the documentation and the gui.
802 *** TODO HklGeometryList different method to help select a solution.
803     this select solution can depend on the geometry
804     for example the kappa axis must be in one side of the plane.
805 *** TODO add a fit on the Hklaxis offsets.
806 *** TODO API to put a detector and a sample on the Geometry.
807 *** TODO HklSample add the cell volum computation.
808 *** TODO HklEngine "zone"
809 *** TODO HklEngine "custom"
810     for now this pseudoaxis let you select the axis you
811     want to use for the computation.
812 *** TODO create a macro to help compare two real the right way
813     fabs(a-b) < epsilon * max(1, abs(a), abs(b))
814 *** TODO add an hkl_sample_set_lattice_unit()
815 *** TODO SOLEIL SIXS
816 **** DONE find the right solutions.                                   :zaxis:
817      The cosinus and sinus properties are not enough to find the solution expected by the users.
818      The idea is to use the Ewalds construction to generate a valid solution from the first one
819      obtain numerically. The basic idea is to rotate the hkl vector around the last axis of the
820      sample holder until it intersect again the Ewalds sphere. Then we just need to fit the
821      detector position. This way the solution can be entirely generic (not geometry specific).
822      Nevertheless it is necessary to propose this only for the hkl pseudo axes. I will add this
823      special feature in the Mode. So it will be possible to add thoses special cases easily.
824 **** TODO Add the DEP diffractometer geometry
825      This diffractometer is a Newport one based on the kappa 6 circles ones.
826      But instead of a kappa head, they use an Hexapod head.
827      This head can be put horizontally or vertically.
828 *** TODO generalisation of the z-axis hkl solver
829     first we need the degenerated member of the Axis. thaht way it could be possible
830     to find the last non degenerated axis for the detector fit.
831 *** TODO investigate the prigo geometry.
832 *** TODO augeas/elektra for the plugin configure part.
833 *** TODO logging
834 **** TODO [1/2] add in a few methods.
835      + [X] hkl_pseudo_axes_values_set
836      + [ ] hkl_sample_affine
837 **** TODO gir logging
838      It would be nice to generate the library logging using the .gir
839      information. So instead of writing the logging code for each
840      method, it would be better to have a generic method for this
841      purpose.
842 **** TODO parsable logging information.
843      A parsable logging format would help to setup some re-play unit
844      test. This way it could help during the developpement process
845      (modification of the hkl internals) to be confident that
846      computation are ok.
847 *** TODO performances
848     Investigate [[http://liboil.freedesktop.org/wiki/][liboil]] to speed calculation (in HklVector, HklMatrix
849     and HklQuaternion)
850 ** documentation
851 *** TODO [1/4] rewrite documentation in org-mode
852     - [ ] embed code into the org-mode
853       - [ ] [0/4] python
854         - [ ] auto generation of the diffractometer descriptions
855         - [ ] trajectories explanations
856         - [ ] trajectories tests.
857         - [ ] unit tests output ?
858       - [ ] asymptote
859     - [X] need to check if templates could be generated using the hkl
860       python binding for all diffractometer geometries.
861     - [ ] need to add a description for the diffractometer, the mode, the parameters.
862     - [ ] need a nice css for the generated doc.
863 ** gui
864 *** TODO change the color of fitparameter cells if they differ from the current
865            sample values
866 *** TODO REPL
867     https://github.com/jonathanslenders/python-prompt-toolkit/tree/master/examples/tutorial
869 ** hkl3d
870 *** TODO add a method to find the 3D models in the right directories.
872 ** packaging
873 *** TODO add a .spec file for rpm generation.