Welcome to hkl's 5.0.0.3367 documentation!
Table of Contents
- 1. Introduction
- 2. PseudoAxes
- 3. Diffractometers
- 4. Developpement
- 5. Bindings
- 6. Releases
- 7. Todo
- 7.1. hkl
- 7.1.1. TODO
HklEngine
q/q2 - 7.1.2. TODO HklSource
- 7.1.3. TODO SOLEIL SIRIUS KAPPA
- 7.1.4. TODO
[0/2]
PetraIII - 7.1.5. TODO
[2/4]
HklParameter - 7.1.6. TODO This will help for the documentation and the gui.
- 7.1.7. TODO HklGeometryList different method to help select a solution.
- 7.1.8. TODO add a fit on the Hklaxis offsets.
- 7.1.9. TODO API to put a detector and a sample on the Geometry.
- 7.1.10. TODO HklSample
- 7.1.11. TODO HklEngine "zone"
- 7.1.12. TODO HklEngine "custom"
- 7.1.13. TODO HklEngine "q/q2" add a "reflectivity" mode
- 7.1.14. TODO create a macro to help compare two real the right way
- 7.1.15. TODO add an hkl_sample_set_lattice_unit()
- 7.1.16. TODO SOLEIL SIXS
- 7.1.17. TODO generalisation of the z-axis hkl solver
- 7.1.18. TODO investigate the prigo geometry.
- 7.1.19. TODO augeas/elektra for the plugin configure part.
- 7.1.20. TODO logging
- 7.1.21. TODO performances
- 7.1.1. TODO
- 7.2. documentation
- 7.3.
[0/3]
gui - 7.4. hkl3d
- 7.5. packaging
- 7.1. hkl
1. Introduction
The purpose of the library is to factorize single crystal diffraction angles computation for different kind of diffractometer geometries. It is used at the SOLEIL, Desy and Alba synchrotron with the Tango control system to pilot diffractometers.
1.1. Features
- mode computation (aka PseudoAxis)
- item for different diffractometer geometries.
- UB matrix computation.
- busing & Levy with 2 reflections
- simplex computation with more than 2 reflections using the GSL library.
- Eulerians angles to pre-orientate your sample.
- Crystal lattice refinement
- with more than 2 reflections you can select which parameter must be fitted.
- Pseudoaxes
- psi, eulerians, q, …
1.2. Conventions
In all this document the next convention will be used to describe the diffractometers geometries.
- right handed convention for all the angles.
- direct space orthogonal base.
- description of the diffractometer geometries is done with all axes values set to zero.
1.3. Diffraction
1.3.1. the crystal
A periodic crystal is the association of a pattern and a lattice. The pattern is located at each points of the lattice node. Positions of those nodes are given by:
\[ R_{uvw}=u\cdot\vec{a}+v\cdot\vec{b}+w\cdot\vec{c} \]
\(\vec{a}\), \(\vec{b}\), \(\vec{c}\) are the former vector of a base of the
space. u
, v
, w
are integers. The pattern contain atoms
associated to each lattice node. the purpose of diffraction is to study
the interaction of this crystal (pattern+lattice) with X-rays.
Figure 1: Crystal direct lattice.
this lattice is defined by \(\vec{a}\), \(\vec{b}\), \(\vec{c}\) vectors, and the angles \(\alpha\), \(\beta\), \(\gamma\). In general cases this lattice is not orthonormal.
Nevertheless to compute the interaction of this real space lattice and the X-Rays, it is convenient to define another lattice called reciprocal lattice defined like this:
\begin{eqnarray*} \vec{a}^{\star} & = & \tau\frac{\vec{b}\wedge\vec{c}}{\vec{a}\cdot(\vec{b}\wedge\vec{c})}\\ \vec{b}^{\star} & = & \tau\frac{\vec{c}\wedge\vec{a}}{\vec{b}\cdot(\vec{c}\wedge\vec{a})}\\ \vec{c}^{\star} & = & \tau\frac{\vec{a}\wedge\vec{b}}{\vec{c}\cdot(\vec{a}\wedge\vec{b})} \end{eqnarray*}\(\tau=2\pi\) or \(\tau=1\) depending on the conventions.
It is then possible to define theses orthogonal properties:
\begin{eqnarray*} \vec{a}^{\star}\cdot\vec{a}=\tau & \vec{b}^{\star}\cdot\vec{a}=0 & \vec{c}^{\star}\cdot\vec{a}=0\\ \vec{a}^{\star}\cdot\vec{b}=0 & \vec{b}^{\star}\cdot\vec{b}=\tau & \vec{c}^{\star}\cdot\vec{b}=0\\ \vec{a}^{\star}\cdot\vec{c}=0 & \vec{b}^{\star}\cdot\vec{c}=0 & \vec{c}^{\star}\cdot\vec{c}=\tau \end{eqnarray*}This reciprocal space lattice allow to write in a simpler form the interaction between the crystal and the X-Rays. We often only know about \(\vec{a}\), \(\vec{b}\), \(\vec{c}\) vectors and the angles \(\alpha\), \(\beta\), \(\gamma\). Using the previous equations reciprocal, we can compute the reciprocal lattice this way:
\begin{eqnarray*} a^{\star} & = & \frac{\sin\alpha}{aD}\\ b^{\star} & = & \frac{\sin\beta}{bD}\\ c^{\star} & = & \frac{\sin\gamma}{cD} \end{eqnarray*}where
\[ D=\sqrt{1-\cos^{2}\alpha-\cos^{2}\beta-\cos^{2}\gamma+2\cos\alpha\cos\beta\cos\gamma} \]
To compute the angles between the reciprocal space vectors, it is once again possible to use the previous equations reciprocal to obtain the sines and cosines of the angles \(\alpha^\star\), \(\beta^\star\) and \(\gamma^\star\):
\begin{eqnarray*} \cos\alpha^{\star}=\frac{\cos\beta\cos\gamma-\cos\alpha}{\sin\beta\sin\gamma} & \, & \sin\alpha^{\star}=\frac{D}{\sin\beta\sin\gamma} \\ \cos\beta^{\star}=\frac{\cos\gamma\cos\alpha-\cos\beta}{\sin\gamma\sin\alpha} & \, & \sin\beta^{\star}=\frac{D}{\sin\gamma\sin\alpha}\\ \cos\gamma^{\star}=\frac{\cos\alpha\cos\beta-\cos\gamma}{\sin\alpha\sin\beta} & \, & \sin\gamma^{\star}=\frac{D}{\sin\alpha\sin\beta} \end{eqnarray*}the volume of the lattice can be compute this way:
\[ V = abcD \]
or
\[ 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}) \]
1.3.2. Diffraction
Let the incoming X-rays beam whose wave vector is \(\vec{k_{i}}\), \(|k_{i}|=\tau/\lambda\) where \(\lambda\) is the wavelength of the signal. The \(\vec{k_{d}}\) vector wavelength of the diffracted beam. There is diffusion if the diffusion vector \(\vec{q}\) can be expressed as follows:
\[ \vec{q}=\vec{k_{d}}-\vec{k_{i}}=h.\vec{a}^{*}+k.\vec{b}^{*}+l.\vec{c}^{*} \]
where \((h,k,l)\in\mathbb{N}^{3}\) and \((h,k,l)\neq(0,0,0)\). Theses indices \((h,k,l)\) are named Miller indices.
Another way of looking at things has been given by Bragg and that famous relationship:
\[ n\lambda=2d\sin\theta \]
where \(d\) is the inter-plan distance and \(n \in \mathbb{N}\).
The diffusion occurs for an unique \(\theta\) angle. Then we got \(\vec{q}\) perpendicular to the diffraction plan.
The Ewald construction allow to represent this diffraction in the reciprocal space.
1.3.3. Quaternions
- Properties
The quaternions will be used to describe the diffractometers geometries. Theses quaternions can represent 3D rotations. There is different way to describe then like complex numbers.
\[ q=a+bi+cj+dk \]
or
\[ q=[a,\vec{v}] \]
To compute the quaternion's norm, we can proceed like for complex numbers
\[ \|q\|=\sqrt{a²+b²+c²+d²} \]
Its conjugate is :
\[ q^{*}=[a,-\vec{u}]=a-bi-cj-dk \]
- Operations
The difference with the complex number algebra is about non-commutativity.
\[ qp \neq pq \]
\[
\begin{bmatrix} ~ & 1 & i & j & k \cr 1 & 1 & i & j & k \cr i & i & -1 & k & -j \cr j & j & -k & -1 & i \cr k & k & j & -i & -1 \end{bmatrix}\]
The product of two quaternions can be express by the Grassman product Grassman product. So for two quaternions \(p\) and \(q\):
\begin{align*} q &= a+\vec{u} = a+bi+cj+dk\\ p &= t+\vec{v} = t+xi+yj+zk \end{align*}we got
\[ pq = at - \vec{u} \cdot \vec{v} + a \vec{v} + t \vec{u} + \vec{v} \times \vec{u} \]
or equivalent
\[ pq = (at - bx - cy - dz) + (bt + ax + cz - dy) i + (ct + ay + dx - bz) j + (dt + az + by - cx) k \]
- 3D rotations
L'ensemble des quaternions unitaires (leur norme est égale à 1) est le groupe qui représente les rotations dans l'espace 3D. Si on a un vecteur unitaire \(\vec{u}\) et un angle de rotation \(\theta\) alors le quaternion \([\cos\frac{\theta}{2},\sin\frac{\theta}{2}\vec{u]}\) représente la rotation de \(\theta\) autour de l'axe \(\vec{u}\) dans le sens trigonométrique. Nous allons donc utiliser ces quaternions unitaires pour représenter les mouvements du diffractomètre.
Alors que dans le plan 2D une simple multiplication entre un nombre complex et le nombre \(e^{i\theta}\) permet de calculer simplement la rotation d'angle \(\theta\) autour de l'origine, dans l'espace 3D l'expression équivalente est:
\[ z'=qzq^{-1} \]
où \(q\) est le quaternion de norme 1 représentant la rotation dans l'espace et \(z\) le quaternion représentant le vecteur qui subit la rotation (sa partie réelle est nulle).
Dans le cas des quaternions de norme 1, il est très facile de calculer \(q^{-1}\). En effet l'inverse d'une rotation d'angle \(\theta\) est la rotation d'angle \(-\theta\). On a donc directement:
\[ q^{-1}=[\cos\frac{-\theta}{2},\sin\frac{-\theta}{2}\vec{u}]=[\cos\frac{\theta}{2},-\sin\frac{\theta}{2}\vec{u}]=q^{*} \]
Le passage aux matrices de rotation se fait par la formule suivante \(q\rightarrow M\).
\[
\begin{bmatrix} a{{}^2}+b{{}^2}-c{{}^2}-d{{}^2} & 2bc-2ad & 2ac+2bd\\ 2ad+2bc & a{{}^2}-b{{}^2}+c{{}^2}-d{{}^2} & 2cd-2ab\\ 2bd-2ac & 2ab+2cd & a{{}^2}-b{{}^2}-c{{}^2}+d{{}^2} \end{bmatrix}\]
La composition de rotation se fait simplement en multipliant les quaternions entre eux. Si l'on à \(q\)
1.4. Modes de fonctionnement
1.5. Equations fondamentales
Le problème que nous devons résoudre est de calculer pour une famille de plan \((h,k,l)\) donné, les angles de rotation du diffractomètre qui permettent de le mettre en condition de diffraction. Il faut donc exprimer les relations mathématiques qui lient les différents angles entre eux lorsque la condition de Bragg est vérifiée. L'équation fondamentale est la suivante:
\begin{align*} \left(\prod_{i}S_{i}\right)\cdot U\cdot B\cdot\vec{h} & =\left(\prod_{j}D_{j}-I\right)\cdot\vec{k_{i}}\\ R\cdot U\cdot B\cdot\vec{h} & =\vec{Q} \end{align*}ou \(\vec{h}\) est le vecteur \((h,k,l)\), \(\vec{k_{i}}\) est le vecteur incident, \(S_{i}\) les matrices de rotations des mouvements liés à l'échantillon, \(D_{j}\) les matrices de rotation des mouvements liés au détecteur, \(I\) la matrice identité, \(U\) la matrice d'orientation du cristal par rapport au repère de l'axe sur lequel ce dernier est monté et \(B\) la matrice de passage d'un repère non orthonormé ( celui du crystal réciproque) à un repère orthonormé.
1.5.1. Calcule de B
Si l'on connaît les paramètres cristallins du cristal étudié, il est très simple de calculer \(B\):
\[ B=
\begin{bmatrix} a^{\star} & b^{\star}\cos\gamma^{\star} & c^{\star}\cos\beta^{\star}\\ 0 & b^{\star}\sin\gamma^{\star} & -c^{\star}\sin\beta^{\star}\cos\alpha\\ 0 & 0 & 1/c \end{bmatrix}\]
1.5.2. Calcule de U
Il existe plusieurs façons de calculer \(U\). Busing et Levy en a proposé plusieurs. Nous allons présenter celle qui nécessite la mesure de seulement deux réflections ainsi que la connaissance des paramètres cristallins. Cette façon de calculer la matrice d'orientation \(U\), peut être généralisée à n'importe quel diffractomètre pour peu que la description des axes de rotation permette d'obtenir la matrice de rotation de la machine \(R\) et le vecteur de diffusion \(\vec{Q}\).
Il est également possible de calculer \(U\) sans la connaîssance des paramètres cristallins. il faut alors faire un affinement des paramètres. Cela revient à minimiser une fonction. Nous allons utiliser la méthode du simplex pour trouver ce minimum et donc ajuster l'ensemble des paramètres cristallins ainsi que la matrice d'orientation.
1.5.3. Algorithme de Busing Levy
L'idée est de se placer dans le repère de l'axe sur lequel est monté l'échantillon. On mesure deux réflections \((\vec{h}_{1},\vec{h}_{2})\) ainsi que leurs angles associés. Cela nous permet de calculer \(R\) et \(\vec{Q}\) pour chacune de ces reflections. nous avons alors ce système:
\begin{eqnarray*} U\cdot B\cdot\vec{h}_{1} & = & \tilde{R}_{1}\cdot\vec{Q}_{1}\\ U\cdot B\cdot\vec{h}_{2} & = & \tilde{R}_{2}\cdot\vec{Q}_{2} \end{eqnarray*}De façon à calculer facilement \(U\), il est intéressant de définir deux trièdres orthonormé \(T_{\vec{h}}\) et \(T_{\vec{Q}}\) à partir des vecteurs \((B\vec{h}_{1},B\vec{h}_{2})\) et \((\tilde{R}_{1}\vec{Q}_{1},\tilde{R}_{2}\vec{Q}_{2})\). On a alors très simplement:
\[ U \cdot T_{\vec{h}} = T_{\vec{Q}} \]
Et donc
\[ U = T_{\vec{Q}} \cdot \tilde{T}_{\vec{h}} \]
1.5.4. Affinement par la méthode du simplex
Dans ce cas nous ne connaissons pas la matrice \(B\), il faut donc mesurer plus que deux réflections pour ajuster les 9 paramètres. Six paramètres pour le crystal et trois pour la matrice d'orientation \(U\). Les trois paramètres qui permennt de representer \(U\) sont en fait les angles d'euler. il faut donc être en mesure de passer d'une représentation eulérien à cette matrice :math::U et réciproquement.
\[ U = X \cdot Y \cdot Z \]
où \(X\) est la matrice rotation suivant l'axe Ox et le premier angle d'Euler, \(Y\) la matrice de rotation suivant l'axe Oy et le deuxième angle d'Euler et \(Z\) la matrice du troisième angle d'Euler pour l'axe Oz.
\(X\) | \(Y\) | \(Z\) |
\(\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}\) |
et donc:
\[ U=
\begin{bmatrix} CE & -CF & D\\ BDE+AF & -BDF+AE & -BC\\ -ADE+BF & ADF+BE & AC \end{bmatrix}\]
Il est donc facile de passer des angles d'Euler à la matrice d'orientation.
Il faut maintenant faire la transformation inverse de la matrice \(U\) vers les angles d'euler.
2. PseudoAxes
This section describe the calculations done by the library for the different kind of pseudo axes.
2.1. General process
2.1.1. First Solution
The hkl library use the gsl library in order to find the first valid solution.
2.1.2. Multiplication of the solutions.
Once we have got the first solution different strategies are applyed in order to generate more solutions.
2.1.3. Restrains of the Solutions
We apply then some constrains to reduce these solutions to only a bunch of acceptable ones. Usualy we take the axis range into account.
2.2. Eulerians to Kappa angles
1st solution
\begin{eqnarray*} \kappa_\omega & = & \omega - p + \frac{\pi}{2} \\ \kappa & = & 2 \arcsin\left(\frac{\sin\frac{\chi}{2}}{\sin\alpha}\right) \\ \kappa_\phi & = & \phi - p - \frac{\pi}{2} \end{eqnarray*}or 2nd one
\begin{eqnarray*} \kappa_\omega & = & \omega - p - \frac{\pi}{2} \\ \kappa & = & -2 \arcsin\left(\frac{\sin\frac{\chi}{2}}{\sin\alpha}\right) \\ \kappa_\phi & = & \phi - p + \frac{\pi}{2} \end{eqnarray*}where
\[ p = \arcsin\left(\frac{\tan\frac{\chi}{2}}{\tan\alpha}\right) \]
and \(\alpha\) is the angle of the kappa axis with the \(\vec{y}\) axis.
2.3. Kappa to Eulerians angles
1st solution
\begin{eqnarray*} \omega & = & \kappa_\omega + p - \frac{\pi}{2} \\ \chi & = & 2 \arcsin\left(\sin\frac{\kappa}{2} \sin\alpha\right) \\ \phi & = & \kappa_\phi + p + \frac{\pi}{2} \end{eqnarray*}or 2nd one
\begin{eqnarray*} \omega & = & \kappa_\omega + p + \frac{\pi}{2} \\ \chi & = & -2 \arcsin\left(\sin\frac{\kappa}{2} \sin\alpha\right) \\ \phi & = & \kappa_\phi + p - \frac{\pi}{2} \end{eqnarray*}where
\[ p = \arctan\left(\tan\frac{\kappa}{2} \cos\alpha\right) \]
Figure 2: \(\omega = 0\), \(\chi = 0\), \(\phi = 0\), 1st solution
Figure 3: \(\omega = 0\), \(\chi = 0\), \(\phi = 0\), 2nd solution
Figure 4: \(\omega = 0\), \(\chi = 90\), \(\phi = 0\), 1st solution
Figure 5: \(\omega = 0\), \(\chi = 90\), \(\phi = 0\), 2nd solution
2.4. Qper and Qpar
this pseudo axis engine compute the perpendicular (\(\left|\left|\vec{Q_\text{per}}\right|\right|\)) and parallel (\(\left|\left|\vec{Q_\text{par}}\right|\right|\)) contribution of \(\vec{Q}\) relatively to the surface of the sample defined by the \(\vec{n}\) vector.
\begin{eqnarray*} \vec{q} & = & \vec{k_\text{f}} - \vec{k_\text{i}} \\ \vec{q} & = & \vec{q_\text{per}} + \vec{q_\text{par}} \\ \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|} \end{eqnarray*}3. Diffractometers
warning
This section is automatically generating by introspecting the hkl library.
4. Developpement
4.1. Getting hkl
To get hkl, you can download the last stable version from sourceforge or if you want the latest development version use git or msysgit on windows system and do:
git clone git://repo.or.cz/hkl.git
or:
git clone http://repo.or.cz/r/hkl.git (slower)
then checkout the next branch like this:
cd hkl
git checkout -b next origin/next
4.2. Building hkl
To build hkl you need Python 2.3+ the GNU Scientific Library 1.12 and GLib-2.0 >= 2.3.4:
./configure --disable-gui make sudo make install
you can also build a GUI interfaces which use gtk:
./configure make sudo make install
optionnaly you can build an experimental libhkl3d library (no public API for now) which is used by the GUI to display and compute diffractometer collisions (only the K6C model). To build it you need also gtkglext and bullet 2.82:
./configure --enable-hkl3d make sudo make install
if you want to work on the documentation you need the extra
- gtk-doc for the api
- sphinx for the html and latex doc.
- asymptote for the figures
- emacs the well known editor
- htmlize used to highlight the source code
- org-mode litteral programming
On Debian/Ubuntu you just need to install
sudo apt-get install emacs dvipng emacs-goodies-el org-mode
./configure --enable-gtk-doc make make html
nevertheless if you do not want to build the documentation you can do:
./configure --disable-hkl-doc
4.3. Hacking hkl
4.3.1. Bug reporting
4.3.2. Providing patches
you can send your patch to Picca Frédéric-Emmanuel using git
and
git-email
.
Here a minimalist example of the workflow to prepare and send
patches for integration into the hkl library. Suppose you wan to
add a new feature, you need first to create a new branch from the
next
one:
git checkout -b my-next next
hack, hack:
git commit -a
more hacks:
git commit -a
now that your new feature is ready, you can send by email your
work using git format-patch
for review:
git format-patch origin/next
which will generate a bunch of 0001\_xxx
, 0002\_xxx
,
… patches
Then you can configure git send-email
in order to send the
patches for review.
git config sendemail.to "picca@synchrotron-soleil.fr"
and send then with this command:
git send-email 0001-xxx.patch, 0002-xxx.patch, ...
If it does not work you can use your usually email software and send these generated patches to the author.
4.4. Howto's
4.4.1. Add a diffractometer
To add a new diffractometer, you just need to copy the
hkl/hkl-engine-template.c
into
hkl/hkl-engine-INSTITUT-BEAMLINE-INSTRUMENT.c
where you replace
the upper case with the appropriate values.
The template file is compiled during the build process to ensure that it is always valid.
Then you just need to follow the instruction found in the template. If you need some precision about the process, do not hesitate to contact the main author.
do not forgot also to add this new file into hkl/Makefile.am
with other diffractometers in the hkl_c_sources variable (please
keep the alphabetic order).
4.4.2. Work on the documentation
The documentation system is written with org-mode, and the babel extension which allow to introspect the library and generate part of the doc using the hkl library. Python code is executed during the build process to generate the Diffractometer section of the documentation. To work on the doc and test the embedded python code it is necessary to setup a few environment variables and start emacs with the right LD_LIBRARY_PATH. In order to simplify the process a make target was written. You just need to type:
cd Documentation
make doc-edit
and start to contribute.
If you do not have emacs, you can nevertheless contribute by
editing the Documentation/hkl.org.in
file which is text only.
The most expected contributions are for now:
- english correctness
- a nicer css
5. Bindings
The hkl library use the gobject-introspection to provide automatic binding for a few languages.
5.1. Python
You can test the binding directly from the source directory with these commandes if ipython is installed.
cd tests/bindings
make ipython
then you have the Hkl module preloaded into the ipython environment.
hkl computation:
has you can see there is 4 available solutions.
let's compute an hkl trajectory and select the first solution.
if we look at the 3 other solutions we can see that there is a problem of continuity at the begining of the trajectory.
hey what's happend with theses solutions ! let's look closely to real numbers. the last column is the distance to the diffractometer current position. This distance is for now express like this:
\(\sum_{axes} \left|\text{current position} - \text{target position}\right|\)
[0.0, 119.99999999999999, 0.0, -90.0, 0.0, 59.99999999999999] 0.0 [0.0, -119.99999999999999, 0.0, -90.0, 0.0, -59.99999999999999] 6.28318530718 [0.0, -60.00000000000005, 0.0, 90.0, 0.0, 59.99999999999999] 6.28318530718 [0.0, 60.00000000000001, 0.0, 90.0, 0.0, -59.99999999999999] 6.28318530718 [0.0, 117.7665607657826, 7.456826294401656, -92.39856410531434, 0.0, 60.33024982425957] 0.216753826612 [0.0, -57.436310940366894, -7.456826294401656, 92.39856418853617, 0.0, 60.33024982425957] 6.41621345188 [0.0, 62.2334392342174, -7.456826294401656, 92.39856410531434, 0.0, -60.33024982425957] 6.42197739723 [0.0, -122.5636890596331, 7.456826294401656, -92.3985641885362, 0.0, -60.33024982425957] 6.50570308205 [0.0, 115.89125602137928, 14.781064139466098, -94.7660423112577, 0.0, 61.314597086440706] 0.219062698235 [0.0, -125.42334103772737, 14.781064139466098, -94.7660427050904, 0.0, -61.314597086440706] 6.53671995288 [0.0, -54.57665896227262, -14.781064139466098, 94.76604270509038, 0.0, 61.314597086440706] 6.67989976726 [0.0, 64.10874397862072, -14.781064139466098, 94.7660423112577, 0.0, -61.314597086440706] 6.71437170098 [0.0, 114.39338605351007, 21.85448296702796, -97.074145033719, 0.0, 62.93506298693471] 0.218163667981 [0.0, -128.54167683157993, 21.85448296702796, -97.07414574435087, 0.0, -62.93506298693471] 6.59846359365 [0.0, -51.45832316842005, -21.85448296702796, 97.07414574435087, 0.0, 62.93506298693471] 6.93673746356 [0.0, 65.60661394648993, -21.85448296702796, 97.074145033719, 0.0, -62.93506298693471] 7.03385205725 [0.0, 113.28316795475283, 28.583837575232764, -99.29953499008337, 0.0, 65.16540747008955] 0.21459359225 [0.0, -131.88223933078322, 28.583837575232764, -99.29953638594702, 0.0, -65.16540747008955] 6.69038531388 [0.0, -48.11776066921677, -28.583837575232764, 99.29953638594702, 0.0, 65.16540747008955] 7.18296350386 [0.0, 66.71683204524717, -28.583837575232764, 99.29953499008337, 0.0, -65.16540747008955] 7.37556986959 [0.0, 112.56286877075006, 34.90573305321372, -101.42496979586187, 0.0, 67.97568017857415] 0.209053830457 [0.0, -135.4128111996365, 34.90573305321372, -101.42497263302461, 0.0, -67.97568017857415] 6.81174779784 [0.0, -44.58718880036348, -34.90573305321372, 101.4249726330246, 0.0, 67.97568017857415] 7.41581162393 [0.0, 67.43713122924994, -34.90573305321372, 101.42496979586187, 0.0, -67.97568017857415] 7.7353201851 [0.0, 112.2291126083182, 40.78594007247402, -103.43941832567457, 0.0, 71.33706722449408] 0.202280147961 [0.0, -139.10795451001587, 40.78594007247402, -103.43942357602316, 0.0, -71.33706722449408] 6.96173845391 [0.0, -40.89204548998411, -40.78594007247402, 103.43942357602312, 0.0, 71.33706722449408] 7.63358787543 [0.0, 67.7708873916818, -40.78594007247402, 103.43941832567457, 0.0, -71.33706722449408] 8.10986069093 [0.0, 112.27578927291766, 46.214916130901734, -105.33741042812996, 0.0, 75.22640762217479] 0.196576175748 [0.0, -142.95061850160724, 46.214916130901734, -105.3374188005596, 0.0, -75.22640762217479] 7.13962155618 [0.0, -37.04938149839278, -46.214916130901734, 105.33741880055959, 0.0, 75.22640762217479] 7.83557762281 [0.0, 67.72421072708234, -46.214916130901734, 105.33741042812996, 0.0, -75.22640762217479] 8.49706672677 [0.0, 112.697137434232, 51.201667684695856, -107.11797492933192, 0.0, 79.63023536264535] 0.202327153157 [0.0, -146.9330984641471, 51.201667684695856, -107.11798610058318, 0.0, -79.63023536264535] 7.34491897177 [0.0, -33.0669015358529, -51.201667684695856, 107.11798610058317, 0.0, 79.63023536264535] 8.02185610877 [0.0, 67.30286256576798, -51.201667684695856, 107.11797492933192, 0.0, -79.63023536264535] 8.89597005568 [0.0, 113.49085964586432, 55.76762791023837, -108.78347437395287, 0.0, 84.54867879242364] 0.208455586312 [0.0, -151.05782007465257, 55.76762791023837, -108.78348605483542, 0.0, -84.54867879242364] 7.57761473366 [0.0, -28.942179925347414, -55.76762791023837, 108.78348605483538, 0.0, 84.54867879242364] 8.19307323084 [0.0, 66.50914035413568, -55.76762791023837, 108.78347437395287, 0.0, -84.54867879242364] 9.30675279514 [0.0, 114.6614608037443, 59.941489465646214, -110.3385360479293, 0.0, 90.00000081324956] 0.215562935229 [0.0, -155.33854118146962, 59.941489465646214, -110.33854432979601, 0.0, -89.99999918675044] 7.83839602383 [0.0, -24.661458818530395, -59.941489465646214, 110.33854432979601, 0.0, 90.00000081324956] 8.3502621071 [0.0, 65.3385391962557, -59.941489465646214, 110.3385360479293, 0.0, -89.99999918675044] 9.7307712883
as you can see for the first point of the trajectory, the 2nd, 3rd and 4th solutions have identical distances to the current position of the diffractometer so they are un-ordered:
[0.0, 119.99999999999999, 0.0, -90.0, 0.0, 59.99999999999999] 0.0 [0.0, -119.99999999999999, 0.0, -90.0, 0.0, -59.99999999999999] 6.28318530718 [0.0, -60.00000000000005, 0.0, 90.0, 0.0, 59.99999999999999] 6.28318530718 [0.0, 60.00000000000001, 0.0, 90.0, 0.0, -59.99999999999999] 6.28318530718
then the problem arise with the second and third solution. you can see a sort of reorganisation of the solution. 2 -> 3, 3 -> 4 and 4 -> 2 then the order will stick unchanged until the end of the trajectory. this is because the distance is computed relatively to the current position of the diffractometer.:
[0.0, 117.7665607657826, 7.456826294401656, -92.39856410531434, 0.0, 60.33024982425957] 0.216753826612 [0.0, -57.436310940366894, -7.456826294401656, 92.39856418853617, 0.0, 60.33024982425957] 6.41621345188 [0.0, 62.2334392342174, -7.456826294401656, 92.39856410531434, 0.0, -60.33024982425957] 6.42197739723 [0.0, -122.5636890596331, 7.456826294401656, -92.3985641885362, 0.0, -60.33024982425957] 6.50570308205 [0.0, 115.89125602137928, 14.781064139466098, -94.7660423112577, 0.0, 61.314597086440706] 0.219062698235 [0.0, -125.42334103772737, 14.781064139466098, -94.7660427050904, 0.0, -61.314597086440706] 6.53671995288 [0.0, -54.57665896227262, -14.781064139466098, 94.76604270509038, 0.0, 61.314597086440706] 6.67989976726 [0.0, 64.10874397862072, -14.781064139466098, 94.7660423112577, 0.0, -61.314597086440706] 6.71437170098
warning
when you compute a trajectory, start from a valid position (the starting point must be the real first point of your trajectory) then use only the closest solution for the next points of the trajectory. (first solution of the geometries list)
6. Releases
6.1. 5.0.0.3367
6.1.1. DONE fix the segfault when trying to create a non valid HklLattice
6.1.2. DONE added the q_sampleaxis_timestamp custom projection to binoculars-ng
6.2. 5.0.0.2661
6.2.1. DONE Only finite float values are allow when setting an HklParameter value or range.
When using hkl_parameter_value_set
or
hkl_parameter_min_max_set
functions it is not allow to use the
float NaN
, -Inf
, +Inf
value.
6.2.2. DONE use python3 instead of python3 for unit tests
In order to prepare the removal of python2 for Debian 11, we switched the unit test. The remaining part is during the build of the documentation. The best would be to report a bug against emacs in order to set python3 as default python interpreter.
6.2.3. DONE Added the Soleil Nanoscopium robot setup.
6.3. 5.0.0.2456
6.3.1. DONE add emergence on all e4c diffractometers
The emergence pseudo axis is was added to SOLEIL MARS
and E4CV
6.3.2. DONE Fix for multiarch (headers)
The ccan_config.h
generated file is arch specific. It is then
necessary to install this file under /usr/include/<triplet> on
Debian like systems. This way it will be possible to co-installa
32/64 bit version of hkl, or to do cross-compilation (arm on
x86_64, etc…)
6.3.3. DONE Fix the FTBFS with the new bullet 2.86.1 version
In order to update the internal structures of Hkl3DObject
(the
is-colliding
member), we were using a callback which became
un-effectiv with this new version of bullet. The logic was
rewritten in order to be much more efficent using the manifold
informations. Now we iterate on Hkl3DObject
object only once
(n) complexity instead of (n²) with the previous one.
6.3.4. DONE Added "SOLEIL SIXS MED2+3 v2" geometry
This diffractometer contain a global HklEngineList parameter in order to activate or not the rotation of the Detector. A new public API was added in order to deal with these parameters.
const darray_string *hkl_engine_list_parameters_names_get(const HklEngineList *self); const HklParameter *hkl_engine_list_parameter_get(const HklEngineList *self, const char *name, GError **error); int hkl_engine_list_parameter_set(HklEngineList *self, const char *name, const HklParameter *parameter, GError **error); void hkl_engine_list_parameters_values_get(const HklEngineList *self, double values[], size_t n_values, HklUnitEnum unit_type); int hkl_engine_list_parameters_values_set(HklEngineList *self, double values[], size_t n_values, HklUnitEnum unit_type, GError **error);
And also available via the Python binding.
engines = factory.create_new_engine_list() # get parameters names names = engines.parameters_names_get() # get the parameters values values = engines.parameters_values_get(Hkl.UnitEnum.USER) # set the parameters values engines.parameters_values_set(values, Hkl.UnitEnum.USER)
6.4. 5.0.0.2080
6.4.1. DONE HklEngine
emergence_fixed for the SOLEIL SIX MED 2+2 geometry.
6.4.2. DONE HklVector
The hkl_vector_init method is now public.
6.4.3. DONE HklParameter
at the end of the computation all solutions are filtered in order to check that they are valid (min < value < range). BUT for a rotation axis this check was instead (min < value % 2pi < max).
6.4.4. DONE HklGeometry
Add hkl_geometry_[sample/detector]_rotation_get method. It is now
possible to get the sample or the detector rotation expressed as a
HklQuaternion
.
qr = geometry.sample_rotation_get(sample) qd = geometry.detector_rotation_get(detector)
6.4.5. DONE HklQuaternion
Add hkl_quaternion_to_matrix in order to convert a HklQuaternion
into a HklMatrix
. Then you just need to convert this HklMatrix
into a numpy array when used from the python binding
def hkl_matrix_to_numpy(m): M = empty((3, 3)) for i in range(3): for j in range(3): M[i, j] = m.get(i, j) return M M = hkl_matrix_to_numpy(q.to_matrix())
6.4.6. DONE Soleil Sirius Turret
Add the basepitch
axis which rotate around \(\vec{y}\) in mrad.
6.5. 4.99.99.1955
Add the ccan_config.h public header. This header is generated with the ccan configurator program.
6.6. 4.99.99.1950
Fix an FTBFS observed on the sparc arch
6.7. 4.99.99.1949
6.7.1. DONE HklInterval
hkl_interval_cmp
was wrong. Now the comparison is done between
HKL_EPSILON
and the distance between minimum and maximum. This
problem was triggered first on ppc64el architecture.
6.7.2. DONE PATH_MAX
Replace getcwd called by get_current_dir_path instead in order to avoid PATH_MAX which is not available on hurd.
6.8. 4.99.99.1946
6.9. 4.99.99.1940
6.9.1. DONE HklLattice
add an hkl_lattice_volume_get
volume = hkl_lattice_volume_get(lattice);
6.9.2. DONE HklEngine
- "nrj, sample, … dependencies"
Add the
hkl_engine_dependencies_get
method which return if theHklEngine
depends of the axes, the energy, or the sample. the possible values are stored in theHklEngineDependencies
enum.dependencies = hkl_engine_dependencies_get(engine); if (dependencies & HKL_ENGINE_DEPENDENCIES_ENERGY) { ... } if (dependencies & HKL_ENGINE_DEPENDENCIES_SAMPLE) { ... } ...
- "tth2"
Add a new hkl engine which contain two pseudo axes.
tth
two times the diffraction angle \(\theta\)alpha
the azimuth of q in the zOy plan.
- "incidence"
Add a new incidence engine which contain only one pseudo axis.
incidence
the incoming beam incidence on the sample surface.azimuth
the sample surface azimuth.
hkl_engine_parameter_set
Fix a bug and expose the method in the binding.
- general
- use #define AXIS "axis_name" in all the code to set the axes names at only one place.
6.9.3. DONE HklLattice
expose in the binding the _x_get/set methods
Now you can use hkl_lattice_x_get where x=a, b, c, alpha, beta, gamma in the bindings.
a = lattice.a_get()
lattice.a_set(a)
6.9.4. DONE HklSampleReflection
expose the flag_get/set and geometry_get/set method
It is now possible to change the geometry stored in a reflection via the bindings.
flag = reflection.flag_get() reflection.flag_set(flag) geometry = reflection.geometry_get() geometry.axes_values_set([omega, chi, phi, ...]) reflection.geometry_set(geometry)
7. Todo
7.1. hkl
7.1.1. TODO HklEngine
q/q2
Fix all these engines… This engine takes into account only the gamma and delta axes. so diffractometers with 3 axes for the detector are wrong. It would be nice to take into account all the detector holder AND the position of the detecteor on the diffractometer arms (for now the detector is always on the last axis).
7.1.2. TODO HklSource
Create a parameter for the wavelength. This is just internally for the futur trajectory system, so no need to change the signature of hkl_geometry_vawelength get/set
7.1.3. TODO SOLEIL SIRIUS KAPPA
Investigation of a problem saw on Sirius Kappa geometry. The idea is to compute a trajectory from \([0, 0, 1]\) to \([0, 0, 6]\) on a \(GaAs\) sample.
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)]) [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)])] 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)]) [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)])] 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)]) [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)])] 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)]) [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)])] 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)]) [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)])] 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)]) [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)])
As we can see the phi and kphi motor switch from time to time to another solution which is at around 180° of the other solutions.
Figure 6: plot the [0,0,1] -> [0,0,6] trajectory from two different starting point and different step size.
Figure 7: plot the [0,0,1] -> [0,0,6] idem previous figure but move the diffractometer.
Figure 8: zoom on the 2 solutions.
Figure 9: plot the [0,0,1] -> [0,0,6] for different number of steps
7.1.4. TODO [0/2]
PetraIII
- TODO computation problem
Dear Teresa,
Using the prruptest.txt ubmatrix I see that the value of psi is offset by 45 degrees. I expect it to be 0 degrees when azimuth reference vector is 0 0 1 that is along the beam. See below thereturned numbers. This might have to do with the definition of the beam axis in the controller. Otherwise now when I change reference vector by 90 degrees the computed value is changed by 90 degrees. That is a progress. Can you contact Frederic and ask him about this ?
Best regards,
Sonia
See below p09/door/haspp09.01 [9]: setaz 1 0 0
p09/door/haspp09.01 [10]: wh
Engine: hkl
Mode: psi_constant_vertical
H K L = 0.00000 3.00605 -0.00000 Ref = 1.00000 0.00000 0.00000 Azimuth (Psi - calculated) = -45.00005 Azimuth (Psi - set) = 0.00000 Wavelength = 2.07957
Delta Theta Chi Phi Mu Gamma 45.77575 22.88783 90.00000 182.85400 0.00000 -0.00000
p09/door/haspp09.01 [11]: setaz 0 0 1
p09/door/haspp09.01 [12]: wh
Engine: hkl
Mode: psi_constant_vertical
H K L = 0.00000 3.00605 -0.00000 Ref = 0.00000 0.00000 1.00000 Azimuth (Psi - calculated) = -135.00005 Azimuth (Psi - set) = 0.00000 Wavelength = 2.07957
Delta Theta Chi Phi Mu Gamma 45.77575 22.88783 90.00000 182.85400 0.00000 -0.00000
where:
Azimuth (Psi - calculated) is the value of the pseudomotor psi. Azimuth (Psi - set) is the value set in the parameter psi of the current mode.
Hi Frederic,
This is the UB matrix:
Best regards,
Sonia
Created at 2015-01-21 12:35
Crystal prruptest
Wavelength 2.07957463938
A 8.03656 B 8.03656 C 8.03656 Alpha 90.0 Beta 90.0 Gamma 90.0
R0 0 0.0 1.0 0.0 0 1 0.0 14.8979 90.0 182.854 0.0 29.7959 R1 1 1.0 0.0 1.0 0 1 0.0 14.8979 0.0 182.854 0.0 29.7959
Mode psi_constant_vertical
PsiRef 0.0 0.0 1.0
U00 -0.580 U01 0.000 U02 0.525 U10 0.000 U11 0.782 U12 -0.000 U20 -0.525 U21 -0.000 U22 -0.580
Ux 179.999952315 Uy 42.14605 Uz -179.999932647
SaveDirectory home/p09user/crystals
- TODO another question
J'ai un probleme avec la position que le controlleur calcule avec la matrice UB que nous t'avons envoye. See sequence of emails echanges avec Teresa.
>>>> I am at 0 3.00605 0 with phi -182 and psi calculated is -135 >>>> When I freeze psi at -135 and type ca 0 3.00605 0 the controller >> should return to me the positions at which I am. But no he tells me that I >> have to go to 178 degrees in phi that is turning by 360 degrees.
Est-ce un probleme avec la trajectoire selectionnee ? Est-ce qu'il est possible de definir des cut-points comme dans spec avec ta librairie ?
7.1.5. TODO [2/4]
HklParameter
[X]
method to use min/max to check for the validity[X]
add a method to get the axis_v and quaternion of the HklAxis this method will return NULL if this is not relevant. hkl_parameter_axis_v_get and hkl_parameter_quaternion_get[ ]
degenerated an axis is degenerated if its position have no effect on the HklPseudoAxis calculus. Add a degenerated member to the axis. that way it would be possible to check a posteriori for this degenerescencence.[ ]
Add a description for each parameters.
7.1.6. TODO This will help for the documentation and the gui.
7.1.7. TODO HklGeometryList different method to help select a solution.
this select solution can depend on the geometry for example the kappa axis must be in one side of the plane.
7.1.8. TODO add a fit on the Hklaxis offsets.
7.1.9. TODO API to put a detector and a sample on the Geometry.
7.1.10. TODO HklSample
- TODO unit test: hkl_sample_affine.
Check this: lattice=1.540000;1.540000;1.540000;90.000000;90.000000;90.000000;0;0;0;0;0;0 uxuyuz=0.000000;0.000000;0.000000 reflection=1.540000;0.159010;1.256718;0.796660;1;0.000000;0.000000;0.000000;0.000000;0.000000 reflection=1.540000;0.206208;0.342357;-0.080346;1;0.000000;0.000000;0.000000;0.000000;0.000000 reflection=1.540000;0.206208;0.342357;-0.080346;1;0.000000;0.000000;0.000000;0.000000;0.000000
A, B, C, Alpha, Beta, Gamma, Ux, Uy, Uy: 17764892.133, 5793679.092, 15733785.198, 179.997, 179.999,452408725.23, -575727594.04, -1913661011.01 (affine) 1rst finetness
all the reflections are non collinear the affine method should warn the user about this.
7.1.11. TODO HklEngine "zone"
7.1.12. TODO HklEngine "custom"
for now this pseudoaxis let you select the axis you want to use for the computation.
7.1.13. TODO HklEngine "q/q2" add a "reflectivity" mode
This mode should have the surface as parameters and the incident angle is equal to the emergence angle.
7.1.14. TODO create a macro to help compare two real the right way
fabs(a-b) < epsilon * max(1, abs(a), abs(b))
7.1.15. TODO add an hkl_sample_set_lattice_unit()
7.1.16. TODO SOLEIL SIXS
- DONE find the right solutions. zaxis
The cosinus and sinus properties are not enough to find the solution expected by the users. The idea is to use the Ewalds construction to generate a valid solution from the first one obtain numerically. The basic idea is to rotate the hkl vector around the last axis of the sample holder until it intersect again the Ewalds sphere. Then we just need to fit the detector position. This way the solution can be entirely generic (not geometry specific). Nevertheless it is necessary to propose this only for the hkl pseudo axes. I will add this special feature in the Mode. So it will be possible to add thoses special cases easily.
- TODO Add the DEP diffractometer geometry
This diffractometer is a Newport one based on the kappa 6 circles ones. But instead of a kappa head, they use an Hexapod head. This head can be put horizontally or vertically.
7.1.17. TODO generalisation of the z-axis hkl solver
first we need the degenerated member of the Axis. thaht way it could be possible to find the last non degenerated axis for the detector fit.
7.1.18. TODO investigate the prigo geometry.
7.1.19. TODO augeas/elektra for the plugin configure part.
7.1.20. TODO logging
- TODO
[1/2]
add in a few methods.
[X]
hkl_pseudo_axes_values_set[ ]
hkl_sample_affine
- TODO gir logging
It would be nice to generate the library logging using the .gir information. So instead of writing the logging code for each method, it would be better to have a generic method for this purpose.
- TODO parsable logging information.
A parsable logging format would help to setup some re-play unit test. This way it could help during the developpement process (modification of the hkl internals) to be confident that computation are ok.
7.1.21. TODO performances
- Investigate liboil to speed calculation (in HklVector, HklMatrix and HklQuaternion)
- Avoid to call
hkl_engine_prepare_internal
at each computation.
7.2. documentation
7.2.1. TODO [1/6]
rewrite documentation in org-mode
[-]
embedding code into the org file[-]
[1/4]
python[X]
auto generation of the diffractometer descriptions[ ]
trajectories explanations[ ]
trajectories tests.[ ]
unit tests output ?
[ ]
asymptote
[X]
need to check if templates could be generated using the hkl python binding for all diffractometer geometries.[ ]
need to add a description for the diffractometer, the mode, the parameters.[ ]
need a nice css for the generated doc.[ ]
check if org-info.js could be usefull[ ]
add documentation explaining the sector-cuts a la hkl
7.3. [0/3]
gui
[ ]
change the color of fitparameter cells if they differ from the current sample values[ ]
check if a REPL could be integrated to provide an autocad like interface.[ ]
add tooltips using hkl_parameter_description_get for the pseudo axes and the mode parameters.