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